CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
CSCBaseElectronicsSim.cc
Go to the documentation of this file.
1 // This is CSCBaseElectronicsSim.cc
2 
7 #include "CLHEP/Units/GlobalPhysicalConstants.h"
9 
10 #include<list>
11 #include<algorithm>
12 
14 :
15  theSpecs(0),
16  theLayerGeometry(0),
17  theLayer(0),
18  theSignalMap(),
19  theAmpResponse(),
20  theBunchSpacing(25.),
21  theNoiseWasAdded(false),
22  nElements(0),
23  theShapingTime(p.getParameter<int>("shapingTime")),
24  thePeakTimeSigma(p.getParameter<double>("peakTimeSigma")),
25  theBunchTimingOffsets(p.getParameter<std::vector<double> >("bunchTimingOffsets")),
26  theSignalStartTime(p.getParameter<double>("signalStartTime")),
27  theSignalStopTime(p.getParameter<double>("signalStopTime")),
28  theSamplingTime(p.getParameter<double>("samplingTime")),
29  theNumberOfSamples(static_cast<int>((theSignalStopTime-theSignalStartTime)/theSamplingTime)),
30  theOffsetOfBxZero(p.getParameter<int>("timeBitForBxZero")),
31  theSignalPropagationSpeed(p.getParameter<std::vector<double> >("signalSpeed")),
32  theTimingCalibrationError(p.getParameter<std::vector<double> >("timingCalibrationError")),
33  doNoise_(p.getParameter<bool>("doNoise")),
34  theRandGaussQ(0)
35 {
36  assert(theBunchTimingOffsets.size() == 11);
37 }
38 
39 
41 {
42  delete theRandGaussQ;
43 }
44 
45 
46 void CSCBaseElectronicsSim::setRandomEngine(CLHEP::HepRandomEngine& engine)
47 {
48  if(theRandGaussQ) delete theRandGaussQ;
49  theRandGaussQ = new CLHEP::RandGaussQ(engine);
50 }
51 
52 
54  const std::vector<CSCDetectorHit> & detectorHits)
55 {
56  theNoiseWasAdded = false;
57 
58  {
59  theSignalMap.clear();
60  theDetectorHitMap.clear();
61  setLayer(layer);
62  // can we swap for efficiency?
64  }
65 
66  {
67  size_t nHits = detectorHits.size();
68  // turn each detector hit into an analog signal
69  for( size_t i = 0; i < nHits; ++i) {
70  int element = readoutElement( detectorHits[i].getElement() );
71 
72  // skip if hit element is not part of a readout element
73  // e.g. wire in non-readout group
74  if ( element != 0 ) add( amplifySignal(detectorHits[i]) );
75  }
76  }
77 
78  {
79  if(doNoise_) {
80  addNoise();
81  }
82  }
83 }
84 
85 
87 {
88  // fill the specs member data
89  theSpecs = layer->chamber()->specs();
90  theLayerGeometry = layer->geometry();
91 
92  theLayer = layer;
95 }
96 
97 
99  std::vector<float> ampBinValues(theNumberOfSamples);
100  int i = 0;
101  for( ; i < theNumberOfSamples; ++i) {
102  ampBinValues[i] = calculateAmpResponse(i*theSamplingTime);
103  // truncate any entries that are trivially small
104  if(i>5 && ampBinValues[i] < 0.000001) break;
105  }
106  ampBinValues.resize(i);
107  theAmpResponse = CSCAnalogSignal(0, theSamplingTime, ampBinValues, 1., 0.);
108 
109  LogTrace("CSCBaseElectronicsSim") <<
110  "CSCBaseElectronicsSim: dump of theAmpResponse follows...\n"
111  << theAmpResponse;
112 }
113 
114 
115 
118  int element = readoutElement(detectorHit.getElement());
119 
120  float readoutTime = detectorHit.getTime()
121  + signalDelay(element, detectorHit.getPosition());
122 
123  // start from the amp response, and modify it.
124  CSCAnalogSignal thisSignal(theAmpResponse);
125  thisSignal *= detectorHit.getCharge();
126  thisSignal.setTimeOffset(readoutTime);
127  thisSignal.setElement(element);
128  // keep track of links between digis and hits
129  theDetectorHitMap.insert( DetectorHitMap::value_type(channelIndex(element), detectorHit) );
130  return thisSignal;
131 }
132 
133 
135  std::vector<float> binValues(theNumberOfSamples);
136  // default is empty
137  return CSCAnalogSignal(element, theSamplingTime, binValues, 0., theSignalStartTime);
138 }
139 
140 
142  for(CSCSignalMap::iterator mapI = theSignalMap.begin();
143  mapI!= theSignalMap.end(); ++mapI) {
144  // superimpose electronics noise
145  (*mapI).second.superimpose(makeNoiseSignal((*mapI).first));
146  // DON'T do amp gain variations. Handled in strips by calibration code
147  // and variations in the shaper peaking time.
148  double timeOffset = theRandGaussQ->fire((*mapI).second.getTimeOffset(), thePeakTimeSigma);
149  (*mapI).second.setTimeOffset(timeOffset);
150  }
151  theNoiseWasAdded = true;
152 }
153 
154 
156  if(element <= 0 || element > nElements) {
157  LogTrace("CSCBaseElectronicsSim") << "CSCBaseElectronicsSim: bad element = " << element <<
158  ". There are " << nElements << " elements.";
159  edm::LogError("Error in CSCBaseElectronicsSim: element out of bounds");
160  }
161  CSCSignalMap::iterator signalMapItr = theSignalMap.find(element);
162  if(signalMapItr == theSignalMap.end()) {
163  CSCAnalogSignal newSignal;
164  if(theNoiseWasAdded) {
165  newSignal = makeNoiseSignal(element);
166  } else {
167  std::vector<float> emptyV(theNumberOfSamples);
168  newSignal = CSCAnalogSignal(element, theSamplingTime, emptyV, 0., theSignalStartTime);
169  }
170  signalMapItr = theSignalMap.insert( std::pair<int, CSCAnalogSignal>(element, newSignal) ).first;
171  }
172  return (*signalMapItr).second;
173 }
174 
175 
177  int element = signal.getElement();
178  CSCAnalogSignal & newSignal = find(element);
179  newSignal.superimpose(signal);
180  return newSignal;
181 }
182 
183 
184 float CSCBaseElectronicsSim::signalDelay(int element, float pos) const {
185  // readout is on top edge of chamber for strips, right edge
186  // for wires.
187  // zero calibrated to chamber center
188  float distance = -1. * pos;
190  return distance / speed;
191 }
192 
193 
194 void CSCBaseElectronicsSim::addLinks(int channelIndex) {
195  std::pair<DetectorHitMap::iterator, DetectorHitMap::iterator> channelHitItr
196  = theDetectorHitMap.equal_range(channelIndex);
197 
198  // find the fraction contribution for each SimTrack
199  std::map<int,float> simTrackChargeMap;
200  std::map<int, EncodedEventId> eventIdMap;
201  float totalCharge = 0;
202  for( DetectorHitMap::iterator hitItr = channelHitItr.first;
203  hitItr != channelHitItr.second; ++hitItr){
204  const PSimHit * hit = hitItr->second.getSimHit();
205  // might be zero for unit tests and such
206  if(hit != 0) {
207  int simTrackId = hitItr->second.getSimHit()->trackId();
208  float charge = hitItr->second.getCharge();
209  std::map<int,float>::iterator chargeItr = simTrackChargeMap.find(simTrackId);
210  if( chargeItr == simTrackChargeMap.end() ) {
211  simTrackChargeMap[simTrackId] = charge;
212  eventIdMap[simTrackId] = hit->eventId();
213  } else {
214  chargeItr->second += charge;
215  }
216  totalCharge += charge;
217  }
218  }
219 
220  for(std::map<int,float>::iterator chargeItr = simTrackChargeMap.begin();
221  chargeItr != simTrackChargeMap.end(); ++chargeItr) {
222  int simTrackId = chargeItr->first;
223  theDigiSimLinks.push_back( StripDigiSimLink(channelIndex, simTrackId,
224  eventIdMap[simTrackId], chargeItr->second/totalCharge ) );
225 
226  }
227 }
228 
229 
230 
std::vector< double > theBunchTimingOffsets
CSCBaseElectronicsSim(const edm::ParameterSet &p)
float getPosition() const
int getElement() const
virtual float signalDelay(int element, float pos) const
int i
Definition: DBlmapReader.cc:9
const CSCChamberSpecs * theSpecs
virtual CSCAnalogSignal makeNoiseSignal(int element)
const CSCLayerGeometry * theLayerGeometry
void push_back(const T &t)
Definition: DetSet.h:68
virtual float calculateAmpResponse(float t) const =0
CSCAnalogSignal amplifySignal(const CSCDetectorHit &)
double charge(const std::vector< uint8_t > &Ampls)
void setRandomEngine(CLHEP::HepRandomEngine &engine)
void setLayer(const CSCLayer *layer)
CLHEP::RandGaussQ * theRandGaussQ
uint32_t rawId() const
get the raw id
Definition: DetId.h:43
int getElement() const
constructor from time and amp shape
std::vector< double > theSignalPropagationSpeed
const CSCChamberSpecs * specs() const
Definition: CSCChamber.h:42
edm::DetSet< StripDigiSimLink > DigiSimLinks
float getCharge() const
DetId geographicalId() const
The label of this GeomDet.
Definition: GeomDet.h:72
EncodedEventId eventId() const
Definition: PSimHit.h:105
float getTime() const
void superimpose(const CSCAnalogSignal &signal2)
virtual int readoutElement(int element) const =0
Container::value_type value_type
#define LogTrace(id)
virtual void addLinks(int channelIndex)
int chamberType() const
CSCAnalogSignal & add(const CSCAnalogSignal &)
void simulate(const CSCLayer *layer, const std::vector< CSCDetectorHit > &inputHits)
CSCDetId layerId() const
the CSCDetId corresponding to the current layer
CSCAnalogSignal & find(int element)
virtual int channelIndex(int channel) const
lets users map channels to different indices for links
volatile std::atomic< bool > shutdown_flag false
virtual void initParameters()=0
const CSCChamber * chamber() const
Definition: CSCLayer.h:52
const CSCLayerGeometry * geometry() const
Definition: CSCLayer.h:47