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 
56 Bool_t KVMultiDetArray::fCloseGeometryNow = kTRUE;
57 Bool_t KVMultiDetArray::fBuildTarget = kFALSE;
58 Bool_t KVMultiDetArray::fMakeMultiDetectorSetParameters = kTRUE;
59 Bool_t KVMultiDetArray::fMakeMultiDetectorPhysicsParametersOnly = kFALSE;
60 Int_t KVMultiDetArray::fMakeMultiDetectorRunNumber = -1;
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
118  fIDTelescopes->SetCleanup(kTRUE);
119 
120  fHitGroups = 0;
121 
122  fTarget = 0;
123  fCurrentRun = 0;
124 
125  fStatusIDTelescopes = 0;
126  fCalibStatusDets = 0;
127  fSimMode = kFALSE;
128 
129  fFilterType = kFilterType_Full;
130 
131  fUpDater = 0;
132 
133  if (!gIDGridManager) new KVIDGridManager;
134 
135  // all trajectories belong to us
136  fTrajectories.SetOwner();
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
145  fExtraRawDataSignals.SetOwner(kTRUE);
146 }
147 
148 
149 
152 
154 {
155  //destroy (delete) the MDA and all the associated structure, detectors etc.
156 
157  SafeDelete(fHitGroups);
158  //destroy all identification telescopes
159  if (fIDTelescopes && fIDTelescopes->TestBit(kNotDeleted)) {
160  fIDTelescopes->Delete();
161  delete fIDTelescopes;
162  }
163  fIDTelescopes = 0;
164 
165  if (gMultiDetArray == this)
166  gMultiDetArray = nullptr;
167 
168  if (fStatusIDTelescopes) {
169  fStatusIDTelescopes->Delete();
170  delete fStatusIDTelescopes;
171  fStatusIDTelescopes = 0;
172  }
173  if (fCalibStatusDets) {
174  fCalibStatusDets->Delete();
175  delete fCalibStatusDets;
176  fCalibStatusDets = 0;
177  }
178 
179  SafeDelete(fUpDater);
180 }
181 
182 
183 
184 
185 
187 
189 {
190 
191 
192 
193 }
194 
195 
196 
197 
221 
222 Int_t KVMultiDetArray::GetIDTelescopes(KVGeoDetectorNode* de, KVDetector* e, TCollection* list)
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 
283 Int_t KVMultiDetArray::try_all_singleID_telescopes(KVDetector* d, TCollection* l)
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 
338 Int_t KVMultiDetArray::try_all_doubleID_telescopes(KVDetector* de, KVDetector* e, TCollection* l)
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 
404 bool KVMultiDetArray::try_upper_and_lower_singleIDtelescope(TString uri, KVDetector* d, TCollection* l)
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 
427 bool KVMultiDetArray::try_upper_and_lower_doubleIDtelescope(TString uri, KVDetector* de, KVDetector* e, TCollection* l)
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 
451 bool KVMultiDetArray::try_a_singleIDtelescope(TString uri, KVDetector* d, TCollection* l)
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))) {
467  set_up_single_stage_telescope(d, idt, l);
468  return true;
469  }
470  }
471 
472  // look for default version
473  KVIDTelescope* idt;
474  if ((idt = KVIDTelescope::MakeIDTelescope(uri))) {
475  set_up_single_stage_telescope(d, idt, l);
476  return true;
477  }
478 
479  return false;
480 }
481 
482 
483 
490 
491 bool KVMultiDetArray::try_a_doubleIDtelescope(TString uri, KVDetector* de, KVDetector* e, TCollection* l)
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 
524 void KVMultiDetArray::set_up_telescope(KVDetector* de, KVDetector* e, KVIDTelescope* idt, TCollection* l)
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
538  KVIDTelescope* p = (KVIDTelescope*)fIDTelescopes->FindObject(idt->GetName());
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 
554 void KVMultiDetArray::set_up_single_stage_telescope(KVDetector* det, KVIDTelescope* idt, TCollection* l)
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
562  KVIDTelescope* p = (KVIDTelescope*)fIDTelescopes->FindObject(idt->GetName());
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 
580 void KVMultiDetArray::RenumberGroups()
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 
603  return (KVIDTelescope*) fIDTelescopes->FindObject(name);
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  KVError::Warning(this, "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  KVError::Error(this, "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  KVError::Warning(this, "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 
738 void KVMultiDetArray::SetExpectedDetectorSignalNames()
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;
867  else if (fMakeMultiDetectorRunNumber > 0) run = fMakeMultiDetectorRunNumber;
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
967  if (fMakeMultiDetectorSetParameters && (run > -1) && gExpDB) mda->SetParameters(run, fMakeMultiDetectorPhysicsParametersOnly);
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);
1001  else fUpDater = KVUpDater::MakeUpDater(fDataSet, 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) {
1063  SetBit(kIDParamsSet);
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) {
1089  SetBit(kCalParamsSet);
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  KVError::Warning(this, "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();
1211  SetIDCodeForIDTelescope(idt);
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;
1345  fStatusIDTelescopes->SetOwner(kTRUE);
1346  }
1347  else {
1348  fStatusIDTelescopes->Delete();
1349  }
1350  if (!fIDTelescopes || !fIDTelescopes->GetEntries()) return fStatusIDTelescopes;
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;
1419  return fIDTelescopes->GetSubListWithLabel(type);
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;
1444  fCalibStatusDets->SetOwner(kTRUE);
1445  }
1446  else {
1447  fCalibStatusDets->Delete();
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;
1644  if (KVDataSet::FindDataSetFile(fDataSet, filename))
1646 
1647  filename = _base_filename;
1648  if (KVDataSet::FindDataSetFile(fDataSet, 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;
1662  set_detector_thicknesses(KVDataSet::GetFullPathToDataSetFile(fDataSet, fr.GetCurrentLine()));
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 
1693 void KVMultiDetArray::set_detector_thicknesses(const TString& fullpath)
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  KVError::Error(this, "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());
1771  if (!fNavigator) fNavigator.reset(new KVRangeTableGeoNavigator(g, KVMaterial::GetRangeTable()));
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->GetListOfIDTelescopes());
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  if (gr->GetParameters()->HasParameter("IDTelescopes")) {
1891  KVString tel_list = gr->GetParameters()->GetStringValue("IDTelescopes");
1892  tel_list.Begin(",");
1893  gr->ClearListOfIDTelescopes();
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  // Modify the transparency of detector volumes in OpenGL view
1984 
1985  TIter itV(GetGeometry()->GetListOfVolumes());
1986  TGeoVolume* vol;
1987  while ((vol = (TGeoVolume*)itV())) vol->SetTransparency(t);
1988 }
1989 
1990 
1991 
1995 
1996 void KVMultiDetArray::CalculateReconstructionTrajectories()
1997 {
1998  // Calculate all possible (sub-)trajectories
1999  // for particle reconstruction (GetReconTrajectories())
2000 
2001  unique_ptr<KVSeqCollection> groups(GetStructureTypeList("GROUP"));
2002  TIter it(groups.get());
2003  KVGroup* group;
2004  Int_t ntr = 0;
2005  Info("CalculateReconstructionTrajectories", "Calculating trajectories for particle reconstruction:");
2007  std::cout << "\xd" << " -- calculated " << ntr << " reconstruction trajectories" << std::flush;
2008  while ((group = (KVGroup*)it())) {
2009  ntr += group->CalculateReconstructionTrajectories();
2011  std::cout << "\xd" << " -- calculated " << ntr << " reconstruction trajectories" << std::flush;
2012  }
2014  std::cout << " -- calculated " << ntr << " reconstruction trajectories" << std::endl;
2015  else
2016  std::cout << std::endl;
2017 }
2018 
2019 
2020 
2025 
2026 void KVMultiDetArray::DeduceIdentificationTelescopesFromGeometry()
2027 {
2028  // Track over all possible particle trajectories calling GetIDTelescopes(KVDetector*,KVDetector*)
2029  // for each pair of (present & functioning) detectors.
2030  // This will create all possible KVIDTelescope identification objects and put them in list fIDTelescopes
2031 
2032  fIDTelescopes->Delete();
2033  TIter next_traj(GetTrajectories());
2034  KVGeoDNTrajectory* traj;
2035  Int_t count = 0;
2036  Info("DeduceIdentificationTelescopesFromGeometry", "Calculating...");
2038  std::cout << "\xd" << " -- created " << count << " telescopes" << std::flush;
2039  while ((traj = (KVGeoDNTrajectory*)next_traj())) { // loop over all trajectories
2040 
2041  traj->IterateFrom(); // from furthest-out to closest-in detector
2042 
2044  while ((N = traj->GetNextNode())) {
2045  KVGeoDetectorNode* Nplus1 = traj->GetNodeInFront(N);
2046  count += GetIDTelescopes(Nplus1, N->GetDetector(), traj->AccessIDTelescopeList());
2048  std::cout << "\xd" << " -- created " << count << " telescopes" << std::flush;
2049  }
2050  }
2052  std::cout << " -- created " << count << " telescopes" << std::endl;
2053  else
2054  std::cout << std::endl;
2055 }
2056 
2057 
2058 
2062 
2063 void KVMultiDetArray::AssociateTrajectoriesAndNodes()
2064 {
2065  // Eliminate any trajectories which are just sub-trajectories of others
2066  // For each trajectory in list fTrajectories, we add a reference to the trajectory to each node on the trajectory
2067 
2068  TIter it(&fTrajectories);
2069  KVGeoDNTrajectory* tr;
2070  KVList duplicates;
2071  // look for duplicate sub-trajectories
2072  while ((tr = (KVGeoDNTrajectory*)it())) {
2073  int len_tr = tr->GetN();
2074  TIter it2(&fTrajectories);
2075  KVGeoDNTrajectory* tr2;
2076  while ((tr2 = (KVGeoDNTrajectory*)it2())) {
2077  if ((tr2 != tr) && (len_tr < tr2->GetN()) && (tr2->ContainsPath(tr))) {
2078  duplicates.Add(tr);
2079  break;
2080  }
2081  }
2082  }
2083  // remove duplicates
2084  if (duplicates.GetEntries()) {
2085  TIter it_dup(&duplicates);
2086  while ((tr = (KVGeoDNTrajectory*)it_dup())) {
2087  fTrajectories.Remove(tr);
2088  }
2089  Info("AssociateTrajectoriesAndNodes", "Removed %d duplicated sub-trajectories", duplicates.GetEntries());
2090  }
2091  Info("AssociateTrajectoriesAndNodes", "Calculated %d particle trajectories", fTrajectories.GetEntries());
2092  it.Reset();
2093  while ((tr = (KVGeoDNTrajectory*)it())) {
2094  tr->AddToNodes();
2095  }
2096 }
2097 
2098 
2099 
2101 
2103 {
2104  if (N->GetNTraj() > 1) {
2105  if (!multitraj_nodes.FindObject(N)) { // look for any detectors which are on multiple trajectories
2106  //cout << "multitraj node found: " << N->GetName() << " (" << N->GetNTraj() << ")" << endl;
2107  multitraj_nodes.Add(N);
2108  TIter tr(N->GetTrajectories());
2109  KVGeoDNTrajectory* traj;
2110  while ((traj = (KVGeoDNTrajectory*)tr())) { // for each trajectory associated with detector
2111  if (tried_trajectories.FindObject(traj)) continue; // trajectory already used
2112  tried_trajectories.Add(traj);
2113  traj->IterateFrom();
2114  KVGeoDetectorNode* node;
2115  while ((node = traj->GetNextNode())) { // store names of all detectors on trajectory
2116  detectors_of_group.Add(node);
2117  RecursiveTrajectoryClustering(node, tried_trajectories, multitraj_nodes, detectors_of_group);
2118  }
2119  }
2120  }
2121  }
2122  else if (N->GetNTraj() == 1) {
2123  // single-trajectory node.
2124  // work along trajectory adding nodes to group
2125  KVGeoDNTrajectory* traj = (KVGeoDNTrajectory*)N->GetTrajectories()->First();
2126  if (tried_trajectories.FindObject(traj)) return; // trajectory already used
2127  tried_trajectories.Add(traj);
2128  traj->IterateFrom();
2129  KVGeoDetectorNode* node;
2130  while ((node = traj->GetNextNode())) { // store names of all detectors on trajectory
2131  detectors_of_group.Add(node);
2132  RecursiveTrajectoryClustering(node, tried_trajectories, multitraj_nodes, detectors_of_group);
2133  }
2134  }
2135  else {
2136  // orphan node? single-detector array?
2137  detectors_of_group.Add(N);
2138  }
2139 }
2140 
2141 
2142 
2151 
2153 {
2154  // Create and return pointer to new KVGroupReconstructor for reconstructing particles
2155  // in the given group. Returns nullptr if group is not part of this array.
2156  //
2157  // Plugins for specific arrays can be defined as plugins using the name of the array:
2158  // +Plugin.KVGroupReconstructor: my_array my_group_reconstructor my_lib "my_group_reconstructor()"
2159  //
2160  // If we are in 'SimMode', the default reconstructor is a KVFilterGroupReconstructor
2161 
2162  KVGroupReconstructor* gr(nullptr);
2163  if (GetGroup(g->GetName())) {
2164  // look for plugin
2166  if (!gr) {
2167  if (IsSimMode()) return KVGroupReconstructor::Factory("Filter", g);
2168  else
2169  gr = new KVGroupReconstructor(g);
2170  }
2171  }
2172  return gr;
2173 }
2174 
2175 
2176 
2180 
2182 {
2183  // Call this method just after opening a raw data file in order to perform any
2184  // necessary initialisations, depending on the type of data
2185 
2186 #ifdef WITH_BUILTIN_GRU
2187  if (r->GetDataFormat() == "EBYEDAT")
2188  dynamic_cast<KVGANILDataReader*>(r)->ConnectRawDataParameters();
2189 #endif
2190 }
2191 
2192 
2193 
2198 
2199 void KVMultiDetArray::DeduceGroupsFromTrajectories()
2200 {
2201  // Deduce the "groups" in the array from the trajectories
2202  // Any trajectories with 1 or more common detectors define a group.
2203  // The group is constituted of all detectors belonging to the trajectories of the group.
2204 
2205  Info("DeduceGroupsFromTrajectories", "Deducing groups of detectors from trajectories");
2206  Int_t number_of_groups = 0;
2207  TIter next_det(GetDetectors());
2208  unique_ptr<KVSeqCollection> stl(GetStructureTypeList("GROUP"));
2209  if (stl.get() && stl->GetEntries()) {
2210  Info("DeduceGroupsFromTrajectories", "Deleting existing %d groups in array", stl->GetEntries());
2211  ClearStructures("GROUP");
2212  Info("DeduceGroupsFromTrajectories", "Done");
2213  }
2214  KVDetector* det;
2215  KVUniqueNameList tried_trajectories;//avoid double-counting/infinite loops
2216  KVUniqueNameList multitraj_nodes;//avoid double-counting/infinite loops
2217  while ((det = (KVDetector*) next_det())) {
2218  if (det->GetGroup()) continue; // group assignment already done
2219  KVUniqueNameList detectors_of_group;
2220  RecursiveTrajectoryClustering(det->GetNode(), tried_trajectories, multitraj_nodes, detectors_of_group);
2221  if (!detectors_of_group.GetEntries()) continue;
2222  KVGroup* Group = new KVGroup;
2223  Group->SetNumber(++number_of_groups);
2224  Add(Group);
2225  TIter next_node(&detectors_of_group);
2227  while ((d = (KVGeoDetectorNode*)next_node())) Group->Add(d->GetDetector());
2228  }
2229  TIter tr(&fTrajectories);
2230  KVGeoDNTrajectory* t;
2231  Info("DeduceGroupsFromTrajectories", "Filling group trajectory lists");
2232  while ((t = (KVGeoDNTrajectory*)tr())) {
2233  if (t->GetNodeAt(0)->GetDetector()->GetGroup())
2234  t->GetNodeAt(0)->GetDetector()->GetGroup()->AddTrajectory(t);
2235  else {
2236  t->Print();
2237  t->GetNodeAt(0)->GetDetector()->Print();
2238  }
2239  }
2240 }
2241 
2242 
2243 
2247 
2249 {
2250  // Called when required to fill KVReconstructedNucleus::fDetList with pointers to
2251  // the detectors whose names are stored in KVReconstructedNucleus::fDetNames.
2252 
2253  DetList->Clear();
2254  DetNames.Begin("/");
2255  while (!DetNames.End()) {
2256  KVDetector* det = GetDetector(DetNames.Next(kTRUE));
2257  if (det) DetList->Add(det);
2258  }
2259 }
2260 
2261 
2262 
2282 
2284 {
2285  // Set status of particle by comparing its identification/calibration codes
2286  // with those set as acceptable in fAcceptIDCodes and fAcceptECodes.
2287  // The status can be tested with method KVReconstructedNucles::IsOK().
2288  //
2289  // The default lists are defined in variables of the form
2290  //```
2291  // [DataSet].[name].ReconstructedNuclei.AcceptIDCodes: [list]
2292  // [DataSet].[name].ReconstructedNuclei.AcceptECodes: [list]
2293  //```
2294  // where:
2295  // + `DataSet` is an optional dataset name for dataset-specific lists
2296  // + `name` is the name of the multidetector array
2297  // + `list` is a numeric list (KVNumberList format)
2298  //
2299  // The default lists can be overridden using methods AcceptIDCodes(), AcceptECodes(),
2300  // AcceptAllIDCodes() and AcceptAllECodes().
2301  //
2302  // If either list is empty, no selection is made for the corresponding code
2303 
2304  Bool_t ok = kTRUE;
2305  if (!fAcceptIDCodes.IsEmpty()) ok = fAcceptIDCodes.Contains(NUC->GetIDCode());
2306  if (!fAcceptECodes.IsEmpty()) ok = ok && fAcceptECodes.Contains(NUC->GetECode());
2307  NUC->SetIsOK(ok);
2308 }
2309 
2310 
2311 #ifdef WITH_BUILTIN_GRU
2312 
2315 
2316 Bool_t KVMultiDetArray::handle_raw_data_event_ebyedat(KVGANILDataReader&)
2317 {
2318  // General method for reading raw data in old GANIL ebyedat format
2319  AbstractMethod("handle_raw_data_event_ebyedat");
2320  return kFALSE;
2321 }
2322 
2323 #endif
2324 
2325 
2328 
2330 {
2331  // reset acquisition parameters etc. before reading new raw data event
2332 
2333  fReconParameters.Clear();
2334  fFiredDetectors.Clear();
2335  fHandledRawData = false;
2336  // reset fired signals
2337  TIter nxt(&fFiredSignals);
2338  KVDetectorSignal* ds;
2339  while ((ds = (KVDetectorSignal*)nxt())) {
2340  ds->SetFired(false);
2341  ds->SetValue(0);
2342  }
2343  fFiredSignals.Clear();
2344 }
2345 
2346 
2347 
2355 
2356 void KVMultiDetArray::PerformClosedROOTGeometryOperations()
2357 {
2358  // Perform any operations to finalise the description of the multidetector
2359  // which can only be done once the geometry is closed, e.g. use KVGeoImport
2360  // to set up nodes, trajectories, detectors, idtelescopes, etc.
2361  // This has to be kept separate for use with KVExpSetUp which first fills
2362  // a single ROOT geometry with all component KVMultiDetArray geometries,
2363  // then closes the geometry only when all have been built.
2364 }
2365 
2366 
2367 
2370 
2372 {
2373  // Copy any parameters in fReconParameters in to the reconstructed event parameter list
2374  e->GetParameters()->Concatenate(fReconParameters);
2375 }
2376 
2377 
2378 
2391 
2392 void KVMultiDetArray::copy_fired_parameters_to_recon_param_list()
2393 {
2394  // values of fired raw data signals (acquisition parameters) from last read raw event
2395  // are copied to the fReconParameters list of parameters to be stored with the
2396  // reconstructed event.
2397  //
2398  // the format for each signal is:
2399  //
2400  // ACQPAR.[array].[detector].[signal]
2401  // ACQPAR.[array].[signal]
2402  //
2403  // in the first case for signals associated with detectors, in the latter case signals
2404  // which are not associated with a detector
2405 
2406  TIter it(GetFiredSignals());
2407  KVDetectorSignal* o;
2408  while ((o = (KVDetectorSignal*)it())) {
2409  fReconParameters.SetValue(Form("ACQPAR.%s.%s", GetName(), o->GetFullName().Data()), o->GetValue());
2410  }
2411 }
2412 
2413 
2414 
2423 
2425 {
2426  // Update array according to last event read using the KVRawDataReader object
2427  // (it is assumed that KVRawDataReader::GetNextEvent() was called before calling this method)
2428  //
2429  // Return kTRUE if raw data was treated
2430  //
2431  // All fired acquisition parameters are written in the fReconParameters list,
2432  // ready to be copied to the reconstructed event
2433 
2434  fRawDataReader = rawdata;
2436  if (rawdata->GetDataFormat() == "MFM") {
2437 #ifdef WITH_MFM
2438  fHandledRawData = handle_raw_data_event_mfmfile(dynamic_cast<KVMFMDataFileReader&>(*rawdata));
2439 #endif
2440  }
2441  else if (rawdata->GetDataFormat() == "PROTOBUF") {
2442 #ifdef WITH_PROTOBUF
2443  fHandledRawData = handle_raw_data_event_protobuf(dynamic_cast<KVProtobufDataReader&>(*rawdata));
2444 #endif
2445  }
2446  else if (rawdata->GetDataFormat() == "EBYEDAT") {
2447 #ifdef WITH_BUILTIN_GRU
2448  fHandledRawData = handle_raw_data_event_ebyedat(dynamic_cast<KVGANILDataReader&>(*rawdata));
2449 #endif
2450  }
2451  if (fHandledRawData) {
2452  copy_fired_parameters_to_recon_param_list();
2453  }
2454  return fHandledRawData;
2455 }
2456 
2457 
2458 #ifdef WITH_MFM
2459 
2468 
2470 {
2471  // Update array according to last event read from MFM buffer
2472  // (it is assumed that MFMBufferReader::ReadNextFrame() was called before calling this method)
2473  //
2474  // Return kTRUE if raw data was treated
2475  //
2476  // All fired acquisition parameters are written in the fReconParameters list,
2477  // ready to be copied to the reconstructed event
2478 
2480  bool ok = false;
2481  ok = handle_raw_data_event_mfmfile(bufrdr);
2482  if (ok) {
2483  copy_fired_parameters_to_recon_param_list();
2484  }
2485  return ok;
2486 }
2487 
2488 #endif
2489 
2490 
2501 
2502 void KVMultiDetArray::add_and_set_detector_signal(KVDetector* detector, KVString detname, Double_t sig_data, KVString sig_type)
2503 {
2504  // Given a pointer to a detector (may be nullptr) try to set the data sig_data in the associated signal
2505  // of the given type, sig_typ.
2506  //
2507  // If the signal does not exist for the detector, it will be created.
2508  //
2509  // If detector pointer is null, the signal will be looked for in fExtraRawDataSignals
2510  // and created if necessary.
2511  //
2512  // All fired detectors and signals are added to the lists fFiredDetectors and fFiredSignals.
2513 
2514  KVDetectorSignal* det_signal = nullptr;
2515  if (detector) {
2516  det_signal = detector->GetDetectorSignal(sig_type);
2517  if (!det_signal) {
2518  det_signal = detector->AddDetectorSignal(sig_type);
2519  }
2520  fFiredDetectors.Add(detector);
2521  }
2522  else {
2523  // raw data not associated with a detector
2524  TString sig_name;
2525  if (detname != "") sig_name = Form("%s.%s", detname.Data(), sig_type.Data());
2526  else sig_name = sig_type;
2527  det_signal = fExtraRawDataSignals.get_object<KVDetectorSignal>(sig_name);
2528  if (!det_signal) {
2529  det_signal = new KVDetectorSignal(sig_name);
2530  fExtraRawDataSignals.Add(det_signal);
2531  }
2532  }
2533  if (det_signal) {
2534  det_signal->SetValue(sig_data);
2535  det_signal->SetFired();
2536  fFiredSignals.Add(det_signal);
2537  }
2538 }
2539 
2540 
2541 
2547 
2549 {
2550  // Take values 'ACQPAR.[array_name].[detname].[signal]' or 'ACQPAR.[array_name].[signal]'
2551  // in the parameter list and use them to set values of raw acquisition parameters.
2552  //
2553  // Any detector signals which don't already exist will be created
2554 
2555  prepare_to_handle_new_raw_data(); // clear previous fired parameters/detectors
2556  auto l = recev.GetParameters();
2557  int N = l->GetNpar();
2558  for (int i = 0; i < N; ++i) {
2559  KVNamedParameter* np = l->GetParameter(i);
2560 
2561  KVString name(np->GetName());
2562  if (name.BeginsWith("ACQPAR")) {
2563  // 3 '.' => 4 values means associated detector
2564  // 2 '.' => 3 values means no detector
2565  int dots = name.GetNValues(".");
2566  bool with_det = (dots == 4);
2567  assert(with_det || (dots == 3)); // sanity check
2568  name.Begin(".");
2569  name.Next(); // "ACQPAR"
2570  if (name.Next() != GetName()) continue; // check name of array - somebody else's parameter ?
2571  KVString det_name;
2572  KVString sig_type;
2573  KVDetector* det = nullptr;
2574  if (with_det) {
2575  det_name = name.Next();
2576  sig_type = name.Next();
2577  det = GetDetector(det_name);
2578  }
2579  else {
2580  sig_type = name.Next();
2581  }
2582  add_and_set_detector_signal(det, det_name, np->GetDouble(), sig_type);
2583  }
2584  }
2585 }
2586 
2587 
2588 
2607 
2609 {
2610  // We first look for following files with the name given by
2611  //
2612  // [dataset].[name].OoODetectors: [name.OoODetectors.dat]
2613  // which should contain the runlists for each malfunctioning detector.
2614  // If found we add to the experiment database a table '[name].OoO Detectors' where [name] is the name of this array.
2615  //
2616  // [dataset].[name].AbsentDetectors: [name.AbsentDetectors.dat]
2617  // which should contain the runlists for each absent detector.
2618  // If found we add to the experiment database a table '[name].Absent Detectors' where [name] is the name of this array.
2619  //
2620  // Then we look for a file with the name given by
2621  //
2622  // [dataset].[name].CalibrationFiles: [CalibrationFiles.dat]
2623  //
2624  // which should contain the names of files to read with each type of calibration
2625  // If found we add to the experiment database a table '[name].Calibrations' where [name] is the name of this array,
2626  // containing all calibrations as KVDBParameterSet objects with the name of the detector concerned.
2627  db->SetDBType(Form("%sDB", GetName()));
2628  ReadOoODetectors(db);
2629  ReadAbsentDetectors(db);
2630  ReadCalibrationFiles(db);
2631 }
2632 
2633 
2634 
2636 
2637 TString KVMultiDetArray::GetFileName(KVExpDB* db, const Char_t* meth, const Char_t* keyw)
2638 {
2639  TString basic_name = db->GetCalibFileName(keyw);
2640  if (basic_name == "") {
2641  Info(meth, "No name found for \"%s\" file", keyw);
2642  return "";
2643  }
2644  Info(meth, "Search for %s for dataset %s ...", basic_name.Data(), fDataSet.Data());
2645  TString fp;
2646  SearchKVFile(basic_name.Data(), fp, fDataSet);
2647  if (fp == "") {
2648  Info(meth, "\tNo file found ...");
2649  }
2650  return fp;
2651 }
2652 
2653 
2654 
2656 
2657 unique_ptr<KVFileReader> KVMultiDetArray::GetKVFileReader(KVExpDB* db, const Char_t* meth, const Char_t* keyw)
2658 {
2659 
2660  TString fp = GetFileName(db, meth, keyw);
2661  if (fp == "")
2662  return unique_ptr<KVFileReader>();
2663 
2664  unique_ptr<KVFileReader> fr(new KVFileReader());
2665  if (!fr->OpenFileToRead(fp.Data())) {
2666  KVError::Error(this, meth, "Error in opening file %s", fp.Data());
2667  fr.reset(nullptr);
2668  }
2669  else
2670  KVError::Info(this, meth, "Reading %s file", fp.Data());
2671  return fr;
2672 }
2673 
2674 
2675 
2677 
2678 void KVMultiDetArray::ReadCalibrationFiles(KVExpDB* db)
2679 {
2680 
2681  unique_ptr<KVFileReader> fr = GetKVFileReader(db, "ReadCalibrationFiles()", "CalibrationFiles");
2682  if (!fr.get())
2683  return;
2684 
2685  KVDBTable* calib_table = db->AddTable(Form("%s.Calibrations", GetName()), Form("Calibrations for %s", GetName()));
2686  while (fr->IsOK()) {
2687  fr->ReadLine(0);
2688  if (fr->GetCurrentLine().BeginsWith("#") || fr->GetCurrentLine() == "") {}
2689  else {
2690  ReadCalibFile(fr->GetCurrentLine().Data(), db, calib_table);
2691  }
2692  }
2693  fr->CloseFile();
2694 }
2695 
2696 
2697 
2743 
2744 void KVMultiDetArray::ReadCalibFile(const Char_t* filename, KVExpDB* db, KVDBTable* calib_table)
2745 {
2746  // Read a calibration file with the format
2747  //
2748  //~~~~~~~~~~~~~
2749  // RunList: 1546-7485
2750  // SignalIn: PG
2751  // SignalOut: Volts
2752  // CalibType: ChannelVolt
2753  // CalibOptions: func=pol3,min=0,max=1
2754  // ZRange: 2-92
2755  // [detector1]: 0.0,0.261829,0.0
2756  // [detector2]: 0.1 0.539535 1.2
2757  //~~~~~~~~~~~~~
2758  //
2759  //The `[RunList]` is optional: if not given, the calibration will be applied to all runs in the database.
2760  //
2761  //If different parameters are required for different sets of runs, they should be written in different
2762  //files (all of which are listed in `CalibrationFiles.dat` or `[array].CalibrationFiles.dat`).
2763  //
2764  //Numerical parameter values for each detector can be given separated by commas, whitespace or tab characters.
2765  //
2766  //The `[CalibClass]`, if given, must correspond to a KVCalibrator plugin name. The list of plugin names and the corresponding
2767  //classes can be retrieved with
2768  //
2769  //~~~~~~~~~~~
2770  //KVBase::GetListOfPlugins("KVCalibrator")
2771  //KVBase::GetListOfPluginURIs("KVCalibrator")
2772  //~~~~~~~~~~~
2773  //
2774  //KVCalibrator objects are added to detectors as required by the contents of calibration files.
2775  //If any detector has an existing calibrator of type `[CalibType]` which is not of the given class
2776  //it will be replaced with a new calibrator corresponding to the plugin.
2777  //
2778  //The `[CalibOptions]` is optional: list in `[CalibOptions]` will be used
2779  //to complete set-up of any new calibrator objects by calling the KVCalibrator::SetOptions()
2780  //method.
2781  //
2782  //`[CalibOptions]` should hold a comma-separated list of `parameter=value` pairs which will be used
2783  //to fill a KVNameValueList for the method call. See the KVCalibrator::SetOptions() method.
2784  //
2785  //`[ZRange]` is an option if several calibrations need to be used to provide the same signal
2786  //for certain detectors depending on the atomic number Z of the particle detected.
2787  //
2788  // If any of the detector names (`[detector1]`, `[detector2]` in above example) contains the `'*'` wildcard character,
2789  // it will be interpreted as a list of detectors whose names correspond to the given wildcard expression.
2790 
2791 
2792  TString fullpath = "";
2793  if (!SearchKVFile(filename, fullpath, fDataSet)) {
2794  Info("ReadCalibFile", "%s does not exist or not found", filename);
2795  return;
2796  }
2797 
2798  Info("ReadCalibFile", "file : %s found", fullpath.Data());
2799  TEnv env;
2800  env.ReadFile(fullpath, kEnvAll);
2801 
2802  // read options from file
2803  KVNameValueList options;
2804  KVString opt_list = "RunList SignalIn SignalOut CalibType CalibClass CalibOptions ZRange";
2805  opt_list.Begin(" ");
2806  while (!opt_list.End()) {
2807  KVString opt = opt_list.Next();
2808  KVString opt_val = env.GetValue(opt, "");
2809  opt_val.Remove(TString::kBoth, ' ');
2810  options.SetValue(opt, opt_val.Data());
2811  }
2812  // check for stupid spellnig mitskaes
2813  if (TString(env.GetValue("Runlist", "")) != "") {
2814  KVError::Warning(this, "ReadCalibFile", "Calibration has 'Runlist' parameter (ignored): %s, did you mean 'RunList'?", env.GetValue("Runlist", ""));
2815  }
2816 
2817  if (options.GetTStringValue("SignalIn") == "") {
2818  KVError::Error(this, "ReadCalibFile", "No input signal defined : SignalIn");
2819  return;
2820  }
2821  if (options.GetTStringValue("SignalOut") == "") {
2822  KVError::Error(this, "ReadCalibFile", "No output signal defined : SignalOut");
2823  return;
2824  }
2825  if (options.GetTStringValue("CalibType") == "") {
2826  KVError::Error(this, "ReadCalibFile", "No calibration type defined : CalibType");
2827  return;
2828  }
2829  Bool_t check_class(options.GetTStringValue("CalibClass") != "");
2830  TString calibrator_class;
2831  if (check_class) {
2832  TPluginHandler* ph = LoadPlugin("KVCalibrator", options.GetStringValue("CalibClass"));
2833  if (ph) calibrator_class = ph->GetClass();
2834  else {
2835  KVError::Error(this, "ReadCalibFile", "No calibrator plugin of type %s", options.GetStringValue("CalibClass"));
2836  return;
2837  }
2838  }
2839 
2840  KVString clop;
2841  if (options.HasParameter("CalibOptions")) clop = options.GetStringValue("CalibOptions");
2842 
2843  KVString zrange;
2844  if (options.HasParameter("ZRange")) zrange = options.GetStringValue("ZRange");
2845 
2846  KVNumberList run_list = db->GetRunList();
2847  if (options.GetTStringValue("RunList") != "") {
2848  run_list.Set(options.GetTStringValue("RunList"));
2849  Info("ReadCalibFile", "Calibration used for runs %s", run_list.AsString());
2850  }
2851  else {
2852  Info("ReadCalibFile", "Calibration used for all runs in database");
2853  }
2854 
2855  TIter next(env.GetTable());
2856  TEnvRec* rec = nullptr;
2857  KVDBParameterSet* par = nullptr;
2858 
2859  // valid delimiters for numerical parameters are: space - comma - tab
2860  // here we add ':' because if there is space in the TEnv file between the key name and the ':'
2861  // i.e. if we have
2862  // SI2-11 : 0.1,0.3
2863  // then the ':' becomes part of the value: TEnv::GetValue("SI2-11","") will give ": 0.1,0.3"
2864  // instead of
2865  // SI2-11: 0.1,0.3
2866  // => TEnv::GetValue("SI2-11","") gives "0.1,0.3"
2867  TString param_delimiters = ":, \t";
2868 
2869  auto set_calib_parameters = [&](const TEnvRec* rec, const KVDetector* det)
2870  {
2871  KVString lval(rec->GetValue());
2872  par = new KVDBParameterSet(det->GetName(), options.GetStringValue("CalibType"), lval.GetNValues(param_delimiters));
2873  par->SetParameter("SignalIn", options.GetStringValue("SignalIn"));
2874  par->SetParameter("SignalOut", options.GetStringValue("SignalOut"));
2875  // put infos on required calibrator class into database so that it can be replaced
2876  // as needed in SetCalibratorParameters
2877  par->SetParameter("CalibClass", options.GetStringValue("CalibClass"));
2878  if (clop != "") par->SetParameter("CalibOptions", clop);
2879  if (zrange != "") par->SetParameter("ZRange", zrange);
2880  Int_t np = 0;
2881  lval.Begin(param_delimiters);
2882  while (!lval.End()) {
2883  par->SetParameter(np++, lval.Next().Atof());
2884  }
2885  calib_table->AddRecord(par);
2886  db->LinkRecordToRunRange(par, run_list);
2887  };
2888 
2889  while ((rec = (TEnvRec*)next()))
2890  {
2891  std::unique_ptr<KVSeqCollection> det_list{GetDetectorNameList(rec->GetName())};
2892  for(auto p_det : *det_list)
2893  set_calib_parameters(rec,dynamic_cast<KVDetector*>(p_det));
2894  }
2895 }
2896 
2897 
2898 #ifdef WITH_MFM
2899 
2905 
2906 Bool_t KVMultiDetArray::handle_raw_data_event_mfmfile(MFMBufferReader& mfmreader)
2907 {
2908  // Update array according to last event read using the KVMFMDataFileReader object
2909  // (it is assumed that KVRawDataReader::GetNextEvent() was called before calling this method)
2910  //
2911  // Return kTRUE if raw data was treated
2912 
2913  if (mfmreader.IsFrameReadMerge()) {
2914  return handle_raw_data_event_mfmmergeframe(mfmreader.GetMergeManager());
2915  }
2916  else {
2917  return handle_raw_data_event_mfmframe(mfmreader.GetFrameRead());
2918  }
2919  return kFALSE;
2920 }
2921 
2922 
2923 
2927 
2928 Bool_t KVMultiDetArray::handle_raw_data_event_mfmmergeframe(const MFMMergeFrameManager& mergeframe)
2929 {
2930  // Method used to handle merged MFM frames
2931  // We call handle_raw_data_event_mfmframe() for each frame contained in the merge
2932 
2933  Bool_t ok = false;
2934  while (mergeframe.ReadNextFrame()) {
2935  Bool_t me = handle_raw_data_event_mfmframe(mergeframe.GetFrameRead());
2936  ok = (ok || me);
2937  }
2938  return ok;
2939 }
2940 
2941 
2942 
2953 
2954 Bool_t KVMultiDetArray::handle_raw_data_event_mfmframe(const MFMCommonFrame& mfmframe)
2955 {
2956  // Method used to treat raw data in MFM format read by KVMFMDataFileReader
2957  //
2958  // Here we dispatch two types of frame - MFMEbyedatFrame & MFMMesytecMDPPFrame -
2959  // to specific methods - handle_raw_data_event_mfmframe_ebyedat() and
2960  // handle_raw_data_event_mfmframe_mesytec_mdpp()
2961  // which need to be implemented in child classes for specific arrays which
2962  // use these data formats.
2963  //
2964  // Return kTRUE if raw data was treated
2965 #ifdef WITH_MESYTEC
2966  if (mfmframe.GetFrameType() == MFM_MESYTEC_FRAME_TYPE)
2967  return handle_raw_data_event_mfmframe_mesytec_mdpp((const MFMMesytecMDPPFrame&)mfmframe);
2968 #endif
2969  if (mfmframe.GetFrameType() == MFM_EBY_EN_FRAME_TYPE
2970  || mfmframe.GetFrameType() == MFM_EBY_TS_FRAME_TYPE
2971  || mfmframe.GetFrameType() == MFM_EBY_EN_TS_FRAME_TYPE)
2972  return handle_raw_data_event_mfmframe_ebyedat((const MFMEbyedatFrame&)mfmframe);
2973 
2974  return kFALSE;
2975 }
2976 
2977 
2978 
2981 
2982 Bool_t KVMultiDetArray::handle_raw_data_event_mfmframe_ebyedat(const MFMEbyedatFrame&)
2983 {
2984  // Read a raw data event from a EBYEDAT MFM Frame.
2985 
2986  AbstractMethod("handle_raw_data_event_mfmframe_ebyedat");
2987  return kFALSE;
2988 }
2989 
2990 
2991 #ifdef WITH_MESYTEC
2992 
2995 
2996 Bool_t KVMultiDetArray::handle_raw_data_event_mfmframe_mesytec_mdpp(const MFMMesytecMDPPFrame&)
2997 {
2998  // Read a raw data event from a Mesytec MFM Frame.
2999 
3000  AbstractMethod("handle_raw_data_event_mfmframe_mesytec_mdpp");
3001  return kFALSE;
3002 }
3003 
3004 #endif
3005 #endif
3006 
3007 #ifdef WITH_PROTOBUF
3008 
3010 
3011 Bool_t KVMultiDetArray::handle_raw_data_event_protobuf(KVProtobufDataReader&)
3012 {
3013  AbstractMethod("handle_raw_data_event_protobuf");
3014  return kFALSE;
3015 }
3016 
3017 #endif
3018 
3019 
3022 
3024 {
3025  // For each IDtelescope in array, calculate an identification grid
3026 
3027  TIter nxtid(GetListOfIDTelescopes());
3028  KVIDTelescope* idt;
3029  while ((idt = (KVIDTelescope*) nxtid())) {
3030  idt->CalculateDeltaE_EGrid("1-92", 0, 20);
3031  }
3032 }
3033 
3034 
3035 
3040 
3042 {
3043  // Sets status of detectors (KVDetector::IsPresent() and KVDetector::IsWorking()) for a given run of a dataset.
3044  //
3045  // If 'myname' is given, we look in database table "myname.OoODets"
3046 
3047  KVRList* absdet = (myname != "" ? kvrun->GetLinks(Form("%s.Absent Detectors", myname.Data())) : kvrun->GetLinks("Absent Detectors"));
3048  KVRList* ooodet = (myname != "" ? kvrun->GetLinks(Form("%s.OoO Detectors", myname.Data())) : kvrun->GetLinks("OoO Detectors"));
3049 
3050  TIter next(GetDetectors());
3051  KVDetector* det;
3052 
3053  Int_t ndet_absent = 0;
3054  Int_t ndet_ooo = 0;
3055  TString absent_dets, ooo_dets;
3056 
3057  while ((det = (KVDetector*)next())) {
3058  //Test de la presence ou non du detecteur
3059  if (!absdet) {
3060  det->SetPresent();
3061  }
3062  else {
3063  if (absdet->FindObject(det->GetName())) {
3064  det->SetPresent(kFALSE);
3065  if (ndet_absent) absent_dets += ",";
3066  absent_dets += det->GetName();
3067  ndet_absent += 1;
3068  }
3069  else {
3070  det->SetPresent();
3071  }
3072  }
3073  if (det->IsPresent()) {
3074  //Test du bon fonctionnement ou non du detecteur
3075  if (!ooodet) {
3076  det->SetDetecting();
3077  }
3078  else {
3079  if (ooodet->FindObject(det->GetName())) {
3080  det->SetDetecting(kFALSE);
3081  if (ndet_ooo) ooo_dets += ",";
3082  ooo_dets += det->GetName();
3083  ndet_ooo += 1;
3084  }
3085  else {
3086  det->SetDetecting();
3087  }
3088  }
3089  }
3090  }
3091 
3092  if (ndet_absent) Info("CheckStatusOfDetectors", "%d detectors absent during run : %s", ndet_absent, absent_dets.Data());
3093  else Info("CheckStatusOfDetectors", "All detectors present during run");
3094  if (ndet_ooo) Info("CheckStatusOfDetectors", "%d detectors malfunctioned during run : %s", ndet_ooo, ooo_dets.Data());
3095  else Info("CheckStatusOfDetectors", "All detectors functioning during run");
3096 }
3097 
3098 
3099 
3101 
3103 {
3104  CheckStatusOfDetectors(dbr, myname);
3105 }
3106 
3107 
3108 
3123 
3124 void KVMultiDetArray::ReadOoODetectors(KVExpDB* db)
3125 {
3126  // Read a file containing runlists for each temporarily non-functioning detector.
3127  //
3128  // The file should be in TEnv format like so:
3129  //
3130  //~~~~
3131  // DET_1: 100-122,541-1938
3132  // DET_2,DET_3: 91-765
3133  //~~~~
3134  //
3135  // i.e. more than one detector can be associated with the same runs (comma-separated list of
3136  // detector names) and the list of runs are given using KVNumberList syntax.
3137  //
3138  // The data is added to the database in a table '[name].OoO Detectors' with the name of this array.
3139 
3140  TString fullpath;
3141  if (!db->FindCalibFile("OoODet", fullpath, GetName())) return;
3142 
3143  Info("ReadOoODetectors()", "Reading lists of out-of-order detectors...");
3144  auto fOoODet = db->AddTable(Form("%s.OoO Detectors", GetName()), "Name of out of order detectors");
3145 
3146  KVDBRecord* dbrec = 0;
3147  TEnv env;
3148  TEnvRec* rec = 0;
3149  env.ReadFile(fullpath.Data(), kEnvAll);
3150  TIter it(env.GetTable());
3151 
3152  while ((rec = (TEnvRec*)it.Next())) {
3153  KVString srec(rec->GetName());
3154  KVNumberList nl(rec->GetValue());
3155  if (srec.Contains(",")) {
3156  srec.Begin(",");
3157  while (!srec.End()) {
3158  dbrec = new KVDBRecord(srec.Next(kTRUE), "OoO Detector");
3159  dbrec->AddKey("Runs", "List of Runs");
3160  fOoODet->AddRecord(dbrec);
3161  db->LinkRecordToRunRange(dbrec, nl);
3162  }
3163  }
3164  else {
3165  dbrec = new KVDBRecord(rec->GetName(), "OoO Detector");
3166  dbrec->AddKey("Runs", "List of Runs");
3167  fOoODet->AddRecord(dbrec);
3168  db->LinkRecordToRunRange(dbrec, nl);
3169  }
3170  }
3171 }
3172 
3173 
3188 
3189 void KVMultiDetArray::ReadAbsentDetectors(KVExpDB* db)
3190 {
3191  // Read a file containing runlists for each temporarily absent/dismounted detector.
3192  //
3193  // The file should be in TEnv format like so:
3194  //
3195  //~~~~
3196  // DET_1: 100-122,541-1938
3197  // DET_2,DET_3: 91-765
3198  //~~~~
3199  //
3200  // i.e. more than one detector can be associated with the same runs (comma-separated list of
3201  // detector names) and the list of runs are given using KVNumberList syntax.
3202  //
3203  // The data is added to the database in a table '[name].Absent Detectors' with the name of this array.
3204 
3205  TString fullpath;
3206  if (!db->FindCalibFile("AbsentDet", fullpath, GetName())) return;
3207 
3208  Info("ReadAbsentDetectors()", "Reading lists of absent/dismounted detectors... file=[%s]", fullpath.Data());
3209  auto fAbsDet = db->AddTable(Form("%s.Absent Detectors", GetName()), "Name of out of order detectors");
3210 
3211  KVDBRecord* dbrec = 0;
3212  TEnv env;
3213  TEnvRec* rec = 0;
3214  env.ReadFile(fullpath.Data(), kEnvAll);
3215  TIter it(env.GetTable());
3216 
3217  while ((rec = (TEnvRec*)it.Next())) {
3218  KVString srec(rec->GetName());
3219  KVNumberList nl(rec->GetValue());
3220  if (srec.Contains(",")) {
3221  srec.Begin(",");
3222  while (!srec.End()) {
3223  dbrec = new KVDBRecord(srec.Next(kTRUE), "Absent Detector");
3224  dbrec->AddKey("Runs", "List of Runs");
3225  fAbsDet->AddRecord(dbrec);
3226  db->LinkRecordToRunRange(dbrec, nl);
3227  }
3228  }
3229  else {
3230  dbrec = new KVDBRecord(rec->GetName(), "Absent Detector");
3231  dbrec->AddKey("Runs", "List of Runs");
3232  fAbsDet->AddRecord(dbrec);
3233  db->LinkRecordToRunRange(dbrec, nl);
3234  }
3235  }
3236 }
3237 
3238 
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
#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:195
virtual const Char_t * GetType() const
Definition: KVBase.h:177
static const Char_t * GetWORKDIRFilePath(const Char_t *namefile="")
Definition: KVBase.cpp:120
const Char_t * GetLabel() const
Definition: KVBase.h:199
static bool is_gnuinstall()
Definition: KVBase.h:276
void Print(Option_t *option="") const override
Definition: KVBase.cpp:412
virtual void SetType(const Char_t *str)
Definition: KVBase.h:173
static Bool_t SearchKVFile(const Char_t *name, TString &fullpath, const Char_t *kvsubdir="")
Definition: KVBase.cpp:540
static TPluginHandler * LoadPlugin(const Char_t *base, const Char_t *uri="0")
Definition: KVBase.cpp:795
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.
Bool_t Init(KVDataSetRepository *=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:2149
const Char_t * GetDataSetDir() const
Definition: KVDataSet.cpp:756
Bool_t HasCalibIdentInfos() const
Definition: KVDataSet.h:381
void cd() const
Definition: KVDataSet.cpp:778
Bool_t DataBaseUpdateInProgress() const
Definition: KVDataSet.h:187
ValType GetDataSetEnv(const Char_t *type, const ValType &defval={}) const
Definition: KVDataSet.h:270
static Bool_t FindDataSetFile(const TString &dataset, const Char_t *filename)
Definition: KVDataSet.cpp:2185
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:173
void SetThickness(Double_t thick) override
KVGroup * GetGroup() const
Bool_t IsCalibrated(const KVNameValueList &params={}) const
Definition: KVDetector.cpp:527
void Print(Option_t *option="") const override
Definition: KVDetector.cpp:338
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:608
virtual KVDetectorSignal * GetDetectorSignal(const KVString &type) const
Definition: KVDetector.h:543
void SetDetecting(Bool_t yes=kTRUE)
Definition: KVDetector.h:671
virtual void RemoveCalibrators()
Definition: KVDetector.cpp:684
KVGeoDetectorNode * GetNode()
Definition: KVDetector.h:354
virtual Bool_t IsPresent() const
Definition: KVDetector.h:657
Bool_t AddCalibrator(KVCalibrator *cal, const KVNameValueList &opts="")
Definition: KVDetector.cpp:421
void SetPresent(Bool_t yes=kTRUE)
Definition: KVDetector.h:662
KVNameValueList * GetParameters() const
Definition: KVEvent.h:180
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:31
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 Bool_t IsReadyForID()
KVIDGrid * CalculateDeltaE_EGrid(const KVNameValueList &AperZ, Int_t npoints=30, Double_t xfactor=1.)
void SetGroup(KVGroup *kvg)
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:115
static KVIonRangeTable * GetRangeTable()
Definition: KVMaterial.cpp:158
Base class for describing the geometry of a detector array.
const KVSeqCollection * GetFiredSignals() const
KVSeqCollection * GetListOfIDTelescopes() const
void FillListOfIDTelescopes(KVIDGraph *gr) const
virtual void GetDetectorEvent(KVDetectorEvent *detev, const TSeqCollection *fired_params=0)
void MakeHistogramsForAllIDTelescopes(KVSeqCollection *list, Int_t dimension=100)
TList * GetStatusOfIDTelescopes()
void Draw(Option_t *option="") override
static KVMultiDetArray * MakeMultiDetector(const Char_t *dataset_name, Int_t run=-1, TString classname="KVMultiDetArray", KVExpDB *db=nullptr)
virtual Double_t GetTargetEnergyLossCorrection(KVReconstructedNucleus *)
KVSeqCollection * GetIDTelescopesWithType(const Char_t *type)
KVTarget * GetTarget()
void RecursiveTrajectoryClustering(KVGeoDetectorNode *N, KVUniqueNameList &tried_trajectories, KVUniqueNameList &multitraj_nodes, KVUniqueNameList &detectors_of_group)
virtual void SetRawDataFromReconEvent(const KVReconstructedEvent &)
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
Bool_t IsSimMode() const
Bool_t ReadGridsFromAsciiFile(const Char_t *) const
virtual void InitialiseRawDataReading(KVRawDataReader *)
virtual void SetParameters(UInt_t n, Bool_t physics_parameters_only=kFALSE)
virtual void SetDetectorParametersForRun(KVDBRun *, const TString &="")
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
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 &)
void CheckStatusOfDetectors(KVDBRun *, const TString &="")
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()
virtual void Build(Int_t run=-1)
virtual void FillDetectorList(KVReconstructedNucleus *rnuc, KVHashList *DetList, const KVString &DetNames)
const TSeqCollection * GetTrajectories() const
TList * GetCalibrationStatusOfDetectors()
TGeoManager * GetGeometry() const
Return pointer to the (ROOT) geometry of the array.
virtual Bool_t HandleRawDataEvent(KVRawDataReader *)
virtual void InitializeIDTelescopes()
virtual void SetRunCalibrationParameters(UShort_t n)
void PrintStatusOfIDTelescopes()
void PrintCalibStatusOfDetectors()
virtual void SetCalibratorParameters(KVDBRun *, const TString &="")
virtual void SetPartSeedCond(const Char_t *cond)
void SetGridsInTelescopes(UInt_t run)
KVIDTelescope * GetIDTelescope(const Char_t *name) const
Return pointer to DeltaE-E ID Telescope with "name".
virtual void SetReconParametersInEvent(KVReconstructedEvent *) const
Copy any parameters in fReconParameters in to the reconstructed event parameter list.
virtual void AcceptParticleForAnalysis(KVReconstructedNucleus *) const
void SetNavigator(KVGeoNavigator *geo)
KVMultiDetArray()
Default constructor.
KVUpDater * GetUpDater()
KVUniqueNameList GetIDTelescopeTypes()
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
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)
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
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)
RVec< PromoteType< T > > abs(const RVec< T > &v)
TGraphErrors * gr
TH1 * h
void Error(UserClass p, const char *location, const char *va_(fmt),...)
Definition: KVError.h:116
void Warning(UserClass p, const char *location, const char *va_(fmt),...)
Definition: KVError.h:125
void Info(UserClass p, const char *location, const char *va_(fmt),...)
Definition: KVError.h:134
void init()
rec
Int_t Nint(T x)
TLine l
ClassImp(TPyArg)