KaliVeda
Toolkit for HIC analysis
KVMultiDetArray.cpp
1 //Created by KVClassFactory on Tue Apr 16 09:45:50 2013
2 //Author: John Frankland,,,
3 
4 #include "KVMultiDetArray.h"
5 #include "KVDetector.h"
6 #include "KVDetectorEvent.h"
7 #include "KVReconstructedEvent.h"
8 #include "KVReconstructedNucleus.h"
9 #include "KVRList.h"
10 #include "KVNucleus.h"
11 #include "KVGroup.h"
12 #include "KVMaterial.h"
13 #include "KVTarget.h"
14 #include "KVIDTelescope.h"
15 #include <KVString.h>
16 #include <TObjString.h>
17 #include <TObjArray.h>
18 #include <KVIDGridManager.h>
19 #include <KVDataSetManager.h>
20 #include <KVUpDater.h>
21 #include "TPluginManager.h"
22 #include "KVDataSet.h"
23 #include "TGeoManager.h"
24 #include "KVHashList.h"
25 #include "KVNameValueList.h"
26 #include "KVUniqueNameList.h"
27 #include "KVIonRangeTable.h"
28 #include "KVRangeTableGeoNavigator.h"
29 #include <KVDataAnalyser.h>
30 #include <KVNamedParameter.h>
31 #include <KVCalibrator.h>
32 #include <KVDBParameterSet.h>
33 #ifdef WITH_RSQLITE
34 #include <KVSQLROOTIDGridManager.h>
35 #endif
36 #ifdef WITH_OPENGL
37 #include <TGLViewer.h>
38 #include <TVirtualPad.h>
39 #endif
40 #ifdef WITH_BUILTIN_GRU
41 #include "KVGANILDataReader.h"
42 #else
43 #include "KVRawDataReader.h"
44 #endif
45 #ifdef WITH_MFM
46 #include "KVMFMDataFileReader.h"
47 #include "MFMEbyedatFrame.h"
48 #endif
49 #ifdef WITH_PROTOBUF
50 #include "KVProtobufDataReader.h"
51 #endif
52 using namespace std;
53 
54 KVMultiDetArray* gMultiDetArray = nullptr;
55 
61 
63 
64 
65 
69  : KVGeoStrucElement(), fTrajectories(kTRUE)
70 {
71  // Default constructor
72  init();
73  gMultiDetArray = this;
74 }
75 
76 
77 
80 
82  : KVGeoStrucElement(name, type), fTrajectories(kTRUE)
83 {
84  // Constructor with name and optional type
85  init();
86  gMultiDetArray = this;
87 }
88 
89 
90 
102 
104 {
105  //Basic initialisation called by constructor.
106  //Creates detectors list fDetectors,
107  //groups list fGroups, identification telescopes list
108  //fIDTelescopes
109  //
110  //The fGroups & fIDTelescopes lists contain objects owned by the multidetector array,
111  //but which may be deleted by other objects (or as a result of the deletion of other
112  //objects: i.e. if all the detectors in a group are deleted, the group itself is destroyed).
113  //We use the ROOT automatic garbage collection to make sure that any object deleted
114  //elsewhere is removed automatically from these lists.
115 
116  fIDTelescopes = new KVHashList();
117  fIDTelescopes->SetOwner(kTRUE); // owns its objects
119 
120  fHitGroups = 0;
121 
122  fTarget = 0;
123  fCurrentRun = 0;
124 
126  fCalibStatusDets = 0;
127  fSimMode = kFALSE;
128 
130 
131  fUpDater = 0;
132 
133  if (!gIDGridManager) new KVIDGridManager;
134 
135  // all trajectories belong to us
137 
138  //all detectors belong to us
140 
141  fRawDataReader = nullptr;
142  fHandledRawData = false;
143 
144  // any extra raw data signals created when reading data belong to us
146 }
147 
148 
149 
152 
154 {
155  //destroy (delete) the MDA and all the associated structure, detectors etc.
156 
158  //destroy all identification telescopes
161  delete fIDTelescopes;
162  }
163  fIDTelescopes = 0;
164 
165  if (gMultiDetArray == this)
166  gMultiDetArray = nullptr;
167 
168  if (fStatusIDTelescopes) {
170  delete fStatusIDTelescopes;
172  }
173  if (fCalibStatusDets) {
175  delete fCalibStatusDets;
176  fCalibStatusDets = 0;
177  }
178 
180 }
181 
182 
183 
184 
185 
187 
189 {
190 
191 
192 
193 }
194 
195 
196 
197 
221 
223 {
224  // Create one or more KVIDTelescope particle-identification objects from the two detectors
225  //
226  // The different ID telescopes are defined as 'Plugin' objects in the file $KVROOT/KVFiles/.kvrootrc :
227  // # The KVMultiDetArray::GetIDTelescopes(KVDetector*de, KVDetector*e) method uses these plugins to
228  // # create KVIDTelescope instances adapted to the specific array geometry and detector types.
229  // # For each pair of detectors we look for a plugin with one of the following names:
230  // # [name_of_dataset].array_name.de_detector_type[de detector thickness]-e_detector_type[de detector thickness]
231  // # Each characteristic in [] brackets may or may not be present in the name; first we test for names
232  // # with these characteristics, then all combinations where one or other of the characteristics is not present.
233  // # In addition, we first test all combinations which begin with [name_of_dataset].
234  // # The first plugin found in this order will be used.
235  // # In addition, if for one of the two detectors there is a plugin called
236  // # [name_of_dataset].array_name.de_detector_type[de detector thickness]
237  // # [name_of_dataset].array_name.e_detector_type[e detector thickness]
238  // # then we add also an instance of this 1-detector identification telescope.
239  //
240  // This method is called by DeduceIdentificationTelescopesFromGeometry
241  // in order to set up all ID telescopes of the array.
242  //
243  // \returns number of ID telescopes created
244  // \param[in] de node corresponding to \f$\Delta E\f$ detector; may be nullptr
245  // \param[in] e residual energy detector; always points to valid object
246 
247  assert(e);
248 
249  Int_t ntels = 0;
250 
251  if (fDataSet == "" && gDataSet) fDataSet = gDataSet->GetName();
252 
253  //look for ID telescopes starting from furthest from target
254  if (e->IsOK()) ntels += try_all_singleID_telescopes(e, list);
255  if (de && (de->GetDetector() != e)) {
256  if (e->IsOK() && de->GetDetector()->IsOK()) ntels += try_all_doubleID_telescopes(de->GetDetector(), e, list);
257  if (de->GetDetector()->IsOK()) ntels += try_all_singleID_telescopes(de->GetDetector(), list);
258  }
259 
260  return ntels;
261 }
262 
263 
264 
282 
284 {
285  // Attempt to find a plugin KVIDTelescope class for making a single-detector
286  // ID telescope from detector *d
287  // We look for plugins with the following signatures (uri):
288  //
289  // [array name].[type]
290  // [array_name].[type][thickness]
291  //
292  // where 'type' is the type of the detector in UPPER or lowercase letters
293  // 'thickness' is the nearest-integer thickness of the detector as returned by d->GetThickness()
294  // In addition, if a dataset is set (gDataSet!=nullptr) we try also for dataset-specific
295  // plugins:
296  //
297  // [dataset].[array name].[type]
298  // [dataset].[array name].[type][thickness]
299  //
300  // Returns number of generated telescopes
301 
302  TString uri = Form("%s.%s", GetName(), d->GetType());
303  Int_t ntels = 0;
304  if (!(ntels += try_upper_and_lower_singleIDtelescope(uri, d, l))) {
305  Int_t d_thick = TMath::Nint(d->GetThickness());
306  uri += d_thick;
307  ntels += try_upper_and_lower_singleIDtelescope(uri, d, l);
308  }
309  return ntels;
310 }
311 
312 
313 
314 
337 
339 {
340  // Attempt to find a plugin KVIDTelescope class for making an ID telescope from detectors de & e.
341  // We look for plugins with the following signatures (uri):
342  //
343  // [array name].[de-type]-[e-type]
344  // [array name].[de-type][thickness]-[e-type]
345  // [array name].[de-type]-[e-type][thickness]
346  // [array name].[de-type][thickness]-[e-type][thickness]
347  //
348  // where 'type' is the type of the detector in UPPER or lowercase letters
349  // 'thickness' is the nearest-integer thickness of the detector.
350  // In addition, if a dataset is set (gDataSet!=nullptr) we try also for dataset-specific
351  // plugins:
352  //
353  // [dataset].[array name].[de-type][thickness]-[e-type][thickness]
354  // [dataset].[array name].[de-type][thickness]-[e-type]
355  // [dataset].[array name].[de-type]-[e-type][thickness]
356  // [dataset].[array name].[de-type]-[e-type]
357  //
358  // if no plugin is found, we return a KVIDTelescope base class object
359  //
360  // Returns 1 (we always generate exactly one telescope)
361 
362  TString de_type = de->GetType();
363  TString e_type = e->GetType();
364  TString de_thick = Form("%d", TMath::Nint(de->GetThickness()));
365  TString e_thick = Form("%d", TMath::Nint(e->GetThickness()));
366 
367  TString uri = de_type + de_thick + "-" + e_type + e_thick;
368  uri.Prepend(Form("%s.", GetName()));
369  if (try_upper_and_lower_doubleIDtelescope(uri, de, e, l)) return 1;
370 
371  uri = de_type + de_thick + "-" + e_type;
372  uri.Prepend(Form("%s.", GetName()));
373  if (try_upper_and_lower_doubleIDtelescope(uri, de, e, l)) return 1;
374 
375  uri = de_type + "-" + e_type + e_thick;
376  uri.Prepend(Form("%s.", GetName()));
377  if (try_upper_and_lower_doubleIDtelescope(uri, de, e, l)) return 1;
378 
379  uri = de_type + "-" + e_type;
380  uri.Prepend(Form("%s.", GetName()));
381  if (try_upper_and_lower_doubleIDtelescope(uri, de, e, l)) return 1;
382 
383  // default id telescope object
384  KVIDTelescope* idt = new KVIDTelescope;
385  uri = de_type + "-" + e_type;
386  idt->SetLabel(uri);
387  // set type as "[DEtype]-[Etype]" where "[*type]" is type of DE/E detectors
388  idt->SetType(Form("%s-%s", de_type.Data(), e_type.Data()));
389  set_up_telescope(de, e, idt, l);
390 
391  return 1;
392 }
393 
394 
395 
403 
405 {
406  // Attempt to find a plugin KVIDTelescope class for making a single-detector
407  // ID telescope from detector *d with the given signature/uri
408  // Both original & all-upper-case versions of uri are tried.
409  // uri is tried both with & without prepended dataset name (if set)
410  // Returns true if successful (the new ID telescope will be added to internal
411  // list fIDTelescopes and also to TCollection* l)
412 
413  if (try_a_singleIDtelescope(uri, d, l)) return true;
414  uri.ToUpper();
415  return try_a_singleIDtelescope(uri, d, l);
416 }
417 
418 
419 
426 
428 {
429  // Attempt to find a plugin KVIDTelescope class for making an ID telescope with the given signature/uri
430  // Both original & all-upper-case versions of uri are tried.
431  // uri is tried both with & without prepended dataset name (if set)
432  // Returns true if successful (the new ID telescope will be added to internal
433  // list fIDTelescopes and also to TCollection* l)
434 
435  if (try_a_doubleIDtelescope(uri, de, e, l)) return true;
436  uri.ToUpper();
437  return try_a_doubleIDtelescope(uri, de, e, l);
438 }
439 
440 
441 
450 
452 {
453  // Attempt to find a plugin KVIDTelescope class for making a single-detector
454  // ID telescope from detector *d with the given signature/uri
455  // Both original & all-upper-case versions of uri are tried.
456  // uri is tried both with & without prepended dataset name (if set)
457  // Returns true if successful (the new ID telescope will be added to internal
458  // list fIDTelescopes and also to TCollection* l)
459 
460  // dataset-specific version takes precedence over default
461  TString duri = uri;
462  if (gDataSet) {
463  // try with dataset name
464  duri.Prepend(Form("%s.", fDataSet.Data()));
465  KVIDTelescope* idt;
466  if ((idt = KVIDTelescope::MakeIDTelescope(duri))) {
468  return true;
469  }
470  }
471 
472  // look for default version
473  KVIDTelescope* idt;
474  if ((idt = KVIDTelescope::MakeIDTelescope(uri))) {
476  return true;
477  }
478 
479  return false;
480 }
481 
482 
483 
490 
492 {
493  // Attempt to find a plugin KVIDTelescope class for making an ID telescope with the given signature/uri
494  // uri is tried both with & without prepended dataset name (if set)
495  // Returns true if successful (the new ID telescope will be added to internal
496  // list fIDTelescopes and also to TCollection* l)
497 
498  // dataset-specific version takes precedence over default
499  TString duri = uri;
500  if (gDataSet) {
501  // try with dataset name
502  duri.Prepend(Form("%s.", fDataSet.Data()));
503  KVIDTelescope* idt;
504  if ((idt = KVIDTelescope::MakeIDTelescope(duri))) {
505  set_up_telescope(de, e, idt, l);
506  return true;
507  }
508  }
509  // look for default version
510  KVIDTelescope* idt;
511  if ((idt = KVIDTelescope::MakeIDTelescope(uri))) {
512  set_up_telescope(de, e, idt, l);
513  return true;
514  }
515 
516  return false;
517 }
518 
519 
520 
523 
525 {
526  // Set up detectors in de-e identification telescope and add to fIDTelescopes and to l
527 
528  idt->AddDetector(de);
529  idt->AddDetector(e);
530  if (de->GetGroup()) {
531  idt->SetGroup(de->GetGroup());
532  }
533  else {
534  idt->SetGroup(e->GetGroup());
535  }
536  // if telescope already exists, we delete this new version and add a reference to
537  // the original into list l
539  if (p) {
540  l->Add(p);
541  delete idt;
542  }
543  else {
544  fIDTelescopes->Add(idt);
545  l->Add(idt);
546  }
547 }
548 
549 
550 
553 
555 {
556  // Set up detector in single-stage identification telescope and add to fIDTelescopes and to l
557 
558  idt->AddDetector(det);
559  idt->SetGroup(det->GetGroup());
560  // if telescope already exists, we delete this new version and add a reference to
561  // the original into list l
563  if (p) {
564  l->Add(p);
565  delete idt;
566  }
567  else {
568  fIDTelescopes->Add(idt);
569  l->Add(idt);
570  }
571 }
572 
573 
574 
575 
579 
581 {
582  //Number groups according to position in list fGroups and set fGr counter to the number
583  //of groups in the list
584  Int_t fGr = 0;
585  KVGroup* g = 0;
586  KVSeqCollection* fGroups = GetStructures()->GetSubListWithType("GROUP");
587  TIter next(fGroups);
588  while ((g = (KVGroup*) next())) {
589  g->SetNumber(++fGr);
590  }
591  delete fGroups;
592 }
593 
594 
595 
598 
600 {
601  //Return pointer to DeltaE-E ID Telescope with "name"
602 
604 }
605 
606 
607 
612 
614 {
615  //Reset all groups (lists of detected particles etc.)
616  //and detectors in groups (energy losses, ACQparams etc. etc.)
617  //and the target if there is one
618 
619  unique_ptr<KVSeqCollection> fGroups(GetStructures()->GetSubListWithType("GROUP"));
620 
621  TIter next(fGroups.get());
622  KVGroup* grp;
623  while ((grp = (KVGroup*) next())) {
624  grp->Reset();
625  }
626  if (GetTarget())
627  GetTarget()->Clear();
628 }
629 
630 
631 
632 
638 
640 {
641  // Sets up calibrators for all detectors with a defined calibration for run
642  // Set parameters for all detectors with links to table "Calibrations" for run
643  // If 'myname' is given, we look in "myname.Calibrations"
644 
645  //Reset all calibrators of all detectors first
646  TIter next(GetDetectors());
647  KVDetector* kvd;
648  while ((kvd = (KVDetector*) next())) kvd->RemoveCalibrators();
649 
650  TString tabname = (myname != "" ? Form("%s.Calibrations", myname.Data()) : "Calibrations");
651  //Info("SetCalibratorParameters", "For array %s in table %s", GetName(), tabname.Data());
652  KVRList* run_links = r->GetLinks(tabname);
653  if (run_links) Info("SetCalibratorParameters", "Found %d calibrations for this run", run_links->GetEntries());
654  else {
655 // Warning("SetCalibratorParameters", "Got no links for %s", tabname.Data());
656 // r->GetKeys()->ls();
657  return;
658  }
659  TIter nxt_link(run_links);
660  KVDBParameterSet* dbps;
661  while ((dbps = (KVDBParameterSet*)nxt_link())) {
662 
663  KVDetector* det = GetDetector(dbps->GetName());
664  if (!det) {
665  Warning("SetCalibratorParameters", "Got parameters for unknown detector: %s", dbps->GetName());
666  continue;
667  }
668 
669  KVNameValueList class_options;
670  KVString clop;
671  if (dbps->HasParameter("CalibOptions")) clop = dbps->GetStringParameter("CalibOptions");
672  if (clop != "") {
673  clop.Begin(",");
674  while (!clop.End()) {
675  KVString clopp = clop.Next(true);
676  clopp.Begin("=");
677  KVString par(clopp.Next(true)), val(clopp.Next(true));
678  class_options.SetValue(par, val);
679  }
680  }
682  cal->SetType(dbps->GetTitle());
683  if (clop != "") {
684  try {
685  cal->SetOptions(class_options);
686  }
687  catch (std::exception& e) {
688  Error("SetCalibratorParameters",
689  "Problem for %s [%s] : %s", det->GetName(), cal->GetType(), e.what());
690  delete cal;
691  continue;
692  }
693  }
694  cal->SetInputSignalType(dbps->GetStringParameter("SignalIn"));
695  cal->SetOutputSignalType(dbps->GetStringParameter("SignalOut"));
696  if (!det->AddCalibrator(cal, dbps->GetParameters())) {
697  // Calibrator invalid - probably input signal is not defined for detector
698  // N.B. 'cal' deleted by KVDetector::AddCalibrator
699  continue;
700  }
701 
702  if (dbps->GetParamNumber() > cal->GetNumberParams()) {
703  Warning("SetCalibratorParameters", "Wrong number of parameters (%d) for calibrator %s for detector %s : should be %d",
704  dbps->GetParamNumber(), dbps->GetTitle(), dbps->GetName(), cal->GetNumberParams());
705  dbps->Print();
706  continue;
707  }
708  for (int i = 0; i < dbps->GetParamNumber(); ++i) {
709  if (i >= cal->GetNumberParams())
710  cal->SetParameter(i, 0);
711  else
712  cal->SetParameter(i, dbps->GetParameter(i));
713  }
714  cal->SetStatus(true);
715  }
716 }
717 
718 
719 
737 
739 {
740  // Detector signals corresponding to raw data acquisition parameters are typically only created and
741  // added to detectors when some raw data has been read including those parameters.
742  //
743  // However, when reconstructing data, we may define identification matrices or calibration formulae
744  // which use these signals before starting to read data. Therefore we need to know beforehand what
745  // detector signals are expected to be available once data has been read.
746  //
747  // These are defined, according to detector types, by variables of the form
748  //
749  //~~~~
750  // [dataset].[array].[detector-type].ExpectedDetectorSignals: [comma-separated list of signal names]
751  //~~~~
752  //
753  // where [dataset] is optionally used to provide dataset-specific definitions.
754  //
755  // Here we add a detector signal of each expected type to each detector of the array
756 
757  TIter it(GetDetectors());
758  KVDetector* det;
759  while ((det = (KVDetector*)it())) {
760  auto s = KVBase::GetDataSetEnv<KVString>(fDataSet.Data(), Form("%s.%s.ExpectedDetectorSignals", GetName(), det->GetType()));
761  if (s.IsNull()) continue;
762  s.Begin(",");
763  while (!s.End()) {
764  det->AddDetectorSignal(s.Next(kTRUE));
765  }
766  }
767 }
768 
769 
770 
781 
783 {
784  // First step in event reconstruction based on current status of detectors in array.
785  // Fills the given KVDetectorEvent with the list of all groups which have fired.
786  // i.e. loop over all groups of the array and test whether KVGroup::Fired() returns true or false.
787  //
788  // If the list of fired detectors 'fired_dets' is given, then we use this list
789  // to find the associated groups. If not given, or if it is empty, we may use the internal fFiredDetectors list.
790  //
791  // Call method detev->Clear() before reading another event in order to reset all of the hit groups
792  // (including all detectors etc.) and emptying the list.
793 
794  if (!fired_dets || !fired_dets->GetEntries()) {
795  if (fFiredDetectors.GetEntries()) fired_dets = &fFiredDetectors;
796  }
797  if (fired_dets && fired_dets->GetEntries()) {
798  // list of fired detectorsgiven
799  TIter next_det(fired_dets);
800  KVDetector* det = 0;
801  KVGroup* grp = 0;
802  while ((det = (KVDetector*)next_det())) {
803  if ((grp = det->GetGroup()) && grp->GetParents()->Contains(this)) detev->AddGroup(grp);
804  }
805  }
806  else {
807  //loop over groups
808  unique_ptr<KVSeqCollection> fGroups(GetStructures()->GetSubListWithType("GROUP"));
809 
810  TIter next_grp(fGroups.get());
811  KVGroup* grp;
812  while ((grp = (KVGroup*) next_grp())) {
813  if (grp->Fired()) {
814  //if (!fHitGroups->FindObject(grp))
815  // grp->Print();
816  //add new group to list of hit groups
817  detev->AddGroup(grp);
818  }
819  }
820  }
821 }
822 
823 
824 
844 
846 {
847  //Static function which will create and 'Build' the multidetector object corresponding to
848  //a given run of dataset 'dataset_name'. Any previously existing multidetector will be
849  //deleted.
850  //
851  //We first activate the given dataset if not already done
852  //
853  //Multidetector arrays are defined as 'Plugin' objects :
854  //
855  //~~~
856  //Plugin.KVMultiDet: [dataset_name] [classname] [library] "[constructor]()"
857  //~~~
858  //
859  //The constructors/macros are always without arguments
860  //
861  //Dataset name is stored in fDataSet
862 
863  // store the run number (if given) so that if the dataset needs to update its database
864  // (which requires building the multidetector by calling MakeMultiDetector()) then it
865  // will build the correct geometry for the run
866  if (run > 0) fMakeMultiDetectorRunNumber = run;
868 
869  if(!gDataSetManager)
870  {
871  auto dsm = new KVDataSetManager;
872  dsm->Init();
873  }
874  if (gDataSetManager && (!gDataSet || (gDataSet != gDataSetManager->GetDataSet(dataset_name)))) {
875  printf("Info in <KVMultiDetArray::MakeMultiDetector>: Changing dataset\n");
876  gDataSetManager->GetDataSet(dataset_name)->cd();
877  }
878 
879  if (gMultiDetArray && gMultiDetArray->GetDataSet() != dataset_name) {
880  printf("Info in <KVMultiDetArray::MakeMultiDetector>: Deleting existing array %s\n", gMultiDetArray->GetName());
881  if (gIDGridManager) {
882  delete gIDGridManager;
883  gIDGridManager = nullptr;
884  }
885  delete gMultiDetArray;
886  gMultiDetArray = nullptr;
887  }
888 
889 
890  // Creation of database when dataset is selected for first time may
891  // include creation of multidetector array (by calling this method)
892  KVMultiDetArray* mda = nullptr;
893  if (!gMultiDetArray) {
894  TPluginHandler* ph;
895  if (!(ph = LoadPlugin(classname.Data(), dataset_name)))
896  return nullptr;
897 
898  //execute constructor/macro for multidetector - assumed without arguments
899  mda = (KVMultiDetArray*) ph->ExecPlugin(0);
900  mda->fDataSet = dataset_name;
901  mda->Build(run);
902  // set dataset-dependent lists of acceptable ID/E codes for reconstructed nuclei
903  auto codes = GetDataSetEnv<KVString>(dataset_name, Form("%s.ReconstructedNuclei.AcceptIDCodes", mda->GetName()));
904  if (codes != "") mda->fAcceptIDCodes.Set(codes);
905  codes = GetDataSetEnv<KVString>(dataset_name, Form("%s.ReconstructedNuclei.AcceptECodes", mda->GetName()));
906  if (codes != "") mda->fAcceptECodes.Set(codes);
907  // set dataset-dependent condition for seeding reconstructed nuclei
908  mda->SetPartSeedCond(GetDataSetEnv<KVString>(dataset_name, Form("%s.ReconstructedNuclei.ParticleSeedCond", mda->GetName())));
909 #ifdef WITH_RSQLITE
910  // save contents of grid manager in an SQL-ROOT database if not already done
911  if (fMakeMultiDetectorSetParameters && !gIDGridManager->IsSQLROOT()) {
912  // 'if(fMakeMultiDetectorSetParameters...' ensures that we are not currently building a subarray
913  // of a KVExpSetUp. Grids can only be saved once in a single file after all have been read.
914  TString filepath;
915  if (is_gnuinstall()) {
916  // GNU-style install: use working directory $HOME/.kaliveda
917  filepath = GetWORKDIRFilePath(gDataSet->GetName());
918  }
919  else
920  filepath = gDataSet->GetDataSetDir();
921 
922  filepath += "/idgrids_DB";
923 
924  int n_grids_to_write = gIDGridManager->GetGrids()->GetEntries();
925 
926  // we retrieve the index multiplier for the dataset in case it is >1,
927  // we use it to "correct" the runlists for the grids
928  auto index_multiplier = gDataSet->GetDataSetEnv("DataSet.RunFileIndexMultiplier.raw", 1);
929 
930  // we also set the runlist for any grids which don't have one, to the runlist of the entire dataset.
931  // in other words, grids with no runlist are considered valid for all runs
932  if (n_grids_to_write) {
933  KVSQLROOTFile f(filepath, "recreate");
934 
935  printf("Info in <KVMultiDetArray::MakeMultiDetector>: Saving %d grids in SQL-ROOT database file %s\n",
936  n_grids_to_write, filepath.Data());
937 
938  TIter it(gIDGridManager->GetGrids());
939  KVIDGraph* gr;
940  if (!db) db = gExpDB;
941  while ((gr = (KVIDGraph*)it())) {
942  // self-consistently modify runlist if necessary
943  auto rl = gr->GetRuns().GetListDividedBy(index_multiplier);
944  if (rl.IsEmpty() && db) rl = db->GetRunList();
945  gr->SetRuns(rl);
946  f.WriteObject(gr, {
947  {"IDLabel", gr->GetIDTelescopeLabel()},
948  {"IDTelescopes", gr->GetParameters()->GetStringValue("IDTelescopes")},
949  {"VarX", gr->GetVarX()},
950  {"VarY", gr->GetVarY()},
951  {"Runlist", gr->GetRunList()},
952  }
953  );
954  --n_grids_to_write;
955  if (!(n_grids_to_write % 1000)) printf("Info in <KVMultiDetArray::MakeMultiDetector>: ...%d grids left...\n",
956  n_grids_to_write);
957 
958  }
959  }
960  }
961 #endif
962  }
963  else {
964  mda = gMultiDetArray;
965  }
966  // set parameters if required & allowed & not done yet
968  return mda;
969 }
970 
971 
972 
984 
986 {
987  // Return pointer to KVUpDater defined by dataset for this multidetector, the class used
988  // is defined as a plugin like this:
989  //
990  // # Plugin.KVUpDater: name_of_dataset name_of_class name_of_plugin_library constructor_to_call
991  //
992  // However, if a dataset defines a variable like this:
993  //
994  // [dataset].ExpSetUp.Updater.[multidetector name]: [name_of_dataset for plugin]
995  //
996  // then we use the updater plugin defined for the given dataset
997 
998  if (!fUpDater) {
999  auto alt_updater = KVBase::GetDataSetEnv<KVString>(fDataSet, Form("ExpSetUp.Updater.%s", GetName()));
1000  if (alt_updater != "") fUpDater = KVUpDater::MakeUpDater(alt_updater, this);
1002  }
1003  Info("GetUpDater", "updater class for dataset %s: %s", fDataSet.Data(), fUpDater->IsA()->GetName());
1004  return fUpDater;
1005 }
1006 
1007 
1008 
1009 
1018 
1019 void KVMultiDetArray::SetParameters(UInt_t run, Bool_t physics_parameters_only)
1020 {
1021  // Set run-dependent parameters of the array.
1022  //
1023  // if physics_parameters_only==false, identification and calibration parameters are set.
1024  // if physics_parameters_only==true, just the minimum necessary for physics analysis of reduced data are set.
1025  //
1026  // This can only be done if gDataSet has been set i.e. a dataset has been chosen,
1027  // otherwise this just has the effect of setting the current run number
1028 
1029  fCurrentRun = run;
1030  KVDataSet* ds = gDataSet;
1031  if (!ds) {
1032  if (gDataSetManager)
1033  ds = gDataSetManager->GetDataSet(fDataSet.Data());
1034  }
1035  if (ds) {
1036  GetUpDater()->SetParameters(run, physics_parameters_only);
1037  SetBit(kParamsSet);
1038  }
1039 }
1040 
1041 
1042 
1043 
1048 
1050 {
1051  //Set identification parameters for run.
1052  //This can only be done if gDataSet has been set i.e. a dataset has been chosen
1053  //Otherwise this just has the effect of setting the current run number
1054 
1055  fCurrentRun = run;
1056  KVDataSet* ds = gDataSet;
1057  if (!ds) {
1058  if (gDataSetManager)
1059  ds = gDataSetManager->GetDataSet(fDataSet.Data());
1060  }
1061  if (ds) {
1064  }
1065 }
1066 
1067 
1068 
1069 
1074 
1076 {
1077  //Set calibration parameters for run.
1078  //This can only be done if gDataSet has been set i.e. a dataset has been chosen
1079  //Otherwise this just has the effect of setting the current run number
1080 
1081  fCurrentRun = run;
1082  KVDataSet* ds = gDataSet;
1083  if (!ds) {
1084  if (gDataSetManager)
1085  ds = gDataSetManager->GetDataSet(fDataSet.Data());
1086  }
1087  if (ds) {
1090  }
1091 }
1092 
1093 
1094 
1095 
1112 
1114 {
1115  //Initialisation of all ACTIVE identification telescopes in the array, i.e. those appearing in a line
1116  //in the .kvrootrc file such as this:
1117  //
1118  //# [dataset name].ActiveIdentifications: [type1] [type2] ...
1119  //
1120  //The 'types' given correspond to the value given by KVIDTelescope::GetLabel(), these are the
1121  //identifiers used to retrieve the different plugin classes in GetIDTelescopes(KVDetector*,KVDetector*,KVList*).
1122  //
1123  //For each type of identification in the list, we retrieve the first identification telescope with this
1124  //label from the list of all ID telescopes, in order to call its KVIDTelescope::SetIdentificationParameters() method.
1125  //This method (when rederived in child classes of KVIDTelescope) initialises the identification objects
1126  //for ALL of the ID telescopes of the same type (class) in the array.
1127  //
1128  //Note that, in general, the parameters of the identifications for a given run are not
1129  //set until SetParameters or SetRunIdentificationParameters is called.
1130 
1131 #ifdef WITH_RSQLITE
1132  // if a KVSQLROOTFile has been filled with the dataset identification parameters we use it.
1133  if (gIDGridManager->IsSQLROOT()) {
1134  // nothing more to do
1135  return;
1136  }
1137  else if (!gDataSet->DataBaseUpdateInProgress())
1138  // the update of the database may have been caused by 1 or more identification files being modified
1139  // (even if they are not part of the database). in this case we read in all the grids again even
1140  // if it has already been done before.
1141  {
1142  TString filepath;
1143  if (is_gnuinstall()) {
1144  // GNU-style install: use working directory $HOME/.kaliveda
1145  filepath = GetWORKDIRFilePath(gDataSet->GetName());
1146  }
1147  else
1148  filepath = gDataSet->GetDataSetDir();
1149 
1150  filepath += "/idgrids_DB";
1151 
1152  if (SearchKVFile(filepath.Data(), filepath)) {
1153  delete gIDGridManager;
1154  gIDGridManager = new KVSQLROOTIDGridManager(filepath);
1155  return;
1156  }
1157  }
1158 #endif
1159 
1160  auto id_labels = GetDataSetEnv<KVString>(fDataSet, "ActiveIdentifications");
1161  if (id_labels == "" || (gDataSet && !gDataSet->HasCalibIdentInfos())) {
1162  Info("SetIdentifications", "No active identifications");
1163  return;
1164  }
1165  //split list of labels
1166  id_labels.Begin(" ");
1167  int ok(0);
1168  //loop over labels/identification 'types'
1169  while (!id_labels.End()) {
1170 
1171  //get first telescope in list with right label
1173  //set ID parameters for all telescopes of this 'type'
1174  if (idt) {
1175  Info("SetIdentifications", "Initialising %s identifications...", idt->GetLabel());
1176  if (idt->SetIdentificationParameters(this))
1177  Info("SetIdentifications", "OK");
1178  ++ok;
1179  }
1180 
1181  }
1182  if (!ok) {
1183  // None of the labels in the list correspond to telescopes in the array
1184  Warning("SetIdentfications", "No telescopes found with labels given in %s.ActiveIdentifications list: %s",
1185  gDataSet->GetName(), id_labels.Data());
1186  }
1187 }
1188 
1189 
1190 
1191 
1198 
1200 {
1201  // Calls Initialize() method of each identification telescope (see KVIDTelescope
1202  // and derived classes) and sets the general identification code defined for each
1203  // telescope.
1204  //
1205  // Calling this method is essential before identification of particles is attempted.
1206 
1207  TIter next(fIDTelescopes);
1208  KVIDTelescope* idt;
1209  while ((idt = (KVIDTelescope*)next())) {
1210  idt->Initialize();
1212  }
1213 }
1214 
1215 
1216 
1227 
1229 {
1230  // Read all identification grids from the file and add them to the IDGridManager object
1231  // used by this array. This method sets up the links between each grid and the
1232  // IDtelescope(s) it is to be used for, unlike calling
1233  //
1234  // gIDGridManager->ReadAsciiFile(grids)
1235  //
1236  // which does not.
1237  //
1238  // Returns kFALSE if there is a problem reading the file
1239 
1240  if (gIDGridManager->ReadAsciiFile(grids)) {
1241  TIter next(gIDGridManager->GetLastReadGrids());
1242  KVIDGraph* gr;
1243  while ((gr = (KVIDGraph*)next())) FillListOfIDTelescopes(gr);
1244  return kTRUE;
1245  }
1246  return kFALSE;
1247 }
1248 
1249 
1250 
1251 
1255 
1257 {
1258  // Print full status report on ID telescopes in array, using informations stored in
1259  // fStatusIDTelescopes (see GetStatusOfIDTelescopes).
1260 
1261  cout << endl << "-----STATUS OF IDENTIFICATION TELESCOPES";
1262  if (GetCurrentRunNumber()) cout << " FOR RUN "
1263  << GetCurrentRunNumber();
1264  cout << "------" << endl << endl;
1265  //get list of active telescopes
1266  KVString id_labels;
1267  if (gDataSet) id_labels = gDataSet->GetDataSetEnv<KVString>("ActiveIdentifications");
1268  else {
1269  auto typelist = GetIDTelescopeTypes();
1270  TIter it(&typelist);
1271  TObjString* type;
1272  while ((type = (TObjString*)it())) {
1273  if (id_labels == "") id_labels += type->GetString().Data();
1274  else {
1275  id_labels += Form(" %s", type->GetString().Data());
1276  }
1277  }
1278  }
1279  if (id_labels == "") {
1280  cout << " *** No active identifications *** " << endl;
1281  return;
1282  }
1283  // iterate over labels
1284  unique_ptr<TObjArray> toks(id_labels.Tokenize(' '));
1285 
1286  //update status infos
1288 
1289  TIter next_type(fStatusIDTelescopes);
1290  TList* id_type_list = 0;
1291  while ((id_type_list = (TList*)next_type())) {
1292 
1293  cout << " *** " << id_type_list->GetName() << " Identifications -------------------" << endl;
1294  if (!toks->FindObject(id_type_list->GetName())) {
1295  cout << " [NOT ACTIVE]" << endl;
1296  }
1297  TList* ok_list = (TList*)id_type_list->FindObject("OK");
1298  TList* notok_list = (TList*)id_type_list->FindObject("NOT OK");
1299  TList* print_list = 0;
1300  Int_t Nok = ok_list->GetEntries();
1301  Int_t Notok = notok_list->GetEntries();
1302  if (Nok && Notok) {
1303  if (Nok < Notok) print_list = ok_list;
1304  else print_list = notok_list;
1305  }
1306  if (Nok && (!Notok)) cout << " ALL telescopes are OK" << endl;
1307  else if (Notok && (!Nok)) cout << " NO telescopes are OK" << endl;
1308  else {
1309  cout << " " << ok_list->GetEntries() << " telescopes are OK, "
1310  << notok_list->GetEntries() << " telescopes are NOT OK" << endl;
1311  cout << " " << print_list->GetName() << " :" << endl;
1312  TIter it(print_list);
1313  TObject* ob = it();
1314  cout << ob->GetName();
1315  while ((ob = it())) cout << "," << ob->GetName();
1316  cout << endl;
1317  }
1318  cout << endl;
1319 
1320  }
1321 }
1322 
1323 
1324 
1325 
1333 
1335 {
1336  // Fill and return pointer to list fStatusIDTelescopes which contains
1337  // a list for each type of ID telescope in the array, each list contains a list
1338  // "OK" with the ID telescopes which have IsReadyForID()=kTRUE, and
1339  // a list "NOT OK" with the others.
1340  //
1341  // The returned TList object must not be deleted (it belongs to the KVMultiDetArray).
1342 
1343  if (!fStatusIDTelescopes) {
1344  fStatusIDTelescopes = new TList;
1346  }
1347  else {
1349  }
1351  TIter next(fIDTelescopes);
1352  KVIDTelescope* idt = 0;
1353  while ((idt = (KVIDTelescope*)next())) {
1354 
1355  TString id_type = idt->GetLabel();
1356  TList* id_type_list = (TList*)fStatusIDTelescopes->FindObject(id_type.Data());
1357  if (!id_type_list) {
1358  id_type_list = new TList;
1359  id_type_list->SetOwner(kTRUE);
1360  id_type_list->SetName(id_type.Data());
1361  fStatusIDTelescopes->Add(id_type_list);
1362  id_type_list->Add(new TList);
1363  ((TList*)id_type_list->At(0))->SetName("OK");
1364  id_type_list->Add(new TList);
1365  ((TList*)id_type_list->At(1))->SetName("NOT OK");
1366  }
1367  if (idt->IsReadyForID())
1368  ((TList*)id_type_list->FindObject("OK"))->Add(idt);
1369  else
1370  ((TList*)id_type_list->FindObject("NOT OK"))->Add(idt);
1371  }
1372  return fStatusIDTelescopes;
1373 }
1374 
1375 
1376 
1377 
1381 
1383 {
1384  // Create, fill and return pointer to a list of TObjString containing the name of each type
1385  // of ID telescope (actually the label) in the array.
1386 
1387  KVUniqueNameList type_list(kTRUE);
1388  type_list.SetOwner();
1389  if (!fIDTelescopes || !fIDTelescopes->GetEntries()) return type_list;
1390  TIter next(fIDTelescopes);
1391  KVIDTelescope* idt = 0;
1392  while ((idt = (KVIDTelescope*)next())) {
1393  type_list.Add(new TObjString(idt->GetLabel()));
1394  }
1395  return type_list;
1396 }
1397 
1398 
1399 
1400 
1408 
1410 {
1411  // Create, fill and return pointer to a list of KVIDTelescopes with
1412  // the given type (label) in the array.
1413  // WARNING! - check pointer is not zero (we return NULL if ID telescopes
1414  // list is not defined or empty)
1415  //
1416  // Delete the KVList after use (it does not own the KVIDTelescopes).
1417 
1418  if (!fIDTelescopes || !fIDTelescopes->GetEntries()) return NULL;
1420 }
1421 
1422 
1423 
1424 
1432 
1434 {
1435  // Fill and return pointer to list fCalibStatusDets which contains
1436  // a list for each type of detector in the array, each list contains a list
1437  // "OK" with the detectors which are calibrated, and
1438  // a list "NOT OK" with the others.
1439  //
1440  // The returned TList object must not be deleted (it belongs to the KVMultiDetArray).
1441 
1442  if (!fCalibStatusDets) {
1443  fCalibStatusDets = new TList;
1445  }
1446  else {
1448  }
1449  if (!GetDetectors()->GetEntries()) return fCalibStatusDets;
1450  TIter next(GetDetectors());
1451  KVDetector* det = 0;
1452  while ((det = (KVDetector*)next())) {
1453 
1454  TString type = det->GetType();
1455  TList* type_list = (TList*)fCalibStatusDets->FindObject(type.Data());
1456  if (!type_list) {
1457  type_list = new TList;
1458  type_list->SetOwner(kTRUE);
1459  type_list->SetName(type.Data());
1460  fCalibStatusDets->Add(type_list);
1461  type_list->Add(new TList);
1462  ((TList*)type_list->At(0))->SetName("OK");
1463  type_list->Add(new TList);
1464  ((TList*)type_list->At(1))->SetName("NOT OK");
1465  }
1466  // check for working calibration for detector, taking into account that some may
1467  // have calibrations which only work for certain specific Z values (CsI...)
1468  bool det_is_cal=false;
1469  for(int z=0; z<100; ++z) // note we start from Z=0 (gamma calibration!)
1470  {
1471  if(det->IsCalibrated(Form("Z=%d",z)))
1472  {
1473  det_is_cal=true;
1474  break;
1475  }
1476  }
1477  if (det_is_cal)
1478  ((TList*)type_list->FindObject("OK"))->Add(det);
1479  else
1480  ((TList*)type_list->FindObject("NOT OK"))->Add(det);
1481  }
1482  return fCalibStatusDets;
1483 }
1484 
1485 
1486 
1487 
1491 
1493 {
1494  // Print full status report on calibration of detectors in array, using informations stored in
1495  // fCalibStatusDets (see GetCalibrationStatusOfDetectors).
1496 
1497  if (!GetCurrentRunNumber()) {
1498  Info("PrintCalibStatusOfDetectors", "Cannot know status without knowing RUN NUMBER");
1499  return;
1500  }
1501 
1502  cout << endl << "-----------STATUS OF CALIBRATIONS FOR RUN "
1503  << GetCurrentRunNumber() << "------------" << endl << endl;
1504 
1505  //update status infos
1507 
1508  TIter next_type(fCalibStatusDets);
1509  TList* id_type_list = 0;
1510  while ((id_type_list = (TList*)next_type())) {
1511 
1512  cout << " *** " << id_type_list->GetName() << " Detectors -------------------" << endl;
1513  TList* ok_list = (TList*)id_type_list->FindObject("OK");
1514  TList* notok_list = (TList*)id_type_list->FindObject("NOT OK");
1515  TList* print_list = 0;
1516  Int_t Nok = ok_list->GetEntries();
1517  Int_t Notok = notok_list->GetEntries();
1518  if (Nok && Notok) {
1519  if (Nok < Notok) print_list = ok_list;
1520  else print_list = notok_list;
1521  }
1522  if (Nok && (!Notok)) cout << " ALL calibrations are OK" << endl;
1523  else if (Notok && (!Nok)) cout << " NO calibrations are OK" << endl;
1524  else {
1525  cout << " " << ok_list->GetEntries() << " calibrations are OK, "
1526  << notok_list->GetEntries() << " calibrations are NOT OK" << endl;
1527  cout << " " << print_list->GetName() << " :" << endl;
1528  TIter it(print_list);
1529  TObject* ob = it();
1530  cout << ob->GetName();
1531  while ((ob = it())) cout << "," << ob->GetName();
1532  cout << endl;
1533  }
1534  cout << endl;
1535 
1536  }
1537 }
1538 
1539 
1540 
1541 
1557 
1559 {
1560  // Calculate the energy loss in the current target of the multidetector
1561  // for the reconstructed charged particle 'ion', assuming that the current
1562  // energy and momentum of this particle correspond to its state on
1563  // leaving the target.
1564  //
1565  // WARNING: for this correction to work, the target must be in the right 'state':
1566  //
1567  // gMultiDetArray->GetTarget()->SetIncoming(kFALSE);
1568  // gMultiDetArray->GetTarget()->SetOutgoing(kTRUE);
1569  //
1570  // (see KVTarget::GetParticleEIncFromERes).
1571  //
1572  // The returned value is the energy lost in the target in MeV.
1573  // The energy/momentum of 'ion' are not affected.
1574 
1575  if (fTarget && ion) return (fTarget->GetParticleEIncFromERes(ion) - ion->GetEnergy());
1576  return 0;
1577 }
1578 
1579 
1580 
1581 
1584 
1586 {
1587  // Return pointer to the (ROOT) geometry of the array.
1588  return gGeoManager;
1589 }
1590 
1591 
1592 
1594 
1596 {
1597  return fNavigator.get();
1598 }
1599 
1600 
1601 
1620 
1622 {
1623  // Actual thicknesses of detectors can be given in one or more files associated with a dataset/multidetector.
1624  //
1625  // We look for the first of the files
1626  //~~~~
1627  //[array_name].DetectorThicknessFiles.dat
1628  //DetectorThicknessFiles.dat
1629  //~~~~
1630  // which exists for the current dataset, and if found we read each file listed in it.
1631  //
1632  // Otherwise we look for the first of the files
1633  //~~~~
1634  //[array_name].DetectorThicknesses.dat
1635  //DetectorThicknesses.dat
1636  //~~~~
1637  // which exists for the current dataset, and if found we read the thicknesses from it.
1638  //
1639  // See set_detector_thicknesses() for details of the format of the individual thickness files.
1640 
1641  auto find_a_file = [this](const TString & _base_filename) {
1642  TString filename = TString(GetName()) + "." + _base_filename;
1643  TString fullpath;
1646 
1647  filename = _base_filename;
1650 
1651  return TString();
1652  };
1653 
1654  // look for list of files
1655  auto fullpath = find_a_file("DetectorThicknessFiles.dat");
1656  if (!fullpath.IsNull()) {
1657  KVFileReader fr;
1658  fr.OpenFileToRead(fullpath);
1659  while (fr.IsOK()) {
1660  fr.ReadLine(0);
1661  if (fr.GetCurrentLine().BeginsWith("#") || fr.GetCurrentLine() == "") continue;
1663  }
1664  return;
1665  }
1666 
1667  // look for single file
1668  fullpath = find_a_file("DetectorThicknesses.dat");
1669  if (!fullpath.IsNull()) set_detector_thicknesses(fullpath);
1670 }
1671 
1672 
1673 
1692 
1694 {
1695  // Use file given by fullpath to set the real thicknesses of the detectors.
1696  // Any detector which is not in the file will be left with its nominal thickness.
1697  //
1698  // EXAMPLE FILE:
1699  //
1700  //# thickness of detector DET01 in default units
1701  //DET01: 56.4627
1702  //
1703  //# DET03 has several layers
1704  //DET03.Abs0: 61.34
1705  //DET03.Abs1: 205.62
1706  //
1707  // !!! WARNING !!!
1708  // Single-layer detectors: The units are those defined by default for the detector's
1709  // Get/SetThickness methods.
1710  // Multi-layer: Each layer is a KVMaterial object. The thickness MUST be given in centimetres
1711  // (default thickness unit for KVMaterial).
1712 
1713  TEnv thickdat;
1714  if (thickdat.ReadFile(fullpath, kEnvUser) != 0) {
1715  Error("SetDetectorThicknesses", "Problem opening file %s", fullpath.Data());
1716  return;
1717  }
1718  Info("SetDetectorThicknesses", "Setting thicknesses of detectors from file %s", fullpath.Data());
1719  TIter next(GetDetectors());
1720  KVDetector* det;
1721  while ((det = (KVDetector*)next())) {
1722  if (thickdat.Defined(det->GetName())) {
1723  // simple single layer detector
1724  Double_t thick = thickdat.GetValue(det->GetName(), 0.0);
1725  det->SetThickness(thick);
1726  //Info("SetDetectorThicknesses", "Set thickness of %s to %f", det->GetName(), thick);
1727  }
1728  else {
1729  Char_t i = 0;
1730  TString absname;
1731  absname.Form("%s.Abs%d", det->GetName(), (Int_t)i);
1732  if (thickdat.Defined(absname.Data())) {
1733  // detector with several layers
1734  KVMaterial* abs = 0;
1735  while ((abs = det->GetAbsorber(i))) {
1736  Double_t thick = thickdat.GetValue(absname.Data(), 0.0);
1737  abs->SetThickness(thick);
1738  //Info("SetDetectorThicknesses", "Set thickness of %s.Abs%d to %f", det->GetName(), (Int_t)i, thick);
1739  i++;
1740  absname.Form("%s.Abs%d", det->GetName(), (Int_t)i);
1741  if (!thickdat.Defined(absname.Data())) break;
1742  }
1743  }
1744  }
1745  }
1746 }
1747 
1748 
1749 
1758 
1760 {
1761  // Called by KVGeoImport::ImportGeometry
1762  //
1763  // Creates KVRangeTableGeoNavigator for calculating energy losses of
1764  // particles propagated through array.
1765  //
1766  // If no name and/or title are defined for the array, the name and title of the TGeoManager
1767  // object will be used for the array.
1768 
1769  if (!strcmp(GetName(), "")) SetName(g->GetName());
1770  if (!strcmp(GetTitle(), "")) SetTitle(g->GetTitle());
1772 }
1773 
1774 
1775 
1804 
1806 {
1807  // Method for positioning volumes in detector geometries
1808  //
1809  // Given:
1810  //
1811  // distance [cm] = distance from target (origin) to the CENTRE of the volume in position
1812  // theta [deg] = polar angle of vector from target to centre of volume in position
1813  // phi [deg] = azimuthal angle of vector
1814  //
1815  // this method generates the matrix which is required to position the volume as required
1816  // while also turning the volume so that the side nearest the target (i.e. the entrance
1817  // window of the detector) remains perpendicular to the vector joining the origin and
1818  // the centre of the volume.
1819  //
1820  // If required, a further translation can be given which will be applied to the volume after
1821  // it has been placed with the required orientation at the nominal distance. This can be used
1822  // e.g. for detector misalignment, when detectors are in a structure which guarantees their line
1823  // of sight to be orthogonal to their surface at a nominal distance, but the nominal distance
1824  // is not respected.
1825  //
1826  // Example of use:
1827  //
1828  //~~~~~~~~~~~~
1829  // TGeoVolume* vol;// volume to be positioned
1830  // double depth = vol->GetShape()->GetDZ(); // half-width of volume in direction of target
1831  // // place front of volume at 100cm, with theta=45 deg. and phi=60 deg.
1832  // gGeoManager->GetTopVolume()->AddNode(vol, 1, KVMultiDetArray::GetVolumePositioningMatrix(100+depth,45,60));
1833  //~~~~~~~~~~~~
1834 
1835  TGeoRotation rot;
1836  TGeoTranslation trans;
1837  rot.SetAngles(phi + 90, theta, -90) ;
1838  trans.SetDz(distance) ;
1839  TGeoHMatrix h;
1840  if (postTrans) h = (*postTrans) * rot * trans ;
1841  else h = rot * trans;
1842  TGeoHMatrix* ph = new TGeoHMatrix(h);
1843  return ph;
1844 }
1845 
1846 
1847 
1848 
1852 
1854 {
1855  // For each grid which is valid for this run, we call the KVIDTelescope::SetIDGrid method
1856  // of each associated ID telescope.
1857 
1858  if (gIDGridManager->IsSQLROOT()) {
1859  gIDGridManager->LoadGridsForRun(run);
1860  }
1861 
1862  TIter next(gIDGridManager->GetGrids());
1863  KVIDGraph* gr = 0;
1864  while ((gr = (KVIDGraph*) next())) {
1865  if (!gIDGridManager->IsSQLROOT()) {
1866  if (!gr->GetRuns().Contains((Int_t) run))
1867  continue;
1868  }
1869  else
1871 
1872  TIter nxtid(gr->GetIDTelescopes());
1873  KVIDTelescope* idt;
1874  while ((idt = (KVIDTelescope*) nxtid())) {
1875  idt->SetIDGrid(gr);
1876  }
1877  }
1878 }
1879 
1880 
1884 
1886 {
1887  // Fill list of ID telescopes with which this grid is associated
1888  // from list of names read from ascii file.
1889 
1890  gr->ClearListOfTelescopes();
1891  if (gr->GetParameters()->HasParameter("IDTelescopes")) {
1892  KVString tel_list = gr->GetParameters()->GetStringValue("IDTelescopes");
1893  tel_list.Begin(",");
1894  while (!tel_list.End()) {
1895  TString tel_name = tel_list.Next();
1896  KVIDTelescope* idt = GetIDTelescope(tel_name.Data()) ;
1897  if (idt) gr->AddIDTelescope(idt);
1898  }
1899  }
1900 }
1901 
1902 
1903 
1913 
1915 {
1916  // Use OpenGL viewer to view multidetector geometry
1917  //
1918  // If option="tracks" we draw any tracks corresponding to the last simulated
1919  // event whose detection was simulated with DetectEvent
1920  // If option="tracks:[numberlist]" with a list of numbers,
1921  // it will be interpreted as a KVNumberList containing the Z of tracks to be drawn
1922  // e.g. option="tracks:1-92" draw only tracks with 1<=Z<=92 (no neutrons)
1923  // option="tracks:2" draw only helium isotopes
1924 
1925  GetGeometry()->GetTopVolume()->Draw("ogl");
1926  KVString opt(option);
1927  opt.Begin(":");
1928  if (opt.Next() == "tracks") {
1929  if (!opt.End()) {
1930  KVNumberList zlist(opt.Next());
1931  GetNavigator()->DrawTracks(&zlist);
1932  }
1933  else
1934  GetNavigator()->DrawTracks();
1935  }
1936 #ifdef WITH_OPENGL
1937  TGLViewer* view = (TGLViewer*)gPad->GetViewer3D();
1940  view->SetSmoothLines(kTRUE);
1941  view->SetSmoothPoints(kTRUE);
1942 #endif
1943 }
1944 
1945 
1946 
1948 
1950 {
1951  fNavigator.reset(geo);
1952 }
1953 
1954 
1955 
1960 
1962 {
1963  // Create TH2F histograms for all IDTelescopes of the array
1964  // They will be added to the list
1965  // histograms will have resolution of dimension*dimension
1966 
1968  KVIDTelescope* idt;
1969  while ((idt = (KVIDTelescope*)it())) {
1970  TString name(idt->GetName());
1971  name.ReplaceAll("-", "_");
1972  list->Add(new TH2F(name, Form("Hits in %s", idt->GetName()), dimension, 0., 0., dimension, 0., 0.));
1973  }
1974 }
1975 
1976 
1977 
1980 
1982 {
1983  // Fill TH2F histograms for all IDTelescopes of the array
1984 
1986  KVIDTelescope* idt;
1987  while ((idt = (KVIDTelescope*)it())) {
1988  TString name(idt->GetName());
1989  name.ReplaceAll("-", "_");
1990  TH2F* h = (TH2F*)list->FindObject(name);
1991  if (h) h->Fill(idt->GetIDMapX(), idt->GetIDMapY());
1992  }
1993 }
1994 
1995 
1996 
1999 
2001 {
2002  // Modify the transparency of detector volumes in OpenGL view
2003 
2004  TIter itV(GetGeometry()->GetListOfVolumes());
2005  TGeoVolume* vol;
2006  while ((vol = (TGeoVolume*)itV())) vol->SetTransparency(t);
2007 }
2008 
2009 
2010 
2014 
2016 {
2017  // Calculate all possible (sub-)trajectories
2018  // for particle reconstruction (GetReconTrajectories())
2019 
2020  unique_ptr<KVSeqCollection> groups(GetStructureTypeList("GROUP"));
2021  TIter it(groups.get());
2022  KVGroup* group;
2023  Int_t ntr = 0;
2024  Info("CalculateReconstructionTrajectories", "Calculating trajectories for particle reconstruction:");
2026  std::cout << "\xd" << " -- calculated " << ntr << " reconstruction trajectories" << std::flush;
2027  while ((group = (KVGroup*)it())) {
2028  ntr += group->CalculateReconstructionTrajectories();
2030  std::cout << "\xd" << " -- calculated " << ntr << " reconstruction trajectories" << std::flush;
2031  }
2033  std::cout << " -- calculated " << ntr << " reconstruction trajectories" << std::endl;
2034  else
2035  std::cout << std::endl;
2036 }
2037 
2038 
2039 
2044 
2046 {
2047  // Track over all possible particle trajectories calling GetIDTelescopes(KVDetector*,KVDetector*)
2048  // for each pair of (present & functioning) detectors.
2049  // This will create all possible KVIDTelescope identification objects and put them in list fIDTelescopes
2050 
2051  fIDTelescopes->Delete();
2052  TIter next_traj(GetTrajectories());
2053  KVGeoDNTrajectory* traj;
2054  Int_t count = 0;
2055  Info("DeduceIdentificationTelescopesFromGeometry", "Calculating...");
2057  std::cout << "\xd" << " -- created " << count << " telescopes" << std::flush;
2058  while ((traj = (KVGeoDNTrajectory*)next_traj())) { // loop over all trajectories
2059 
2060  traj->IterateFrom(); // from furthest-out to closest-in detector
2061 
2063  while ((N = traj->GetNextNode())) {
2064  KVGeoDetectorNode* Nplus1 = traj->GetNodeInFront(N);
2065  count += GetIDTelescopes(Nplus1, N->GetDetector(), traj->AccessIDTelescopeList());
2067  std::cout << "\xd" << " -- created " << count << " telescopes" << std::flush;
2068  }
2069  }
2071  std::cout << " -- created " << count << " telescopes" << std::endl;
2072  else
2073  std::cout << std::endl;
2074 }
2075 
2076 
2077 
2081 
2083 {
2084  // Eliminate any trajectories which are just sub-trajectories of others
2085  // For each trajectory in list fTrajectories, we add a reference to the trajectory to each node on the trajectory
2086 
2087  TIter it(&fTrajectories);
2088  KVGeoDNTrajectory* tr;
2089  KVList duplicates;
2090  // look for duplicate sub-trajectories
2091  while ((tr = (KVGeoDNTrajectory*)it())) {
2092  int len_tr = tr->GetN();
2093  TIter it2(&fTrajectories);
2094  KVGeoDNTrajectory* tr2;
2095  while ((tr2 = (KVGeoDNTrajectory*)it2())) {
2096  if ((tr2 != tr) && (len_tr < tr2->GetN()) && (tr2->ContainsPath(tr))) {
2097  duplicates.Add(tr);
2098  break;
2099  }
2100  }
2101  }
2102  // remove duplicates
2103  if (duplicates.GetEntries()) {
2104  TIter it_dup(&duplicates);
2105  while ((tr = (KVGeoDNTrajectory*)it_dup())) {
2106  fTrajectories.Remove(tr);
2107  }
2108  Info("AssociateTrajectoriesAndNodes", "Removed %d duplicated sub-trajectories", duplicates.GetEntries());
2109  }
2110  Info("AssociateTrajectoriesAndNodes", "Calculated %d particle trajectories", fTrajectories.GetEntries());
2111  it.Reset();
2112  while ((tr = (KVGeoDNTrajectory*)it())) {
2113  tr->AddToNodes();
2114  }
2115 }
2116 
2117 
2118 
2120 
2122 {
2123  if (N->GetNTraj() > 1) {
2124  if (!multitraj_nodes.FindObject(N)) { // look for any detectors which are on multiple trajectories
2125  //cout << "multitraj node found: " << N->GetName() << " (" << N->GetNTraj() << ")" << endl;
2126  multitraj_nodes.Add(N);
2127  TIter tr(N->GetTrajectories());
2128  KVGeoDNTrajectory* traj;
2129  while ((traj = (KVGeoDNTrajectory*)tr())) { // for each trajectory associated with detector
2130  if (tried_trajectories.FindObject(traj)) continue; // trajectory already used
2131  tried_trajectories.Add(traj);
2132  traj->IterateFrom();
2133  KVGeoDetectorNode* node;
2134  while ((node = traj->GetNextNode())) { // store names of all detectors on trajectory
2135  detectors_of_group.Add(node);
2136  RecursiveTrajectoryClustering(node, tried_trajectories, multitraj_nodes, detectors_of_group);
2137  }
2138  }
2139  }
2140  }
2141  else if (N->GetNTraj() == 1) {
2142  // single-trajectory node.
2143  // work along trajectory adding nodes to group
2144  KVGeoDNTrajectory* traj = (KVGeoDNTrajectory*)N->GetTrajectories()->First();
2145  if (tried_trajectories.FindObject(traj)) return; // trajectory already used
2146  tried_trajectories.Add(traj);
2147  traj->IterateFrom();
2148  KVGeoDetectorNode* node;
2149  while ((node = traj->GetNextNode())) { // store names of all detectors on trajectory
2150  detectors_of_group.Add(node);
2151  RecursiveTrajectoryClustering(node, tried_trajectories, multitraj_nodes, detectors_of_group);
2152  }
2153  }
2154  else {
2155  // orphan node? single-detector array?
2156  detectors_of_group.Add(N);
2157  }
2158 }
2159 
2160 
2161 
2170 
2172 {
2173  // Create and return pointer to new KVGroupReconstructor for reconstructing particles
2174  // in the given group. Returns nullptr if group is not part of this array.
2175  //
2176  // Plugins for specific arrays can be defined as plugins using the name of the array:
2177  // +Plugin.KVGroupReconstructor: my_array my_group_reconstructor my_lib "my_group_reconstructor()"
2178  //
2179  // If we are in 'SimMode', the default reconstructor is a KVFilterGroupReconstructor
2180 
2181  KVGroupReconstructor* gr(nullptr);
2182  if (GetGroup(g->GetName())) {
2183  // look for plugin
2185  if (!gr) {
2186  if (IsSimMode()) return KVGroupReconstructor::Factory("Filter", g);
2187  else
2188  gr = new KVGroupReconstructor(g);
2189  }
2190  }
2191  return gr;
2192 }
2193 
2194 
2195 
2199 
2201 {
2202  // Call this method just after opening a raw data file in order to perform any
2203  // necessary initialisations, depending on the type of data
2204 
2205 #ifdef WITH_BUILTIN_GRU
2206  if (r->GetDataFormat() == "EBYEDAT")
2207  dynamic_cast<KVGANILDataReader*>(r)->ConnectRawDataParameters();
2208 #endif
2209 }
2210 
2211 
2212 
2217 
2219 {
2220  // Deduce the "groups" in the array from the trajectories
2221  // Any trajectories with 1 or more common detectors define a group.
2222  // The group is constituted of all detectors belonging to the trajectories of the group.
2223 
2224  Info("DeduceGroupsFromTrajectories", "Deducing groups of detectors from trajectories");
2225  Int_t number_of_groups = 0;
2226  TIter next_det(GetDetectors());
2227  unique_ptr<KVSeqCollection> stl(GetStructureTypeList("GROUP"));
2228  if (stl.get() && stl->GetEntries()) {
2229  Info("DeduceGroupsFromTrajectories", "Deleting existing %d groups in array", stl->GetEntries());
2230  ClearStructures("GROUP");
2231  Info("DeduceGroupsFromTrajectories", "Done");
2232  }
2233  KVDetector* det;
2234  KVUniqueNameList tried_trajectories;//avoid double-counting/infinite loops
2235  KVUniqueNameList multitraj_nodes;//avoid double-counting/infinite loops
2236  while ((det = (KVDetector*) next_det())) {
2237  if (det->GetGroup()) continue; // group assignment already done
2238  KVUniqueNameList detectors_of_group;
2239  RecursiveTrajectoryClustering(det->GetNode(), tried_trajectories, multitraj_nodes, detectors_of_group);
2240  if (!detectors_of_group.GetEntries()) continue;
2241  KVGroup* Group = new KVGroup;
2242  Group->SetNumber(++number_of_groups);
2243  Add(Group);
2244  TIter next_node(&detectors_of_group);
2246  while ((d = (KVGeoDetectorNode*)next_node())) Group->Add(d->GetDetector());
2247  }
2248  TIter tr(&fTrajectories);
2249  KVGeoDNTrajectory* t;
2250  Info("DeduceGroupsFromTrajectories", "Filling group trajectory lists");
2251  while ((t = (KVGeoDNTrajectory*)tr())) {
2252  if (t->GetNodeAt(0)->GetDetector()->GetGroup())
2253  t->GetNodeAt(0)->GetDetector()->GetGroup()->AddTrajectory(t);
2254  else {
2255  t->Print();
2256  t->GetNodeAt(0)->GetDetector()->Print();
2257  }
2258  }
2259 }
2260 
2261 
2262 
2266 
2268 {
2269  // Called when required to fill KVReconstructedNucleus::fDetList with pointers to
2270  // the detectors whose names are stored in KVReconstructedNucleus::fDetNames.
2271 
2272  DetList->Clear();
2273  DetNames.Begin("/");
2274  while (!DetNames.End()) {
2275  KVDetector* det = GetDetector(DetNames.Next(kTRUE));
2276  if (det) DetList->Add(det);
2277  }
2278 }
2279 
2280 
2281 
2301 
2303 {
2304  // Set status of particle by comparing its identification/calibration codes
2305  // with those set as acceptable in fAcceptIDCodes and fAcceptECodes.
2306  // The status can be tested with method KVReconstructedNucles::IsOK().
2307  //
2308  // The default lists are defined in variables of the form
2309  //```
2310  // [DataSet].[name].ReconstructedNuclei.AcceptIDCodes: [list]
2311  // [DataSet].[name].ReconstructedNuclei.AcceptECodes: [list]
2312  //```
2313  // where:
2314  // + `DataSet` is an optional dataset name for dataset-specific lists
2315  // + `name` is the name of the multidetector array
2316  // + `list` is a numeric list (KVNumberList format)
2317  //
2318  // The default lists can be overridden using methods AcceptIDCodes(), AcceptECodes(),
2319  // AcceptAllIDCodes() and AcceptAllECodes().
2320  //
2321  // If either list is empty, no selection is made for the corresponding code
2322 
2323  Bool_t ok = kTRUE;
2325  if (!fAcceptECodes.IsEmpty()) ok = ok && fAcceptECodes.Contains(NUC->GetECode());
2326  NUC->SetIsOK(ok);
2327 }
2328 
2329 
2330 #ifdef WITH_BUILTIN_GRU
2331 
2334 
2336 {
2337  // General method for reading raw data in old GANIL ebyedat format
2338  AbstractMethod("handle_raw_data_event_ebyedat");
2339  return kFALSE;
2340 }
2341 
2342 #endif
2343 
2344 
2347 
2349 {
2350  // reset acquisition parameters etc. before reading new raw data event
2351 
2354  fHandledRawData = false;
2355  // reset fired signals
2356  TIter nxt(&fFiredSignals);
2357  KVDetectorSignal* ds;
2358  while ((ds = (KVDetectorSignal*)nxt())) {
2359  ds->SetFired(false);
2360  ds->SetValue(0);
2361  }
2362  fFiredSignals.Clear();
2363 }
2364 
2365 
2366 
2374 
2376 {
2377  // Perform any operations to finalise the description of the multidetector
2378  // which can only be done once the geometry is closed, e.g. use KVGeoImport
2379  // to set up nodes, trajectories, detectors, idtelescopes, etc.
2380  // This has to be kept separate for use with KVExpSetUp which first fills
2381  // a single ROOT geometry with all component KVMultiDetArray geometries,
2382  // then closes the geometry only when all have been built.
2383 }
2384 
2385 
2386 
2389 
2391 {
2392  // Copy any parameters in fReconParameters in to the reconstructed event parameter list
2393  e->GetParameters()->Concatenate(fReconParameters);
2394 }
2395 
2396 
2397 
2410 
2412 {
2413  // values of fired raw data signals (acquisition parameters) from last read raw event
2414  // are copied to the fReconParameters list of parameters to be stored with the
2415  // reconstructed event.
2416  //
2417  // the format for each signal is:
2418  //
2419  // ACQPAR.[array].[detector].[signal]
2420  // ACQPAR.[array].[signal]
2421  //
2422  // in the first case for signals associated with detectors, in the latter case signals
2423  // which are not associated with a detector
2424 
2425  TIter it(GetFiredSignals());
2426  KVDetectorSignal* o;
2427  while ((o = (KVDetectorSignal*)it())) {
2428  fReconParameters.SetValue(Form("ACQPAR.%s.%s", GetName(), o->GetFullName().Data()), o->GetValue());
2429  }
2430 }
2431 
2432 
2433 
2442 
2444 {
2445  // Update array according to last event read using the KVRawDataReader object
2446  // (it is assumed that KVRawDataReader::GetNextEvent() was called before calling this method)
2447  //
2448  // Return kTRUE if raw data was treated
2449  //
2450  // All fired acquisition parameters are written in the fReconParameters list,
2451  // ready to be copied to the reconstructed event
2452 
2453  fRawDataReader = rawdata;
2455  if (rawdata->GetDataFormat() == "MFM") {
2456 #ifdef WITH_MFM
2458 #endif
2459  }
2460  else if (rawdata->GetDataFormat() == "PROTOBUF") {
2461 #ifdef WITH_PROTOBUF
2463 #endif
2464  }
2465  else if (rawdata->GetDataFormat() == "EBYEDAT") {
2466 #ifdef WITH_BUILTIN_GRU
2468 #endif
2469  }
2470  if (fHandledRawData) {
2472  }
2473  return fHandledRawData;
2474 }
2475 
2476 
2477 #ifdef WITH_MFM
2478 
2487 
2489 {
2490  // Update array according to last event read from MFM buffer
2491  // (it is assumed that MFMBufferReader::ReadNextFrame() was called before calling this method)
2492  //
2493  // Return kTRUE if raw data was treated
2494  //
2495  // All fired acquisition parameters are written in the fReconParameters list,
2496  // ready to be copied to the reconstructed event
2497 
2499  bool ok = false;
2500  ok = handle_raw_data_event_mfmfile(bufrdr);
2501  if (ok) {
2503  }
2504  return ok;
2505 }
2506 
2507 #endif
2508 
2509 
2520 
2522 {
2523  // Given a pointer to a detector (may be nullptr) try to set the data sig_data in the associated signal
2524  // of the given type, sig_typ.
2525  //
2526  // If the signal does not exist for the detector, it will be created.
2527  //
2528  // If detector pointer is null, the signal will be looked for in fExtraRawDataSignals
2529  // and created if necessary.
2530  //
2531  // All fired detectors and signals are added to the lists fFiredDetectors and fFiredSignals.
2532 
2533  KVDetectorSignal* det_signal = nullptr;
2534  if (detector) {
2535  det_signal = detector->GetDetectorSignal(sig_type);
2536  if (!det_signal) {
2537  det_signal = detector->AddDetectorSignal(sig_type);
2538  }
2539  fFiredDetectors.Add(detector);
2540  }
2541  else {
2542  // raw data not associated with a detector
2543  TString sig_name;
2544  if (detname != "") sig_name = Form("%s.%s", detname.Data(), sig_type.Data());
2545  else sig_name = sig_type;
2546  det_signal = fExtraRawDataSignals.get_object<KVDetectorSignal>(sig_name);
2547  if (!det_signal) {
2548  det_signal = new KVDetectorSignal(sig_name);
2549  fExtraRawDataSignals.Add(det_signal);
2550  }
2551  }
2552  if (det_signal) {
2553  det_signal->SetValue(sig_data);
2554  det_signal->SetFired();
2555  fFiredSignals.Add(det_signal);
2556  }
2557 }
2558 
2559 
2560 
2566 
2568 {
2569  // Take values 'ACQPAR.[array_name].[detname].[signal]' or 'ACQPAR.[array_name].[signal]'
2570  // in the parameter list and use them to set values of raw acquisition parameters.
2571  //
2572  // Any detector signals which don't already exist will be created
2573 
2574  prepare_to_handle_new_raw_data(); // clear previous fired parameters/detectors
2575  int N = l.GetNpar();
2576  for (int i = 0; i < N; ++i) {
2577  KVNamedParameter* np = l.GetParameter(i);
2578 
2579  KVString name(np->GetName());
2580  if (name.BeginsWith("ACQPAR")) {
2581  // 3 '.' => 4 values means associated detector
2582  // 2 '.' => 3 values means no detector
2583  int dots = name.GetNValues(".");
2584  bool with_det = (dots == 4);
2585  assert(with_det || (dots == 3)); // sanity check
2586  name.Begin(".");
2587  name.Next(); // "ACQPAR"
2588  if (name.Next() != GetName()) continue; // check name of array - somebody else's parameter ?
2589  KVString det_name;
2590  KVString sig_type;
2591  KVDetector* det = nullptr;
2592  if (with_det) {
2593  det_name = name.Next();
2594  sig_type = name.Next();
2595  det = GetDetector(det_name);
2596  }
2597  else {
2598  sig_type = name.Next();
2599  }
2600  add_and_set_detector_signal(det, det_name, np->GetDouble(), sig_type);
2601  }
2602  }
2603 }
2604 
2605 
2606 
2625 
2627 {
2628  // We first look for following files with the name given by
2629  //
2630  // [dataset].[name].OoODetectors: [name.OoODetectors.dat]
2631  // which should contain the runlists for each malfunctioning detector.
2632  // If found we add to the experiment database a table '[name].OoO Detectors' where [name] is the name of this array.
2633  //
2634  // [dataset].[name].AbsentDetectors: [name.AbsentDetectors.dat]
2635  // which should contain the runlists for each absent detector.
2636  // If found we add to the experiment database a table '[name].Absent Detectors' where [name] is the name of this array.
2637  //
2638  // Then we look for a file with the name given by
2639  //
2640  // [dataset].[name].CalibrationFiles: [CalibrationFiles.dat]
2641  //
2642  // which should contain the names of files to read with each type of calibration
2643  // If found we add to the experiment database a table '[name].Calibrations' where [name] is the name of this array,
2644  // containing all calibrations as KVDBParameterSet objects with the name of the detector concerned.
2645  db->SetDBType(Form("%sDB", GetName()));
2646  ReadOoODetectors(db);
2647  ReadAbsentDetectors(db);
2649 }
2650 
2651 
2652 
2654 
2656 {
2657  TString basic_name = db->GetCalibFileName(keyw);
2658  if (basic_name == "") {
2659  Info(meth, "No name found for \"%s\" file", keyw);
2660  return "";
2661  }
2662  Info(meth, "Search for %s for dataset %s ...", basic_name.Data(), fDataSet.Data());
2663  TString fp;
2664  SearchKVFile(basic_name.Data(), fp, fDataSet);
2665  if (fp == "") {
2666  Info(meth, "\tNo file found ...");
2667  }
2668  return fp;
2669 }
2670 
2671 
2672 
2674 
2675 unique_ptr<KVFileReader> KVMultiDetArray::GetKVFileReader(KVExpDB* db, const Char_t* meth, const Char_t* keyw)
2676 {
2677 
2678  TString fp = GetFileName(db, meth, keyw);
2679  if (fp == "")
2680  return unique_ptr<KVFileReader>();
2681 
2682  unique_ptr<KVFileReader> fr(new KVFileReader());
2683  if (!fr->OpenFileToRead(fp.Data())) {
2684  Error(meth, "Error in opening file %s", fp.Data());
2685  fr.reset(nullptr);
2686  }
2687  else
2688  Info(meth, "Reading %s file", fp.Data());
2689  return fr;
2690 }
2691 
2692 
2693 
2695 
2697 {
2698 
2699  unique_ptr<KVFileReader> fr = GetKVFileReader(db, "ReadCalibrationFiles()", "CalibrationFiles");
2700  if (!fr.get())
2701  return;
2702 
2703  KVDBTable* calib_table = db->AddTable(Form("%s.Calibrations", GetName()), Form("Calibrations for %s", GetName()));
2704  while (fr->IsOK()) {
2705  fr->ReadLine(0);
2706  if (fr->GetCurrentLine().BeginsWith("#") || fr->GetCurrentLine() == "") {}
2707  else {
2708  ReadCalibFile(fr->GetCurrentLine().Data(), db, calib_table);
2709  }
2710  }
2711  fr->CloseFile();
2712 }
2713 
2714 
2715 
2761 
2762 void KVMultiDetArray::ReadCalibFile(const Char_t* filename, KVExpDB* db, KVDBTable* calib_table)
2763 {
2764  // Read a calibration file with the format
2765  //
2766  //~~~~~~~~~~~~~
2767  // RunList: 1546-7485
2768  // SignalIn: PG
2769  // SignalOut: Volts
2770  // CalibType: ChannelVolt
2771  // CalibOptions: func=pol3,min=0,max=1
2772  // ZRange: 2-92
2773  // [detector1]: 0.0,0.261829,0.0
2774  // [detector2]: 0.1 0.539535 1.2
2775  //~~~~~~~~~~~~~
2776  //
2777  //The `[RunList]` is optional: if not given, the calibration will be applied to all runs in the database.
2778  //
2779  //If different parameters are required for different sets of runs, they should be written in different
2780  //files (all of which are listed in `CalibrationFiles.dat` or `[array].CalibrationFiles.dat`).
2781  //
2782  //Numerical parameter values for each detector can be given separated by commas, whitespace or tab characters.
2783  //
2784  //The `[CalibClass]`, if given, must correspond to a KVCalibrator plugin name. The list of plugin names and the corresponding
2785  //classes can be retrieved with
2786  //
2787  //~~~~~~~~~~~
2788  //KVBase::GetListOfPlugins("KVCalibrator")
2789  //KVBase::GetListOfPluginURIs("KVCalibrator")
2790  //~~~~~~~~~~~
2791  //
2792  //KVCalibrator objects are added to detectors as required by the contents of calibration files.
2793  //If any detector has an existing calibrator of type `[CalibType]` which is not of the given class
2794  //it will be replaced with a new calibrator corresponding to the plugin.
2795  //
2796  //The `[CalibOptions]` is optional: list in `[CalibOptions]` will be used
2797  //to complete set-up of any new calibrator objects by calling the KVCalibrator::SetOptions()
2798  //method.
2799  //
2800  //`[CalibOptions]` should hold a comma-separated list of `parameter=value` pairs which will be used
2801  //to fill a KVNameValueList for the method call. See the KVCalibrator::SetOptions() method.
2802  //
2803  //`[ZRange]` is an option if several calibrations need to be used to provide the same signal
2804  //for certain detectors depending on the atomic number Z of the particle detected.
2805  //
2806  // If any of the detector names (`[detector1]`, `[detector2]` in above example) contains the `'*'` wildcard character,
2807  // it will be interpreted as a list of detectors whose names correspond to the given wildcard expression.
2808 
2809 
2810  TString fullpath = "";
2811  if (!SearchKVFile(filename, fullpath, fDataSet)) {
2812  Info("ReadCalibFile", "%s does not exist or not found", filename);
2813  return;
2814  }
2815 
2816  Info("ReadCalibFile", "file : %s found", fullpath.Data());
2817  TEnv env;
2818  env.ReadFile(fullpath, kEnvAll);
2819 
2820  // read options from file
2821  KVNameValueList options;
2822  KVString opt_list = "RunList SignalIn SignalOut CalibType CalibClass CalibOptions ZRange";
2823  opt_list.Begin(" ");
2824  while (!opt_list.End()) {
2825  KVString opt = opt_list.Next();
2826  KVString opt_val = env.GetValue(opt, "");
2827  opt_val.Remove(TString::kBoth, ' ');
2828  options.SetValue(opt, opt_val.Data());
2829  }
2830  // check for stupid spellnig mitskaes
2831  if (TString(env.GetValue("Runlist", "")) != "") {
2832  Warning("ReadCalibFile", "Calibration has 'Runlist' parameter (ignored): %s, did you mean 'RunList'?", env.GetValue("Runlist", ""));
2833  }
2834 
2835  if (options.GetTStringValue("SignalIn") == "") {
2836  Error("ReadCalibFile", "No input signal defined : SignalIn");
2837  return;
2838  }
2839  if (options.GetTStringValue("SignalOut") == "") {
2840  Error("ReadCalibFile", "No output signal defined : SignalOut");
2841  return;
2842  }
2843  if (options.GetTStringValue("CalibType") == "") {
2844  Error("ReadCalibFile", "No calibration type defined : CalibType");
2845  return;
2846  }
2847  Bool_t check_class(options.GetTStringValue("CalibClass") != "");
2848  TString calibrator_class;
2849  if (check_class) {
2850  TPluginHandler* ph = LoadPlugin("KVCalibrator", options.GetStringValue("CalibClass"));
2851  if (ph) calibrator_class = ph->GetClass();
2852  else {
2853  Error("ReadCalibFile", "No calibrator plugin of type %s", options.GetStringValue("CalibClass"));
2854  return;
2855  }
2856  }
2857 
2858  KVString clop;
2859  if (options.HasParameter("CalibOptions")) clop = options.GetStringValue("CalibOptions");
2860 
2861  KVString zrange;
2862  if (options.HasParameter("ZRange")) zrange = options.GetStringValue("ZRange");
2863 
2864  KVNumberList run_list = db->GetRunList();
2865  if (options.GetTStringValue("RunList") != "") {
2866  run_list.Set(options.GetTStringValue("RunList"));
2867  Info("ReadCalibFile", "Calibration used for runs %s", run_list.AsString());
2868  }
2869  else {
2870  Info("ReadCalibFile", "Calibration used for all runs in database");
2871  }
2872 
2873  TIter next(env.GetTable());
2874  TEnvRec* rec = nullptr;
2875  KVDBParameterSet* par = nullptr;
2876 
2877  // valid delimiters for numerical parameters are: space - comma - tab
2878  // here we add ':' because if there is space in the TEnv file between the key name and the ':'
2879  // i.e. if we have
2880  // SI2-11 : 0.1,0.3
2881  // then the ':' becomes part of the value: TEnv::GetValue("SI2-11","") will give ": 0.1,0.3"
2882  // instead of
2883  // SI2-11: 0.1,0.3
2884  // => TEnv::GetValue("SI2-11","") gives "0.1,0.3"
2885  TString param_delimiters = ":, \t";
2886 
2887  auto set_calib_parameters = [&](const TEnvRec* rec, const KVDetector* det)
2888  {
2889  KVString lval(rec->GetValue());
2890  par = new KVDBParameterSet(det->GetName(), options.GetStringValue("CalibType"), lval.GetNValues(param_delimiters));
2891  par->SetParameter("SignalIn", options.GetStringValue("SignalIn"));
2892  par->SetParameter("SignalOut", options.GetStringValue("SignalOut"));
2893  // put infos on required calibrator class into database so that it can be replaced
2894  // as needed in SetCalibratorParameters
2895  par->SetParameter("CalibClass", options.GetStringValue("CalibClass"));
2896  if (clop != "") par->SetParameter("CalibOptions", clop);
2897  if (zrange != "") par->SetParameter("ZRange", zrange);
2898  Int_t np = 0;
2899  lval.Begin(param_delimiters);
2900  while (!lval.End()) {
2901  par->SetParameter(np++, lval.Next().Atof());
2902  }
2903  calib_table->AddRecord(par);
2904  db->LinkRecordToRunRange(par, run_list);
2905  };
2906 
2907  while ((rec = (TEnvRec*)next()))
2908  {
2909  std::unique_ptr<KVSeqCollection> det_list{GetDetectorNameList(rec->GetName())};
2910  for(auto p_det : *det_list)
2911  set_calib_parameters(rec,dynamic_cast<KVDetector*>(p_det));
2912  }
2913 }
2914 
2915 
2916 #ifdef WITH_MFM
2917 
2923 
2925 {
2926  // Update array according to last event read using the KVMFMDataFileReader object
2927  // (it is assumed that KVRawDataReader::GetNextEvent() was called before calling this method)
2928  //
2929  // Return kTRUE if raw data was treated
2930 
2931  if (mfmreader.IsFrameReadMerge()) {
2932  return handle_raw_data_event_mfmmergeframe(mfmreader.GetMergeManager());
2933  }
2934  else {
2935  return handle_raw_data_event_mfmframe(mfmreader.GetFrameRead());
2936  }
2937  return kFALSE;
2938 }
2939 
2940 
2941 
2945 
2946 Bool_t KVMultiDetArray::handle_raw_data_event_mfmmergeframe(const MFMMergeFrameManager& mergeframe)
2947 {
2948  // Method used to handle merged MFM frames
2949  // We call handle_raw_data_event_mfmframe() for each frame contained in the merge
2950 
2951  Bool_t ok = false;
2952  while (mergeframe.ReadNextFrame()) {
2953  Bool_t me = handle_raw_data_event_mfmframe(mergeframe.GetFrameRead());
2954  ok = (ok || me);
2955  }
2956  return ok;
2957 }
2958 
2959 
2960 
2971 
2973 {
2974  // Method used to treat raw data in MFM format read by KVMFMDataFileReader
2975  //
2976  // Here we dispatch two types of frame - MFMEbyedatFrame & MFMMesytecMDPPFrame -
2977  // to specific methods - handle_raw_data_event_mfmframe_ebyedat() and
2978  // handle_raw_data_event_mfmframe_mesytec_mdpp()
2979  // which need to be implemented in child classes for specific arrays which
2980  // use these data formats.
2981  //
2982  // Return kTRUE if raw data was treated
2983 #ifdef WITH_MESYTEC
2984  if (mfmframe.GetFrameType() == MFM_MESYTEC_FRAME_TYPE)
2985  return handle_raw_data_event_mfmframe_mesytec_mdpp((const MFMMesytecMDPPFrame&)mfmframe);
2986 #endif
2987  if (mfmframe.GetFrameType() == MFM_EBY_EN_FRAME_TYPE
2988  || mfmframe.GetFrameType() == MFM_EBY_TS_FRAME_TYPE
2989  || mfmframe.GetFrameType() == MFM_EBY_EN_TS_FRAME_TYPE)
2990  return handle_raw_data_event_mfmframe_ebyedat((const MFMEbyedatFrame&)mfmframe);
2991 
2992  return kFALSE;
2993 }
2994 
2995 
2996 
2999 
3001 {
3002  // Read a raw data event from a EBYEDAT MFM Frame.
3003 
3004  AbstractMethod("handle_raw_data_event_mfmframe_ebyedat");
3005  return kFALSE;
3006 }
3007 
3008 
3009 #ifdef WITH_MESYTEC
3010 
3013 
3015 {
3016  // Read a raw data event from a Mesytec MFM Frame.
3017 
3018  AbstractMethod("handle_raw_data_event_mfmframe_mesytec_mdpp");
3019  return kFALSE;
3020 }
3021 
3022 #endif
3023 #endif
3024 
3025 #ifdef WITH_PROTOBUF
3026 
3028 
3030 {
3031  AbstractMethod("handle_raw_data_event_protobuf");
3032  return kFALSE;
3033 }
3034 
3035 #endif
3036 
3037 
3040 
3042 {
3043  // For each IDtelescope in array, calculate an identification grid
3044 
3045  TIter nxtid(GetListOfIDTelescopes());
3046  KVIDTelescope* idt;
3047  while ((idt = (KVIDTelescope*) nxtid())) {
3048  idt->CalculateDeltaE_EGrid("1-92", 0, 20);
3049  }
3050 }
3051 
3052 
3053 
3058 
3060 {
3061  // Sets status of detectors (KVDetector::IsPresent() and KVDetector::IsWorking()) for a given run of a dataset.
3062  //
3063  // If 'myname' is given, we look in database table "myname.OoODets"
3064 
3065  KVRList* absdet = (myname != "" ? kvrun->GetLinks(Form("%s.Absent Detectors", myname.Data())) : kvrun->GetLinks("Absent Detectors"));
3066  KVRList* ooodet = (myname != "" ? kvrun->GetLinks(Form("%s.OoO Detectors", myname.Data())) : kvrun->GetLinks("OoO Detectors"));
3067 
3068  TIter next(GetDetectors());
3069  KVDetector* det;
3070 
3071  Int_t ndet_absent = 0;
3072  Int_t ndet_ooo = 0;
3073  TString absent_dets, ooo_dets;
3074 
3075  while ((det = (KVDetector*)next())) {
3076  //Test de la presence ou non du detecteur
3077  if (!absdet) {
3078  det->SetPresent();
3079  }
3080  else {
3081  if (absdet->FindObject(det->GetName())) {
3082  det->SetPresent(kFALSE);
3083  if (ndet_absent) absent_dets += ",";
3084  absent_dets += det->GetName();
3085  ndet_absent += 1;
3086  }
3087  else {
3088  det->SetPresent();
3089  }
3090  }
3091  if (det->IsPresent()) {
3092  //Test du bon fonctionnement ou non du detecteur
3093  if (!ooodet) {
3094  det->SetDetecting();
3095  }
3096  else {
3097  if (ooodet->FindObject(det->GetName())) {
3098  det->SetDetecting(kFALSE);
3099  if (ndet_ooo) ooo_dets += ",";
3100  ooo_dets += det->GetName();
3101  ndet_ooo += 1;
3102  }
3103  else {
3104  det->SetDetecting();
3105  }
3106  }
3107  }
3108  }
3109 
3110  if (ndet_absent) Info("CheckStatusOfDetectors", "%d detectors absent during run : %s", ndet_absent, absent_dets.Data());
3111  else Info("CheckStatusOfDetectors", "All detectors present during run");
3112  if (ndet_ooo) Info("CheckStatusOfDetectors", "%d detectors malfunctioned during run : %s", ndet_ooo, ooo_dets.Data());
3113  else Info("CheckStatusOfDetectors", "All detectors functioning during run");
3114 }
3115 
3116 
3117 
3119 
3121 {
3122  CheckStatusOfDetectors(dbr, myname);
3123 }
3124 
3125 
3126 
3141 
3143 {
3144  // Read a file containing runlists for each temporarily non-functioning detector.
3145  //
3146  // The file should be in TEnv format like so:
3147  //
3148  //~~~~
3149  // DET_1: 100-122,541-1938
3150  // DET_2,DET_3: 91-765
3151  //~~~~
3152  //
3153  // i.e. more than one detector can be associated with the same runs (comma-separated list of
3154  // detector names) and the list of runs are given using KVNumberList syntax.
3155  //
3156  // The data is added to the database in a table '[name].OoO Detectors' with the name of this array.
3157 
3158  TString fullpath;
3159  if (!db->FindCalibFile("OoODet", fullpath, GetName())) return;
3160 
3161  Info("ReadOoODetectors()", "Reading lists of out-of-order detectors...");
3162  auto fOoODet = db->AddTable(Form("%s.OoO Detectors", GetName()), "Name of out of order detectors");
3163 
3164  KVDBRecord* dbrec = 0;
3165  TEnv env;
3166  TEnvRec* rec = 0;
3167  env.ReadFile(fullpath.Data(), kEnvAll);
3168  TIter it(env.GetTable());
3169 
3170  while ((rec = (TEnvRec*)it.Next())) {
3171  KVString srec(rec->GetName());
3172  KVNumberList nl(rec->GetValue());
3173  if (srec.Contains(",")) {
3174  srec.Begin(",");
3175  while (!srec.End()) {
3176  dbrec = new KVDBRecord(srec.Next(kTRUE), "OoO Detector");
3177  dbrec->AddKey("Runs", "List of Runs");
3178  fOoODet->AddRecord(dbrec);
3179  db->LinkRecordToRunRange(dbrec, nl);
3180  }
3181  }
3182  else {
3183  dbrec = new KVDBRecord(rec->GetName(), "OoO Detector");
3184  dbrec->AddKey("Runs", "List of Runs");
3185  fOoODet->AddRecord(dbrec);
3186  db->LinkRecordToRunRange(dbrec, nl);
3187  }
3188  }
3189 }
3190 
3191 
3206 
3208 {
3209  // Read a file containing runlists for each temporarily absent/dismounted detector.
3210  //
3211  // The file should be in TEnv format like so:
3212  //
3213  //~~~~
3214  // DET_1: 100-122,541-1938
3215  // DET_2,DET_3: 91-765
3216  //~~~~
3217  //
3218  // i.e. more than one detector can be associated with the same runs (comma-separated list of
3219  // detector names) and the list of runs are given using KVNumberList syntax.
3220  //
3221  // The data is added to the database in a table '[name].Absent Detectors' with the name of this array.
3222 
3223  TString fullpath;
3224  if (!db->FindCalibFile("AbsentDet", fullpath, GetName())) return;
3225 
3226  Info("ReadAbsentDetectors()", "Reading lists of absent/dismounted detectors... file=[%s]", fullpath.Data());
3227  auto fAbsDet = db->AddTable(Form("%s.Absent Detectors", GetName()), "Name of out of order detectors");
3228 
3229  KVDBRecord* dbrec = 0;
3230  TEnv env;
3231  TEnvRec* rec = 0;
3232  env.ReadFile(fullpath.Data(), kEnvAll);
3233  TIter it(env.GetTable());
3234 
3235  while ((rec = (TEnvRec*)it.Next())) {
3236  KVString srec(rec->GetName());
3237  KVNumberList nl(rec->GetValue());
3238  if (srec.Contains(",")) {
3239  srec.Begin(",");
3240  while (!srec.End()) {
3241  dbrec = new KVDBRecord(srec.Next(kTRUE), "Absent Detector");
3242  dbrec->AddKey("Runs", "List of Runs");
3243  fAbsDet->AddRecord(dbrec);
3244  db->LinkRecordToRunRange(dbrec, nl);
3245  }
3246  }
3247  else {
3248  dbrec = new KVDBRecord(rec->GetName(), "Absent Detector");
3249  dbrec->AddKey("Runs", "List of Runs");
3250  fAbsDet->AddRecord(dbrec);
3251  db->LinkRecordToRunRange(dbrec, nl);
3252  }
3253  }
3254 }
3255 
3256 
int Int_t
unsigned int UInt_t
ROOT::R::TRInterface & r
#define SafeDelete(p)
#define d(i)
#define f(i)
#define e(i)
bool Bool_t
unsigned short UShort_t
char Char_t
constexpr Bool_t kFALSE
double Double_t
constexpr Bool_t kTRUE
const char Option_t
kEnvUser
kEnvAll
#define N
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t option
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 winding char text const char depth char const char Int_t count const char ColorStruct_t color const char filename
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 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 winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t Atom_t typelist
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 g
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 winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
char name[80]
R__EXTERN TGeoManager * gGeoManager
char * Form(const char *fmt,...)
#define gPad
void SetLabel(const Char_t *lab)
Definition: KVBase.h:194
virtual const Char_t * GetType() const
Definition: KVBase.h:176
void Error(const char *method, const char *msgfmt,...) const override
Definition: KVBase.cpp:1709
static const Char_t * GetWORKDIRFilePath(const Char_t *namefile="")
Definition: KVBase.cpp:121
const Char_t * GetLabel() const
Definition: KVBase.h:198
static bool is_gnuinstall()
Definition: KVBase.h:275
void Print(Option_t *option="") const override
Definition: KVBase.cpp:413
virtual void SetType(const Char_t *str)
Definition: KVBase.h:172
static Bool_t SearchKVFile(const Char_t *name, TString &fullpath, const Char_t *kvsubdir="")
Definition: KVBase.cpp:541
static TPluginHandler * LoadPlugin(const Char_t *base, const Char_t *uri="0")
Definition: KVBase.cpp:796
void Warning(const char *method, const char *msgfmt,...) const override
Definition: KVBase.cpp:1696
Base class for all detector calibrations.
Definition: KVCalibrator.h:99
virtual Int_t GetNumberParams() const
Definition: KVCalibrator.h:154
virtual void SetParameter(int i, Double_t par_val)
Definition: KVCalibrator.h:159
virtual void SetOptions(const KVNameValueList &)
void SetStatus(Bool_t ready)
Definition: KVCalibrator.h:167
void SetOutputSignalType(const TString &type)
Definition: KVCalibrator.h:224
void SetInputSignalType(const TString &type)
Definition: KVCalibrator.h:220
static KVCalibrator * MakeCalibrator(const Char_t *type)
To store calibration parameters in a database ,.
TString GetStringParameter(const TString &name) const
Double_t GetParameter(UShort_t i=0) const
Bool_t HasParameter(const TString &name) const
void Print(Option_t *option="") const override
Int_t GetParamNumber() const
void SetParameter(UShort_t i, Double_t val)
const KVNameValueList & GetParameters() const
Record folder for the database.
Definition: KVDBRecord.h:43
virtual Bool_t AddKey(KVDBKey *key, Bool_t check=kTRUE)
Definition: KVDBRecord.cpp:65
virtual KVRList * GetLinks(const Char_t *key) const
Returns the list of records linked to this record in table "key".
Definition: KVDBRecord.cpp:206
Description of an experimental run in database ,,.
Definition: KVDBRun.h:41
Table in a database.
Definition: KVDBTable.h:34
virtual Bool_t AddRecord(KVDBRecord *add)
Definition: KVDBTable.cpp:75
static Bool_t IsRunningBatchAnalysis()
virtual Bool_t AddTable(KVDBTable *table)
Definition: KVDataBase.cpp:84
Manage all datasets contained in a given data repository.
virtual Bool_t Init(KVDataRepository *=0)
KVDataSet * GetDataSet(Int_t) const
Return pointer to DataSet using index in list of all datasets, index>=0.
Manage an experimental dataset corresponding to a given experiment or campaign.
Definition: KVDataSet.h:146
TString GetFullPathToDataSetFile(const Char_t *filename) const
Definition: KVDataSet.cpp:2067
const Char_t * GetDataSetDir() const
Definition: KVDataSet.cpp:762
Bool_t HasCalibIdentInfos() const
Definition: KVDataSet.h:380
void cd() const
Definition: KVDataSet.cpp:784
Bool_t DataBaseUpdateInProgress() const
Definition: KVDataSet.h:186
ValType GetDataSetEnv(const Char_t *type, const ValType &defval={}) const
Definition: KVDataSet.h:269
static Bool_t FindDataSetFile(const TString &dataset, const Char_t *filename)
Definition: KVDataSet.cpp:2102
List of hit groups in a multidetector array.
void AddGroup(KVGroup *grp)
Base class for output signal data produced by a detector.
virtual void SetValue(Double_t x)
virtual Double_t GetValue(const KVNameValueList &params="") const
TString GetFullName() const
void SetFired(Bool_t yes=true)
Base class for detector geometry description, interface to energy-loss calculations.
Definition: KVDetector.h:160
void SetThickness(Double_t thick) override
KVGroup * GetGroup() const
void AddDetectorSignal(KVDetectorSignal *ds)
Definition: KVDetector.h:278
Bool_t IsCalibrated(const KVNameValueList &params={}) const
Definition: KVDetector.cpp:545
void Print(Option_t *option="") const override
Definition: KVDetector.cpp:356
KVMaterial * GetAbsorber(Int_t i) const
Returns pointer to the i-th absorber in the detector (i=0 first absorber, i=1 second,...
Definition: KVDetector.cpp:626
virtual KVDetectorSignal * GetDetectorSignal(const KVString &type) const
Definition: KVDetector.h:534
void SetDetecting(Bool_t yes=kTRUE)
Definition: KVDetector.h:662
virtual void RemoveCalibrators()
Definition: KVDetector.cpp:702
KVGeoDetectorNode * GetNode()
Definition: KVDetector.h:345
virtual Bool_t IsPresent() const
Definition: KVDetector.h:648
Bool_t AddCalibrator(KVCalibrator *cal, const KVNameValueList &opts="")
Definition: KVDetector.cpp:439
void SetPresent(Bool_t yes=kTRUE)
Definition: KVDetector.h:653
Base class to describe database of an experiment ,,.
Definition: KVExpDB.h:61
void SetDBType(const TString &s)
Definition: KVExpDB.h:118
TString GetCalibFileName(const Char_t *type) const
Definition: KVExpDB.h:188
const KVNumberList & GetRunList() const
Definition: KVExpDB.h:156
virtual void LinkRecordToRunRange(KVDBRecord *rec, UInt_t first_run, UInt_t last_run)
Definition: KVExpDB.cpp:290
Bool_t FindCalibFile(const Char_t *type, TString &fullpath, const TString &array_name="") const
Definition: KVExpDB.cpp:672
Handle reading columns of numeric data in text files.
Definition: KVFileReader.h:121
KVString GetCurrentLine()
Definition: KVFileReader.h:320
ReadStatus ReadLine(const KVString &pattern="")
Definition: KVFileReader.h:243
Bool_t IsOK()
Definition: KVFileReader.h:231
Bool_t OpenFileToRead(const KVString &filename)
Definition: KVFileReader.h:210
Reads GANIL acquisition files (EBYEDAT)
Path taken by particles through multidetector geometry.
KVGeoDetectorNode * GetNextNode() const
KVSeqCollection * AccessIDTelescopeList()
void AddToNodes()
Add reference to this trajectory to all nodes on it.
void IterateFrom(const KVGeoDetectorNode *node0=nullptr) const
KVGeoDetectorNode * GetNodeInFront(const KVGeoDetectorNode *n) const
Bool_t ContainsPath(const KVGeoDNTrajectory *other) const
KVGeoDetectorNode * GetNodeAt(Int_t i) const
Information on relative positions of detectors & particle trajectories.
KVDetector * GetDetector() const
Base class for propagation of particles through array geometry.
void DrawTracks(KVNumberList *=nullptr)
Base class describing elements of array geometry.
virtual Bool_t Fired(Option_t *opt="any") const
void SetOwnsDetectors(Bool_t yes=kTRUE)
virtual KVDetector * GetDetector(const Char_t *name) const
Return detector in this structure with given name.
const KVSeqCollection * GetDetectors() const
const KVSeqCollection * GetStructures() const
virtual void Add(KVBase *)
KVSeqCollection * GetStructureTypeList(const Char_t *type) const
void ClearStructures(const Char_t *type="")
KVSeqCollection * GetDetectorNameList(const Char_t *name) const
const KVSeqCollection * GetParents() const
Base class for particle reconstruction in one group of a detector array.
static KVGroupReconstructor * Factory(const TString &plugin="", const KVGroup *g=nullptr)
Group of detectors which can be treated independently of all others in array.
Definition: KVGroup.h:20
void SetNumber(UInt_t num) override
Definition: KVGroup.h:38
void AddTrajectory(KVGeoDNTrajectory *t)
Definition: KVGroup.h:91
void Reset(Option_t *opt="")
Definition: KVGroup.h:45
Extended version of ROOT THashList.
Definition: KVHashList.h:29
Base class for particle identification in a 2D map.
Definition: KVIDGraph.h:32
Handles a stock of identification grids to be used by one or more identification telescopes.
virtual void LoadGridsForRun(UInt_t)
KVSeqCollection * GetGrids()
Bool_t ReadAsciiFile(const Char_t *filename)
const TList * GetLastReadGrids() const
virtual bool IsSQLROOT() const
Base class for all detectors or associations of detectors in array which can identify charged particl...
Definition: KVIDTelescope.h:85
virtual Double_t GetIDMapY(Option_t *opt="")
virtual Bool_t IsReadyForID()
KVIDGrid * CalculateDeltaE_EGrid(const KVNameValueList &AperZ, Int_t npoints=30, Double_t xfactor=1.)
void SetGroup(KVGroup *kvg)
virtual Double_t GetIDMapX(Option_t *opt="")
static KVIDTelescope * MakeIDTelescope(const Char_t *name)
virtual Bool_t SetIdentificationParameters(const KVMultiDetArray *)
void SetIDGrid(KVIDGraph *)
virtual void AddDetector(KVDetector *d)
virtual void Initialize(void)
Extended TList class which owns its objects by default.
Definition: KVList.h:22
Read MFM format acquisition data.
Description of physical materials used to construct detectors & targets; interface to range tables.
Definition: KVMaterial.h:90
static KVIonRangeTable * GetRangeTable()
Definition: KVMaterial.cpp:158
Base class for describing the geometry of a detector array.
const KVSeqCollection * GetFiredSignals() const
KVNumberList fAcceptECodes
list of acceptable calibration codes for reconstructed nuclei
bool try_a_singleIDtelescope(TString uri, KVDetector *d, TCollection *l)
KVUniqueNameList fExtraRawDataSignals
any signals read from raw data not associated with a detector
KVSeqCollection * GetListOfIDTelescopes() const
void FillListOfIDTelescopes(KVIDGraph *gr) const
virtual Bool_t handle_raw_data_event_mfmframe_ebyedat(const MFMEbyedatFrame &)
Read a raw data event from a EBYEDAT MFM Frame.
KVNumberList fAcceptIDCodes
list of acceptable identification codes for reconstructed nuclei
virtual void GetDetectorEvent(KVDetectorEvent *detev, const TSeqCollection *fired_params=0)
virtual Bool_t handle_raw_data_event_protobuf(KVProtobufDataReader &)
void MakeHistogramsForAllIDTelescopes(KVSeqCollection *list, Int_t dimension=100)
TList * GetStatusOfIDTelescopes()
int try_all_singleID_telescopes(KVDetector *d, TCollection *l)
static Bool_t fCloseGeometryNow
void Draw(Option_t *option="") override
virtual void DeduceIdentificationTelescopesFromGeometry()
static KVMultiDetArray * MakeMultiDetector(const Char_t *dataset_name, Int_t run=-1, TString classname="KVMultiDetArray", KVExpDB *db=nullptr)
std::unique_ptr< KVFileReader > GetKVFileReader(KVExpDB *db, const Char_t *meth, const Char_t *keyw)
virtual Double_t GetTargetEnergyLossCorrection(KVReconstructedNucleus *)
virtual Bool_t handle_raw_data_event_mfmmergeframe(const MFMMergeFrameManager &)
virtual Bool_t handle_raw_data_event_mfmfile(MFMBufferReader &)
void ReadOoODetectors(KVExpDB *db)
Bool_t fHandledRawData
set to true if multidetector handles data in last call to HandleRawData
KVSeqCollection * GetIDTelescopesWithType(const Char_t *type)
TList * fCalibStatusDets
used by GetStatusIDTelescopes
KVDetectorEvent * fHitGroups
list of hit groups in simulation
void ReadAbsentDetectors(KVExpDB *db)
KVTarget * GetTarget()
void RecursiveTrajectoryClustering(KVGeoDetectorNode *N, KVUniqueNameList &tried_trajectories, KVUniqueNameList &multitraj_nodes, KVUniqueNameList &detectors_of_group)
KVSeqCollection * fIDTelescopes
deltaE-E telescopes in groups
UInt_t fCurrentRun
Number of the current run used to call SetParameters.
static Bool_t fMakeMultiDetectorSetParameters
void Clear(Option_t *opt="") override
void CalculateIdentificationGrids()
For each IDtelescope in array, calculate an identification grid.
void prepare_to_handle_new_raw_data()
reset acquisition parameters etc. before reading new raw data event
int try_all_doubleID_telescopes(KVDetector *de, KVDetector *e, TCollection *l)
Bool_t IsSimMode() const
void FillHistogramsForAllIDTelescopes(KVSeqCollection *list)
Fill TH2F histograms for all IDTelescopes of the array.
virtual void set_detector_thicknesses(const TString &)
Bool_t ReadGridsFromAsciiFile(const Char_t *) const
virtual void InitialiseRawDataReading(KVRawDataReader *)
virtual void SetExpectedDetectorSignalNames()
virtual void SetParameters(UInt_t n, Bool_t physics_parameters_only=kFALSE)
virtual void SetDetectorParametersForRun(KVDBRun *, const TString &="")
virtual void copy_fired_parameters_to_recon_param_list()
TString GetDataSet() const
KVGroup * GetGroup(const Char_t *name) const
static TGeoHMatrix * GetVolumePositioningMatrix(Double_t distance, Double_t theta, Double_t phi, TGeoTranslation *postTrans=nullptr)
KVGeoNavigator * GetNavigator() const
KVUpDater * fUpDater
used to set parameters for multidetector
void SetGeometry(TGeoManager *)
virtual void MakeCalibrationTables(KVExpDB *)
virtual ~KVMultiDetArray()
destroy (delete) the MDA and all the associated structure, detectors etc.
virtual void SetRunIdentificationParameters(UShort_t n)
Bool_t HandleRawDataBuffer(MFMBufferReader &)
TString GetFileName(KVExpDB *, const Char_t *meth, const Char_t *keyw)
void CheckStatusOfDetectors(KVDBRun *, const TString &="")
virtual void PerformClosedROOTGeometryOperations()
UInt_t GetCurrentRunNumber() const
void SetDetectorTransparency(Char_t)
Modify the transparency of detector volumes in OpenGL view.
virtual KVGroupReconstructor * GetReconstructorForGroup(const KVGroup *) const
virtual void SetIdentifications()
static Bool_t fMakeMultiDetectorPhysicsParametersOnly
TList * fStatusIDTelescopes
used by GetStatusIDTelescopes
Bool_t fSimMode
=kTRUE in "simulation mode" (use for calculating response to simulated events)
virtual void Build(Int_t run=-1)
virtual void FillDetectorList(KVReconstructedNucleus *rnuc, KVHashList *DetList, const KVString &DetNames)
virtual Bool_t handle_raw_data_event_ebyedat(KVGANILDataReader &)
General method for reading raw data in old GANIL ebyedat format.
const TSeqCollection * GetTrajectories() const
static Bool_t fBuildTarget
KVTarget * fTarget
target used in experiment
virtual void set_up_telescope(KVDetector *de, KVDetector *e, KVIDTelescope *idt, TCollection *l)
Set up detectors in de-e identification telescope and add to fIDTelescopes and to l.
TList * GetCalibrationStatusOfDetectors()
bool try_upper_and_lower_singleIDtelescope(TString uri, KVDetector *d, TCollection *l)
virtual Bool_t handle_raw_data_event_mfmframe(const MFMCommonFrame &)
TGeoManager * GetGeometry() const
Return pointer to the (ROOT) geometry of the array.
KVRawDataReader * fRawDataReader
last raw data reader object used in call to HandleRawData
virtual void SetRawDataFromReconEvent(KVNameValueList &)
void add_and_set_detector_signal(KVDetector *det, KVString detname, Double_t sig_data, KVString sig_type)
static Int_t fMakeMultiDetectorRunNumber
virtual Bool_t HandleRawDataEvent(KVRawDataReader *)
virtual void InitializeIDTelescopes()
KVUniqueNameList fFiredDetectors
list of fired detectors after reading raw data event
virtual void RenumberGroups()
virtual void SetRunCalibrationParameters(UShort_t n)
void PrintStatusOfIDTelescopes()
bool try_upper_and_lower_doubleIDtelescope(TString uri, KVDetector *de, KVDetector *e, TCollection *l)
void PrintCalibStatusOfDetectors()
void ReadCalibrationFiles(KVExpDB *db)
virtual void SetCalibratorParameters(KVDBRun *, const TString &="")
Int_t fFilterType
type of filtering (used by DetectEvent)
virtual void SetPartSeedCond(const Char_t *cond)
std::unique_ptr< KVGeoNavigator > fNavigator
for propagating particles through array geometry
void SetGridsInTelescopes(UInt_t run)
KVIDTelescope * GetIDTelescope(const Char_t *name) const
Return pointer to DeltaE-E ID Telescope with "name".
void CalculateReconstructionTrajectories()
KVUniqueNameList fTrajectories
list of all possible trajectories through detectors of array
virtual void SetIDCodeForIDTelescope(KVIDTelescope *) const
virtual void SetReconParametersInEvent(KVReconstructedEvent *) const
Copy any parameters in fReconParameters in to the reconstructed event parameter list.
KVNameValueList fReconParameters
general purpose list of parameters for storing information on data reconstruction
TString fDataSet
name of associated dataset, used with MakeMultiDetector()
virtual void AssociateTrajectoriesAndNodes()
void ReadCalibFile(const Char_t *filename, KVExpDB *db, KVDBTable *calib_table)
virtual void AcceptParticleForAnalysis(KVReconstructedNucleus *) const
Int_t GetIDTelescopes(KVGeoDetectorNode *, KVDetector *, TCollection *list)
void SetNavigator(KVGeoNavigator *geo)
KVMultiDetArray()
Default constructor.
KVUpDater * GetUpDater()
KVUniqueNameList GetIDTelescopeTypes()
void DeduceGroupsFromTrajectories()
virtual void set_up_single_stage_telescope(KVDetector *det, KVIDTelescope *idt, TCollection *l)
Set up detector in single-stage identification telescope and add to fIDTelescopes and to l.
bool try_a_doubleIDtelescope(TString uri, KVDetector *de, KVDetector *e, TCollection *l)
virtual Bool_t handle_raw_data_event_mfmframe_mesytec_mdpp(const MFMMesytecMDPPFrame &)
Read a raw data event from a Mesytec MFM Frame.
KVUnownedList fFiredSignals
list of fired signals after reading raw data event
Handles lists of named parameters with different types, a list of KVNamedParameter objects.
void SetValue(const Char_t *name, value_type value)
void Clear(Option_t *opt="") override
const Char_t * GetStringValue(const Char_t *name) const
Bool_t HasParameter(const Char_t *name) const
TString GetTStringValue(const Char_t *name) const
A generic named parameter storing values of different types.
Strings used to represent a set of ranges of values.
Definition: KVNumberList.h:85
Bool_t Contains(Int_t val) const
returns kTRUE if the value 'val' is contained in the ranges defined by the number list
const Char_t * AsString(Int_t maxchars=0) const
void Set(const TString &l)
Definition: KVNumberList.h:135
Bool_t IsEmpty() const
Definition: KVNumberList.h:175
void SetIsOK(Bool_t flag=kTRUE)
Definition: KVParticle.cpp:371
Double_t GetEnergy() const
Definition: KVParticle.h:624
Read Google Protobuf DAQ files.
Wrapper for TRefArray adding some functionality.
Definition: KVRList.h:37
KVBase * FindObject(const Char_t *name, const Char_t *type) const
Definition: KVRList.cpp:106
Propagate particles through array geometry calculating energy losses.
Abstract base class for reading raw (DAQ) data.
virtual TString GetDataFormat() const =0
Event containing KVReconstructedNucleus nuclei reconstructed from hits in detectors.
Nuclei reconstructed from data measured by a detector array .
virtual Int_t GetECode() const
virtual Int_t GetIDCode() const
Combine ROOT file containing objects with SQLite database with info on the objects.
Definition: KVSQLROOTFile.h:76
ID grid manager using KVSQLROOTFile backend.
KaliVeda extensions to ROOT collection classes.
virtual TObject * FindObjectByLabel(const Char_t *) const
T * get_object(const TString &name) const
TObject * Remove(TObject *obj) override
Remove object from list.
void Add(TObject *obj) override
TObject * FindObject(const char *name) const override
KVSeqCollection * GetSubListWithType(const Char_t *retvalue) const
void Clear(Option_t *option="") override
virtual void SetCleanup(Bool_t enable=kTRUE)
void SetOwner(Bool_t enable=kTRUE) override
void Delete(Option_t *option="") override
KVSeqCollection * GetSubListWithLabel(const Char_t *retvalue) const
Extension of ROOT TString class which allows backwards compatibility with ROOT v3....
Definition: KVString.h:73
void Begin(TString delim) const
Definition: KVString.cpp:565
Bool_t End() const
Definition: KVString.cpp:634
KVString Next(Bool_t strip_whitespace=kFALSE) const
Definition: KVString.cpp:695
Int_t GetNValues(TString delim) const
Definition: KVString.cpp:886
Double_t GetParticleEIncFromERes(KVNucleus *, TVector3 *norm=0) override
Definition: KVTarget.cpp:969
void Clear(Option_t *opt="") override
Definition: KVTarget.cpp:748
Optimised list in which named objects can only be placed once.
void Add(TObject *obj) override
Base class implementing necessary methods for setting multidetector parameters for each run of the cu...
Definition: KVUpDater.h:25
virtual void SetParameters(UInt_t, Bool_t physics_parameters_only=kFALSE)
Definition: KVUpDater.cpp:91
static KVUpDater * MakeUpDater(const Char_t *uri, KVMultiDetArray *)
Definition: KVUpDater.cpp:59
virtual void SetCalibrationParameters(UInt_t)
Set calibration parameters for this run.
Definition: KVUpDater.cpp:198
virtual void SetIdentificationParameters(UInt_t)
Definition: KVUpDater.cpp:157
void SetName(const char *name)
const char * GetName() const override
virtual Int_t GetEntries() const
virtual void SetOwner(Bool_t enable=kTRUE)
Bool_t Contains(const char *name) const
THashList * GetTable() const
virtual const char * GetValue(const char *name, const char *dflt) const
virtual Int_t ReadFile(const char *fname, EEnvLevel level)
Bool_t Defined(const char *name) const
void SetStyle(Short_t st)
void SetCurrentCamera(ECameraType camera)
void SetSmoothPoints(Bool_t s)
void SetSmoothLines(Bool_t s)
TGeoVolume * GetTopVolume() const
void SetAngles(Double_t phi, Double_t theta, Double_t psi)
void SetDz(Double_t dz) override
void Draw(Option_t *option="") override
void SetTransparency(Char_t transparency=0)
virtual Int_t Fill(const char *name, Double_t w)
TObject * Next()
void Reset()
TObject * FindObject(const char *name) const override
void Add(TObject *obj) override
void Delete(Option_t *option="") override
TObject * At(Int_t idx) const override
virtual void SetTitle(const char *title="")
const char * GetName() const override
const char * GetTitle() const override
virtual void SetName(const char *name)
TClass * IsA() const override
void AbstractMethod(const char *method) const
virtual const char * GetName() const
void SetBit(UInt_t f)
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
virtual void Info(const char *method, const char *msgfmt,...) const
const char * GetClass() const
Longptr_t ExecPlugin(int nargs)
Int_t GetEntries() const override
Double_t Atof() const
const char * Data() const
void ToUpper()
TObjArray * Tokenize(const TString &delim) const
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
TString & Prepend(char c, Ssiz_t rep=1)
void Form(const char *fmt,...)
TString & Remove(EStripType s, char c)
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
RVec< PromoteType< T > > abs(const RVec< T > &v)
TGraphErrors * gr
TH1 * h
void init()
rec
Int_t Nint(T x)
TLine l
ClassImp(TPyArg)