00001
00002
00003 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00004 #include "SimMuon/CSCDigitizer/src/CSCBaseElectronicsSim.h"
00005 #include "SimMuon/CSCDigitizer/src/CSCDetectorHit.h"
00006 #include "Geometry/CSCGeometry/interface/CSCLayer.h"
00007 #include "CLHEP/Units/GlobalPhysicalConstants.h"
00008 #include "SimDataFormats/TrackingHit/interface/PSimHit.h"
00009
00010 #include<list>
00011 #include<algorithm>
00012
00013 CSCBaseElectronicsSim::CSCBaseElectronicsSim(const edm::ParameterSet & p)
00014 :
00015 theSpecs(0),
00016 theLayerGeometry(0),
00017 theLayer(0),
00018 theSignalMap(),
00019 theAmpResponse(),
00020 theBunchSpacing(25.),
00021 theNoiseWasAdded(false),
00022 nElements(0),
00023 theShapingTime(p.getParameter<int>("shapingTime")),
00024 thePeakTimeSigma(p.getParameter<double>("peakTimeSigma")),
00025 theBunchTimingOffsets(p.getParameter<std::vector<double> >("bunchTimingOffsets")),
00026 theSignalStartTime(p.getParameter<double>("signalStartTime")),
00027 theSignalStopTime(p.getParameter<double>("signalStopTime")),
00028 theSamplingTime(p.getParameter<double>("samplingTime")),
00029 theNumberOfSamples(static_cast<int>((theSignalStopTime-theSignalStartTime)/theSamplingTime)),
00030 theOffsetOfBxZero(p.getParameter<int>("timeBitForBxZero")),
00031 theSignalPropagationSpeed(p.getParameter<std::vector<double> >("signalSpeed")),
00032 theTimingCalibrationError(p.getParameter<std::vector<double> >("timingCalibrationError")),
00033 doNoise_(p.getParameter<bool>("doNoise")),
00034 theRandGaussQ(0)
00035 {
00036 assert(theBunchTimingOffsets.size() == 11);
00037 }
00038
00039
00040 CSCBaseElectronicsSim::~CSCBaseElectronicsSim()
00041 {
00042 delete theRandGaussQ;
00043 }
00044
00045
00046 void CSCBaseElectronicsSim::setRandomEngine(CLHEP::HepRandomEngine& engine)
00047 {
00048 if(theRandGaussQ) delete theRandGaussQ;
00049 theRandGaussQ = new CLHEP::RandGaussQ(engine);
00050 }
00051
00052
00053 void CSCBaseElectronicsSim::simulate(const CSCLayer * layer,
00054 const std::vector<CSCDetectorHit> & detectorHits)
00055 {
00056 theNoiseWasAdded = false;
00057
00058 {
00059 theSignalMap.clear();
00060 theDetectorHitMap.clear();
00061 setLayer(layer);
00062
00063 theDigiSimLinks = DigiSimLinks(layerId().rawId());
00064 }
00065
00066 {
00067 size_t nHits = detectorHits.size();
00068
00069 for( size_t i = 0; i < nHits; ++i) {
00070 int element = readoutElement( detectorHits[i].getElement() );
00071
00072
00073
00074 if ( element != 0 ) add( amplifySignal(detectorHits[i]) );
00075 }
00076 }
00077
00078 {
00079 if(doNoise_) {
00080 addNoise();
00081 }
00082 }
00083 }
00084
00085
00086 void CSCBaseElectronicsSim::setLayer(const CSCLayer * layer)
00087 {
00088
00089 theSpecs = layer->chamber()->specs();
00090 theLayerGeometry = layer->geometry();
00091
00092 theLayer = layer;
00093 theLayerId = CSCDetId(theLayer->geographicalId().rawId());
00094 initParameters();
00095 }
00096
00097
00098 void CSCBaseElectronicsSim::fillAmpResponse() {
00099 std::vector<float> ampBinValues(theNumberOfSamples);
00100 int i = 0;
00101 for( ; i < theNumberOfSamples; ++i) {
00102 ampBinValues[i] = calculateAmpResponse(i*theSamplingTime);
00103
00104 if(i>5 && ampBinValues[i] < 0.000001) break;
00105 }
00106 ampBinValues.resize(i);
00107 theAmpResponse = CSCAnalogSignal(0, theSamplingTime, ampBinValues, 1., 0.);
00108
00109 LogTrace("CSCBaseElectronicsSim") <<
00110 "CSCBaseElectronicsSim: dump of theAmpResponse follows...\n"
00111 << theAmpResponse;
00112 }
00113
00114
00115
00116 CSCAnalogSignal
00117 CSCBaseElectronicsSim::amplifySignal(const CSCDetectorHit & detectorHit) {
00118 int element = readoutElement(detectorHit.getElement());
00119
00120 float readoutTime = detectorHit.getTime()
00121 + signalDelay(element, detectorHit.getPosition());
00122
00123
00124 CSCAnalogSignal thisSignal(theAmpResponse);
00125 thisSignal *= detectorHit.getCharge();
00126 thisSignal.setTimeOffset(readoutTime);
00127 thisSignal.setElement(element);
00128
00129 theDetectorHitMap.insert( DetectorHitMap::value_type(channelIndex(element), detectorHit) );
00130 return thisSignal;
00131 }
00132
00133
00134 CSCAnalogSignal CSCBaseElectronicsSim::makeNoiseSignal(int element) {
00135 std::vector<float> binValues(theNumberOfSamples);
00136
00137 return CSCAnalogSignal(element, theSamplingTime, binValues, 0., theSignalStartTime);
00138 }
00139
00140
00141 void CSCBaseElectronicsSim::addNoise() {
00142 for(CSCSignalMap::iterator mapI = theSignalMap.begin();
00143 mapI!= theSignalMap.end(); ++mapI) {
00144
00145 (*mapI).second.superimpose(makeNoiseSignal((*mapI).first));
00146
00147
00148 double timeOffset = theRandGaussQ->fire((*mapI).second.getTimeOffset(), thePeakTimeSigma);
00149 (*mapI).second.setTimeOffset(timeOffset);
00150 }
00151 theNoiseWasAdded = true;
00152 }
00153
00154
00155 CSCAnalogSignal & CSCBaseElectronicsSim::find(int element) {
00156 if(element <= 0 || element > nElements) {
00157 LogTrace("CSCBaseElectronicsSim") << "CSCBaseElectronicsSim: bad element = " << element <<
00158 ". There are " << nElements << " elements.";
00159 edm::LogError("Error in CSCBaseElectronicsSim: element out of bounds");
00160 }
00161 CSCSignalMap::iterator signalMapItr = theSignalMap.find(element);
00162 if(signalMapItr == theSignalMap.end()) {
00163 CSCAnalogSignal newSignal;
00164 if(theNoiseWasAdded) {
00165 newSignal = makeNoiseSignal(element);
00166 } else {
00167 std::vector<float> emptyV(theNumberOfSamples);
00168 newSignal = CSCAnalogSignal(element, theSamplingTime, emptyV, 0., theSignalStartTime);
00169 }
00170 signalMapItr = theSignalMap.insert( std::pair<int, CSCAnalogSignal>(element, newSignal) ).first;
00171 }
00172 return (*signalMapItr).second;
00173 }
00174
00175
00176 CSCAnalogSignal & CSCBaseElectronicsSim::add(const CSCAnalogSignal & signal) {
00177 int element = signal.getElement();
00178 CSCAnalogSignal & newSignal = find(element);
00179 newSignal.superimpose(signal);
00180 return newSignal;
00181 }
00182
00183
00184 float CSCBaseElectronicsSim::signalDelay(int element, float pos) const {
00185
00186
00187
00188 float distance = -1. * pos;
00189 float speed = theSignalPropagationSpeed[theSpecs->chamberType()];
00190 return distance / speed;
00191 }
00192
00193
00194 void CSCBaseElectronicsSim::addLinks(int channelIndex) {
00195 std::pair<DetectorHitMap::iterator, DetectorHitMap::iterator> channelHitItr
00196 = theDetectorHitMap.equal_range(channelIndex);
00197
00198
00199 std::map<int,float> simTrackChargeMap;
00200 std::map<int, EncodedEventId> eventIdMap;
00201 float totalCharge = 0;
00202 for( DetectorHitMap::iterator hitItr = channelHitItr.first;
00203 hitItr != channelHitItr.second; ++hitItr){
00204 const PSimHit * hit = hitItr->second.getSimHit();
00205
00206 if(hit != 0) {
00207 int simTrackId = hitItr->second.getSimHit()->trackId();
00208 float charge = hitItr->second.getCharge();
00209 std::map<int,float>::iterator chargeItr = simTrackChargeMap.find(simTrackId);
00210 if( chargeItr == simTrackChargeMap.end() ) {
00211 simTrackChargeMap[simTrackId] = charge;
00212 eventIdMap[simTrackId] = hit->eventId();
00213 } else {
00214 chargeItr->second += charge;
00215 }
00216 totalCharge += charge;
00217 }
00218 }
00219
00220 for(std::map<int,float>::iterator chargeItr = simTrackChargeMap.begin();
00221 chargeItr != simTrackChargeMap.end(); ++chargeItr) {
00222 int simTrackId = chargeItr->first;
00223 theDigiSimLinks.push_back( StripDigiSimLink(channelIndex, simTrackId,
00224 eventIdMap[simTrackId], chargeItr->second/totalCharge ) );
00225
00226 }
00227 }
00228
00229
00230