CMS 3D CMS Logo

EcalTimeMapDigitizer.cc
Go to the documentation of this file.
2 
8 //#include "FWCore/ServiceRegistry/interface/Service.h"
9 //#include "FWCore/Utilities/interface/RandomNumberGenerator.h"
10 //#include "CLHEP/Random/RandPoissonQ.h"
11 //#include "CLHEP/Random/RandGaussQ.h"
12 
15 
17 
18 #include "CLHEP/Units/GlobalPhysicalConstants.h"
19 #include "CLHEP/Units/GlobalSystemOfUnits.h"
20 
21 #include <iostream>
22 
23 //#define ecal_time_debug 1
24 
25 const float EcalTimeMapDigitizer::MIN_ENERGY_THRESHOLD=5e-5; //50 KeV threshold to consider a valid hit in the timing detector
26 
28  m_subDet(myDet),
29  m_geometry(nullptr)
30 {
31 // edm::Service<edm::RandomNumberGenerator> rng ;
32 // if ( !rng.isAvailable() )
33 // {
34 // throw cms::Exception("Configuration")
35 // << "EcalTimeMapDigitizer requires the RandomNumberGeneratorService\n"
36 // "which is not present in the configuration file. You must add the service\n"
37 // "in the configuration file or remove the modules that require it.";
38 // }
39 // m_RandPoisson = new CLHEP::RandPoissonQ( rng->getEngine() ) ;
40 // m_RandGauss = new CLHEP::RandGaussQ( rng->getEngine() ) ;
41 
42  unsigned int size=0;
43  DetId detId(0);
44 
45  //Initialize the map
46  if (myDet==EcalBarrel)
47  {
49  detId=EBDetId::detIdFromDenseIndex( 0 ) ;
50  }
51  else if (myDet==EcalEndcap)
52  {
54  detId=EEDetId::detIdFromDenseIndex( 0 ) ;
55  }
56  else
57  edm::LogError("TimeDigiError") << "[EcalTimeMapDigitizer]::ERROR::This subdetector " << myDet << " is not implemented";
58 
59 
60  assert(m_maxBunch-m_minBunch+1<=10);
61  assert(m_minBunch<=0);
62 
63  m_vSam.reserve( size ) ;
64 
65  for( unsigned int i ( 0 ) ; i != size ; ++i )
66  {
67  // m_vSam.emplace_back(CaloGenericDetId( detId.det(), detId.subdetId(), i ) ,
68  // m_maxBunch-m_minBunch+1, abs(m_minBunch) );
69  m_vSam.emplace_back(TimeSamples(CaloGenericDetId( detId.det(), detId.subdetId(), i )));
70  }
71 
72 
73  edm::LogInfo("TimeDigiInfo") << "[EcalTimeDigitizer]::Subdetector " << m_subDet << "::Reserved size for time digis " << m_vSam.size();
74 
75 #ifdef ecal_time_debug
76  std::cout << "[EcalTimeDigitizer]::Subdetector " << m_subDet << "::Reserved size for time digis " << m_vSam.size() << std::endl;
77 #endif
78 
79 }
80 
82 {
83 }
84 
85 void
86 EcalTimeMapDigitizer::add(const std::vector<PCaloHit> & hits, int bunchCrossing) {
87  if(bunchCrossing>=m_minBunch && bunchCrossing<=m_maxBunch ) {
88 
89  for(std::vector<PCaloHit>::const_iterator it = hits.begin(), itEnd = hits.end(); it != itEnd; ++it) {
90  //here goes the map logic
91 
92  if (edm::isNotFinite( (*it).time() ) )
93  continue;
94 
95  //Just consider only the hits belonging to the specified time layer
96  int depth2 = (((*it).depth() >> PCaloHit::kEcalDepthOffset) &
98 
99  if (depth2 != m_timeLayerId) continue;
100 
101  if ((*it).energy()<MIN_ENERGY_THRESHOLD) //apply a minimal cut on the hit energy
102  continue;
103 
104  const DetId detId ( (*it).id() ) ;
105 
106  double time = (*it).time();
107 
108  //time of flight is not corrected here for the vertex position
109  const double jitter ( time - timeOfFlight( detId, m_timeLayerId ) ) ;
110 
111  TimeSamples& result ( *findSignal( detId ) ) ;
112 
113  //here fill the result for the given bunch crossing
114  result.average_time[bunchCrossing-m_minBunch]+=jitter*(*it).energy();
115  result.tot_energy[bunchCrossing-m_minBunch]+=(*it).energy();
116  result.nhits[bunchCrossing-m_minBunch]++;
117 
118 #ifdef ecal_time_debug
119  std::cout << (*it).id() << "\t" << (*it).depth() << "\t" << jitter << "\t" << (*it).energy() << "\t" << result.average_time[bunchCrossing-m_minBunch] << "\t" << result.nhits[bunchCrossing-m_minBunch] << "\t" << timeOfFlight( detId, m_timeLayerId ) << std::endl;
120 #endif
121  }
122  }
123 }
124 
125 
128 {
129  const unsigned int di ( CaloGenericDetId( detId ).denseIndex() ) ;
130  TimeSamples* result ( vSamAll( di ) ) ;
131  if( result->zero() ) m_index.push_back( di ) ;
132  return result ;
133 }
134 
135 
136 
137 void
139 {
140  m_geometry = geometry ;
141 }
142 
143 
144 void
145 EcalTimeMapDigitizer::blankOutUsedSamples() // blank out previously used elements
146 {
147  const unsigned int size ( m_index.size() ) ;
148 
149 
150  for( unsigned int i ( 0 ) ; i != size ; ++i )
151  {
152 #ifdef ecal_time_debug
153  std::cout << "Zeroing " << m_index[i] << std::endl;
154 #endif
155  vSamAll( m_index[i] )->setZero() ;
156  }
157 
158  m_index.erase( m_index.begin() , // done and make ready to start over
159  m_index.end() ) ;
160 }
161 
162 
163 void
165 {
166  //Getting the size from the actual hits
167  const unsigned int size ( m_index.size() ) ;
168 
169  //Here just averaging the MC truth
170  for( unsigned int i ( 0 ) ; i != size ; ++i )
171  {
172 #ifdef ecal_time_debug
173  std::cout << "Averaging " << m_index[i] << std::endl;
174 #endif
176 #ifdef ecal_time_debug
177  for ( unsigned int j ( 0 ) ; j != vSamAll( m_index[i] )->time_average_capacity; ++j )
178  std::cout << j << "\t" << vSamAll( m_index[i] )->average_time[j] << "\t" << vSamAll( m_index[i] )->nhits[j] << "\t" << vSamAll( m_index[i] )->tot_energy[j] << std::endl;
179 #endif
180  }
181 
182  //Noise can be added here
183 
184 }
185 
186 void
188 {
189 #ifdef ecal_time_debug
190  std::cout << "[EcalTimeMapDigitizer]::Zeroing the used samples" << std::endl;
191 #endif
193 }
194 
195 
196 void
198 {
199 #ifdef ecal_time_debug
200  std::cout << "[EcalTimeMapDigitizer]::Finalizing hits and fill output collection" << std::endl;
201 #endif
202 
203  //Do the time averages and add noise if simulated
204  finalizeHits();
205 
206  //Until we do now simulated noise we can get the size from the index vector
207  const unsigned int ssize ( m_index.size() ) ;
208 
209  output.reserve( ssize ) ;
210 
211  for( unsigned int i ( 0 ) ; i != ssize ; ++i )
212  {
213 
214  #ifdef ecal_time_debug
215  std::cout << "----- in digi loop " << i << std::endl;
216  #endif
217 
218  output.push_back( Digi(vSamAll( m_index[i] )->id) );
219 
220  unsigned int nTimeHits=0;
221  float timeHits[vSamAll( m_index[i] )->time_average_capacity];
222  unsigned int timeBX[vSamAll( m_index[i] )->time_average_capacity];
223 
224  for ( unsigned int j ( 0 ) ; j != vSamAll( m_index[i] )->time_average_capacity; ++j ) //here sampling on the OOTPU
225  {
226  if (vSamAll( m_index[i] )->nhits[j]>0)
227  {
228  timeHits[nTimeHits]= vSamAll( m_index[i] )->average_time[j];
229  timeBX[nTimeHits++]= m_minBunch+j;
230  }
231  }
232 
233  output.back().setSize(nTimeHits);
234 
235  for (unsigned int j ( 0 ) ; j != nTimeHits; ++j ) //filling the !zero hits
236  {
237  output.back().setSample(j,timeHits[j]);
238  if (timeBX[j]==0)
239  {
240 #ifdef ecal_time_debug
241  std::cout << "setting interesting sample " << j << std::endl;
242 #endif
243  output.back().setSampleOfInterest(j);
244  }
245  }
246 
247  #ifdef ecal_time_debug
248  std::cout << "digi " << output.back().id().rawId() << "\t" << output.back().size();
249  if (output.back().sampleOfInterest()>0)
250  std::cout << "\tBX0 time " << output.back().sample(output.back().sampleOfInterest()) << std::endl;
251  else
252  std::cout << "\tNo in time hits" << std::endl;
253  #endif
254  }
255 #ifdef ecal_time_debug
256  std::cout << "[EcalTimeMapDigitizer]::Output collection size " << output.size() << std::endl;
257 #endif
258 
259 }
260 
261 
262 double
263 EcalTimeMapDigitizer::timeOfFlight( const DetId& detId , int layer) const
264 {
265  //not using the layer yet
266  const CaloCellGeometry* cellGeometry ( m_geometry->getGeometry( detId ) ) ;
267  assert( nullptr != cellGeometry ) ;
268  GlobalPoint layerPos = (dynamic_cast<const TruncatedPyramid*>(cellGeometry))->getPosition( double(layer)+0.5 ); //depth in mm in the middle of the layer position
269  return layerPos.mag()*cm/c_light ;
270 }
271 
272 
273 unsigned int
275 {
276  return m_vSam.size() ;
277 }
278 
279 unsigned int
281 {
282  return m_vSam.size() ;
283 }
284 
286 EcalTimeMapDigitizer::operator[]( unsigned int i ) const
287 {
288  return &m_vSam[ i ] ;
289 }
290 
293 {
294  return &m_vSam[ i ] ;
295 }
296 
299 {
300  return &m_vSam[ i ] ;
301 }
302 
305 {
306  return &m_vSam[ i ] ;
307 }
308 
310 EcalTimeMapDigitizer::vSamAll( unsigned int i ) const
311 {
312  return &m_vSam[ i ] ;
313 }
314 
315 int
317 {
318  return m_minBunch ;
319 }
320 
321 int
323 {
324  return m_maxBunch ;
325 }
326 
329 {
330  return m_index ;
331 }
332 
335 {
336  return m_index ;
337 }
338 
339 // const EcalTimeMapDigitizer::TimeSamples*
340 // EcalTimeMapDigitizer::findDetId( const DetId& detId ) const
341 // {
342 // const unsigned int di ( CaloGenericDetId( detId ).denseIndex() ) ;
343 // return vSamAll( di ) ;
344 // }
static EEDetId detIdFromDenseIndex(uint32_t din)
Definition: EEDetId.h:220
size
Write out results.
unsigned int samplesSizeAll() const
void run(EcalTimeDigiCollection &output)
static const int m_maxBunch
const CaloSubdetectorGeometry * m_geometry
void push_back(T const &t)
const TimeSamples * operator[](unsigned int i) const
#define nullptr
unsigned int nhits[time_average_capacity]
std::vector< TimeSamples > m_vSam
void setGeometry(const CaloSubdetectorGeometry *geometry)
virtual const CaloCellGeometry * getGeometry(const DetId &id) const
Get the cell geometry of a given detector id. Should return false if not found.
static EBDetId detIdFromDenseIndex(uint32_t di)
Definition: EBDetId.h:111
unsigned int samplesSize() const
T mag() const
Definition: PV3DBase.h:67
bool isNotFinite(T x)
Definition: isFinite.h:10
static const int kEcalDepthMask
Definition: PCaloHit.h:68
TimeSamples * vSamAll(unsigned int i)
static const int kEcalDepthOffset
Definition: PCaloHit.h:69
int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:37
static const unsigned short time_average_capacity
Definition: DetId.h:18
static const int m_minBunch
TimeSamples * findSignal(const DetId &detId)
double timeOfFlight(const DetId &detId, int layer) const
A base class to handle the particular shape of Ecal Xtals. Taken from ORCA Calorimetry Code...
void add(const std::vector< PCaloHit > &hits, int bunchCrossing)
ESHandle< TrackerGeometry > geometry
EcalTimeMapDigitizer(EcalSubdetector myDet)
size_type size() const
float average_time[time_average_capacity]
void reserve(size_type n)
float tot_energy[time_average_capacity]
std::vector< unsigned int > VecInd
Detector det() const
get the detector field from this detid
Definition: DetId.h:35
EcalSubdetector
static const float MIN_ENERGY_THRESHOLD
TimeSamples * vSam(unsigned int i)
const_reference back() const