All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CRTHitTiming.cc
Go to the documentation of this file.
1 /**
2  * \file CRTHitTiming.cc
3  *
4  *
5  * Author:
6  */
7 
8 #include <iostream>
9 #include <array>
10 
11 #include "nusimdata/SimulationBase/MCParticle.h"
12 
13 #include "canvas/Utilities/InputTag.h"
14 #include "core/SelectionBase.hh"
15 #include "core/Event.hh"
16 #include "core/Experiment.hh"
17 #include "core/ProviderManager.hh"
18 
19 #include "canvas/Persistency/Common/FindManyP.h"
22 #include "icaruscode/CRT/CRTProducts/CRTChannelData.h"
26 #include "fhiclcpp/ParameterSet.h"
27 
30 
31 #include "TH2D.h"
32 #include "TGraph.h"
33 
34 namespace ana {
35  namespace SBNOsc {
36 
37 /**
38  * \class CRTHitTiming
39  * \brief Electron neutrino event selection
40  */
42 public:
43  /** Constructor. */
45 
46  /**
47  * Initialization.
48  *
49  * \param config A configuration, as a FHiCL ParameterSet object
50  */
51  void Initialize(fhicl::ParameterSet* config=NULL) {
52  fCRTHitTag = config ? config->get<std::string>("CRTHitTag", "crtsimhit") : "crtsimhit";
53  fIsICARUS = config ? config->get<bool>("IsICARUS", true) : true;
54  event_ind = 0;
55  _verbose = false;
56  _true_v_hit_time = new TH1D("true_v_hit_time", "true_v_hit_time", 200, -100., 100.);
57  _true_v_hit_time_c = new TH1D("true_v_hit_time_c", "true_v_hit_time_c", 200, -100., 100.);
58  _true_v_hit_time_d = new TH1D("true_v_hit_time_d", "true_v_hit_time_d", 200, -100., 100.);
59  _true_v_hit_time_m = new TH1D("true_v_hit_time_m", "true_v_hit_time_m", 200, -100., 100.);
60  _true_v_hit_time_coince = new TH1D("true_v_hit_time_coince", "true_v_hit_time_coince", 200, -100., 100.);
61  _hitpe_muon = new TH1D("hitpe_muon", "hitpe_muon", 1000, 0., 1000.);
62  _hitpe_proton = new TH1D("hitpe_proton", "hitpe_proton", 1000, 0., 1000.);
63  _hitpe_neutron = new TH1D("hitpe_neutron", "hitpe_neutron", 1000, 0., 1000.);
64  FillFebMap();
65  }
66 
67  /** Finalize and write objects to the output file. */
68  void Finalize() {
69  fOutputFile->cd();
70  _true_v_hit_time_coince->Write();
71  _true_v_hit_time->Write();
72  _true_v_hit_time_c->Write();
73  _true_v_hit_time_m->Write();
74  _true_v_hit_time_d->Write();
75  _hitpe_muon->Write();
76  _hitpe_proton->Write();
77  _hitpe_neutron->Write();
78  }
79 
80  int GetPDG(const std::vector<simb::MCParticle> &mc_particles, int trackID) {
81  for (const simb::MCParticle &part: mc_particles) {
82  if (part.TrackId() == trackID) return part.PdgCode();
83  }
84  return -1;
85  }
86 
87  /**
88  * Process one event.
89  *
90  * \param ev A single event, as a gallery::Event
91  * \param Reconstructed interactions
92  * \return True to keep event
93  */
94  bool ProcessEvent(const gallery::Event& ev, const std::vector<event::Interaction> &truth, std::vector<event::RecoInteraction>& reco) {
95  const std::vector<simb::MCParticle> &mc_particles = *ev.getValidHandle<std::vector<simb::MCParticle>>("largeant");
96 
97  if (fIsICARUS) {
98  auto const &crt_hits_handle = ev.getValidHandle<std::vector<sbn::crt::CRTHit>>(fCRTHitTag);;
99  const std::vector<sbn::crt::CRTHit> &crt_hits = *crt_hits_handle;
100  const std::vector<sim::AuxDetSimChannel> &crt_sim_channels = *ev.getValidHandle<std::vector<sim::AuxDetSimChannel>>("largeant");
101  art::FindManyP<icarus::crt::CRTData, void> hits_to_data(crt_hits_handle, ev, fCRTHitTag);
102 
103  // TODO: fix when ICARUS has the necessary associations
104  // collect the mapping of track ID to IDE's
105  std::map<int, std::vector<std::pair<std::pair<int, int>, sim::AuxDetIDE>>> tracks_to_ides;
106  for (const sim::AuxDetSimChannel &simchannel: crt_sim_channels) {
107  for (const sim::AuxDetIDE &ide: simchannel.AuxDetIDEs()) {
108  tracks_to_ides[ide.trackID].push_back({{simchannel.AuxDetID(), simchannel.AuxDetSensitiveID()}, ide});
109  }
110  }
111 
112  // Now for each CRT hit, try to figure out the IDE(s) that made it
113  for (unsigned i = 0; i < crt_hits.size(); i++) {
114  const sbn::crt::CRTHit &hit = crt_hits[i];
115  std::vector<art::Ptr<icarus::crt::CRTData>> datas = hits_to_data.at(i);
116  assert(datas.size() == 1 || datas.size() == 2);
117  bool has_coincedence = datas.size() == 2;
118  _verbose = false;
119 
120  // map to auxdet
121  int auxdetid_0 = MacToAuxDetID(datas[0]->Mac5(), datas[0]->ChanTrig());
122  // and to type
123  const geo::AuxDetGeo& adGeo = fProviderManager->GetAuxDetGeometryProvider()->AuxDet(auxdetid_0);
124  const char auxDetType = GetAuxDetType(adGeo); //CRT module type (c, d, or m)
125 
126  if (has_coincedence) {
127  int auxdetid_1 = MacToAuxDetID(datas[1]->Mac5(), datas[1]->ChanTrig());
128  const geo::AuxDetGeo& adGeo = fProviderManager->GetAuxDetGeometryProvider()->AuxDet(auxdetid_1);
129  assert(auxDetType == GetAuxDetType(adGeo));
130  }
131 
132  double hit_time = (int)hit.ts0_ns;
133 
134  if (_verbose) std::cout << "CRT Hit at: " << hit.ts1_ns << " " << (int)hit.ts0_ns << " " << (int)hit.ts0_ns_corr << std::endl;
135  if (_verbose) std::cout << "Has Coincedence: " << has_coincedence << std::endl;
136 
137  double true_time_sum = 0.;
138  unsigned n_true_time = 0;
139 
140  bool has_muon = false;
141  bool has_proton = false;
142  bool has_neutron = false;
143  for (unsigned j = 0; j < datas.size(); j++) {
144  const icarus::crt::CRTData &data = *datas[j];
145  if (_verbose) std::cout << "CRT Data at: " << data.TTrig() << " Mac5: " << data.Mac5() << " chan: " << data.ChanTrig() << std::endl;
146  const std::vector<icarus::crt::CRTChannelData> &channel_datas = data.ChanData();
147 
148 
149  for (const icarus::crt::CRTChannelData &chan: channel_datas) {
150  const std::vector<int> track_ids = chan.TrackID();
151  if (_verbose) std::cout << "Channel Data at: " << chan.T0() << " chan: " << chan.Channel() << std::endl;
152  for (int track_id: track_ids) {
153  int pdg_match = abs(GetPDG(mc_particles, track_id));
154  if (abs(pdg_match) == 13) has_muon = true;
155  else if (abs(pdg_match) == 2212) has_proton = true;
156  else if (abs(pdg_match) == 2112) has_neutron = true;
157  if (_verbose) std::cout << "True Particle: " << track_id << std::endl;
158  for (const auto &ide_pair: tracks_to_ides.at(track_id)) {
159  const sim::AuxDetIDE &ide = ide_pair.second;
160  std::pair<int, int> channel = ide_pair.first;
161  double true_time = ide.entryT - 1.1e6;
162  if (_verbose) std::cout << "True Hit at: " << true_time << " X: " << ide.entryX << " Y: " << ide.entryY <<" Z: " << ide.entryZ << " Chan: " << channel.first << " " << channel.second << std::endl;
163  std::array<int, 3> crt_channel = GetCRTChannel(channel.first, channel.second);
164  if (_verbose) std::cout << "Mapped FEB: " << crt_channel[0] << "Mapped channel: " << crt_channel[1] << " " << crt_channel[2] << std::endl;
165 
166  if (data.Mac5() == crt_channel[0] && (data.ChanTrig() == crt_channel[1] || data.ChanTrig() == crt_channel[2])) {
167  true_time_sum += true_time;
168  n_true_time += 1;
169  }
170  }
171  }
172  }
173  }
174  if (has_coincedence) _true_v_hit_time_coince->Fill((true_time_sum/n_true_time) - hit_time);
175  else {
176  std::cout << "Hit time: " << hit_time << " avg true time: " << (true_time_sum/n_true_time) << std::endl;
177  _true_v_hit_time->Fill((true_time_sum/n_true_time) - hit_time);
178  }
179  if (auxDetType == 'm') _true_v_hit_time_m->Fill((true_time_sum/n_true_time) - hit_time);
180  else if (auxDetType == 'd') _true_v_hit_time_d->Fill((true_time_sum/n_true_time) - hit_time);
181  else if (auxDetType == 'c') _true_v_hit_time_c->Fill((true_time_sum/n_true_time) - hit_time);
182  else assert(false);
183 
184  double pes = (hit.peshit - 2*63.6) / (70.*2);
185  if (has_muon) _hitpe_muon->Fill(pes);
186  else if (has_proton) _hitpe_proton->Fill(pes);
187  else if (has_neutron) _hitpe_neutron->Fill(pes);
188 
189  }
190  // fOutputFile->cd();
191  }
192  else {
193  auto const &crt_hits_handle = ev.getValidHandle<std::vector<sbn::crt::CRTHit>>(fCRTHitTag);;
194  const std::vector<sbn::crt::CRTHit> &crt_hits = *crt_hits_handle;
195  const std::vector<sim::AuxDetSimChannel> &crt_sim_channels = *ev.getValidHandle<std::vector<sim::AuxDetSimChannel>>("largeant");
196  art::FindManyP<sbnd::crt::CRTData, void> hits_to_data(crt_hits_handle, ev, fCRTHitTag);
197  auto const &crt_data_handle = ev.getValidHandle<std::vector<sbnd::crt::CRTData>>("crt");
198  for (unsigned i = 0; i < crt_hits.size(); i++) {
199  int track_id = -1;
200  const sbn::crt::CRTHit &hit = crt_hits[i];
201  std::vector<art::Ptr<sbnd::crt::CRTData>> datas = hits_to_data.at(i);
202  art::FindManyP<sim::AuxDetIDE, void> sims(datas, ev, "crt");
203  bool has_muon = false;
204  bool has_proton = false;
205  bool has_neutron = false;
206  for (unsigned j = 0; j < datas.size(); j++) {
207  for (unsigned k = 0; k < sims.at(j).size(); k++) {
208  track_id = sims.at(j).at(k)->trackID;
209  int pdg_match = GetPDG(mc_particles, track_id);
210  if (abs(pdg_match) == 13) has_muon = true;
211  else if (abs(pdg_match) == 2212) has_proton = true;
212  else if (abs(pdg_match) == 2112) has_neutron = true;
213  }
214  }
215  double pes = hit.peshit;
216  if (has_muon) _hitpe_muon->Fill(pes);
217  else if (has_proton) _hitpe_proton->Fill(pes);
218  else if (has_neutron) _hitpe_neutron->Fill(pes);
219  }
220  }
221  event_ind += 1;
222 
223  return false;
224  }
225 
226 protected:
227  void FillFebMap()
228  {
229  if(!this->fFebMap.empty())
230  return;
231 
232  std::string fullFileName;
233  cet::search_path searchPath("FW_SEARCH_PATH");
234  searchPath.find_file("feb_map.txt",fullFileName);
235  std::ifstream fin;
236  fin.open(fullFileName,std::ios::in);
237  if(fin.good()) std::cout << "opened file 'feb_map.txt' for reading..." << std::endl;
238  else
239  throw cet::exception("FillFebMap") << "Unable to find/open file 'feb_map.txt'" << std::endl;
240  std::vector<std::string> row;
241  std::string line, word;
242  while(getline(fin,line)) {
243  row.clear();
244  std::stringstream s(line);
245  int mod;
246  while (std::getline(s, word, ',')) {
247  row.push_back(word);
248  }
249  mod = std::stoi(row[0]);
250  (this->fFebMap)[mod].push_back(std::make_pair(std::stoi(row[1]),std::stoi(row[2])));
251  if(row.size()>3)
252  (this->fFebMap)[mod].push_back(std::make_pair(std::stoi(row[3]),std::stoi(row[4])));
253  }
254  std::cout << "filled febMap with " << (this->fFebMap).size() << " entries" << std::endl;
255  fin.close();
256  } //FillFebMap()
257 
258 char GetAuxDetType(geo::AuxDetGeo const& adgeo)
259 {
260  std::string volName(adgeo.TotalVolume()->GetName());
261  if (volName.find("MINOS") != std::string::npos) return 'm';
262  if (volName.find("CERN") != std::string::npos) return 'c';
263  if (volName.find("DC") != std::string::npos) return 'd';
264 
265  return 'e';
266 }//GetAuxDetType()
267 
268  char MacToType(int mac)
269  {
270 
271  int reg = MacToRegion(mac);
272  if(reg>=30&&reg<40) return 'c';
273  if(reg>=40&&reg<50) return 'm';
274  if(reg==50) return 'd';
275  std::cout << "ERROR in MacToType: type not set!" << std::endl;
276  return 'e';
277  }
278 
279  int MacToRegion(int mac){
280 
281  if(mac>=107 && mac<=190) return 30; //top
282  if(mac>=191 && mac<=204) return 31; //rim west
283  if(mac>=205 && mac<=218) return 32; //rim east
284  if(mac>=219 && mac<=224) return 33; //rim south
285  if(mac>=225 && mac<=230) return 34; //rim north
286  if( mac<=12 ) return 40; //west side, south stack
287  if(mac>=13 && mac<=24 ) return 41; //west side, center stack
288  if(mac>=25 && mac<=36 ) return 42; //west side, north stack
289  if(mac>=37 && mac<=48 ) return 43; //east side, south stack
290  if(mac>=49 && mac<=60 ) return 44; //east side, center stack
291  if(mac>=61 && mac<=72 ) return 45; //east side, north stack
292  if(mac>=73 && mac<=84 ) return 46; //south
293  if(mac>=85 && mac<=92 ) return 47; //north
294  if(mac>=93 && mac<=106) return 50; //bottom
295 
296  std::cout << "ERROR in MacToRegion: unknown mac address " << mac << std::endl;
297  return 0;
298  }
299 
300  int MacToAuxDetID(int mac, int chan)
301  {
302  char type = MacToType(mac);
303  if (type == 'e') return INT_MAX;
304 
305  int pos=1;
306  if(type=='m')
307  pos = chan/10 + 1;
308 
309  if((this->fFebMap).empty())
310  std::cout << "ERROR in MacToAuxDetID: FEBMap is empty!" << std::endl;
311 
312  for(const auto& p : this->fFebMap) {
313  if(p.second[0].first == mac && p.second[0].second==pos)
314  return (uint32_t)p.first;
315  if(p.second.size()==2)
316  if(p.second[1].first==mac && p.second[1].second==pos)
317  return (uint32_t)p.first;
318  }
319 
320 
321  std::cout << "ERROR in MacToAuxDetID: auxDetID not set!" << std::endl;
322  return INT_MAX;
323  }
324 
325 
326  std::array<int, 3> GetCRTChannel(int aux_det_id, int aux_det_sens_id) {
327  // const char auxDetType, ) {
328  const int adid = aux_det_id; //adsc.AuxDetID(); //CRT module ID number (from gdml)
329  const int adsid = aux_det_sens_id; //adsc.AuxDetSensitiveID(); //CRT strip ID number (from gdml)
331  const char auxDetType = GetAuxDetType(adGeo); //CRT module type (c, d, or m)
332 
333  int channel0ID=-1, channel1ID=-1;
334  int mac5;
335  int mac5dual;
336  switch (auxDetType){
337  case 'c' :
338  mac5 =fFebMap[adid][0].first;
339  channel0ID = 2 * adsid + 0;
340  channel1ID = 2 * adsid + 1;
341  if(mac5<107||mac5>230)
342  std::cout << "WARNING: mac5 out of bounds for c-type!" << std::endl;
343  if(channel0ID<0 || channel0ID > 31 || channel1ID<0 || channel1ID>31)
344  std::cout << "WARNING: channel out of bounds for c-type!" << std::endl;
345  break;
346  case 'd' :
347  mac5 = fFebMap[adid][0].first;
348  channel0ID = adsid;
349  if(mac5<93||mac5>106)
350  std::cout << "WARNING: mac5 out of bounds for d-type!" << std::endl;
351  if(channel0ID<0 || channel0ID > 63)
352  std::cout << "WARNING: channel out of bounds for d-type!" << std::endl;
353  break;
354  case 'm' :
355  mac5 = fFebMap[adid][0].first;
356  channel0ID = adsid/2 + 10*(fFebMap[adid][0].second-1);
357  if(mac5<1||mac5>92)
358  std::cout << "WARNING: mac5 out of bounds for m-type!" << std::endl;
359  if(channel0ID<0 || channel0ID > 31)
360  std::cout << "WARNING: channel out of bounds for m-type!" << std::endl;
361  if (fFebMap[adid].size()==2) {
362  mac5dual = fFebMap[adid][1].first;
363  if(mac5dual<1||mac5dual>92)
364  std::cout << "WARNING: mac5dual out of bounds for m-type!" << std::endl;
365  }
366  break;
367  }
368  return {mac5, channel0ID, channel1ID};
369  }
370 
371  std::map<int,std::vector<std::pair<int,int>>> fFebMap;
372  std::string fCRTHitTag;
373  bool fIsICARUS;
374  bool _verbose;
375  unsigned event_ind;
381  TH1D *_hitpe_muon;
384 };
385 
386  } // namespace SBNOsc
387 } // namespace ana
389 
then if[["$THISISATEST"==1]]
Definition: neoSmazza.sh:95
char GetAuxDetType(geo::AuxDetGeo const &adgeo)
double ts1_ns
Timestamp T1 ([signal time w.r.t. Trigger time]), in UTC absolute time scale in nanoseconds from the ...
Definition: CRTHit.hh:34
AuxDetGeo const & AuxDet(unsigned int const ad=0) const
Returns the specified auxiliary detector.
float peshit
Total photo-electron (PE) in a crt hit.
Definition: CRTHit.hh:27
pdgs p
Definition: selectors.fcl:22
const geo::AuxDetGeometryCore * GetAuxDetGeometryProvider() const
TFile * fOutputFile
The output ROOT file.
std::size_t size(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:561
process_name hit
Definition: cheaterreco.fcl:51
process_name opflashCryoW ana
std::map< int, std::vector< std::pair< int, int > > > fFebMap
double ts0_ns_corr
[Honestly, not sure at this point, it was there since long time (BB)]
Definition: CRTHit.hh:33
Electron neutrino event selection.
Definition: CRTHitTiming.cc:41
Collection of particles crossing one auxiliary detector cell.
double ts0_ns
Timestamp T0 (from White Rabbit), in UTC absolute time scale in nanoseconds from the Epoch...
Definition: CRTHit.hh:32
T abs(T value)
object containing MC truth information necessary for making RawDigits and doing back tracking ...
process_name standard_reco_uboone reco
float entryT
Entry time of particle.
art framework interface to geometry description for auxiliary detectors
Single hit (self trigger) of a CRT board.
#define DECLARE_SBN_PROCESSOR(classname)
Base class for event selections.
float entryZ
Entry position Z of particle.
Encapsulate the geometry of an auxiliary detector.
bool ProcessEvent(const gallery::Event &ev, const std::vector< event::Interaction > &truth, std::vector< event::RecoInteraction > &reco)
Definition: CRTHitTiming.cc:94
std::array< int, 3 > GetCRTChannel(int aux_det_id, int aux_det_sens_id)
float entryX
Entry position X of particle.
float entryY
Entry position Y of particle.
if &&[-z"$BASH_VERSION"] then echo Attempting to switch to bash bash shellSwitch exit fi &&["$1"= 'shellSwitch'] shift declare a IncludeDirectives for Dir in
const TGeoVolume * TotalVolume() const
Definition: AuxDetGeo.h:106
then echo File list $list not found else cat $list while read file do echo $file sed s
Definition: file_to_url.sh:60
MC truth information to make RawDigits and do back tracking.
ProviderManager * fProviderManager
Interface for provider access.
int MacToAuxDetID(int mac, int chan)
pdgs k
Definition: selectors.fcl:22
bool empty(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:555
int GetPDG(const std::vector< simb::MCParticle > &mc_particles, int trackID)
Definition: CRTHitTiming.cc:80
BEGIN_PROLOG could also be cout
void Initialize(fhicl::ParameterSet *config=NULL)
Definition: CRTHitTiming.cc:51