CMS 3D CMS Logo

List of all members | Public Member Functions | Private Member Functions | Private Attributes
CSCWireElectronicsSim Class Reference

#include <CSCWireElectronicsSim.h>

Inheritance diagram for CSCWireElectronicsSim:
CSCBaseElectronicsSim

Public Member Functions

 CSCWireElectronicsSim (const edm::ParameterSet &p)
 configurable parameters More...
 
void fillDigis (CSCWireDigiCollection &digis, CLHEP::HepRandomEngine *)
 
void setFraction (float newFraction)
 
- Public Member Functions inherited from CSCBaseElectronicsSim
const DigiSimLinksdigiSimLinks () const
 
void setLayerId (const CSCDetId &id)
 for standalone apps who don't calculate it from the geometry More...
 
void simulate (const CSCLayer *layer, const std::vector< CSCDetectorHit > &inputHits, CLHEP::HepRandomEngine *)
 
virtual ~CSCBaseElectronicsSim ()
 

Private Member Functions

float calculateAmpResponse (float t) const
 
virtual int channelIndex (int channel) const
 we code strip indices from 1-80, and wire indices start at 100 More...
 
virtual void initParameters ()
 initialization for each layer More...
 
virtual int readoutElement (int element) const
 
virtual float timeOfFlightCalibration (int wireGroup) const
 

Private Attributes

float theFraction
 
float theWireNoise
 
float theWireThreshold
 

Additional Inherited Members

- Public Types inherited from CSCBaseElectronicsSim
typedef std::map< int, CSCAnalogSignal, std::less< int > > CSCSignalMap
 
typedef edm::DetSet< StripDigiSimLinkDigiSimLinks
 
- Protected Types inherited from CSCBaseElectronicsSim
enum  { NONE, CONSERVATIVE, RADICAL }
 
typedef std::multimap< int, CSCDetectorHit, std::less< int > > DetectorHitMap
 
- Protected Member Functions inherited from CSCBaseElectronicsSim
CSCAnalogSignaladd (const CSCAnalogSignal &, CLHEP::HepRandomEngine *)
 
virtual void addLinks (int channelIndex)
 
void addNoise (CLHEP::HepRandomEngine *)
 
CSCAnalogSignal amplifySignal (const CSCDetectorHit &)
 
double averageTimeOfFlight (const DetId &detId) const
 the average time-of-flight from the interaction point to the given detector More...
 
void combineAnalogSignals (const std::vector< CSCAnalogSignal > &)
 
 CSCBaseElectronicsSim (const edm::ParameterSet &p)
 
void fillAmpResponse ()
 
CSCAnalogSignalfind (int element, CLHEP::HepRandomEngine *)
 
CSCDetId layerId () const
 the CSCDetId corresponding to the current layer More...
 
virtual CSCAnalogSignal makeNoiseSignal (int element, CLHEP::HepRandomEngine *)
 
void setLayer (const CSCLayer *layer)
 
void setNoise (float rmsNoise, float noiseSigmaThreshold)
 
void setSignalTimeRange (double startTime, double stopTime)
 
virtual float signalDelay (int element, float pos) const
 
- Protected Attributes inherited from CSCBaseElectronicsSim
bool doNoise_
 
int nElements
 
CSCAnalogSignal theAmpResponse
 
float theBunchSpacing
 
std::vector< double > theBunchTimingOffsets
 
DetectorHitMap theDetectorHitMap
 
DigiSimLinks theDigiSimLinks
 
const CSCLayertheLayer
 
const CSCLayerGeometrytheLayerGeometry
 
CSCDetId theLayerId
 
bool theNoiseWasAdded
 
int theNumberOfSamples
 
int theOffsetOfBxZero
 
float thePeakTimeSigma
 
float theSamplingTime
 
int theShapingTime
 
CSCSignalMap theSignalMap
 
std::vector< double > theSignalPropagationSpeed
 
float theSignalStartTime
 
float theSignalStopTime
 
const CSCChamberSpecstheSpecs
 
std::vector< double > theTimingCalibrationError
 

Detailed Description

Model the readout electronics chain for EMU CSC wires

Author
Rick Wilkinson

Definition at line 21 of file CSCWireElectronicsSim.h.

Constructor & Destructor Documentation

CSCWireElectronicsSim::CSCWireElectronicsSim ( const edm::ParameterSet p)

configurable parameters

Definition at line 16 of file CSCWireElectronicsSim.cc.

References CSCBaseElectronicsSim::fillAmpResponse().

Member Function Documentation

float CSCWireElectronicsSim::calculateAmpResponse ( float  t) const
privatevirtual

Implements CSCBaseElectronicsSim.

Definition at line 163 of file CSCWireElectronicsSim.cc.

References reco::dp, JetChargeProducer_cfi::exp, p1, and funct::pow().

Referenced by setFraction().

163  {
164  static const float fC_by_ns = 1000000;
165  static const float resistor = 20000;
166  static const float amplifier_pole = 1/7.5;
167  static const float fastest_chamber_exp_risetime = 10.;
168  static const float p0=amplifier_pole;
169  static const float p1=1/fastest_chamber_exp_risetime;
170 
171  static const float dp = p0 - p1;
172 
173  // ENABLE DISC:
174 
175  static const float norm = -12 * resistor * p1 * pow(p0/dp, 4) / fC_by_ns;
176 
177  float enable_disc_volts = norm*( exp(-p0*t) *(1 +
178  t*dp +
179  pow(t*dp,2)/2 +
180  pow(t*dp,3)/6 )
181  - exp(-p1*t) );
182  static const float collectionFraction = 0.12;
183  static const float igain = 1./0.005; // volts per fC
184  return enable_disc_volts * igain * collectionFraction;
185 }
auto dp
Definition: deltaR.h:22
double p1[4]
Definition: TauolaWrapper.h:89
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40
virtual int CSCWireElectronicsSim::channelIndex ( int  channel) const
inlineprivatevirtual

we code strip indices from 1-80, and wire indices start at 100

Reimplemented from CSCBaseElectronicsSim.

Definition at line 43 of file CSCWireElectronicsSim.h.

Referenced by fillDigis().

43 {return channel+100;}
void CSCWireElectronicsSim::fillDigis ( CSCWireDigiCollection digis,
CLHEP::HepRandomEngine *  engine 
)

Definition at line 38 of file CSCWireElectronicsSim.cc.

References CSCBaseElectronicsSim::addLinks(), CSCChamberSpecs::chamberType(), channelIndex(), CSCBaseElectronicsSim::doNoise_, CSCAnalogSignal::getBinValue(), CSCAnalogSignal::getSize(), i, CSCBaseElectronicsSim::layerId(), LogTrace, CSCBaseElectronicsSim::theBunchSpacing, CSCBaseElectronicsSim::theBunchTimingOffsets, theFraction, CSCBaseElectronicsSim::theOffsetOfBxZero, CSCBaseElectronicsSim::theSamplingTime, CSCBaseElectronicsSim::theSignalMap, CSCBaseElectronicsSim::theSignalStartTime, CSCBaseElectronicsSim::theSpecs, CSCBaseElectronicsSim::theTimingCalibrationError, theWireNoise, theWireThreshold, totemRPUVPatternFinder_cfi::threshold, and timeOfFlightCalibration().

Referenced by CSCDigitizer::doAction(), and setFraction().

38  {
39 
40  if(theSignalMap.empty()) {
41  return;
42  }
43 
44  // Loop over analog signals, run the fractional discriminator on each one,
45  // and save the DIGI in the layer.
46  for(CSCSignalMap::iterator mapI = theSignalMap.begin(),
47  lastSignal = theSignalMap.end();
48  mapI != lastSignal; ++mapI)
49  {
50  int wireGroup = (*mapI).first;
51  const CSCAnalogSignal & signal = (*mapI).second;
52  LogTrace("CSCWireElectronicsSim") << "CSCWireElectronicsSim: dump of wire signal follows... "
53  << signal;
54  int signalSize = signal.getSize();
55 
56  int timeWord = 0; // and this will remain if too early or late (<bx-6 or >bx+9)
57 
58  // the way we handle noise in this chamber is by randomly varying
59  // the threshold
61  if (doNoise_) {
62  threshold += CLHEP::RandGaussQ::shoot(engine) * theWireNoise;
63  }
64  for(int ibin = 0; ibin < signalSize; ++ibin)
65  {
66  if(signal.getBinValue(ibin) > threshold)
67  {
68  // jackpot. Now define this signal as everything up until
69  // the signal goes below zero.
70  int lastbin = signalSize;
71  int i;
72  for(i = ibin; i < signalSize; ++i) {
73  if(signal.getBinValue(i) < 0.) {
74  lastbin = i;
75  break;
76  }
77  }
78 
79  float qMax = 0.0;
80  // in this loop, find the max charge and the 'fifth' electron arrival
81  for ( i = ibin; i < lastbin; ++i)
82  {
83  float next_charge = signal.getBinValue(i);
84  if(next_charge > qMax) {
85  qMax = next_charge;
86  }
87  }
88 
89  int bin_firing_FD = 0;
90  for ( i = ibin; i < lastbin; ++i)
91  {
92  if( signal.getBinValue(i) >= qMax * theFraction )
93  {
94  bin_firing_FD = i;
95  //@@ Long-standing but unlikely minor bug, I (Tim) think - following 'break' was missing...
96  //@@ ... So if both ibins 0 and 1 could fire FD, we'd flag the firing bin as 1 not 0
97  //@@ (since the above test was restricted to bin_firing_FD==0 too).
98  break;
99  }
100  }
101 
102  float tofOffset = timeOfFlightCalibration(wireGroup);
103  int chamberType = theSpecs->chamberType();
104 
105  // Note that CSCAnalogSignal::superimpose does not reset theTimeOffset to the earliest
106  // of the two signal's time offsets. If it did then we could handle signals from any
107  // time range e.g. form pileup events many bx's from the signal bx (bx=0).
108  // But then we would be wastefully storing signals over times which we can never
109  // see in the real detector, because only hits within a few bx's of bx=0 are read out.
110  // Instead, the working time range for wire hits is always started from
111  // theSignalStartTime, set as a parameter in the config file.
112  // On the other hand, if any of the overlapped CSCAnalogSignals happens to have
113  // a timeOffset earlier than theSignalStartTime (which is currently set to -100 ns)
114  // then we're in trouble. For pileup events this would mean events from collisions
115  // earlier than 4 bx before the signal bx.
116 
117  float fdTime = theSignalStartTime + theSamplingTime*bin_firing_FD;
118  if(doNoise_) {
119  fdTime += theTimingCalibrationError[chamberType] * CLHEP::RandGaussQ::shoot(engine);
120  }
121 
122  float bxFloat = (fdTime - tofOffset- theBunchTimingOffsets[chamberType]) / theBunchSpacing
124  int bxInt = static_cast<int>(bxFloat);
125  if(bxFloat >= 0 && bxFloat < 16)
126  {
127  timeWord |= (1 << bxInt );
128  // discriminator stays high for 35 ns
129  if(bxFloat-bxInt > 0.6)
130  {
131  timeWord |= (1 << (bxInt+1) );
132  }
133  }
134 
135  // Wire digi as of Oct-2006 adapted to real data: time word has 16 bits with set bit
136  // flagging appropriate bunch crossing, and bx 0 corresponding to the 7th bit, 'bit 6':
137 
138  // 1st bit set (bit 0) <-> bx -6
139  // 2nd 1 <-> bx -5
140  // ... ... ....
141  // 7th 6 <-> bx 0
142  // 8th 7 <-> bx +1
143  // ... ... ....
144  // 16th 15 <-> bx +9
145 
146  // skip over all the time bins used for this digi
147  ibin = lastbin;
148  } // if over threshold
149  } // loop over time bins in signal
150 
151  // Only create a wire digi if there is a wire hit within [-6 bx, +9 bx]
152  if(timeWord != 0)
153  {
154  CSCWireDigi newDigi(wireGroup, timeWord);
155  LogTrace("CSCWireElectronicsSim") << newDigi;
156  digis.insertDigi(layerId(), newDigi);
157  addLinks(channelIndex(wireGroup));
158  }
159  } // loop over wire signals
160 }
std::vector< double > theBunchTimingOffsets
int i
Definition: DBlmapReader.cc:9
const CSCChamberSpecs * theSpecs
float getBinValue(int i) const
virtual int channelIndex(int channel) const
we code strip indices from 1-80, and wire indices start at 100
int getSize() const
#define LogTrace(id)
virtual void addLinks(int channelIndex)
int chamberType() const
CSCDetId layerId() const
the CSCDetId corresponding to the current layer
virtual float timeOfFlightCalibration(int wireGroup) const
std::vector< double > theTimingCalibrationError
void CSCWireElectronicsSim::initParameters ( )
privatevirtual

initialization for each layer

Implements CSCBaseElectronicsSim.

Definition at line 26 of file CSCWireElectronicsSim.cc.

References e_SI, CSCBaseElectronicsSim::nElements, CSCLayerGeometry::numberOfWireGroups(), funct::pow(), CSCBaseElectronicsSim::theLayerGeometry, CSCBaseElectronicsSim::theShapingTime, CSCBaseElectronicsSim::theSpecs, theWireNoise, theWireThreshold, and CSCChamberSpecs::wireNoise().

Referenced by setFraction().

26  {
29  * e_SI * pow(10.0,15);
31 }
const CSCChamberSpecs * theSpecs
const CSCLayerGeometry * theLayerGeometry
int numberOfWireGroups() const
#define e_SI
float wireNoise(float timeInterval) const
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40
int CSCWireElectronicsSim::readoutElement ( int  element) const
privatevirtual

Implements CSCBaseElectronicsSim.

Definition at line 34 of file CSCWireElectronicsSim.cc.

References CSCBaseElectronicsSim::theLayerGeometry, and CSCLayerGeometry::wireGroup().

Referenced by setFraction().

34  {
35  return theLayerGeometry->wireGroup(element);
36 }
const CSCLayerGeometry * theLayerGeometry
int wireGroup(int wire) const
void CSCWireElectronicsSim::setFraction ( float  newFraction)
inline
float CSCWireElectronicsSim::timeOfFlightCalibration ( int  wireGroup) const
privatevirtual

Definition at line 188 of file CSCWireElectronicsSim.cc.

References CSCLayer::centerOfWireGroup(), LogTrace, PV3DBase< T, PVType, FrameType >::mag(), CSCLayerGeometry::numberOfWireGroups(), CSCBaseElectronicsSim::theLayer, and CSCBaseElectronicsSim::theLayerGeometry.

Referenced by fillDigis(), and setFraction().

188  {
189  // calibration is done for groups of 8 wire groups, facetiously
190  // called wireGroupGroups
191  int middleWireGroup = wireGroup - wireGroup%8 + 4;
192  int numberOfWireGroups = theLayerGeometry->numberOfWireGroups();
193  if(middleWireGroup > numberOfWireGroups)
194  middleWireGroup = numberOfWireGroups;
195 
196  GlobalPoint centerOfGroupGroup = theLayer->centerOfWireGroup(middleWireGroup);
197  float averageDist = centerOfGroupGroup.mag();
198  float averageTOF = averageDist * cm / c_light; // Units of c_light: mm/ns
199 
200  LogTrace("CSCWireElectronicsSim") << "CSCWireElectronicsSim: TofCalib wg = " << wireGroup <<
201  " mid wg = " << middleWireGroup <<
202  " av dist = " << averageDist <<
203  " av tof = " << averageTOF;
204 
205  return averageTOF;
206 }
const CSCLayerGeometry * theLayerGeometry
int numberOfWireGroups() const
T mag() const
Definition: PV3DBase.h:67
#define LogTrace(id)
GlobalPoint centerOfWireGroup(int wireGroup) const
Definition: CSCLayer.cc:10

Member Data Documentation

float CSCWireElectronicsSim::theFraction
private

Definition at line 48 of file CSCWireElectronicsSim.h.

Referenced by fillDigis(), and setFraction().

float CSCWireElectronicsSim::theWireNoise
private

Definition at line 49 of file CSCWireElectronicsSim.h.

Referenced by fillDigis(), and initParameters().

float CSCWireElectronicsSim::theWireThreshold
private

Definition at line 50 of file CSCWireElectronicsSim.h.

Referenced by fillDigis(), and initParameters().