CMS 3D CMS Logo

CSCWireElectronicsSim Class Reference

Model the readout electronics chain for EMU CSC wires. More...

#include <SimMuon/CSCDigitizer/src/CSCWireElectronicsSim.h>

Inheritance diagram for CSCWireElectronicsSim:

CSCBaseElectronicsSim

List of all members.

Public Member Functions

 CSCWireElectronicsSim (const edm::ParameterSet &p)
 configurable parameters
void fillDigis (CSCWireDigiCollection &digis)
void setFraction (float newFraction)

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
virtual void initParameters ()
 initialization for each layer
virtual int readoutElement (int element) const
virtual float signalDelay (int element, float pos) const
 how long, in ns, it takes a signal at pos to propagate to the readout edge.
virtual float timeOfFlightCalibration (int wireGroup) const

Private Attributes

float theFraction
float theTimingCalibrationError
float theWireNoise
float theWireThreshold


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 12 of file CSCWireElectronicsSim.cc.

References CSCBaseElectronicsSim::fillAmpResponse().

00013  : CSCBaseElectronicsSim(p),
00014    theFraction(0.5),
00015    theWireNoise(0.0),
00016    theWireThreshold(0.),
00017    theTimingCalibrationError(p.getParameter<double>("wireTimingError"))
00018 {
00019   fillAmpResponse();
00020 }


Member Function Documentation

float CSCWireElectronicsSim::calculateAmpResponse ( float  t  )  const [private, virtual]

Implements CSCBaseElectronicsSim.

Definition at line 150 of file CSCWireElectronicsSim.cc.

References funct::exp(), norm, p1, and funct::pow().

00150                                                                {
00151   static const float fC_by_ns = 1000000;
00152   static const float resistor = 20000;
00153   static const float amplifier_pole               = 1/7.5;
00154   static const float fastest_chamber_exp_risetime = 10.;
00155   static const float p0=amplifier_pole;
00156   static const float p1=1/fastest_chamber_exp_risetime;
00157 
00158   static const float dp = p0 - p1;
00159 
00160   // ENABLE DISC:
00161 
00162   static const float norm = -12 * resistor * p1 * pow(p0/dp, 4) / fC_by_ns;
00163 
00164   float enable_disc_volts = norm*(  exp(-p0*t) *(1          +
00165                                                  t*dp       +
00166                                                  pow(t*dp,2)/2 +
00167                                                  pow(t*dp,3)/6  )
00168                                     - exp(-p1*t) );
00169   static const float collectionFraction = 0.12;
00170   static const float igain = 1./0.005; // volts per fC
00171   return enable_disc_volts * igain * collectionFraction;
00172 }                                                                               

virtual int CSCWireElectronicsSim::channelIndex ( int  channel  )  const [inline, private, virtual]

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

Reimplemented from CSCBaseElectronicsSim.

Definition at line 44 of file CSCWireElectronicsSim.h.

Referenced by fillDigis().

00044 {return channel+100;}

void CSCWireElectronicsSim::fillDigis ( CSCWireDigiCollection digis  ) 

Definition at line 36 of file CSCWireElectronicsSim.cc.

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

Referenced by CSCDigitizer::doAction().

00036                                                                    {
00037 
00038   if(theSignalMap.empty()) {
00039     return;
00040   }
00041 
00042   // Loop over analog signals, run the fractional discriminator on each one,
00043   // and save the DIGI in the layer.
00044   for(CSCSignalMap::iterator mapI = theSignalMap.begin(),
00045       lastSignal = theSignalMap.end();
00046       mapI != lastSignal; ++mapI) 
00047   {
00048     int wireGroup = (*mapI).first;
00049     const CSCAnalogSignal & signal = (*mapI).second;
00050     LogTrace("CSCWireElectronicsSim") << "CSCWireElectronicsSim: dump of wire signal follows... " 
00051        <<  signal;
00052     int signalSize = signal.getSize();
00053 
00054     int timeWord = 0; // and this will remain if too early or late (<bx-6 or >bx+9)
00055 
00056     // the way we handle noise in this chamber is by randomly varying
00057     // the threshold
00058     float threshold = theWireThreshold;
00059     if (doNoise_) {
00060        threshold += theRandGaussQ->fire() * theWireNoise;
00061     }
00062     for(int ibin = 0; ibin < signalSize; ++ibin)
00063     {
00064       if(signal.getBinValue(ibin) > threshold) 
00065       {
00066         // jackpot.  Now define this signal as everything up until
00067         // the signal goes below zero.
00068         int lastbin = signalSize;
00069         int i;
00070         for(i = ibin; i < signalSize; ++i) {
00071           if(signal.getBinValue(i) < 0.) {
00072             lastbin = i;
00073             break;
00074           }
00075         }
00076 
00077         float qMax = 0.0;
00078         // in this loop, find the max charge and the 'fifth' electron arrival
00079         for ( i = ibin; i < lastbin; ++i)
00080         {
00081           float next_charge = signal.getBinValue(i);
00082           if(next_charge > qMax) {
00083             qMax = next_charge;
00084           }
00085         }
00086      
00087         int bin_firing_FD = 0;
00088         for ( i = ibin; i < lastbin; ++i)
00089         {
00090           if( bin_firing_FD == 0 && signal.getBinValue(i) >= qMax * theFraction )
00091           {
00092              bin_firing_FD = i;
00093           }
00094         } 
00095         float tofOffset = timeOfFlightCalibration(wireGroup);
00096         int chamberType = theSpecs->chamberType();
00097 
00098         // Note that CSCAnalogSignal::superimpose does not reset theTimeOffset to the earliest
00099         // of the two signal's time offsets. If it did then we could handle signals from any
00100         // time range e.g. form pileup events many bx's from the signal bx (bx=0).
00101         // But then we would be wastefully storing signals over times which we can never
00102         // see in the real detector, because only hits within a few bx's of bx=0 are read out.
00103         // Instead, the working time range for wire hits is always started from
00104         // theSignalStartTime, set as a parameter in the config file.
00105         // On the other hand, if any of the overlapped CSCAnalogSignals happens to have
00106         // a timeOffset earlier than theSignalStartTime (which is currently set to -100 ns)
00107         // then we're in trouble. For pileup events this would mean events from collisions
00108         // earlier than 4 bx before the signal bx.
00109 
00110         float fdTime = theSignalStartTime + theSamplingTime*bin_firing_FD;
00111         if(doNoise_) {
00112           fdTime += theTimingCalibrationError * theRandGaussQ->fire();
00113         }
00114 
00115         float bxFloat = (fdTime - tofOffset- theBunchTimingOffsets[chamberType]) / theBunchSpacing
00116                            + theOffsetOfBxZero;
00117         if(bxFloat >= 0 && bxFloat < 16)
00118         {
00119            timeWord |= (1 << static_cast<int>(bxFloat) );
00120         }
00121 
00122         // Wire digi as of Oct-2006 adapted to real data: time word has 16 bits with set bit
00123         // flagging appropriate bunch crossing, and bx 0 corresponding to the 7th bit, 'bit 6':
00124   
00125         //      1st bit set (bit 0) <-> bx -6
00126         //      2nd              1  <-> bx -5
00127         //      ...           ...       ....
00128         //      7th              6  <-> bx  0
00129         //      8th              7  <-> bx +1
00130         //      ...           ...       ....
00131         //     16th             15  <-> bx +9
00132 
00133         // skip over all the time bins used for this digi
00134         ibin = lastbin;
00135       } // if over threshold
00136     } // loop over time bins in signal
00137 
00138     // Only create a wire digi if there is a wire hit within [-6 bx, +9 bx]
00139     if(timeWord != 0)
00140     {
00141       CSCWireDigi newDigi(wireGroup, timeWord);
00142       LogTrace("CSCWireElectronicsSim") << newDigi;
00143       digis.insertDigi(layerId(), newDigi);
00144       addLinks(channelIndex(wireGroup));
00145     }
00146   } // loop over wire signals   
00147 }

void CSCWireElectronicsSim::initParameters (  )  [private, virtual]

initialization for each layer

Implements CSCBaseElectronicsSim.

Definition at line 23 of file CSCWireElectronicsSim.cc.

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

int CSCWireElectronicsSim::readoutElement ( int  element  )  const [private, virtual]

Implements CSCBaseElectronicsSim.

Definition at line 32 of file CSCWireElectronicsSim.cc.

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

00032                                                            {
00033   return theLayerGeometry->wireGroup(element);
00034 }

void CSCWireElectronicsSim::setFraction ( float  newFraction  )  [inline]

Definition at line 27 of file CSCWireElectronicsSim.h.

References theFraction.

00027 {theFraction = newFraction;};

float CSCWireElectronicsSim::signalDelay ( int  element,
float  pos 
) const [private, virtual]

how long, in ns, it takes a signal at pos to propagate to the readout edge.

This may be negative, since the timing may be calibrated to the center of the detector

Implements CSCBaseElectronicsSim.

Definition at line 175 of file CSCWireElectronicsSim.cc.

00175                                                                      {
00176   // readout is on right edge of chamber, signal speed is c
00177   // zero calibrated to chamber center
00178   // pos is assumed to be in wire coordinates, not local
00179   float distance = -1. * pos; // in cm
00180   float speed = c_light / cm;
00181   float delay = distance / speed;
00182   return delay;
00183 }

float CSCWireElectronicsSim::timeOfFlightCalibration ( int  wireGroup  )  const [private, virtual]

Definition at line 185 of file CSCWireElectronicsSim.cc.

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

Referenced by fillDigis().

00185                                                                         {
00186   // calibration is done for groups of 8 wire groups, facetiously
00187   // called wireGroupGroups
00188   int middleWireGroup = wireGroup - wireGroup%8 + 4;
00189   int numberOfWireGroups = theLayerGeometry->numberOfWireGroups();
00190   if(middleWireGroup > numberOfWireGroups) 
00191      middleWireGroup = numberOfWireGroups;
00192 
00193   GlobalPoint centerOfGroupGroup = theLayer->centerOfWireGroup(middleWireGroup);
00194   float averageDist = centerOfGroupGroup.mag();
00195   float averageTOF  = averageDist * cm / c_light; // Units of c_light: mm/ns
00196 
00197   LogTrace("CSCWireElectronicsSim") << "CSCWireElectronicsSim: TofCalib  wg = " << wireGroup << 
00198        " mid wg = " << middleWireGroup << 
00199        " av dist = " << averageDist << 
00200       " av tof = " << averageTOF;
00201   
00202   return averageTOF;
00203 }


Member Data Documentation

float CSCWireElectronicsSim::theFraction [private]

Definition at line 49 of file CSCWireElectronicsSim.h.

Referenced by fillDigis(), and setFraction().

float CSCWireElectronicsSim::theTimingCalibrationError [private]

Definition at line 52 of file CSCWireElectronicsSim.h.

Referenced by fillDigis().

float CSCWireElectronicsSim::theWireNoise [private]

Definition at line 50 of file CSCWireElectronicsSim.h.

Referenced by fillDigis(), and initParameters().

float CSCWireElectronicsSim::theWireThreshold [private]

Definition at line 51 of file CSCWireElectronicsSim.h.

Referenced by fillDigis(), and initParameters().


The documentation for this class was generated from the following files:
Generated on Tue Jun 9 18:17:33 2009 for CMSSW by  doxygen 1.5.4