NAIA  1.0.2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups
RichFill.cpp
Go to the documentation of this file.
1 #include "Containers/Rich.h"
2 
3 #include "RichCharge.h"
4 #include "richidOff.h"
5 #include "richradidOff.h"
6 #include "richrecOff.h"
7 
8 namespace NAIA {
9 
10 bool RichBaseData::Fill(RichRingR *ringPtr, RichRingBR *ringBPtr) {
11 
12  if (!ringPtr && !ringBPtr)
13  return false;
14 
15  RichBaseDataR data;
16 
17  if (ringPtr) {
18  data.isNaF = ringPtr->IsNaF();
19 
20  data.beta[Rich::BetaType::CIEMAT] = ringPtr->getBeta();
21  data.beta[Rich::BetaType::SIMPLE] = ringPtr->Beta;
22  data.beta[Rich::BetaType::REFIT] = ringPtr->BetaRefit;
23  data.beta[Rich::BetaType::LIP] = 0;
24 
25  data.ebeta[Rich::BetaType::CIEMAT] = ringPtr->getBetaError();
26  data.ebeta[Rich::BetaType::SIMPLE] = ringPtr->ErrorBeta;
27  data.ebeta[Rich::BetaType::REFIT] = ringPtr->getBetaError();
28  data.ebeta[Rich::BetaType::LIP] = 0;
29 
30  data.isGood = ringPtr->IsGood();
31  data.Pos[0] = ringPtr->getTrackEmissionPoint()[0];
32  data.Pos[1] = ringPtr->getTrackEmissionPoint()[1];
33  data.hasBetaLIP = false;
34  }
35  if (ringBPtr) {
36  data.beta[Rich::BetaType::LIP] = ringBPtr->Beta;
37  data.ebeta[Rich::BetaType::LIP] = 0;
38  data.hasBetaLIP = true;
39  }
40 
41  m_beta.push_back(data);
42 
43  return true;
44 }
45 
46 bool RichPlusData::Fill(AMSEventR *evPtr, RichRingR *ringPtr, RichRingBR *ringPtrB, TrTrackR *trackPtr) {
47  RichAdditionalData data;
48 
49  data.NHitsTot = evPtr->NRichHit();
50  data.NPETotUncorr = RichHitR::getCollectedPhotoElectrons();
51  if (ringPtr) {
52  data.NHitsUsed = ringPtr->getUsedHits();
53  data.NPEExpUncorr = ringPtr->getExpectedPhotoElectrons(false);
54  data.NPEExpCorr = ringPtr->getExpectedPhotoElectrons();
55  data.NPEMeasUncorr = ringPtr->getPhotoElectrons(false);
56  data.NPEMeasCorr = ringPtr->getPhotoElectrons();
57  data.Probability = ringPtr->getProb();
58  data.RingPMTs = ringPtr->NpColPMT.size();
59  data.RingPMTs2 = ringPtr->getPMTs();
60  data.RichPMTs = RichHitR::getPMTs() - RichHitR::getPMTs(false);
61  data.ChargeConsistency = ringPtr->getPMTChargeConsistency();
62  data.RichCharge = ringPtr->getCharge2Estimate();
63  data.RichCharge2 = ringPtr->NpExp > 0 ? sqrt(ringPtr->NpCol / ringPtr->NpExp) : -1; // expected collected
64 
65  FillHyp1Data(data, evPtr, ringPtr, trackPtr);
66  }
67  if (ringPtrB)
68  data.LIP_ringProb = ringPtrB->ProbKolm;
69 
70  m_data.push_back(data);
71  return true;
72 }
73 
74 void RichPlusData::FillHyp1Data(RichAdditionalData &data, AMSEventR *evPtr, RichRingR *ringPtr, TrTrackR *trackPtr) {
75  // get the PMT calibration, if available
76  RichPMTCalib *pmt_calib = (!m_isMC) ? RichPMTCalib::getHead() : nullptr;
77 
78  struct pmt_info {
79  int pmt = -1;
80  int nhit = 0;
81  float np = 0;
82  std::array<float, 3> coo{0, 0, 0};
83  float dist = 0;
84  };
85 
86  std::map<unsigned int, pmt_info> pmt_info_map;
87  std::vector<int> crossed_pmt[2]; // primary/secondary
88  std::vector<RichHitR *> rich_hit_on_ring_list;
89  std::map<int, RichHitR *> rich_hit_offline_map;
90 
91  // fill pmt info map
92  for (const RichHitR &hit : evPtr->RichHit()) {
93  int pmt = int(hit.Channel / 16);
94 
95  // discard bad PMTs
96  if ((pmt_calib) && (find(begin(pmt_calib->BadPMTs), end(pmt_calib->BadPMTs), pmt) != end(pmt_calib->BadPMTs)))
97  continue;
98 
99  float np = hit.Npe;
100  pmt_info_map[pmt].pmt = pmt;
101  pmt_info_map[pmt].nhit++;
102  pmt_info_map[pmt].np += np;
103  for (int icoo = 0; icoo < 3; icoo++)
104  pmt_info_map[pmt].coo[icoo] += np * hit.Coo[icoo];
105  }
106 
107  for (auto &it : pmt_info_map) {
108  for (int icoo = 0; icoo < 3; icoo++)
109  it.second.coo[icoo] /= it.second.np;
110  if (trackPtr) {
111  double rigidity;
112  AMSPlane plm(TVector3(0, 0, it.second.coo[2]), TVector3(1, 0, 0), TVector3(0, 1, 0));
113  trackPtr->Interpolate(plm, rigidity);
114  TVector3 pglob = plm.getP();
115  it.second.dist = sqrt(pow(it.second.coo[0] - pglob.x(), 2.) + pow(it.second.coo[1] - pglob.y(), 2.));
116  }
117  if (it.second.np < 5)
118  continue;
119  crossed_pmt[(it.second.dist < 3.5) ? 0 : 1].push_back(it.first);
120  }
121  int index = 0;
122  std::vector<std::pair<int, pmt_info>> pmt_info_vec;
123  for (const auto &it : pmt_info_map) {
124  pmt_info_vec.emplace_back(it.first, it.second);
125  }
126  std::sort(begin(pmt_info_vec), end(pmt_info_vec),
127  [](const std::pair<int, pmt_info> &elem1, const std::pair<int, pmt_info> &elem2) {
128  return elem1.second.np > elem2.second.np;
129  });
130  std::array<float, 5> pmt_np_uncorr;
131  std::array<float, 5> pmt_dist;
132  for (const auto &it : pmt_info_vec) {
133  if (index > 4)
134  continue;
135  pmt_np_uncorr[index] = it.second.np;
136  pmt_dist[index] = it.second.dist;
137  index++;
138  }
139 
140  // selected ring
141  for (int ihit = 0; ihit < ringPtr->getUsedHits(false); ihit++)
142  rich_hit_on_ring_list.push_back(evPtr->pRichHit(ringPtr->iRichHit(ihit)));
143  // beta hypothesys
144  int which = 0;
145  for (RichOffline::RichRawEvent *hit = new RichOffline::RichRawEvent(evPtr); hit; hit = hit->next(), which++) {
146  rich_hit_offline_map.insert(std::make_pair(which, hit->getpointer()));
147  }
148  // loop on beta hypothesys
149  for (int i = 0; i < ringPtr->RawBetas(); i++) {
150  int ihit = ringPtr->HitBeta(i);
151  RichHitR *rich_hit = rich_hit_offline_map[ihit];
152  if (!rich_hit)
153  continue;
154 
155  int pmt = int(rich_hit->Channel / 16);
156  bool is_bad_pmt =
157  (pmt_calib) && (find(begin(pmt_calib->BadPMTs), end(pmt_calib->BadPMTs), pmt) != end(pmt_calib->BadPMTs));
158 
159  // we don't have the offline occupancy map used in the dbar analysis. Disable this for now
160  bool is_bad_occupancy = false;
161  // bool is_bad_occupancy = (pRichOcc) ? (!pRichOcc->IsGood(rich_hit->Channel)) : true;
162 
163  bool is_crossed_pri = find(begin(crossed_pmt[0]), end(crossed_pmt[0]), pmt) != end(crossed_pmt[0]);
164  bool is_crossed_sec = find(begin(crossed_pmt[1]), end(crossed_pmt[1]), pmt) != end(crossed_pmt[1]);
165  bool is_not_in_selected_ring =
166  (find(begin(rich_hit_on_ring_list), end(rich_hit_on_ring_list), rich_hit) == end(rich_hit_on_ring_list));
167  int status2 = ((is_bad_pmt) ? 0x1 : 0) + ((is_bad_occupancy) ? 0x2 : 0) + ((is_crossed_pri) ? 0x4 : 0) +
168  ((is_crossed_sec) ? 0x8 : 0) + ((is_not_in_selected_ring) ? 0x10 : 0);
169 
170  // integrate beta = 1 hypothesys with only good hits
171  if ((rich_hit->Status >> 31) & 0x1)
172  continue;
173  if ((status2 & 0xf) != 0)
174  continue;
175 
176  int kind_of_tile = ringPtr->IsNaF();
177  std::array<float, 2> simple_resolution{1.2e-3, 4e-3};
178  for (int ibeta = 0; ibeta < 2; ibeta++) {
179  if (std::fabs(ringPtr->RawBeta(i, ibeta) - 1) > 3. * simple_resolution[kind_of_tile])
180  continue;
181 
182  data.NHitsHyp1Tot[ibeta]++;
183  if ((ringPtr->UsedBeta(i) < 0) || (ringPtr->UsedBeta(i) > 1)) {
184  data.NHitsHyp1OutOfRing[ibeta]++;
185  data.NPEHyp1UncorrTot += rich_hit->Npe;
186  }
187  }
188  }
189 
190  // Apparently re-clustering requires a valid TrTrackR. I don't know why
191  // this wasn't the case in the DBar ntuple
192  if (trackPtr) {
193  unsigned int nclus = ringPtr->ClusterizeZ1();
194  int dummy1;
195  float dummy2, mean;
196  if (nclus > 0) {
197  for (int iclu = 0; iclu < std::min(10u, nclus); iclu++) {
198  ringPtr->GetClusters(iclu, dummy1, mean, dummy2);
199  if (std::fabs(mean - ringPtr->getBeta()) > 0.01)
200  data.NBadClusters++;
201  }
202  }
203  }
204 
205  for (int is = 0; is < 5; is++) {
206  if ((pmt_np_uncorr[is] > 5) && (pmt_dist[is] > 3.5))
207  data.NSecondaryHits++;
208  }
209 }
210 
211 } // namespace NAIA
std::vector< RichAdditionalData > m_data
Definition: Rich.h:239
NAIAChain::EventItr begin(NAIAChain &chain)
Definition: NAIAChain.h:297
std::vector< RichBaseDataR > m_beta
Definition: Rich.h:140
Rich container class description.
NAIAChain::EventItr end(NAIAChain &chain)
Definition: NAIAChain.h:298