KaliVeda
Toolkit for HIC analysis
Loading...
Searching...
No Matches
KVItvFinderDialog.cpp
1//Created by KVClassFactory on Mon Jan 23 10:03:13 2017
2//Author: Diego Gruyer
3
4#include "KVItvFinderDialog.h"
6#include "TStyle.h"
7#include "TSystem.h"
8#include "TROOT.h"
9#include "TGMsgBox.h"
10#include "TGFileDialog.h"
11#include "KVTestIDGridDialog.h"
12#include "KVIdentificationResult.h"
13#include "KVNameValueListGUI.h"
14#include <KVMultiGaussIsotopeFit.h>
15#include "KeySymbols.h"
16#include <thread>
17
19//ClassImp(interval_painter)
20
21// Set default values for mass-fit parameters
22
23
24
26 {"Limit range of fit", false},
27 {"PID min for fit", 0.},
28 {"PID max for fit", 10.},
29 {"Minimum probability [%]", 50.},
30 {"Minimum #sigma", 1.e-2},
31 {"Maximum #sigma", 5.e-2}
32};
33
34
35
39
41{
42 // remove painter from list and modify the 'left_painter' and 'right_painter' references
43 // in any adjacent painters/intervals, then delete painter
44
45 std::unique_ptr<KVPIDIntervalPainter> _p(p);
46 auto pleft = p->get_left_interval();
47 auto pright = p->get_right_interval();
48 if (pleft) pleft->set_right_interval(pright);
49 if (pright) pright->set_left_interval(pleft);
51}
52
53
54
56
58{
59 fGrid = gg;
60 fHisto = hh;
61
62 fPoints = new TGraph;
64 fNPoints = 0;
65
68
69 gROOT->ProcessLine(Form("KVItvFinderDialog* _dummy_itv=(KVItvFinderDialog*)%p", this));
70
71 fMain = new TGTransientFrame(gClient->GetDefaultRoot(), gClient->GetDefaultRoot(), 10, 10);
72 // Here is the recipe for cleanly closing a window
73 // (see https://root-forum.cern.ch/t/error-in-rootx11errorhandler-baddrawable-quot/8095/6)
74 fMain->Connect("CloseWindow()", "KVItvFinderDialog", this, "DoClose()");
77 // afterwards, in the destructor do fMain->CloseWindow(), and in DoClose(), do 'delete this'
78
79 // Default constructor
80 TGHorizontalFrame* fCanvasFrame = new TGHorizontalFrame(fMain, 627, 7000, kHorizontalFrame);
81 // fCanvasFrame->SetBackgroundColor(fColor);
82
83
84 TRootEmbeddedCanvas* fRootEmbeddedCanvas615 = new TRootEmbeddedCanvas(0, fCanvasFrame, 800, 440);
85 // to replace the TCanvas in a TRootEmbeddedCanvas, just delete the original like so:
86 // (see https://root-forum.cern.ch/t/error-in-rootx11errorhandler-baddrawable-quot/8095/6)
87 auto WID = fRootEmbeddedCanvas615->GetCanvasWindowId();
88 delete fRootEmbeddedCanvas615->GetCanvas();
89 fCanvas = new TCanvas("c123", 10, 10, WID);
90 fCanvas->AddExec("toto", "if(_dummy_itv)_dummy_itv->HandleKey();");
91 fRootEmbeddedCanvas615->AdoptCanvas(fCanvas);
92 fPad = fCanvas->cd();
94 fCanvas->SetTopMargin(0.02);
97
98 fCanvasFrame->AddFrame(fRootEmbeddedCanvas615, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY, 2, 2, 2, 2));
99 fMain->AddFrame(fCanvasFrame, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY, 0, 0, 0, 0));
100
101 TGVerticalFrame* fControlOscillo = new TGVerticalFrame(fCanvasFrame, 2000, 7000, kVerticalFrame);
102
103 {
104 const char* xpms[] = {
105 "filesaveas.xpm",
106 "profile_t.xpm",
107 "bld_copy.png",
108 "ed_new.png",
109 "refresh2.xpm",
110 "sm_delete.xpm",
111 "h1_t.xpm",
112 "query_new.xpm",
113 "tb_back.xpm",
114 "bld_colorselect.png",
115 "latex.xpm",
116 "move_cursor.png",
117 0
118 };
119 // toolbar tool tip text
120 const char* tips[] = {
121 "Save intervals in current grid",
122 "Find intervals",
123 "Create a new interval set",
124 "Create a new interval",
125 "Update interval lists",
126 "Remove selected intervals",
127 "Multigauss fit to isotopes in interval set",
128 "Set parameters for fit",
129 "Remove fit from selected interval set",
130 "Test identification",
131 "Set log scale on y axis",
132 "Unzoom the histogram",
133 0
134 };
135 int spacing[] = {
136 5,
137 20,
138 0,
139 0,
140 0,
141 20,
142 50,
143 0,
144 0,
145 50,
146 80,
147 0,
148 0
149 };
150 const char* method[] = {
151 "SaveGrid()",
152 "Identify()",
153 "NewIntervalSet()",
154 "NewInterval()",
155 "UpdateLists()",
156 "RemoveInterval()",
157 "FitIsotopes()",
158 "SetFitParameters()",
159 "RemoveFit()",
160 "TestIdent()",
161 "SetLogy()",
162 "UnzoomHisto()",
163 0
164 };
165 fNbButtons = 0;
166 ToolBarData_t t[50];
167 fToolBar = new TGToolBar(fControlOscillo, 450, 80);
168 int i = 0;
169 while (xpms[i]) {
170 t[i].fPixmap = xpms[i];
171 t[i].fTipText = tips[i];
172 t[i].fStayDown = kFALSE;
173 t[i].fId = i + 1;
174 t[i].fButton = NULL;
175 TGButton* bb = fToolBar->AddButton(fControlOscillo, &t[i], spacing[i]);
176 bb->Connect("Clicked()", "KVItvFinderDialog", this, method[i]);
177 fNbButtons++;
178 i++;
179 }
180 fControlOscillo->AddFrame(fToolBar, new TGLayoutHints(kLHintsTop | kLHintsExpandX));
181 }
182
183 fIntervalSetListView = new KVListView(interval_set::Class(), fControlOscillo, 450, 200);
186 fIntervalSetListView->SetDataColumn(1, "PIDs", "GetNPID", kTextCenterX);
187 fIntervalSetListView->SetDataColumn(2, "Masses", "GetListOfMasses", kTextLeft);
188 fIntervalSetListView->Connect("SelectionChanged()", "KVItvFinderDialog", this, "DisplayPIDint()");
189 fIntervalSetListView->SetDoubleClickAction("KVItvFinderDialog", this, "ZoomOnCanvas()");
192
193 fIntervalListView = new KVListView(interval::Class(), fControlOscillo, 450, 180);
195 fIntervalListView->SetDataColumn(0, "Z", "GetZ", kTextLeft);
197 fIntervalListView->SetDataColumn(2, "min", "GetPIDmin", kTextCenterX);
198 fIntervalListView->SetDataColumn(3, "pid", "GetPID", kTextCenterX);
199 fIntervalListView->SetDataColumn(4, "max", "GetPIDmax", kTextCenterX);
200
201
202
203 {
204 const char* xpms[] = {
205 "arrow_down.xpm",
206 "arrow_up.xpm",
207 0
208 };
209 const char* tips[] = {
210 "Decrease A by one",
211 "Increase A by one",
212 0
213 };
214 int spacing[] = {
215 120,
216 0,
217 0
218 };
219 const char* method[] = {
220 "MassesDown()",
221 "MassesUp()",
222 0
223 };
224 fNbButtons = 0;
225 ToolBarData_t t[50];
226 fToolBar2 = new TGToolBar(fControlOscillo, 450, 80);
227 int i = 0;
228 while (xpms[i]) {
229 t[i].fPixmap = xpms[i];
230 t[i].fTipText = tips[i];
231 t[i].fStayDown = kFALSE;
232 t[i].fId = i + 1;
233 t[i].fButton = NULL;
234 TGButton* bb = fToolBar2->AddButton(fControlOscillo, &t[i], spacing[i]);
235 bb->Connect("Clicked()", "KVItvFinderDialog", this, method[i]);
236 fNbButtons++;
237 i++;
238 }
239 fControlOscillo->AddFrame(fToolBar2, new TGLayoutHints(kLHintsTop | kLHintsExpandX));
240 }
241
242 // fCurrentView->ActivateSortButtons();
243 fIntervalListView->Connect("SelectionChanged()", "KVItvFinderDialog", this, "SelectionITVChanged()");
244 // fCurrentView->SetDoubleClickAction("FZCustomFrameManager",this,"ChangeParValue()");
246
247 fControlOscillo->AddFrame(fIntervalListView, new TGLayoutHints(kLHintsTop | kLHintsExpandX, 2, 2, 2, 2));
248
249 fCanvasFrame->AddFrame(fControlOscillo, new TGLayoutHints(kLHintsExpandY, 0, 0, 0, 0));
250
251
252 //layout and display window
255
256 // position relative to the parent's window
258
259 fMain->SetWindowName("Masses Identification");
261 fMain->MapWindow();
262
263 fIntervalSetListView->Display(((KVIDZAFromZGrid*)fGrid)->GetIntervalSets());
264 current_interval_set = nullptr;
265 fPad->cd();
266
267 LinearizeHisto(100);
270 fLinearHisto->Draw("hist");
271
272 int tmp[30] = {3, 3, 3, 4, 4, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6};
273 for (int ii = 0; ii < 30; ii++) fNpeaks[ii] = tmp[ii];
274
275 fSig = 0.1;
276 fRat = 0.0001;
277
279 PrintHelp();
280
281}
282
283
284
285
287
289{
290 std::unique_ptr<TList> list(fIntervalSetListView->GetSelectedObjects());
291 Int_t nSelected = list->GetSize();
292 if (nSelected == 1) {
293 current_interval_set = (interval_set*)list->At(0);
295 }
296 else {
297 current_interval_set = nullptr;
299 }
301}
302
303
304
306
308{
309 fPad->cd();
310 fItvPaint.Execute("HighLight", "0");
311
313 int zz = ((interval*)fIntervalListView->GetLastSelectedObject())->GetZ();
314 int aa = ((interval*)fIntervalListView->GetLastSelectedObject())->GetA();
316 if (!painter) Info("SelectionITVChanged", "%d %d not found...", zz, aa);
317 painter->HighLight();
318 }
319 fCanvas->Modified();
320 fCanvas->Update();
321}
322
323
324
326
328{
329 std::unique_ptr<TList> list(fIntervalSetListView->GetSelectedObjects());
330 Int_t nSelected = list->GetSize();
331 if (nSelected == 1) {
332 current_interval_set = (interval_set*)list->At(0);
334 }
335 else {
336 current_interval_set = nullptr;
338 }
339}
340
341
342
345
347{
348 // Display the interval set for a given Z when the user double clicks on it
349
351 current_interval_set = nullptr;
352 return;
353 }
355 auto zz = current_interval_set->GetZ();
356
357 fLinearHisto->GetXaxis()->SetRangeUser(zz - 0.5, zz + 0.5);
358
359 fItvPaint.Execute("SetDisplayLabel", "0");
360
361 std::unique_ptr<KVSeqCollection> tmp(fItvPaint.GetSubListWithMethod(Form("%d", zz), "GetZ"));
362
363 tmp->Execute("SetDisplayLabel", "1");
364
365 // Check - if no mass fit is displayed, we look to see if the grid has a saved
366 // multigauss fit from a previous session, and if so we display it
367 if (!fPad->GetPrimitive(KVMultiGaussIsotopeFit::get_name_of_multifit(zz))) {
368 if (fGrid->GetParameters()->HasParameter(Form("MASSFIT_%d", zz))) {
369 KVString massfit = fGrid->GetParameters()->GetTStringValue(Form("MASSFIT_%d", zz));
370 massfit.ReplaceAll(":", "=");
371 KVNameValueList fitparams;
372 fitparams.Set(massfit);
373 KVMultiGaussIsotopeFit fitfunc(zz, fitparams);
374 fitfunc.DrawFitWithGaussians("same");
375 // deactivate intervals in painter
376 tmp->Execute("DeactivateIntervals", "");
377 }
378 }
379
380 fCanvas->Modified();
381 fCanvas->Update();
382}
383
384
385
387
389{
390 interval_set* itvs = 0;
391 last_drawn_interval = nullptr;
393 while ((itvs = (interval_set*)it())) {
394 DrawInterval(itvs);
395 }
396}
397
398
399
401
403{
404 fPad->cd();
405 interval* itv = nullptr;
406 // give a different colour to each interval
407 auto nitv = itvs->GetIntervals()->GetEntries();
408 auto cstep = TColor::GetPalette().GetSize() / (nitv + 1);
409 int i = 1;
410 auto deactivate_intervals = fGrid->GetParameters()->HasParameter(Form("MASSFIT_%d", itvs->GetZ()));
411
412 TIter itt(itvs->GetIntervals());
413 while ((itv = (interval*)itt())) {
415 ++i;
416 if (label) dummy->SetDisplayLabel();
417 if (deactivate_intervals) dummy->DeactivateIntervals();
418 dummy->Draw();
419 dummy->SetCanvas(fCanvas);
420 dummy->Connect("IntMod()", "KVItvFinderDialog", this, "UpdatePIDList()");
421 fItvPaint.Add(dummy);
422 last_drawn_interval = dummy;
423 }
424}
425
426
427
432
434{
435 // empty an interval set, effectively removing it from the interval sets which will be saved with the grid.
436 //
437 // we also remove any previous fits from the grid's parameters
438
439 std::vector<int> alist;
440 for (int ii = 0; ii < itvs->GetNPID(); ii++) {
441 interval* itv = (interval*)itvs->GetIntervals()->At(ii);
444 alist.push_back(itv->GetA());
445 }
446 itvs->GetIntervals()->Clear();
447 UpdateLists();
448 // remove any fit displayed in pad
449 KVMultiGaussIsotopeFit fitfunc(itvs->GetZ(), alist);
450 fitfunc.UnDraw(fPad);
451 // mop up any stray gaussians (from intervals which have been removed)
452 KVMultiGaussIsotopeFit::UnDrawAnyGaussian(itvs->GetZ(), fPad);
453
454 // remove from grid parameters
455 if (fGrid->GetParameters()->HasParameter(Form("MASSFIT_%d", itvs->GetZ()))) {
456 fGrid->GetParameters()->RemoveParameter(Form("MASSFIT_%d", itvs->GetZ()));
457 KVNumberList zlist(fGrid->GetParameters()->GetStringValue("MASSFITS"));
458 zlist.Remove(itvs->GetZ());
459 fGrid->GetParameters()->SetValue("MASSFITS", zlist.AsString());
460 }
461 fCanvas->Modified();
462 fCanvas->Update();
463}
464
465
466
468
470{
471 Double_t zmin = ((KVIDentifier*)fGrid->GetIdentifiers()->First())->GetPID() - 1.0;
472 Double_t zmax = 0;
473
474 for (int iz = 1; iz < fGrid->GetIdentifiers()->GetSize() + 1; iz++) {
476 if (tmp && tmp->GetPID() > zmax) zmax = tmp->GetPID();
477 }
478
479 Int_t zbins = (Int_t)(zmax - zmin) * nbins;
480
481 fLinearHisto = new TH1F("fLinearHisto", "fLinearHisto", zbins, zmin, zmax);
482
483 fGrid->SetOnlyZId();
484
485 // use multi-threading capacities
486 auto available_cpu = WITH_MULTICORE_CPU;
487 Int_t xbins_per_cpu = fHisto->GetNbinsX() / available_cpu;
488
489 std::vector<std::thread> jobs; // threads to do the work
490
491 // to clean up copies of grid
492 KVList grid_copies;
493
494 // do not add copies of grid to ID grid manager
495 auto save_auto_add = KVIDGraph::GetAutoAdd();
497
498 std::cout << "Will run " << available_cpu << " threads, each for " << xbins_per_cpu << " bins in X" << std::endl;
499
500 int nthreads = available_cpu;
501 // join threads
502 std::cout << "Histo linearization using " << nthreads << " threads..." << std::endl;
503
504 for (int job = 0; job < available_cpu; ++job) {
505 auto imin = 1 + job * xbins_per_cpu;
506 auto imax = (job + 1) * xbins_per_cpu;
507 if (job == available_cpu - 1) imax = fHisto->GetNbinsX();
508
509 // make new copy of grid
510 auto grid_copy = new KVIDZAFromZGrid(*fGrid);
511 grid_copy->Initialize();
512 grid_copies.Add(grid_copy);
513
514 // start new thread
515 jobs.push_back(std::thread([ =, &nthreads]() {
516
518
519 bool no_mass_id_zone_defined = (grid_copy->GetInfos()->FindObject("MassID") == nullptr);
520
521 for (int i = imin; i <= imax; ++i) {
522 for (int j = 1; j <= fHisto->GetNbinsY(); j++) {
523 Stat_t poids = fHisto->GetBinContent(i, j);
524 if (poids == 0) continue;
525
526 Axis_t x0 = fHisto->GetXaxis()->GetBinCenter(i);
527 Axis_t y0 = fHisto->GetYaxis()->GetBinCenter(j);
528 Axis_t wx = fHisto->GetXaxis()->GetBinWidth(i);
529 Axis_t wy = fHisto->GetYaxis()->GetBinWidth(j);
530
531 if (x0 < 4) continue;
532
533 Double_t x, y;
534 Int_t kmax = (Int_t) TMath::Min(20., poids);
535 Double_t weight = (kmax == 20 ? poids / 20. : 1.);
536 for (int k = 0; k < kmax; k++) {
537 x = gRandom->Uniform(x0 - .5 * wx, x0 + .5 * wx);
538 y = gRandom->Uniform(y0 - .5 * wy, y0 + .5 * wy);
539 if (grid_copy->IsIdentifiable(x, y)) {
540 idr.Clear();
541 grid_copy->KVIDZAGrid::Identify(x, y, &idr);
542 if (no_mass_id_zone_defined || idr.HasFlag(grid_copy->GetName(), "MassID")) {
543 Float_t PID = idr.PID;
544 fLinearHisto->Fill(PID, weight);
545 }
546 }
547 }
548 }
549 }
550 --nthreads;
551 std::cout << "...remaining threads: " << nthreads << std::endl;
552 }));
553 }
554 for (auto& j : jobs) {
555 if (j.joinable()) j.join();
556 }
557
558 // reset automatic grid adding to previous state
559 KVIDGraph::SetAutoAdd(save_auto_add);
560}
561
562
563
566
568{
569 // KVBase::OpenContextMenu("Identify(double,double)",this);
570 Identify(0.1, 0.001);
571}
572
573
574
576
577void KVItvFinderDialog::Identify(double sigma, double ratio)
578{
579 fSig = sigma;
580 fRat = ratio;
581
582 fPad->cd();
583 std::unique_ptr<TList> list(fIntervalSetListView->GetSelectedObjects());
584 if (!list->GetSize()) {
586 for (int ii = 0; ii < fGrid->GetIntervalSets()->GetSize(); ii++) DrawInterval((interval_set*)fGrid->GetIntervalSets()->At(ii), 0);
587 }
588 else {
589 for (int ii = 0; ii < list->GetSize(); ii++) {
590 interval_set* itvs = (interval_set*) list->At(ii);
591 ProcessIdentification(itvs->GetZ(), itvs->GetZ());
592 DrawInterval(itvs, 0);
593 }
594 }
595
596 fCanvas->Modified();
597 fCanvas->Update();
598
599}
600
601
602
604
606{
607 ExportToGrid();
608
609 TString currentdir(gSystem->ExpandPathName("."));
610
611 TString fn = fHisto->GetName();
612 fn += ".dat";
613
614 Int_t ret_code;
615 new TGMsgBox(
616 gClient->GetRoot(),
617 gClient->GetDefaultRoot(),
618 "KVIDGridEditor::SaveCurrentGrid", Form("Do you wat to save the grid here : %s", fn.Data()),
619 kMBIconExclamation, kMBYes | kMBNo, &ret_code
620 );
621
622 if (ret_code == kMBYes) {
623 fGrid->WriteAsciiFile(Form("%s", fn.Data()));
624 return;
625 }
626
627 static TString dir(".");
628 const char* filetypes[] = {
629 "ID Grid files", "*.dat",
630 "All files", "*",
631 0, 0
632 };
633 TGFileInfo fi;
634 fi.fFileTypes = filetypes;
635 fi.fIniDir = StrDup(dir);
636 new TGFileDialog(gClient->GetDefaultRoot(), gClient->GetDefaultRoot(), kFDSave, &fi);
637 if (fi.fFilename) {
638 TString filenam(fi.fFilename);
639 if (filenam.Contains("toto")) filenam.ReplaceAll("toto", fGrid->GetName());
640 if (!filenam.Contains('.')) filenam += ".dat";
641 fGrid->WriteAsciiFile(filenam.Data());
642 }
643 dir = fi.fIniDir;
645
646 fIntervalSetListView->Display(((KVIDZAFromZGrid*)fGrid)->GetIntervalSets());
647 current_interval_set = nullptr;
649
652}
653
654
655
658
660{
661 // Write all PID intervals in grid parameters "PIDRANGE", "PIDRANGE%d", etc.
662
664 KVNumberList pids;
665 interval_set* itvs = 0;
666 TIter npid(fGrid->GetIntervalSets());
667 while ((itvs = (interval_set*)npid())) {
668 if (!itvs->GetNPID()) continue;
669 pids.Add(itvs->GetZ());
670 }
671 fGrid->GetParameters()->SetValue("PIDRANGE", pids.AsString());
672
673 itvs = 0;
674 TIter next(fGrid->GetIntervalSets());
675 while ((itvs = (interval_set*)next())) {
676 if (!itvs->GetNPID()) continue;
677 KVString par = Form("PIDRANGE%d", itvs->GetZ());
678 KVString val = "";
679 interval* itv = 0;
680 TIter ni(itvs->GetIntervals());
681 while ((itv = (interval*)ni())) {
682 val += Form("%d:%lf,%lf,%lf|", itv->GetA(), itv->GetPIDmin(), itv->GetPID(), itv->GetPIDmax());
683 }
684 val.Remove(val.Length() - 1);
685 fGrid->GetParameters()->SetValue(par.Data(), val.Data());
686 }
687}
688
689
690
692
694{
695 std::unique_ptr<TList> list(fIntervalSetListView->GetSelectedObjects());
696 if (!list->GetSize() || list->GetSize() > 1) {
697 current_interval_set = nullptr;
698 return;
699 }
700
701 current_interval_set = (interval_set*)list->At(0);
702
703 fPad->WaitPrimitive("TMarker");
704 auto mm = dynamic_cast<TMarker*>(fPad->GetListOfPrimitives()->Last());
705 assert(mm);
706 double pid = mm->GetX();
707 delete mm;
708
709 int aa = 0;
710 int iint = 0;
711
712 // try to guess mass from position (PID)
713 // typical isotope separation in PID is 0.12 (e.g. for carbon isotopes)
714 // assume that PID=z means A=2*Z
715 auto aa_guessstimate = TMath::Nint(current_interval_set->GetZ() * 2 + (pid - current_interval_set->GetZ()) / 0.12);
716//Info("NewINt","pid = %f guess a=%d",pid,aa_guessstimate);
718 aa = aa_guessstimate;
719 iint = 0;
720 }
721 else if (pid < ((interval*)current_interval_set->GetIntervals()->First())->GetPID()) { // to left of all others
722 aa = ((interval*)current_interval_set->GetIntervals()->First())->GetA() - 1;
723 // NO MORE : use guesstimate as long as it is smaller than A of previously defined interval with largest PID
724 // NOW : use 'aa_guessstimate' only for first interval
725 //Info("NewInt","before first interval, with a=%d",aa+1);
726// if (aa_guessstimate < aa + 1) aa = aa_guessstimate;
727 iint = 0;
728 }
729 else if (pid > ((interval*)current_interval_set->GetIntervals()->Last())->GetPID()) { // to right of all others
730 aa = ((interval*)current_interval_set->GetIntervals()->Last())->GetA() + 1;
731 // NO MORE : use guesstimate as long as it is larger than A of previously defined interval with smallest PID
732 // NOW : use 'aa_guessstimate' only for first interval
733 //Info("NewInt","after last interval, with a=%d",aa-1);
734// if (aa_guessstimate > aa - 1) aa = aa_guessstimate;
736 }
737 else {
738 // look for intervals between which the new one is places
739 for (int ii = 1; ii < current_interval_set->GetNPID(); ii++) {
740 if (pid > ((interval*)current_interval_set->GetIntervals()->At(ii - 1))->GetPID()
741 && pid < ((interval*)current_interval_set->GetIntervals()->At(ii))->GetPID()) {
742 aa = ((interval*)current_interval_set->GetIntervals()->At(ii - 1))->GetA() + 1;
743 // use guesstimate if it is in between masses of adjacent intervals (in terms of PID)
744 if ((aa_guessstimate > (aa - 1)) &&
745 (aa_guessstimate < ((interval*)current_interval_set->GetIntervals()->At(ii))->GetA()))
746 aa = aa_guessstimate;
747 iint = ii;
748 break;
749 }
750 }
751 }
752
753 interval* itv = new interval(current_interval_set->GetZ(), aa, mm->GetX(), mm->GetX() - 0.05, mm->GetX() + 0.05);
755
756 // find intervals which are now left (smaller mass) and right (higher mass) than this one
757 interval* left_interval = iint > 0 ? (interval*)current_interval_set->GetIntervals()->At(iint - 1) : nullptr;
758 interval* right_interval = iint < current_interval_set->GetIntervals()->GetEntries() - 1 ? (interval*)current_interval_set->GetIntervals()->At(iint + 1) : nullptr;
759 // find the corresponding painters
760 KVPIDIntervalPainter* left_painter{nullptr}, *right_painter{nullptr};
761 TIter next_painter(&fItvPaint);
762 KVPIDIntervalPainter* pidpnt;
763 while ((pidpnt = (KVPIDIntervalPainter*)next_painter())) {
764 if (pidpnt->GetInterval() == left_interval) left_painter = pidpnt;
765 else if (pidpnt->GetInterval() == right_interval) right_painter = pidpnt;
766 }
767
768 // give a different colour to each interval
770 auto cstep = TColor::GetPalette().GetSize() / (nitv + 1);
771
772 KVPIDIntervalPainter* dummy = new KVPIDIntervalPainter(itv, fLinearHisto, TColor::GetPalette()[cstep * (iint + 1)],
773 left_painter);
774 // set up links between painters
775 if (right_painter) {
776 right_painter->set_left_interval(dummy);
777 dummy->set_right_interval(right_painter);
778 }
779 fPad->cd();
780 dummy->Draw();
781 dummy->Connect("IntMod()", "KVItvFinderDialog", this, "UpdatePIDList()");
782 dummy->SetDisplayLabel(1);
783 dummy->SetCanvas(fCanvas);
784 fItvPaint.Add(dummy);
785
787
788 fItvPaint.Execute("Update", "");
789
790 fCanvas->Modified();
791 fCanvas->Update();
792}
793
794
795
797
799{
800 std::unique_ptr<TList> list(fIntervalSetListView->GetSelectedObjects());
801 if (!list->GetSize() || list->GetSize() > 1) {
802 current_interval_set = nullptr;
803 return;
804 }
805
806 current_interval_set = (interval_set*)list->At(0);
807
808 int aa = 0;
809 int iint = 0;
810
811 // try to guess mass from position (PID)
812 // typical isotope separation in PID is 0.12 (e.g. for carbon isotopes)
813 // assume that PID=z means A=2*Z
814 auto aa_guessstimate = TMath::Nint(current_interval_set->GetZ() * 2 + (pid - current_interval_set->GetZ()) / 0.12);
815//Info("NewINt","pid = %f guess a=%d",pid,aa_guessstimate);
817 aa = aa_guessstimate;
818 iint = 0;
819 }
820 else if (pid < ((interval*)current_interval_set->GetIntervals()->First())->GetPID()) { // to left of all others
821 aa = ((interval*)current_interval_set->GetIntervals()->First())->GetA() - 1;
822 // NO MORE : use guesstimate as long as it is smaller than A of previously defined interval with largest PID
823 // NOW : use 'aa_guessstimate' only for first interval
824 //Info("NewInt","before first interval, with a=%d",aa+1);
825// if (aa_guessstimate < aa + 1) aa = aa_guessstimate;
826 iint = 0;
827 }
828 else if (pid > ((interval*)current_interval_set->GetIntervals()->Last())->GetPID()) { // to right of all others
829 aa = ((interval*)current_interval_set->GetIntervals()->Last())->GetA() + 1;
830 // NO MORE : use guesstimate as long as it is larger than A of previously defined interval with smallest PID
831 // NOW : use 'aa_guessstimate' only for first interval
832 //Info("NewInt","after last interval, with a=%d",aa-1);
833// if (aa_guessstimate > aa - 1) aa = aa_guessstimate;
835 }
836 else {
837 // look for intervals between which the new one is places
838 for (int ii = 1; ii < current_interval_set->GetNPID(); ii++) {
839 if (pid > ((interval*)current_interval_set->GetIntervals()->At(ii - 1))->GetPID()
840 && pid < ((interval*)current_interval_set->GetIntervals()->At(ii))->GetPID()) {
841 aa = ((interval*)current_interval_set->GetIntervals()->At(ii - 1))->GetA() + 1;
842 // use guesstimate if it is in between masses of adjacent intervals (in terms of PID)
843 if ((aa_guessstimate > (aa - 1)) &&
844 (aa_guessstimate < ((interval*)current_interval_set->GetIntervals()->At(ii))->GetA()))
845 aa = aa_guessstimate;
846 iint = ii;
847 break;
848 }
849 }
850 }
851
852 interval* itv = new interval(current_interval_set->GetZ(), aa, pid, pid - 0.05, pid + 0.05);
854
855 // find intervals which are now left (smaller mass) and right (higher mass) than this one
856 interval* left_interval = iint > 0 ? (interval*)current_interval_set->GetIntervals()->At(iint - 1) : nullptr;
857 interval* right_interval = iint < current_interval_set->GetIntervals()->GetEntries() - 1 ? (interval*)current_interval_set->GetIntervals()->At(iint + 1) : nullptr;
858 // find the corresponding painters
859 KVPIDIntervalPainter* left_painter{nullptr}, *right_painter{nullptr};
860 TIter next_painter(&fItvPaint);
861 KVPIDIntervalPainter* pidpnt;
862 while ((pidpnt = (KVPIDIntervalPainter*)next_painter())) {
863 if (pidpnt->GetInterval() == left_interval) left_painter = pidpnt;
864 else if (pidpnt->GetInterval() == right_interval) right_painter = pidpnt;
865 }
866
867 // give a different colour to each interval
869 auto cstep = TColor::GetPalette().GetSize() / (nitv + 1);
870
871 KVPIDIntervalPainter* dummy = new KVPIDIntervalPainter(itv, fLinearHisto, TColor::GetPalette()[cstep * (iint + 1)],
872 left_painter);
873 // set up links between painters
874 if (right_painter) {
875 right_painter->set_left_interval(dummy);
876 dummy->set_right_interval(right_painter);
877 }
878 fPad->cd();
879 dummy->Draw();
880 dummy->Connect("IntMod()", "KVItvFinderDialog", this, "UpdatePIDList()");
881 dummy->SetDisplayLabel(1);
882 dummy->SetCanvas(fCanvas);
883 fItvPaint.Add(dummy);
884
886
887 fItvPaint.Execute("Update", "");
888
889 fCanvas->Modified();
890 fCanvas->Update();
891
892}
893
894
895
897
899{
900 if (fGrid->GetIntervalSets()->GetSize() == 0) fNextIntervalZ = 1;
901 else fNextIntervalZ = ((interval_set*)fGrid->GetIntervalSets()->Last())->GetZ() + 1;
902 // KVBase::OpenContextMenu("SetNextIntervalZ()",this);
904 UpdateLists();
905}
906
907
908
910
912{
914 itvs->GetIntervals()->Remove(itv);
916 if (remove_fit) {
917 // remove any fits from pad corresponding to intervals
918 KVMultiGaussIsotopeFit::UnDrawGaussian(itvs->GetZ(), itv->GetA(), fPad);
919 }
920}
921
922
923
925
927{
928 std::unique_ptr<TList> list(fIntervalSetListView->GetSelectedObjects());
929 Int_t nSelected = list->GetSize();
930 current_interval_set = nullptr;
931
932 if (nSelected == 1) {
933 current_interval_set = (interval_set*)list->At(0);
935 nSelected = list->GetSize();
936 if (nSelected >= 1) {
937 for (int ii = 0; ii < nSelected; ii++) {
938 interval* itv = (interval*) list->At(ii);
940 }
942 fCanvas->Modified();
943 fCanvas->Update();
944 }
946 }
947 else if (nSelected > 1) {
948 for (int ii = 0; ii < nSelected; ii++) {
949 auto itvs = (interval_set*)list->At(ii);
950 ClearInterval(itvs);
951 }
952 }
953}
954
955
956
958
960{
961 std::unique_ptr<TList> list(fIntervalSetListView->GetSelectedObjects());
962 Int_t nSelected = list->GetSize();
963
964 current_interval_set = nullptr;
965 if (nSelected == 1) {
966 current_interval_set = (interval_set*)list->At(0);
967
969 nSelected = list->GetSize();
970
971 if (nSelected == 1) {
972 interval* itv = (interval*) list->At(0);
973 itv->SetA(itv->GetA() + 1);
974 fItvPaint.Execute("Update", "");
975 // change the name of any gaussian in the pad associated with this isotope
976 auto gfit = (TNamed*)fPad->GetPrimitive(KVMultiGaussIsotopeFit::get_name_of_isotope_gaussian(itv->GetZ(), itv->GetA() - 1));
977 if (gfit) gfit->SetName(KVMultiGaussIsotopeFit::get_name_of_isotope_gaussian(itv->GetZ(), itv->GetA()));
978 fCanvas->Modified();
979 fCanvas->Update();
980 }
981 else {
982 TIter next_itv(list.get());
983 interval* itv;
984 while ((itv = (interval*)next_itv())) {
985 itv->SetA(itv->GetA() + 1);
986 // change the name of any gaussian in the pad associated with this isotope
987 auto gfit = (TNamed*)fPad->GetPrimitive(KVMultiGaussIsotopeFit::get_name_of_isotope_gaussian(itv->GetZ(), itv->GetA() - 1));
988 if (gfit) gfit->SetName(KVMultiGaussIsotopeFit::get_name_of_isotope_gaussian(itv->GetZ(), itv->GetA()));
989 }
990 fItvPaint.Execute("Update", "");
991 fCanvas->Modified();
992 fCanvas->Update();
993 }
994 }
995}
996
997
998
1000
1002{
1003 std::unique_ptr<TList> list(fIntervalSetListView->GetSelectedObjects());
1004 Int_t nSelected = list->GetSize();
1005
1006 current_interval_set = nullptr;
1007 if (nSelected == 1) {
1008 current_interval_set = (interval_set*)list->At(0);
1010 nSelected = list->GetSize();
1011
1012 if (nSelected == 1) {
1013 interval* itv = (interval*) list->At(0);
1014 itv->SetA(itv->GetA() - 1);
1015 fItvPaint.Execute("Update", "");
1016 // change the name of any gaussian in the pad associated with this isotope
1017 auto gfit = (TNamed*)fPad->GetPrimitive(KVMultiGaussIsotopeFit::get_name_of_isotope_gaussian(itv->GetZ(), itv->GetA() + 1));
1018 if (gfit) gfit->SetName(KVMultiGaussIsotopeFit::get_name_of_isotope_gaussian(itv->GetZ(), itv->GetA()));
1019 fCanvas->Modified();
1020 fCanvas->Update();
1021 }
1022 else {
1023 TIter next_itv(list.get());
1024 interval* itv;
1025 while ((itv = (interval*)next_itv())) {
1026 itv->SetA(itv->GetA() - 1);
1027 // change the name of any gaussian in the pad associated with this isotope
1028 auto gfit = (TNamed*)fPad->GetPrimitive(KVMultiGaussIsotopeFit::get_name_of_isotope_gaussian(itv->GetZ(), itv->GetA() + 1));
1029 if (gfit) gfit->SetName(KVMultiGaussIsotopeFit::get_name_of_isotope_gaussian(itv->GetZ(), itv->GetA()));
1030 }
1031 fItvPaint.Execute("Update", "");
1032 fCanvas->Modified();
1033 fCanvas->Update();
1034 }
1035 }
1036}
1037
1038
1039
1041
1043{
1044 fIntervalSetListView->Display(((KVIDZAFromZGrid*)fGrid)->GetIntervalSets());
1045 std::unique_ptr<TList> list(fIntervalSetListView->GetSelectedObjects());
1046 Int_t nSelected = list->GetSize();
1047 interval_set* itvs = 0;
1048 if (nSelected == 1) {
1049 current_interval_set = (interval_set*)list->At(0);
1051 }
1052 else {
1053 current_interval_set = nullptr;
1055 }
1056}
1057
1058
1059
1062
1064{
1065 //fGrid->SetOnlyZId(0);
1066 fGrid->Initialize();
1067 ExportToGrid();
1068
1070
1071 fIntervalSetListView->Display(((KVIDZAFromZGrid*)fGrid)->GetIntervalSets());
1072 current_interval_set = nullptr;
1074
1075 fItvPaint.Clear();
1076 DrawIntervals();
1077
1078 new KVTestIDGridDialog(gClient->GetDefaultRoot(), gClient->GetDefaultRoot(), 10, 10, fGrid, fHisto);
1079}
1080
1081
1082
1084
1086{
1088 fCanvas->Modified();
1089 fCanvas->Update();
1090}
1091
1092
1093
1095
1097{
1098 fItvPaint.Execute("SetDisplayLabel", "0");
1099 current_interval_set = nullptr;
1101 fCanvas->Modified();
1102 fCanvas->Update();
1103}
1104
1105
1106
1117
1119{
1120 // fit the PID spectrum for the currently selected interval set (Z).
1121 //
1122 // for an interval with N isotopes, we use N gaussians plus an exponential (decreasing)
1123 // background. each gaussian has the same width. the centroids of the gaussians are first
1124 // fixed to the positions of the PID markers, the intensity and width of the peaks
1125 // (plus the background) are fitted.
1126 // then another fit is performed without constraining the centroids.
1127 //
1128 // finally the PID markers (PID of each interval) are modified according to the fitted centroid positions.
1129
1130 if (!current_interval_set) return;
1131
1132 KVNumberList alist;
1133 std::vector<double> pidlist;
1135 interval* intvl = nullptr;
1136 while ((intvl = (interval*)nxt_int())) {
1137 alist.Add(intvl->GetA());
1138 pidlist.push_back(intvl->GetPID());
1139 }
1142 alist, pidlist);
1143
1144 // check user fit parameters
1145 if (mass_fit_parameters.GetBoolValue("Limit range of fit")) {
1146 // if the user's range is not valid for the current interval set, we ignore it
1147 if (mass_fit_parameters.GetDoubleValue("PID min for fit") >= current_interval_set->GetZ() - 0.5
1148 && mass_fit_parameters.GetDoubleValue("PID max for fit") <= current_interval_set->GetZ() + 0.5)
1149 fitfunc.SetFitRange(mass_fit_parameters.GetDoubleValue("PID min for fit"),
1150 mass_fit_parameters.GetDoubleValue("PID max for fit"));
1151
1152 }
1153 fitfunc.SetSigmaLimits(mass_fit_parameters.GetDoubleValue("Minimum #sigma"),
1154 mass_fit_parameters.GetDoubleValue("Maximum #sigma"));
1155
1156 fLinearHisto->Fit(&fitfunc, "NR");
1157
1158 // now release the centroids
1159 fitfunc.ReleaseCentroids();
1160
1161 fLinearHisto->Fit(&fitfunc, "NRME");
1162
1163 // remove any previous fit from pad
1164 fitfunc.UnDraw();
1165 // mop up any stray gaussians (from intervals which have been removed)
1166 KVMultiGaussIsotopeFit::UnDrawAnyGaussian(current_interval_set->GetZ(), fPad);
1167
1168 // draw fit with individual gaussians
1169 fitfunc.DrawFitWithGaussians("same");
1170
1171 // deactivate intervals for fitted masses
1172 std::unique_ptr<KVSeqCollection> tmp(fItvPaint.GetSubListWithMethod(Form("%d", current_interval_set->GetZ()), "GetZ"));
1173 tmp->Execute("DeactivateIntervals", "");
1174
1175 // set interval limits according to regions of most probable mass
1176 int most_prob_A = 0;
1177 nxt_int.Reset();
1178 // minimum probability for which isotopes are taken into account
1179 double min_proba = mass_fit_parameters.GetDoubleValue("Minimum probability [%]") / 100.;
1180 double delta_pid = 0.001;
1181 TList accepted_intervals;//any intervals not in this list at the end of the procedure will be removed
1182 for (double pid = fitfunc.GetPIDmin() ; pid <= fitfunc.GetPIDmax(); pid += delta_pid) {
1183 double proba;
1184 auto Amax = fitfunc.GetMostProbableA(pid, proba);
1185 if (proba > min_proba) {
1186 if (most_prob_A) {
1187 if (Amax > most_prob_A) {
1188 //std::cout << pid << " " << Amax << " " << proba << std::endl;
1189 //std::cout << "got PIDmax for A=" << intvl->GetA() << std::endl;
1190 intvl->SetPIDmax(pid - delta_pid);
1191 most_prob_A = Amax;
1192 intvl = (interval*)nxt_int();
1193 while (intvl->GetA() < most_prob_A) {
1194 intvl = (interval*)nxt_int();
1195 }
1196 accepted_intervals.Add(intvl);
1197 intvl->SetPIDmin(pid);
1198 //std::cout << "got PIDmin for A=" << intvl->GetA() << std::endl;
1199 }
1200 }
1201 else {
1202 most_prob_A = Amax;
1203 intvl = (interval*)nxt_int();
1204 while (intvl->GetA() < most_prob_A) {
1205 intvl = (interval*)nxt_int();
1206 }
1207 accepted_intervals.Add(intvl);
1208 intvl->SetPIDmin(pid);
1209 //std::cout << pid << " " << Amax << " " << proba << std::endl;
1210 //std::cout << "got PIDmin for A=" << intvl->GetA() << std::endl;
1211 }
1212 }
1213 else if (most_prob_A) {
1214 intvl->SetPIDmax(pid - delta_pid);
1215 //std::cout << pid << " " << Amax << " " << proba << std::endl;
1216 //std::cout << "got PIDmax for A=" << intvl->GetA() << std::endl;
1217 most_prob_A = 0;
1218 }
1219 }
1220 nxt_int.Reset();
1221// TList intervals_to_remove;
1222// while ((intvl = (interval*)nxt_int())) {
1223// if (!accepted_intervals.FindObject(intvl)) intervals_to_remove.Add(intvl);
1224// }
1225// if (intervals_to_remove.GetEntries()) {
1226// // remove intervals below minimum probability (leave gaussians on display)
1227// TIter it_rem(&intervals_to_remove);
1228// while ((intvl = (interval*)it_rem())) remove_interval_from_interval_set(current_interval_set, intvl, false);
1229// }
1230// intervals_to_remove.Clear();
1231 int ig(1);
1232 // update PID positions from fitted centroids
1233 nxt_int.Reset();
1234 KVNumberList remaining_gaussians, remaining_alist;
1235 auto vec_alist = alist.GetArray();
1236 while ((intvl = (interval*)nxt_int())) {
1237 // in case we removed some peaks
1238 while (vec_alist[ig - 1] < intvl->GetA()) {
1239 ++ig;
1240 }
1241 intvl->SetPID(fitfunc.GetCentroid(ig));
1242 remaining_gaussians.Add(ig);
1243 remaining_alist.Add(intvl->GetA());
1244 ++ig;
1245 }
1246// if (intervals_to_remove.GetEntries()) {
1247// // remove intervals with centroids outside PID limits
1248// TIter it_rem(&intervals_to_remove);
1249// while ((intvl = (interval*)it_rem())) remove_interval_from_interval_set(current_interval_set, intvl, false);
1250// }
1251 UpdatePIDList();
1252 fItvPaint.Execute("Update", "");
1253
1254 fPad->Modified();
1255 fPad->Update();
1256
1257 // save results in grid parameters
1258 KVNumberList zlist;
1259 if (fGrid->GetParameters()->HasStringParameter("MASSFITS"))
1260 zlist.Set(fGrid->GetParameters()->GetStringValue("MASSFITS"));
1261 zlist.Add(current_interval_set->GetZ());
1262 fGrid->GetParameters()->SetValue("MASSFITS", zlist.AsString());
1263 TString massfit = Form("MASSFIT_%d", current_interval_set->GetZ());
1264 KVNameValueList fitparams;
1265 fitparams.SetValue("Ng", alist.GetNValues());
1266 fitparams.SetValue("Alist", alist.AsQuotedString());
1267 fitparams.SetValue("PIDmin", fitfunc.GetPIDmin());
1268 fitparams.SetValue("PIDmax", fitfunc.GetPIDmax());
1269 fitparams.SetValue("Bkg_cst", fitfunc.GetBackgroundConstant());
1270 fitparams.SetValue("Bkg_slp", fitfunc.GetBackgroundSlope());
1271 fitparams.SetValue("GausWid", fitfunc.GetGaussianWidth(0));
1272 fitparams.SetValue("PIDvsA_a0", fitfunc.GetPIDvsAfit_a0());
1273 fitparams.SetValue("PIDvsA_a1", fitfunc.GetPIDvsAfit_a1());
1274 fitparams.SetValue("PIDvsA_a2", fitfunc.GetPIDvsAfit_a2());
1275 for (ig = 1; ig <= alist.GetNValues(); ++ig) {
1276 fitparams.SetValue(Form("Norm_%d", ig), fitfunc.GetGaussianNorm(ig));
1277 }
1278 auto sanitized = fitparams.Get().ReplaceAll("=", ":");
1279 fGrid->GetParameters()->SetValue(massfit, sanitized);
1280}
1281
1282
1283
1286
1288{
1289 // Open dialog to modify parameters for multigauss mass fit
1290
1291 bool cancel = false;
1292 auto dialog = new KVNameValueListGUI(fMain, &mass_fit_parameters, &cancel);
1293 dialog->EnableDependingOnBool("PID min for fit", "Limit range of fit");
1294 dialog->EnableDependingOnBool("PID max for fit", "Limit range of fit");
1295 dialog->DisplayDialog();
1296}
1297
1298
1299
1302
1304{
1305 // Remove fit of currently selected interval set from pad
1306
1307 if (!current_interval_set) return;
1308
1309 std::vector<int> alist;
1311 interval* intvl = nullptr;
1312 while ((intvl = (interval*)nxt_int())) {
1313 alist.push_back(intvl->GetA());
1314 }
1316
1317 fitfunc.UnDraw(fPad);
1318 // mop up any stray gaussians (from intervals which have been removed)
1319 KVMultiGaussIsotopeFit::UnDrawAnyGaussian(current_interval_set->GetZ(), fPad);
1320
1321 fPad->Modified();
1322 fPad->Update();
1323}
1324
1325
1326
1328
1330{
1331
1332 if (!fCanvas) return;
1333 if (fCanvas->GetEvent() == kMouseMotion) return;
1334
1335 switch (fCanvas->GetEvent()) {
1336 case kButton2Up:
1337 FitIsotopes();
1338 break;
1339 case kButton1Double:
1341 break;
1342 case kButton1Shift:
1344 break;
1345 }
1346
1347}
1348
1349
1350
1352
1354{
1355 std::cout << "Mouse shortcuts : Wheel-click Fit intervals of current Z" << std::endl;
1356 std::cout << " Double-click Set/Unset log scale on Y axis" << std::endl;
1357 std::cout << " Shift-click Add an interval where clicked" << std::endl;
1358}
1359
1360
1361
1363
1365{
1366 interval_set* itvs = fGrid->GetIntervalSet(zz);
1367 if (!itvs) {
1369 fGrid->GetIntervalSets()->Add(itvs);
1370 }
1371 else ClearInterval(itvs);
1372
1373
1374 if (zz == 1) fLinearHisto->SetAxisRange(0.9, zz + 0.5, "X");
1375 else fLinearHisto->SetAxisRange(zz - 0.5, zz + 0.5, "X");
1376
1377 int nfound = fSpectrum.Search(fLinearHisto, fSig, "goff", ((zz == 2) ? 0.1 * fRat : fRat));
1378
1379#if ROOT_VERSION_CODE > ROOT_VERSION(5,99,01)
1380 Double_t* xpeaks = fSpectrum.GetPositionX();
1381// Double_t* ypeaks = fSpectrum.GetPositionY();
1382#else
1383 Float_t* xpeaks = fSpectrum.GetPositionX();
1384// Float_t* ypeaks = fSpectrum.GetPositionY();
1385#endif
1386
1387 nfound = TMath::Min(fNpeaks[zz - 1], nfound);
1388
1389 int idx[nfound];
1390 TMath::Sort(nfound, xpeaks, idx, 0);
1391
1392 int zrefs[] = {1, 4, 7, 9, 11, 12, 15, 16, 19, 21, 23, 25, 27, 29, 31, 34, 35, 38, 40, 42, 44, 47, 49, 51, 53};
1393 int zref = zrefs[zz - 1];
1394
1395 int idref = -1;
1396 for (int p = 0; p < nfound; p++) {
1397 if (abs(xpeaks[idx[p]] - xpeaks[0]) < .0001) idref = p;
1398 }
1399 Info("FindPIDIntervals", "Z=%d : idref = %d ", zz, idref);
1400
1401 for (int p = 0; p < nfound; p++) {
1402// Info("FindPIDIntervals","Z=%d : (%.2lf %.2lf) (%d %d) ",zz,xpeaks[p],ypeaks[p],idx[p],p);
1403 double pid = xpeaks[idx[p]];//ff->GetParameter(3 * ii + 1);
1404 itvs->add(zref + (p - idref), pid, pid - 0.05, pid + 0.05);
1405 }
1406
1407
1408}
1409
1410
1411
1413
1415{
1416 Double_t result = 0;
1417 int np = par[0];
1418 for (Int_t p = 0; p < np; p++) {
1419 Double_t norm = par[3 * p + 3];
1420 Double_t mean = par[3 * p + 1];
1421 Double_t sigma = par[3 * p + 2];
1422 result += norm * TMath::Gaus(x[0], mean, sigma);
1423 }
1424 return result;
1425}
1426
1427
1429
1431{
1432
1433 if (zmin < 0) zmin = ((KVIDentifier*)fGrid->GetIdentifiers()->First())->GetZ();
1434 if (zmax < 0) zmax = ((KVIDentifier*)fGrid->GetIdentifiers()->Last())->GetZ();
1435
1436 for (int z = zmin; z <= zmax; z++) FindPIDIntervals(z);
1437
1438}
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
kMouseMotion
kButton1Double
kButton1Shift
kButton2Up
int Int_t
kVerticalFrame
kHorizontalFrame
float Float_t
double Axis_t
constexpr Bool_t kFALSE
double Double_t
double Stat_t
kGray
kBlack
#define gClient
kFDSave
kDeepCleanup
kLHintsExpandY
kLHintsTop
kLHintsExpandX
kMBNo
kMBYes
kMBIconExclamation
kTextCenterX
kTextLeft
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t np
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
#define gROOT
R__EXTERN TRandom * gRandom
char * Form(const char *fmt,...)
char * StrDup(const char *str)
R__EXTERN TStyle * gStyle
R__EXTERN TSystem * gSystem
const KVNameValueList * GetParameters() const
Definition KVIDGraph.h:288
static void SetAutoAdd(Bool_t yes=kTRUE)
Definition KVIDGraph.h:100
static Bool_t GetAutoAdd()
Definition KVIDGraph.h:106
const KVList * GetIdentifiers() const
Definition KVIDGraph.h:298
const Char_t * GetName() const
void WriteAsciiFile(const Char_t *filename)
Open, write and close ascii file containing this grid.
Hybrid charge & mass identification grid.
KVList * GetIntervalSets()
interval_set * GetIntervalSet(int zint) const
void SetOnlyZId(Bool_t=kTRUE)
Base class for graphical cuts used in particle identification.
virtual Double_t GetPID() const
Full result of one attempted particle identification.
void Clear(Option_t *opt="")
Reset to initial values.
Double_t PID
= "real" Z if Zident==kTRUE and Aident==kFALSE, "real" A if Zident==Aident==kTRUE
Bool_t HasFlag(std::string grid_name, TString flag)
GUI for finding/fixing mass identification intervals.
KVListView * fIntervalListView
void DrawInterval(interval_set *itvs, bool label=0)
KVIDZAFromZGrid * fGrid
TGTransientFrame * fMain
void ClearInterval(interval_set *itvs)
void ProcessIdentification(Int_t zmin=-1, Int_t zmax=-1)
void AddInterval(double pid)
void delete_painter_from_painter_list(KVPIDIntervalPainter *)
void Identify()
KVBase::OpenContextMenu("Identify(double,double)",this);.
void SetFitParameters()
Open dialog to modify parameters for multigauss mass fit.
interval_set * current_interval_set
void FindPIDIntervals(Int_t zz)
KVItvFinderDialog(KVIDZAFromZGrid *gg, TH2 *hh)
KVListView * fIntervalSetListView
static KVNameValueList mass_fit_parameters
for user control of multi-gaussian fit
void RemoveFit()
Remove fit of currently selected interval set from pad.
void ExportToGrid()
Write all PID intervals in grid parameters "PIDRANGE", "PIDRANGE%d", etc.
void TestIdent()
fGrid->SetOnlyZId(0);
void LinearizeHisto(int nbins)
Double_t fpeaks(Double_t *x, Double_t *par)
void remove_interval_from_interval_set(interval_set *itvs, interval *itv, bool remove_fit=true)
KVPIDIntervalPainter * last_drawn_interval
void ZoomOnCanvas()
Display the interval set for a given Z when the user double clicks on it.
Enhanced version of ROOT TGListView widget.
Definition KVListView.h:146
virtual void SetDataColumns(Int_t ncolumns)
void SetDoubleClickAction(const char *receiver_class, void *receiver, const char *slot)
virtual void Display(const TCollection *l)
Definition KVListView.h:173
virtual void RemoveAll()
Definition KVListView.h:190
TObject * GetLastSelectedObject() const
Definition KVListView.h:231
void AllowContextMenu(Bool_t on=kTRUE)
Definition KVListView.h:283
TList * GetSelectedObjects() const
Definition KVListView.h:245
virtual void SetDataColumn(Int_t index, const Char_t *name, const Char_t *method="", Int_t mode=kTextCenterX)
Extended TList class which owns its objects by default.
Definition KVList.h:28
Function for fitting PID mass spectra.
GUI for setting KVNameValueList parameters.
Handles lists of named parameters with different types, a list of KVNamedParameter objects.
Double_t GetDoubleValue(const Char_t *name) const
void SetValue(const Char_t *name, value_type value)
void RemoveParameter(const Char_t *name)
Bool_t HasStringParameter(const Char_t *name) const
Bool_t GetBoolValue(const Char_t *name) const
KVString Get() const
const Char_t * GetStringValue(const Char_t *name) const
bool Set(const KVString &)
Bool_t HasParameter(const Char_t *name) const
TString GetTStringValue(const Char_t *name) const
Strings used to represent a set of ranges of values.
const Char_t * AsQuotedString() const
const Char_t * AsString(Int_t maxchars=0) const
void Remove(Int_t)
Remove value 'n' from the list.
Int_t GetNValues() const
void Add(Int_t)
Add value 'n' to the list.
void Set(const TString &l)
IntArray GetArray() const
Graphical representation of a PID interval in the KVIDZAFromZGrid mass assignation GUI.
void SetCanvas(TCanvas *cc)
void Draw(Option_t *option="")
void SetDisplayLabel(bool dis=true)
void HighLight(bool hi=true)
void set_right_interval(KVPIDIntervalPainter *i)
interval * GetInterval() const
virtual TObject * FindObject(const char *name) const
KVSeqCollection * GetSubListWithMethod(const Char_t *retvalue, const Char_t *method) const
virtual void Clear(Option_t *option="")
virtual Int_t GetSize() const
virtual TObject * Last() const
virtual void Execute(const char *method, const char *params, Int_t *error=0)
virtual TObject * First() const
virtual TObject * At(Int_t idx) const
virtual void Add(TObject *obj)
virtual void AddAt(TObject *obj, Int_t idx)
virtual TObject * Remove(TObject *obj)
Remove object from list.
Extension of ROOT TString class which allows backwards compatibility with ROOT v3....
Definition KVString.h:73
GUI for testing identification grids.
Int_t GetSize() const
virtual void SetFillColor(Color_t fcolor)
virtual void SetLineColor(Color_t lcolor)
virtual void SetMarkerStyle(Style_t mstyle=1)
virtual void SetBottomMargin(Float_t bottommargin)
virtual void SetLeftMargin(Float_t leftmargin)
virtual void SetRightMargin(Float_t rightmargin)
virtual void SetTopMargin(Float_t topmargin)
virtual void UnZoom()
virtual void SetRangeUser(Double_t ufirst, Double_t ulast)
Int_t GetEventX() const override
TVirtualPad * cd(Int_t subpadnumber=0) override
void Update() override
Int_t GetEvent() const override
virtual Int_t GetEntries() const
static const TArrayI & GetPalette()
TGDimension GetDefaultSize() const override
virtual void AddFrame(TGFrame *f, TGLayoutHints *l=nullptr)
void MapSubwindows() override
void SetCleanup(Int_t mode=kLocalCleanup) override
char * fFilename
const char ** fFileTypes
char * fIniDir
virtual void Resize(TGDimension size)
void MapWindow() override
void DontCallClose()
void SetWindowName(const char *name=nullptr) override
virtual TGButton * AddButton(const TGWindow *w, TGPictureButton *button, Int_t spacing=0)
virtual void CenterOnParent(Bool_t croot=kTRUE, EPlacement pos=kCenter)
virtual void RequestFocus()
virtual Int_t GetNbinsY() const
TAxis * GetXaxis()
virtual TFitResultPtr Fit(const char *formula, Option_t *option="", Option_t *goption="", Double_t xmin=0, Double_t xmax=0)
virtual Int_t GetNbinsX() const
TAxis * GetYaxis()
void Draw(Option_t *option="") override
virtual Int_t Fill(const char *name, Double_t w)
virtual void SetAxisRange(Double_t xmin, Double_t xmax, Option_t *axis="X")
virtual Double_t GetBinContent(Int_t bin) const
void Reset()
void Add(TObject *obj) override
TObject * Last() const override
const char * GetName() const override
static TClass * Class()
virtual void Execute(const char *method, const char *params, Int_t *error=nullptr)
void AddExec(const char *name, const char *command) override
Double_t AbsPixeltoX(Int_t px) override
void Modified(Bool_t flag=1) override
void SetLogy(Int_t value=1) override
Int_t GetLogy() const override
Bool_t Connect(const char *signal, const char *receiver_class, void *receiver, const char *slot)
virtual Double_t Uniform(Double_t x1, Double_t x2)
void AdoptCanvas(TCanvas *c)
TCanvas * GetCanvas() const
Int_t GetCanvasWindowId() const
virtual Int_t Search(const TH1 *hist, Double_t sigma=2, Option_t *option="", Double_t threshold=0.05)
Double_t * GetPositionX() const
Ssiz_t Length() const
const char * Data() const
TString & Remove(EStripType s, char c)
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
TString & ReplaceAll(const char *s1, const char *s2)
void SetOptTitle(Int_t tit=1)
void SetOptStat(Int_t stat=1)
virtual char * ExpandPathName(const char *path)
virtual void Modified(Bool_t flag=1)=0
virtual TList * GetListOfPrimitives() const=0
virtual TVirtualPad * cd(Int_t subpadnumber=0)=0
virtual void Update()=0
virtual TObject * WaitPrimitive(const char *pname="", const char *emode="")=0
virtual TObject * GetPrimitive(const char *name) const=0
void add(int aa, double pid, double pidmin=-1., double pidmax=-1.)
KVList * GetIntervals()
bool SetPID(double pid)
double GetPID()
double GetPIDmin()
void SetPIDmin(double pidmin)
void SetA(int aa)
double GetPIDmax()
void SetPIDmax(double pidmax)
RVec< PromoteType< T > > abs(const RVec< T > &v)
const Double_t sigma
Double_t y[n]
Double_t x[n]
void Info(const char *location, const char *fmt,...)
Double_t Min(Double_t a, Double_t b)
Double_t Gaus(Double_t x, Double_t mean=0, Double_t sigma=1, Bool_t norm=kFALSE)
Int_t Nint(T x)
void Sort(Index n, const Element *a, Index *index, Bool_t down=kTRUE)
const char * fTipText
TGButton * fButton
Bool_t fStayDown
const char * fPixmap
ClassImp(TPyArg)