NAIA
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups
NtpSelector.cpp
Go to the documentation of this file.
2 
3 #include "NtpMaker/NtpSelector.h"
4 #include "NtpMaker/NtpTools.h"
5 
6 #include "Tofrec02_ihep.h"
7 
8 namespace NAIA {
10  m_logger->info("UBegin =============================================");
11 
12  auto stpw = m_benchmark.MakeStopwatch("NtpSelector::UBegin");
13 
14  m_logger->info("Creating output file {}", m_outputFilename);
15  m_outputFile = std::make_unique<TFile>(m_outputFilename.c_str(), "recreate");
16  m_outputFile->SetCompressionLevel(7);
17 
18  m_logger->info("Creating NAIA event tree");
19  m_chain = std::make_unique<NAIAChain>(NAIAChain::AccessMode::Write);
20  m_chain->m_event.SetMC(m_isMC);
21  m_chain->SetupBranches(m_isMC);
22  m_logger->info("NAIA branches created");
23 }
24 
26  static bool firstCall = true;
27  if (!firstCall) {
28  m_logger->debug("Switching file in chain: {}", m_tree->GetCurrentFile()->GetName());
29  // reset file info containers
30  m_chain->m_fileInfo.Clear();
31  if (m_isMC)
32  m_chain->m_fileInfoMC.Clear();
33  } else {
34  firstCall = false;
35  }
36  return AMSEventR::Notify();
37 }
38 
40  m_logger->debug("Called NtpSelector::ProcessFileInfo");
41 
42  m_chain->m_fileInfo.Clear();
43  if (m_isMC)
44  m_chain->m_fileInfoMC.Clear();
45 
46  m_chain->m_fileInfo.FileName = m_tree->GetCurrentFile()->GetName();
47 
48  m_chain->m_fileInfo.Run = Run();
49  m_chain->m_fileInfo.EventNo.first = Event();
50  m_chain->m_fileInfo.EventNo.second = Event();
51 
52  m_chain->m_fileInfo.UTCTime.first = fHeader.Time[0];
53  m_chain->m_fileInfo.UTCTime.second = fHeader.Time[0];
54 
55  if (m_isMC) {
56  m_chain->m_fileInfoMC.EventNo.first = Event();
57  m_chain->m_fileInfoMC.EventNo.second = Event();
58  MCEventgR *primary = (nMCEventg() != 0) ? pMCEventg(0) : nullptr;
59  m_chain->m_fileInfoMC.Charge = (primary) ? static_cast<int>(primary->Charge) : 0;
60  m_chain->m_fileInfoMC.Mass = (primary) ? primary->Mass : 0;
61  m_chain->m_fileInfoMC.MomentumRange.first = std::numeric_limits<float>::max();
62  m_chain->m_fileInfoMC.MomentumRange.second = 0;
63  auto *datacard = m_tree->GetCurrentFile()->Get<TObjString>("DataCards");
64  if (!datacard) {
65  m_logger->error("No Datacard Object available!");
66  }
67  m_chain->m_fileInfoMC.DatacardPID = NtpTools::GetDatacardValue<int>(datacard, "PART");
68  m_chain->m_fileInfoMC.DatacardMomentumRange.first = NtpTools::GetDatacardValue<float>(datacard, "PMIN");
69  m_chain->m_fileInfoMC.DatacardMomentumRange.second = NtpTools::GetDatacardValue<float>(datacard, "PMAX");
70  m_chain->m_fileInfoMC.DatacardNGen = NtpTools::GetDatacardValue<unsigned int>(datacard, "TRIG");
71 
72  if (m_chain->m_fileInfo.FileName.find(".l1.") != std::string::npos) {
73  m_chain->m_fileInfoMC.Focus = MCFileInfo::SimFocus::L1;
74  } else if (m_chain->m_fileInfo.FileName.find(".l19.") != std::string::npos) {
75  m_chain->m_fileInfoMC.Focus = MCFileInfo::SimFocus::L19;
76  } else if (m_chain->m_fileInfo.FileName.find(".l1a9.") != std::string::npos) {
77  m_chain->m_fileInfoMC.Focus = MCFileInfo::SimFocus::L19;
78  } else if (m_chain->m_fileInfo.FileName.find(".tb.") != std::string::npos) {
79  m_chain->m_fileInfoMC.Focus = MCFileInfo::SimFocus::TB;
80  }
81  } else {
82  // not MC
83  // [VF] here we reproduce the logic of AMSEventR::IsBadRun. Can't use that since the "reason" parameter is thrown
84  // away and we actually need it
85  if (getsetup())
86  m_chain->m_fileInfo.BadRunTag = getsetup()->IsBadRun(m_chain->m_fileInfo.BadRunReason, UTime(), Run());
87  else
88  m_chain->m_fileInfo.BadRunTag = 2;
89  }
90 }
91 
93  if (m_chain->m_fileInfo.Run == 0) {
94  // this happens when a file is first loaded
96  }
97 
98  // fill FileInfo stuff...
99  m_chain->m_fileInfo.NEvents++;
100  m_chain->m_fileInfo.EventNo.second = Event();
101  m_chain->m_fileInfo.UTCTime.second = fHeader.Time[0];
102 
103  if (m_isMC) {
104  m_chain->m_fileInfoMC.EventNo.first = std::min(Event(), m_chain->m_fileInfoMC.EventNo.first);
105  m_chain->m_fileInfoMC.EventNo.second = std::max(Event(), m_chain->m_fileInfoMC.EventNo.second);
106 
107  MCEventgR *primary = (nMCEventg() != 0) ? pMCEventg(0) : nullptr;
108  float p = (primary) ? primary->Momentum : 0;
109  m_chain->m_fileInfoMC.MomentumRange.first = std::min(p, m_chain->m_fileInfoMC.MomentumRange.first);
110  m_chain->m_fileInfoMC.MomentumRange.second = std::max(p, m_chain->m_fileInfoMC.MomentumRange.second);
111  }
112 
113  // quickly discard entries we don't care about...
114  if (Entry() < firstentry) {
115  m_logger->trace("Skip entry {} < {}", Entry(), firstentry);
116  return false;
117  } else if (Entry() > lastentry) {
118  // TODO: check why Abort doesn't work...
119  m_logger->trace("Skip entry {} > {}", Entry(), lastentry);
120  return false;
121  }
122 
123  static bool got_it = false;
124  if (!got_it) {
125  m_logger->debug("UProcessCut - First event processed - Entry: {}, Run: {}, Event: {}", Entry(), Run(), Event());
126  } else if (Entry() % 10000 == 0) {
127  m_logger->debug("UProcessCut - Event processed - Entry: {}, Run: {}, Event: {}", Entry(), Run(), Event());
128  }
129  got_it = true;
130 
131  m_logger->trace("Entry: {}", Entry());
132 
133  m_chain->Clear();
134 
135  // cut really bad stuff
136  if ((nDaqEvent() < 1) || (nLevel1() < 1)) {
137  return false;
138  }
139 
140  auto stpw = m_benchmark.MakeStopwatch("Event processing");
141 
142  // temporary event processing for prototyping
143  static unsigned long lastSec = 0;
144  // int ibetah_select = -1;
145  ParticleR *particle = nullptr;
146 
147  if (m_isMC) {
148  auto stpw = m_benchmark.MakeStopwatch("MCTruth::Fill");
149  m_chain->m_event.mcTruthBase.Fill(this);
150  m_chain->m_event.mcTruthPlus.Fill(this);
151  }
152 
153  {
154  auto stpw = m_benchmark.MakeStopwatch("(Header+EventSummary)::Fill");
155  m_chain->m_event.header.Fill(this);
156  m_chain->m_event.evSummary.Fill(this);
157  }
158 
159  // RTI
160  if (!m_isMC && lastSec != m_chain->m_event.header.UTCTime) {
161  auto stpw = m_benchmark.MakeStopwatch("RTIInfo::Fill");
162 
163  // don't fill the first time we enter here
164  if (lastSec > 0) {
165  m_chain->m_rtiInfo.FillEventVariables();
166  m_chain->FillRTI();
167  }
168  m_chain->m_rtiInfo.Clear();
169 
171  GetRTI(m_rti);
172  m_chain->m_rtiInfo.Fill(&m_rti, m_chain->m_event.header.RunTag);
174  lastSec = m_chain->m_event.header.UTCTime;
175  }
176 
177  if (!m_isMC) {
178  auto stpw = m_benchmark.MakeStopwatch("RTIInfo::AccumulateEventVariables");
180  m_chain->m_rtiInfo.AccumulateEventVariables(this);
182  }
183 
184  if (pDaqEvent(0)) {
185  auto stpw = m_benchmark.MakeStopwatch("DAQ::Fill");
186  m_chain->m_event.daq.Fill(*pDaqEvent(0));
187  }
188 
189  // temporary! To be reviewed
190  particle = pParticle(0);
191 
192  if (particle) {
193 
194  if (particle->pBetaH()) {
195  m_chain->m_event.header.SetMaskCategory(NAIA::Category::HasTof);
196  }
197  // TofBase
198  {
199  auto stpw = m_benchmark.MakeStopwatch("TofBase::Fill");
200  m_chain->m_event.tofBase.Fill(particle->pBeta(), particle->pBetaH());
201  float UTOFCharge = m_chain->m_event.tofBase.Charge[NAIA::Tof::ChargeType::Upper];
202  if (std::fabs(UTOFCharge - 1) < 0.5) {
203  m_chain->m_event.SetMaskCategory(NAIA::Category::Charge1_Tof);
204  } else if (std::fabs(UTOFCharge - 2) < 0.5) {
205  m_chain->m_event.SetMaskCategory(NAIA::Category::Charge2_Tof);
206  } else if (UTOFCharge > 2.5) {
207  m_chain->m_event.SetMaskCategory(NAIA::Category::ChargeGT2_Tof);
208  }
209  }
210  // TofPlus
211  {
212  auto stpw = m_benchmark.MakeStopwatch("TofPlus::Fill");
213  m_chain->m_event.tofPlus.Fill(particle->pBeta(), particle->pBetaH());
214  }
215 
216  if (particle->pTrTrack()) {
217  if (m_isMC)
218  m_chain->m_event.mcTruthPlus.FillTrMCHit(particle->pTrTrack());
219 
220  m_chain->m_event.header.SetMaskCategory(NAIA::Category::HasTrack);
221 
222  // TrTrackBase
223  {
224  auto stpw = m_benchmark.MakeStopwatch("TrTrackBase::Fill");
225 
226  m_logger->trace("Track no. = {}", particle->iTrTrack());
227 
228  if (MatchAllBits(m_chain->m_event.header.Mask(), NAIA::Category::HasTof) &&
229  ContainsKeys(m_chain->m_event.tofBase.Beta, NAIA::Tof::BetaType::BetaH)) {
230  m_chain->m_event.trTrackBase.SetBeta(m_chain->m_event.tofBase.Beta[NAIA::Tof::BetaType::BetaH]);
231  }
232 
233  m_chain->m_event.trTrackBase.Fill(particle->pTrTrack());
234 
235  float innerCharge = m_chain->m_event.trTrackBase.InnerCharge[NAIA::TrTrack::ChargeRecoType::STD];
236  if (std::fabs(innerCharge - 1) < 0.5) {
237  m_chain->m_event.SetMaskCategory(NAIA::Category::Charge1_Trk);
238  } else if (std::fabs(innerCharge - 2) < 0.5) {
239  m_chain->m_event.SetMaskCategory(NAIA::Category::Charge2_Trk);
240  } else if (innerCharge > 2.5) {
241  m_chain->m_event.SetMaskCategory(NAIA::Category::ChargeGT2_Trk);
242  }
243  }
244  // TrTrackPlus
245  {
246  auto stpw = m_benchmark.MakeStopwatch("TrTrackPlus::Fill");
247  m_chain->m_event.trTrackPlus.Fill(particle->pTrTrack());
248  }
249  // TrdKBase
250  {
251  auto stpw = m_benchmark.MakeStopwatch("TrdKBase::Fill");
252 
254  auto trdK = std::make_unique<TrdKCluster>(this, particle->pTrTrack(), 0);
256 
257  if (trdK) {
258  m_chain->m_event.header.SetMaskCategory(NAIA::Category::HasTrd);
259  m_chain->m_event.trdKBase.Fill(trdK.get(), particle->pTrTrack());
260  }
261  }
262 
263  // we still need to fill electron-related track fits
264  }
265 
266  if (particle->pEcalShower()) {
267  m_chain->m_event.header.SetMaskCategory(NAIA::Category::HasEcal);
268  // EcalBase
269  {
270  auto stpw = m_benchmark.MakeStopwatch("EcalBase::Fill");
271  m_chain->m_event.ecalBase.Fill(particle->pEcalShower());
272  }
273  // EcalPlus
274  {
275  auto stpw = m_benchmark.MakeStopwatch("EcalPlus::Fill");
276  m_chain->m_event.ecalPlus.Fill(particle->pEcalShower());
277  }
278  }
279 
280  // fill standalone containers
281  {
282  auto stpw = m_benchmark.MakeStopwatch("DefineStandalone");
284  }
285  if (m_betahStPtr) {
286  m_chain->m_event.header.SetMaskCategory(NAIA::Category::HasTofStandalone);
287  // TofBaseStandalone
288  {
289  auto stpw = m_benchmark.MakeStopwatch("TofBaseStandalone::Fill");
290  m_chain->m_event.tofBaseSt.Fill(nullptr, m_betahStPtr, true);
291  }
292  // TofPlusStandalone
293  {
294  auto stpw = m_benchmark.MakeStopwatch("TofPlusStandalone::Fill");
295  m_chain->m_event.tofPlusSt.Fill(nullptr, m_betahStPtr, true);
296  }
297 
298  // TrdKBase
299  {
300  auto stpw = m_benchmark.MakeStopwatch("TrdKBaseStandalone::Fill");
301 
303  auto trdK = std::make_unique<TrdKCluster>();
304  if (m_betahStPtr->pTrdTrack()) {
305  trdK->Build(m_betahStPtr->pTrdTrack());
306  } else {
307  trdK->Build(m_betahStPtr);
308  }
310 
311  if (trdK) {
312  m_chain->m_event.header.SetMaskCategory(NAIA::Category::HasTrdStandalone);
313  m_chain->m_event.trdKBaseSt.Fill(trdK.get(), nullptr);
314  }
315  }
316  }
317 
318  if (particle->pRichRing()) {
319  m_chain->m_event.header.SetMaskCategory(NAIA::Category::HasRich);
320  // RichBase
321  {
322  auto stpw = m_benchmark.MakeStopwatch("RichBase::Fill");
323  m_chain->m_event.richBase.Fill(particle->pRichRing(), particle->pRichRingB());
324  }
325  // RichPlus
326  {
327  auto stpw = m_benchmark.MakeStopwatch("RichPlus::Fill");
328  m_chain->m_event.richPlus.Fill(this, particle->pRichRing(), particle->pTrTrack());
329  }
330  }
331 
332  // unbiased ExtHit
333  if (MatchAllBits(m_chain->m_event.header.Mask(), NAIA::Category::HasTofStandalone)) {
334  auto stpw = m_benchmark.MakeStopwatch("UnbExtHitBase::Fill");
336  m_chain->m_event.extHitBase.Fill(this);
338  }
339 
340  // only at the very end we screw up gbatch's tracker fits internals and fill electron-related variables
341  if (particle->pTrTrack() && MatchAllBits(m_chain->m_event.header.Mask(), Category::HasTrd)) {
342  // condition for Kalman electron fit: ECAL EnergyD > 0.4 GeV
343  bool refitKalman = MatchAllBits(m_chain->m_event.header.Mask(), Category::HasEcal) &&
344  m_chain->m_event.ecalBase.Energy[Ecal::EnergyRecoType::EnergyD] > 0.4;
345  {
346  auto stpw = m_benchmark.MakeStopwatch("TrTrackBase::FillElectronVars");
347  m_chain->m_event.trTrackBase.FillElectronVars(particle->pTrTrack(), refitKalman);
348  }
349  {
350  auto stpw = m_benchmark.MakeStopwatch("TrTrackPlus::FillElectronVars");
351  float zEcalCOG = MatchAllBits(m_chain->m_event.header.Mask(), Category::HasEcal)
352  ? static_cast<float>(m_chain->m_event.ecalBase.GetCOG().z())
353  : std::numeric_limits<float>::max();
354  m_chain->m_event.trTrackPlus.FillElectronVars(particle->pTrTrack(), zEcalCOG, refitKalman);
355  }
356  }
357 
358  m_logger->trace("Event mask: {}", to_string_binary<32>(m_chain->m_event.header.Mask()));
359  } else {
360  // do selection without particle here?
361  }
362 
363  m_chain->Fill();
364 
365  return true;
366 }
367 
368 void NtpSelector::UProcessFill() {}
369 
370 void NtpSelector::UTerminate() {
371  // last call for accumulated info
372  m_chain->FillFileInfo();
373 
374  m_chain->m_rtiInfo.FillEventVariables();
375  m_chain->FillRTI();
376 
377  m_logger->info("UTerminate =============================================");
378  // m_chain->Print();
379 
380  m_outputFile->cd();
381  NAIA::Version versionHeader;
382  m_outputFile->WriteTObject(&versionHeader, "VersionHeader");
383  m_chain->Write();
384 
385  m_benchmark.Print(m_logger);
386 }
387 
388 void NtpSelector::DefineStandAlone() {
389  m_betahStPtr = nullptr;
390 
391  // dummy variables for gbatch terrible interface
392  int nlayers;
393  float qrms;
394 
395  unsigned int ib = 0;
396  double prev_tofcharge = 0;
397  // Rebuild Tof with standalone reconstruction
398  auto oldOpt = TofRecH::BuildOpt;
399  TofRecH::BuildOpt = 3110;
400  m_logger->trace("Rebuilding Tof with opt {}", TofRecH::BuildOpt);
401  TofRecH::ReBuild();
402  m_logger->trace("{} BetaH objects found", nBetaH());
403 
404  // Search Max Q standalone BetaH
405  for (BetaHR &betah : BetaH()) {
406  auto tofGoodPatt = 1000 * betah.IsGoodQPathL(0) + 100 * betah.IsGoodQPathL(1) + 10 * betah.IsGoodQPathL(2) +
407  1 * betah.IsGoodQPathL(3);
408  float temp_tofcharge = betah.GetQ(nlayers, qrms, 2, TofClusterHR::DefaultQOptIon, tofGoodPatt);
409  if (temp_tofcharge <= 0)
410  continue;
411 
412  m_logger->trace("StAl BetaH n. {} - Charge {} (Chi2C: {} - Chi2T: {})", ib, temp_tofcharge, betah.GetChi2C(),
413  betah.GetChi2T());
414  if (temp_tofcharge > prev_tofcharge) {
415  m_betahStPtr = &betah;
416  prev_tofcharge = temp_tofcharge;
417  }
418  ib++;
419  }
420 
421  // search for same charge, better spatial chisq.
422  for (BetaHR &betah : BetaH()) {
423  auto tofGoodPatt_h = 1000 * m_betahStPtr->IsGoodQPathL(0) + 100 * m_betahStPtr->IsGoodQPathL(1) +
424  10 * m_betahStPtr->IsGoodQPathL(2) + 1 * m_betahStPtr->IsGoodQPathL(3);
425  auto tofGoodPatt = 1000 * betah.IsGoodQPathL(0) + 100 * betah.IsGoodQPathL(1) + 10 * betah.IsGoodQPathL(2) +
426  1 * betah.IsGoodQPathL(3);
427 
428  int high_charge = floor(m_betahStPtr->GetQ(nlayers, qrms, 2, TofClusterHR::DefaultQOptIon, tofGoodPatt_h) + 0.5);
429  int temp_charge = floor(betah.GetQ(nlayers, qrms, 2, TofClusterHR::DefaultQOptIon, tofGoodPatt) + 0.5);
430 
431  if ((high_charge == temp_charge) && (betah.GetChi2C() < m_betahStPtr->GetChi2C())) {
432  m_betahStPtr = &betah;
433  }
434  }
435 
436  if (m_betahStPtr) {
437  m_logger->trace("Selected StAl BetaH: - Charge {} (Chi2C: {})",
438  m_betahStPtr->GetQ(nlayers, qrms, 2, TofClusterHR::DefaultQOptIon), m_betahStPtr->GetChi2C());
439  }
440 
441  TofRecH::BuildOpt = oldOpt;
442  m_logger->trace("Rebuilding Tof with opt {}", TofRecH::BuildOpt);
443  TofRecH::ReBuild();
444 }
445 
446 } // namespace NAIA
Tof standalone data is available for this event.
This event is classified as charge 2 according to tof (1.5 &lt; Q &lt; 2.5)
TrTrack data is available for this event.
Rich data is available for this event.
Stopwatch MakeStopwatch(std::string name)
Definition: Benchmark.h:66
Container class for versioning info.
Definition: NAIAVersion.h:21
This event is classified as charge &gt;2 according to tof (Q &gt; 2.5)
TRD standalone data is available for this event.
unsigned long long firstentry
first entry to be processed
Definition: NtpSelector.h:28
void UnmuteOutput()
Definition: Logging.cpp:36
This event is classified as charge 1 according to tracker (0.5 &lt; Q &lt; 1.5)
test beam simulation
Charge estimated using the upper half of the TRD.
Definition: Utils.h:226
bool m_isMC
is simulation?
Definition: NtpSelector.h:26
Event object.
Definition: Event.h:20
virtual void UBegin() override
Init output.
Definition: NtpSelector.cpp:9
Ecal data is available for this event.
TRD data is available for this event.
This event is classified as charge 1 according to tof (0.5 &lt; Q &lt; 1.5)
Benchmark m_benchmark
Definition: NtpSelector.h:68
This event is classified as charge 2 according to tracker (1.5 &lt; Q &lt; 2.5)
IHEP reconstruction.
Definition: Utils.h:342
std::shared_ptr< spdlog::logger > m_logger
Definition: NtpSelector.h:69
std::unique_ptr< TFile > m_outputFile
Definition: NtpSelector.h:58
BetaHR * m_betahStPtr
Definition: NtpSelector.h:64
Total deposited energy in Ecal.
Definition: Utils.h:282
virtual bool UProcessCut() override
Cut, select and prescale.
Definition: NtpSelector.cpp:92
This event is classified as charge &gt;2 according to tracker (Q &gt; 2.5)
std::enable_if< std::is_convertible< T, Key >::value, bool >::type ContainsKeys(const std::map< Key, Value > &container, T key)
Definition: Utils.hpp:69
void MuteOutput()
Definition: Logging.cpp:22
particles shot towards Layer 1
AMSSetupR::RTI m_rti
Definition: NtpSelector.h:65
std::enable_if< EnableBitMaskOperators< Enum >::enable, bool >::type MatchAllBits(const Enum test, const Enum ones, const Enum zeroes=static_cast< Enum >(0))
Definition: bitmask.h:87
virtual bool Notify() override
Called every time a new file is loaded in the chain.
Definition: NtpSelector.cpp:25
std::string m_outputFilename
Definition: NtpSelector.h:57
Standard tracker charge reconstruction.
Definition: Utils.h:85
void DefineStandAlone()
Select standalone objects.
particles shot towards layer 1 and passing through layer 9
Tof data is available for this event.
std::unique_ptr< NAIAChain > m_chain
Definition: NtpSelector.h:61
unsigned long long lastentry
last entry to be processed
Definition: NtpSelector.h:30