KaliVeda
Toolkit for HIC analysis
KVFAZIA.cpp
1 //Created by KVClassFactory on Tue Jan 27 11:37:39 2015
2 //Author: ,,,
3 
4 #include "KVFAZIA.h"
5 #include "KVGeoImport.h"
6 #include "KVFAZIADetector.h"
7 #include "KVGroup.h"
8 #include "KVDetectorEvent.h"
9 #include "KVTarget.h"
10 #include "KVDataSet.h"
11 #include "KVConfig.h"
12 #include "KVFAZIAIDSiPSA.h"
13 #include "KVFAZIAIDCsI.h"
14 #include "KVFAZIAIDSiCsI.h"
15 #include "KVFAZIAIDSiSi.h"
16 
17 #include "TGeoCompositeShape.h"
18 #include "TGeoEltu.h"
19 
20 #include <KVFAZIAIDSiSiCsI.h>
21 #include <KVReconstructedNucleus.h>
22 
23 #ifdef WITH_MFM
24 #include "MFMFaziaFrame.h"
25 #endif
26 
27 #ifdef WITH_PROTOBUF
28 #include "FzEventSet.pb.h"
29 #include "KVFzDataReader.h"
30 #endif
31 
33 
34 // BEGIN_HTML <!--
36 /* -->
37 <h2>KVFAZIA</h2>
38 <h4>Base class for description of the FAZIA set up</h4>
39 <!-- */
40 // --> END_HTML
42 KVFAZIA* gFazia;
43 
44 static Char_t const* const FzDataType_str[] = { "QH1", "I1", "QL1", "Q2", "I2", "Q3", "ADC", "UNK" };
45 static Char_t const* const FzDetector_str[] = { "SI1", "SI1", "SI1", "SI2", "SI2", "CSI" };
46 
47 
50 
51 KVFAZIA::KVFAZIA(const Char_t* title)
52  : KVMultiDetArray("FAZIA", title)
53 {
54  // Default constructor
56  gFazia = this;
57  fDetectorLabels = "";
58  fSignalTypes = "QL1,I1,QH1,Q2,I2,Q3";
61 
62  // values of trapezoidal filter rise time set in the fpgas to be linked with a database...
63  fQH1risetime = GetSetupParameter("QH1.FPGARiseTime");
64  fQ2risetime = GetSetupParameter("Q2.FPGARiseTime");
65  fQ3slowrisetime = GetSetupParameter("Q3.slow.FPGARiseTime");
66  fQ3fastrisetime = GetSetupParameter("Q3.fast.FPGARiseTime");
67 
68  Info("KVFAZIA", "fpga shapers: %lf %lf %lf %lf", fQH1risetime, fQ2risetime, fQ3slowrisetime, fQ3fastrisetime);
69 }
70 
71 
72 
74 
76 {
77 
78  Double_t lval = -1;
79  if (gDataSet) lval = gDataSet->GetDataSetEnv(parname, 0.0);
80  else lval = gEnv->GetValue(parname, 0.0);
81  return lval;
82 }
83 
84 
85 
88 
90 {
91  // Overrides base method in order to set the value of the trigger bit pattern for the event
93  if (l.HasIntParameter("FAZIA.TRIGPAT")) SetTriggerPattern(l.GetIntValue("FAZIA.TRIGPAT"));
94  else SetTriggerPattern(0);// FAZIA absent from event
95 }
96 
97 
98 
101 
103 {
104  // Override base method in order to read FAZIA trigger for each run
105 
108 }
109 
110 
111 
125 
127 {
128  // Returns the symbolic name for the principal DAQ trigger used for the current run
129  // e.g. 'Mult2', 'Mult1/100', etc. (see SetTriggerPatternsForDataSet()).
130  //
131  // This can be used to test if the actual DAQ trigger for an event was consistent
132  // with the principal trigger by doing:
133  //
134  //~~~~{.cpp}
135  // if( gFazia->GetTrigger().IsTrigger( gFazia->GetTriggerForCurrentRun() ) )
136  // {
137  // ===ok in this case trigger is consistent==
138  // }
139  //~~~~
140 
141  if (gExpDB) {
142  if (gExpDB->GetTable("FAZIA.Triggers")) {
143  auto rundb = gExpDB->GetDBRun(GetCurrentRunNumber());
144  if (rundb) {
145  auto links = rundb->GetLinks("FAZIA.Triggers");
146  if (links && links->GetEntries())
147  return links->First()->GetName();
148  }
149  }
150  }
151  return "";
152 }
153 
154 
155 
179 
181 {
182  // Set identification telescope objects for FAZIA geometry by hand.
183  //
184  // The actual telescope classes used depends on the value of the variable:
185  //
186  //~~~
187  //[dataset].FAZIA.IDTelescopes
188  //~~~
189  //
190  // which can be different for different datasets.
191  //
192  // The default value is
193  //~~~
194  //FAZIA.IDTelescopes: SI1-PSA SI1-SI2 SI2-CSI CSI-PSA
195  //~~~
196  //
197  // The possible values are:
198  // - CSI-PSA
199  // - SI2-CSI
200  // - SI1+SI2-CSI (name: ID_SI_CSI_xxxx)
201  // - SI2-PSA
202  // - SI1-SI2
203  // - SI1-PSA
204 
205 
206  auto id_tel_list = GetDataSetEnv(fDataSet, "FAZIA.IDTelescopes", "");
207 
209  TIter next_traj(GetTrajectories());
210  KVGeoDNTrajectory* traj;
211  while ((traj = (KVGeoDNTrajectory*)next_traj())) { // loop over all trajectories
212 
213  traj->IterateBackFrom(); // from closest-in to furthest-out detector
214 
216  KVDetector* csi{nullptr}, *si2{nullptr}, *si1{nullptr};
217  while ((N = traj->GetNextNode())) {
218  auto d = N->GetDetector();
219  if (d->IsLabelled("SI1") && d->IsOK()) si1 = d;
220  else if (d->IsLabelled("SI2") && d->IsOK()) si2 = d;
221  else if (d->IsLabelled("CSI") && d->IsOK()) csi = d;
222  }
223 
224  auto add_telescope = [ = ](KVIDTelescope * idt, KVGroup * g) {
225  idt->SetGroup(g);
226  traj->AccessIDTelescopeList()->Add(idt);
227  fIDTelescopes->Add(idt);
228  };
229 
230  if (csi) {
231  // add CSI, SI2-CSI and/or SI1-SI2-CSI telescopes
232  if(id_tel_list.Contains("CSI-PSA"))
233  {
234  auto idt = new KVFAZIAIDCsI;
235  idt->AddDetector(csi);
236  add_telescope(idt, csi->GetGroup());
237  }
238  if (si2) {
239  if(id_tel_list.Contains("SI2-CSI"))
240  {
241  auto idt = new KVFAZIAIDSiCsI;
242  idt->AddDetector(si2);
243  idt->AddDetector(csi);
244  add_telescope(idt, csi->GetGroup());
245  }
246  if (si1) {
247  if(id_tel_list.Contains("SI1+SI2-CSI"))
248  {
249  auto idt = new KVFAZIAIDSiSiCsI;
250  idt->AddDetector(si1);
251  idt->AddDetector(si2);
252  idt->AddDetector(csi);
253  idt->SetName(Form("ID_SI_CSI_%d", csi->GetIndex()));
254  add_telescope(idt, csi->GetGroup());
255  }
256  }
257  }
258  }
259  if (si2) {
260  if(id_tel_list.Contains("SI2-PSA"))
261  {
262  auto idt = new KVFAZIAIDSiPSA;
263  idt->AddDetector(si2);
264  add_telescope(idt, si2->GetGroup());
265  }
266  }
267  if (si1 && si2) {
268  if(id_tel_list.Contains("SI1-SI2"))
269  {
270  auto idt = new KVFAZIAIDSiSi;
271  idt->AddDetector(si1);
272  idt->AddDetector(si2);
273  add_telescope(idt, si2->GetGroup());
274  }
275  }
276  if (si1) {
277  if(id_tel_list.Contains("SI1-PSA"))
278  {
279  auto idt = new KVFAZIAIDSiPSA;
280  idt->AddDetector(si1);
281  add_telescope(idt, si1->GetGroup());
282  }
283  }
284  }
285 }
286 
287 
288 
289 
292 
294 {
295  // Destructor
296 
297  if (gFazia == this) gFazia = nullptr;
298 }
299 
300 
301 
303 
305 {
306  if (fDetectorLabels == "") fDetectorLabels += label;
307  else if (!fDetectorLabels.Contains(label)) fDetectorLabels += Form(",%s", label);
308 }
309 
310 
311 
315 
317 {
318  // Look for the geometry object <-> detector name correspondance file in the dataset directory
319  // If not found, we create it
320 
321  fCorrespondanceFile = "";
322  if (gDataSet) fCorrespondanceFile = gDataSet->GetFullPathToDataSetFile(Form("%s.names", ClassName()));
323  if (fCorrespondanceFile != "") return;
324 
325 #ifdef WITH_GNU_INSTALL
327 #else
328  fCorrespondanceFile.Form("%s/%s.names", gDataSet->GetDataSetDir(), ClassName());
329 #endif
330  Info("GenerateCorrespondanceFile", "Creation de %s", fCorrespondanceFile.Data());
331  KVEnv env;
332 
333  fDetectorLabels = "SI1,SI2,CSI";
334 
335  SetNameOfDetectors(env);
336  if (env.GetTable() && env.GetTable()->GetEntries() > 0) {
337  env.AddCommentLine(Form("Automatic generated file by %s::GenerateCorrespondanceFile", ClassName()));
338  env.AddCommentLine("Make link between geometric ROOT objects and detector names");
340  }
341  fDetectorLabels = "";
342 }
343 
344 
345 
353 
355 {
356  //define the format of detectors name
357  // label-index
358  // where index = block*100+quartet*10+telescope
359  // example :
360  // SI1-123 is the Silicon 1 of the block 1, the quartet 2 and the telescope 3
361  //
362 
363  for (Int_t bb = fStartingBlockNumber; bb < fNblocks; bb += 1) {
364  for (Int_t qq = 1; qq <= 4; qq += 1) {
365  for (Int_t tt = 1; tt <= 4; tt += 1) {
366  fDetectorLabels.Begin(",");
367  while (!fDetectorLabels.End()) {
368  KVString sdet = fDetectorLabels.Next();
369  env.SetValue(
370  Form("BLOCK_%d_QUARTET_%d_%s-T%d", bb, qq, sdet.Data(), tt),
371  Form("%s-%d", sdet.Data(), bb * 100 + qq * 10 + tt)
372  );
373  }
374  }
375  }
376  }
377 }
378 
379 
380 
384 
386 {
387  // Finalise description of array performing all operations which require ROOT
388  // geometry to be closed
389 
392  imp.SetDetectorPlugin(GetDataSetEnv(GetDataSet(), "FAZIADetectorPlugin", "FAZIADetector"));
394  // any additional structure name formatting definitions
396  imp.AddAcceptedDetectorName("SI1-");
397  imp.AddAcceptedDetectorName("SI2-");
398  imp.AddAcceptedDetectorName("CSI-");
399 
400  // the following parameters are optimized for a 12-block compact
401  // geometry placed at 80cm with rings 1-5 of INDRA removed.
402  // make sure that the expected number of detectors get imported!
404 
406 
408  SetBit(kIsBuilt);
409 }
410 
411 
412 
415 
417 {
418  //Called by the Build method
419  AbstractMethod("GetGeometryParameters");
420 }
421 
422 
423 
443 
445 {
446  // Read and set up definitions of trigger patterns for this dataset.
447  // These should be given by variables such as:
448  //
449  //~~~~
450  // +[dataset].FAZIA.TriggerPatterns: [name1]
451  // [dataset].FAZIA.TriggerPattern.[name1]: [value1]
452  // +[dataset].FAZIA.TriggerPatterns: [name2]
453  // [dataset].FAZIA.TriggerPattern.[name2]: [value2]
454  //~~~~
455  //
456  // where [name*]='Mult1','Mult1/100','Mult2', etc. (see KVFAZIATrigger for known trigger patterns).
457  //
458  // and [value*] is the value of the corresponding bit pattern, e.g. if bit '3' (0b100) corresponds to
459  // 'Mult2' (i.e. multiplicity >= 2) then this would give
460  //
461  //~~~~
462  // [dataset].FAZIA.TriggerPattern.Mult2: 4
463  //~~~~
464 
465  KVString patterns = GetDataSetEnv(dataset, "FAZIA.TriggerPatterns", "");
466  if (patterns.Length()) {
467  patterns.Begin(" ");
468  while (!patterns.End()) {
469  auto pattern = patterns.Next(kTRUE);
470  uint16_t val = (uint16_t)GetDataSetEnv(dataset, Form("FAZIA.TriggerPattern.%s", pattern.Data()), 0.);
471  fTrigger.AddTriggerPattern(pattern, val);
472  }
473  }
474 }
475 
476 
477 
480 
482 {
483  //Called by the Build method
484  Info("BuildFAZIA", "to be defined in child class ...");
485 
486 }
487 
488 
489 
491 
493 {
494 
495  KVMaterial target_holder_mat("Al");
496  new TGeoBBox("TARGET_FRAME", 3., 3., 0.1 / 2.);
497  new TGeoEltu("TARGET_HOLE", 2., 2., 0.1 / 2.);
498  TGeoCompositeShape* cs = new TGeoCompositeShape("TARGET_FRAME", "TARGET_FRAME - TARGET_HOLE");
499  TGeoVolume* target_frame = new TGeoVolume("TARGET_FRAME", cs, target_holder_mat.GetGeoMedium());
500  gGeoManager->GetTopVolume()->AddNode(target_frame, 1);
501 
502  KVTarget* T = GetTarget();
503  if (T) {
504  KVMaterial* targMat = (KVMaterial*)T->GetLayers()->First();
505  TGeoVolume* target = gGeoManager->MakeEltu("TARGET", targMat->GetGeoMedium(), 2., 2., targMat->GetThickness() / 2.);
507  }
508 }
509 
510 
511 
514 
516 {
517  // Build the FAZIA array
520 
522 
523  BuildFAZIA();
524 
525  if (fBuildTarget)
526  BuildTarget();
527 
528  if (fCloseGeometryNow) {
531  }
532 
534 }
535 
536 
537 
549 
551 {
552  // First step in event reconstruction based on current status of detectors in array.
553  //
554  // Fills the given KVDetectorEvent with the list of all groups which have fired.
555  // i.e. loop over all groups of the array and test whether KVGroup::Fired() returns true or false.
556  //
557  // This can be made more efficient if the detectors which were hit in the event are already known:
558  // then their list should be given to argument dets
559  //
560  // If the list of fired detectors dets is not given, we use the internal fFiredDetectors list
561  // which is filled with all hit detectors when raw data is treated in treat_event()
562 
563  if (!IsSimMode() && !fHandledRawData) {
564  //Info("GetDetectorEvent","i didnt handle any data...");
565  return;
566  }
567  if (!dets || !dets->GetEntries()) {
568  if (fFiredDetectors.GetEntries()) {
569  dets = &fFiredDetectors;
570  //Info("GetDetectorEvent", "using internal list");
571  }
572  }
573  if (dets && dets->GetEntries()) {
574  TIter next_det(dets);
575 
576  KVDetector* det = 0;
577  while ((det = (KVDetector*)next_det())) {
578 
579  if (det->GetGroup()->Fired()) detev->AddGroup(det->GetGroup());
580 
581  }
582  }
583  else {
584  //Info("GetDetectorEvent", "Calling base method");
586  }
587 }
588 
589 
590 
595 
597 {
598  // Protected method, called when required to fill fDetList with pointers to
599  // the detectors whose names are stored in fDetNames.
600  // Also set all raw data values in the detectors.
601 
602  KVFAZIADetector* det = 0;
603 
604  DetList->Clear();
605  DetNames.Begin("/");
606  while (!DetNames.End()) {
607  KVString sdet = DetNames.Next(kTRUE);
608  det = (KVFAZIADetector*)GetDetector(sdet.Data());
609  if (!det) {
611  }
612 
613  if (det) {
614  DetList->Add(det);
615  // read and set from the particle's parameter list any relevant detector signal values
616  // each signal is stored with a name "[detname].[signal name]"
617  // except GTTag and DetTag which have the same value for all detectors of the same telescope
618  // and so are only stored once with name "DetTag" or "GTTag".
619 
620  TIter it(&det->GetListOfDetectorSignals());
621  KVDetectorSignal* ds;
622  while ((ds = (KVDetectorSignal*)it())) {
623  if (ds->IsRaw() && !ds->IsExpression())
624  // only look for raw data, excluding any expressions based only on raw data
625  {
626  TString pname = Form("%s.%s", det->GetName(), ds->GetName());
627  if (rnuc->GetParameters()->HasParameter(pname))
628  ds->SetValue(rnuc->GetParameters()->GetDoubleValue(pname));
629  }
630  }
631  if (rnuc->GetParameters()->HasParameter("GTTag"))
632  det->SetGTTag(rnuc->GetParameters()->GetIntValue("GTTag"));
633  if (rnuc->GetParameters()->HasParameter("DetTag"))
634  det->SetDetTag(rnuc->GetParameters()->GetIntValue("DetTag"));
635  }
636  }
637 }
638 
639 
640 
643 
645 {
646  // Specialized group reconstructor for FAZIA
647  KVGroupReconstructor* gr(nullptr);
648  if (GetGroup(g->GetName())) { // make sure group belongs to us
649  if (IsSimMode())
650  gr = KVGroupReconstructor::Factory("FAZIA.Filter", g);
651  else
652  gr = KVGroupReconstructor::Factory("FAZIA", g);
653  }
654  return gr;
655 }
656 
657 
658 
660 
662 {
663 
664  TString sname;
665  if (bb == 4) {
666  if (fDataSet == "FAZIASYM") {
667  sname.Form("%s-RUTH", FzDataType_str[idsig]);
668  }
669  else {
670  sname.Form("%s-%d", FzDataType_str[idsig], 100 * bb + 10 * qq + tt);
671  }
672  }
673  else if (bb == 6) {
674  if (fDataSet == "FAZIAPRE") {
675  sname.Form("%s-RUTH", FzDataType_str[idsig]);
676  }
677  else {
678  sname.Form("%s-%d", FzDataType_str[idsig], 100 * bb + 10 * qq + tt);
679  }
680  }
681  else {
682  sname.Form("%s-%d", FzDataType_str[idsig], 100 * bb + 10 * qq + tt);
683  }
684  return sname;
685 
686 }
687 
688 
689 #ifdef WITH_PROTOBUF
690 
692 
694 {
695  return treat_event(((KVFzDataReader&)R).get_fazia_event());
696 }
697 
698 
699 
701 
703 {
704  Int_t value = (val << 2);
705  value >>= 2;
706  Double_t dval = -1.;
707  switch (sigid) {
708  case DAQ::FzData_FzDataType_QH1:
709  if (eid == 0) dval = value / (fQH1risetime * 1e3 / 10.);
710  break;
711  case DAQ::FzData_FzDataType_I1:
712  break;
713  case DAQ::FzData_FzDataType_QL1:
714  break;
715  case DAQ::FzData_FzDataType_Q2:
716  if (eid == 0) dval = value / (fQ2risetime * 1e3 / 10.);
717  break;
718  case DAQ::FzData_FzDataType_I2:
719  break;
720  case DAQ::FzData_FzDataType_Q3:
721  if (eid == 0) dval = value / (fQ3slowrisetime * 1e3 / 10.);
722  if (eid == 1) dval = value / (fQ3fastrisetime * 1e3 / 10.);
723  break;
724  }
725  return dval;
726 }
727 
728 
729 
732 
733 Bool_t KVFAZIA::treat_event(const DAQ::FzEvent& e)
734 {
735  // Read raw data for an event
736 
737  Bool_t good = kTRUE;
738 
739  //get info from trigger
740  int ts = e.trinfo_size();
741  double dt = 0;
742  uint64_t tot = 0;
743  for (Int_t tr = ts - 1; tr >= 0; tr--) {
744  const DAQ::FzTrigInfo& rdtrinfo = e.trinfo(tr);
745  uint64_t triggervalue = rdtrinfo.value();
746  if (tr == ts - 5) {
747  fReconParameters.SetValue("FAZIA.TRIGPAT", (int)triggervalue);
748  SetTriggerPattern((uint16_t)triggervalue);
749  }
750  else if (tr == ts - 6) fReconParameters.SetValue64bit("FAZIA.EC", ((triggervalue << 12) + e.ec()));
751  else if (tr == ts - 8) {
752  dt = triggervalue / (1e6);
753  fReconParameters.SetValue("FAZIA.TRIGRATE.DT", dt);
754  double faziats = fReconParameters.GetValue64bit("FAZIA.TS") * 1.e-8;
755  if (oldfaziats > 0.) fReconParameters.SetValue("FAZIA.CENTRUM.DT", faziats - oldfaziats);
756  oldfaziats = faziats;
757  }
758  else if (tr == ts - 9) fReconParameters.SetValue("FAZIA.TRIGRATE.EXT", 1.*triggervalue / dt);
759  else if (tr == ts - 10) fReconParameters.SetValue("FAZIA.TRIGRATE.MAN", 1.*triggervalue / dt);
760  else if (tr == ts - 11) fReconParameters.SetValue(Form("FAZIA.TRIGRATE.PAT%d", tr - 2), 1.*triggervalue / dt);
761  else if (tr == ts - 12) fReconParameters.SetValue(Form("FAZIA.TRIGRATE.PAT%d", tr - 2), 1.*triggervalue / dt);
762  else if (tr == ts - 13) fReconParameters.SetValue(Form("FAZIA.TRIGRATE.PAT%d", tr - 2), 1.*triggervalue / dt);
763  else if (tr == ts - 14) fReconParameters.SetValue(Form("FAZIA.TRIGRATE.PAT%d", tr - 2), 1.*triggervalue / dt);
764  else if (tr == ts - 15) fReconParameters.SetValue(Form("FAZIA.TRIGRATE.PAT%d", tr - 2), 1.*triggervalue / dt);
765  else if (tr == ts - 16) fReconParameters.SetValue(Form("FAZIA.TRIGRATE.PAT%d", tr - 2), 1.*triggervalue / dt);
766  else if (tr == ts - 17) fReconParameters.SetValue(Form("FAZIA.TRIGRATE.PAT%d", tr - 2), 1.*triggervalue / dt);
767  else if (tr == ts - 18) fReconParameters.SetValue(Form("FAZIA.TRIGRATE.PAT%d", tr - 2), 1.*triggervalue / dt);
768  else if (tr == ts - 19) {
769  fReconParameters.SetValue("FAZIA.TRIGRATE.TOT", 1.*triggervalue / dt);
770  tot = triggervalue;
771  }
772  else if (tr == ts - 20) {
773  fReconParameters.SetValue("FAZIA.TRIGRATE.VAL", 1.*triggervalue / dt);
774  fReconParameters.SetValue("FAZIA.DEADTIME", 100.*(1. - 1.*triggervalue / tot));
775  }
776  else {}
777  }
778 
779 // if (tot > 0) fReconParameters.ls();
780 
781  for (int b = 0; b < e.block_size(); ++b) {
782 
783  // check block errors
784  if (e.block(b).len_error() || e.block(b).crc_error() || (!good)) {
785  //Warning("treat_event", "BLOCK LEN OR CRC ERROR B%03d", e.block(b).blkid());
786  good = kFALSE;
787  break; //stop iteration on blocks
788  }
789  int fIdBlk = e.block(b).blkid();
790 
791  for (int f = 0; f < e.block(b).fee_size(); ++f) {
792 
793  const DAQ::FzFee& rdfee = e.block(b).fee(f);
794 
795  for (int h = 0; h < rdfee.hit_size(); ++h) {
796 
797  const DAQ::FzHit& rdhit = rdfee.hit(h);
798  // check fee errors
799  if (rdfee.len_error() || rdfee.crc_error() || (!good)) {
800  Warning("treat_event", "FEE LEN OR CRC ERROR B%03d-FE%d", e.block(b).blkid(), rdfee.feeid());
801  good = kFALSE;
802  break; //stop iteration on hits
803  }
804  int fIdFee = rdhit.feeid();
805  int fIdTel = rdhit.telid();
806 
807  for (Int_t mm = 0; mm < rdhit.data_size(); mm++) {
808  const DAQ::FzData& rdata = rdhit.data(mm);
809  int fIdSignal = rdata.type();
810 
811  int DetTag = rdhit.dettag();
812  int GTTag = rdhit.gttag();
813  if (DetTag >= 16384 && GTTag < 16384) GTTag += 32768;
814 
815  //on decompile le HIT
816  int fIdQuartet = fQuartet[fIdFee][fIdTel];
817  int fIdTelescope = fTelescope[fIdFee][fIdTel];
818 
819  KVFAZIADetector* det = (KVFAZIADetector*)GetDetector(Form("%s-%d", FzDetector_str[fIdSignal], 100 * fIdBlk + 10 * fIdQuartet + fIdTelescope));
820  if (!det) {
821  Error("treat_event", "No detector %s-%d found in FAZIA geometry...", FzDetector_str[fIdSignal], 100 * fIdBlk + 10 * fIdQuartet + fIdTelescope);
822  continue;
823  }
824  det->SetDetTag(DetTag);
825  det->SetGTTag(GTTag);
826 
827  if (!rdata.has_energy() && !rdata.has_waveform()) {
828  if (FzDataType_str[fIdSignal] != "I2") Warning("treat_event", "[NO DATA] [%s %s]", det->GetName(), FzDataType_str[fIdSignal]);
829  continue;
830  }
831 
832  if (rdata.has_energy()) {
833  const DAQ::Energy& ren = rdata.energy();
834  for (Int_t ee = 0; ee < ren.value_size(); ee++) {
835  Double_t energy = TreatEnergy(fIdSignal, ee, ren.value(ee));
836  fFiredSignals.Add(det->SetFPGAEnergy(fIdSignal, ee, energy));
837  }
838  fFiredDetectors.Add(det);
839  }
840  if (rdata.has_baseline()) {
841  Float_t bl = rdata.baseline();
842  fFiredSignals.Add(det->SetBaseLine(fIdSignal, bl));
843  }
844  if (rdata.has_waveform()) {
845  const DAQ::Waveform& rwf = rdata.waveform();
846  Int_t supp;
847 
848  if (fIdSignal <= 5) {
849  TString sname = GetSignalName(fIdBlk, fIdQuartet, fIdTelescope, fIdSignal);//QH1-123 etc.
850  if (sname == "")
851  Warning("treat_event", "signal name is empty !!! blk=%d qua=%d tel=%d\n", fIdBlk, fIdQuartet, fIdTelescope);
852 
853  TGraph sig(rwf.sample_size());
854 
855  for (Int_t nn = 0; nn < rwf.sample_size(); nn++) {
856  if (fIdSignal != DAQ::FzData::ADC) {
857  if (rwf.sample(nn) > 8191) {
858  supp = rwf.sample(nn) | 0xFFFFC000;
859  }
860  else {
861  supp = rwf.sample(nn);
862  }
863  }
864  else {
865  supp = rwf.sample(nn);
866  }
867  sig.SetPoint(nn, nn, supp);
868  }
869  det->SetSignal(&sig, sname);
870  }
871  else {
872  if (fIdSignal > 5)
873  Warning("treat_event", "datatype %d>5 - taille = %d\n", fIdSignal, rwf.sample_size());
874  }
875  }
876  }
877  }
878  }
879  }
880 
881 // cout << "good=" << good << endl;
882 // fFPGAParameters.ls();
883 // fSignals.ls();
884 
885  return good;
886 }
887 
888 #endif
889 
890 #ifdef WITH_MFM
891 
896 
898 {
899  // Treatment of raw data in MFM frames with type MFM_FAZIA_FRAME_TYPE
900  // The timestamp is extracted from the frame header and added to fReconParameters
901  // in a 64 bit parameter with name "FAZIA.TS"
902 
903  if (f.GetFrameType() != MFM_FAZIA_FRAME_TYPE) return kFALSE;
904  fReconParameters.SetValue64bit("FAZIA.TS", f.GetTimeStamp());
905 
906 #ifdef WITH_PROTOBUF
907  DAQ::FzEventSet fazia_set;
908  DAQ::FzEvent fazia_event;
909  // Parse protobuf data in MFM frame
910  if (fazia_set.ParseFromArray(f.GetPointUserData(), ((MFMFaziaFrame&)f).GetEventSize())) {
911  // Parsed an event set
912  if (fazia_set.ev_size() > 1) {
913  Warning("handle_raw_data_event_mfmframe",
914  "Got a FzEventSet from data: cannot handle multiple events at once!");
915  return kFALSE;
916  }
917  return treat_event(fazia_set.ev(0));
918  }
919  else if (fazia_event.ParseFromArray(f.GetPointUserData(), ((MFMFaziaFrame&)f).GetEventSize())) {
920  // Parsed an event
921  return treat_event(fazia_event);
922  }
923 #endif
924  return kTRUE;
925 }
926 
927 #endif
928 
929 
933 
935 {
936  // set up correspondence between FPGA number/FEE number (from acquisition)
937  // and Quartet/Telescope numbers
938 
939  TString DataFilePath;
940  if (!KVBase::SearchKVFile("ElecDetLink.env", DataFilePath, "data")) {
941  Error("CreateCorrespondence", "ElecDetLink.env not found");
942  return;
943  }
944  KVEnv DetLink;
945  DetLink.ReadFile(DataFilePath, kEnvUser);
946  for (int t = 1; t <= 4; t++) {
947  for (int q = 1; q <= 4; q++) {
948  TString elec = DetLink.GetValue(Form("T%1d-Q%1d", t, q), " ");
949  if (!elec.IsWhitespace()) {
950  int fee, fpga;
951  sscanf(elec.Data(), "FPGA%d-FE%d", &fpga, &fee);
952  fQuartet[fee][fpga] = q;
953  fTelescope[fee][fpga] = t;
954  }
955  else {
956  Error("CreateCorrespondence", "Problem reading FAZIA ElecDetLink.env file : T%1d-Q%1d = %s", t, q, elec.Data());
957  }
958  }
959  }
960 }
961 
962 
963 
978 
980 {
981  // Read a file containing runlists for each principal trigger used during an experiment
982  //
983  // The file should be in TEnv format like so:
984  //
985  //~~~~
986  // Mult1: 100-122,541-1938
987  // Mult2: 91-765
988  //~~~~
989  //
990  // where each trigger pattern name must be known and declared to occur during the dataset
991  // (see SetTriggerPatternsForDataSet()) and the list of runs are given using KVNumberList syntax.
992  //
993  // The data is added to the database in a table 'FAZIA.Triggers'.
994 
995  TString fullpath;
996  if (!db->FindCalibFile("Triggers", fullpath)) return;
997 
998  Info("ReadTriggerPatterns()", "Reading FAZIA triggers used during runs...");
999  auto trigs = db->AddTable("FAZIA.Triggers", "Principal triggers used by FAZIA");
1000 
1001  KVDBRecord* dbrec = 0;
1002  TEnv env;
1003  TEnvRec* rec = 0;
1004  env.ReadFile(fullpath.Data(), kEnvAll);
1005  TIter it(env.GetTable());
1006 
1007  while ((rec = (TEnvRec*)it.Next())) {
1008  KVString srec(rec->GetName());
1009  KVNumberList nl(rec->GetValue());
1010  dbrec = new KVDBRecord(rec->GetName(), "FAZIA Trigger");
1011  dbrec->AddKey("Runs", "List of Runs");
1012  trigs->AddRecord(dbrec);
1013  db->LinkRecordToRunRange(dbrec, nl);
1014  }
1015 }
1016 
1017 
1018 
1021 
1023 {
1024  // Set the FAZIA-specific general identification code for the given telescope
1025 
1026  if (idt->InheritsFrom(KVFAZIAIDSiPSA::Class())) {
1027  if (idt->GetDetector(1)->IsLabelled("SI1")) idt->SetIDCode(IDCodes::ID_SI1_PSA);
1028  else idt->SetIDCode(IDCodes::ID_SI2_PSA);
1029  }
1030  else if (idt->InheritsFrom(KVFAZIAIDSiSi::Class())) idt->SetIDCode(IDCodes::ID_SI1_SI2);
1031  else if (idt->InheritsFrom(KVFAZIAIDSiCsI::Class())) idt->SetIDCode(IDCodes::ID_SI2_CSI);
1032  else if (idt->InheritsFrom(KVFAZIAIDSiSiCsI::Class())) {
1033  // ID code for these telescopes depends on what detectors the grid's VARY uses
1034  auto labsY = idt->GetDetectorLabelsForGridCoord("y");
1035  if (labsY.Contains("SI1") && labsY.Contains("SI2"))
1036  idt->SetIDCode(IDCodes::ID_SI12_CSI);
1037  else if (labsY.Contains("SI1"))
1038  idt->SetIDCode(IDCodes::ID_SI1_CSI);
1039  else if (labsY.Contains("SI2"))
1040  idt->SetIDCode(IDCodes::ID_SI2_CSI);
1041  }
1042  else if (idt->InheritsFrom(KVFAZIAIDCsI::Class())) idt->SetIDCode(IDCodes::ID_CSI_PSA);
1043  else {
1044  Error("SetIDCodeForIDTelescope", "Request for telescope name=%s of unknown class=%s",
1045  idt->GetName(), idt->IsA()->GetName());
1046  }
1047 }
1048 
1049 
int Int_t
unsigned int UInt_t
#define d(i)
#define f(i)
#define e(i)
bool Bool_t
char Char_t
float Float_t
constexpr Bool_t kFALSE
double Double_t
constexpr Bool_t kTRUE
R__EXTERN TEnv * gEnv
kEnvUser
kEnvAll
#define N
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t b
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t target
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t g
R__EXTERN TGeoManager * gGeoManager
float * q
char * Form(const char *fmt,...)
static const Char_t * WorkingDirectory()
Definition: KVBase.h:180
static ValType GetDataSetEnv(const KVString &dataset, const KVString &type, const ValType &defval)
Definition: KVBase.h:304
static Bool_t SearchKVFile(const Char_t *name, TString &fullpath, const Char_t *kvsubdir="")
Definition: KVBase.cpp:517
Record folder for the database.
Definition: KVDBRecord.h:43
virtual Bool_t AddKey(KVDBKey *key, Bool_t check=kTRUE)
Definition: KVDBRecord.cpp:65
virtual KVRList * GetLinks(const Char_t *key) const
Returns the list of records linked to this record in table "key".
Definition: KVDBRecord.cpp:206
virtual KVDBTable * GetTable(const Char_t *table) const
Definition: KVDataBase.h:159
virtual Bool_t AddTable(KVDBTable *table)
Definition: KVDataBase.cpp:84
const Char_t * GetDataSetDir() const
Definition: KVDataSet.cpp:746
KVString GetDataSetEnv(const Char_t *type, const Char_t *defval="") const
Definition: KVDataSet.cpp:784
TString GetFullPathToDataSetFile(const Char_t *filename)
Definition: KVDataSet.cpp:1926
List of hit groups in a multidetector array.
void AddGroup(KVGroup *grp)
Base class for output signal data produced by a detector.
virtual Bool_t IsExpression() const
virtual void SetValue(Double_t x)
virtual Bool_t IsRaw() const
Extension of TEnv to allow the writing of comments in the file.
Definition: KVEnv.h:17
void AddCommentLine(const Char_t *line)
Definition: KVEnv.cpp:104
Int_t WriteFile(const char *fname, EEnvLevel level=kEnvAll) override
Definition: KVEnv.cpp:174
Base class to describe database of an experiment ,,.
Definition: KVExpDB.h:20
KVDBRun * GetDBRun(Int_t number) const
Definition: KVExpDB.h:89
virtual void LinkRecordToRunRange(KVDBRecord *rec, UInt_t first_run, UInt_t last_run)
Definition: KVExpDB.cpp:90
Bool_t FindCalibFile(const Char_t *type, TString &fullpath, const TString &array_name="") const
Definition: KVExpDB.cpp:486
Base class for FAZIA detectors.
void SetSignal(TGraph *signal, const Char_t *signal_name)
KVDetectorSignal * SetBaseLine(int sigid, Float_t baseline)
void SetGTTag(Int_t t)
void SetDetTag(Int_t t)
static const Char_t * GetNewName(KVString oldname)
KVDetectorSignal * SetFPGAEnergy(int sigid, Int_t idx, Double_t energy)
Telescope for FAZIA identification using SI1 and/or SI2 with CSI.
void AddTriggerPattern(const TString &name, uint16_t value)
Description of a FAZIA detector geometry.
Definition: KVFAZIA.h:33
Double_t fImport_Xorg
for geometry import
Definition: KVFAZIA.h:50
void PerformClosedROOTGeometryOperations() override
Definition: KVFAZIA.cpp:385
Double_t fImport_ThetaMin
for geometry import
Definition: KVFAZIA.h:46
Double_t fQ2risetime
Definition: KVFAZIA.h:58
Double_t fQH1risetime
values of trapezoidal filter rise time set in the fpgas defined in .kvrootrc
Definition: KVFAZIA.h:57
Double_t TreatEnergy(Int_t sigid, Int_t eid, UInt_t val)
Definition: KVFAZIA.cpp:702
Double_t fQ3slowrisetime
Definition: KVFAZIA.h:59
void SetTriggerPatternsForDataSet(const TString &dataset)
Definition: KVFAZIA.cpp:444
void SetGeometryImportParameters(Double_t dt=0.25, Double_t dp=1.0, Double_t tmin=2., Double_t pmin=0, Double_t tmax=20., Double_t pmax=360., Double_t xorg=0, Double_t yorg=0, Double_t zorg=0)
Definition: KVFAZIA.h:243
int fQuartet[8][2]
quartet number from #FEE and #FPGA
Definition: KVFAZIA.h:53
Double_t GetSetupParameter(const Char_t *parname)
Definition: KVFAZIA.cpp:75
Double_t fImport_dTheta
for geometry import
Definition: KVFAZIA.h:44
Bool_t handle_raw_data_event_mfmframe(const MFMCommonFrame &) override
Definition: KVFAZIA.cpp:897
void SetIDCodeForIDTelescope(KVIDTelescope *) const override
Set the FAZIA-specific general identification code for the given telescope.
Definition: KVFAZIA.cpp:1022
std::string GetTriggerForCurrentRun() const
Definition: KVFAZIA.cpp:126
void AddDetectorLabel(const Char_t *label)
Definition: KVFAZIA.cpp:304
void GetDetectorEvent(KVDetectorEvent *detev, const TSeqCollection *dets) override
Definition: KVFAZIA.cpp:550
virtual void BuildTarget()
Definition: KVFAZIA.cpp:492
void Build(Int_t=-1) override
Build the FAZIA array.
Definition: KVFAZIA.cpp:515
Int_t fStartingBlockNumber
Definition: KVFAZIA.h:39
TString fCorrespondanceFile
Bool_t fBuildTarget; //kTRUE to include target frame in the geometry.
Definition: KVFAZIA.h:41
Double_t fImport_PhiMax
for geometry import
Definition: KVFAZIA.h:49
virtual void SetNameOfDetectors(KVEnv &env)
Definition: KVFAZIA.cpp:354
Double_t fImport_Zorg
for geometry import
Definition: KVFAZIA.h:52
virtual void BuildFAZIA()
methods to be implemented in child classes
Definition: KVFAZIA.cpp:481
void DeduceIdentificationTelescopesFromGeometry() override
Definition: KVFAZIA.cpp:180
KVFAZIA(const Char_t *title="")
Default constructor.
Definition: KVFAZIA.cpp:51
void FillDetectorList(KVReconstructedNucleus *rnuc, KVHashList *DetList, const KVString &DetNames) override
Definition: KVFAZIA.cpp:596
void ReadTriggerPatterns(KVExpDB *db)
Definition: KVFAZIA.cpp:979
virtual void DefineStructureFormats(KVGeoImport &)
Definition: KVFAZIA.h:83
void GenerateCorrespondanceFile()
Definition: KVFAZIA.cpp:316
Double_t fQ3fastrisetime
Definition: KVFAZIA.h:60
KVString fSignalTypes
Definition: KVFAZIA.h:43
Bool_t treat_event(const DAQ::FzEvent &)
Read raw data for an event.
Definition: KVFAZIA.cpp:733
virtual ~KVFAZIA()
Destructor.
Definition: KVFAZIA.cpp:293
Double_t fImport_dPhi
for geometry import
Definition: KVFAZIA.h:45
Double_t fImport_ThetaMax
for geometry import
Definition: KVFAZIA.h:47
int fTelescope[8][2]
telescope number from #FEE and #FPGA
Definition: KVFAZIA.h:54
KVFAZIATrigger fTrigger
trigger pattern read from data for each event
Definition: KVFAZIA.h:63
KVGroupReconstructor * GetReconstructorForGroup(const KVGroup *) const override
Specialized group reconstructor for FAZIA.
Definition: KVFAZIA.cpp:644
void SetRawDataFromReconEvent(KVNameValueList &) override
Overrides base method in order to set the value of the trigger bit pattern for the event.
Definition: KVFAZIA.cpp:89
virtual void GetGeometryParameters()
Called by the Build method.
Definition: KVFAZIA.cpp:416
void SetTriggerPattern(uint16_t fp)
Definition: KVFAZIA.h:69
double oldfaziats
dummy ts to control trigger info transmission rate
Definition: KVFAZIA.h:66
Bool_t handle_raw_data_event_protobuf(KVProtobufDataReader &) override
Definition: KVFAZIA.cpp:693
TString GetSignalName(Int_t bb, Int_t qq, Int_t tt, Int_t idsig)
Definition: KVFAZIA.cpp:661
Double_t fImport_PhiMin
for geometry import
Definition: KVFAZIA.h:48
Int_t fNblocks
number of blocks
Definition: KVFAZIA.h:38
Double_t fImport_Yorg
for geometry import
Definition: KVFAZIA.h:51
KVString fDetectorLabels
Definition: KVFAZIA.h:42
void CreateCorrespondence()
Definition: KVFAZIA.cpp:934
void MakeCalibrationTables(KVExpDB *) override
Override base method in order to read FAZIA trigger for each run.
Definition: KVFAZIA.cpp:102
Handle FAZIA protobuf-format raw data files.
Path taken by particles through multidetector geometry.
KVGeoDetectorNode * GetNextNode() const
KVSeqCollection * AccessIDTelescopeList()
void IterateBackFrom(const KVGeoDetectorNode *node0=nullptr) const
Information on relative positions of detectors & particle trajectories.
Import detector array described by ROOT geometry and set up corresponding KVMultiDetArray object.
Definition: KVGeoImport.h:69
void AddAcceptedDetectorName(const char *name)
void SetOrigin(double x, double y, double z)
Definition: KVGeoImport.h:117
void SetDetectorPlugin(const TString &name)
Definition: KVGeoImport.h:111
void ImportGeometry(Double_t dTheta=0.1, Double_t dPhi=1.0, Double_t ThetaMin=0.0, Double_t PhiMin=0.0, Double_t ThetaMax=180.0, Double_t PhiMax=360.0)
void SetNameCorrespondanceList(const Char_t *)
virtual KVDetector * GetDetector(const Char_t *name) const
Return detector in this structure with given name.
Base class for particle reconstruction in one group of a detector array.
static KVGroupReconstructor * Factory(const TString &plugin="", const KVGroup *g=nullptr)
Group of detectors which can be treated independently of all others in array.
Definition: KVGroup.h:19
Extended version of ROOT THashList.
Definition: KVHashList.h:29
Base class for all detectors or associations of detectors in array which can identify charged particl...
Definition: KVIDTelescope.h:84
void SetGroup(KVGroup *kvg)
KVDetector * GetDetector(UInt_t n) const
virtual void SetIDCode(UShort_t c)
KVGroup * GetGroup() const
virtual void AddDetector(KVDetector *d)
KVString GetDetectorLabelsForGridCoord(const KVString &axis) const
Description of physical materials used to construct detectors & targets; interface to range tables.
Definition: KVMaterial.h:89
virtual Double_t GetThickness() const
Definition: KVMaterial.cpp:484
virtual TGeoMedium * GetGeoMedium(const Char_t *="")
static KVIonRangeTable * GetRangeTable()
Definition: KVMaterial.cpp:158
Base class for describing the geometry of a detector array.
virtual void GetDetectorEvent(KVDetectorEvent *detev, const TSeqCollection *fired_params=0)
static Bool_t fCloseGeometryNow
void CreateGeoManager(Double_t dx=500, Double_t dy=500, Double_t dz=500)
Bool_t fHandledRawData
set to true if multidetector handles data in last call to HandleRawData
KVTarget * GetTarget()
KVSeqCollection * fIDTelescopes
deltaE-E telescopes in groups
Bool_t IsSimMode() const
TString GetDataSet() const
KVGroup * GetGroup(const Char_t *name) const
virtual void MakeCalibrationTables(KVExpDB *)
UInt_t GetCurrentRunNumber() const
virtual void SetIdentifications()
const TSeqCollection * GetTrajectories() const
static Bool_t fBuildTarget
virtual void SetRawDataFromReconEvent(KVNameValueList &)
KVUniqueNameList fFiredDetectors
list of fired detectors after reading raw data event
KVNameValueList fReconParameters
general purpose list of parameters for storing information on data reconstruction
TString fDataSet
name of associated dataset, used with MakeMultiDetector()
KVUnownedList fFiredSignals
list of fired signals after reading raw data event
Handles lists of named parameters with different types, a list of KVNamedParameter objects.
Int_t GetIntValue(const Char_t *name) const
Double_t GetDoubleValue(const Char_t *name) const
void SetValue(const Char_t *name, value_type value)
void SetValue64bit(const Char_t *name, ULong64_t)
ULong64_t GetValue64bit(const Char_t *name) const
Bool_t HasParameter(const Char_t *name) const
Strings used to represent a set of ranges of values.
Definition: KVNumberList.h:85
KVNameValueList * GetParameters() const
Definition: KVParticle.h:818
Read Google Protobuf DAQ files.
Nuclei reconstructed from data measured by a detector array .
void Add(TObject *obj) override
void Clear(Option_t *option="") override
void Delete(Option_t *option="") override
Extension of ROOT TString class which allows backwards compatibility with ROOT v3....
Definition: KVString.h:73
void Begin(TString delim) const
Definition: KVString.cpp:565
Bool_t End() const
Definition: KVString.cpp:634
KVString Next(Bool_t strip_whitespace=kFALSE) const
Definition: KVString.cpp:695
Calculation/correction of energy losses of particles through an experimental target.
Definition: KVTarget.h:128
void Add(TObject *obj) override
virtual Int_t GetEntries() const
THashList * GetTable() const
virtual const char * GetValue(const char *name, const char *dflt) const
virtual Int_t ReadFile(const char *fname, EEnvLevel level)
virtual void SetValue(const char *name, const char *value, EEnvLevel level=kEnvChange, const char *type=nullptr)
void CloseGeometry(Option_t *option="d")
TGeoVolume * GetTopVolume() const
TGeoVolume * MakeEltu(const char *name, TGeoMedium *medium, Double_t a, Double_t b, Double_t dz)
virtual TGeoNode * AddNode(TGeoVolume *vol, Int_t copy_no, TGeoMatrix *mat=nullptr, Option_t *option="")
virtual void SetPoint(Int_t i, Double_t x, Double_t y)
TObject * Next()
const char * GetName() const override
static TClass * Class()
virtual void SetName(const char *name)
TClass * IsA() const override
void AbstractMethod(const char *method) const
virtual const char * GetName() const
void SetBit(UInt_t f)
virtual const char * ClassName() const
virtual void Warning(const char *method, const char *msgfmt,...) const
virtual Bool_t InheritsFrom(const char *classname) const
virtual void Error(const char *method, const char *msgfmt,...) const
virtual void Info(const char *method, const char *msgfmt,...) const
TObject * First() const override
Ssiz_t Length() const
const char * Data() const
Bool_t IsWhitespace() const
void Form(const char *fmt,...)
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
TGraphErrors * gr
TH1 * h
double T(double x)
rec
constexpr Double_t R()
TLine l
auto * tt
ClassImp(TPyArg)