KaliVeda  1.13/01
Heavy-Ion Analysis Toolkit
KVMultiDetArray.cpp
Go to the documentation of this file.
1 //Created by KVClassFactory on Tue Apr 16 09:45:50 2013
2 //Author: John Frankland,,,
3 
4 #include "KVMultiDetArray.h"
5 #include "Riostream.h"
6 #include "TROOT.h"
7 #include "KVDetector.h"
8 #include "KVDetectorEvent.h"
9 #include "KVReconstructedEvent.h"
10 #include "KVReconstructedNucleus.h"
11 #include "KVRList.h"
12 #include "KVLayer.h"
13 #include "KVTemplateEvent.h"
14 #include "KVNucleus.h"
15 #include "KVGroup.h"
16 #include "KVRing.h"
17 #include "KVTelescope.h"
18 #include "KVMaterial.h"
19 #include "KVTarget.h"
20 #include "KVIDTelescope.h"
21 #include "KV2Body.h"
22 #include <KVString.h>
23 #include <TObjString.h>
24 #include <TObjArray.h>
25 #include <KVIDGridManager.h>
26 #include <KVDataSetManager.h>
27 #include <KVUpDater.h>
28 #include "TPluginManager.h"
29 #include "KVDataSet.h"
30 #include "TGeoManager.h"
31 #include "TGeoMedium.h"
32 #include "TGeoMaterial.h"
33 #include "KVHashList.h"
34 #include "KVNameValueList.h"
35 #include "KVUniqueNameList.h"
36 #include "KVIonRangeTable.h"
38 #include <KVDataAnalyser.h>
39 #include <KVNamedParameter.h>
40 #include <KVCalibrator.h>
41 #include <KVDBParameterSet.h>
42 #ifdef WITH_RSQLITE
43 #include <KVSQLROOTIDGridManager.h>
44 #endif
45 #ifdef WITH_OPENGL
46 #include <TGLViewer.h>
47 #include <TVirtualPad.h>
48 #endif
49 #ifdef WITH_BUILTIN_GRU
50 #include "KVGANILDataReader.h"
51 #else
52 #include "KVRawDataReader.h"
53 #endif
54 #ifdef WITH_MFM
55 #include "KVMFMDataFileReader.h"
56 #include "MFMEbyedatFrame.h"
57 #ifdef WITH_MESYTEC
58 #include "MFMMesytecMDPPFrame.h"
59 #endif
60 #endif
61 #ifdef WITH_PROTOBUF
62 #include "KVProtobufDataReader.h"
63 #endif
64 using namespace std;
65 
67 
71 
73 
74 
75 
79  : KVGeoStrucElement(), fTrajectories(kTRUE)
80 {
81  // Default constructor
82  init();
83  gMultiDetArray = this;
84 }
85 
86 
87 
90 
92  : KVGeoStrucElement(name, type), fTrajectories(kTRUE)
93 {
94  // Constructor with name and optional type
95  init();
96  gMultiDetArray = this;
97 }
98 
99 
100 
112 
114 {
115  //Basic initialisation called by constructor.
116  //Creates detectors list fDetectors,
117  //groups list fGroups, identification telescopes list
118  //fIDTelescopes
119  //
120  //The fGroups & fIDTelescopes lists contain objects owned by the multidetector array,
121  //but which may be deleted by other objects (or as a result of the deletion of other
122  //objects: i.e. if all the detectors in a group are deleted, the group itself is destroyed).
123  //We use the ROOT automatic garbage collection to make sure that any object deleted
124  //elsewhere is removed automatically from these lists.
125 
126  fIDTelescopes = new KVHashList();
127  fIDTelescopes->SetOwner(kTRUE); // owns its objects
129 
130  fHitGroups = 0;
131 
132  fTarget = 0;
133  fCurrentRun = 0;
134 
136  fCalibStatusDets = 0;
137  fSimMode = kFALSE;
138 
139  fROOTGeometry = gEnv->GetValue("KVMultiDetArray.ROOTGeometry", kTRUE);
141 
142  fNavigator = 0;
143  fUpDater = 0;
144 
146 
147  // all trajectories belong to us
149 
150  //all detectors belong to us
152 
153  fRawDataReader = nullptr;
154  fHandledRawData = false;
155 
156  // any extra raw data signals created when reading data belong to us
158 }
159 
160 
161 
164 
166 {
167  //destroy (delete) the MDA and all the associated structure, detectors etc.
168 
170  //destroy all identification telescopes
173  delete fIDTelescopes;
174  }
175  fIDTelescopes = 0;
176 
177  if (gMultiDetArray == this)
178  gMultiDetArray = nullptr;
179 
180  if (fStatusIDTelescopes) {
182  delete fStatusIDTelescopes;
184  }
185  if (fCalibStatusDets) {
187  delete fCalibStatusDets;
188  fCalibStatusDets = 0;
189  }
190 
191  if (fNavigator) {
192  if (gGeoManager) {
193  delete gGeoManager;
194  gGeoManager = nullptr;
195  }
196  delete fNavigator;
197  fNavigator = nullptr;
198  }
200 }
201 
202 
203 
204 
205 
207 
209 {
210 
211 
212 
213 }
214 
215 
216 
217 
239 
241 {
242  // Create one or more KVIDTelescope particle-identification objects from the two detectors
243  //
244  // The different ID telescopes are defined as 'Plugin' objects in the file $KVROOT/KVFiles/.kvrootrc :
245  // # The KVMultiDetArray::GetIDTelescopes(KVDetector*de, KVDetector*e) method uses these plugins to
246  // # create KVIDTelescope instances adapted to the specific array geometry and detector types.
247  // # For each pair of detectors we look for a plugin with one of the following names:
248  // # [name_of_dataset].array_name.de_detector_type[de detector thickness]-e_detector_type[de detector thickness]
249  // # Each characteristic in [] brackets may or may not be present in the name; first we test for names
250  // # with these characteristics, then all combinations where one or other of the characteristics is not present.
251  // # In addition, we first test all combinations which begin with [name_of_dataset].
252  // # The first plugin found in this order will be used.
253  // # In addition, if for one of the two detectors there is a plugin called
254  // # [name_of_dataset].array_name.de_detector_type[de detector thickness]
255  // # [name_of_dataset].array_name.e_detector_type[e detector thickness]
256  // # then we add also an instance of this 1-detector identification telescope.
257  //
258  // This method is called by DeduceIdentificationTelescopesFromGeometry
259  // in order to set up all ID telescopes of the array.
260  //
261  // Returns number of ID telescopes created
262 
263  Int_t ntels = 0;
264  // if both detectors are not OK then stop
265  if (!de->IsOK() && !e->IsOK()) return ntels;
266 
267  if (fDataSet == "" && gDataSet) fDataSet = gDataSet->GetName();
268 
269  //look for ID telescopes starting from furthest from target
270  if (e->IsOK()) ntels += try_all_singleID_telescopes(e, list);
271  if (de != e) {
272  if (e->IsOK() && de->IsOK()) ntels += try_all_doubleID_telescopes(de, e, list);
273  if (de->IsOK()) ntels += try_all_singleID_telescopes(de, list);
274  }
275 
276  return ntels;
277 }
278 
279 
280 
298 
300 {
301  // Attempt to find a plugin KVIDTelescope class for making a single-detector
302  // ID telescope from detector *d
303  // We look for plugins with the following signatures (uri):
304  //
305  // [array name].[type]
306  // [array_name].[type][thickness]
307  //
308  // where 'type' is the type of the detector in UPPER or lowercase letters
309  // 'thickness' is the nearest-integer thickness of the detector as returned by d->GetThickness()
310  // In addition, if a dataset is set (gDataSet!=nullptr) we try also for dataset-specific
311  // plugins:
312  //
313  // [dataset].[array name].[type]
314  // [dataset].[array name].[type][thickness]
315  //
316  // Returns number of generated telescopes
317 
318  TString uri = Form("%s.%s", GetName(), d->GetType());
319  Int_t ntels = 0;
320  if (!(ntels += try_upper_and_lower_singleIDtelescope(uri, d, l))) {
321  Int_t d_thick = TMath::Nint(d->GetThickness());
322  uri += d_thick;
323  ntels += try_upper_and_lower_singleIDtelescope(uri, d, l);
324  }
325  return ntels;
326 }
327 
328 
329 
330 
353 
355 {
356  // Attempt to find a plugin KVIDTelescope class for making an ID telescope from detectors de & e.
357  // We look for plugins with the following signatures (uri):
358  //
359  // [array name].[de-type]-[e-type]
360  // [array name].[de-type][thickness]-[e-type]
361  // [array name].[de-type]-[e-type][thickness]
362  // [array name].[de-type][thickness]-[e-type][thickness]
363  //
364  // where 'type' is the type of the detector in UPPER or lowercase letters
365  // 'thickness' is the nearest-integer thickness of the detector.
366  // In addition, if a dataset is set (gDataSet!=nullptr) we try also for dataset-specific
367  // plugins:
368  //
369  // [dataset].[array name].[de-type][thickness]-[e-type][thickness]
370  // [dataset].[array name].[de-type][thickness]-[e-type]
371  // [dataset].[array name].[de-type]-[e-type][thickness]
372  // [dataset].[array name].[de-type]-[e-type]
373  //
374  // if no plugin is found, we return a KVIDTelescope base class object
375  //
376  // Returns 1 (we always generate exactly one telescope)
377 
378  TString de_type = de->GetType();
379  TString e_type = e->GetType();
380  TString de_thick = Form("%d", TMath::Nint(de->GetThickness()));
381  TString e_thick = Form("%d", TMath::Nint(e->GetThickness()));
382 
383  TString uri = de_type + de_thick + "-" + e_type + e_thick;
384  uri.Prepend(Form("%s.", GetName()));
385  if (try_upper_and_lower_doubleIDtelescope(uri, de, e, l)) return 1;
386 
387  uri = de_type + de_thick + "-" + e_type;
388  uri.Prepend(Form("%s.", GetName()));
389  if (try_upper_and_lower_doubleIDtelescope(uri, de, e, l)) return 1;
390 
391  uri = de_type + "-" + e_type + e_thick;
392  uri.Prepend(Form("%s.", GetName()));
393  if (try_upper_and_lower_doubleIDtelescope(uri, de, e, l)) return 1;
394 
395  uri = de_type + "-" + e_type;
396  uri.Prepend(Form("%s.", GetName()));
397  if (try_upper_and_lower_doubleIDtelescope(uri, de, e, l)) return 1;
398 
399  // default id telescope object
400  KVIDTelescope* idt = new KVIDTelescope;
401  uri = de_type + "-" + e_type;
402  idt->SetLabel(uri);
403  // set type as "[DEtype]-[Etype]" where "[*type]" is type of DE/E detectors
404  idt->SetType(Form("%s-%s", de_type.Data(), e_type.Data()));
405  set_up_telescope(de, e, idt, l);
406 
407  return 1;
408 }
409 
410 
411 
419 
421 {
422  // Attempt to find a plugin KVIDTelescope class for making a single-detector
423  // ID telescope from detector *d with the given signature/uri
424  // Both original & all-upper-case versions of uri are tried.
425  // uri is tried both with & without prepended dataset name (if set)
426  // Returns true if successful (the new ID telescope will be added to internal
427  // list fIDTelescopes and also to TCollection* l)
428 
429  if (try_a_singleIDtelescope(uri, d, l)) return true;
430  uri.ToUpper();
431  return try_a_singleIDtelescope(uri, d, l);
432 }
433 
434 
435 
442 
444 {
445  // Attempt to find a plugin KVIDTelescope class for making an ID telescope with the given signature/uri
446  // Both original & all-upper-case versions of uri are tried.
447  // uri is tried both with & without prepended dataset name (if set)
448  // Returns true if successful (the new ID telescope will be added to internal
449  // list fIDTelescopes and also to TCollection* l)
450 
451  if (try_a_doubleIDtelescope(uri, de, e, l)) return true;
452  uri.ToUpper();
453  return try_a_doubleIDtelescope(uri, de, e, l);
454 }
455 
456 
457 
466 
468 {
469  // Attempt to find a plugin KVIDTelescope class for making a single-detector
470  // ID telescope from detector *d with the given signature/uri
471  // Both original & all-upper-case versions of uri are tried.
472  // uri is tried both with & without prepended dataset name (if set)
473  // Returns true if successful (the new ID telescope will be added to internal
474  // list fIDTelescopes and also to TCollection* l)
475 
476  // dataset-specific version takes precedence over default
477  TString duri = uri;
478  if (gDataSet) {
479  // try with dataset name
480  duri.Prepend(Form("%s.", fDataSet.Data()));
481  KVIDTelescope* idt;
482  if ((idt = KVIDTelescope::MakeIDTelescope(duri))) {
484  return true;
485  }
486  }
487 
488  // look for default version
489  KVIDTelescope* idt;
490  if ((idt = KVIDTelescope::MakeIDTelescope(uri))) {
492  return true;
493  }
494 
495  return false;
496 }
497 
498 
499 
506 
508 {
509  // Attempt to find a plugin KVIDTelescope class for making an ID telescope with the given signature/uri
510  // uri is tried both with & without prepended dataset name (if set)
511  // Returns true if successful (the new ID telescope will be added to internal
512  // list fIDTelescopes and also to TCollection* l)
513 
514  // dataset-specific version takes precedence over default
515  TString duri = uri;
516  if (gDataSet) {
517  // try with dataset name
518  duri.Prepend(Form("%s.", fDataSet.Data()));
519  KVIDTelescope* idt;
520  if ((idt = KVIDTelescope::MakeIDTelescope(duri))) {
521  set_up_telescope(de, e, idt, l);
522  return true;
523  }
524  }
525  // look for default version
526  KVIDTelescope* idt;
527  if ((idt = KVIDTelescope::MakeIDTelescope(uri))) {
528  set_up_telescope(de, e, idt, l);
529  return true;
530  }
531 
532  return false;
533 }
534 
535 
536 
539 
541 {
542  // Set up detectors in de-e identification telescope and add to fIDTelescopes and to l
543 
544  idt->AddDetector(de);
545  idt->AddDetector(e);
546  if (de->GetGroup()) {
547  idt->SetGroup(de->GetGroup());
548  }
549  else {
550  idt->SetGroup(e->GetGroup());
551  }
552  // if telescope already exists, we delete this new version and add a reference to
553  // the original into list l
555  if (p) {
556  l->Add(p);
557  delete idt;
558  }
559  else {
560  fIDTelescopes->Add(idt);
561  l->Add(idt);
562  }
563 }
564 
565 
566 
569 
571 {
572  // Set up detector in single-stage identification telescope and add to fIDTelescopes and to l
573 
574  idt->AddDetector(det);
575  idt->SetGroup(det->GetGroup());
576  // if telescope already exists, we delete this new version and add a reference to
577  // the original into list l
579  if (p) {
580  l->Add(p);
581  delete idt;
582  }
583  else {
584  fIDTelescopes->Add(idt);
585  l->Add(idt);
586  }
587 }
588 
589 
591 
593 {
594  fIDTelescopes->Delete(); // clear out (delete) old identification telescopes
595  KVGroup* grp;
596  unique_ptr<KVSeqCollection> fGroups(GetStructures()->GetSubListWithType("GROUP"));
597  TIter ngrp(fGroups.get());
598  while ((grp = (KVGroup*) ngrp())) {
600  }
601 }
602 
603 
604 
605 
609 
611 {
612  //Number groups according to position in list fGroups and set fGr counter to the number
613  //of groups in the list
614  Int_t fGr = 0;
615  KVGroup* g = 0;
616  KVSeqCollection* fGroups = GetStructures()->GetSubListWithType("GROUP");
617  TIter next(fGroups);
618  while ((g = (KVGroup*) next())) {
619  g->SetNumber(++fGr);
620  }
621  delete fGroups;
622 }
623 
624 
625 
626 
632 
634 {
635  // Perform multi-hit and coherency analysis of filtered event.
636  // round=1,2,... depending on number of times method has been called
637  // Returns number of particles whose status were changed.
638  // When this becomes zero, the coherency analysis is finished
639 
640  Int_t nchanged = 0;
641  KVReconstructedNucleus* recon_nuc;
642 
643  while ((recon_nuc = rec_event->GetNextParticle())) {
644  if (!recon_nuc->IsIdentified()) {
645  int dethits = recon_nuc->GetStoppingDetector()->GetHits()->GetEntries() ;
647  Bool_t pileup = kFALSE;
648  if (dethits > 1) {
649  // if any of the other particles also stopped in the same detector, we assume identification
650  // will be so false as to reject particle
651  for (int j = 0; j < dethits; j++) {
653  if (n != recon_nuc && n->GetStoppingDetector() == recon_nuc->GetStoppingDetector()) pileup = kTRUE;
654  }
655  }
656  if (pileup) {
657  nchanged++;
658  recon_nuc->SetIsIdentified();//to stop looking anymore & to allow identification of other particles in same group
659  if (idtelstop) recon_nuc->SetIDCode(GetBadIDCode());// idtelstop->SetIDCode(recon_nuc, idtelstop->GetBadIDCode());
660  else recon_nuc->SetIsOK(kFALSE);
661  }
662  else if (recon_nuc->GetStatus() == 3) {
663  //stopped in first member
664  recon_nuc->SetIsIdentified();
665  nchanged++;
666  }
667  else if (recon_nuc->GetStatus() == 2) {
668  // pile-up in first stage of telescopes
669  recon_nuc->SetIsIdentified();
670  if (idtelstop && idtelstop->IsReadyForID()) recon_nuc->SetIDCode(GetMultiHitFirstStageIDCode());//idtelstop->SetIDCode(recon_nuc, idtelstop->GetMultiHitFirstStageIDCode());
671  else recon_nuc->SetIsOK(kFALSE);
672  nchanged++;
673  }
674  else if (recon_nuc->GetStatus() == 0) {
675  // try to "identify" the particle
677  idtelstop = (KVIDTelescope*)nxtidt();
678  while (idtelstop) {
679  if (idtelstop->IsReadyForID() && idtelstop->CanIdentify(recon_nuc->GetZ(), recon_nuc->GetA())
680  && idtelstop->CheckTheoreticalIdentificationThreshold(recon_nuc)) { // make sure we are above identification threshold
681  nchanged++;
682  // if this is not the first round, this particle has been 'identified' after
683  // dealing with other particles in the group
684  if (round > 1) recon_nuc->SetIDCode(GetCoherencyIDCode());//idtelstop->SetIDCode(recon_nuc, idtelstop->GetCoherencyIDCode());
685  recon_nuc->SetIsIdentified();
686  recon_nuc->SetIsCalibrated();
687  idtelstop->SetIdentificationStatus(recon_nuc);
688  break;
689  }
690  else {
691  Int_t nseg = recon_nuc->GetNSegDet();
692  recon_nuc->SetNSegDet(TMath::Max(nseg - 1, 0));
693  //if there are other unidentified particles in the group and NSegDet is < 2
694  //then exact status depends on segmentation of the other particles : reanalyse
695  if (recon_nuc->GetNSegDet() < 2 &&
697  nchanged++;
698  break;
699  }
700  //if NSegDet = 0 it's hopeless
701  if (!recon_nuc->GetNSegDet()) {
702  nchanged++;
703  break;
704  }
705  }
706  idtelstop = (KVIDTelescope*)nxtidt();
707  }
708  }
709  }
710  }
711  return nchanged;
712 }
713 
714 
715 
801 
802 void KVMultiDetArray::DetectEvent(KVEvent* event, KVReconstructedEvent* rec_event, const Char_t* detection_frame)
803 {
804  //Simulate detection of event by multidetector array.
805  //
806  // optional argument detection_frame(="" by default) can be used to give name of
807  // inertial reference frame (defined for all particles of 'event') to be used.
808  // e.g. if the simulated event's default reference frame is the centre of mass frame, before calling this method
809  // you should create the 'laboratory' or 'detector' frame with KVEvent::SetFrame(...), and then give the
810  // name of the 'LAB' or 'DET' frame as 3rd argument here.
811  //
812  //For each particle in the event we calculate first its energy loss in the target (if the target has been defined, see KVMultiDetArray::SetTarget).
813  //By default these energy losses are calculated from a point half-way along the beam-direction through the target (taking into account the orientation
814  //of the target), if you want random depths for each event call GetTarget()->SetRandomized() before using DetectEvent().
815  //
816  //If the particle escapes the target then we look for the group in the array that it will hit. If there is one, then the detection of this particle by the
817  //different members of the group is simulated. The actual geometry and algorithms used to calculate the particle's trajectory depend on the
818  //value of fROOTGeometry (modify with SetROOTGeometry(kTRUE/kFALSE):
819  // if kTRUE: we use the ROOT TGeo description of the array generated by CreateGeoManager(). In this case, CreateGeoManager()
820  // must be called once in order to set up the geometry.
821  // if kFALSE: we use the simplistic KaliVeda geometry, i.e. detectors are only defined by min/max polar & azimuthal angles.
822  //
823  //The detectors concerned have their fEloss members set to the energy lost by the particle when it crosses them.
824  //
825  //Give tags to the simulated particles via KVNucleus::AddGroup() method
826  //Two general tags :
827  // - DETECTED : cross at least one active layer of one detector
828  // - UNDETECTED : go through dead zone or stopped in target
829  //We add also different sub group :
830  // - For UNDETECTED particles : "NO HIT", "NEUTRON", "DEAD ZONE", "STOPPED IN TARGET" and "THRESHOLD", the last one concerned particle
831  //go through the first detection stage of the multidetector array but stopped in an absorber (ie an inactive layer)
832  // - For DETECTED particles :
833  // "PUNCH THROUGH" corrresponds to particle which cross all the materials in front of it
834  // (high energy particle punh through), or which miss some detectors due to a non perfect
835  // overlap between defined telescope,
836  // "INCOMPLETE" corresponds to particles which stopped in the first detection stage of the multidetector
837  // in a detector which can not give alone a clear identification,
838  // this correponds to status=3 or idcode=5 in INDRA data
839  //
840  //After the filtered process, a reconstructed event are obtain from the fired groups corresponding
841  //to detection group where at least one detector havec an active layer energy loss greater than zero
842  //this reconstructed event are available for the user in the KVReconstructedEvent* rec_event argument
843  //This pointer is cleared and also the multidet array at the beginning of the method
844  //
845  //INFO to the user :
846  // - at this point the different PILE-UP, several particles going through same telescope, detector
847  // are only taken into account for filter type KVMultiDetArray::kFilterType_Full
848  // - specific cases correponding specific multi detectors are to be implemented in the child class
849  //
850  // === FILTER TYPES ===
851  // Use gMultiDetArray->SetFilterType(...) with one of the following values:
852  // KVMultiDetArray::kFilterType_Geo geometric filter only, particles are kept if they hit detector in the array
853  // energy losses are not calculated, particle energies are irrelevant
854  // KVMultiDetArray::kFilterType_GeoThresh particles are kept if they have enough energy to leave the target,
855  // and enough energy to cross at least one detector of the array
856  // ---> for these two cases, accepted particles are copied into the 'reconstructed' event with their
857  // original simulated energy, charge and mass, although angles are randomized to reflect detector granularity
858  //
859  // KVMultiDetArray::kFilterType_Full full simulation of detection of particles by the array. the calibration parameters
860  // for the chosen run (call to gMultiDetArray->SetParameters(...)) are inverted in order
861  // to calculate pseudo-raw data from the calculated energy losses. the resulting pseudo-raw
862  //
863  // SIMULATED EVENT PARAMETERS
864  // ==========================
865  // The event given as input to the method may contain extra information in its parameter
866  // list concerning the simulation. The parameter list of the event is copied into that of the
867  // reconstructed event, therefore these informations can be accessed from the reconstructed
868  // event using the method
869  // rec_event->GetParameters()
870  //
871  // SIMULATED PARTICLE PARAMETERS
872  // ==========================
873  // For filter types KVMultiDetArray::kFilterType_Geo and KVMultiDetArray::kFilterType_GeoThresh,
874  // for which there is a 1-to-1 correspondance between simulated and reconstructed particles,
875  // we copy the list of parameters associated to each input particle into the output particle.
876  // Note that this list contains full informations on the detection of each particle
877  // (see Users Guide chapter on Filtering)
878  //
879  // TRACKING (only with ROOT geometries)
880  // ====================================
881  // You can visualise the trajectories of particles for individual events in the 3D OpenGL viewer.
882  // To enable this:
883  // gMultiDetArray->GetNavigator()->SetTracking(kTRUE)
884  // Then you can do:
885  // gMultiDetArray->DetectEvent(...)
886  // gMultiDetArray->Draw("tracks")
887  // The geometry of the array with the tracks overlaid will be displayed.
888 
889  if (!event) {
890  Error("DetectEvent", "the KVEvent object pointer has to be valid");
891  return;
892  }
893  if (!rec_event) {
894  Error("DetectEvent", "the KVReconstructedEvent object pointer has to be valid");
895  return;
896  }
897 
898  if (IsROOTGeometry()) {
899  if (!gGeoManager) {
900  Error("DetectEvent", "ROOT geometry is requested, but has not been set: gGeoManager=0x0");
901  return;
902  }
903  if (!fNavigator) {
904  Error("DetectEvent", "Using ROOT geometry, but no navigator exists");
905  return;
906  }
907  if (fNavigator->IsTracking()) {
908  // clear any tracks created by last event
911  }
912  }
913 
914  //Clear the KVReconstructed pointer before a new filter process
915  rec_event->Clear();
916  //Copy any parameters associated with simulated event into the reconstructed event
917  event->GetParameters()->Copy(*(rec_event->GetParameters()));
918  if (!fHitGroups) {
919  //Create the list where fired groups will be stored
920  //for reconstruction
921  fHitGroups = new KVDetectorEvent;
922  }
923  else {
924  //Clear the multidetector before a new filter process
925  fHitGroups->Clear();
926  }
927 
928  // iterate through list of particles
929  KVNucleus* part, *_part;
930  KVNameValueList det_stat;
931  KVNameValueList* nvl = 0;
932  KVNameValueList un;
933 
934  Int_t part_index = 0; //index of particle in event
935  while ((part = event->GetNextNucleus())) { // loop over particles
936  ++part_index;
937  TList* lidtel = 0;
938 
939 #ifdef KV_DEBUG
940  cout << "DetectEvent(): looking at particle---->" << endl;
941  part->Print();
942 #endif
943  if (strcmp(detection_frame, "")) _part = (KVNucleus*)part->GetFrame(detection_frame);
944  else _part = (KVNucleus*)part;
945  _part->SetE0();
946  det_stat.Clear();
947  Double_t eLostInTarget = 0;
948  KVDetector* last_det = 0;
949 
950  if (part->GetZ() && !fNavigator->CheckIonForRangeTable(part->GetZ(), part->GetA())) {
951  // ignore charged particles which range table cannot handle
952  det_stat.SetValue("UNDETECTED", Form("Z=%d", part->GetZ()));
953 
954  part->AddGroup("UNDETECTED");
955  part->AddGroup("SUPERHEAVY");
956  }
957  else if (!fNavigator->IsTracking() && (part->GetZ() == 0)) {
958  // when tracking is activated, we follow neutron trajectories
959  // if not, we don't even bother trying
960  det_stat.SetValue("UNDETECTED", "NEUTRON");
961 
962  part->AddGroup("UNDETECTED");
963  part->AddGroup("NEUTRON");
964  }
965  else if (_part->GetKE() < 1.e-3) {
966  det_stat.SetValue("UNDETECTED", "NO ENERGY");
967 
968  part->AddGroup("UNDETECTED");
969  part->AddGroup("NO ENERGY");
970  }
971  else {
972 
973  //Double_t eLostInTarget=0;
974  if (fTarget && part->GetZ()) {
976  //simulate passage through target material
977  Double_t ebef = _part->GetKE();
979  eLostInTarget = ebef - _part->GetKE();
980  if (_part->GetKE() < 1.e-3) {
981  det_stat.SetValue("UNDETECTED", "STOPPED IN TARGET");
982 
983  part->AddGroup("UNDETECTED");
984  part->AddGroup("STOPPED IN TARGET");
985  }
987  }
988 
989  if ((fFilterType != kFilterType_Geo) && _part->GetKE() < 1.e-3) {
990  // unless we are doing a simple geometric filter, particles which
991  // do not have the energy to leave the target are not detected
992  }
993  else {
994  if (!(nvl = DetectParticle(_part))) {
995  if (part->GetZ() == 0) {
996  // tracking
997  det_stat.SetValue("UNDETECTED", "NEUTRON");
998 
999  part->AddGroup("UNDETECTED");
1000  part->AddGroup("NEUTRON");
1001  }
1002  else {
1003  det_stat.SetValue("UNDETECTED", "NO HIT");
1004 
1005  part->AddGroup("UNDETECTED");
1006  part->AddGroup("NO HIT");
1007  }
1008 
1009  }
1010  else if (nvl->GetNpar() == 0) {
1011 
1012  if (part->GetZ() == 0) {
1013  // tracking
1014  det_stat.SetValue("UNDETECTED", "NEUTRON");
1015 
1016  part->AddGroup("UNDETECTED");
1017  part->AddGroup("NEUTRON");
1018  }
1019  else {
1020  part->AddGroup("UNDETECTED");
1021  part->AddGroup("DEAD ZONE");
1022 
1023  det_stat.SetValue("UNDETECTED", "DEAD ZONE");
1024  }
1025  delete nvl;
1026  nvl = 0;
1027  }
1028  else {
1029  Int_t nbre_nvl = nvl->GetNpar();
1030  KVString LastDet(nvl->GetNameAt(nbre_nvl - 1));
1031  last_det = GetDetector(LastDet.Data());
1032  TList* ldet = last_det->GetAlignedDetectors();
1033  TIter it1(ldet);
1034 
1035  Int_t ntrav = 0;
1036  KVDetector* dd = 0;
1037  if (!IsROOTGeometry()) {
1038  //Test de la trajectoire coherente
1039  while ((dd = (KVDetector*)it1.Next())) {
1040  if (dd->GetHits()) {
1041  if (dd->GetHits()->FindObject(_part))
1042  ntrav += 1;
1043  else if (dd->IsSmallerThan(last_det))
1044  ntrav += 1;
1045  }
1046  else {
1047  if (dd->IsSmallerThan(last_det))
1048  ntrav += 1;
1049  }
1050  }
1051  }
1052  else {
1053  ntrav = ldet->GetEntries();
1054  }
1055 
1056  if (ntrav != ldet->GetEntries()) {
1057 
1058  // la particule a une trajectoire
1059  // incoherente, elle a loupe un detecteur avec une ouverture
1060  // plus large que ceux a la suite ou la particule est passe
1061  // (ceci peut etre du a un pb de definition de zone morte autour de certains detecteur)
1062  //
1063  // on retire la particule sur tout les detecteurs
1064  // ou elle est enregistree et on retire egalement
1065  // sa contribution en energie
1066  //
1067  // on assimile en fait ces particules a
1068  // des particules arretes dans les zones mortes
1069  // non detectees
1070  it1.Reset();
1071  //Warning("DetectEvent","trajectoire incoherente ...");
1072  while ((dd = (KVDetector*)it1.Next()))
1073  if (dd->GetHits() && dd->GetHits()->FindObject(_part)) {
1074  if (nvl->HasParameter(dd->GetName())) {
1075  Double_t el = dd->GetEnergy();
1076  el -= nvl->GetDoubleValue(dd->GetName());
1077  dd->SetEnergyLoss(el);
1078  if (dd->GetNHits() == 1)
1079  dd->SetEnergyLoss(0);
1080  }
1081  dd->GetHits()->Remove(_part);
1082  }
1083  det_stat.SetValue("UNDETECTED", "GEOMETRY INCOHERENCY");
1084 
1085  part->AddGroup("UNDETECTED");
1086  part->AddGroup("GEOMETRY INCOHERENCY");
1087  }
1088  else {
1089 
1090  //On recupere les telescopes d identification
1091  //associe au dernier detecteur touche
1092  lidtel = last_det->GetTelescopesForIdentification();
1093  if (lidtel->GetEntries() == 0 && last_det->GetEnergy() <= 0) {
1094  //Arret dans un absorbeur
1095  det_stat.SetValue("UNDETECTED", "THRESHOLD");
1096 
1097  part->AddGroup("UNDETECTED");
1098  part->AddGroup("THRESHOLD");
1099 
1100  //On retire la particule du detecteur considere
1101  //
1102  last_det->GetHits()->Remove(_part);
1103  //Warning("DetectEvent","threshold ...");
1104  }
1105  else {
1106  part->AddGroup("DETECTED");
1107  det_stat.SetValue("DETECTED", "OK");
1108  fHitGroups->AddGroup(last_det->GetGroup());
1109 
1110  if (lidtel->GetEntries() > 0) {
1111  //Il y a possibilite d identification
1112  }
1113  else if (last_det->GetEnergy() > 0) {
1114  //Il n'y a pas de possibilite d'identification
1115  //arret dans le premier etage de detection
1116  det_stat.SetValue("DETECTED", "INCOMPLETE");
1117  part->AddGroup("INCOMPLETE");
1118  }
1119  else {
1120  Warning("DetectEvent", "Cas non prevu ....");
1121  printf("last_det->GetName()=%s, lidtel->GetEntries()=%d, last_det->GetEnergy()=%lf\n",
1122  last_det->GetName(),
1123  lidtel->GetEntries(),
1124  last_det->GetEnergy()
1125  );
1126  }
1127 
1128  //Test d'une energie residuelle non nulle
1129  //La particule n a pas ete arrete par le detecteur
1130  if (_part->GetKE() > 1.e-3) {
1131  //Pour ces deux cas
1132  //on a une information incomplete
1133  //pour la particule
1134  if (nbre_nvl != Int_t(last_det->GetGroup()->GetNumberOfDetectorLayers())) {
1135  //----
1136  // Fuite,
1137  // la particule a loupe des detecteurs normalement aligne
1138  // avec le dernier par laquelle elle est passee
1139  // (ceci peut etre du a un pb de definition de la geometrie)
1140  part->RemoveGroup("DETECTED");
1141  det_stat.RemoveParameter("DETECTED");
1142 
1143  det_stat.SetValue("UNDETECTED", "GEOMETRY INCOHERENCY");
1144  part->AddGroup("UNDETECTED");
1145  part->AddGroup("GEOMETRY INCOHERENCY");
1146  //Warning("DetectEvent","Fuite ......");
1147  }
1148  else if (nbre_nvl) {
1149  //----
1150  // Punch Through,
1151  // La particule est trop energetique, elle a traversee
1152  // tout l'appareillage de detection
1153  //Warning("DetectEvent","Punch Through ......");
1154  part->AddGroup("PUNCH THROUGH");
1155  det_stat.SetValue("DETECTED", "PUNCH THROUGH");
1156  //Warning("DetectEvent","Punch Through ......");
1157  }
1158  } //fin du cas ou la particule avait encore de l energie apres avoir traverser l ensemble du detecteur
1159  } //fin du cas ou la particule a laisse de l energie dans un detecteur
1160  } //fin du cas ou la trajectoire est coherente avec la geometrie
1161  } //fin du cas ou la particule a touche un detecteur au sens large
1162  } //fin de la condition (FilterType == kFilterType_Geo) || _part->GetKE()>1.e-3
1163  } // end case where particle with a non-zero KE left the target
1164 
1165  //On enregistre l eventuelle perte dans la cible
1166  if (fTarget)
1167  part->GetParameters()->SetValue("TARGET Out", eLostInTarget);
1168  //On enregistre le detecteur ou la particule s'arrete
1169  if (last_det)
1170  part->GetParameters()->SetValue("STOPPING DETECTOR", last_det->GetName());
1171  //On enregistre le telescope d'identification
1172  if (lidtel && lidtel->GetEntries()) {
1173  KVIDTelescope* theIDT = 0;
1174  TIter nextIDT(lidtel);
1175  while ((theIDT = (KVIDTelescope*)nextIDT())) {
1176  // make sure particle passed through telescope's detectors
1177  Int_t ndet = theIDT->GetSize();
1178  Int_t ntouche = 0;
1179  for (int i = 1; i <= ndet; i++) {
1180  if (nvl && nvl->HasParameter(Form("%s", theIDT->GetDetector(i)->GetName())))
1181  ntouche++;
1182  }
1183  if (ntouche < ndet) continue;
1184  //Info("DetectEvent","about to check id in %s", theIDT->GetName());
1185  //Info("DetectEvent","ready=%d can identify(%d,%d)=%d", theIDT->IsReadyForID(),part->GetZ(),part->GetA(),theIDT->CanIdentify(part->GetZ(),part->GetA()));
1186  if (fFilterType == kFilterType_Geo ||
1187  (theIDT->IsReadyForID() && theIDT->CanIdentify(part->GetZ(), part->GetA()))) {
1188  //Info("DetectEvent","IDENTIFYING TELESCOPE = %s", theIDT->GetName());
1189  part->GetParameters()->SetValue("IDENTIFYING TELESCOPE", theIDT->GetName());
1190  break;
1191  }
1192  }
1193  }
1194  //On enregistre le statut de detection
1195  //dans l objet KVNucleus
1196  for (Int_t ii = 0; ii < det_stat.GetNpar(); ii += 1) {
1197  part->GetParameters()->SetValue(det_stat.GetNameAt(ii), det_stat.GetStringValue(ii));
1198  }
1199  //On enregistre les differentes pertes d'energie dans les detecteurs
1200  //dans l objet KVNucleus
1201  if (nvl) {
1202 
1203  for (Int_t ii = 0; ii < nvl->GetNpar(); ii += 1) {
1204  TString detname = nvl->GetNameAt(ii);
1205  part->GetParameters()->SetValue(detname, nvl->GetDoubleValue(ii));
1206  // For fFilterType == kFilterType_Full:
1207  // for each detector hit we record the index of each particle hitting the detector
1208  // [detector]="13" => detector hit by particle 13
1209  // if more than one we have
1210  // [detector]="1 6" => detector hit by particles 1 & 6
1211  if (fFilterType == kFilterType_Full) {
1212  if (un.HasParameter(detname)) {
1213  KVNumberList ppp(un.GetStringValue(detname));
1214  ppp.Add(part_index);
1215  un.SetValue(detname, ppp.AsString());
1216  }
1217  else {
1218  un.SetValue(detname, Form("%d", part_index));
1219  }
1220  }
1221  }
1222  delete nvl;
1223  nvl = 0;
1224  }
1225 
1226  _part->SetMomentum(*_part->GetPInitial());
1227 
1228  } //fin de loop over particles
1229 
1230  // Info("DetectEvent", "Finished filtering event. Event status now:");
1231  // event->Print();
1232 
1233  // EVENT RECONSTRUCTION FOR SIMPLE GEOMETRIC FILTER
1234  /*
1235  We keep all particles EXCEPT those belonging to groups
1236  "NO HIT" "DEAD ZONE" or "GEOMETRY INCOHERENCY"
1237  */
1238  if (fFilterType == kFilterType_Geo) {
1239 
1240  KVGroup* grp_tch;
1241  TIter nxt_grp(fHitGroups->GetGroups());
1242  while ((grp_tch = (KVGroup*) nxt_grp())) {
1243  grp_tch->ClearHitDetectors();
1244  }
1245  while ((part = event->GetNextNucleus())) {
1246  if (part->BelongsToGroup("DETECTED") ||
1247  (part->BelongsToGroup("UNDETECTED") &&
1248  !part->BelongsToGroup("NO HIT") &&
1249  !part->BelongsToGroup("DEAD ZONE") &&
1250  !part->BelongsToGroup("GEOMETRY INCOHERENCY") &&
1251  !part->BelongsToGroup("NEUTRON") &&
1252  !part->BelongsToGroup("NO ENERGY"))
1253  ) {
1254  KVDetector* last_det = 0;
1255  if (part->GetParameters()->HasParameter("STOPPING DETECTOR"))
1256  last_det = GetDetector(part->GetParameters()->GetStringValue("STOPPING DETECTOR"));
1257  if (!last_det) continue;
1258  KVReconstructedNucleus* recon_nuc = (KVReconstructedNucleus*)rec_event->AddParticle();
1259  // copy parameter list
1260  part->GetParameters()->Copy(*(recon_nuc->GetParameters()));
1261  recon_nuc->Reconstruct(last_det);
1262  recon_nuc->SetZandA(part->GetZ(), part->GetA());
1263  recon_nuc->SetE(part->GetFrame(detection_frame, kFALSE)->GetE());
1264  if (part->GetParameters()->HasParameter("IDENTIFYING TELESCOPE")) {
1265  KVIDTelescope* idt = GetIDTelescope(part->GetParameters()->GetStringValue("IDENTIFYING TELESCOPE"));
1266  if (idt) {
1267  recon_nuc->SetIdentifyingTelescope(idt);
1268  recon_nuc->SetIDCode(idt->GetIDCode());//idt->SetIDCode(recon_nuc, idt->GetIDCode());
1269  recon_nuc->SetECode(GetNormalCalibrationCode());//recon_nuc->SetECode(idt->GetECode());
1270  }
1271  }
1273  }
1274  }
1275 
1276  // analyse all groups & particles
1277  nxt_grp.Reset();
1278  while ((grp_tch = (KVGroup*) nxt_grp())) {
1280  }
1281  KVReconstructedNucleus* recon_nuc;
1282  while ((recon_nuc = rec_event->GetNextParticle())) {
1283  // check for undetectable pile-ups
1284  if (recon_nuc->GetStatus() == KVReconstructedNucleus::kStatusOK) {
1285  if (recon_nuc->GetStoppingDetector()->GetNHits() > 1)
1287  else {
1288  KVIDTelescope* idt = recon_nuc->GetIdentifyingTelescope();
1289  if (idt) {
1290  KVDetector* de_det = idt->GetDetector(1);
1291  if (de_det->GetNHits() > 1) recon_nuc->SetStatus(KVReconstructedNucleus::kStatusPileupDE);
1292  }
1293  }
1294  }
1295  recon_nuc->SetIsOK(kFALSE);
1297  recon_nuc->SetIsIdentified();
1298  recon_nuc->SetIsCalibrated();
1299  recon_nuc->SetIsOK();
1300  recon_nuc->SetZMeasured();
1301  recon_nuc->SetAMeasured();
1302  }
1303  }
1304  return;
1305  }
1306  // EVENT RECONSTRUCTION FOR SIMPLE GEOMETRIC FILTER WITH THRESHOLDS
1307  /*
1308  We keep all particles belonging to "DETECTED" group
1309  Those in "INCOMPLETE" group are treated as Zmin particles
1310  */
1312  // before reconstruction we have to clear the list of 'hits' of each detector
1313  // (they currently hold the addresses of the simulated particles which were detected)
1314  // which will be filled with the reconstructed particles, otherwise the number of hits
1315  // in each detector will be 2x the real value, and coherency analysis of the reconstructed
1316  // events will not work
1317  KVGroup* grp_tch;
1318  TIter nxt_grp(fHitGroups->GetGroups());
1319  while ((grp_tch = (KVGroup*) nxt_grp())) grp_tch->ClearHitDetectors();
1320  KVReconstructedNucleus* recon_nuc;
1321  while ((part = event->GetNextNucleus())) {
1322  if (part->BelongsToGroup("DETECTED")) {
1323  KVDetector* last_det = 0;
1324  if (part->GetParameters()->HasParameter("STOPPING DETECTOR"))
1325  last_det = GetDetector(part->GetParameters()->GetStringValue("STOPPING DETECTOR"));
1326  if (!last_det || !(last_det->IsOK())) continue;
1327 
1328  recon_nuc = (KVReconstructedNucleus*)rec_event->AddParticle();
1329  // copy parameter list
1330  part->GetParameters()->Copy(*(recon_nuc->GetParameters()));
1331  recon_nuc->Reconstruct(last_det);
1332  recon_nuc->SetZandA(part->GetZ(), part->GetA());
1333  recon_nuc->SetE(part->GetFrame(detection_frame, kFALSE)->GetE());
1334 
1335  if (part->GetParameters()->HasParameter("IDENTIFYING TELESCOPE")) {
1336  KVIDTelescope* idt = GetIDTelescope(part->GetParameters()->GetStringValue("IDENTIFYING TELESCOPE"));
1337  if (idt) {
1338  recon_nuc->SetIdentifyingTelescope(idt);
1339  // for particles which are apprently well-identified, we
1340  // check that they are in fact sufficiently energetic to be identified
1341  if (!part->BelongsToGroup("INCOMPLETE")
1342  && !idt->CheckTheoreticalIdentificationThreshold((KVNucleus*)part->GetFrame(detection_frame, kFALSE)))
1343  part->AddGroup("INCOMPLETE");
1344  if (!part->BelongsToGroup("INCOMPLETE")) {
1345  recon_nuc->SetIDCode(idt->GetIDCode());//idt->SetIDCode(recon_nuc, idt->GetIDCode());
1346  idt->SetIdentificationStatus(recon_nuc);
1347  }
1348  else {
1349  recon_nuc->SetIDCode(GetZminCode());//idt->SetIDCode(recon_nuc, idt->GetZminCode());
1350  }
1351  recon_nuc->SetECode(GetNormalCalibrationCode());
1352  //recon_nuc->SetIsIdentified();
1353  //recon_nuc->SetIsCalibrated();
1354  }
1355  }
1356  else { /*if(part->BelongsToGroup("INCOMPLETE"))*/
1357  // for particles stopping in 1st member of a telescope, there is no "identifying telescope"
1358  //KVIDTelescope* idt = (KVIDTelescope*)last_det->GetIDTelescopes()->First();
1359  //if (idt) idt->SetIDCode(recon_nuc, idt->GetZminCode());
1360  recon_nuc->SetIDCode(GetZminCode());
1361  }
1363  }
1364  }
1365  // analyse all groups & particles
1366  nxt_grp.Reset();
1367  while ((grp_tch = (KVGroup*) nxt_grp())) {
1369  }
1370 
1371  // now perform mult-hit/coherency analysis until no further changes take place
1372  Int_t round = 1, nchanged;
1373  //cout << "SIM: " << event->GetMult() << " REC: " << rec_event->GetMult() << endl;
1374  //for(int i=1;i<=rec_event->GetMult();i++) cout << i << " Z=" << rec_event->GetParticle(i)->GetZ()<<" status="<<rec_event->GetParticle(i)->GetStatus() <<endl;
1375  do {
1376  nchanged = FilteredEventCoherencyAnalysis(round++, rec_event);
1377  //cout << "Round = " << round-1 << " : nchanged = " << nchanged << endl;
1378  nxt_grp.Reset();
1379  while ((grp_tch = (KVGroup*) nxt_grp())) {
1381  }
1382  //for(int i=1;i<=rec_event->GetMult();i++) cout << i << " Z=" << rec_event->GetParticle(i)->GetZ()<<" status="<<rec_event->GetParticle(i)->GetStatus() <<endl;
1383  }
1384  while (nchanged);
1385 
1386  return;
1387  }
1388 
1389  if (fFilterType == kFilterType_Full) {
1390  // Calculate acquisition parameters, taking into account pile-up
1391  KVDetector* det = 0;
1392  for (Int_t nn = 0; nn < un.GetNpar(); nn += 1) {
1393  det = GetDetector(un.GetNameAt(nn));
1394  KVNumberList ppp(un.GetStringValue(nn));
1395  det->DeduceACQParameters(event, ppp);
1396  }
1397 
1398  // before reconstruction we have to clear the list of 'hits' of each detector
1399  // (they currently hold the addresses of the simulated particles which were detected)
1400  // which will be filled with the reconstructed particles, otherwise the number of hits
1401  // in each detector will be 2x the real value, and coherency analysis of the reconstructed
1402  // events will not work
1403  KVGroup* grp_tch;
1404  TIter nxt_grp(fHitGroups->GetGroups());
1405  while ((grp_tch = (KVGroup*) nxt_grp())) {
1406  grp_tch->ClearHitDetectors();
1407  }
1408  // Info("DetectEvent", "Multidetector status before event reconstruction:");
1409  // fHitGroups->Print();
1410 
1411  // reconstruct & identify the event
1412  ReconstructEvent(rec_event, fHitGroups);
1413  rec_event->IdentifyEvent();
1414  // calculate particle energies
1415  rec_event->CalibrateEvent();
1416  // 'coherency'
1417  rec_event->SecondaryIdentCalib();
1418  return;
1419  }
1420 
1421 }
1422 
1423 
1437 
1439 {
1440  // Use ROOT geometry to propagate particle through the array,
1441  // calculating its energy losses in all absorbers, and setting the
1442  // energy loss members of the active detectors on the way.
1443  //
1444  // It is assumed that the ROOT geometry has been generated and is
1445  // pointed to by gGeoManager.
1446  //
1447  // Returns a list (KVNameValueList pointer) of the crossed detectors with their name and energy loss
1448  // if particle hits detector in array, 0 if not (i.e. particle
1449  // in beam pipe or dead zone of the multidetector)
1450  // INFO User has to delete the KVNameValueList after its use
1451 
1452  // list of energy losses in active layers of detectors
1453  KVNameValueList* NVL = 0;
1454  if (!fNavigator) {
1455  Error("DetectParticle_TGEO", "No existing navigator ...");
1456  return 0;
1457  }
1459 
1460  // particle missed all detectors
1461  if (!part->GetParameters()->GetNpar()) return NVL;
1462  else {
1463  // find detectors in array hit by particle
1464  // and set their energies
1465  TIter next(part->GetParameters()->GetList());
1466  KVNamedParameter* param;
1467  while ((param = (KVNamedParameter*)next())) {
1468  KVString pname(param->GetName());
1469  pname.Begin(":");
1470  KVString pn2 = pname.Next();
1471  KVString pn3 = pname.Next();
1472  if (pn2 == "DE") {
1473  pn3.Begin("/");
1474  KVString det_name = pn3.Next();
1475  if (pn3.End() || pn3.Next().BeginsWith("ACTIVE")) {
1476  // energy loss in active layer of detector
1477  KVDetector* curDet = GetDetector(det_name);
1478  if (curDet) {
1479  Double_t de = param->GetDouble();
1480  if (!NVL) NVL = new KVNameValueList;
1481  NVL->SetValue(curDet->GetName(), de);
1482  }
1483  }
1484  }
1485  }
1486  }
1487  return NVL;
1488 }
1489 
1490 
1491 
1507 
1509  KVDetector*)
1510 {
1511  //Replace (and destroy) the named detector in the array with a detector based on the prototype
1512  //given by the pointer new_kvd.
1513 
1514 // KVDetector *kvd = GetDetector(name);
1515 // if (!kvd) {
1516 // Warning("ReplaceDetector", "Detector %s not found", name);
1517 // return;
1518 // }
1519 // //get telescope of detector, so we know where to put the replacement
1520 // KVTelescope *tel = kvd->GetTelescope();
1521 // if (!tel) {
1522 // Error("ReplaceDetector", "Detector %s is not in a telescope", name);
1523 // return;
1524 // }
1525 // tel->ReplaceDetector(kvd, new_kvd);
1526  Warning("ReplaceDetector", "Needs reimplementing");
1527 }
1528 
1529 
1530 
1531 
1534 
1536 {
1537  // Return pointer to telescope in array with name given by "name"
1538  return 0;
1539 }
1540 
1541 
1542 
1545 
1547 {
1548  //Return pointer to DeltaE-E ID Telescope with "name"
1549 
1550  return (KVIDTelescope*) fIDTelescopes->FindObject(name);
1551 }
1552 
1553 
1554 
1555 
1556 
1560 
1562 {
1563  //return pointer to group in array which contains detector or telescope
1564  //with name "name"
1565 
1566  KVTelescope* tel = 0;
1567  KVDetector* det = 0;
1568  KVGroup* grp = 0;
1569  if ((tel = GetTelescope(name))) {
1570  grp = (KVGroup*)tel->GetParentStructure("GROUP");
1571  return grp;
1572  }
1573  if ((det = GetDetector(name))) {
1574  grp = det->GetGroup();
1575  }
1576  return grp;
1577 }
1578 
1579 
1580 
1583 
1585 {
1586  // Return pointer to group with name
1587  return (KVGroup*)GetStructure("GROUP", name);
1588 }
1589 
1590 
1591 
1592 
1593 
1595 
1597 {
1598  AbstractMethod("MakeListOfDetectors");
1599 }
1600 
1601 
1602 
1607 
1609 {
1610  //Reset all groups (lists of detected particles etc.)
1611  //and detectors in groups (energy losses, ACQparams etc. etc.)
1612  //and the target if there is one
1613 
1614  unique_ptr<KVSeqCollection> fGroups(GetStructures()->GetSubListWithType("GROUP"));
1615 
1616  TIter next(fGroups.get());
1617  KVGroup* grp;
1618  while ((grp = (KVGroup*) next())) {
1619  grp->Reset();
1620  }
1621  if (GetTarget())
1622  GetTarget()->Clear();
1623 }
1624 
1625 
1626 //void KVMultiDetArray::AddACQParam(KVACQParam* par)
1627 //{
1628 // //Add an acquisition parameter corresponding to a detector of the array.
1629 // //The fACQParams list is added to the list of cleanups (gROOT->GetListOfCleanups).
1630 // //Each acq-param has its kMustCleanup bit set.
1631 // //Thus, if the acq-param is deleted (e.g. by the detector which owns it), it is
1632 // //automatically removed from the fACQParams list by ROOT.
1633 
1634 // if (!fACQParams) {
1635 // fACQParams = new KVHashList;
1636 // fACQParams->SetName(Form("List of acquisition parameters for multidetector array %s", GetName()));
1637 // fACQParams->SetOwner(kFALSE);
1638 // fACQParams->SetCleanup(kTRUE);
1639 // }
1640 // if (par) {
1641 // fACQParams->Add(par);
1642 // }
1643 // else
1644 // Warning("AddACQParam", "Null pointer passed as argument");
1645 //}
1646 
1647 
1648 //void KVMultiDetArray::SetACQParams()
1649 //{
1650 // // Set up acquisition parameters in all detectors of the array + any acquisition parameters which are not
1651 // // directly related to a detector.
1652 // //
1653 // // Override the method SetArrayACQParams() in order to add any acquisition parameters not directly
1654 // // related to a detector.
1655 // //
1656 // // For the detector acquisition parameters, we loop over all detectors of the array and call each detector's
1657 // // SetACQParams() method, if it has not already been done (i.e. if the detector has no associated parameters).
1658 // // Each specific implementation of a KVDetector class should redefine the KVDetector::SetACQParams()
1659 // // method in order to give the detector in question the necessary acquisition parameters (KVACQParam objects).
1660 // //
1661 // // The list of acquisition parameters of each detector is then used to
1662 // // 1) add to fACQParams list of all acquisition parameters of the array
1663 // // 2) set as "not working" the acquisition parameters for which environment variables such as
1664 // // [dataset name].KVACQParam.[acq par name].Working: NO
1665 // // are set in a .kvrootrc file.
1666 // // 3) set bitmask for each detector used to determine which acquisition parameters are
1667 // // taken into account by KVDetector::Fired based on the environment variables
1668 // // [classname].Fired.ACQParameterList.[type]: PG,GG,T
1669 // // where [classname]=KVDetector by default, or the name of some class
1670 // // derived from KVDetector which calls the method KVDetector::SetKVDetectorFiredACQParameterListFormatString()
1671 // // in its constructor.
1672 
1673 // if (fACQParams) {
1674 // fACQParams->Clear();
1675 // }
1676 
1677 // SetArrayACQParams();
1678 
1679 // TIter next(GetDetectors());
1680 // KVDetector* det;
1681 // while ((det = (KVDetector*) next())) {
1682 // KVSeqCollection* l = det->GetACQParamList();
1683 // if (!l) {
1684 // //detector has no acq params
1685 // //set up acqparams in detector
1686 // det->SetACQParams();
1687 // l = det->GetACQParamList();
1688 // }
1689 // //loop over acqparams and add them to fACQParams list, checking
1690 // //their status (working or not working ?)
1691 // TIter next_par(l);
1692 // KVACQParam* par;
1693 // while ((par = (KVACQParam*) next_par())) {
1694 // AddACQParam(par);
1695 // par->SetWorking(gDataSet->GetDataSetEnv(Form("KVACQParam.%s.Working", par->GetName()), kTRUE));
1696 // }
1697 // // set bitmask
1698 // KVString inst;
1699 // inst.Form(det->GetFiredACQParameterListFormatString(), det->GetType());
1700 // KVString lpar = gDataSet->GetDataSetEnv(inst);
1701 // det->SetFiredBitmask(lpar);
1702 // }
1703 //}
1704 
1705 
1706 //void KVMultiDetArray::SetArrayACQParams()
1707 //{
1708 // // Method called by SetACQParams() in order to define any acquisition parameters which are not
1709 // // directly related to any detectors of the array.
1710 // // This implementation does nothing: override it in derived classes if needed.
1711 //}
1712 
1713 
1719 
1721 {
1722  // Sets up calibrators for all detectors with a defined calibration for run
1723  // Set parameters for all detectors with links to table "Calibrations" for run
1724  // If 'myname' is given, we look in "myname.Calibrations"
1725 
1726  //Reset all calibrators of all detectors first
1727  TIter next(GetDetectors());
1728  KVDetector* kvd;
1729  while ((kvd = (KVDetector*) next())) kvd->RemoveCalibrators();
1730 
1731  TString tabname = (myname != "" ? Form("%s.Calibrations", myname.Data()) : "Calibrations");
1732  Info("SetCalibratorParameters", "For array %s in table %s", GetName(), tabname.Data());
1733  KVRList* run_links = r->GetLinks(tabname);
1734  if (run_links) Info("SetCalibratorParameters", "Found %d calibrations for this run", run_links->GetEntries());
1735  else {
1736  Warning("SetCalibratorParameters", "Got no links for %s", tabname.Data());
1737  r->GetKeys()->ls();
1738  return;
1739  }
1740  TIter nxt_link(run_links);
1741  KVDBParameterSet* dbps;
1742  while ((dbps = (KVDBParameterSet*)nxt_link())) {
1743 
1744  KVDetector* det = GetDetector(dbps->GetName());
1745  if (!det) {
1746  Warning("SetCalibratorParameters", "Got parameters for unknown detector: %s", dbps->GetName());
1747  continue;
1748  }
1749 
1750  KVNameValueList class_options;
1751  KVString clop;
1752  if (dbps->HasParameter("CalibOptions")) clop = dbps->GetStringParameter("CalibOptions");
1753  if (clop != "") {
1754  clop.Begin(",");
1755  while (!clop.End()) {
1756  KVString clopp = clop.Next(true);
1757  clopp.Begin("=");
1758  KVString par(clopp.Next(true)), val(clopp.Next(true));
1759  class_options.SetValue(par, val);
1760  }
1761  }
1762  KVCalibrator* cal = KVCalibrator::MakeCalibrator(dbps->GetStringParameter("CalibClass"));
1763  cal->SetType(dbps->GetTitle());
1764  if (clop != "") {
1765  try {
1766  cal->SetOptions(class_options);
1767  }
1768  catch (std::exception& e) {
1769  Error("SetCalibratorParameters",
1770  "Problem for %s [%s] : %s", det->GetName(), cal->GetType(), e.what());
1771  delete cal;
1772  continue;
1773  }
1774  }
1775  cal->SetInputSignalType(dbps->GetStringParameter("SignalIn"));
1776  cal->SetOutputSignalType(dbps->GetStringParameter("SignalOut"));
1777  if (!det->AddCalibrator(cal, dbps->GetParameters())) {
1778  // Calibrator invalid - probably input signal is not defined for detector
1779  // N.B. 'cal' deleted by KVDetector::AddCalibrator
1780  continue;
1781  }
1782 
1783  if (dbps->GetParamNumber() > cal->GetNumberParams()) {
1784  Warning("SetCalibratorParameters", "Wrong number of parameters (%d) for calibrator %s for detector %s : should be %d",
1785  dbps->GetParamNumber(), dbps->GetTitle(), dbps->GetName(), cal->GetNumberParams());
1786  dbps->Print();
1787  continue;
1788  }
1789  for (int i = 0; i < dbps->GetParamNumber(); ++i) {
1790  if (i >= cal->GetNumberParams())
1791  cal->SetParameter(i, 0);
1792  else
1793  cal->SetParameter(i, dbps->GetParameter(i));
1794  }
1795  cal->SetStatus(true);
1796  }
1797 }
1798 
1799 
1800 
1818 
1820 {
1821  // Detector signals corresponding to raw data acquisition parameters are typically only created and
1822  // added to detectors when some raw data has been read including those parameters.
1823  //
1824  // However, when reconstructing data, we may define identification matrices or calibration formulae
1825  // which use these signals before starting to read data. Therefore we need to know beforehand what
1826  // detector signals are expected to be available once data has been read.
1827  //
1828  // These are defined, according to detector types, by variables of the form
1829  //
1830  //~~~~
1831  // [dataset].[array].[detector-type].ExpectedDetectorSignals: [comma-separated list of signal names]
1832  //~~~~
1833  //
1834  // where [dataset] is optionally used to provide dataset-specific definitions.
1835  //
1836  // Here we add a detector signal of each expected type to each detector of the array
1837 
1838  TIter it(GetDetectors());
1839  KVDetector* det;
1840  while ((det = (KVDetector*)it())) {
1841  KVString s = KVBase::GetDataSetEnv(fDataSet.Data(), Form("%s.%s.ExpectedDetectorSignals", GetName(), det->GetType()), "");
1842  if (s.IsNull()) continue;
1843  s.Begin(",");
1844  while (!s.End()) {
1845  det->AddDetectorSignal(s.Next(kTRUE));
1846  }
1847  }
1848 }
1849 
1850 
1851 
1862 
1863 void KVMultiDetArray::GetDetectorEvent(KVDetectorEvent* detev, const TSeqCollection* fired_dets)
1864 {
1865  // First step in event reconstruction based on current status of detectors in array.
1866  // Fills the given KVDetectorEvent with the list of all groups which have fired.
1867  // i.e. loop over all groups of the array and test whether KVGroup::Fired() returns true or false.
1868  //
1869  // If the list of fired detectors 'fired_dets' is given, then we use this list
1870  // to find the associated groups. If not given, or if it is empty, we may use the internal fFiredDetectors list.
1871  //
1872  // Call method detev->Clear() before reading another event in order to reset all of the hit groups
1873  // (including all detectors etc.) and emptying the list.
1874 
1875  if (!fired_dets || !fired_dets->GetEntries()) {
1876  if (fFiredDetectors.GetEntries()) fired_dets = &fFiredDetectors;
1877  }
1878  if (fired_dets && fired_dets->GetEntries()) {
1879  // list of fired detectorsgiven
1880  TIter next_det(fired_dets);
1881  KVDetector* det = 0;
1882  KVGroup* grp = 0;
1883  while ((det = (KVDetector*)next_det())) {
1884  if ((grp = det->GetGroup()) && grp->GetParents()->Contains(this)) detev->AddGroup(grp);
1885  }
1886  }
1887  else {
1888  //loop over groups
1889  unique_ptr<KVSeqCollection> fGroups(GetStructures()->GetSubListWithType("GROUP"));
1890 
1891  TIter next_grp(fGroups.get());
1892  KVGroup* grp;
1893  while ((grp = (KVGroup*) next_grp())) {
1894  if (grp->Fired()) {
1895  //if (!fHitGroups->FindObject(grp))
1896  // grp->Print();
1897  //add new group to list of hit groups
1898  detev->AddGroup(grp);
1899  }
1900  }
1901  }
1902 }
1903 
1904 
1905 
1917 
1918 void KVMultiDetArray::ReconstructEvent(KVReconstructedEvent* recev, KVDetectorEvent* kvde)
1919 {
1920  // Use the KVDetectorEvent (list of hit groups) in order to fill the
1921  // KVReconstructedEvent with reconstructed nuclei
1922  //
1923  // Reconstruction of detected particles
1924  //
1925  // - loop over last stage of group telescopes
1926  // - if any detector is hit, construct "particle" from energy losses in all detectors
1927  // directly in front of it.
1928  // - loop over next to last stage...if any detector hit NOT ALREADY IN A "PARTICLE"
1929  // construct "particle" etc. etc.
1930 
1931  KVGroup* grp_tch;
1932  TIter nxt_grp(kvde->GetGroups());
1933  while ((grp_tch = (KVGroup*) nxt_grp())) {
1934  AnalyseGroupAndReconstructEvent(recev, grp_tch);
1935  }
1936 }
1937 
1938 
1939 
1940 
1944 
1946 {
1947  // Loop over detectors in group, starting from the furthest from the target,
1948  // and working inwards. Calls KVReconstructedEvent::AnalyseDetectors
1949 
1950  for (Int_t il = grp->GetNumberOfDetectorLayers(); il > 0; il--) {
1951  unique_ptr<TList> dets(grp->GetDetectorsInLayer(il));
1952  recev->AnalyseDetectors(dets.get());
1953  }
1954  //perform first-order coherency analysis (set fAnalStatus for each particle)
1956 }
1957 
1958 
1959 
1960 
1961 
1962 
1968 
1970 {
1971  //Remove (i.e. destroy) all the telescopes belonging to a given group
1972 // if (grp) {
1973 // grp->Destroy();
1974 // }
1975  Warning("RemoveGroup", "Needs reimplementing");
1976 }
1977 
1978 
1979 
1983 
1985 {
1986  //Remove (i.e. destroy) all the telescopes belonging to the group in array
1987  //which contains detector or telescope with name "name"
1988  KVGroup* grp = GetGroupWithDetector(name);
1989  if (grp) {
1990  RemoveGroup(grp);
1991  }
1992 }
1993 
1994 
1995 
1996 
2001 
2003  KVNucleus* kvp)
2004 {
2005  //Given the name of a detector, simulate detection of a given particle
2006  //by the complete corresponding group. The particle's theta and phi are set
2007  //at random within the limits of detector entrance window
2008 
2009  KVDetector* kvd = GetDetector(detname);
2010  if (kvd) {
2011  KVNameValueList* nvl = 0;
2012  kvp->SetMomentum(kvp->GetEnergy(), kvd->GetRandomDirection("random"));
2013  if ((nvl = DetectParticle(kvp))) delete nvl;
2014  }
2015  else {
2016  Error("DetectParticleIn", "Detector %s not found", detname);
2017  }
2018 }
2019 
2020 
2021 
2035 
2037 {
2038  //Static function which will create and 'Build' the multidetector object corresponding to
2039  //a given run of dataset 'dataset_name'. Any previously existing multidetector will be
2040  //deleted.
2041  //We first activate the given dataset if not already done
2042  //
2043  //Multidetector arrays are defined as 'Plugin' objects in the file $KVROOT/KVFiles/.kvrootrc :
2044  //
2045  //Plugin.KVMultiDet: [dataset_name] [classname] [library] "[constructor]()"
2046  //
2047  //The constructors/macros are always without arguments
2048  //
2049  //Dataset name is stored in fDataSet
2050 
2051  if (gDataSetManager && (!gDataSet || (gDataSet != gDataSetManager->GetDataSet(dataset_name)))) {
2052  printf("Info in <KVMultiDetArray::MakeMultiDetector>: Changing dataset\n");
2053  gDataSetManager->GetDataSet(dataset_name)->cd();
2054  }
2055 
2056  if (gMultiDetArray && gMultiDetArray->GetDataSet() != dataset_name) {
2057  printf("Info in <KVMultiDetArray::MakeMultiDetector>: Deleting existing array %s\n", gMultiDetArray->GetName());
2058  if (gIDGridManager) {
2059  delete gIDGridManager;
2060  gIDGridManager = nullptr;
2061  }
2062  delete gMultiDetArray;
2063  gMultiDetArray = nullptr;
2064  }
2065 
2066 
2067  // Creation of database when dataset is selected for first time may
2068  // include creation of multidetector array (by calling this method)
2069  KVMultiDetArray* mda = nullptr;
2070  if (!gMultiDetArray) {
2071  TPluginHandler* ph;
2072  if (!(ph = LoadPlugin(classname.Data(), dataset_name)))
2073  return nullptr;
2074 
2075  //execute constructor/macro for multidetector - assumed without arguments
2076  mda = (KVMultiDetArray*) ph->ExecPlugin(0);
2077  mda->fDataSet = dataset_name;
2078  mda->Build(run);
2079  // if ROOT geometry is not allowed ([dataset_name].KVMultiDetArray.ROOTGeometry = no
2080  // or KVMultiDetArray.ROOTGeometry = no), disable it
2081  mda->fROOTGeometry = GetDataSetEnv(dataset_name, "KVMultiDetArray.ROOTGeometry", kTRUE);
2082  if (mda->fROOTGeometry) mda->CheckROOTGeometry();
2083  // set dataset-dependent lists of acceptable ID/E codes for reconstructed nuclei
2084  KVString codes = GetDataSetEnv(dataset_name, Form("%s.ReconstructedNuclei.AcceptIDCodes", mda->GetName()), "");
2085  if (codes != "") mda->fAcceptIDCodes.Set(codes);
2086  codes = GetDataSetEnv(dataset_name, Form("%s.ReconstructedNuclei.AcceptECodes", mda->GetName()), "");
2087  if (codes != "") mda->fAcceptECodes.Set(codes);
2088  // set dataset-dependent condition for seeding reconstructed nuclei
2089  mda->SetPartSeedCond(GetDataSetEnv(dataset_name, Form("%s.ReconstructedNuclei.ParticleSeedCond", mda->GetName()), ""));
2090 #ifdef WITH_RSQLITE
2091  // save contents of grid manager in an SQL-ROOT database if not already done
2093  // 'if(fMakeMultiDetectorSetParameters...' ensures that we are not currently building a subarray
2094  // of a KVExpSetUp. Grids can only be saved once in a single file after all have been read.
2095  TString filepath;
2096  if (is_gnuinstall()) {
2097  // GNU-style install: use working directory $HOME/.kaliveda
2098  filepath = GetWORKDIRFilePath(gDataSet->GetName());
2099  }
2100  else
2101  filepath = gDataSet->GetDataSetDir();
2102 
2103  filepath += "/idgrids_DB";
2104 
2105  int n_grids_to_write = gIDGridManager->GetGrids()->GetEntries();
2106 
2107  KVSQLROOTFile f(filepath, "recreate");
2108 
2109  printf("Info in <KVMultiDetArray::MakeMultiDetector>: Saving %d grids in SQL-ROOT database file %s\n",
2110  n_grids_to_write, filepath.Data());
2111 
2112  TIter it(gIDGridManager->GetGrids());
2113  KVIDGraph* gr;
2114  while ((gr = (KVIDGraph*)it())) {
2115  f.WriteObject(gr, {
2116  {"IDLabel", gr->GetIDTelescopeLabel()},
2117  {"IDTelescopes", gr->GetParameters()->GetStringValue("IDTelescopes")},
2118  {"VarX", gr->GetVarX()},
2119  {"VarY", gr->GetVarY()},
2120  {"Runlist", gr->GetRunList()},
2121  }
2122  );
2123  --n_grids_to_write;
2124  if (!(n_grids_to_write % 1000)) printf("Info in <KVMultiDetArray::MakeMultiDetector>: ...%d grids left...\n",
2125  n_grids_to_write);
2126 
2127  }
2128  }
2129 #endif
2130  }
2131  else {
2132  mda = gMultiDetArray;
2133  }
2134  // set parameters if required & allowed & not done yet
2135  if (fMakeMultiDetectorSetParameters && (run > -1)) mda->SetParameters(run);
2136  return mda;
2137 }
2138 
2139 
2140 
2152 
2154 {
2155  // Return pointer to KVUpDater defined by dataset for this multidetector, the class used
2156  // is defined as a plugin like this:
2157  //
2158  // # Plugin.KVUpDater: name_of_dataset name_of_class name_of_plugin_library constructor_to_call
2159  //
2160  // However, if a dataset defines a variable like this:
2161  //
2162  // [dataset].ExpSetUp.Updater.[multidetector name]: [name_of_dataset for plugin]
2163  //
2164  // then we use the updater plugin defined for the given dataset
2165 
2166  if (!fUpDater) {
2167  KVString alt_updater = KVBase::GetDataSetEnv(fDataSet, Form("ExpSetUp.Updater.%s", GetName()), "");
2168  if (alt_updater != "") fUpDater = KVUpDater::MakeUpDater(alt_updater, this);
2170  }
2171  Info("GetUpDater", "updater class for dataset %s: %s", fDataSet.Data(), fUpDater->IsA()->GetName());
2172  return fUpDater;
2173 }
2174 
2175 
2176 
2177 
2186 
2187 void KVMultiDetArray::SetParameters(UInt_t run, Bool_t physics_parameters_only)
2188 {
2189  // Set run-dependent parameters of the array.
2190  //
2191  // if physics_parameters_only==false, identification and calibration parameters are set.
2192  // if physics_parameters_only==true, just the minimum necessary for physics analysis of reduced data are set.
2193  //
2194  // This can only be done if gDataSet has been set i.e. a dataset has been chosen,
2195  // otherwise this just has the effect of setting the current run number
2196 
2197  fCurrentRun = run;
2198  KVDataSet* ds = gDataSet;
2199  if (!ds) {
2200  if (gDataSetManager)
2202  }
2203  if (ds) {
2204  GetUpDater()->SetParameters(run, physics_parameters_only);
2205  SetBit(kParamsSet);
2206  }
2207 }
2208 
2209 
2210 
2211 
2216 
2218 {
2219  //Set identification parameters for run.
2220  //This can only be done if gDataSet has been set i.e. a dataset has been chosen
2221  //Otherwise this just has the effect of setting the current run number
2222 
2223  fCurrentRun = run;
2224  KVDataSet* ds = gDataSet;
2225  if (!ds) {
2226  if (gDataSetManager)
2228  }
2229  if (ds) {
2232  }
2233 }
2234 
2235 
2236 
2237 
2242 
2244 {
2245  //Set calibration parameters for run.
2246  //This can only be done if gDataSet has been set i.e. a dataset has been chosen
2247  //Otherwise this just has the effect of setting the current run number
2248 
2249  fCurrentRun = run;
2250  KVDataSet* ds = gDataSet;
2251  if (!ds) {
2252  if (gDataSetManager)
2254  }
2255  if (ds) {
2258  }
2259 }
2260 
2261 
2262 
2263 
2280 
2282 {
2283  //Initialisation of all ACTIVE identification telescopes in the array, i.e. those appearing in a line
2284  //in the .kvrootrc file such as this:
2285  //
2286  //# [dataset name].ActiveIdentifications: [type1] [type2] ...
2287  //
2288  //The 'types' given correspond to the value given by KVIDTelescope::GetLabel(), these are the
2289  //identifiers used to retrieve the different plugin classes in GetIDTelescopes(KVDetector*,KVDetector*,KVList*).
2290  //
2291  //For each type of identification in the list, we retrieve the first identification telescope with this
2292  //label from the list of all ID telescopes, in order to call its KVIDTelescope::SetIdentificationParameters() method.
2293  //This method (when rederived in child classes of KVIDTelescope) initialises the identification objects
2294  //for ALL of the ID telescopes of the same type (class) in the array.
2295  //
2296  //Note that, in general, the parameters of the identifications for a given run are not
2297  //set until SetParameters or SetRunIdentificationParameters is called.
2298 
2299 #ifdef WITH_RSQLITE
2300  // if a KVSQLROOTFile has been filled with the dataset identification parameters we use it.
2301  if (gIDGridManager->IsSQLROOT()) {
2302  // nothing more to do
2303  return;
2304  }
2305  else if (!gDataSet->DataBaseUpdateInProgress())
2306  // the update of the database may have been caused by 1 or more identification files being modified
2307  // (even if they are not part of the database). in this case we read in all the grids again even
2308  // if it has already been done before.
2309  {
2310  TString filepath;
2311  if (is_gnuinstall()) {
2312  // GNU-style install: use working directory $HOME/.kaliveda
2313  filepath = GetWORKDIRFilePath(gDataSet->GetName());
2314  }
2315  else
2316  filepath = gDataSet->GetDataSetDir();
2317 
2318  filepath += "/idgrids_DB";
2319 
2320  if (SearchKVFile(filepath.Data(), filepath)) {
2321  delete gIDGridManager;
2322  gIDGridManager = new KVSQLROOTIDGridManager(filepath);
2323  return;
2324  }
2325  }
2326 #endif
2327 
2328  KVString id_labels = GetDataSetEnv(fDataSet, "ActiveIdentifications", "");
2329  if (id_labels == "" || (gDataSet && !gDataSet->HasCalibIdentInfos())) {
2330  Info("SetIdentifications", "No active identifications");
2331  return;
2332  }
2333  //split list of labels
2334  id_labels.Begin(" ");
2335  int ok(0);
2336  //loop over labels/identification 'types'
2337  while (!id_labels.End()) {
2338 
2339  //get first telescope in list with right label
2341  //set ID parameters for all telescopes of this 'type'
2342  if (idt) {
2343  Info("SetIdentifications", "Initialising %s identifications...", idt->GetLabel());
2344  if (idt->SetIdentificationParameters(this))
2345  Info("SetIdentifications", "OK");
2346  ++ok;
2347  }
2348 
2349  }
2350  if (!ok) {
2351  // None of the labels in the list correspond to telescopes in the array
2352  Warning("SetIdentfications", "No telescopes found with labels given in %s.ActiveIdentifications list: %s",
2353  gDataSet->GetName(), id_labels.Data());
2354  }
2355 }
2356 
2357 
2358 
2359 
2366 
2368 {
2369  // Calls Initialize() method of each identification telescope (see KVIDTelescope
2370  // and derived classes) and sets the general identification code defined for each
2371  // telescope.
2372  //
2373  // Calling this method is essential before identification of particles is attempted.
2374 
2375  TIter next(fIDTelescopes);
2376  KVIDTelescope* idt;
2377  while ((idt = (KVIDTelescope*)next())) {
2378  idt->Initialize();
2380  }
2381 }
2382 
2383 
2384 
2395 
2397 {
2398  // Read all identification grids from the file and add them to the IDGridManager object
2399  // used by this array. This method sets up the links between each grid and the
2400  // IDtelescope(s) it is to be used for, unlike calling
2401  //
2402  // gIDGridManager->ReadAsciiFile(grids)
2403  //
2404  // which does not.
2405  //
2406  // Returns kFALSE if there is a problem reading the file
2407 
2408  if (gIDGridManager->ReadAsciiFile(grids)) {
2410  KVIDGraph* gr;
2411  while ((gr = (KVIDGraph*)next())) FillListOfIDTelescopes(gr);
2412  return kTRUE;
2413  }
2414  return kFALSE;
2415 }
2416 
2417 
2418 
2419 
2423 
2425 {
2426  // Print full status report on ID telescopes in array, using informations stored in
2427  // fStatusIDTelescopes (see GetStatusOfIDTelescopes).
2428 
2429  cout << endl << "-----STATUS OF IDENTIFICATION TELESCOPES";
2430  if (GetCurrentRunNumber()) cout << " FOR RUN "
2431  << GetCurrentRunNumber();
2432  cout << "------" << endl << endl;
2433  //get list of active telescopes
2434  KVString id_labels;
2435  if (gDataSet) id_labels = gDataSet->GetDataSetEnv("ActiveIdentifications");
2436  else {
2437  unique_ptr<KVUniqueNameList> typelist(GetIDTelescopeTypes());
2438  TIter it(typelist.get());
2439  TObjString* type;
2440  while ((type = (TObjString*)it())) {
2441  if (id_labels == "") id_labels += type->GetString().Data();
2442  else {
2443  id_labels += Form(" %s", type->GetString().Data());
2444  }
2445  }
2446  }
2447  if (id_labels == "") {
2448  cout << " *** No active identifications *** " << endl;
2449  return;
2450  }
2451  // iterate over labels
2452  unique_ptr<TObjArray> toks(id_labels.Tokenize(' '));
2453 
2454  //update status infos
2456 
2457  TIter next_type(fStatusIDTelescopes);
2458  TList* id_type_list = 0;
2459  while ((id_type_list = (TList*)next_type())) {
2460 
2461  cout << " *** " << id_type_list->GetName() << " Identifications -------------------" << endl;
2462  if (!toks->FindObject(id_type_list->GetName())) {
2463  cout << " [NOT ACTIVE]" << endl;
2464  }
2465  TList* ok_list = (TList*)id_type_list->FindObject("OK");
2466  TList* notok_list = (TList*)id_type_list->FindObject("NOT OK");
2467  TList* print_list = 0;
2468  Int_t Nok = ok_list->GetEntries();
2469  Int_t Notok = notok_list->GetEntries();
2470  if (Nok && Notok) {
2471  if (Nok < Notok) print_list = ok_list;
2472  else print_list = notok_list;
2473  }
2474  if (Nok && (!Notok)) cout << " ALL telescopes are OK" << endl;
2475  else if (Notok && (!Nok)) cout << " NO telescopes are OK" << endl;
2476  else {
2477  cout << " " << ok_list->GetEntries() << " telescopes are OK, "
2478  << notok_list->GetEntries() << " telescopes are NOT OK" << endl;
2479  cout << " " << print_list->GetName() << " :" << endl;
2480  TIter it(print_list);
2481  TObject* ob = it();
2482  cout << ob->GetName();
2483  while ((ob = it())) cout << "," << ob->GetName();
2484  cout << endl;
2485  }
2486  cout << endl;
2487 
2488  }
2489 }
2490 
2491 
2492 
2493 
2501 
2503 {
2504  // Fill and return pointer to list fStatusIDTelescopes which contains
2505  // a list for each type of ID telescope in the array, each list contains a list
2506  // "OK" with the ID telescopes which have IsReadyForID()=kTRUE, and
2507  // a list "NOT OK" with the others.
2508  //
2509  // The returned TList object must not be deleted (it belongs to the KVMultiDetArray).
2510 
2511  if (!fStatusIDTelescopes) {
2512  fStatusIDTelescopes = new TList;
2514  }
2515  else {
2517  }
2519  TIter next(fIDTelescopes);
2520  KVIDTelescope* idt = 0;
2521  while ((idt = (KVIDTelescope*)next())) {
2522 
2523  TString id_type = idt->GetLabel();
2524  TList* id_type_list = (TList*)fStatusIDTelescopes->FindObject(id_type.Data());
2525  if (!id_type_list) {
2526  id_type_list = new TList;
2527  id_type_list->SetOwner(kTRUE);
2528  id_type_list->SetName(id_type.Data());
2529  fStatusIDTelescopes->Add(id_type_list);
2530  id_type_list->Add(new TList);
2531  ((TList*)id_type_list->At(0))->SetName("OK");
2532  id_type_list->Add(new TList);
2533  ((TList*)id_type_list->At(1))->SetName("NOT OK");
2534  }
2535  if (idt->IsReadyForID())
2536  ((TList*)id_type_list->FindObject("OK"))->Add(idt);
2537  else
2538  ((TList*)id_type_list->FindObject("NOT OK"))->Add(idt);
2539  }
2540  return fStatusIDTelescopes;
2541 }
2542 
2543 
2544 
2545 
2551 
2553 {
2554  // Create, fill and return pointer to a list of TObjString containing the name of each type
2555  // of ID telescope (actually the label) in the array.
2556  //
2557  // Delete the list after use (it owns the TObjString objects)
2558 
2559  KVUniqueNameList* type_list = new KVUniqueNameList(kTRUE);
2560  type_list->SetOwner();
2561  if (!fIDTelescopes || !fIDTelescopes->GetEntries()) return type_list;
2562  TIter next(fIDTelescopes);
2563  KVIDTelescope* idt = 0;
2564  while ((idt = (KVIDTelescope*)next())) {
2565  type_list->Add(new TObjString(idt->GetLabel()));
2566  }
2567  return type_list;
2568 }
2569 
2570 
2571 
2572 
2580 
2582 {
2583  // Create, fill and return pointer to a list of KVIDTelescopes with
2584  // the given type (label) in the array.
2585  // WARNING! - check pointer is not zero (we return NULL if ID telescopes
2586  // list is not defined or empty)
2587  //
2588  // Delete the KVList after use (it does not own the KVIDTelescopes).
2589 
2590  if (!fIDTelescopes || !fIDTelescopes->GetEntries()) return NULL;
2592 }
2593 
2594 
2595 
2596 
2604 
2606 {
2607  // Fill and return pointer to list fCalibStatusDets which contains
2608  // a list for each type of detector in the array, each list contains a list
2609  // "OK" with the detectors which are calibrated, and
2610  // a list "NOT OK" with the others.
2611  //
2612  // The returned TList object must not be deleted (it belongs to the KVMultiDetArray).
2613 
2614  if (!fCalibStatusDets) {
2615  fCalibStatusDets = new TList;
2617  }
2618  else {
2620  }
2621  if (!GetDetectors()->GetEntries()) return fCalibStatusDets;
2622  TIter next(GetDetectors());
2623  KVDetector* det = 0;
2624  while ((det = (KVDetector*)next())) {
2625 
2626  TString type = det->GetType();
2627  TList* type_list = (TList*)fCalibStatusDets->FindObject(type.Data());
2628  if (!type_list) {
2629  type_list = new TList;
2630  type_list->SetOwner(kTRUE);
2631  type_list->SetName(type.Data());
2632  fCalibStatusDets->Add(type_list);
2633  type_list->Add(new TList);
2634  ((TList*)type_list->At(0))->SetName("OK");
2635  type_list->Add(new TList);
2636  ((TList*)type_list->At(1))->SetName("NOT OK");
2637  }
2638  if (det->IsCalibrated())
2639  ((TList*)type_list->FindObject("OK"))->Add(det);
2640  else
2641  ((TList*)type_list->FindObject("NOT OK"))->Add(det);
2642  }
2643  return fCalibStatusDets;
2644 }
2645 
2646 
2647 
2648 
2652 
2654 {
2655  // Print full status report on calibration of detectors in array, using informations stored in
2656  // fCalibStatusDets (see GetCalibrationStatusOfDetectors).
2657 
2658  if (!GetCurrentRunNumber()) {
2659  Info("PrintCalibStatusOfDetectors", "Cannot know status without knowing RUN NUMBER");
2660  return;
2661  }
2662 
2663  cout << endl << "-----------STATUS OF CALIBRATIONS FOR RUN "
2664  << GetCurrentRunNumber() << "------------" << endl << endl;
2665 
2666  //update status infos
2668 
2669  TIter next_type(fCalibStatusDets);
2670  TList* id_type_list = 0;
2671  while ((id_type_list = (TList*)next_type())) {
2672 
2673  cout << " *** " << id_type_list->GetName() << " Detectors -------------------" << endl;
2674  TList* ok_list = (TList*)id_type_list->FindObject("OK");
2675  TList* notok_list = (TList*)id_type_list->FindObject("NOT OK");
2676  TList* print_list = 0;
2677  Int_t Nok = ok_list->GetEntries();
2678  Int_t Notok = notok_list->GetEntries();
2679  if (Nok && Notok) {
2680  if (Nok < Notok) print_list = ok_list;
2681  else print_list = notok_list;
2682  }
2683  if (Nok && (!Notok)) cout << " ALL calibrations are OK" << endl;
2684  else if (Notok && (!Nok)) cout << " NO calibrations are OK" << endl;
2685  else {
2686  cout << " " << ok_list->GetEntries() << " calibrations are OK, "
2687  << notok_list->GetEntries() << " calibrations are NOT OK" << endl;
2688  cout << " " << print_list->GetName() << " :" << endl;
2689  TIter it(print_list);
2690  TObject* ob = it();
2691  cout << ob->GetName();
2692  while ((ob = it())) cout << "," << ob->GetName();
2693  cout << endl;
2694  }
2695  cout << endl;
2696 
2697  }
2698 }
2699 
2700 
2701 
2702 
2718 
2720 {
2721  // Calculate the energy loss in the current target of the multidetector
2722  // for the reconstructed charged particle 'ion', assuming that the current
2723  // energy and momentum of this particle correspond to its state on
2724  // leaving the target.
2725  //
2726  // WARNING: for this correction to work, the target must be in the right 'state':
2727  //
2728  // gMultiDetArray->GetTarget()->SetIncoming(kFALSE);
2729  // gMultiDetArray->GetTarget()->SetOutgoing(kTRUE);
2730  //
2731  // (see KVTarget::GetParticleEIncFromERes).
2732  //
2733  // The returned value is the energy lost in the target in MeV.
2734  // The energy/momentum of 'ion' are not affected.
2735 
2736  if (fTarget && ion) return (fTarget->GetParticleEIncFromERes(ion) - ion->GetEnergy());
2737  return 0;
2738 }
2739 
2740 
2741 
2742 
2745 
2747 {
2748  // Return pointer to the (ROOT) geometry of the array.
2749  return gGeoManager;
2750 }
2751 
2752 
2753 
2755 
2757 {
2758  return fNavigator;
2759 }
2760 
2761 
2762 
2788 
2790 {
2791  // Actual thicknesses of detectors can be given in one or more files associated with a dataset.
2792  //
2793  // If the variable
2794  //
2795  //~~~~
2796  //[dataset].DetectorThicknessesFile: toto.dat
2797  //~~~~
2798  //
2799  // is defined for the current dataset, we expect toto.dat to contain a list of files to be read in order
2800  // to set dectector thicknesses. Note that the same detector may appear several times in the files.
2801  // In this case it is the thickness in the last file (in the order listed in toto.dat) which will remain.
2802  //
2803  // Otherwise, we look for a single file in the dataset directory with the name given by one or other of
2804  // the variables
2805  //
2806  //~~~~
2807  //KVMultiDetArray.DetectorThicknesses:
2808  //[dataset].KVMultiDetArray.DetectorThicknesses:
2809  //~~~~
2810  //
2811  // and, if found, we use it to set the detector thicknesses.
2812  //
2813  // See set_detector_thicknesses() for details of the format of the individual thickness files.
2814 
2815  // look for list of files
2816  TString filename = GetDataSetEnv(fDataSet, "DetectorThicknessesFile", "");
2817  if (filename != "") {
2818  KVFileReader fr;
2820  if (fr.OpenFileToRead(fullpath)) {
2821  while (fr.IsOK()) {
2822  fr.ReadLine(0);
2823  if (fr.GetCurrentLine().BeginsWith("#") || fr.GetCurrentLine() == "") continue;
2825  }
2826  return;
2827  }
2828  else {
2829  Warning("SetDetectorThicknesses", "Could not open DetectorThicknessesFile %s...", fullpath.Data());
2830  }
2831  return;
2832  }
2833  // look for single file
2834  filename = GetDataSetEnv(fDataSet, "KVMultiDetArray.DetectorThicknesses", "");
2835  if (filename == "") {
2836  Error("SetDetectorThicknesses", "*.KVMultiDetArray.DetectorThicknesses not defined in .kvrootrc");
2837  return;
2838  }
2839  TString fullpath;
2840  fullpath = KVDataSet::GetFullPathToDataSetFile(fDataSet, filename);
2841  if (fullpath == "") {
2842  Info("SetDetectorThicknesses", "File %s not found", filename.Data());
2843  return;
2844  }
2845  set_detector_thicknesses(fullpath);
2846 }
2847 
2848 
2849 
2868 
2870 {
2871  // Use file given by fullpath to set the real thicknesses of the detectors.
2872  // Any detector which is not in the file will be left with its nominal thickness.
2873  //
2874  // EXAMPLE FILE:
2875  //
2876  //# thickness of detector DET01 in default units
2877  //DET01: 56.4627
2878  //
2879  //# DET03 has several layers
2880  //DET03.Abs0: 61.34
2881  //DET03.Abs1: 205.62
2882  //
2883  // !!! WARNING !!!
2884  // Single-layer detectors: The units are those defined by default for the detector's
2885  // Get/SetThickness methods.
2886  // Multi-layer: Each layer is a KVMaterial object. The thickness MUST be given in centimetres
2887  // (default thickness unit for KVMaterial).
2888 
2889  TEnv thickdat;
2890  if (thickdat.ReadFile(fullpath, kEnvUser) != 0) {
2891  Error("SetDetectorThicknesses", "Problem opening file %s", fullpath.Data());
2892  return;
2893  }
2894  Info("SetDetectorThicknesses", "Setting thicknesses of detectors from file %s", fullpath.Data());
2895  TIter next(GetDetectors());
2896  KVDetector* det;
2897  while ((det = (KVDetector*)next())) {
2898  if (thickdat.Defined(det->GetName())) {
2899  // simple single layer detector
2900  Double_t thick = thickdat.GetValue(det->GetName(), 0.0);
2901  det->SetThickness(thick);
2902  //Info("SetDetectorThicknesses", "Set thickness of %s to %f", det->GetName(), thick);
2903  }
2904  else {
2905  Char_t i = 0;
2906  TString absname;
2907  absname.Form("%s.Abs%d", det->GetName(), (Int_t)i);
2908  if (thickdat.Defined(absname.Data())) {
2909  // detector with several layers
2910  KVMaterial* abs = 0;
2911  while ((abs = det->GetAbsorber(i))) {
2912  Double_t thick = thickdat.GetValue(absname.Data(), 0.0);
2913  abs->SetThickness(thick);
2914  //Info("SetDetectorThicknesses", "Set thickness of %s.Abs%d to %f", det->GetName(), (Int_t)i, thick);
2915  i++;
2916  absname.Form("%s.Abs%d", det->GetName(), (Int_t)i);
2917  if (!thickdat.Defined(absname.Data())) break;
2918  }
2919  }
2920  }
2921  }
2922 }
2923 
2924 
2925 
2931 
2933 {
2934  // Define the geometry of the array with a valid ROOT geometry (TGeoManager instance)
2935  // If no name and/or title are defined for the array, the name and title of the TGeoManager
2936  // object will be used for the array.
2937  // ROOT geometry will be used by default from now on.
2938 
2939  if (!strcmp(GetName(), "")) SetName(g->GetName());
2940  if (!strcmp(GetTitle(), "")) SetTitle(g->GetTitle());
2941  SetROOTGeometry();
2942 }
2943 
2944 
2945 
2949 
2951 {
2952  // Calculate incident energy of particle (Z,A) required to punch through given detector,
2953  // taking into account any detectors which the particle must first cross in order to reach it.
2954 
2955  KVDetector* theDet = GetDetector(detector);
2956  if (!theDet) {
2957  Error("GetPunchThroughEnergy", "Detector %s not found in array", detector);
2958  return -1.0;
2959  }
2960  Double_t E0 = theDet->GetPunchThroughEnergy(Z, A);
2961  TIter alDets(theDet->GetAlignedDetectors());
2962  // first detector in list is theDet
2963  alDets.Next();
2964  KVDetector* D;
2965  while ((D = (KVDetector*)alDets.Next())) {
2966  Double_t E1 = D->GetIncidentEnergyFromERes(Z, A, E0);
2967  E0 = E1;
2968  }
2969  return E0;
2970 }
2971 
2972 
2973 
2978 
2980 {
2981  // Creates and fills a TGraph with the punch through energy in MeV vs. Z for the given detector,
2982  // for Z=1-92. The mass of each nucleus is calculated according to the given mass formula
2983  // (see KVNucleus).
2984 
2985  TGraph* punch = new TGraph(92);
2986  punch->SetName(Form("KVMultiDetpunchthrough_%s_mass%d", detector, massform));
2987  punch->SetTitle(Form("Array Punch-through %s (MeV) (mass formula %d)", detector, massform));
2988  KVNucleus nuc;
2989  nuc.SetMassFormula(massform);
2990  for (int Z = 1; Z <= 92; Z++) {
2991  nuc.SetZ(Z);
2992  punch->SetPoint(Z - 1, Z, GetPunchThroughEnergy(detector, nuc.GetZ(), nuc.GetA()));
2993  }
2994  return punch;
2995 }
2996 
2997 
2998 
3003 
3005 {
3006  // Creates and fills a TGraph with the punch through energy in MeV/nucleon vs. Z for the given detector,
3007  // for Z=1-92. The mass of each nucleus is calculated according to the given mass formula
3008  // (see KVNucleus).
3009 
3010  TGraph* punch = new TGraph(92);
3011  punch->SetName(Form("KVMultiDetpunchthroughEsurA_%s_mass%d", detector, massform));
3012  punch->SetTitle(Form("Array Punch-through %s (AMeV) (mass formula %d)", detector, massform));
3013  KVNucleus nuc;
3014  nuc.SetMassFormula(massform);
3015  for (int Z = 1; Z <= 92; Z++) {
3016  nuc.SetZ(Z);
3017  punch->SetPoint(Z - 1, Z, GetPunchThroughEnergy(detector, nuc.GetZ(), nuc.GetA()) / nuc.GetA());
3018  }
3019  return punch;
3020 }
3021 
3022 
3023 
3029 
3031 {
3032  // Creates and fills a TGraph with the Z vs. the punch-through velocity paralllel to the beam
3033  // direction in cm/ns for the given detector,
3034  // for Z=1-92. The mass of each nucleus is calculated according to the given mass formula
3035  // (see KVNucleus).
3036 
3037  TGraph* punch = new TGraph(92);
3038  punch->SetName(Form("KVMultiDetpunchthroughV_%s_mass%d", detector, massform));
3039  punch->SetTitle(Form("Array Punch-through %s (cm/ns) (mass formula %d)", detector, massform));
3040  KVNucleus nuc;
3041  nuc.SetMassFormula(massform);
3042  for (int Z = 1; Z <= 92; Z++) {
3043  nuc.SetZ(Z);
3044  nuc.SetE(GetPunchThroughEnergy(detector, nuc.GetZ(), nuc.GetA()));
3045  nuc.SetTheta(GetDetector(detector)->GetTheta());
3046  punch->SetPoint(Z - 1, nuc.GetVpar(), Z);
3047  }
3048  return punch;
3049 }
3050 
3051 
3052 
3056 
3058 {
3059  // Call with on=kTRUE if array uses ROOT geometry for tracking
3060  // Call SetGeometry(TGeoManager*) first with a valid geometry.
3061 
3062  fROOTGeometry = on;
3063  if (on && !gGeoManager) {
3064  Error("SetROOTGeometry", "ROOT geometry is requested, but has not been set: gGeoManager=0x0,\n Call CreateGeoManager() method first");
3065  return;
3066  }
3067 
3068  // set up geometry navigator
3070  else if (!on) SafeDelete(fNavigator);
3071 }
3072 
3073 
3074 
3103 
3105 {
3106  // Method for positioning volumes in detector geometries
3107  //
3108  // Given:
3109  //
3110  // distance [cm] = distance from target (origin) to the CENTRE of the volume in position
3111  // theta [deg] = polar angle of vector from target to centre of volume in position
3112  // phi [deg] = azimuthal angle of vector
3113  //
3114  // this method generates the matrix which is required to position the volume as required
3115  // while also turning the volume so that the side nearest the target (i.e. the entrance
3116  // window of the detector) remains perpendicular to the vector joining the origin and
3117  // the centre of the volume.
3118  //
3119  // If required, a further translation can be given which will be applied to the volume after
3120  // it has been placed with the required orientation at the nominal distance. This can be used
3121  // e.g. for detector misalignment, when detectors are in a structure which guarantees their line
3122  // of sight to be orthogonal to their surface at a nominal distance, but the nominal distance
3123  // is not respected.
3124  //
3125  // Example of use:
3126  //
3127  //~~~~~~~~~~~~
3128  // TGeoVolume* vol;// volume to be positioned
3129  // double depth = vol->GetShape()->GetDZ(); // half-width of volume in direction of target
3130  // // place front of volume at 100cm, with theta=45 deg. and phi=60 deg.
3131  // gGeoManager->GetTopVolume()->AddNode(vol, 1, KVMultiDetArray::GetVolumePositioningMatrix(100+depth,45,60));
3132  //~~~~~~~~~~~~
3133 
3134  TGeoRotation rot1, rot2;
3135  TGeoTranslation trans;
3136  phi += 90;
3137  rot1.SetAngles(-phi, 0, 0) ;
3138  rot2.SetAngles(phi, theta, 0) ;
3139  trans.SetDz(distance) ;
3140  TGeoHMatrix h;
3141  if (postTrans) h = (*postTrans) * rot2 * trans * rot1 ;
3142  else h = rot2 * trans * rot1;
3143  TGeoHMatrix* ph = new TGeoHMatrix(h);
3144  return ph;
3145 }
3146 
3147 
3148 
3156 
3158 {
3159  // *** Set 'segmentation' index of detectors ***
3160  // This is essential for particle reconstruction, judging whether particles can be identified
3161  // independently of any others in the same group etc.
3162  // Basically, any detector with >1 detector placed directly behind it has a seg. index = 0
3163  // if <=1 detector is directly behind, the seg. index = 1
3164  // This method is used for arrays imported from ROOT geometries.
3165 
3166  TIter next(GetDetectors());
3167  KVDetector* d;
3168  while ((d = (KVDetector*)next())) {
3169  if (d->GetNode()->GetNDetsBehind() > 1) d->SetSegment(0);
3170  else d->SetSegment(1);
3171  }
3172 }
3173 
3174 
3175 
3176 
3183 
3185 {
3186  //Create and add to list all ID telescopes made of this detector
3187  //and the aligned detectors placed in front of it.
3188  //
3189  //If list=0 then we store pointers to the ALREADY EXISTING ID telescopes
3190  //in det->fIDTelAlign. (first clear det->fIDTelAlign)
3191 
3192  if (!(det->IsOK())) return;
3193 
3194  TList* aligned = det->GetAlignedDetectors();
3195 
3196  Bool_t list_zero = kFALSE;
3197 
3198  if (!list) {
3199  list_zero = kTRUE;
3200  //the IDTelescopes created will be destroyed at the end,
3201  //once we have used their names to find pointers to the corresponding
3202  //telescopes in gMultiDetArray
3203  list = new KVList;
3204  //clear any existing list of aligned telescopes
3205  det->GetAlignedIDTelescopes()->Clear();
3206  }
3207 
3208  if (aligned->GetSize() > 1) {
3209  //pairwise looping through list
3210  for (int i = 0; i < (aligned->GetSize() - 1); i++) {
3211  KVDetector* det1 = (KVDetector*) aligned->At(i + 1);
3212  KVDetector* det2 = (KVDetector*) aligned->At(i);
3213 
3214  GetIDTelescopes(det1, det2, list);
3215  }
3216  }
3217  else {
3218  //The following line is in case there are no detectors aligned
3219  //with 'det', but 'det' acts as an IDTelescope all by itself.
3220  //In this case we expect KVMultiDetArray::GetIDTelescopes
3221  //to define the appropriate ID telescope whenever one of the
3222  //two detector arguments (or both!) corresponds to 'det''s type.
3223  GetIDTelescopes(det, det, list);
3224  }
3225 
3226  if (list_zero) {
3227  //now we use the created ID telescopes to find pointers to the already
3228  //existing identical telescopes in gMultiDetArray, stock them in
3229  //det->fIDTelAlign
3230  TIter next_tel(list);
3231  KVIDTelescope* tel;
3232  while ((tel = (KVIDTelescope*) next_tel())) {
3233  KVIDTelescope* trash = GetIDTelescope(tel->GetName());
3234  if (trash) {
3235  det->GetAlignedIDTelescopes()->Add(trash);
3236  }
3237  }
3238  //destroy the superfluous copy telescopes we just created
3239  list->Delete();
3240  delete list;
3241  }
3242 
3243 }
3244 
3245 
3246 
3260 
3262 {
3263  //Identify all the ways of identifying particles possible from the detectors
3264  //in the group, create the appropriate KVIDTelescope objects and add them to
3265  //the list pointed to by tel_list.
3266  //USER'S RESPONSIBILITY TO DELETE CONTENTS OF LIST!!
3267  //
3268  //Starting from each detector in the group,
3269  //we build ID telescopes from all pairs of aligned detectors.
3270  //
3271  //For each pair of detectors, it is KVMultiDetArray::GetIDTelescopes
3272  //which determines which KVIDTelescope class to use (specialise this method
3273  //in KVMultiDetArray child classes). It must also make sure that
3274  //each IDTelescope is added only once (i.e. check it is not already in the list).
3275 
3276  TIter next_det(grp->GetDetectors());
3277  KVDetector* det;
3278 
3279  while ((det = (KVDetector*) next_det())) {
3280  if (det->IsOK()) {
3281  //1st call: create ID telescopes, they will be added to the
3282  //gMultiDetArray list of IDTelescopes
3283  GetAlignedIDTelescopesForDetector(det, tel_list);
3284  //2nd call: set up in the detector a list of pointers to the
3285  //ID telescopes made up of it and all aligned detectors in front
3286  //of it
3288  }
3289  }
3290 }
3291 
3292 
3293 
3303 
3305 {
3306  //Casse tous les liens entre les detecteurs d un meme groupe
3307  //Retire de la liste gMultiDetArray->GetListOfIDTelescopes() les
3308  //telescopes associes et les efface apres les avoir
3309  //retires des grilles auxquelles ils etaient associees
3310  //pour preparer l ajout ou le retrait d un detecteur
3311  //voir KVDetector::SetPresent()
3312  //
3313  //
3314  KVNameValueList nv;
3315 
3316  KVDetector* det = 0;
3317  KVIDTelescope* id = 0;
3318 
3319  const KVSeqCollection* lgrdet = grp->GetDetectors();
3320  TIter nextdet(lgrdet);
3321  while ((det = (KVDetector*)nextdet())) {
3322  //Info("PrepareModif","On retire les detecteurs alignes pour %s",det->GetName());
3325  Int_t ntel = det->GetIDTelescopes()->GetEntries();
3326  for (Int_t ii = 0; ii < ntel; ii += 1) {
3327  id = (KVIDTelescope*)det->GetIDTelescopes()->At(0);
3328  if (id->GetDetectors()->FindObject(dd)) {
3329  nv.SetValue(id->GetName(), "");
3330  det->GetIDTelescopes()->RemoveAt(0);
3331  }
3332  }
3333  }
3334 
3336  for (Int_t ii = 0; ii < nv.GetEntries(); ii += 1) {
3337  id = (KVIDTelescope*)lidtel->FindObject(nv.GetNameAt(ii));
3338  //Info("PrepareModif","On retire et on detruit l'ID tel %s",id->GetName());
3339 
3340  if (id->GetListOfIDGrids()) {
3341  KVIDGraph* idg = 0;
3342  for (Int_t kk = 0; kk < id->GetListOfIDGrids()->GetEntries(); kk += 1) {
3343  idg = (KVIDGraph*)id->GetListOfIDGrids()->At(kk);
3344  idg->RemoveIDTelescope(id);
3345  }
3346  }
3347 
3348  //Info("PrepareModif","Je retire et j efface le idtel %s %s",id->GetName(),id->ClassName());
3349  delete lidtel->Remove(id);
3350  }
3351  nv.Clear();
3352 
3353 }
3354 
3355 
3356 
3369 
3371 {
3372  //
3373  // If present=kTRUE (default), detector is present
3374  // If present=kFALSE, detector has been removed
3375  // This method does nothing is required state is already current state.
3376  //
3377  // Methode applicable seulement pour un detecteur
3378  // etant le seul dans un telescope
3379  // ex les ChIo pour Indra
3380  //
3381  // This method as always to be call before
3382  // call the SetDetecting() method
3383 
3384  if (present == det->IsPresent())
3385  return;
3386 
3387  det->SetPresent(present);
3388 
3389  //On passe l etat d un detecteur de present a absent
3390  //
3391  KVTelescope* fTelescope = (KVTelescope*)det->GetParentStructure("TELESCOPE");
3392  if (!det->IsPresent()) {
3393 
3394  //Le detecteur etait l unique d un KVTelescope
3395  //on retire directement le KVTelescope
3396  if (fTelescope->GetDetectors()->GetEntries() == 1) {
3397  KVGroup* gr = (KVGroup*)fTelescope->GetParentStructure("GROUP");
3398 
3399  PrepareModifGroup(gr, det);
3400 
3401  gr->Remove(fTelescope);
3402  gr->Remove(det);
3404 
3405  }
3406  else {
3407  Warning("SetPresent", "Method implemented only in case detector is alone in telescope");
3408  }
3409  }
3410  //On remet le detecteur dans le groupe auquel il appartenait
3411  else {
3412 
3413  if (!det->GetGroup()) {
3414  KVGroup* gr = GetGroupWithAngles(det->GetTheta(), det->GetPhi());
3415 
3416  PrepareModifGroup(gr, det);
3417 
3418  gr->Add(fTelescope);
3419  gr->Add(det);
3420  gr->Sort();
3421  gr->CountLayers();
3423 
3424  }
3425 
3426  }
3427 
3428 }
3429 
3430 
3431 
3440 
3442 {
3443 
3444  // This method has effect only if detector is present
3445  //
3446  // If detecting=kTRUE (default), detector is detecting
3447  // If detecting=kFALSE, detector has been switch off or no gas or just dead
3448  // Does nothing if:
3449  // - detector already marked as absent
3450  // - required state is already current state
3451 
3452  if (!det->IsPresent())
3453  return;
3454 
3455  if (detecting == det->IsDetecting())
3456  return;
3457 
3458  det->SetDetecting(detecting);
3459  if (!det->IsDetecting()) {
3460  KVGroup* gr = det->GetGroup();
3461  PrepareModifGroup(gr, det);
3463  }
3464  else {
3465  KVGroup* gr = GetGroupWithAngles(det->GetTheta(), det->GetPhi());
3466  PrepareModifGroup(gr, det);
3468  }
3469 
3470 }
3471 
3472 
3473 
3477 
3479 {
3480  // For each grid which is valid for this run, we call the KVIDTelescope::SetIDGrid method
3481  // of each associated ID telescope.
3482 
3483  if (gIDGridManager->IsSQLROOT()) {
3485  }
3486 
3487  TIter next(gIDGridManager->GetGrids());
3488  KVIDGraph* gr = 0;
3489  while ((gr = (KVIDGraph*) next())) {
3490  if (!gIDGridManager->IsSQLROOT()) {
3491  if (!gr->GetRuns().Contains((Int_t) run))
3492  continue;
3493  }
3494  else
3496 
3497  TIter nxtid(gr->GetIDTelescopes());
3498  KVIDTelescope* idt;
3499  while ((idt = (KVIDTelescope*) nxtid())) {
3500  idt->SetIDGrid(gr);
3501  }
3502  }
3503 }
3504 
3505 
3509 
3511 {
3512  // Fill list of ID telescopes with which this grid is associated
3513  // from list of names read from ascii file.
3514 
3515  gr->ClearListOfTelescopes();
3516  if (gr->GetParameters()->HasParameter("IDTelescopes")) {
3517  KVString tel_list = gr->GetParameters()->GetStringValue("IDTelescopes");
3518  tel_list.Begin(",");
3519  while (!tel_list.End()) {
3520  TString tel_name = tel_list.Next();
3521  KVIDTelescope* idt = GetIDTelescope(tel_name.Data()) ;
3522  if (idt) gr->AddIDTelescope(idt);
3523  }
3524  }
3525 }
3526 
3527 
3528 
3538 
3540 {
3541  // Use OpenGL viewer to view multidetector geometry (only for ROOT geometries)
3542  //
3543  // If option="tracks" we draw any tracks corresponding to the last simulated
3544  // event whose detection was simulated with DetectEvent
3545  // If option="tracks:[numberlist]" with a list of numbers,
3546  // it will be interpreted as a KVNumberList containing the Z of tracks to be drawn
3547  // e.g. option="tracks:1-92" draw only tracks with 1<=Z<=92 (no neutrons)
3548  // option="tracks:2" draw only helium isotopes
3549  if (IsROOTGeometry()) {
3550  GetGeometry()->GetTopVolume()->Draw("ogl");
3551  KVString opt(option);
3552  opt.Begin(":");
3553  if (opt.Next() == "tracks") {
3554  if (!opt.End()) {
3555  KVNumberList zlist(opt.Next());
3556  GetNavigator()->DrawTracks(&zlist);
3557  }
3558  else
3559  GetNavigator()->DrawTracks();
3560  }
3561 #ifdef WITH_OPENGL
3562  TGLViewer* view = (TGLViewer*)gPad->GetViewer3D();
3565  view->SetSmoothLines(kTRUE);
3566  view->SetSmoothPoints(kTRUE);
3567 #endif
3568  }
3569  else Error("Draw", "Only ROOT geometries can be viewed");
3570 
3571 }
3572 
3573 
3574 
3576 
3578 {
3580 }
3581 
3582 
3583 
3588 
3590 {
3591  // Create TH2F histograms for all IDTelescopes of the array
3592  // They will be added to the list
3593  // histograms will have resolution of dimension*dimension
3594 
3596  KVIDTelescope* idt;
3597  while ((idt = (KVIDTelescope*)it())) {
3598  TString name(idt->GetName());
3599  name.ReplaceAll("-", "_");
3600  list->Add(new TH2F(name, Form("Hits in %s", idt->GetName()), dimension, 0., 0., dimension, 0., 0.));
3601  }
3602 }
3603 
3604 
3605 
3608 
3610 {
3611  // Fill TH2F histograms for all IDTelescopes of the array
3612 
3614  KVIDTelescope* idt;
3615  while ((idt = (KVIDTelescope*)it())) {
3616  TString name(idt->GetName());
3617  name.ReplaceAll("-", "_");
3618  TH2F* h = (TH2F*)list->FindObject(name);
3619  if (h) h->Fill(idt->GetIDMapX(), idt->GetIDMapY());
3620  }
3621 }
3622 
3623 
3624 
3627 
3629 {
3630  // Modify the transparency of detector volumes in OpenGL view
3631 
3632  TIter itV(GetGeometry()->GetListOfVolumes());
3633  TGeoVolume* vol;
3634  while ((vol = (TGeoVolume*)itV())) vol->SetTransparency(t);
3635 }
3636 
3637 
3638 
3642 
3644 {
3645  // Calculate all possible (sub-)trajectories
3646  // for particle reconstruction (GetReconTrajectories())
3647 
3648  unique_ptr<KVSeqCollection> groups(GetStructureTypeList("GROUP"));
3649  TIter it(groups.get());
3650  KVGroup* group;
3651  Int_t ntr = 0;
3652  Info("CalculateReconstructionTrajectories", "Calculating trajectories for particle reconstruction:");
3654  std::cout << "\xd" << " -- calculated " << ntr << " reconstruction trajectories" << std::flush;
3655  while ((group = (KVGroup*)it())) {
3656  ntr += group->CalculateReconstructionTrajectories();
3658  std::cout << "\xd" << " -- calculated " << ntr << " reconstruction trajectories" << std::flush;
3659  }
3661  std::cout << " -- calculated " << ntr << " reconstruction trajectories" << std::endl;
3662  else
3663  std::cout << std::endl;
3664 }
3665 
3666 
3667 
3674 
3676 {
3677  // Track over all possible particle trajectories calling
3678  // GetIDTelescopes(KVDetector*,KVDetector*)
3679  // for each pair of (present & functioning) detectors.
3680  // This will create all possible KVIDTelescope identification
3681  // objects and put them in list fIDTelescopes
3682 
3683  fIDTelescopes->Delete();
3684  TIter next_traj(GetTrajectories());
3685  KVGeoDNTrajectory* traj;
3686  Int_t count = 0;
3687  Info("DeduceIdentificationTelescopesFromGeometry", "Calculating...");
3689  std::cout << "\xd" << " -- created " << count << " telescopes" << std::flush;
3690  while ((traj = (KVGeoDNTrajectory*)next_traj())) { // loop over all trajectories
3691 
3692  traj->IterateFrom(); // from furthest-out to closest-in detector
3693 
3695  while ((N = traj->GetNextNode())) {
3696  KVGeoDetectorNode* Nplus1 = traj->GetNodeInFront(N);
3697 
3698  if (Nplus1) {
3699  count += GetIDTelescopes(Nplus1->GetDetector(), N->GetDetector(), traj->AccessIDTelescopeList());
3701  std::cout << "\xd" << " -- created " << count << " telescopes" << std::flush;
3702  }
3703  }
3704  }
3706  std::cout << " -- created " << count << " telescopes" << std::endl;
3707  else
3708  std::cout << std::endl;
3709 }
3710 
3711 
3712 
3716 
3718 {
3719  // Eliminate any trajectories which are just sub-trajectories of others
3720  // For each trajectory in list fTrajectories, we add a reference to the trajectory to each node on the trajectory
3721 
3722  TIter it(&fTrajectories);
3723  KVGeoDNTrajectory* tr;
3724  KVList duplicates;
3725  // look for duplicate sub-trajectories
3726  while ((tr = (KVGeoDNTrajectory*)it())) {
3727  int len_tr = tr->GetN();
3728  TIter it2(&fTrajectories);
3729  KVGeoDNTrajectory* tr2;
3730  while ((tr2 = (KVGeoDNTrajectory*)it2())) {
3731  if ((tr2 != tr) && (len_tr < tr2->GetN()) && (tr2->ContainsPath(tr))) {
3732  duplicates.Add(tr);
3733  break;
3734  }
3735  }
3736  }
3737  // remove duplicates
3738  if (duplicates.GetEntries()) {
3739  TIter it_dup(&duplicates);
3740  while ((tr = (KVGeoDNTrajectory*)it_dup())) {
3741  fTrajectories.Remove(tr);
3742  }
3743  Info("AssociateTrajectoriesAndNodes", "Removed %d duplicated sub-trajectories", duplicates.GetEntries());
3744  }
3745  Info("AssociateTrajectoriesAndNodes", "Calculated %d particle trajectories", fTrajectories.GetEntries());
3746  it.Reset();
3747  while ((tr = (KVGeoDNTrajectory*)it())) {
3748  tr->AddToNodes();
3749  }
3750 }
3751 
3752 
3753 
3755 
3757 {
3758  if (N->GetNTraj() > 1) {
3759  if (!multitraj_nodes.FindObject(N)) { // look for any detectors which are on multiple trajectories
3760  //cout << "multitraj node found: " << N->GetName() << " (" << N->GetNTraj() << ")" << endl;
3761  multitraj_nodes.Add(N);
3762  TIter tr(N->GetTrajectories());
3763  KVGeoDNTrajectory* traj;
3764  while ((traj = (KVGeoDNTrajectory*)tr())) { // for each trajectory associated with detector
3765  if (tried_trajectories.FindObject(traj)) continue; // trajectory already used
3766  tried_trajectories.Add(traj);
3767  traj->IterateFrom();
3768  KVGeoDetectorNode* node;
3769  while ((node = traj->GetNextNode())) { // store names of all detectors on trajectory
3770  detectors_of_group.Add(node);
3771  RecursiveTrajectoryClustering(node, tried_trajectories, multitraj_nodes, detectors_of_group);
3772  }
3773  }
3774  }
3775  }
3776  else if (N->GetNTraj() == 1) {
3777  // single-trajectory node.
3778  // work along trajectory adding nodes to group
3779  KVGeoDNTrajectory* traj = (KVGeoDNTrajectory*)N->GetTrajectories()->First();
3780  if (tried_trajectories.FindObject(traj)) return; // trajectory already used
3781  tried_trajectories.Add(traj);
3782  traj->IterateFrom();
3783  KVGeoDetectorNode* node;
3784  while ((node = traj->GetNextNode())) { // store names of all detectors on trajectory
3785  detectors_of_group.Add(node);
3786  RecursiveTrajectoryClustering(node, tried_trajectories, multitraj_nodes, detectors_of_group);
3787  }
3788  }
3789  else {
3790  // orphan node? single-detector array?
3791  detectors_of_group.Add(N);
3792  }
3793 }
3794 
3795 
3796 
3803 
3805 {
3806  // Create and return pointer to new KVGroupReconstructor for reconstructing particles
3807  // in the given group. Returns nullptr if group is not part of this array.
3808  //
3809  // Plugins for specific arrays can be defined as plugins using the name of the array:
3810  // +Plugin.KVGroupReconstructor: my_array my_group_reconstructor my_lib "my_group_reconstructor()"
3811 
3812  KVGroupReconstructor* gr(nullptr);
3813  if (GetGroup(g->GetName())) {
3814  // look for plugin
3816  if (!gr) gr = new KVGroupReconstructor;
3817  }
3818  return gr;
3819 }
3820 
3821 
3822 
3826 
3828 {
3829  // Call this method just after opening a raw data file in order to perform any
3830  // necessary initialisations, depending on the type of data
3831 
3832 #ifdef WITH_BUILTIN_GRU
3833  if (r->GetDataFormat() == "EBYEDAT")
3834  dynamic_cast<KVGANILDataReader*>(r)->ConnectRawDataParameters();
3835 #endif
3836 }
3837 
3838 
3839 
3844 
3846 {
3847  // Deduce the "groups" in the array from the trajectories
3848  // Any trajectories with 1 or more common detectors define a group.
3849  // The group is constituted of all detectors belonging to the trajectories of the group.
3850 
3851  Info("DeduceGroupsFromTrajectories", "Deducing groups of detectors from trajectories");
3852  Int_t number_of_groups = 0;
3853  TIter next_det(GetDetectors());
3854  unique_ptr<KVSeqCollection> stl(GetStructureTypeList("GROUP"));
3855  if (stl.get() && stl->GetEntries()) {
3856  Info("DeduceGroupsFromTrajectories", "Deleting existing %d groups in array", stl->GetEntries());
3857  ClearStructures("GROUP");
3858  Info("DeduceGroupsFromTrajectories", "Done");
3859  }
3860  KVDetector* det;
3861  KVUniqueNameList tried_trajectories;//avoid double-counting/infinite loops
3862  KVUniqueNameList multitraj_nodes;//avoid double-counting/infinite loops
3863  while ((det = (KVDetector*) next_det())) {
3864  if (det->GetGroup()) continue; // group assignment already done
3865  KVUniqueNameList detectors_of_group;
3866  RecursiveTrajectoryClustering(det->GetNode(), tried_trajectories, multitraj_nodes, detectors_of_group);
3867  if (!detectors_of_group.GetEntries()) continue;
3868  KVGroup* Group = new KVGroup;
3869  Group->SetNumber(++number_of_groups);
3870  Add(Group);
3871  TIter next_node(&detectors_of_group);
3873  while ((d = (KVGeoDetectorNode*)next_node())) Group->Add(d->GetDetector());
3874  }
3875  TIter tr(&fTrajectories);
3876  KVGeoDNTrajectory* t;
3877  Info("DeduceGroupsFromTrajectories", "Filling group trajectory lists");
3878  while ((t = (KVGeoDNTrajectory*)tr())) {
3879  if (t->GetNodeAt(0)->GetDetector()->GetGroup())
3880  t->GetNodeAt(0)->GetDetector()->GetGroup()->AddTrajectory(t);
3881  else {
3882  t->Print();
3883  t->GetNodeAt(0)->GetDetector()->Print();
3884  }
3885  }
3886 }
3887 
3888 
3889 
3893 
3895 {
3896  // Called when required to fill KVReconstructedNucleus::fDetList with pointers to
3897  // the detectors whose names are stored in KVReconstructedNucleus::fDetNames.
3898 
3899  DetList->Clear();
3900  DetNames.Begin("/");
3901  while (!DetNames.End()) {
3902  KVDetector* det = GetDetector(DetNames.Next(kTRUE));
3903  if (det) DetList->Add(det);
3904  }
3905 }
3906 
3907 
3908 
3919 
3921 {
3922  // Set status (IsOK) of particle by comparing its identification/calibration codes
3923  // with those set as acceptable in fAcceptIDCodes and fAcceptECodes.
3924  // The default lists are defined in variables of the form
3925  // [DataSet].[name].ReconstructedNuclei.AcceptIDCodes: [list]
3926  // [DataSet].[name].ReconstructedNuclei.AcceptECodes: [list]
3927  // where DataSet is an optional dataset name for dataset-specific lists
3928  // name is the name of the multidetector array
3929  // list is a numeric list (KVNumberList format)
3930  // If either list is empty, no selection is made for the corresponding code
3931 
3932  Bool_t ok = kTRUE;
3934  if (!fAcceptECodes.IsEmpty()) ok = ok && fAcceptECodes.Contains(NUC->GetECode());
3935  NUC->SetIsOK(ok);
3936 }
3937 
3938 
3939 
3946 
3948 {
3949  // Set the minimum number of particles which are "OK" in the event
3950  // (usually a KVReconstructedEvent) for it to be retained for analysis.
3951  // This could, for example, depend on the experimental multiplicity trigger
3952  // used during the run.
3953  // This default version sets a minimum of 1 "OK" particle
3954  e->SetMinimumOKMultiplicity(1);
3955 }
3956 
3957 
3958 #ifdef WITH_BUILTIN_GRU
3959 
3962 
3964 {
3965  // General method for reading raw data in old GANIL ebyedat format
3966  AbstractMethod("handle_raw_data_event_ebyedat");
3967  return kFALSE;
3968 }
3969 
3970 #endif
3971 
3972 
3975 
3977 {
3978  // reset acquisition parameters etc. before reading new raw data event
3979 
3982  fHandledRawData = false;
3983  // reset fired signals
3984  TIter nxt(&fFiredSignals);
3985  KVDetectorSignal* ds;
3986  while ((ds = (KVDetectorSignal*)nxt())) {
3987  ds->SetFired(false);
3988  ds->SetValue(0);
3989  }
3990  fFiredSignals.Clear();
3991 }
3992 
3993 
3994 
4002 
4004 {
4005  // Perform any operations to finalise the description of the multidetector
4006  // which can only be done once the geometry is closed, e.g. use KVGeoImport
4007  // to set up nodes, trajectories, detectors, idtelescopes, etc.
4008  // This has to be kept separate for use with KVExpSetUp which first fills
4009  // a single ROOT geometry with all component KVMultiDetArray geometries,
4010  // then closes the geometry only when all have been built.
4011 }
4012 
4013 
4014 
4017 
4019 {
4020  // Copy any parameters in fReconParameters in to the reconstructed event parameter list
4021  *(e->GetParameters()) += fReconParameters;
4022 }
4023 
4024 
4025 
4038 
4040 {
4041  // values of fired raw data signals (acquisition parameters) from last read raw event
4042  // are copied to the fReconParameters list of parameters to be stored with the
4043  // reconstructed event.
4044  //
4045  // the format for each signal is:
4046  //
4047  // ACQPAR.[array].[detector].[signal]
4048  // ACQPAR.[array].[signal]
4049  //
4050  // in the first case for signals associated with detectors, in the latter case signals
4051  // which are not associated with a detector
4052 
4053  TIter it(GetFiredSignals());
4054  KVDetectorSignal* o;
4055  while ((o = (KVDetectorSignal*)it())) {
4056  fReconParameters.SetValue(Form("ACQPAR.%s.%s", GetName(), o->GetFullName().Data()), o->GetValue());
4057  }
4058 }
4059 
4060 
4061 
4070 
4072 {
4073  // Update array according to last event read using the KVRawDataReader object
4074  // (it is assumed that KVRawDataReader::GetNextEvent() was called before calling this method)
4075  //
4076  // Return kTRUE if raw data was treated
4077  //
4078  // All fired acquisition parameters are written in the fReconParameters list,
4079  // ready to be copied to the reconstructed event
4080 
4081  fRawDataReader = rawdata;
4083  if (rawdata->GetDataFormat() == "MFM") {
4084 #ifdef WITH_MFM
4086 #endif
4087  }
4088  else if (rawdata->GetDataFormat() == "PROTOBUF") {
4089 #ifdef WITH_PROTOBUF
4091 #endif
4092  }
4093  else if (rawdata->GetDataFormat() == "EBYEDAT") {
4094 #ifdef WITH_BUILTIN_GRU
4096 #endif
4097  }
4098  if (fHandledRawData) {
4100  }
4101  return fHandledRawData;
4102 }
4103 
4104 
4105 #ifdef WITH_MFM
4106 
4115 
4117 {
4118  // Update array according to last event read from MFM buffer
4119  // (it is assumed that MFMBufferReader::ReadNextFrame() was called before calling this method)
4120  //
4121  // Return kTRUE if raw data was treated
4122  //
4123  // All fired acquisition parameters are written in the fReconParameters list,
4124  // ready to be copied to the reconstructed event
4125 
4127  bool ok = false;
4128  ok = handle_raw_data_event_mfmfile(bufrdr);
4129  if (ok) {
4131  }
4132  return ok;
4133 }
4134 
4135 #endif
4136 
4137 
4148 
4150 {
4151  // Given a pointer to a detector (may be nullptr) try to set the data sig_data in the associated signal
4152  // of the given type, sig_typ.
4153  //
4154  // If the signal does not exist for the detector, it will be created.
4155  //
4156  // If detector pointer is null, the signal will be looked for in fExtraRawDataSignals
4157  // and created if necessary.
4158  //
4159  // All fired detectors and signals are added to the lists fFiredDetectors and fFiredSignals.
4160 
4161  KVDetectorSignal* det_signal = nullptr;
4162  if (detector) {
4163  det_signal = detector->GetDetectorSignal(sig_type);
4164  if (!det_signal) {
4165  det_signal = detector->AddDetectorSignal(sig_type);
4166  }
4167  fFiredDetectors.Add(detector);
4168  }
4169  else {
4170  // raw data not associated with a detector
4171  TString sig_name;
4172  if (detname != "") sig_name = Form("%s.%s", detname.Data(), sig_type.Data());
4173  else sig_name = sig_type;
4174  det_signal = fExtraRawDataSignals.get_object<KVDetectorSignal>(sig_name);
4175  if (!det_signal) {
4176  det_signal = new KVDetectorSignal(sig_name);
4177  fExtraRawDataSignals.Add(det_signal);
4178  }
4179  }
4180  if (det_signal) {
4181  det_signal->SetValue(sig_data);
4182  det_signal->SetFired();
4183  fFiredSignals.Add(det_signal);
4184  }
4185 }
4186 
4187 
4188 
4194 
4196 {
4197  // Take values 'ACQPAR.[array_name].[detname].[signal]' or 'ACQPAR.[array_name].[signal]'
4198  // in the parameter list and use them to set values of raw acquisition parameters.
4199  //
4200  // Any detector signals which don't already exist will be created
4201 
4202  prepare_to_handle_new_raw_data(); // clear previous fired parameters/detectors
4203  int N = l.GetNpar();
4204  for (int i = 0; i < N; ++i) {
4205  KVNamedParameter* np = l.GetParameter(i);
4206 
4207  KVString name(np->GetName());
4208  if (name.BeginsWith("ACQPAR")) {
4209  // 3 '.' => 4 values means associated detector
4210  // 2 '.' => 3 values means no detector
4211  int dots = name.GetNValues(".");
4212  bool with_det = (dots == 4);
4213  assert(with_det || (dots == 3)); // sanity check
4214  name.Begin(".");
4215  name.Next(); // "ACQPAR"
4216  if (name.Next() != GetName()) continue; // check name of array - somebody else's parameter ?
4217  KVString det_name;
4218  KVString sig_type;
4219  KVDetector* det = nullptr;
4220  if (with_det) {
4221  det_name = name.Next();
4222  sig_type = name.Next();
4223  det = GetDetector(det_name);
4224  }
4225  else {
4226  sig_type = name.Next();
4227  }
4228  add_and_set_detector_signal(det, det_name, np->GetDouble(), sig_type);
4229  }
4230  }
4231 }
4232 
4233 
4234 
4250 
4252 {
4253  // We first look for a file with the name given by
4254  //
4255  // [dataset].[name].OoODetectors: [name.OoODetectors.dat]
4256  //
4257  // which should contain the runlists for each malfunctioning detector.
4258  // If found we add to the experiment database a table '[name].OoO Detectors' where [name] is the name of this array.
4259  //
4260  // Then we look for a file with the name given by
4261  //
4262  // [dataset].[name].CalibrationFiles: [CalibrationFiles.dat]
4263  //
4264  // which should contain the names of files to read with each type of calibration
4265  // If found we add to the experiment database a table '[name].Calibrations' where [name] is the name of this array,
4266  // containing all calibrations as KVDBParameterSet objects with the name of the detector concerned.
4267 
4268  ReadOoODetectors(db);
4270 }
4271 
4272 
4273 
4275 
4277 {
4278  TString basic_name = db->GetCalibFileName(keyw);
4279  if (basic_name == "") {
4280  Info(meth, "No name found for \"%s\" file", keyw);
4281  return "";
4282  }
4283  Info(meth, "Search for %s for dataset %s ...", basic_name.Data(), fDataSet.Data());
4284  TString fp;
4285  SearchKVFile(basic_name.Data(), fp, fDataSet);
4286  if (fp == "") {
4287  Info(meth, "\tNo file found ...");
4288  }
4289  return fp;
4290 }
4291 
4292 
4293 
4295 
4296 unique_ptr<KVFileReader> KVMultiDetArray::GetKVFileReader(KVExpDB* db, const Char_t* meth, const Char_t* keyw)
4297 {
4298 
4299  TString fp = GetFileName(db, meth, keyw);
4300  if (fp == "")
4301  return unique_ptr<KVFileReader>();
4302 
4303  unique_ptr<KVFileReader> fr(new KVFileReader());
4304  if (!fr->OpenFileToRead(fp.Data())) {
4305  Error(meth, "Error in opening file %s", fp.Data());
4306  fr.reset(nullptr);
4307  }
4308  else
4309  Info(meth, "Reading %s file", fp.Data());
4310  return fr;
4311 }
4312 
4313 
4314 
4316 
4318 {
4319 
4320  unique_ptr<KVFileReader> fr = GetKVFileReader(db, "ReadCalibrationFiles()", "CalibrationFiles");
4321  if (!fr.get())
4322  return;
4323 
4324  KVDBTable* calib_table = db->AddTable(Form("%s.Calibrations", GetName()), Form("Calibrations for %s", GetName()));
4325  while (fr->IsOK()) {
4326  fr->ReadLine(0);
4327  if (fr->GetCurrentLine().BeginsWith("#") || fr->GetCurrentLine() == "") {}
4328  else {
4329  ReadCalibFile(fr->GetCurrentLine().Data(), db, calib_table);
4330  }
4331  }
4332  fr->CloseFile();
4333 }
4334 
4335 
4336 
4377 
4378 void KVMultiDetArray::ReadCalibFile(const Char_t* filename, KVExpDB* db, KVDBTable* calib_table)
4379 {
4380  // Read a calibration file with the format
4381  //
4382  //~~~~~~~~~~~~~
4383  // RunList: 1546-7485
4384  // SignalIn: PG
4385  // SignalOut: Volts
4386  // CalibType: ChannelVolt
4387  // CalibOptions: func=pol3,min=0,max=1
4388  // ZRange: 2-92
4389  // [detector1]: 0.0,0.261829,0.0
4390  // [detector2]: 0.1,0.539535,1.2
4391  //~~~~~~~~~~~~~
4392  //
4393  //The `[RunList]` is optional: if not given, the calibration will be applied to all runs in the database.
4394  //
4395  //If different parameters are required for different sets of runs, they should be written in different
4396  //files (all of which are listed in `CalibrationFiles.dat` or `[array].CalibrationFiles.dat`).
4397  //
4398  //The `[CalibClass]`, if given, must correspond to a KVCalibrator plugin name. The list of plugin names and the corresponding
4399  //classes can be retrieved with
4400  //
4401  //~~~~~~~~~~~
4402  //KVBase::GetListOfPlugins("KVCalibrator")
4403  //KVBase::GetListOfPluginURIs("KVCalibrator")
4404  //~~~~~~~~~~~
4405  //
4406  //KVCalibrator objects are added to detectors as required by the contents of calibration files.
4407  //If any detector has an existing calibrator of type `[CalibType]` which is not of the given class
4408  //it will be replaced with a new calibrator corresponding to the plugin.
4409  //
4410  //The `[CalibOptions]` is optional: list in `[CalibOptions]` will be used
4411  //to complete set-up of any new calibrator objects by calling the KVCalibrator::SetOptions()
4412  //method.
4413  //
4414  //`[CalibOptions]` should hold a comma-separated list of `parameter=value` pairs which will be used
4415  //to fill a KVNameValueList for the method call. See the KVCalibrator::SetOptions() method.
4416  //
4417  //`[ZRange]` is an option if several calibrations need to be used to provide the same signal
4418  //for certain detectors depending on the atomic number Z of the particle detected.
4419 
4420 
4421  TString fullpath = "";
4422  if (!SearchKVFile(filename, fullpath, fDataSet)) {
4423  Info("ReadCalibFile", "%s does not exist or not found", filename);
4424  return;
4425  }
4426 
4427  Info("ReadCalibFile", "file : %s found", fullpath.Data());
4428  TEnv env;
4429  env.ReadFile(fullpath, kEnvAll);
4430 
4431  // read options from file
4432  KVNameValueList options;
4433  KVString opt_list = "RunList SignalIn SignalOut CalibType CalibClass CalibOptions ZRange";
4434  opt_list.Begin(" ");
4435  while (!opt_list.End()) {
4436  KVString opt = opt_list.Next();
4437  KVString opt_val = env.GetValue(opt, "");
4438  opt_val.Remove(TString::kBoth, ' ');
4439  options.SetValue(opt, opt_val.Data());
4440  }
4441  // check for stupid spellnig mitskaes
4442  if (TString(env.GetValue("Runlist", "")) != "") {
4443  Warning("ReadCalibFile", "Calibration has 'Runlist' parameter (ignored): %s, did you mean 'RunList'?", env.GetValue("Runlist", ""));
4444  }
4445 
4446  if (options.GetTStringValue("SignalIn") == "") {
4447  Error("ReadCalibFile", "No input signal defined : SignalIn");
4448  return;
4449  }
4450  if (options.GetTStringValue("SignalOut") == "") {
4451  Error("ReadCalibFile", "No output signal defined : SignalOut");
4452  return;
4453  }
4454  if (options.GetTStringValue("CalibType") == "") {
4455  Error("ReadCalibFile", "No calibration type defined : CalibType");
4456  return;
4457  }
4458  Bool_t check_class(options.GetTStringValue("CalibClass") != "");
4459  TString calibrator_class;
4460  if (check_class) {
4461  TPluginHandler* ph = LoadPlugin("KVCalibrator", options.GetStringValue("CalibClass"));
4462  if (ph) calibrator_class = ph->GetClass();
4463  else {
4464  Error("ReadCalibFile", "No calibrator plugin of type %s", options.GetStringValue("CalibClass"));
4465  return;
4466  }
4467  }
4468 
4469  KVString clop;
4470  if (options.HasParameter("CalibOptions")) clop = options.GetStringValue("CalibOptions");
4471 
4472  KVString zrange;
4473  if (options.HasParameter("ZRange")) zrange = options.GetStringValue("ZRange");
4474 
4475  KVNumberList run_list = db->GetRunList();
4476  if (options.GetTStringValue("RunList") != "") {
4477  run_list.Set(options.GetTStringValue("RunList"));
4478  Info("ReadCalibFile", "Calibration used for runs %s", run_list.AsString());
4479  }
4480  else {
4481  Info("ReadCalibFile", "Calibration used for all runs in database");
4482  }
4483 
4484  TIter next(env.GetTable());
4485  TEnvRec* rec = 0;
4486  KVDBParameterSet* par = 0;
4487 
4488  while ((rec = (TEnvRec*)next())) {
4489 
4490  TString sname(rec->GetName());
4491  KVDetector* det = GetDetector(sname);
4492  if (!det) continue;
4493 
4494  KVString lval(rec->GetValue());
4495  par = new KVDBParameterSet(sname.Data(), options.GetStringValue("CalibType"), lval.GetNValues(","));
4496  par->SetParameter("SignalIn", options.GetStringValue("SignalIn"));
4497  par->SetParameter("SignalOut", options.GetStringValue("SignalOut"));
4498  // put infos on required calibrator class into database so that it can be replaced
4499  // as needed in SetCalibratorParameters
4500  par->SetParameter("CalibClass", options.GetStringValue("CalibClass"));
4501  if (clop != "") par->SetParameter("CalibOptions", clop);
4502  if (zrange != "") par->SetParameter("ZRange", zrange);
4503  Int_t np = 0;
4504  lval.Begin(",");
4505  while (!lval.End()) {
4506  par->SetParameter(np++, lval.Next().Atof());
4507  }
4508  calib_table->AddRecord(par);
4509  db->LinkRecordToRunRange(par, run_list);
4510 
4511  }
4512 }
4513 
4514 
4515 #ifdef WITH_MFM
4516 
4522 
4524 {
4525  // Update array according to last event read using the KVMFMDataFileReader object
4526  // (it is assumed that KVRawDataReader::GetNextEvent() was called before calling this method)
4527  //
4528  // Return kTRUE if raw data was treated
4529 
4530  if (mfmreader.IsFrameReadMerge()) {
4531  return handle_raw_data_event_mfmmergeframe(mfmreader.GetMergeManager());
4532  }
4533  else {
4534  return handle_raw_data_event_mfmframe(mfmreader.GetFrameRead());
4535  }
4536  return kFALSE;
4537 }
4538 
4539 
4540 
4544 
4545 Bool_t KVMultiDetArray::handle_raw_data_event_mfmmergeframe(const MFMMergeFrameManager& mergeframe)
4546 {
4547  // Method used to handle merged MFM frames
4548  // We call handle_raw_data_event_mfmframe() for each frame contained in the merge
4549 
4550  Bool_t ok = false;
4551  while (mergeframe.ReadNextFrame()) {
4552  Bool_t me = handle_raw_data_event_mfmframe(mergeframe.GetFrameRead());
4553  ok = (ok || me);
4554  }
4555  return ok;
4556 }
4557 
4558 
4559 
4570 
4572 {
4573  // Method used to treat raw data in MFM format read by KVMFMDataFileReader
4574  //
4575  // Here we dispatch two types of frame - MFMEbyedatFrame & MFMMesytecMDPPFrame -
4576  // to specific methods - handle_raw_data_event_mfmframe_ebyedat() and
4577  // handle_raw_data_event_mfmframe_mesytec_mdpp()
4578  // which need to be implemented in child classes for specific arrays which
4579  // use these data formats.
4580  //
4581  // Return kTRUE if raw data was treated
4582 #ifdef WITH_MESYTEC
4583  if (mfmframe.GetFrameType() == MFM_MESYTEC_MDPP_FRAME_TYPE)
4584  return handle_raw_data_event_mfmframe_mesytec_mdpp((const MFMMesytecMDPPFrame&)mfmframe);
4585 #endif
4586  if (mfmframe.GetFrameType() == MFM_EBY_EN_FRAME_TYPE
4587  || mfmframe.GetFrameType() == MFM_EBY_TS_FRAME_TYPE
4588  || mfmframe.GetFrameType() == MFM_EBY_EN_TS_FRAME_TYPE)
4589  return handle_raw_data_event_mfmframe_ebyedat((const MFMEbyedatFrame&)mfmframe);
4590 
4591  return kFALSE;
4592 }
4593 
4594 
4595 
4598 
4600 {
4601  // Read a raw data event from a EBYEDAT MFM Frame.
4602 
4603  AbstractMethod("handle_raw_data_event_mfmframe_ebyedat");
4604  return kFALSE;
4605 }
4606 
4607 
4608 #ifdef WITH_MESYTEC
4609 
4612 
4613 Bool_t KVMultiDetArray::handle_raw_data_event_mfmframe_mesytec_mdpp(const MFMMesytecMDPPFrame&)
4614 {
4615  // Read a raw data event from a Mesytec MFM Frame.
4616 
4617  AbstractMethod("handle_raw_data_event_mfmframe_mesytec_mdpp");
4618  return kFALSE;
4619 }
4620 
4621 #endif
4622 #endif
4623 
4624 #ifdef WITH_PROTOBUF
4625 
4627 
4629 {
4630  AbstractMethod("handle_raw_data_event_protobuf");
4631  return kFALSE;
4632 }
4633 
4634 #endif
4635 
4636 
4639 
4641 {
4642  // For each IDtelescope in array, calculate an identification grid
4643 
4644  TIter nxtid(GetListOfIDTelescopes());
4645  KVIDTelescope* idt;
4646  while ((idt = (KVIDTelescope*) nxtid())) {
4647  idt->CalculateDeltaE_EGrid("1-92", 0, 20);
4648  }
4649 }
4650 
4651 
4652 
4657 
4659 {
4660  // Sets status of detectors (KVDetector::IsPresent() and KVDetector::IsWorking()) for a given run of a dataset.
4661  //
4662  // If 'myname' is given, we look in database table "myname.OoODets"
4663 
4664  KVRList* absdet = (myname != "" ? kvrun->GetLinks(Form("%s.Absent Detectors", myname.Data())) : kvrun->GetLinks("Absent Detectors"));
4665  KVRList* ooodet = (myname != "" ? kvrun->GetLinks(Form("%s.OoO Detectors", myname.Data())) : kvrun->GetLinks("OoO Detectors"));
4666 
4667  TIter next(GetDetectors());
4668  KVDetector* det;
4669 
4670  Int_t ndet_absent = 0;
4671  Int_t ndet_ooo = 0;
4672  TString absent_dets, ooo_dets;
4673 
4674  while ((det = (KVDetector*)next())) {
4675  //Test de la presence ou non du detecteur
4676  if (!absdet) {
4677  det->SetPresent();
4678  }
4679  else {
4680  if (absdet->FindObject(det->GetName())) {
4681  det->SetPresent(kFALSE);
4682  if (ndet_absent) absent_dets += ",";
4683  absent_dets += det->GetName();
4684  ndet_absent += 1;
4685  }
4686  else {
4687  det->SetPresent();
4688  }
4689  }
4690  if (det->IsPresent()) {
4691  //Test du bon fonctionnement ou non du detecteur
4692  if (!ooodet) {
4693  det->SetDetecting();
4694  }
4695  else {
4696  if (ooodet->FindObject(det->GetName())) {
4697  det->SetDetecting(kFALSE);
4698  if (ndet_ooo) ooo_dets += ",";
4699  ooo_dets += det->GetName();
4700  ndet_ooo += 1;
4701  }
4702  else {
4703  det->SetDetecting();
4704  }
4705  }
4706  }
4707  }
4708 
4709  if (ndet_absent) Info("CheckStatusOfDetectors", "%d detectors absent during run : %s", ndet_absent, absent_dets.Data());
4710  else Info("CheckStatusOfDetectors", "All detectors present during run");
4711  if (ndet_ooo) Info("CheckStatusOfDetectors", "%d detectors malfunctioned during run : %s", ndet_ooo, ooo_dets.Data());
4712  else Info("CheckStatusOfDetectors", "All detectors functioning during run");
4713 }
4714 
4715 
4716 
4731 
4733 {
4734  // Read a file containing runlists for each temporarily non-functioning detector.
4735  //
4736  // The file should be in TEnv format like so:
4737  //
4738  //~~~~
4739  // DET_1: 100-122,541-1938
4740  // DET_2,DET_3: 91-765
4741  //~~~~
4742  //
4743  // i.e. more than one detector can be associated with the same runs (comma-separated list of
4744  // detector names) and the list of runs are given using KVNumberList syntax.
4745  //
4746  // The data is added to the database in a table '[name].OoO Detectors' with the name of this array.
4747 
4748  TString fullpath;
4749  if (!db->FindCalibFile("OoODet", fullpath)) return;
4750 
4751  Info("ReadOoODetectors()", "Reading lists of out-of-order detectors...");
4752  auto fOoODet = db->AddTable(Form("%s.OoO Detectors", GetName()), "Name of out of order detectors");
4753 
4754  KVDBRecord* dbrec = 0;
4755  TEnv env;
4756  TEnvRec* rec = 0;
4757  env.ReadFile(fullpath.Data(), kEnvAll);
4758  TIter it(env.GetTable());
4759 
4760  while ((rec = (TEnvRec*)it.Next())) {
4761  KVString srec(rec->GetName());
4762  KVNumberList nl(rec->GetValue());
4763  if (srec.Contains(",")) {
4764  srec.Begin(",");
4765  while (!srec.End()) {
4766  dbrec = new KVDBRecord(srec.Next(kTRUE), "OoO Detector");
4767  dbrec->AddKey("Runs", "List of Runs");
4768  fOoODet->AddRecord(dbrec);
4769  db->LinkRecordToRunRange(dbrec, nl);
4770  }
4771  }
4772  else {
4773  dbrec = new KVDBRecord(rec->GetName(), "OoO Detector");
4774  dbrec->AddKey("Runs", "List of Runs");
4775  fOoODet->AddRecord(dbrec);
4776  db->LinkRecordToRunRange(dbrec, nl);
4777  }
4778  }
4779 }
4780 
4781 
int Int_t
unsigned int UInt_t
KVDataSetManager * gDataSetManager
KVDataSet * gDataSet
Definition: KVDataSet.cpp:29
KVIDGridManager * gIDGridManager
KVMultiDetArray * gMultiDetArray
ClassImp(KVPartitionList) void KVPartitionList
Initialisation.
ROOT::R::TRInterface & r
#define SafeDelete(p)
#define d(i)
#define f(i)
#define e(i)
unsigned short UShort_t
char Char_t
const Bool_t kFALSE
bool Bool_t
double Double_t
const Bool_t kTRUE
const char Option_t
R__EXTERN TEnv * gEnv
kEnvUser
kEnvAll
#define N
int type
R__EXTERN TGeoManager * gGeoManager
char * Form(const char *fmt,...)
#define gPad
void SetLabel(const Char_t *lab)
Definition: KVBase.h:194
virtual const Char_t * GetType() const
Definition: KVBase.h:176
static const Char_t * GetWORKDIRFilePath(const Char_t *namefile="")
Definition: KVBase.cpp:127
const Char_t * GetLabel() const
Definition: KVBase.h:198
static bool is_gnuinstall()
Definition: KVBase.h:276
virtual void Print(Option_t *option="") const
Definition: KVBase.cpp:410
virtual void SetType(const Char_t *str)
Definition: KVBase.h:172
static const Char_t * GetDataSetEnv(const Char_t *dataset, const Char_t *type, const Char_t *defval)
Definition: KVBase.cpp:1619
static Bool_t SearchKVFile(const Char_t *name, TString &fullpath, const Char_t *kvsubdir="")
Definition: KVBase.cpp:538
static TPluginHandler * LoadPlugin(const Char_t *base, const Char_t *uri="0")
Definition: KVBase.cpp:793
Base class for all detector calibrations.
Definition: KVCalibrator.h:98
Int_t GetNumberParams() const
Definition: KVCalibrator.h:152
virtual void SetOptions(const KVNameValueList &)
void SetParameter(int i, Double_t par_val) const
Definition: KVCalibrator.h:157
void SetStatus(Bool_t ready)
Definition: KVCalibrator.h:165
void SetOutputSignalType(const TString &type)
Definition: KVCalibrator.h:219
void SetInputSignalType(const TString &type)
Definition: KVCalibrator.h:215
static KVCalibrator * MakeCalibrator(const Char_t *type)
To store calibration parameters in a database ,.
Bool_t HasParameter(const Char_t *name) const
TString GetStringParameter(const TString &name) const
Double_t GetParameter(UShort_t i=0) const
void Print(Option_t *option="") const
Int_t GetParamNumber() const
void SetParameter(UShort_t i, Double_t val)
const KVNameValueList & GetParameters() const
Record folder for the database.
Definition: KVDBRecord.h:42
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:35
Table in a database.
Definition: KVDBTable.h:33
virtual Bool_t AddRecord(KVDBRecord *add)
Definition: KVDBTable.cpp:74
static Bool_t IsRunningBatchAnalysis()
virtual Bool_t AddTable(KVDBTable *table)
Definition: KVDataBase.cpp:84
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:207
const Char_t * GetDataSetDir() const
Definition: KVDataSet.cpp:720
Bool_t HasCalibIdentInfos() const
Definition: KVDataSet.h:403
const Char_t * GetDataSetEnv(const Char_t *type, const Char_t *defval="") const
Definition: KVDataSet.cpp:758
TString GetFullPathToDataSetFile(const Char_t *filename)
Definition: KVDataSet.cpp:1887
void cd() const
Definition: KVDataSet.cpp:736
Bool_t DataBaseUpdateInProgress() const
Definition: KVDataSet.h:249
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.
Definition: KVDetector.h:159
virtual Bool_t IsOK() const
Definition: KVDetector.h:681
TList * GetTelescopesForIdentification()
Definition: KVDetector.cpp:761
KVList * GetAlignedIDTelescopes()
Definition: KVDetector.cpp:736
KVGeoStrucElement * GetParentStructure(const Char_t *type, const Char_t *name="") const
KVGroup * GetGroup() const
void AddDetectorSignal(KVDetectorSignal *ds)
Definition: KVDetector.h:260
virtual void SetEnergyLoss(Double_t e) const
Definition: KVDetector.h:372
KVList * GetHits() const
Return the list of particles hitting this detector in an event.
Definition: KVDetector.h:425
virtual Double_t GetEnergy() const
Definition: KVDetector.h:348
Int_t GetNHits() const
Return the number of particles hitting this detector in an event.
Definition: KVDetector.h:435
KVList * GetIDTelescopes()
Definition: KVDetector.h:550
Double_t GetTheta() const
Definition: KVDetector.h:743
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:645
virtual void DeduceACQParameters(KVEvent *, KVNumberList &)
Definition: KVDetector.h:687
void SetThickness(Double_t thick)
virtual KVDetectorSignal * GetDetectorSignal(const KVString &type) const
Definition: KVDetector.h:532
Bool_t IsCalibrated() const
Definition: KVDetector.h:389
void SetDetecting(Bool_t yes=kTRUE)
Definition: KVDetector.h:676
virtual void RemoveCalibrators()
Definition: KVDetector.cpp:699
Double_t GetPhi() const
Definition: KVDetector.h:761
virtual Double_t GetPunchThroughEnergy(Int_t Z, Int_t A)
virtual Bool_t IsDetecting() const
Definition: KVDetector.h:671
virtual TList * GetAlignedDetectors(UInt_t direction=1)
KVGeoDetectorNode * GetNode()
Definition: KVDetector.h:325
virtual Double_t GetIncidentEnergyFromERes(Int_t Z, Int_t A, Double_t Eres)
virtual Bool_t IsPresent() const
Definition: KVDetector.h:662
TVector3 GetRandomDirection(Option_t *t="isotropic")
Definition: KVDetector.h:719
void ResetAlignedDetectors(UInt_t direction=1)
virtual void Print(Option_t *option="") const
Definition: KVDetector.cpp:364
Bool_t AddCalibrator(KVCalibrator *cal, const KVNameValueList &opts="")
Definition: KVDetector.cpp:478
void SetPresent(Bool_t yes=kTRUE)
Definition: KVDetector.h:667
Abstract base class container for multi-particle events.
Definition: KVEvent.h:66
KVNameValueList * GetParameters() const
Definition: KVEvent.h:203
void Clear(Option_t *opt="")
Clear object properties : name, type/title, number, label.
Definition: KVEvent.h:262
Base class to describe database of an experiment ,.
Definition: KVExpDB.h:19
Bool_t FindCalibFile(const Char_t *type, TString &fullpath) const
Definition: KVExpDB.cpp:477
TString GetCalibFileName(const Char_t *type) const
Definition: KVExpDB.h:108
const KVNumberList & GetRunList() const
Definition: KVExpDB.h:79
virtual void LinkRecordToRunRange(KVDBRecord *rec, UInt_t first_run, UInt_t last_run)
Definition: KVExpDB.cpp:87
Handle reading columns of numeric data in text files.
Definition: KVFileReader.h:119
KVString GetCurrentLine()
Definition: KVFileReader.h:319
ReadStatus ReadLine(const KVString &pattern="")
Definition: KVFileReader.h:242
Bool_t IsOK()
Definition: KVFileReader.h:230
Bool_t OpenFileToRead(const KVString &filename)
Definition: KVFileReader.h:209
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
Bool_t ContainsPath(KVGeoDNTrajectory *other)
KVGeoDetectorNode * GetNodeInFront(const KVGeoDetectorNode *n) 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.
Bool_t IsTracking() const
void ResetTrackID(Int_t id=0)
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)
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
KVGeoStrucElement * GetStructure(const Char_t *name) const
void ClearStructures(const Char_t *type="")
KVGeoStrucElement * GetParentStructure(const Char_t *type, 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="")
Group of detectors which can be treated independently of all others in array.
Definition: KVGroup.h:19
void AddTrajectory(KVGeoDNTrajectory *t)
Definition: KVGroup.h:82
void Reset(Option_t *opt="")
Definition: KVGroup.cpp:114
@ kBackwards
Definition: KVGroup.h:33
@ kForwards
Definition: KVGroup.h:32
virtual void SetNumber(UInt_t num)
Definition: KVGroup.h:38
virtual TList * GetDetectorsInLayer(UInt_t lay)
Definition: KVGroup.cpp:88
virtual UInt_t GetNumberOfDetectorLayers()
Definition: KVGroup.cpp:64
void ClearHitDetectors()
Definition: KVGroup.cpp:222
Extended version of ROOT THashList.
Definition: KVHashList.h:28
Base class for particle identification in a 2D map.
Definition: KVIDGraph.h:31
void RemoveIDTelescope(KVBase *t)
Definition: KVIDGraph.h:415
Handles a stock of identification grids to be used by one or more identification telescopes.
KVList * GetGrids()
virtual void LoadGridsForRun(UInt_t)
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:83
virtual Double_t GetIDMapY(Option_t *opt="")
virtual Bool_t IsReadyForID()
KVIDGrid * CalculateDeltaE_EGrid(const KVNameValueList &AperZ, Int_t npoints=30, Double_t xfactor=1.)
void SetGroup(KVGroup *kvg)
virtual Double_t GetIDMapX(Option_t *opt="")
static KVIDTelescope * MakeIDTelescope(const Char_t *name)
virtual Bool_t SetIdentificationParameters(const KVMultiDetArray *)
void SetIDGrid(KVIDGraph *)
KVDetector * GetDetector(UInt_t n) const
virtual Bool_t CheckTheoreticalIdentificationThreshold(KVNucleus *, Double_t=0.0)
virtual Bool_t CanIdentify(Int_t Z, Int_t)
virtual void AddDetector(KVDetector *d)
const KVList * GetDetectors() const
virtual UShort_t GetIDCode()
virtual void Initialize(void)
virtual void SetIdentificationStatus(KVReconstructedNucleus *)
UInt_t GetSize() const
const KVList * GetListOfIDGrids() const
Extended TList class which owns its objects by default.
Definition: KVList.h:27
Read MFM format acquisition data.
Description of physical materials used to construct detectors & targets; interface to range tables.
Definition: KVMaterial.h:93
virtual void SetThickness(Double_t thick)
Definition: KVMaterial.cpp:454
static KVIonRangeTable * GetRangeTable()
Definition: KVMaterial.cpp:166
Base class for describing the geometry of a detector array.
const KVSeqCollection * GetFiredSignals() const
KVNumberList fAcceptECodes
list of acceptable calibration codes for reconstructed nuclei
virtual KVNameValueList * DetectParticle(KVNucleus *part)
Bool_t IsROOTGeometry() const
bool try_a_singleIDtelescope(TString uri, KVDetector *d, TCollection *l)
KVUniqueNameList fExtraRawDataSignals
any signals read from raw data not associated with a detector
virtual KVGroup * GetGroupWithDetector(const Char_t *)
KVSeqCollection * GetListOfIDTelescopes() const
KVUniqueNameList * GetIDTelescopeTypes()
void FillListOfIDTelescopes(KVIDGraph *gr) const
virtual Bool_t handle_raw_data_event_mfmframe_ebyedat(const MFMEbyedatFrame &)
Read a raw data event from a EBYEDAT MFM Frame.
KVNumberList fAcceptIDCodes
list of acceptable identification codes for reconstructed nuclei
virtual void DetectEvent(KVEvent *event, KVReconstructedEvent *rec_event, const Char_t *detection_frame="")
virtual void GetDetectorEvent(KVDetectorEvent *detev, const TSeqCollection *fired_params=0)
virtual Bool_t handle_raw_data_event_protobuf(KVProtobufDataReader &)
void MakeHistogramsForAllIDTelescopes(KVSeqCollection *list, Int_t dimension=100)
TList * GetStatusOfIDTelescopes()
int try_all_singleID_telescopes(KVDetector *d, TCollection *l)
virtual void GetIDTelescopesForGroup(KVGroup *grp, TCollection *tel_list)
static Bool_t fCloseGeometryNow
virtual KVGroup * GetGroup(const Char_t *) const
Return pointer to group with name.
virtual void DeduceIdentificationTelescopesFromGeometry()
std::unique_ptr< KVFileReader > GetKVFileReader(KVExpDB *db, const Char_t *meth, const Char_t *keyw)
virtual Double_t GetTargetEnergyLossCorrection(KVReconstructedNucleus *)
virtual Bool_t handle_raw_data_event_mfmmergeframe(const MFMMergeFrameManager &)
virtual Bool_t handle_raw_data_event_mfmfile(MFMBufferReader &)
void ReadOoODetectors(KVExpDB *db)
Bool_t fHandledRawData
set to true if multidetector handles data in last call to HandleRawData
KVSeqCollection * GetIDTelescopesWithType(const Char_t *type)
TList * fCalibStatusDets
used by GetStatusIDTelescopes
KVDetectorEvent * fHitGroups
list of hit groups in simulation
virtual UShort_t GetCoherencyIDCode()
KVTarget * GetTarget()
void RecursiveTrajectoryClustering(KVGeoDetectorNode *N, KVUniqueNameList &tried_trajectories, KVUniqueNameList &multitraj_nodes, KVUniqueNameList &detectors_of_group)
KVSeqCollection * fIDTelescopes
deltaE-E telescopes in groups
virtual Int_t FilteredEventCoherencyAnalysis(Int_t round, KVReconstructedEvent *rec_event)
virtual void SetMinimumOKMultiplicity(KVEvent *) const
UInt_t fCurrentRun
Number of the current run used to call SetParameters.
static Bool_t fMakeMultiDetectorSetParameters
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
virtual UChar_t GetNormalCalibrationCode()
int try_all_doubleID_telescopes(KVDetector *de, KVDetector *e, TCollection *l)
void FillHistogramsForAllIDTelescopes(KVSeqCollection *list)
Fill TH2F histograms for all IDTelescopes of the array.
void set_detector_thicknesses(const TString &)
virtual TGraph * DrawPunchThroughEsurAVsZ(const Char_t *detector, Int_t massform=KVNucleus::kBetaMass)
Bool_t ReadGridsFromAsciiFile(const Char_t *) const
virtual void InitialiseRawDataReading(KVRawDataReader *)
virtual void SetExpectedDetectorSignalNames()
virtual void SetParameters(UInt_t n, Bool_t physics_parameters_only=kFALSE)
virtual void SetDetecting(KVDetector *det, Bool_t detecting=kTRUE)
virtual void copy_fired_parameters_to_recon_param_list()
TString GetDataSet() const
virtual void SetPresent(KVDetector *det, Bool_t present=kTRUE)
void CalculateDetectorSegmentationIndex()
virtual void AnalyseGroupAndReconstructEvent(KVReconstructedEvent *recev, KVGroup *grp)
static TGeoHMatrix * GetVolumePositioningMatrix(Double_t distance, Double_t theta, Double_t phi, TGeoTranslation *postTrans=nullptr)
KVGeoNavigator * GetNavigator() const
void DetectParticleIn(const Char_t *detname, KVNucleus *kvp)
KVUpDater * fUpDater
used to set parameters for multidetector
virtual Int_t GetIDTelescopes(KVDetector *, KVDetector *, TCollection *list)
void SetGeometry(TGeoManager *)
UShort_t GetZminCode()
virtual void MakeCalibrationTables(KVExpDB *)
virtual ~KVMultiDetArray()
destroy (delete) the MDA and all the associated structure, detectors etc.
virtual void SetRunIdentificationParameters(UShort_t n)
Bool_t HandleRawDataBuffer(MFMBufferReader &)
TString GetFileName(KVExpDB *, const Char_t *meth, const Char_t *keyw)
virtual void Clear(Option_t *opt="")
virtual void CheckStatusOfDetectors(KVDBRun *, const TString &="")
virtual void PerformClosedROOTGeometryOperations()
KVRangeTableGeoNavigator * fNavigator
for propagating particles through array geometry
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()
void RemoveGroup(KVGroup *)
TList * fStatusIDTelescopes
used by GetStatusIDTelescopes
Bool_t fSimMode
=kTRUE in "simulation mode" (use for calculating response to simulated events)
virtual void Build(Int_t run=-1)
virtual void FillDetectorList(KVReconstructedNucleus *rnuc, KVHashList *DetList, const KVString &DetNames)
virtual UShort_t GetBadIDCode()
virtual Bool_t handle_raw_data_event_ebyedat(KVGANILDataReader &)
General method for reading raw data in old GANIL ebyedat format.
const TSeqCollection * GetTrajectories() const
virtual void MakeListOfDetectors()
static Bool_t fBuildTarget
KVTarget * fTarget
target used in experiment
virtual void set_up_telescope(KVDetector *de, KVDetector *e, KVIDTelescope *idt, TCollection *l)
Set up detectors in de-e identification telescope and add to fIDTelescopes and to l.
TList * GetCalibrationStatusOfDetectors()
void Draw(Option_t *option="")
bool try_upper_and_lower_singleIDtelescope(TString uri, KVDetector *d, TCollection *l)
void ReplaceDetector(const Char_t *name, KVDetector *new_kvd)
virtual Bool_t handle_raw_data_event_mfmframe(const MFMCommonFrame &)
TGeoManager * GetGeometry() const
Return pointer to the (ROOT) geometry of the array.
static KVMultiDetArray * MakeMultiDetector(const Char_t *dataset_name, Int_t run=-1, TString classname="KVMultiDetArray")
KVRawDataReader * fRawDataReader
last raw data reader object used in call to HandleRawData
virtual void ReconstructEvent(KVReconstructedEvent *, KVDetectorEvent *)
virtual KVGroup * GetGroupWithAngles(Float_t, Float_t)
virtual void SetRawDataFromReconEvent(KVNameValueList &)
void add_and_set_detector_signal(KVDetector *det, KVString detname, Double_t sig_data, KVString sig_type)
virtual TGraph * DrawPunchThroughZVsVpar(const Char_t *detector, Int_t massform=KVNucleus::kBetaMass)
virtual Bool_t HandleRawDataEvent(KVRawDataReader *)
virtual Double_t GetPunchThroughEnergy(const Char_t *detector, Int_t Z, Int_t A)
virtual void InitializeIDTelescopes()
virtual void SetROOTGeometry(Bool_t on=kTRUE)
KVUniqueNameList fFiredDetectors
list of fired detectors after reading raw data event
virtual void RenumberGroups()
virtual void SetRunCalibrationParameters(UShort_t n)
void PrintStatusOfIDTelescopes()
bool try_upper_and_lower_doubleIDtelescope(TString uri, KVDetector *de, KVDetector *e, TCollection *l)
void PrintCalibStatusOfDetectors()
virtual TGraph * DrawPunchThroughEnergyVsZ(const Char_t *detector, Int_t massform=KVNucleus::kBetaMass)
Bool_t fROOTGeometry
=kTRUE use ROOT geometry
void ReadCalibrationFiles(KVExpDB *db)
virtual UShort_t GetMultiHitFirstStageIDCode()
virtual void SetCalibratorParameters(KVDBRun *, const TString &="")
KVNameValueList * DetectParticle_TGEO(KVNucleus *part)
Int_t fFilterType
type of filtering (used by DetectEvent)
virtual void PrepareModifGroup(KVGroup *grp, KVDetector *dd)
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".
void CalculateReconstructionTrajectories()
KVUniqueNameList fTrajectories
list of all possible trajectories through detectors of array
virtual void SetIDCodeForIDTelescope(KVIDTelescope *) const
virtual void SetReconParametersInEvent(KVReconstructedEvent *) const
Copy any parameters in fReconParameters in to the reconstructed event parameter list.
KVNameValueList fReconParameters
general purpose list of parameters for storing information on data reconstruction
TString fDataSet
name of associated dataset, used with MakeMultiDetector()
void AssociateTrajectoriesAndNodes()
void ReadCalibFile(const Char_t *filename, KVExpDB *db, KVDBTable *calib_table)
virtual void AcceptParticleForAnalysis(KVReconstructedNucleus *) const
virtual KVTelescope * GetTelescope(const Char_t *name) const
Return pointer to telescope in array with name given by "name".
void SetNavigator(KVGeoNavigator *geo)
KVMultiDetArray()
Default constructor.
KVUpDater * GetUpDater()
void DeduceGroupsFromTrajectories()
virtual void set_up_single_stage_telescope(KVDetector *det, KVIDTelescope *idt, TCollection *l)
Set up detector in single-stage identification telescope and add to fIDTelescopes and to l.
bool try_a_doubleIDtelescope(TString uri, KVDetector *de, KVDetector *e, TCollection *l)
virtual void GetAlignedIDTelescopesForDetector(KVDetector *det, TCollection *list)
virtual void CreateIDTelescopesInGroups()
KVUnownedList fFiredSignals
list of fired signals after reading raw data event
Handles lists of named parameters with different types, a list of KVNamedParameter objects.
Double_t GetDoubleValue(const Char_t *name) const
void SetValue(const Char_t *name, value_type value)
void RemoveParameter(const Char_t *name)
virtual void Clear(Option_t *opt="")
const Char_t * GetNameAt(Int_t idx) const
Int_t GetNpar() const
return the number of stored parameters
Int_t GetEntries() const
const Char_t * GetStringValue(const Char_t *name) const
Bool_t HasParameter(const Char_t *name) const
KVHashList * GetList() const
TString GetTStringValue(const Char_t *name) const
void Copy(TObject &nvl) const
A generic named parameter storing values of different types.
Double_t GetDouble() const
Description of properties and kinematics of atomic nuclei.
Definition: KVNucleus.h:125
virtual void Print(Option_t *t="") const
Display nucleus parameters.
Definition: KVNucleus.cpp:758
Int_t GetA() const
Definition: KVNucleus.cpp:799
void SetZ(Int_t z, Char_t mt=-1)
Definition: KVNucleus.cpp:704
void SetZandA(Int_t z, Int_t a)
Set atomic number and mass number.
Definition: KVNucleus.cpp:721
void SetMassFormula(UChar_t mt)
Definition: KVNucleus.h:344
Int_t GetZ() const
Return the number of proton / atomic number.
Definition: KVNucleus.cpp:770
Strings used to represent a set of ranges of values.
Definition: KVNumberList.h:83
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 Add(Int_t)
Add value 'n' to the list.
void Set(const TString &l)
Definition: KVNumberList.h:133
Bool_t IsEmpty() const
Definition: KVNumberList.h:173
void SetIsOK(Bool_t flag=kTRUE)
Definition: KVParticle.cpp:339
void SetTheta(Double_t theta)
Definition: KVParticle.h:695
TVector3 * GetPInitial() const
Definition: KVParticle.h:728
void RemoveGroup(const Char_t *groupname)
Remove group from list of groups.
Definition: KVParticle.cpp:530
void AddGroup(const Char_t *groupname, const Char_t *from="") const
Definition: KVParticle.cpp:436
KVNameValueList * GetParameters() const
Definition: KVParticle.h:816
void SetMomentum(const TVector3 &v)
Definition: KVParticle.h:576
Double_t GetEnergy() const
Definition: KVParticle.h:623
Double_t GetE() const
Definition: KVParticle.h:654
void SetE(Double_t a)
Definition: KVParticle.h:596
void SetE0(TVector3 *e=0)
Definition: KVParticle.h:717
Double_t GetKE() const
Definition: KVParticle.h:616
Double_t GetVpar() const
Definition: KVParticle.h:677
KVParticle const * GetFrame(const Char_t *frame, Bool_t warn_and_return_null_if_unknown=kTRUE) const
Definition: KVParticle.cpp:855
Bool_t BelongsToGroup(const Char_t *groupname) const
Definition: KVParticle.cpp:509
Bool_t IsSmallerThan(KVPosition *pos)
kTRUE if "this" is entirely contained within "pos"
Definition: KVPosition.cpp:379
Read Google Protobuf DAQ files.
Wrapper for TRefArray adding some functionality.
Definition: KVRList.h:36
virtual KVBase * FindObject(const Char_t *name, const Char_t *type) const
Definition: KVRList.cpp:106
Propagate particles through array geometry calculating energy losses.
Bool_t CheckIonForRangeTable(Int_t Z, Int_t A)
virtual void PropagateParticle(KVNucleus *, TVector3 *TheOrigin=0)
We start a new track to represent the particle's trajectory through the array.
Abstract base class for reading raw (DAQ) data.
virtual TString GetDataFormat() const =0
Event containing KVReconstructedNucleus nuclei reconstructed from hits in detectors.
virtual Bool_t AnalyseDetectors(TList *kvtl)
virtual void SecondaryIdentCalib()
Nuclei reconstructed from data measured by a detector array .
virtual void Reconstruct(KVDetector *kvd)
virtual void SetAMeasured(Bool_t yes=kTRUE)
virtual Int_t GetECode() const
static UInt_t GetNUnidentifiedInGroup(KVGroup *grp)
virtual Int_t GetIDCode() const
KVDetector * GetStoppingDetector() const
void SetDetector(int i, KVDetector *);
virtual void GetAnglesFromReconstructionTrajectory(Option_t *opt="random")
virtual void SetZMeasured(Bool_t yes=kTRUE)
KVIDTelescope * GetIdentifyingTelescope() const
static void AnalyseParticlesInGroup(KVGroup *grp)
@ kStatusPileupDE
telescope; a minimum Z could be estimated from the measured energy loss.
void SetIdentifyingTelescope(KVIDTelescope *i)
Combine ROOT file containing objects with SQLite database with info on the objects.
Definition: KVSQLROOTFile.h:19
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
virtual void SetOwner(Bool_t enable=kTRUE)
virtual void Clear(Option_t *option="")
virtual TObject * At(Int_t idx) const
KVSeqCollection * GetSubListWithType(const Char_t *retvalue) const
virtual void SetCleanup(Bool_t enable=kTRUE)
virtual void Add(TObject *obj)
KVSeqCollection * GetSubListWithLabel(const Char_t *retvalue) const
virtual TObject * Remove(TObject *obj)
Remove object from list.
virtual void Delete(Option_t *option="")
virtual TObject * FindObject(const char *name) const
Extension of ROOT TString class which allows backwards compatibility with ROOT v3....
Definition: KVString.h:72
void Begin(TString delim) const
Definition: KVString.cpp:565
Bool_t End() const
Definition: KVString.cpp:634
KVString Next(Bool_t strip_whitespace=kFALSE) const
Definition: KVString.cpp:695
Int_t GetNValues(TString delim) const
Definition: KVString.cpp:886
virtual void DetectParticle(KVNucleus *, TVector3 *norm=0)
Definition: KVTarget.cpp:485
virtual Double_t GetParticleEIncFromERes(KVNucleus *, TVector3 *norm=0)
Definition: KVTarget.cpp:957
void Clear(Option_t *opt="")
Reset absorber - set stored energy lost by particles in absorber to zero.
Definition: KVTarget.cpp:747
void SetOutgoing(Bool_t r=kTRUE)
Definition: KVTarget.h:236
Associates two detectors placed one behind the other.
Definition: KVTelescope.h:35
Particle * GetNextParticle(Option_t *opt="") const
Particle * AddParticle()
Optimised list in which named objects can only be placed once.
virtual void Add(TObject *obj)
Abstract class implementing necessary methods for setting multidetector parameters for each run of th...
Definition: KVUpDater.h:24
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
virtual const char * GetName() const
void SetName(const char *name)
virtual Int_t GetEntries() const
virtual void Delete(Option_t *option="")=0
virtual void SetOwner(Bool_t enable=kTRUE)
Bool_t Contains(const char *name) const
virtual Int_t GetSize() const
const char * GetName() const
const char * GetValue() 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
THashList * GetTable() const
void SetStyle(Short_t st)
void SetCurrentCamera(ECameraType camera)
void SetSmoothPoints(Bool_t s)
void SetSmoothLines(Bool_t s)
TGeoVolume * GetTopVolume() const
void ClearTracks()
void SetAngles(Double_t phi, Double_t theta, Double_t psi)
virtual void SetDz(Double_t dz)
void SetTransparency(Char_t transparency=0)
virtual void Draw(Option_t *option="")
virtual void SetPoint(Int_t i, Double_t x, Double_t y)
virtual void SetName(const char *name="")
virtual void SetTitle(const char *title="")
virtual void Sort(Bool_t(*greater)(const TGraph *, Int_t, Int_t)=&TGraph::CompareX, Bool_t ascending=kTRUE, Int_t low=0, Int_t high=-1111)
virtual Int_t Fill(const char *name, Double_t w)
TObject * Next()
void Reset()
virtual void Add(TObject *obj)
virtual TObject * FindObject(const char *name) const
virtual TObject * At(Int_t idx) const
virtual void Delete(Option_t *option="")
virtual TObject * First() const
virtual const char * GetName() const
virtual void SetTitle(const char *title="")
virtual const char * GetTitle() const
virtual void SetName(const char *name)
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 Warning(const char *method, const char *msgfmt,...) const
virtual void Error(const char *method, const char *msgfmt,...) const
virtual void ls(Option_t *option="") const
virtual void Info(const char *method, const char *msgfmt,...) const
const char * GetClass() const
Longptr_t ExecPlugin(int nargs, const T &... params)
Int_t GetEntries() const
virtual TObject * RemoveAt(Int_t idx)
Double_t Atof() const
void ToUpper()
TObjArray * Tokenize(const TString &delim) const
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
const char * Data() const
TString & Prepend(char c, Ssiz_t rep=1)
void Form(const char *fmt,...)
TString & Remove(EStripType s, char c)
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
TString & ReplaceAll(const char *s1, const char *s2)
const Int_t n
TGraphErrors * gr
TH1 * h
const long double s
Definition: KVUnits.h:94
const long double g
masses
Definition: KVUnits.h:72
Int_t Nint(T x)
Double_t Max(Double_t a, Double_t b)
auto * l