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 
26  5e-5; //50 KeV threshold to consider a valid hit in the timing detector
27 
28 EcalTimeMapDigitizer::EcalTimeMapDigitizer(EcalSubdetector myDet) : m_subDet(myDet), m_geometry(nullptr) {
29  // edm::Service<edm::RandomNumberGenerator> rng ;
30  // if ( !rng.isAvailable() )
31  // {
32  // throw cms::Exception("Configuration")
33  // << "EcalTimeMapDigitizer requires the RandomNumberGeneratorService\n"
34  // "which is not present in the configuration file. You must add the service\n"
35  // "in the configuration file or remove the modules that require it.";
36  // }
37  // m_RandPoisson = new CLHEP::RandPoissonQ( rng->getEngine() ) ;
38  // m_RandGauss = new CLHEP::RandGaussQ( rng->getEngine() ) ;
39 
40  unsigned int size = 0;
41  DetId detId(0);
42 
43  //Initialize the map
44  if (myDet == EcalBarrel) {
47  } else if (myDet == EcalEndcap) {
50  } else
51  edm::LogError("TimeDigiError") << "[EcalTimeMapDigitizer]::ERROR::This subdetector " << myDet
52  << " is not implemented";
53 
54  assert(m_maxBunch - m_minBunch + 1 <= 10);
55  assert(m_minBunch <= 0);
56 
57  m_vSam.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  m_vSam.emplace_back(TimeSamples(CaloGenericDetId(detId.det(), detId.subdetId(), i)));
63  }
64 
65  edm::LogInfo("TimeDigiInfo") << "[EcalTimeDigitizer]::Subdetector " << m_subDet << "::Reserved size for time digis "
66  << m_vSam.size();
67 
68 #ifdef ecal_time_debug
69  std::cout << "[EcalTimeDigitizer]::Subdetector " << m_subDet << "::Reserved size for time digis " << m_vSam.size()
70  << std::endl;
71 #endif
72 }
73 
75 
76 void EcalTimeMapDigitizer::add(const std::vector<PCaloHit>& hits, int bunchCrossing) {
77  if (bunchCrossing >= m_minBunch && bunchCrossing <= m_maxBunch) {
78  for (std::vector<PCaloHit>::const_iterator it = hits.begin(), itEnd = hits.end(); it != itEnd; ++it) {
79  //here goes the map logic
80 
81  if (edm::isNotFinite((*it).time()))
82  continue;
83 
84  //Just consider only the hits belonging to the specified time layer
85  int depth2 = (((*it).depth() >> PCaloHit::kEcalDepthOffset) & PCaloHit::kEcalDepthMask);
86 
87  if (depth2 != m_timeLayerId)
88  continue;
89 
90  if ((*it).energy() < MIN_ENERGY_THRESHOLD) //apply a minimal cut on the hit energy
91  continue;
92 
93  const DetId detId((*it).id());
94 
95  double time = (*it).time();
96 
97  //time of flight is not corrected here for the vertex position
98  const double jitter(time - timeOfFlight(detId, m_timeLayerId));
99 
100  TimeSamples& result(*findSignal(detId));
101 
102  //here fill the result for the given bunch crossing
103  result.average_time[bunchCrossing - m_minBunch] += jitter * (*it).energy();
104  result.tot_energy[bunchCrossing - m_minBunch] += (*it).energy();
105  result.nhits[bunchCrossing - m_minBunch]++;
106 
107 #ifdef ecal_time_debug
108  std::cout << (*it).id() << "\t" << (*it).depth() << "\t" << jitter << "\t" << (*it).energy() << "\t"
109  << result.average_time[bunchCrossing - m_minBunch] << "\t" << result.nhits[bunchCrossing - m_minBunch]
110  << "\t" << timeOfFlight(detId, m_timeLayerId) << std::endl;
111 #endif
112  }
113  }
114 }
115 
117  const unsigned int di(CaloGenericDetId(detId).denseIndex());
118  TimeSamples* result(vSamAll(di));
119  if (result->zero())
120  m_index.push_back(di);
121  return result;
122 }
123 
125 
126 void EcalTimeMapDigitizer::blankOutUsedSamples() // blank out previously used elements
127 {
128  const unsigned int size(m_index.size());
129 
130  for (unsigned int i(0); i != size; ++i) {
131 #ifdef ecal_time_debug
132  std::cout << "Zeroing " << m_index[i] << std::endl;
133 #endif
134  vSamAll(m_index[i])->setZero();
135  }
136 
137  m_index.erase(m_index.begin(), // done and make ready to start over
138  m_index.end());
139 }
140 
142  //Getting the size from the actual hits
143  const unsigned int size(m_index.size());
144 
145  //Here just averaging the MC truth
146  for (unsigned int i(0); i != size; ++i) {
147 #ifdef ecal_time_debug
148  std::cout << "Averaging " << m_index[i] << std::endl;
149 #endif
151 #ifdef ecal_time_debug
152  for (unsigned int j(0); j != vSamAll(m_index[i])->time_average_capacity; ++j)
153  std::cout << j << "\t" << vSamAll(m_index[i])->average_time[j] << "\t" << vSamAll(m_index[i])->nhits[j] << "\t"
154  << vSamAll(m_index[i])->tot_energy[j] << std::endl;
155 #endif
156  }
157 
158  //Noise can be added here
159 }
160 
162 #ifdef ecal_time_debug
163  std::cout << "[EcalTimeMapDigitizer]::Zeroing the used samples" << std::endl;
164 #endif
166 }
167 
169 #ifdef ecal_time_debug
170  std::cout << "[EcalTimeMapDigitizer]::Finalizing hits and fill output collection" << std::endl;
171 #endif
172 
173  //Do the time averages and add noise if simulated
174  finalizeHits();
175 
176  //Until we do now simulated noise we can get the size from the index vector
177  const unsigned int ssize(m_index.size());
178 
179  output.reserve(ssize);
180 
181  for (unsigned int i(0); i != ssize; ++i) {
182 #ifdef ecal_time_debug
183  std::cout << "----- in digi loop " << i << std::endl;
184 #endif
185 
186  output.push_back(Digi(vSamAll(m_index[i])->id));
187 
188  unsigned int nTimeHits = 0;
189  float timeHits[vSamAll(m_index[i])->time_average_capacity];
190  unsigned int timeBX[vSamAll(m_index[i])->time_average_capacity];
191 
192  for (unsigned int j(0); j != vSamAll(m_index[i])->time_average_capacity; ++j) //here sampling on the OOTPU
193  {
194  if (vSamAll(m_index[i])->nhits[j] > 0) {
195  timeHits[nTimeHits] = vSamAll(m_index[i])->average_time[j];
196  timeBX[nTimeHits++] = m_minBunch + j;
197  }
198  }
199 
200  output.back().setSize(nTimeHits);
201 
202  for (unsigned int j(0); j != nTimeHits; ++j) //filling the !zero hits
203  {
204  output.back().setSample(j, timeHits[j]);
205  if (timeBX[j] == 0) {
206 #ifdef ecal_time_debug
207  std::cout << "setting interesting sample " << j << std::endl;
208 #endif
209  output.back().setSampleOfInterest(j);
210  }
211  }
212 
213 #ifdef ecal_time_debug
214  std::cout << "digi " << output.back().id().rawId() << "\t" << output.back().size();
215  if (output.back().sampleOfInterest() > 0)
216  std::cout << "\tBX0 time " << output.back().sample(output.back().sampleOfInterest()) << std::endl;
217  else
218  std::cout << "\tNo in time hits" << std::endl;
219 #endif
220  }
221 #ifdef ecal_time_debug
222  std::cout << "[EcalTimeMapDigitizer]::Output collection size " << output.size() << std::endl;
223 #endif
224 }
225 
226 double EcalTimeMapDigitizer::timeOfFlight(const DetId& detId, int layer) const {
227  //not using the layer yet
228  auto cellGeometry(m_geometry->getGeometry(detId));
229  assert(nullptr != cellGeometry);
230  GlobalPoint layerPos =
231  (cellGeometry)->getPosition(double(layer) + 0.5); //depth in mm in the middle of the layer position
232  return layerPos.mag() * cm / c_light;
233 }
234 
235 unsigned int EcalTimeMapDigitizer::samplesSize() const { return m_vSam.size(); }
236 
237 unsigned int EcalTimeMapDigitizer::samplesSizeAll() const { return m_vSam.size(); }
238 
240 
242 
244 
246 
248 
250 
252 
254 
256 
257 // const EcalTimeMapDigitizer::TimeSamples*
258 // EcalTimeMapDigitizer::findDetId( const DetId& detId ) const
259 // {
260 // const unsigned int di ( CaloGenericDetId( detId ).denseIndex() ) ;
261 // return vSamAll( di ) ;
262 // }
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
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)
constexpr Detector det() const
get the detector field from this detid
Definition: DetId.h:46
std::vector< TimeSamples > m_vSam
void setGeometry(const CaloSubdetectorGeometry *geometry)
double timeOfFlight(const DetId &detId, int layer) const
static EBDetId detIdFromDenseIndex(uint32_t di)
Definition: EBDetId.h:107
constexpr std::array< uint8_t, layerIndexSize< TrackerTraits > > layer
const TimeSamples * operator[](unsigned int i) const
static const int kEcalDepthMask
Definition: PCaloHit.h:61
T mag() const
Definition: PV3DBase.h:64
std::vector< unsigned int > VecInd
TimeSamples * vSamAll(unsigned int i)
static const int kEcalDepthOffset
Definition: PCaloHit.h:62
constexpr int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:48
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
TimeSamples * findSignal(const DetId &detId)
void add(const std::vector< PCaloHit > &hits, int bunchCrossing)
EcalTimeMapDigitizer(EcalSubdetector myDet)
float average_time[time_average_capacity]
float tot_energy[time_average_capacity]
Definition: output.py:1
EcalSubdetector
static const float MIN_ENERGY_THRESHOLD
TimeSamples * vSam(unsigned int i)