AlcapDAQ  1
Lifetime.cpp
Go to the documentation of this file.
1 #include "Lifetime.h"
2 #include "TAnalysedPulse.h"
3 #include "definitions.h"
4 
5 #include <iostream>
6 #include <string>
7 #include <vector>
8 #include <map>
9 
10 #include "TH1I.h"
11 
13 static unsigned int nECut; // Number of histograms to make (each with different energy cut for final "capture" event)
14 static double tCut[2]; // Two time cuts in nanosecond (minimum time before looking for decay, maximum time)
15 static double tPileUp; // Pileup window time (no two muons allowed within this window of each other)
16 static std::vector<int> eCut; // Energy cuts to make for histograms
17 static std::vector<std::string> sNames; // Histogram names for ROOT application
18 static std::vector<std::string> sTitles; // Histogram titles
19 static std::vector<TH1I*> hLifetime; // Histograms
20 
21 Lifetime::Lifetime(char *HistogramDirectoryName) :
22  FillHistBase(HistogramDirectoryName) {
23 
24  // Time in ns
25  tCut[0] = 800.;
26  tCut[1] = 5000.;
27  tPileUp = 10000.;
28  // Energy cuts in ADC
29  eCut.push_back(100);
30  eCut.push_back(200);
31  eCut.push_back(300);
32  eCut.push_back(400);
33  eCut.push_back(500);
34  eCut.push_back(600);
35  eCut.push_back(700);
36  eCut.push_back(800);
37  eCut.push_back(900);
38  eCut.push_back(1000);
39  eCut.push_back(1100);
40  eCut.push_back(1200);
41  eCut.push_back(1300);
42  eCut.push_back(1400);
43  eCut.push_back(1500);
44  sNames.push_back("hLifetime100");
45  sNames.push_back("hLifetime200");
46  sNames.push_back("hLifetime300");
47  sNames.push_back("hLifetime400");
48  sNames.push_back("hLifetime500");
49  sNames.push_back("hLifetime600");
50  sNames.push_back("hLifetime700");
51  sNames.push_back("hLifetime800");
52  sNames.push_back("hLifetime900");
53  sNames.push_back("hLifetime1000");
54  sNames.push_back("hLifetime1100");
55  sNames.push_back("hLifetime1200");
56  sNames.push_back("hLifetime1300");
57  sNames.push_back("hLifetime1400");
58  sNames.push_back("hLifetime1500");
59  sTitles.push_back("Lifetime (100 ADC cut)");
60  sTitles.push_back("Lifetime (200 ADC cut)");
61  sTitles.push_back("Lifetime (300 ADC cut)");
62  sTitles.push_back("Lifetime (400 ADC cut)");
63  sTitles.push_back("Lifetime (500 ADC cut)");
64  sTitles.push_back("Lifetime (600 ADC cut)");
65  sTitles.push_back("Lifetime (700 ADC cut)");
66  sTitles.push_back("Lifetime (800 ADC cut)");
67  sTitles.push_back("Lifetime (900 ADC cut)");
68  sTitles.push_back("Lifetime (1000 ADC cut)");
69  sTitles.push_back("Lifetime (1100 ADC cut)");
70  sTitles.push_back("Lifetime (1200 ADC cut)");
71  sTitles.push_back("Lifetime (1300 ADC cut)");
72  sTitles.push_back("Lifetime (1400 ADC cut)");
73  sTitles.push_back("Lifetime (1500 ADC cut)");
74  // Number to index later
75  nECut = eCut.size();
76  // Sanity check: All vectors are the same size above
77  if (nECut != sNames.size() || nECut != sTitles.size())
78  std::cout << "Error! Coder forgot a line or two in initialization of Lifetime module in rootana!" << std::endl;
79  // Prepare histograms
80  for (unsigned int iECut = 0; iECut < nECut; ++iECut)
81  hLifetime.push_back(new TH1I(sNames[iECut].c_str(), sTitles[iECut].c_str(), 1000, 0., 2000.));
82 
83  gDirectory->cd("/");
84 }
85 
87 }
88 
90 
91  // Look for muSc and at least one arm
92  AnalysedPulseList *musc;
93  AnalysedPulseList *sir, *sil;
94  if (gAnalysedPulseMap.count("muSc")) musc = &gAnalysedPulseMap.at("muSc");
95  else return 0;
96 
97  if (gAnalysedPulseMap.count("SiR2-F")) sir = &gAnalysedPulseMap.at("SiR2-F");
98  else sir = NULL;
99 
100  if (gAnalysedPulseMap.count("SiL2-F")) sil = &gAnalysedPulseMap.at("SiL2-F");
101  else sil = NULL;
102 
103  // If neither arm had hits, there's nothing to loop through
104  if (sil == NULL && sir == NULL) return 0;
105 
106  // Iterators through aforementioned vectors
107  AnalysedPulseList::iterator cMusc;
108  AnalysedPulseList::iterator cSiR, cSiL;
109  cMusc = musc->begin();
110  if (sir)
111  cSiR = sir->begin();
112  if (sil)
113  cSiL = sil->begin();
114 
115  unsigned int iECut;
116  double tMusc;
117  bool bFound[15];
118  for (; cMusc < musc->end(); ++cMusc) {
119  tMusc = (*cMusc)->GetTime();
120  // If there's pile-up, advance beyond it
121  if ((cMusc+1) != musc->end() && (*(cMusc + 1))->GetTime() - tMusc < tPileUp) {
122  ++cMusc;
123  continue;
124  }
125  // Set all flags to 'not-found-yet' status
126  for (iECut = 0; iECut < nECut; ++iECut)
127  bFound[iECut] = false;
128  // Advance silicon pulses beyond time of muSc
129  if (sir)
130  while (cSiR != sir->end() && (*cSiR)->GetTime() -tMusc < tCut[0])
131  ++cSiR;
132  if (sil)
133  while (cSiL != sil->end() && (*cSiL)->GetTime() < tMusc)
134  ++cSiL;
135  // Check for hits
136  if (sir)
137  while (cSiR != sir->end() && (*cSiR)->GetTime() - tMusc < tCut[1]) {
138  for (iECut = 0; iECut < nECut; ++iECut)
139  if (!(bFound[iECut]))
140  if ((*cSiR)->GetAmplitude() > eCut[iECut]) {
141  hLifetime[iECut]->Fill((*cSiR)->GetTime() - tMusc);
142  bFound[iECut] = true;
143  }
144  ++cSiR;
145  }
146  if (sil)
147  while (cSiL != sil->end() && (*cSiL)->GetTime() - tMusc < tCut[1]) {
148  for (iECut = 0; iECut < nECut; ++iECut)
149  if (!(bFound[iECut]))
150  if ((*cSiL)->GetAmplitude() > eCut[iECut]) {
151  hLifetime[iECut]->Fill((*cSiL)->GetTime() - tMusc);
152  bFound[iECut] = true;
153  }
154  ++cSiL;
155  }
156  }
157 
158  return 0;
159 }