All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
icaruscode/icaruscode/CRT/CRTChannelMapAlg.cxx
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////////
2 /// \file CRTChannelMapAlg.cxx
3 /// \brief Algorithm class for ICARUS auxiliary detector channel mapping
4 ///
5 /// Originally ported from AuxDetChannelMapLArIATAlg.cxx (Author: brebel@fnal.gov)
6 /// and modified for SBND (Author: mastbaum@uchicago.edu) then ICARUS
7 /// \version $Id: 0.0 $
8 /// \author chilge@rams.colostate.edu
9 ///////////////////////////////////////////////////////////////////////////////
10 
11 #include "art/Framework/Services/Registry/ServiceHandle.h"
12 #include "messagefacility/MessageLogger/MessageLogger.h"
17 #include "TVector3.h"
18 #include <iostream>
19 #include <ostream>
20 #include <vector>
21 
22 //namespace icarus{
23 //namespace crt {
24 namespace geo {
25 
26 
27  //---------------------------------------------------------------------------
29  fhicl::ParameterSet const& p)
30  : fSorter(geo::CRTGeoObjectSorter(p)) {}
31 
32  //---------------------------------------------------------------------------
34  Uninitialize();
35 
36  std::vector<geo::AuxDetGeo>& adgeo = geodata.auxDets;
37  std::vector<geo::AuxDetGeo*> adgeo_copy;
38  for (size_t i=0; i<adgeo.size(); i++) adgeo_copy.push_back(&adgeo[i]);
39 
40  // Sort the AuxDetGeo objects and map them to names of the detectors
41  // (SBN workshop 19 March) seemed to cause some problems for SBND folks --comment out?
42  // fSorter.SortAuxDets(adgeo);
43 
44  // for (size_t a=0; a<adgeo.size(); a++){
45  // std::cout << "module number: " << a << " volname: " << adgeo[a].TotalVolume()->GetName() << std::endl;
46  // }
47 
48  fSorter.SortCRTs(adgeo);
49 
50  /*
51  for (size_t i=0; i<adgeo.size(); i++) {
52  std::cout << "i: " << i
53  << " | name1: " << adgeo[i].TotalVolume()->GetName()
54  << " | name2: " << adgeo_copy[i]->TotalVolume()->GetName() << std::endl;
55  }
56  */
57 
58 
59  // Map the AuxDetGeo names to their position in the sorted vector
60  //
61  // The ICARUS CRT is composed of three subsystems
62  // (1) The top and 'eaves' portion is new construction from CERN/Bologna.
63  // Each module consists of two layers of 8 strips in an X-Y configuration.
64  // Each strip contains 2 fibers read out seperately for a total of 32 channels/module.
65  // Each module is read out by a single CAEN front-end board (same as SBND, uBooNE).
66  // (2) The sides are made up of MINOS modules. Each module consists of 1 layer of 20 strips.
67  // Each strip contains a single fiber read out at both ends. 2 strips are optically
68  // ganged on a single SiPM on each end for a total of 20 channels/module. A single end
69  // of 3 modules are read out by a single CAEN front-end board.
70  // (3) The bottom is made up of Double Chooz veto modules. Each module consists of two layers of
71  // 32 strips in an X-X configuration with the layers laterally offset by 0.5*(strip width).
72  // Each strip contains a single fiber read out at a single end by an M64 PMT for a total of
73  // 64 channels / module. The front-end electronics are different from the subsystems 1 & 2.
74  //
75  // In the geometry, CRT modules are AuxDets and CRT strips are the
76  // AuxDetSensitives. Each strip has one-two SiPM channels depending on module
77  // type, one per optical fiber (not in the geometry).
78  //
79  // Top: 84 modules, 1344 strips, 2688 channels
80  // Front, back eaves: 6 modules, 96 strips, 192 channels
81  // Left, right eaves: 13 modules, 208 strips, 416 channels
82  // Front, back sides: 20 modules, 400 strips, 400 channels
83  // Left, right sides: 54 modules, 1080 strips, 1080 channels
84  // Bottom: 14 modules, 896 strips, 896 channels
85  //
86  // Total: 284 modules, 5808 strips, 7760 channels
87  // CERN type: 122 modules, 122 FEBs, 3904 channels: 4052-7956
88  // MINOS type: 148 modules, 100 FEBs, 2960 channels: 0-3155 (2 channels/FEB not used)
89  // DblCh type: 14 modules, 14 FEBs, 896 channels: 3156-4051
90 
91  fADGeoToName.clear();
92  fADGeoToChannelAndSV.clear();
93 
94 
95 
96  int chID = 0;
97 
98  //loop over modules
99  for (size_t a=0; a<adgeo.size(); a++){
100 
101  std::string volName(adgeo[a].TotalVolume()->GetName());
102 
103  // define a list of pair of sensitive volume ID and sensitive volume
104  // we are making a pair because the sorted strip number is necessary
105  // while assigning each strip number to a channelID.
106  std::vector<std::pair<int, geo::AuxDetSensitiveGeo> > adslist;
107 
108  //get number of strips in this module
109  size_t nsv = adgeo[a].NSensitiveVolume();
110 
111  // make a pair of sensitive volume ID and sensitive volume
112  for(int isv = 0; isv < (int)nsv; isv++ ){
113  adslist.push_back(std::make_pair(isv,adgeo[a].SensitiveVolume(isv)));
114  //std::cout << isv << "\t" << std::endl;
115  }
116  // std::cout << " before sort................. \t" << std::endl;
117  //for (size_t a=0; a<adslist.size(); a++){
118  //std::cout << adslist[a].first << "\t" << std::endl;
119  //}
120  // sort the sensitive volume inside a module
121  fSorter.SortCRTSensitive(adslist);
122  //std::cout << " after sort..................... \t" << std::endl;
123  //for (size_t a=0; a<adslist.size(); a++){
124  //std::cout << adslist[a].first << "\t" << std::endl;
125  //}
126 
127  if (nsv != 20 && nsv !=16 && nsv != 64) {
128  throw cet::exception("CRTChannelMap")
129  << "Wrong number of sensitive volumes for CRT volume "
130  << volName << " (got " << nsv << ", expected 20, 16 or 64)" << std::endl;
131  }//if strip number correct
132 
133  fADGeoToName[a] = volName;
134  fNameToADGeo[volName] = a;
135 
136 
137  //-------------------------------------------------------
138 
139  // Example string
140  std::string str = volName;
141 
142  // For atoi, the input string has to start with a digit, so lets search for the first digit
143  size_t i = 0;
144  for ( ; i < str.length(); i++ ){ if ( std::isdigit(str[i]) ) break; }
145 
146  // remove the first chars, which aren't digits
147  str = str.substr(i, str.length() - i );
148 
149  // convert the remaining text to an integer
150  int id = std::atoi(str.c_str());
151 
152  //-------------------------------------------------------
153 
154 
155  //if volume is a module, not a strip (search doesn't hit end)
156  if (volName.find("volAuxDet_") != std::string::npos) {
157  //loop over strips
158  //for (size_t svID=0; svID<nsv; svID++) {
159  //std::cout<< "hello << -------------------------- >> " << std::endl;
160  //CERN modules
161  if (nsv==16){
162  for (size_t svID=0; svID<16; svID++) {
163  //each strip has 2 fibers, 1 SiPM per fiber at the same strip end
164  //ch id in range (0,31)
165  for (size_t ich=0; ich<2; ich++) {
166  fADGeoToChannelAndSV[a].push_back(std::make_pair(chID, adslist[svID].first));
167  chID++;
168  //std::cout << " " << a << " \t" << volName << "\t "<< id << " \t" << adslist[svID].first << " \t" << chID << std::endl;
169  }
170  }
171  }
172  //DC modules
173  if (nsv==64){
174  //1 fiber per strip read out at one end
175  for (size_t svID=0; svID<64; svID++) {
176  fADGeoToChannelAndSV[a].push_back(std::make_pair(chID, adslist[svID].first));
177  chID++;
178  // std::cout << "module index | " << a << " volName: | " << volName << "channelno: | " << chID << std::endl;
179  // std::cout << " " << a << " \t" << volName << "\t "<< id << " \t" << adslist[svID].first << " \t" << chID << std::endl;
180  }
181  }
182  //MINOS modules
183  if (nsv==20){
184 
185  for (size_t svID=0; svID<20; svID+=2) {
186  // size_t chID = svID/2 + ich+31; //2 fibers on one SiPM, at both ends, w/different FEBs
187  fADGeoToChannelAndSV[a].push_back(std::make_pair(chID, adslist[svID].first));
188  fADGeoToChannelAndSV[a].push_back(std::make_pair(chID, adslist[svID+1].first));
189  chID++;
190  //std::cout << "module index | " << a << " volName: | " << volName << "\t " << adslist[svID].first << "\t " << adslist[svID+1].first<<" channelno: | " << chID << std::endl;
191  // std::cout << " " << a << " \t" << volName << "\t "<< id << " \t" << adslist[svID].first << " \t" << chID << std::endl;
192 
193  if (adslist[svID].second.Length() == 800){
194  fADGeoToChannelAndSV[a].push_back(std::make_pair(chID, adslist[svID].first));
195  fADGeoToChannelAndSV[a].push_back(std::make_pair(chID, adslist[svID+1].first));
196  chID++;
197 
198  //std::cout << " " << a << " \t" << volName << "\t "<< id << " \t" << adslist[svID].first << " \t" << chID << std::endl;
199 
200  // std::cout << "module index : 800 cm | " << a << " volName: | " << volName << "\t " << adslist[svID].first << "\t " << adslist[svID+1].first << " channelno: | " << chID << std::endl;
201  }
202  }
203 
204 
205  } // if side crt strips
206  //extractIntegerWords(volName);
207 
208 
209 
210  // print the result
211  // std::cout << id << std::endl;
212 
213  // std::cout << "module index " << a << " volName " << volName << " module no "<< id << " channelID: " << chID << std::endl;
214  std::cout << " " << a << " \t" << volName << "\t "<< id << " \t" << chID << std::endl;
215  } //if correct name
216  else {
217  throw cet::exception("CRTChannelMap")
218  << "Unrecognized volume found: " << volName << std::endl;
219  }
220  }//for modules
221 
222  /*
223  for (auto& csvItr : fADGeoToChannelAndSV){
224 
225  for (auto& pairItr : csvItr.second)
226  std::cout << "module index | "<< csvItr.first << " channel: | "<< pairItr.first << " sv: | "<< pairItr.second <<std::endl;
227  }
228  */
229 
230  }//Initialize
231 
232  //----------------------------------------------------------------------------
234 
235  //----------------------------------------------------------------------------
237  double const worldLoc[3],
238  std::vector<geo::AuxDetGeo> const& auxDets,
239  size_t& ad,
240  size_t& sv) const {
241 
242  // Set the default to be that we don't find the position in any AuxDet
243  uint32_t channel = UINT_MAX;
244  //uint32_t channel;
245 
246  // Figure out which detector we are in
247  ad = 0;
248  sv = this->NearestSensitiveAuxDet(worldLoc, auxDets, ad);
249 
250 
251  // Get the origin of the sensitive volume in the world coordinate system
252  double svOrigin[3] = {0, 0, 0};
253  double localOrigin[3] = {0, 0, 0};
254 
255  auxDets[ad].SensitiveVolume(sv).LocalToWorld(localOrigin, svOrigin);
256  // std::cout <<"ad: " << ad << " ,x: "<< svOrigin[0] << " ,y: " << svOrigin[1] << " ,z: "<< svOrigin[2] << std::endl;
257  // std::cout << ad << "\t"<< auxDets[ad].TotalVolume()->GetName() << std::endl;
258  // for (auto& adtoname : fADGeoToName) std::cout << "ad: "<<adtoname.first << " | volname: " << adtoname.second<<std::endl;
259  // Check to see which AuxDet this position corresponds to
260  auto gnItr = fADGeoToName.find(ad);
261  if (gnItr != fADGeoToName.end()){
262  // Get the vector of channel and sensitive volume pairs
263 
264  auto csvItr = fADGeoToChannelAndSV.find(ad);
265 
266  if (csvItr == fADGeoToChannelAndSV.end()) {
267  throw cet::exception("CRTChannelMapAlg")
268  << "No entry in channel and sensitive volume map for AuxDet index "
269  << ad;
270  }
271  //*/
272  /*
273  // N.B. This is the ID on the nth channel, and the strip has n and n+1
274  auto pairItr = std::find_if((csvItr->second).begin(), (csvItr->second).end(),
275  [sv](const std::pair<uint32_t,size_t>& element){ return element.second == sv;} );
276  channel = pairItr->first;
277  */
278  // }
279 
280 
281 
282  for (auto& pairItr : csvItr->second)
283  if (pairItr.second == sv) channel = pairItr.first;
284  }
285 
286  /*if (channel == UINT_MAX) {
287  throw cet::exception("CRTChannelMapAlg")
288  << "position ("
289  << worldLoc[0] << "," << worldLoc[1] << "," << worldLoc[2]
290  << ") does not correspond to any AuxDet";
291  }*/
292 
293  return channel;
294  }
295 
296  //----------------------------------------------------------------------------
298  uint32_t const& channel,
299  std::string const& auxDetName,
300  std::vector<geo::AuxDetGeo> const& auxDets) const {
301  double x = 0;
302  double y = 0;
303  double z = 0;
304 
305  // Figure out which detector we are in
306  size_t ad = UINT_MAX;
307  if (fNameToADGeo.count(auxDetName) > 0) {
308  ad = fNameToADGeo.find(auxDetName)->second;
309  }
310  else {
311  throw cet::exception("CRTChannelMapAlg")
312  << "No AuxDetGeo with name " << auxDetName;
313  }
314 
315  // Get the vector of channel and sensitive volume pairs
316  auto csvItr = fADGeoToChannelAndSV.find(ad);
317 
318  if (csvItr == fADGeoToChannelAndSV.end()) {
319  throw cet::exception("CRTChannelMapAlg")
320  << "No entry in channel and sensitive volume"
321  << " map for AuxDet index " << ad << " bail";
322  }
323 
324  // Loop over the vector of channel and sensitive volumes to determine the
325  // sensitive volume for this channel. Then get the origin of the sensitive
326  // volume in the world coordinate system.
327  double svOrigin[3] = {0, 0, 0};
328  double localOrigin[3] = {0, 0, 0};
329  for (auto csv : csvItr->second) {
330  if (csv.first == channel) {
331  // Get the center of the sensitive volume for this channel
332  auxDets[ad].SensitiveVolume(csv.second).LocalToWorld(localOrigin,
333  svOrigin);
334 
335  x = svOrigin[0];
336  y = svOrigin[1];
337  z = svOrigin[2];
338 
339  break;
340  }
341  }
342 
343  return TVector3(x, y, z);
344  }
345 
346 } // namespace crt
347 //} //namespace icarus
std::map< std::string, size_t > fNameToADGeo
map the names to the AuxDetGeo index
process_name opflash particleana ie ie ie z
void SortCRTSensitive(std::vector< std::pair< int, geo::AuxDetSensitiveGeo > > &adsgeo) const
process_name opflash particleana ie x
Encapsulate the geometry of the sensitive portion of an auxiliary detector.
void Initialize(AuxDetGeometryData_t &geodata) override
std::map< size_t, std::vector< chanAndSV > > fADGeoToChannelAndSV
pdgs p
Definition: selectors.fcl:22
Access the description of auxiliary detector geometry.
process_name gaushit a
uint32_t PositionToAuxDetChannel(double const worldLoc[3], std::vector< geo::AuxDetGeo > const &auxDets, size_t &ad, size_t &sv) const override
process_name opflash particleana ie ie y
void SortCRTs(std::vector< geo::AuxDetGeo > &adgeo) const
geo::CRTGeoObjectSorter fSorter
Class to sort geo objects.
Encapsulate the geometry of an auxiliary detector.
AuxDetList_t auxDets
The auxiliary detectors.
const TVector3 AuxDetChannelToPosition(uint32_t const &channel, std::string const &auxDetName, std::vector< geo::AuxDetGeo > const &auxDets) const override
std::map< size_t, std::string > fADGeoToName
map the AuxDetGeo index to the name
virtual size_t NearestSensitiveAuxDet(const double *point, std::vector< geo::AuxDetGeo > const &auxDets, size_t &ad, double tolerance=0) const
BEGIN_PROLOG could also be cout