All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
icaruscode/icaruscode/CRT/CRTUtils/CRTCommonUtils.cc
Go to the documentation of this file.
1 #ifndef IC_CRTCOMMONUTILS_CC
2 #define IC_CRTCOMMONUTILS_CC
3 
5 #include "larcore/CoreUtils/ServiceUtil.h" // lar::providerFrom()
6 #include <fstream>
7 
8 using namespace icarus::crt;
9 
11  // fGeoService = art::ServiceHandle<geo::AuxDetGeometry const>()->GetProviderPtr();
12  fGeoService = lar::providerFrom<geo::Geometry>();
13  FillFebMap();
15 }
16 
17 //given an AuxDetGeo object, returns name of the CRT subsystem to which it belongs
18 char CRTCommonUtils::GetAuxDetType(size_t adid) {
19  if(fAuxDetIdToType.find(adid)==fAuxDetIdToType.end()) {
20  throw cet::exception("CRTCommonUtils::GetAuxDetType")
21  << "unknown AuxDetID passed to function";
22  }
23  return fAuxDetIdToType[adid];
24 }
25 
26 //------------------------------------------------------------------------------------
28  char type = GetAuxDetType(adid);
29  switch(type){
30  case 'c': return 0;
31  case 'm': return 1;
32  case 'd': return 2;
33  default: return -1;
34  }
35 }
36 
37 //------------------------------------------------------------------------------------
38 //given an AuxDetGeo object, returns name of the CRT region to which it belongs
39 string CRTCommonUtils::GetAuxDetRegion(size_t adid) {
40  if(fAuxDetIdToRegion.find(adid)==fAuxDetIdToRegion.end()) {
41  throw cet::exception("CRTCommonUtils::GetAuxDetRegion")
42  << "unknown AuxDetID passed to function";
43  }
44  return fAuxDetIdToRegion[adid];
45 }
46 
47 //------------------------------------------------------------------------------
49 {
50  if(reg == "Top") return 30;
51  if(reg == "RimWest") return 31;
52  if(reg == "RimEast") return 32;
53  if(reg == "RimSouth") return 33;
54  if(reg == "RimNorth") return 34;
55  if(reg == "WestSouth") return 40;
56  if(reg == "WestCenter") return 41;
57  if(reg == "WestNorth") return 42;
58  if(reg == "EastSouth") return 43;
59  if(reg == "EastCenter") return 44;
60  if(reg == "EastNorth") return 45;
61  if(reg == "South") return 46;
62  if(reg == "North") return 47;
63  if(reg == "Bottom") return 50;
64  mf::LogError("CRT") << "region not found!" << '\n';
65  return INT_MAX;
66 }//GetAuxDetRegionNum()
67 
68 //---------------------------------------------------------------------------------
70  switch(num) {
71  case 30 :
72  return "Top";
73  case 31 :
74  return "RimWest";
75  case 32 :
76  return "RimEast";
77  case 33 :
78  return "RimSouth";
79  case 34 :
80  return "RimNorth";
81  case 40 :
82  return "WestSouth";
83  case 41 :
84  return "WestCenter";
85  case 42 :
86  return "WestNorth";
87  case 43 :
88  return "EastSouth";
89  case 44 :
90  return "EastCenter";
91  case 45 :
92  return "EastNorth";
93  case 46 :
94  return "South";
95  case 47 :
96  return "North";
97  case 50 :
98  return "Bottom";
99  }
100 
101  return "Region not found!";
102 }
103 
104 //-------------------------------------------------------------------------------------------
106 
107  //CERN modules
108  if(name=="Top"||name=="RimWest"||name=="RimEast"||name=="RimSouth"||name=="RimNorth")
109  return 'c';
110  //MINOS modules
111  if(name=="WestSouth"||name=="WestCenter"||name=="WestNorth"||
112  name=="EastSouth"||name=="EastCenter"||name=="EastNorth"||
113  name=="North"||name=="South")
114  return 'm';
115  //DC modules
116  if(name=="Bottom")
117  return 'd';
118 
119  //error
120  throw cet::exception("CRTCommonUtils::GetRegTypeFromRegName")
121  << "passed region name not recognized!" << '\n';
122 }
123 
124 //-------------------------------------------------------------------------------------------
126  char type = GetRegTypeFromRegName(name);
127  switch(type){
128  case 'c': return 0;
129  case 'm': return 1;
130  case 'd': return 2;
131  default: return -1;
132  }
133 }
134 
135 //---------------------------------------------------------------------------------------------
136 //for C- and D-modules, 1 mac5 address
137 //three M-modules / FEB, full-length modules read out at both ends (2 FEBs)
138 // cut modules read out at one end (1 FEB)
139 // numbering convention is module from FEB i
140 // return pair<FEB i,FEB i> (C-, D-, Cut M- module)
141 // return pair<FEB i,FEB j> (Full-length M-modules)
142 pair<uint8_t,uint8_t> CRTCommonUtils::ADToMac(size_t adid) {
143 
144  if(fAuxDetIdToFeb.find(adid)==fAuxDetIdToFeb.end()) {
145  throw cet::exception("CRTCommonUtils::ADToMac")
146  << "unknown AuxDetID passed to function";
147  }
148  vector<pair<uint8_t,int>> febs = fAuxDetIdToFeb[adid];
149  if(febs.size()==2)
150  return std::make_pair(febs[0].first,febs[1].first);
151  else
152  return std::make_pair(febs[0].first,febs[0].first);
153 }
154 
155 //---------------------------------------------------------------------------------
157  if(fAuxDetIdToChanGroup.find(adid)==fAuxDetIdToChanGroup.end()){
158  throw cet::exception("CRTCommonUtils::ADMacToChanGroup")
159  << "unknown AuxDetID passed to function";
160  }
161  return fAuxDetIdToChanGroup[adid];
162 }
163 
164 //-------------------------------------------------------------------------------------
165 int CRTCommonUtils::NFeb(size_t adid){
166  if(fAuxDetIdToFeb.find(adid)==fAuxDetIdToFeb.end()) {
167  throw cet::exception("CRTCommonUtils::NFeb")
168  << "unknown AuxDetID passed to function";
169  }
170  return(fAuxDetIdToFeb[adid]).size();
171 }
172 
173 //--------------------------------------------------------------------------------------
174 string CRTCommonUtils::MacToRegion(uint8_t mac){
175  if(fFebToAuxDetId.find(mac)==fFebToAuxDetId.end()) {
176  throw cet::exception("CRTCommonUtils::MacToRegion")
177  << "unknown mac passed to function";
178  }
179  return GetAuxDetRegion(fFebToAuxDetId[mac][0]);
180 }
181 
182 //--------------------------------------------------------------------------------------
183 char CRTCommonUtils::MacToType(uint8_t mac)
184 {
185  if(fFebToAuxDetId.find(mac)==fFebToAuxDetId.end()) {
186  throw cet::exception("CRTCommonUtils::MacToType")
187  << "unknown mac passed to function";
188  }
189  return GetAuxDetType(fFebToAuxDetId[mac][0]);
190 }
191 
192 //--------------------------------------------------------------------------------------
194 {
195  if(fFebToAuxDetId.find(mac)==fFebToAuxDetId.end()) {
196  throw cet::exception("CRTCommonUtils::MacToType")
197  << "unknown mac passed to function";
198  }
199  char type = GetAuxDetType(fFebToAuxDetId[mac][0]);
200  switch(type){
201  case 'c': return 0;
202  case 'm': return 1;
203  case 'd': return 2;
204  default: return -1;
205  }
206 }
207 
208 
209 //--------------------------------------------------------------------------------------
210 
211 int CRTCommonUtils::ChannelToAuxDetSensitiveID(uint8_t mac, int chan) {
212  char type = MacToType(mac);
213  if (type=='d') return chan;
214  if (type=='c') return chan/2;
215  if (type=='m') return (chan % 10)*2;
216 
217  return INT_MAX;
218 }
219 
220 //--------------------------------------------------------------------------------------
221 
222 size_t CRTCommonUtils::MacToAuxDetID(uint8_t mac, int chan)
223 {
224  char type = MacToType(mac);
225  int pos=1;
226 
227 
228  /*
229  if(type=='m'){
230  if (chan >=0 && chan < 12) pos = 1;
231  else if (chan >=12 && chan < 22) pos = 2;
232  else if (chan >=22 && chan < 32) pos = 3;
233  //else pos = 1;
234  }
235  */
236  if(type=='m') pos = chan/10 + 1;
237 
238 
239 
240  if(fFebToAuxDetId.find(mac)==fFebToAuxDetId.end()) {
241  throw cet::exception("CRTCommonUtils::MacToAuxDetID")
242  << "unknown mac passed to function";
243  }
244 
245 
246  for(auto const& adid : fFebToAuxDetId[mac]) {
247 
248  if(fAuxDetIdToChanGroup.find(adid)==fAuxDetIdToChanGroup.end()){
249  throw cet::exception("CRTCommonUtils::ADMacToChanGroup")
250  << "unknown AuxDetID passed to function";
251  }
252 
253 
254  //std::cout << "mac: " << (int)mac << " ,module number " << adid << ", pos " << fAuxDetIdToChanGroup[adid]
255  // << ", chan " << chan <<", pos to match " << pos << std::endl;
256  //std::cout << " good upto Step 1" << std::endl;
257  /*
258  if (mac == 49 && pos == 3){
259  // std::cout << " good upto Step 2" << std::endl;
260  continue;
261  } else if (fAuxDetIdToChanGroup[adid]==pos){
262  //std::cout << " good upto Step 3" << std::endl;
263  return adid;
264  } else {
265  //std::cout << " good upto Step 4" << std::endl;
266  return 0;
267  }
268 
269  */
270 
271  if (fAuxDetIdToChanGroup[adid]==pos){
272  return adid;
273  }
274  // std::cout << "mac: " << (int)mac << ", chan " << chan << ", pos " << pos << ", adid " << adid<< std::endl;
275  }
276 
277  // std::cout << "------------------------- mac: " << (int)mac << ", chan " << chan << ", pos " << pos << std::endl;
278 
279  throw cet::exception("CRTCommonUtils::MacToAuxDetID")
280  << "AuxDetID not found!";
281 
282 }
283 
284 //-----------------------------------------------------------------------
285 //returns average 4-position in the scintillator strip
286 //ROOT::Math::XYZTVector
288  double x = 0.5*(ide.entryX + ide.exitX);
289  double y = 0.5*(ide.entryY + ide.exitY);
290  double z = 0.5*(ide.entryZ + ide.exitZ);
291  double t = 0.5*(ide.entryT + ide.exitT);
292  //ROOT::Math::XYZTVector
293  TLorentzVector v(x,y,z,t);
294 
295  return v;
296 }
297 
298 //-----------------------------------------------------------------------
299 //returns the path length in the scintillator strip
301  double dx=0., dy=0., dz=0.;
302  dx = ide.entryX - ide.exitX;
303  dy = ide.entryY - ide.exitY;
304  dz = ide.entryZ - ide.exitZ;
305  return sqrt(dx*dx+dy*dy+dz*dz);
306 }
307 
308 //----------------------------------------------------------------------
310  int layer = -1;
311 
312  auto const& adGeo = fGeoService->AuxDet(adsc.AuxDetID());
313  auto const& adsGeo = adGeo.SensitiveVolume(adsc.AuxDetSensitiveID());
314  int region = AuxDetRegionNameToNum(GetAuxDetRegion(adsc.AuxDetID()));
315  char type = GetAuxDetType(adsc.AuxDetID());
316 
317  std::set<string> volNames = { adsGeo.TotalVolume()->GetName() };
318  vector<vector<TGeoNode const*> > paths = fGeoService->FindAllVolumePaths(volNames);
319 
320  std::string path = "";
321  for (size_t inode=0; inode<paths.at(0).size(); inode++) {
322  path += paths.at(0).at(inode)->GetName();
323  if (inode < paths.at(0).size() - 1) {
324  path += "/";
325  }
326  }
327  TGeoManager* manager = fGeoService->ROOTGeoManager();
328  manager->cd(path.c_str());
329  TGeoNode* nodeStrip = manager->GetCurrentNode();
330  TGeoNode* nodeInner = manager->GetMother(1);
331  TGeoNode* nodeModule = manager->GetMother(2);
332  double origin[3] = {0, 0, 0};
333  double modulePosMother[3]; //position in CRT region volume
334  double stripPosMother[3]; // strip position in module frame
335  double stripPosModule[3];
336 
337  nodeModule->LocalToMaster(origin, modulePosMother);
338  nodeStrip->LocalToMaster(origin, stripPosMother);
339  nodeInner->LocalToMaster(stripPosMother,stripPosModule);
340 
341  //if 'c' or 'd' type
342  if ( type == 'c' || type == 'd' )
343  layer = (stripPosModule[1] > 0);
344 
345  // if 'm' type
346  if ( type == 'm' ) {
347  // if east or west stacks (6 in total)
348  if ( region >=40 && region <=45 ) {
349  layer = ( modulePosMother[0]>0 );
350  }
351  // if north stack
352  if ( region == 47) {
353  layer = ( modulePosMother[2]> 0 );
354  }
355  // if south stack
356  if( region == 46) {
357  auto const& adsGeo = adGeo.SensitiveVolume(0);
358  // if(adsGeo.Length() < 500) //is cut module?
359  if(adsGeo.Length() == 400 || adsGeo.Length() == 485.15) //is cut module?
360  layer = 1;
361  else
362  layer = 0;
363  }
364  }
365 
366  return layer;
367 
368 }
369 
370 //----------------------------------------------------------------------
371 int CRTCommonUtils::GetLayerID(const art::Ptr<sim::AuxDetSimChannel> adsc){
372  int layer = -1;
373 
374  auto const& adGeo = fGeoService->AuxDet(adsc->AuxDetID());
375  auto const& adsGeo = adGeo.SensitiveVolume(adsc->AuxDetSensitiveID());
376  int region = AuxDetRegionNameToNum(GetAuxDetRegion(adsc->AuxDetID()));
377  char type = GetAuxDetType(adsc->AuxDetID());
378 
379  std::set<string> volNames = { adsGeo.TotalVolume()->GetName() };
380  vector<vector<TGeoNode const*> > paths = fGeoService->FindAllVolumePaths(volNames);
381 
382  std::string path = "";
383  for (size_t inode=0; inode<paths.at(0).size(); inode++) {
384  path += paths.at(0).at(inode)->GetName();
385  if (inode < paths.at(0).size() - 1) {
386  path += "/";
387  }
388  }
389  TGeoManager* manager = fGeoService->ROOTGeoManager();
390  manager->cd(path.c_str());
391  TGeoNode* nodeStrip = manager->GetCurrentNode();
392  TGeoNode* nodeInner = manager->GetMother(1);
393  TGeoNode* nodeModule = manager->GetMother(2);
394  double origin[3] = {0, 0, 0};
395  double modulePosMother[3]; //position in CRT region volume
396  double stripPosMother[3]; // strip position in module frame
397  double stripPosModule[3];
398 
399  nodeModule->LocalToMaster(origin, modulePosMother);
400  nodeStrip->LocalToMaster(origin, stripPosMother);
401  nodeInner->LocalToMaster(stripPosMother,stripPosModule);
402 
403  //if 'c' or 'd' type
404  if ( type == 'c' || type == 'd' )
405  layer = (stripPosModule[1] > 0);
406 
407  // if 'm' type
408  if ( type == 'm' ) {
409  // if east or west stacks (6 in total)
410  if ( region >=40 && region <=45 ) {
411  layer = ( modulePosMother[0]>0 );
412  }
413  // if north stack
414  if ( region == 47) {
415  layer = ( modulePosMother[2]> 0 );
416  }
417  // if south stack
418  if( region == 46) {
419  //if(adsGeo.Length() < 500) //is cut module?
420  if(adsGeo.Length() == 400 || adsGeo.Length() == 485.15) //is cut module?
421  layer = 1;
422  else
423  layer = 0;
424  }
425  }
426 
427  return layer;
428 
429 }
430 
431 //--------------------------------------------------------------------------------------------------
433  int layer = -1;
434 
435  int region = AuxDetRegionNameToNum(GetAuxDetRegion(adid));
436  char type = GetAuxDetType(adid);
437  auto const& adGeo = fGeoService->AuxDet(adid);
438  if(type!='m') {
439  mf::LogError("CRTCommonUtils") << "non-MINOS module provided to GetMINOSLayerID";
440  return layer;
441  }
442 
443  std::set<string> volNames = { adGeo.TotalVolume()->GetName() };
444  vector<vector<TGeoNode const*> > paths = fGeoService->FindAllVolumePaths(volNames);
445 
446  std::string path = "";
447  for (size_t inode=0; inode<paths.at(0).size(); inode++) {
448  path += paths.at(0).at(inode)->GetName();
449  if (inode < paths.at(0).size() - 1) {
450  path += "/";
451  }
452  }
453  TGeoManager* manager = fGeoService->ROOTGeoManager();
454  manager->cd(path.c_str());
455  TGeoNode* nodeModule = manager->GetCurrentNode(); //Mother(2);
456  double origin[3] = {0, 0, 0};
457  double modulePosMother[3]; //position in CRT region volume
458  nodeModule->LocalToMaster(origin, modulePosMother);
459 
460  // if east or west stacks (6 in total)
461  if ( region >=40 && region <=45 ) {
462  layer = ( modulePosMother[0]>0 );
463  }
464  // if north stack
465  if ( region == 47) {
466  layer = ( modulePosMother[2]> 0 );
467  }
468  // if south stack
469  if( region == 46) {
470  auto const& adsGeo = adGeo.SensitiveVolume(0);
471  if(adsGeo.Length() == 400 || adsGeo.Length() == 485.15) //is cut module?
472  // if(adsGeo.Length() < 500) //is cut module?
473  layer = 1;
474  else
475  layer = 0;
476  }
477 
478  if(layer==-1)
479  mf::LogError("CRTCommonUtils::GetMINOSLayerID")
480  << "layer ID not set!";
481 
482  return layer;
483 
484 
485 }
486 
487 //--------------------------------------------------------------------------------------------------
488 // given mac address and mac channel, return CRT strip center in module coordinates (w.r.t. module center)
489 TVector3 CRTCommonUtils::ChanToLocalCoords(uint8_t mac, int chan) {
490 
491  TVector3 coords(0.,0.,0.);
492  size_t adid = MacToAuxDetID(mac,chan); //CRT module ID
493  auto const& adGeo = fGeoService->AuxDet(adid); //CRT module
494  int adsid = ChannelToAuxDetSensitiveID(mac,chan); //CRT strip ID
495  auto const& adsGeo = adGeo.SensitiveVolume(adsid); //CRT strip
496 
497  double origin[3] = {0,0,0};
498  double stripPosWorld[3], modPos[3];
499 
500  adsGeo.LocalToWorld(origin,stripPosWorld);
501  adGeo.WorldToLocal(stripPosWorld,modPos);
502 
503  coords.SetXYZ(modPos[0],modPos[1],modPos[2]);
504  return coords;
505 }
506 
507 //--------------------------------------------------------------------------------------------------
508 // given mac address and mac channel, return CRT strip center in World coordinates (w.r.t. LAr active volume center)
509 TVector3 CRTCommonUtils::ChanToWorldCoords(uint8_t mac, int chan) {
510 
511  TVector3 coords(0.,0.,0.);
512  int adid = MacToAuxDetID(mac,chan); //CRT module ID
513  auto const& adGeo = fGeoService->AuxDet(adid); //CRT module
514  int adsid = ChannelToAuxDetSensitiveID(mac,chan); //CRT strip ID
515  auto const& adsGeo = adGeo.SensitiveVolume(adsid); //CRT strip
516 
517  double origin[3] = {0,0,0};
518  double stripPosWorld[3];
519 
520  adsGeo.LocalToWorld(origin,stripPosWorld);
521 
522  coords.SetXYZ(stripPosWorld[0],stripPosWorld[1],stripPosWorld[2]);
523  return coords;
524 }
525 
526 //--------------------------------------------------------------------------------------
527 //reads a file generated by CRT geometry generation script and
528 // fills a map modID->vector<pair<FEB, FEB channel subset>,+1 dual readoutfor MINOS module>
529 // channel subset = 1,2,or 3 (always =1 for c or d modules)
531 
532  string fullFileName;// = "/icarus/app/users/chilgenb/ana_icaruscode_v08_52_00/feb_map.txt";
533  cet::search_path searchPath("FW_SEARCH_PATH");
534  searchPath.find_file("feb_map.txt",fullFileName);
535  std::ifstream fin;
536  fin.open(fullFileName,std::ios::in);
537 
538  if(!fin.good())
539 // std::cout << "opened file 'feb_map.txt' for reading..." << std::endl;
540 // else
541  throw cet::exception("CRTDetSim::FillFebMap")
542  << "Unable to find/open file 'feb_map.txt'" << std::endl;
543 
544  vector<string> row;
545  string line, word;
546  //each line has pattern
547  // auxDetID, mac5, chan pos, '\n' (CERN, DC, cut MINOS) OR
548  // auxDetID, mac5, chan pos, mac5', chan pos', '\n' (full length MINOS)
549  while(getline(fin,line)) {
550  row.clear();
551  std::stringstream s(line);
552  while (std::getline(s, word, ',')) { //parse line
553  row.push_back(word);
554  }
555  int mod = (size_t)std::stoi(row[0]); //auxDetID
556  uint8_t mac5 = (uint8_t)std::stoi(row[1]); //febID
557  int pos = std::stoi(row[2]); //feb channel block
558  fAuxDetIdToFeb[mod].push_back(std::make_pair(mac5,pos));
559  fAuxDetIdToChanGroup[mod]=pos;
560  fFebToAuxDetId[mac5].push_back(mod);
561 // std::cout << "mod: " << mod << ", mac: " << (int)mac5 << ", pos: " << pos;
562  if(row.size()>3) { //if dual ended readout MINOS module
563  mac5 = (uint8_t)std::stoi(row[3]);
564  fAuxDetIdToFeb[mod].push_back(std::make_pair(mac5,pos));
565  fFebToAuxDetId[mac5].push_back(mod);
566 // if(pos!=std::stoi(row[4])) //feb channel block same on both febs
567 // std::cout << "WARNING in CRTComUtil: 2 unique chan groups for ADId!" << std::endl;
568 // std::cout << ", mac: " << (int)mac5;
569  }
570 // std::cout << std::endl;
571  }
572 // std::cout << "filled febMap with " << fAuxDetIdToFeb.size() << " entries" << std::endl;
573  fin.close();
574 }
575 
576 //------------------------------------------------------------------------
578 
579  for(auto const& ad : fAuxDetIdToFeb){
580  auto const& adGeo = fGeoService->AuxDet(ad.first);
581 
582  //AuxDetType
583  switch(adGeo.NSensitiveVolume()) {
584  case 16:
585  fAuxDetIdToType[ad.first] = 'c';
586  break;
587  case 20:
588  fAuxDetIdToType[ad.first] = 'm';
589  break;
590  case 64:
591  fAuxDetIdToType[ad.first] = 'd';
592  break;
593  }
594 
595  //AuxDet region
596  string name = adGeo.TotalVolume()->GetName();
597  fNameToAuxDetId[name] = ad.first;
598  fAuxDetIdToRegion[ad.first] = AuxDetNameToRegion(name);
599  }
600 
601 }
602 
603 //--------------------------------------------------------------------
605 
606  string base("volAuxDet_");
607  const char type = fAuxDetIdToType[fNameToAuxDetId[name]];
608 
609  switch( type ){
610  case 'c' : base+= "CERN"; break;
611  case 'd' : base+= "DC"; break;
612  case 'm' : base+= "MINOS"; break;
613  default :
614  throw cet::exception("CRTCommonUtils::Constructor::AuxDetNameToRegion")
615  << "AuxDet type not set!";
616  }
617  base+="_module_###_";
618 
619  //module name has 2 possible formats
620  // volAuxDet_<subsystem>_module_###_<region>
621  // volAuxDet_<subsystem>_module_###_cut###_<region>
622  string region(name.substr(base.length(),name.length()));
623  if( region.find("_")==string::npos)
624  return region;
625 
626  else
627  return region.substr(region.find("_")+1,region.length());
628 }
629 
630 //--------------------------------------------------------------------------
631 TVector3 CRTCommonUtils::WorldToModuleCoords(TVector3 point, size_t adid) {
632 
633  char type = GetAuxDetType(adid);
634  auto const& adGeo = fGeoService->AuxDet(adid);
635  double world[3], local[3];
636  world[0] = point.X();
637  world[1] = point.Y();
638  world[2] = point.Z();
639 
640  adGeo.WorldToLocal(world,local);
641  TVector3 localpoint(local[0],local[1],local[2]);
642 
643  if(type=='c') {
644  localpoint.SetX( 8.*(localpoint.X()/adGeo.HalfWidth1()+1.));
645  localpoint.SetY(0);
646  localpoint.SetZ( 8.*(localpoint.Z()/adGeo.HalfWidth1()+1.));
647  return localpoint;
648  }
649  if(type=='m') { //needs fixing
650  localpoint.SetX(0);
651  localpoint.SetY(ADToChanGroup(adid)*10.*(localpoint.Y()/adGeo.HalfHeight()+1.));
652  localpoint.SetZ(localpoint.Z());
653  return localpoint;
654  }
655  if(type=='d') {
656  localpoint.SetX(32.5*(localpoint.X()/adGeo.HalfWidth1()+1.));
657  localpoint.SetY(0);
658  localpoint.SetZ(localpoint.Z());
659  return localpoint;
660  }
661 
662  return localpoint;
663 }
664 
665 // Simple distance of closest approach between infinite track and centre of hit
666 double CRTCommonUtils::SimpleDCA(sbn::crt::CRTHit hit, TVector3 start, TVector3 direction){
667 
668  TVector3 pos (hit.x_pos, hit.y_pos, hit.z_pos);
669  TVector3 end = start + direction;
670  double denominator = direction.Mag();
671  double numerator = (pos - start).Cross(pos - end).Mag();
672  return numerator/denominator;
673 
674 }
675 
676 // Minimum distance from infinite track to CRT hit assuming that hit is a 2D square
677 double CRTCommonUtils::DistToCrtHit(sbn::crt::CRTHit hit, TVector3 start, TVector3 end){
678 
679  // Check if track goes inside hit
680  TVector3 min (hit.x_pos - hit.x_err, hit.y_pos - hit.y_err, hit.z_pos - hit.z_err);
681  TVector3 max (hit.x_pos + hit.x_err, hit.y_pos + hit.y_err, hit.z_pos + hit.z_err);
682  if(CubeIntersection(min, max, start, end).first.X() != -99999) return 0;
683 
684  // Calculate the closest distance to each edge of the CRT hit
685  // Assume min error is the fixed position of tagger
686  TVector3 vertex1 (hit.x_pos, hit.y_pos - hit.y_err, hit.z_pos - hit.z_err);
687  TVector3 vertex2 (hit.x_pos, hit.y_pos + hit.y_err, hit.z_pos - hit.z_err);
688  TVector3 vertex3 (hit.x_pos, hit.y_pos - hit.y_err, hit.z_pos + hit.z_err);
689  TVector3 vertex4 (hit.x_pos, hit.y_pos + hit.y_err, hit.z_pos + hit.z_err);
690  if(hit.y_err < hit.x_err && hit.y_err < hit.z_err){
691  vertex1.SetXYZ(hit.x_pos - hit.x_err, hit.y_pos, hit.z_pos - hit.z_err);
692  vertex2.SetXYZ(hit.x_pos + hit.x_err, hit.y_pos, hit.z_pos - hit.z_err);
693  vertex3.SetXYZ(hit.x_pos - hit.x_err, hit.y_pos, hit.z_pos + hit.z_err);
694  vertex4.SetXYZ(hit.x_pos + hit.x_err, hit.y_pos, hit.z_pos + hit.z_err);
695  }
696  if(hit.z_err < hit.x_err && hit.z_err < hit.y_err){
697  vertex1.SetXYZ(hit.x_pos - hit.x_err, hit.y_pos - hit.y_err, hit.z_pos);
698  vertex2.SetXYZ(hit.x_pos + hit.x_err, hit.y_pos - hit.y_err, hit.z_pos);
699  vertex3.SetXYZ(hit.x_pos - hit.x_err, hit.y_pos + hit.y_err, hit.z_pos);
700  vertex4.SetXYZ(hit.x_pos + hit.x_err, hit.y_pos + hit.y_err, hit.z_pos);
701  }
702 
703  double dist1 = LineSegmentDistance(vertex1, vertex2, start, end);
704  double dist2 = LineSegmentDistance(vertex1, vertex3, start, end);
705  double dist3 = LineSegmentDistance(vertex4, vertex2, start, end);
706  double dist4 = LineSegmentDistance(vertex4, vertex3, start, end);
707 
708  return std::min(std::min(dist1, dist2), std::min(dist3, dist4));
709 
710 }
711 
712 
713 // Distance between infinite line (2) and segment (1)
714 // http://geomalgorithms.com/a07-_distance.html
715 double CRTCommonUtils::LineSegmentDistance(TVector3 start1, TVector3 end1, TVector3 start2, TVector3 end2){
716 
717  double smallNum = 0.00001;
718 
719  // 1 is segment
720  TVector3 direction1 = end1 - start1;
721  // 2 is infinite line
722  TVector3 direction2 = end2 - start2;
723 
724  TVector3 u = direction1;
725  TVector3 v = direction2;
726  TVector3 w = start1 - start2;
727 
728  double a = u.Dot(u);
729  double b = u.Dot(v);
730  double c = v.Dot(v);
731  double d = u.Dot(w);
732  double e = v.Dot(w);
733  double D = a * c - b * b;
734  double sc, sN, sD = D; // sc = sN/sD
735  double tc, tN, tD = D; // sc = sN/sD
736 
737  // Compute the line parameters of the two closest points
738  if(D < smallNum){ // Lines are almost parallel
739  sN = 0.0;
740  sD = 1.0;
741  tN = e;
742  tD = c;
743  }
744  else{
745  sN = (b * e - c * d)/D;
746  tN = (a * e - b * d)/D;
747  if(sN < 0.){ // sc < 0, the s = 0 edge is visible
748  sN = 0.;
749  tN = e;
750  tD = c;
751  }
752  else if(sN > sD){ // sc > 1, the s = 1 edge is visible
753  sN = sD;
754  tN = e + b;
755  tD = c;
756  }
757  }
758 
759  sc = (std::abs(sN) < smallNum ? 0.0 : sN / sD);
760  tc = (std::abs(tN) < smallNum ? 0.0 : tN / tD);
761  // Get the difference of the two closest points
762  TVector3 dP = w + (sc * u) - (tc * v);
763 
764  return dP.Mag();
765 
766 }
767 
768 // Intersection between axis-aligned cube and infinite line
769 // (https://www.scratchapixel.com/lessons/3d-basic-rendering/minimal-ray-tracer-rendering-simple-shapes/ray-box-intersection)
770 std::pair<TVector3, TVector3> CRTCommonUtils::CubeIntersection(TVector3 min, TVector3 max, TVector3 start, TVector3 end){
771 
772  TVector3 dir = (end - start);
773  TVector3 invDir (1./dir.X(), 1./dir.Y(), 1/dir.Z());
774 
775  double tmin, tmax, tymin, tymax, tzmin, tzmax;
776 
777  TVector3 enter (-99999, -99999, -99999);
778  TVector3 exit (-99999, -99999, -99999);
779 
780  // Find the intersections with the X plane
781  if(invDir.X() >= 0){
782  tmin = (min.X() - start.X()) * invDir.X();
783  tmax = (max.X() - start.X()) * invDir.X();
784  }
785  else{
786  tmin = (max.X() - start.X()) * invDir.X();
787  tmax = (min.X() - start.X()) * invDir.X();
788  }
789 
790  // Find the intersections with the Y plane
791  if(invDir.Y() >= 0){
792  tymin = (min.Y() - start.Y()) * invDir.Y();
793  tymax = (max.Y() - start.Y()) * invDir.Y();
794  }
795  else{
796  tymin = (max.Y() - start.Y()) * invDir.Y();
797  tymax = (min.Y() - start.Y()) * invDir.Y();
798  }
799 
800  // Check that it actually intersects
801  if((tmin > tymax) || (tymin > tmax)) return std::make_pair(enter, exit);
802 
803  // Max of the min points is the actual intersection
804  if(tymin > tmin) tmin = tymin;
805 
806  // Min of the max points is the actual intersection
807  if(tymax < tmax) tmax = tymax;
808 
809  // Find the intersection with the Z plane
810  if(invDir.Z() >= 0){
811  tzmin = (min.Z() - start.Z()) * invDir.Z();
812  tzmax = (max.Z() - start.Z()) * invDir.Z();
813  }
814  else{
815  tzmin = (max.Z() - start.Z()) * invDir.Z();
816  tzmax = (min.Z() - start.Z()) * invDir.Z();
817  }
818 
819  // Check for intersection
820  if((tmin > tzmax) || (tzmin > tmax)) return std::make_pair(enter, exit);
821 
822  // Find final intersection points
823  if(tzmin > tmin) tmin = tzmin;
824 
825  // Find final intersection points
826  if(tzmax < tmax) tmax = tzmax;
827 
828  // Calculate the actual crossing points
829  double xmin = start.X() + tmin * dir.X();
830  double xmax = start.X() + tmax * dir.X();
831  double ymin = start.Y() + tmin * dir.Y();
832  double ymax = start.Y() + tmax * dir.Y();
833  double zmin = start.Z() + tmin * dir.Z();
834  double zmax = start.Z() + tmax * dir.Z();
835 
836  // Return pair of entry and exit points
837  enter.SetXYZ(xmin, ymin, zmin);
838  exit.SetXYZ(xmax, ymax, zmax);
839  return std::make_pair(enter, exit);
840 
841 }
842 
843 
844 #endif
float z_err
position uncertainty in z-direction (cm).
Definition: CRTHit.hh:43
std::pair< TVector3, TVector3 > CubeIntersection(TVector3 min, TVector3 max, TVector3 start, TVector3 end)
process_name opflash particleana ie ie ie z
float x_err
position uncertainty in x-direction (cm).
Definition: CRTHit.hh:39
Utilities related to art service access.
process_name opflash particleana ie x
AuxDetSensitiveGeo const & SensitiveVolume(size_t sv) const
Definition: AuxDetGeo.h:171
float y_err
position uncertainty in y-direction (cm).
Definition: CRTHit.hh:41
process_name hit
Definition: cheaterreco.fcl:51
TGeoManager * ROOTGeoManager() const
Access to the ROOT geometry description manager.
double SimpleDCA(sbn::crt::CRTHit hit, TVector3 start, TVector3 direction)
process_name gaushit a
float exitY
Exit position Y of particle.
process_name pandoraGausCryo1 vertexChargeCryo1 vertexStubCryo1 xmin
BEGIN_PROLOG triggeremu_data_config_icarus settings PMTADCthresholds sequence::icarus_stage0_multiTPC_TPC physics sequence::icarus_stage0_EastHits_TPC physics sequence::icarus_stage0_WestHits_TPC physics producers purityana0 caloskimCalorimetryCryoE physics caloskimCalorimetryCryoW physics path
then local
Collection of particles crossing one auxiliary detector cell.
float z_pos
position in z-direction (cm).
Definition: CRTHit.hh:42
T abs(T value)
process_name opflash particleana ie ie y
uint32_t AuxDetID() const
float entryT
Entry time of particle.
float exitT
Exit time of particle.
auto end(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:585
TVector3 ChanToLocalCoords(const uint8_t mac, const int chan)
float exitZ
Exit position Z of particle.
process_name west layer
Definition: crt_ana.fcl:40
float entryZ
Entry position Z of particle.
float exitX
Exit position X of particle.
AuxDetGeo const & AuxDet(unsigned int const ad=0) const
Returns the specified auxiliary detector.
tuple dir
Definition: dropbox.py:28
float y_pos
position in y-direction (cm).
Definition: CRTHit.hh:40
float entryX
Entry position X of particle.
double LineSegmentDistance(TVector3 start1, TVector3 end1, TVector3 start2, TVector3 end2)
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
uint32_t AuxDetSensitiveID() const
float x_pos
position in x-direction (cm).
Definition: CRTHit.hh:38
TVector3 ChanToWorldCoords(const uint8_t mac, const int chan)
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.
do i e
then echo fcl name
std::vector< std::vector< TGeoNode const * > > FindAllVolumePaths(std::set< std::string > const &vol_names) const
Returns paths of all nodes with volumes with the specified names.
double DistToCrtHit(sbn::crt::CRTHit hit, TVector3 start, TVector3 end)
process_name crt
map< size_t, vector< pair< uint8_t, int > > > fAuxDetIdToFeb
constexpr Point origin()
Returns a origin position with a point of the specified type.
Definition: geo_vectors.h:227