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 // #define waveform_debug 1
25 
27  5e-5; //50 KeV threshold to consider a valid hit in the timing detector
28 
30  : m_subDet(myDet), m_ComponentShapes(componentShapes), m_geometry(nullptr) {
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 
44  //Initialize the map
45  if (myDet == EcalBarrel) {
47  } else if (myDet == EcalEndcap) {
49  } else
50  edm::LogError("TimeDigiError") << "[EcalTimeMapDigitizer]::ERROR::This subdetector " << myDet
51  << " is not implemented";
52 
53  assert(m_maxBunch - m_minBunch + 1 <= 10);
54  assert(m_minBunch <= 0);
55 
56  m_vSam.reserve(size);
57  m_index.reserve(size);
58 
59  for (unsigned int i(0); i != size; ++i) {
60  // m_vSam.emplace_back(CaloGenericDetId( detId.det(), detId.subdetId(), i ) ,
61  // m_maxBunch-m_minBunch+1, abs(m_minBunch) );
62  if (myDet == EcalBarrel) {
64  } else {
66  }
67  }
68 
69  edm::LogInfo("TimeDigiInfo") << "[EcalTimeDigitizer]::Subdetector " << m_subDet << "::Reserved size for time digis "
70  << m_vSam.size();
71 
72 #ifdef ecal_time_debug
73  std::cout << "[EcalTimeDigitizer]::Subdetector " << m_subDet << "::Reserved size for time digis " << m_vSam.size()
74  << std::endl;
75 #endif
76 }
77 
79 
80 void EcalTimeMapDigitizer::add(const std::vector<PCaloHit>& hits, int bunchCrossing) {
81  if (bunchCrossing >= m_minBunch && bunchCrossing <= m_maxBunch) {
82  for (std::vector<PCaloHit>::const_iterator it = hits.begin(), itEnd = hits.end(); it != itEnd; ++it) {
83  //here goes the map logic
84 
85  if (edm::isNotFinite((*it).time()))
86  continue;
87 
88  if ((*it).energy() < MIN_ENERGY_THRESHOLD) //apply a minimal cut on the hit energy
89  continue;
90 
91  //Old behavior: Just consider only the hits belonging to the specified time layer
92  //int depth2 = (((*it).depth() >> PCaloHit::kEcalDepthOffset) & PCaloHit::kEcalDepthMask);
93  //I think things make more sense if we allow all depths -- JCH
94 
95  const DetId detId((*it).id());
96 
97  double time = (*it).time();
98 
99  //time of flight is not corrected here for the vertex position
100  const double jitter(time - timeOfFlight(detId, m_timeLayerId));
101 
103 
104  if (nullptr != m_ComponentShapes) {
105  // for now we have waveform_granularity = 1., 10 BX, and waveform capacity 250 -- we want to start at 25*bunchCrossing and go to the end of waveform capacity
106  double binTime(0);
107  for (unsigned int bin(0); bin != result.waveform_capacity; ++bin) {
109  result.waveform[bin] +=
110  (*(shapes()->at((*it).depth())))(binTime - jitter - 25 * (bunchCrossing - m_minBunch)) * (*it).energy();
111  }
112 #ifdef waveform_debug
113  else {
114  std::cout << "strange depth found: " << ComponentShapeCollection::toDepthBin((*it).depth()) << std::endl;
115  } // note: understand what these depths mean
116 #endif
117  binTime += result.waveform_granularity;
118  }
119  }
120 
121  //here fill the result for the given bunch crossing
122 
123  // i think this is obsolete now that there is a real MTD
124  //if (depth2 != m_timeLayerId)
125  // continue;
126  result.average_time[bunchCrossing - m_minBunch] += jitter * (*it).energy();
127  result.tot_energy[bunchCrossing - m_minBunch] += (*it).energy();
128  result.nhits[bunchCrossing - m_minBunch]++;
129 
130 #ifdef ecal_time_debug
131  std::cout << (*it).id() << "\t" << (*it).depth() << "\t" << jitter << "\t" << (*it).energy() << "\t"
132  << result.average_time[bunchCrossing - m_minBunch] << "\t" << result.nhits[bunchCrossing - m_minBunch]
133  << "\t" << timeOfFlight(detId, m_timeLayerId) << std::endl;
134 #endif
135  }
136  }
137 }
138 
140  const unsigned int di(CaloGenericDetId(detId).denseIndex());
141  TimeSamples* result(vSamAll(di));
142  if (result->zero())
143  m_index.push_back(di);
144  return result;
145 }
146 
148 
149 void EcalTimeMapDigitizer::blankOutUsedSamples() // blank out previously used elements
150 {
151  const unsigned int size(m_index.size());
152 
153  for (unsigned int i(0); i != size; ++i) {
154 #ifdef ecal_time_debug
155  std::cout << "Zeroing " << m_index[i] << std::endl;
156 #endif
157  vSamAll(m_index[i])->setZero();
158  }
159 
160  m_index.clear(); // done and make ready to start over
161 }
162 
164  //Getting the size from the actual hits
165  const unsigned int size(m_index.size());
166 
167  //Here just averaging the MC truth
168  for (unsigned int i(0); i != size; ++i) {
169 #ifdef ecal_time_debug
170  std::cout << "Averaging " << m_index[i] << std::endl;
171 #endif
173 #ifdef ecal_time_debug
174  for (unsigned int j(0); j != vSamAll(m_index[i])->time_average_capacity; ++j)
175  std::cout << j << "\t" << vSamAll(m_index[i])->average_time[j] << "\t" << vSamAll(m_index[i])->nhits[j] << "\t"
176  << vSamAll(m_index[i])->tot_energy[j] << std::endl;
177 #endif
178  }
179 
180  //Noise can be added here
181 }
182 
184 #ifdef ecal_time_debug
185  std::cout << "[EcalTimeMapDigitizer]::Zeroing the used samples" << std::endl;
186 #endif
188 }
189 
191  if (nullptr != m_ComponentShapes)
193  else
194  throw cms::Exception(
195  "[EcalTimeMapDigitizer] setEventSetup was called, but this should only be called when componentWaveform is "
196  "activated by cfg parameter");
197 }
198 
200 
202 #ifdef ecal_time_debug
203  std::cout << "[EcalTimeMapDigitizer]::Finalizing hits and fill output collection" << std::endl;
204 #endif
205 
206  //Do the time averages and add noise if simulated
207  finalizeHits();
208 
209  //Until we do now simulated noise we can get the size from the index vector
210  const unsigned int ssize(m_index.size());
211 
212  output.reserve(ssize);
213 
214  for (unsigned int i(0); i != ssize; ++i) {
215 #ifdef ecal_time_debug
216  std::cout << "----- in digi loop " << i << std::endl;
217 #endif
218 
219  output.push_back(Digi(vSamAll(m_index[i])->id));
220  if (nullptr != m_ComponentShapes)
221  output.back().setWaveform(vSamAll(m_index[i])->waveform);
222 
223  unsigned int nTimeHits = 0;
224  unsigned int nTimeHitsMax = vSamAll(m_index[i])->time_average_capacity;
225  float timeHits[nTimeHitsMax];
226  unsigned int timeBX[nTimeHitsMax];
227 
228  for (unsigned int j(0); j != nTimeHitsMax; ++j) //here sampling on the OOTPU
229  {
230  if (vSamAll(m_index[i])->nhits[j] > 0) {
231  timeHits[nTimeHits] = vSamAll(m_index[i])->average_time[j];
232  timeBX[nTimeHits] = m_minBunch + j;
233  nTimeHits++;
234  }
235  }
236 
237  output.back().setSize(nTimeHits);
238 
239  for (unsigned int j(0); j != nTimeHits; ++j) //filling the !zero hits
240  {
241  output.back().setSample(j, timeHits[j]);
242  if (timeBX[j] == 0) {
243 #ifdef ecal_time_debug
244  std::cout << "setting interesting sample " << j << std::endl;
245 #endif
246  output.back().setSampleOfInterest(j);
247  }
248  }
249 
250 #ifdef ecal_time_debug
251  std::cout << "digi " << output.back().id().rawId() << "\t" << output.back().size();
252  if (output.back().sampleOfInterest() > 0)
253  std::cout << "\tBX0 time " << output.back().sample(output.back().sampleOfInterest()) << std::endl;
254  else
255  std::cout << "\tNo in time hits" << std::endl;
256 #endif
257  }
258 #ifdef ecal_time_debug
259  std::cout << "[EcalTimeMapDigitizer]::Output collection size " << output.size() << std::endl;
260 #endif
261 }
262 
264  //not using the layer yet
265  auto cellGeometry(m_geometry->getGeometry(detId));
266  assert(nullptr != cellGeometry);
267  GlobalPoint layerPos = (cellGeometry)->getPosition();
268  //(cellGeometry)->getPosition(double(layer) + 0.5); //depth in mm in the middle of the layer position // JCH : I am not sure this is doing what it's supposed to, probably unimplemented since CaloCellGeometry returns the same value regardless of this double
269  return layerPos.mag() * cm / c_light;
270 }
271 
272 unsigned int EcalTimeMapDigitizer::samplesSize() const { return m_vSam.size(); }
273 
274 unsigned int EcalTimeMapDigitizer::samplesSizeAll() const { return m_vSam.size(); }
275 
277 
279 
281 
283 
285 
287 
289 
291 
293 
294 // const EcalTimeMapDigitizer::TimeSamples*
295 // EcalTimeMapDigitizer::findDetId( const DetId& detId ) const
296 // {
297 // const unsigned int di ( CaloGenericDetId( detId ).denseIndex() ) ;
298 // return vSamAll( di ) ;
299 // }
static EEDetId detIdFromDenseIndex(uint32_t din)
Definition: EEDetId.h:220
size
Write out results.
static constexpr int kSizeForDenseIndexing
Definition: EEDetId.h:328
EcalTimeMapDigitizer(EcalSubdetector myDet, ComponentShapeCollection *componentShapes)
unsigned int samplesSizeAll() const
void run(EcalTimeDigiCollection &output)
static const int m_maxBunch
constexpr bool isNotFinite(T x)
Definition: isFinite.h:9
const CaloSubdetectorGeometry * m_geometry
unsigned int samplesSize() const
Log< level::Error, false > LogError
unsigned int nhits[time_average_capacity]
assert(be >=bs)
std::vector< TimeSamples > m_vSam
void setGeometry(const CaloSubdetectorGeometry *geometry)
const ComponentShapeCollection * shapes() const
double timeOfFlight(const DetId &detId, int layer) const
static EBDetId detIdFromDenseIndex(uint32_t di)
Definition: EBDetId.h:107
ComponentShapeCollection * m_ComponentShapes
static constexpr int kSizeForDenseIndexing
Definition: EBDetId.h:155
const TimeSamples * operator[](unsigned int i) const
T mag() const
Definition: PV3DBase.h:64
std::vector< unsigned int > VecInd
TimeSamples * vSamAll(unsigned int i)
void setEventSetup(const edm::EventSetup &evtSetup)
virtual std::shared_ptr< const CaloCellGeometry > getGeometry(const DetId &id) const
Get the cell geometry of a given detector id. Should return false if not found.
static const unsigned short time_average_capacity
Log< level::Info, false > LogInfo
Definition: DetId.h:17
static const int m_minBunch
void setEventSetup(const edm::EventSetup &eventSetup)
static int toDepthBin(int index)
TimeSamples * findSignal(const DetId &detId)
void add(const std::vector< PCaloHit > &hits, int bunchCrossing)
float average_time[time_average_capacity]
float tot_energy[time_average_capacity]
Definition: output.py:1
EcalSubdetector
const std::shared_ptr< ComponentShape > at(int depthIndex) const
static const float MIN_ENERGY_THRESHOLD
TimeSamples * vSam(unsigned int i)