CrpGainService_service.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 // Class: CrpGainService
3 // Plugin Type: service (art v3_02_06)
4 // File: CrpGainService_service.cc
5 //
6 // Generated at Thu Nov 7 16:24:55 2019 by Vyacheslav Galymov using cetskelgen
7 // from cetlib version v3_07_02.
8 ////////////////////////////////////////////////////////////////////////
9 
10 #include <iostream>
11 
12 #include "CrpGainService.h"
16 #include "fhiclcpp/ParameterSet.h"
17 
20 
23 
24 #include <TFile.h>
25 #include <TH2F.h>
26 
27 using std::cout;
28 using std::endl;
29 using std::string;
30 
31 // ctor
33 {
34  const string myname = "util::CrpGainService::ctor: ";
35  m_LogLevel = ps.get<int>("LogLevel");
36  m_CrpDefGain = ps.get<double>("CrpDefaultGain");
37  m_CrpNLem = ps.get<unsigned int>("CrpNumLem");
38  m_LemViewChans = ps.get<unsigned int>("LemViewChans");
39  m_LemEffTool = ps.get<string>("LemEffTool");
40 
41  if( !m_LemEffTool.empty() )
42  {
43 
44  // try to load lem transparency map
46  if ( ptm == nullptr )
47  {
48  cout << myname << "Unable to retrieve tool manaager." << endl;
49  }
50  else
51  {
53  if( ! m_plemeff )
54  {
55  cout << myname << "Unable to retrieve lem efficiency tool " << m_LemEffTool << endl;
56  }
57  }
58  }
59  else m_plemeff = nullptr;
60 
61  //
62  m_LemTotChans = m_LemViewChans * m_LemViewChans;
63  m_CrpNLemPerSide = sqrt( m_CrpNLem );
64 
65  m_UseDefGain = ((m_plemeff == nullptr) && (m_lemgainmap.empty()));
66 
67  // geo service
69 
70  if(m_LogLevel >= 1 )
71  {
72  cout<<myname<<"Configurations\n";
73  cout<<myname<<" LogLevel : "<<m_LogLevel<<endl;
74  cout<<myname<<" CrpNominalGain : "<<m_CrpDefGain<<endl;
75  cout<<myname<<" CrpNumLem : "<<m_CrpNLem<<endl;
76  cout<<myname<<" LemViewChans : "<<m_LemViewChans<<endl;
77  cout<<myname<<" LemEffTool : "<<m_LemEffTool<<" (@"<<m_plemeff<<")"<<endl;
78  cout<<myname<<" Use nominal gain : "<<m_UseDefGain<<endl;
79  }
80 
81  if( !checkGeoConfig() && !m_UseDefGain )
82  {
83  throw cet::exception("CrpGainService")
84  << "Bad geometry configuration detected. ";
85  }
86 
87  if( m_plemeff ) {
88  if( m_LemTotChans != m_plemeff->size() ){
89  cout<<myname<<"WARNING the LEM transmission map does not match the expected size."<<endl;
90  }
91  }
92 
93  // dump
94  int nlemeff = ps.get<int>("DumpLemEff", 0);
95  if( nlemeff > 0 ) dumpLemEffMap( nlemeff );
96 
97 } // ctor
98 
99 //
100 //
102 {
103  const string myname = "util::CrpGainService::checkGeoConfig: ";
104 
106  {
107  cout<<myname<<"ERROR the number of LEMs per CRP is non-square\n";
108  return false;
109  }
110 
111  for (geo::TPCID const& tpcid: m_geo->IterateTPCIDs())
112  {
113  const geo::TPCGeo &tpcgeo = m_geo->TPC(tpcid);
114  if(tpcgeo.Nplanes() > 2)
115  {
116  cout<<myname<<"ERROR wrong number of readout planes\n";
117  return false;
118  }
119  //
120  for(unsigned p = 0; p < tpcgeo.Nplanes(); ++p)
121  {
122  const geo::PlaneGeo& plane = tpcgeo.Plane( p );
123  unsigned nwires = plane.Nwires();
124  if( nwires % m_LemViewChans != 0 )
125  {
126  cout<<myname<<"ERROR problem with number of channels per view\n";
127  return false;
128  }
129  }
130  }
131 
132  return true;
133 }
134 
135 
136 //
137 // get view charge
138 double util::CrpGainService::viewCharge( const sim::SimChannel* psc, unsigned itck ) const
139 {
140  const string myname = "util::CrpGainService::viewCharge: ";
141 
142  double q = psc->Charge(itck);
143  if(q <= 1.0E-3) return 0; //if 0 nothing to do -> return 0
144 
145  // default result: divide the charge equally between collection views
146  q *= (0.5 * m_CrpDefGain);
147 
148  // use default gain value given if no other information is provided
149  if( m_UseDefGain ) return q;
150 
151  //
152  // otherwise ...
153 
154  std::vector< geo::WireID > wids = m_geo->ChannelToWire( psc->Channel() );
155  geo::WireID wid = wids[0];
156 
157  // get tpc
158  const geo::TPCGeo& tpcgeo = m_geo->TPC(wid.TPC);
159 
160  // this plane
161  const geo::PlaneGeo& pthis = tpcgeo.Plane( wid.Plane );
162  // wire number in this plane
163  int wire = (int)(wid.Wire);
164 
165  // other plane
166  unsigned widother = 0;
167  if(wid.Plane == 0 ) widother = 1;
168  const geo::PlaneGeo& pother = tpcgeo.Plane( widother );
169 
170  // get drift axis
171  int drift = std::abs(tpcgeo.DetectDriftDirection())-1; //x:0, y:1, z:2
172  int tcoord = -1;
173  if( pthis.View() == geo::kZ )
174  {
175  if( drift == 0 ) tcoord = 1;
176  else if( drift == 1 ) tcoord = 0;
177  }
178  else if( pthis.View() == geo::kX || pthis.View() == geo::kY )
179  {
180  tcoord = 2;
181  }
182 
183  if( m_LogLevel >= 3 )
184  {
185  cout<<myname<<"chan "<<psc->Channel()
186  <<" plane "<<wid.Plane
187  <<" wire "<<wire
188  <<" view "<<pthis.View()
189  <<" viewother "<<pother.View()
190  <<" tcoord "<<tcoord<<endl;
191  }
192 
193  if( tcoord < 0 || (tcoord == 2 && pother.View() != geo::kZ) )
194  {
195  cout<<myname<<"WARNING cannot figure out the coordinate system\n";
196  // return the default value
197  return q;
198  }
199 
200 
201  // get IDEs for this tick
202  std::vector<sim::IDE> IDEs = psc->TrackIDsAndEnergies( itck, itck );
203  if( IDEs.empty() )
204  {
205  cout<<myname<<"WARNING could not get IDEs for tick "<<itck<<endl;
206  return q;
207  }
208 
209  unsigned tpcid = wid.TPC;
210 
211  //
212  double qsum = 0.0;
213  for(auto &ide: IDEs)
214  {
215 
216  // get the wire number in the other view for this position
217  int wother = pother.WireCoordinate( geo::Point_t{ide.x, ide.y, ide.z} );
218  if( wother < 0 || wother >= (int)pother.Nwires() )
219  {
220  cout<<myname<<"WARNING the wire number appeares to be incorrect "<<wother<<"\n";
221  continue;
222  }
223 
224  double G = 0;
225  if( tcoord < 2 ) // we are in view kZ
226  {
227  G = getCrpGain( tpcid, wire, wother );
228  }
229  else // we are in view kX or kY
230  {
231  G = getCrpGain( tpcid, wother, wire );
232  }
233  // the charge is divided equially between collectiong views
234  // so the effective gain per view is 1/2 of the total effective CRP gain
235  qsum += (0.5 * G) * ide.numElectrons;
236  }
237 
238  //if( q != qsum )
239  //cout<<q<<" "<<qsum<<endl;
240 
241  return qsum;
242 }
243 
244 //
245 //
247 {
248  const string myname = "util::CrpGainService::crpGain: ";
249 
250  //geo::Point_t pos(x,y,z);
251  if( m_UseDefGain ) return crpDefaultGain();
252 
253  // get tpc
254  geo::TPCGeo const *tpcgeo = m_geo->PositionToTPCptr( pos );
255 
256  if( !tpcgeo )
257  {
258  cout << myname << "WARNING cannot find the point in a TPC" << endl;
259  return crpDefaultGain();
260  }
261 
262  // get the planes: should be only 2 (see checkGeoConfig)
263  const geo::PlaneGeo& pfirst = tpcgeo->FirstPlane();
264  const geo::PlaneGeo& plast = tpcgeo->LastPlane();
265 
266  //pthis.View() == geo::kX || pthis.View() == geo::kY
267  int ch[2] = {-1, -1};
268 
269  if( pfirst.View() == geo::kZ )
270  {
271  ch[0] = pfirst.WireCoordinate( pos );
272  ch[1] = plast.WireCoordinate( pos );
273 
274  if( ch[0] < 0 || ch[0] >= (int)pfirst.Nwires() )
275  {
276  cout<<myname<<"WARNING the wire number appeares to be incorrect " << endl;
277  return crpDefaultGain();
278  }
279 
280  if( ch[1] < 0 || ch[1] >= (int)plast.Nwires() )
281  {
282  cout<<myname<<"WARNING the wire number appeares to be incorrect " << endl;
283  return crpDefaultGain();
284  }
285  }
286  else if( plast.View() == geo::kZ )
287  {
288  ch[0] = plast.WireCoordinate( pos );
289  ch[1] = pfirst.WireCoordinate( pos );
290 
291  if( ch[0] < 0 || ch[0] >= (int)plast.Nwires() )
292  {
293  cout<<myname<<"WARNING the wire number appeares to be incorrect " << endl;
294  return crpDefaultGain();
295  }
296 
297  if( ch[1] < 0 || ch[1] >= (int)pfirst.Nwires() )
298  {
299  cout<<myname<<"WARNING the wire number appeares to be incorrect " << endl;
300  return crpDefaultGain();
301  }
302  }
303  else
304  {
305  cout<<myname<<"WARNING cannot figure out the coordinate system\n";
306  return crpDefaultGain();
307  }
308 
309  //
310  return getCrpGain( tpcgeo->ID().TPC, ch[0], ch[1] );
311 }
312 
313 
314 //
315 //
316 int util::CrpGainService::getLemId( unsigned crp, int chx, int chy ) const
317 {
318  const string myname = "util::CrpGainService::getLemId: ";
319  int iX = chx / m_LemViewChans;
320  int iY = chy / m_LemViewChans;
321 
322  int id = iY + iX * m_CrpNLemPerSide;
323  if( id >= (int)m_CrpNLem )
324  {
325  cout<<myname<<"WARNING LEM ID exceeds the number of declared LEMs: "
326  <<chx<<" "<<chy<<" "<<iX<<" "<<iY<<" "<<id<<endl;
327  return -1;
328  }
329 
330  // add offset corresponding to the CRP num
331  // which should match the TPCID in geo !
332  id += (int)crp * m_CrpNLem;
333 
334  return id;
335 }
336 
337 
338 //
339 //
340 double util::CrpGainService::getCrpGain( unsigned crp, int chx, int chy) const
341 {
342  // transmission factor (dead areas)
343  double T = getLemTransparency( chx, chy );
344 
345  // gain for this LEM per view
346  double G = getLemGain( getLemId( crp, chx, chy ) );
347 
348  return G*T;
349 }
350 
351 //
352 //
353 double util::CrpGainService::getLemTransparency( int chx, int chy ) const
354 {
355  const string myname = "util::CrpGainService::getLemTransparency: ";
356 
357  // if no map is defined return 1 -> fully transparent
358  if( !m_plemeff ) return 1.0;
359 
360  //
361  if( chx < 0 || chy < 0 ) return 0;
362 
363  // query transparency map
364  unsigned iX = (unsigned)chx % m_LemViewChans;
365  unsigned iY = (unsigned)chy % m_LemViewChans;
366  unsigned idx = iX + iY * m_LemViewChans;
367  if( idx >= m_plemeff->size() ){
368  cout<< myname << "WARNING the index of LEM transmission map is too large"<<endl;
369  }
370 
371  return m_plemeff->value(idx, 0.0);
372 }
373 
374 //
375 // variable gain map for LEM is not implemented yet
376 // so the return is the default gain value
377 double util::CrpGainService::getLemGain( int lemid ) const
378 {
379  // wrong Id return default gain value
380  if( lemid < 0 ) return m_CrpDefGain;
381 
382  // TO DO add variable gain map
383  return m_CrpDefGain;
384 }
385 
386 //
387 //
388 //
390 {
391  const string myname = "util::CrpGainService::dumpLemEffMap: ";
392  cout<<myname<<"Dump LEM efficiecy map for a block "<<nlems<<" x "<<nlems<<"\n";
393  //
394  //if( m_plemeff == nullptr ) return;
395 
396  TFile *fout = TFile::Open("dumplemeffmap.root", "RECREATE");
397  TH2F *hist = new TH2F( "lemeffmap", "lemeffmap",
398  nlems*m_LemViewChans, 0, nlems*m_LemViewChans,
399  nlems*m_LemViewChans, 0, nlems*m_LemViewChans );
400 
401  for( int iy = 0; iy<hist->GetNbinsY(); ++iy){
402  for( int ix = 0; ix<hist->GetNbinsX(); ++ix){
403  hist->SetBinContent(ix+1, iy+1, getLemTransparency( ix, iy ));
404  }
405  }
406  hist->Write();
407  fout->Close();
408 }
409 
410 namespace util{
412 }
geo::TPCID const & ID() const
Returns the identifier of this TPC.
Definition: TPCGeo.h:333
double getCrpGain(unsigned crp, int chx, int chy) const
CrpGainService(fhicl::ParameterSet const &ps, art::ActivityRegistry &areg)
Namespace for general, non-LArSoft-specific utilities.
Energy deposited on a readout channel by simulated tracks.
Definition: SimChannel.h:140
std::string string
Definition: nybbler.cc:12
unsigned int Nplanes() const
Number of planes in this tpc.
Definition: TPCGeo.h:165
Planes which measure X direction.
Definition: geo_types.h:134
Geometry information for a single TPC.
Definition: TPCGeo.h:38
geo::PlaneGeo const & FirstPlane() const
Returns the first wire plane (the closest to TPC center).
Definition: TPCGeo.h:245
geo::TPCGeo const * PositionToTPCptr(geo::Point_t const &point) const
Returns the TPC at specified location.
std::vector< geo::WireID > ChannelToWire(raw::ChannelID_t const channel) const
Returns a list of wires connected to the specified TPC channel.
Planes which measure Z direction.
Definition: geo_types.h:132
unsigned int m_CrpNLemPerSide
WireID_t Wire
Index of the wire within its plane.
Definition: geo_types.h:580
double crpGain(geo::Point_t const &pos) const
IteratorBox< TPC_id_iterator,&GeometryCore::begin_TPC_id,&GeometryCore::end_TPC_id > IterateTPCIDs() const
Enables ranged-for loops on all TPC IDs of the detector.
Planes which measure Y direction.
Definition: geo_types.h:133
unsigned int m_LemTotChans
T abs(T value)
View_t View() const
Which coordinate does this plane measure.
Definition: PlaneGeo.h:184
double crpDefaultGain() const
double Charge(TDC_t tdc) const
Returns the total number of ionization electrons on this channel in the specified TDC...
Definition: SimChannel.cxx:134
T get(std::string const &key) const
Definition: ParameterSet.h:271
Geometry information for a single wire plane.The plane is represented in the geometry by a solid whic...
Definition: PlaneGeo.h:82
p
Definition: test.py:223
void dumpLemEffMap(int nlems) const
static constexpr double ps
Definition: Units.h:99
The data type to uniquely identify a TPC.
Definition: geo_types.h:386
PlaneID_t Plane
Index of the plane within its TPC.
Definition: geo_types.h:493
unsigned int m_LemViewChans
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space.
Definition: geo_vectors.h:184
double viewCharge(const sim::SimChannel *psc, unsigned itck) const
raw::ChannelID_t Channel() const
Returns the readout channel this object describes.
Definition: SimChannel.h:329
#define DEFINE_ART_SERVICE(svc)
const geo::Geometry * m_geo
std::string m_LemEffTool
short int DetectDriftDirection() const
Returns the expected drift direction based on geometry.
Definition: TPCGeo.cxx:157
std::vector< sim::IDE > TrackIDsAndEnergies(TDC_t startTDC, TDC_t endTDC) const
Return all the recorded energy deposition within a time interval.
Definition: SimChannel.cxx:180
virtual Index size() const
geo::PlaneGeo const & LastPlane() const
Returns the last wire plane (the farther from TPC center).
Definition: TPCGeo.h:248
double getLemGain(int lemid) const
unsigned int Nwires() const
Number of wires in this plane.
Definition: PlaneGeo.h:269
FloatArrayPtr m_plemeff
double getLemTransparency(int chx, int chy) const
int getLemId(unsigned crp, int chx, int chy) const
TPCGeo const & TPC(unsigned int const tpc=0, unsigned int const cstat=0) const
Returns the specified TPC.
virtual float value(Index ival) const
PlaneGeo const & Plane(geo::View_t view) const
Return the plane in the tpc with View_t view.
Definition: TPCGeo.cxx:263
double WireCoordinate(Point const &point) const
Returns the coordinate of the point on the plane, in wire units.
Definition: PlaneGeo.h:882
TPCID_t TPC
Index of the TPC within its cryostat.
Definition: geo_types.h:406
std::vector< float > m_lemgainmap
static DuneToolManager * instance(std::string fclname="", int dbg=1)
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
unsigned int m_CrpNLem
T * getShared(std::string name)
QTextStream & endl(QTextStream &s)