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 override
 
int channelIndex (int channel) const override
 we code strip indices from 1-80, and wire indices start at 100 More...
 
void initParameters () override
 initialization for each layer More...
 
int readoutElement (int element) const override
 
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
 
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 20 of file CSCWireElectronicsSim.h.

Constructor & Destructor Documentation

◆ CSCWireElectronicsSim()

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

Member Function Documentation

◆ calculateAmpResponse()

float CSCWireElectronicsSim::calculateAmpResponse ( float  t) const
overrideprivatevirtual

Implements CSCBaseElectronicsSim.

Definition at line 144 of file CSCWireElectronicsSim.cc.

References Calorimetry_cff::dp, JetChargeProducer_cfi::exp, LaserDQM_cfg::p1, conifer::pow(), and submitPVValidationJobs::t.

144  {
145  static const float fC_by_ns = 1000000;
146  static const float resistor = 20000;
147  static const float amplifier_pole = 1 / 7.5;
148  static const float fastest_chamber_exp_risetime = 10.;
149  static const float p0 = amplifier_pole;
150  static const float p1 = 1 / fastest_chamber_exp_risetime;
151 
152  static const float dp = p0 - p1;
153 
154  // ENABLE DISC:
155 
156  static const float norm = -12 * resistor * p1 * pow(p0 / dp, 4) / fC_by_ns;
157 
158  float enable_disc_volts =
159  norm * (exp(-p0 * t) * (1 + t * dp + pow(t * dp, 2) / 2 + pow(t * dp, 3) / 6) - exp(-p1 * t));
160  static const float collectionFraction = 0.12;
161  static const float igain = 1. / 0.005; // volts per fC
162  return enable_disc_volts * igain * collectionFraction;
163 }
constexpr int pow(int x)
Definition: conifer.h:24

◆ channelIndex()

int CSCWireElectronicsSim::channelIndex ( int  channel) const
inlineoverrideprivatevirtual

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

Reimplemented from CSCBaseElectronicsSim.

Definition at line 41 of file CSCWireElectronicsSim.h.

Referenced by fillDigis().

41 { return channel + 100; }

◆ fillDigis()

void CSCWireElectronicsSim::fillDigis ( CSCWireDigiCollection digis,
CLHEP::HepRandomEngine *  engine 
)

Definition at line 28 of file CSCWireElectronicsSim.cc.

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

Referenced by CSCDigitizer::doAction().

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

◆ initParameters()

void CSCWireElectronicsSim::initParameters ( )
overrideprivatevirtual

initialization for each layer

Implements CSCBaseElectronicsSim.

Definition at line 20 of file CSCWireElectronicsSim.cc.

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

20  {
24 }
const CSCChamberSpecs * theSpecs
const CSCLayerGeometry * theLayerGeometry
float wireNoise(float timeInterval) const
constexpr int pow(int x)
Definition: conifer.h:24
int numberOfWireGroups() const
#define e_SI

◆ readoutElement()

int CSCWireElectronicsSim::readoutElement ( int  element) const
overrideprivatevirtual

Implements CSCBaseElectronicsSim.

Definition at line 26 of file CSCWireElectronicsSim.cc.

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

26 { return theLayerGeometry->wireGroup(element); }
const CSCLayerGeometry * theLayerGeometry
int wireGroup(int wire) const

◆ setFraction()

void CSCWireElectronicsSim::setFraction ( float  newFraction)
inline

Definition at line 25 of file CSCWireElectronicsSim.h.

References theFraction.

25 { theFraction = newFraction; };

◆ timeOfFlightCalibration()

float CSCWireElectronicsSim::timeOfFlightCalibration ( int  wireGroup) const
privatevirtual

Definition at line 165 of file CSCWireElectronicsSim.cc.

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

Referenced by fillDigis().

165  {
166  // calibration is done for groups of 8 wire groups, facetiously
167  // called wireGroupGroups
168  int middleWireGroup = wireGroup - wireGroup % 8 + 4;
169  int numberOfWireGroups = theLayerGeometry->numberOfWireGroups();
170  if (middleWireGroup > numberOfWireGroups)
171  middleWireGroup = numberOfWireGroups;
172 
173  GlobalPoint centerOfGroupGroup = theLayer->centerOfWireGroup(middleWireGroup);
174  float averageDist = centerOfGroupGroup.mag();
175  float averageTOF = averageDist * cm / c_light; // Units of c_light: mm/ns
176 
177  LogTrace("CSCWireElectronicsSim") << "CSCWireElectronicsSim: TofCalib wg = " << wireGroup
178  << " mid wg = " << middleWireGroup << " av dist = " << averageDist
179  << " av tof = " << averageTOF;
180 
181  return averageTOF;
182 }
const CSCLayerGeometry * theLayerGeometry
#define LogTrace(id)
int numberOfWireGroups() const
T mag() const
Definition: PV3DBase.h:64
GlobalPoint centerOfWireGroup(int wireGroup) const
Definition: CSCLayer.cc:10

Member Data Documentation

◆ theFraction

float CSCWireElectronicsSim::theFraction
private

Definition at line 46 of file CSCWireElectronicsSim.h.

Referenced by fillDigis(), and setFraction().

◆ theWireNoise

float CSCWireElectronicsSim::theWireNoise
private

Definition at line 47 of file CSCWireElectronicsSim.h.

Referenced by fillDigis(), and initParameters().

◆ theWireThreshold

float CSCWireElectronicsSim::theWireThreshold
private

Definition at line 48 of file CSCWireElectronicsSim.h.

Referenced by fillDigis(), and initParameters().