00001 #include "Utilities/Timing/interface/TimingReport.h"
00002 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00003 #include "SimMuon/CSCDigitizer/src/CSCStripElectronicsSim.h"
00004 #include "SimMuon/CSCDigitizer/src/CSCAnalogSignal.h"
00005 #include "SimMuon/CSCDigitizer/src/CSCCrosstalkGenerator.h"
00006 #include "SimMuon/CSCDigitizer/src/CSCStripConditions.h"
00007 #include "DataFormats/CSCDigi/interface/CSCComparatorDigi.h"
00008 #include "DataFormats/CSCDigi/interface/CSCStripDigi.h"
00009 #include "Geometry/CSCGeometry/interface/CSCLayer.h"
00010 #include "Geometry/CSCGeometry/interface/CSCChamberSpecs.h"
00011 #include "Geometry/CSCGeometry/interface/CSCLayerGeometry.h"
00012 #include "SimMuon/CSCDigitizer/src/CSCDetectorHit.h"
00013 #include "CLHEP/Units/PhysicalConstants.h"
00014 #include <list>
00015 #include <cassert>
00016
00017
00018
00019 CSCStripElectronicsSim::CSCStripElectronicsSim(const edm::ParameterSet & p)
00020 : CSCBaseElectronicsSim(p),
00021 theAmpResponse(theShapingTime, CSCStripAmpResponse::RADICAL),
00022 theComparatorThreshold(20.),
00023 theComparatorNoise(0.),
00024 theComparatorRMSOffset(2.),
00025 theComparatorSaturation(1057.),
00026 theComparatorWait(50.),
00027 theComparatorDeadTime(100.),
00028 theDaqDeadTime(200.),
00029 theTimingOffset(0.),
00030 nScaBins_(p.getParameter<int>("nScaBins")),
00031 doSuppression_(p.getParameter<bool>("doSuppression")),
00032 doCrosstalk_(p.getParameter<bool>("doCrosstalk")),
00033 theStripConditions(0),
00034 theCrosstalkGenerator(0),
00035 theComparatorClockJump(2),
00036 sca_time_bin_size(50.),
00037 sca_peak_bin(p.getParameter<int>("scaPeakBin")),
00038 theComparatorTimeBinOffset(p.getParameter<double>("comparatorTimeBinOffset")),
00039 theComparatorTimeOffset(p.getParameter<double>("comparatorTimeOffset"))
00040 {
00041
00042 if(doCrosstalk_) {
00043 theCrosstalkGenerator = new CSCCrosstalkGenerator();
00044 }
00045
00046 fillAmpResponse();
00047 }
00048
00049
00050 CSCStripElectronicsSim::~CSCStripElectronicsSim() {
00051 if(doCrosstalk_) {
00052 delete theCrosstalkGenerator;
00053 }
00054 }
00055
00056 void CSCStripElectronicsSim::initParameters() {
00057 TimeMe t("CSCStripEl:init");
00058 theLayerGeometry = theLayer->geometry();
00059 nElements = theLayerGeometry->numberOfStrips();
00060 theComparatorThreshold = 20.;
00061
00062
00063
00064 float averageDistance = theLayer->surface().position().mag();
00065 float averageTimeOfFlight = averageDistance * cm / c_light;
00066 int chamberType = theSpecs->chamberType();
00067
00068 theTimingOffset = theShapingTime + averageTimeOfFlight
00069 + theBunchTimingOffsets[chamberType];
00070
00071 theSignalStartTime = theTimingOffset
00072 - (sca_peak_bin-1) * sca_time_bin_size;
00073 theSignalStopTime = theSignalStartTime + nScaBins_*sca_time_bin_size;
00074 theNumberOfSamples = nScaBins_*static_cast<int>(sca_time_bin_size/theSamplingTime);
00075
00076 }
00077
00078
00079 int CSCStripElectronicsSim::readoutElement(int strip) const {
00080 return theLayerGeometry->channel(strip);
00081 }
00082
00083
00084 float CSCStripElectronicsSim::calculateAmpResponse(float t) const
00085 {
00086 return theAmpResponse.calculateAmpResponse(t);
00087 }
00088
00089
00090 CSCAnalogSignal CSCStripElectronicsSim::makeNoiseSignal(int element) {
00091 std::vector<float> noiseBins(nScaBins_);
00092 CSCAnalogSignal tmpSignal(element, sca_time_bin_size, noiseBins);
00093 if(doNoise_) {
00094 theStripConditions->noisify(layerId(), tmpSignal);
00095 }
00096
00097 std::vector<float> binValues(theNumberOfSamples);
00098 for(int ibin=0; ibin < theNumberOfSamples; ++ibin) {
00099 binValues[ibin] = tmpSignal.getValue(ibin*theSamplingTime);
00100 }
00101 CSCAnalogSignal finalSignal(element, theSamplingTime, binValues, 0., theSignalStartTime);
00102 return finalSignal;
00103 }
00104
00105
00106 float CSCStripElectronicsSim::signalDelay(int element, float pos) const {
00107
00108
00109 float distance = -1. * pos;
00110 float speed = 0.8 * c_light / cm;
00111 return distance / speed;;
00112 }
00113
00114
00115 float CSCStripElectronicsSim::comparatorReading(const CSCAnalogSignal & signal,
00116 float time) const {
00117 return std::min(signal.getValue(time), theComparatorSaturation)
00118 + theComparatorRMSOffset* theRandGaussQ->fire();
00119 }
00120
00121
00122 void
00123 CSCStripElectronicsSim::runComparator(std::vector<CSCComparatorDigi> & result) {
00124
00125
00126 std::list<int> comparatorsWithSignal;
00127 CSCSignalMap::iterator signalMapItr;
00128 for(signalMapItr = theSignalMap.begin();
00129 signalMapItr != theSignalMap.end(); ++signalMapItr) {
00130
00131
00132 comparatorsWithSignal.push_back( ((*signalMapItr).first-1)/2 );
00133 }
00134
00135 comparatorsWithSignal.unique();
00136 for(std::list<int>::iterator listItr = comparatorsWithSignal.begin();
00137 listItr != comparatorsWithSignal.end(); ++listItr) {
00138 int iComparator = *listItr;
00139
00140
00141
00142 const CSCAnalogSignal & signal1 = find(readoutElement(iComparator*2 + 1));
00143 const CSCAnalogSignal & signal2 = find(readoutElement(iComparator*2 + 2));
00144 for(float time = theSignalStartTime +theComparatorTimeOffset;
00145 time < theSignalStopTime-theComparatorWait;
00146 time += theSamplingTime)
00147 {
00148 if(comparatorReading(signal1, time) > theComparatorThreshold
00149 || comparatorReading(signal2, time) > theComparatorThreshold) {
00150
00151 float comparatorTime = time;
00152 time += theComparatorWait;
00153
00154 float height1 = comparatorReading(signal1, time);
00155 float height2 = comparatorReading(signal2, time);
00156 int output = 0;
00157 int strip = 0;
00158
00159
00160
00161
00162
00163
00164
00165 const CSCAnalogSignal * mainSignal = 0;
00166
00167 if(height1 > height2) {
00168 mainSignal = &signal1;
00169 float leftStrip = 0.;
00170 if(iComparator > 0) {
00171 leftStrip = comparatorReading(find(readoutElement(iComparator*2)), time);
00172 }
00173
00174 if(leftStrip < height1 && height1 > theComparatorThreshold) {
00175 output = (leftStrip < height2);
00176 strip = iComparator*2 + 1;
00177 }
00178 } else {
00179 mainSignal = &signal2;
00180 float rightStrip = 0.;
00181 if(iComparator*2+3 <= nElements) {
00182 rightStrip = comparatorReading(find(readoutElement(iComparator*2+3)), time);
00183 }
00184 if(rightStrip < height2 && height2 > theComparatorThreshold) {
00185 output = (height1 < rightStrip);
00186 strip = iComparator*2 + 2;
00187 }
00188 }
00189 if(strip != 0) {
00190
00191 float bxFloat = (comparatorTime-theTimingOffset)/theBunchSpacing
00192 + theComparatorTimeBinOffset + theOffsetOfBxZero;
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208 int timeWord = 0;
00209 if ( (bxFloat>= 0) && (bxFloat<16) )
00210 timeWord = (1 << static_cast<int>(bxFloat) );
00211
00212 CSCComparatorDigi newDigi(strip, output, timeWord);
00213 result.push_back(newDigi);
00214 }
00215
00216
00217 time += theComparatorDeadTime;
00218
00219 float resetThreshold = 1;
00220 while(time < theSignalStopTime
00221 && mainSignal->getValue(time) > resetThreshold) {
00222 time += theSamplingTime;
00223 }
00224
00225 }
00226 }
00227 }
00228
00229 sort(result.begin(), result.end());
00230 }
00231
00232
00233 std::list<int>
00234 CSCStripElectronicsSim::getKeyStrips(const std::vector<CSCComparatorDigi> & comparators) const
00235 {
00236 std::list<int> result;
00237 for(std::vector<CSCComparatorDigi>::const_iterator compItr = comparators.begin();
00238 compItr != comparators.end(); ++compItr)
00239 {
00240 if(std::abs(compItr->getTimeBin()-theOffsetOfBxZero) <= 2)
00241 {
00242 result.push_back(compItr->getStrip());
00243 }
00244 }
00245
00246 result.sort();
00247 result.unique();
00248 return result;
00249 }
00250
00251
00252 std::list<int>
00253 CSCStripElectronicsSim::getKeyStripsFromMC() const
00254 {
00255
00256 std::list<int> result;
00257 transform(theDetectorHitMap.begin(), theDetectorHitMap.end(),
00258 back_inserter(result), boost::bind(&DetectorHitMap::value_type::first,_1));
00259 result.sort();
00260 result.unique();
00261 return result;
00262 }
00263
00264
00265 std::list<int>
00266 CSCStripElectronicsSim::channelsToRead(const std::list<int> & keyStrips, int window) const
00267 {
00268 std::list<int> result;
00269 std::list<int>::const_iterator keyStripItr = keyStrips.begin();
00270 if(doSuppression_)
00271 {
00272 for( ; keyStripItr != keyStrips.end(); ++keyStripItr)
00273 {
00274
00275 for(int istrip = (*keyStripItr)-window; istrip <= (*keyStripItr)+window; ++istrip)
00276 {
00277 if(istrip>0 && istrip<= nElements)
00278 {
00279 result.push_back(readoutElement(istrip));
00280 }
00281 }
00282 }
00283 result.sort();
00284 result.unique();
00285 }
00286 else
00287 {
00288
00289 std::list<int> cfebsToRead;
00290 for( ; keyStripItr != keyStrips.end(); ++keyStripItr)
00291 {
00292 int cfeb = (readoutElement(*keyStripItr)-1)/16;
00293 cfebsToRead.push_back(cfeb);
00294 int remainder = (readoutElement(*keyStripItr)-1)%16;
00295
00296 if(remainder < window && cfeb != 0)
00297 {
00298 cfebsToRead.push_back(cfeb-1);
00299 }
00300
00301 int maxCFEBs = readoutElement(nElements)/16 - 1;
00302 if(remainder >= 16-window && cfeb != maxCFEBs)
00303 {
00304 cfebsToRead.push_back(cfeb+1);
00305 }
00306 }
00307 cfebsToRead.sort();
00308 cfebsToRead.unique();
00309
00310
00311 for(std::list<int>::const_iterator cfebItr = cfebsToRead.begin();
00312 cfebItr != cfebsToRead.end(); ++cfebItr)
00313 {
00314 for(int i = 1; i <= 16; ++i)
00315 {
00316 result.push_back((*cfebItr)*16 + i);
00317 }
00318 }
00319 }
00320 return result;
00321 }
00322
00323
00324
00325
00326 bool SortSignalsByTotal(const CSCAnalogSignal & s1,
00327 const CSCAnalogSignal & s2) {
00328 return ( s1.getTotal() > s2.getTotal() );
00329 }
00330
00331
00332 void CSCStripElectronicsSim::fillDigis(CSCStripDigiCollection & digis,
00333 CSCComparatorDigiCollection & comparators)
00334 {
00335 TimeMe t("CSCStripEl:filldigi");
00336 if(doCrosstalk_) {
00337 addCrosstalk();
00338 }
00339
00340 std::vector<CSCComparatorDigi> comparatorOutputs;
00341 runComparator(comparatorOutputs);
00342
00343 CSCComparatorDigiCollection::Range range(comparatorOutputs.begin(),
00344 comparatorOutputs.end());
00345 comparators.put(range, layerId());
00346
00347 double startTime = theTimingOffset
00348 - (sca_peak_bin-1) * sca_time_bin_size;
00349
00350
00351 std::list<int> keyStrips = getKeyStripsFromMC();
00352 std::list<int> stripsToDo = channelsToRead(keyStrips, 3);
00353 std::vector<CSCStripDigi> stripDigis;
00354 stripDigis.reserve(stripsToDo.size());
00355 for(std::list<int>::const_iterator stripItr = stripsToDo.begin();
00356 stripItr != stripsToDo.end(); ++stripItr)
00357 {
00358 createDigi(*stripItr, startTime, stripDigis);
00359 }
00360
00361 CSCStripDigiCollection::Range stripRange(stripDigis.begin(), stripDigis.end());
00362 digis.put(stripRange, layerId());
00363 }
00364
00365
00366 void CSCStripElectronicsSim::addCrosstalk() {
00367
00368
00369 std::vector<CSCAnalogSignal> realSignals;
00370 realSignals.reserve(theSignalMap.size());
00371 CSCSignalMap::iterator mapI = theSignalMap.begin(), mapEnd = theSignalMap.end();
00372 for( ; mapI != mapEnd; ++mapI) {
00373 realSignals.push_back((*mapI).second);
00374 }
00375 sort(realSignals.begin(), realSignals.end(), SortSignalsByTotal);
00376 std::vector<CSCAnalogSignal>::iterator realSignalItr = realSignals.begin(),
00377 realSignalsEnd = realSignals.end();
00378 for( ; realSignalItr != realSignalsEnd; ++realSignalItr)
00379 {
00380 int thisStrip = (*realSignalItr).getElement();
00381
00382 if(thisStrip > 1) {
00383 int otherStrip = thisStrip - 1;
00384 addCrosstalk(*realSignalItr, thisStrip, otherStrip);
00385 }
00386 if(thisStrip < nElements) {
00387 int otherStrip = thisStrip + 1;
00388 addCrosstalk(*realSignalItr, thisStrip, otherStrip);
00389 }
00390 }
00391 }
00392
00393
00394 void CSCStripElectronicsSim::addCrosstalk(const CSCAnalogSignal & signal,
00395 int thisStrip, int otherStrip)
00396 {
00397 float capacitiveCrosstalk, resistiveCrosstalk;
00398 bool leftRight = (otherStrip > thisStrip);
00399 theStripConditions->crosstalk(layerId(), thisStrip,
00400 theLayerGeometry->length(), leftRight,
00401 capacitiveCrosstalk, resistiveCrosstalk);
00402 theCrosstalkGenerator->setParameters(capacitiveCrosstalk, 0., resistiveCrosstalk);
00403 CSCAnalogSignal crosstalkSignal( theCrosstalkGenerator->getCrosstalk(signal) );
00404 find(readoutElement(otherStrip)).superimpose(crosstalkSignal);
00405
00406
00407 crosstalkSignal *= -1.;
00408 find(thisStrip).superimpose(crosstalkSignal);
00409
00410 }
00411
00412
00413 void CSCStripElectronicsSim::createDigi(int channel, float startTime, std::vector<CSCStripDigi> & result)
00414 {
00415 const CSCAnalogSignal & signal = find(channel);
00416
00417 std::vector<int> scaCounts(nScaBins_);
00418
00419 float pedestal = theStripConditions->pedestal(layerId(), channel);
00420 float gain = theStripConditions->smearedGain(layerId(), channel);
00421
00422 for(int scaBin = 0; scaBin < nScaBins_; ++scaBin) {
00423 scaCounts[scaBin] = static_cast< int >
00424 ( pedestal + signal.getValue(startTime+scaBin*sca_time_bin_size) * gain );
00425 }
00426 CSCStripDigi newDigi(channel, scaCounts);
00427
00428
00429 doSaturation(newDigi);
00430
00431 result.push_back(newDigi);
00432 addLinks(channelIndex(channel));
00433 LogTrace("CSCStripElectronicsSim") << newDigi;
00434 }
00435
00436
00437 void CSCStripElectronicsSim::doSaturation(CSCStripDigi & digi)
00438 {
00439 std::vector<int> scaCounts(digi.getADCCounts());
00440 for(unsigned scaBin = 0; scaBin < scaCounts.size(); ++scaBin) {
00441 scaCounts[scaBin] = std::min(scaCounts[scaBin], 4095);
00442 }
00443 digi.setADCCounts(scaCounts);
00444 }
00445
00446
00447 void CSCStripElectronicsSim::selfTest() const
00448 {
00449
00450 std::list<int> keyStrips, stripsRead;
00451
00452 bool isGanged = (readoutElement(nElements) == 16);
00453 keyStrips.push_back(readoutElement(19));
00454 keyStrips.push_back(readoutElement(30));
00455 keyStrips.push_back(readoutElement(32));
00456 stripsRead = channelsToRead(keyStrips, 3);
00457 if(doSuppression_)
00458 {
00459 unsigned int expectedSize = isGanged ? 10 : 12;
00460 assert(stripsRead.size() == expectedSize);
00461 assert(stripsRead.front() == readoutElement(17));
00462 }
00463 else
00464 {
00465 unsigned int expectedSize = isGanged ? 16 : 48;
00466 assert(stripsRead.size() == expectedSize);
00467 assert(stripsRead.front() == 1);
00468 }
00469 }
00470
00471
00472