CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/SimMuon/CSCDigitizer/src/CSCDigitizer.cc

Go to the documentation of this file.
00001 #include "SimMuon/CSCDigitizer/src/CSCDigitizer.h"
00002 #include "SimDataFormats/TrackingHit/interface/PSimHit.h"
00003 #include "SimMuon/CSCDigitizer/src/CSCDetectorHit.h"
00004 #include "SimMuon/CSCDigitizer/src/CSCWireHitSim.h"
00005 #include "SimMuon/CSCDigitizer/src/CSCStripHitSim.h"
00006 #include "SimMuon/CSCDigitizer/src/CSCDriftSim.h"
00007 #include "SimMuon/CSCDigitizer/src/CSCWireElectronicsSim.h"
00008 #include "SimMuon/CSCDigitizer/src/CSCStripElectronicsSim.h"
00009 #include "SimMuon/CSCDigitizer/src/CSCNeutronReader.h"
00010 #include "SimMuon/CSCDigitizer/src/CSCStripConditions.h"
00011 #include "Geometry/CSCGeometry/interface/CSCLayer.h"
00012 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00013 #include <iostream>
00014 
00015 
00016 CSCDigitizer::CSCDigitizer(const edm::ParameterSet & p)
00017 : theDriftSim(new CSCDriftSim()),
00018   theWireHitSim(new CSCWireHitSim(theDriftSim)),
00019   theStripHitSim(new CSCStripHitSim()),
00020   theWireElectronicsSim(new CSCWireElectronicsSim(p.getParameter<edm::ParameterSet>("wires"))),
00021   theStripElectronicsSim(new CSCStripElectronicsSim(p.getParameter<edm::ParameterSet>("strips"))),
00022   theNeutronReader(0),
00023   theCSCGeometry(0),
00024   theLayersNeeded(p.getParameter<unsigned int>("layersNeeded")),
00025   digitizeBadChambers_(p.getParameter<bool>("digitizeBadChambers"))
00026 {
00027   if(p.getParameter<bool>("doNeutrons"))
00028   {
00029     theNeutronReader = new CSCNeutronReader(p.getParameter<edm::ParameterSet>("neutrons"));
00030   }
00031 }
00032 
00033 
00034 CSCDigitizer::~CSCDigitizer() {
00035   delete theNeutronReader;
00036   delete theStripElectronicsSim;
00037   delete theWireElectronicsSim;
00038   delete theStripHitSim;
00039   delete theWireHitSim;
00040   delete theDriftSim;
00041 }
00042 
00043 
00044 
00045 void CSCDigitizer::doAction(MixCollection<PSimHit> & simHits, 
00046                             CSCWireDigiCollection & wireDigis, 
00047                             CSCStripDigiCollection & stripDigis, 
00048                             CSCComparatorDigiCollection & comparators,
00049                             DigiSimLinks & wireDigiSimLinks,
00050                             DigiSimLinks & stripDigiSimLinks) 
00051 {
00052   // arrange the hits by layer
00053   std::map<int, edm::PSimHitContainer> hitMap;
00054   for(MixCollection<PSimHit>::MixItr hitItr = simHits.begin();
00055       hitItr != simHits.end(); ++hitItr) 
00056   {
00057     hitMap[hitItr->detUnitId()].push_back(*hitItr);
00058   }
00059 
00060   // count how many layers on each chamber are hit
00061   std::map<int, std::set<int> > layersInChamberHit;
00062   for(std::map<int, edm::PSimHitContainer>::const_iterator hitMapItr = hitMap.begin();
00063       hitMapItr != hitMap.end(); ++hitMapItr)
00064   {
00065     CSCDetId cscDetId(hitMapItr->first); 
00066     int chamberId = cscDetId.chamberId();
00067     layersInChamberHit[chamberId].insert(cscDetId.layer());
00068   }
00069 
00070   // add neutron background, if needed
00071   if(theNeutronReader != 0)
00072   {
00073     theNeutronReader->addHits(hitMap);
00074   }
00075 
00076   // now loop over layers and run the simulation for each one
00077   for(std::map<int, edm::PSimHitContainer>::const_iterator hitMapItr = hitMap.begin();
00078       hitMapItr != hitMap.end(); ++hitMapItr)
00079   {
00080     int chamberId = CSCDetId(hitMapItr->first).chamberId();
00081     unsigned int nLayersInChamberHit = layersInChamberHit[chamberId].size();
00082     if(nLayersInChamberHit < theLayersNeeded) continue;
00083     // skip bad chambers
00084     if ( !digitizeBadChambers_ && theConditions->isInBadChamber( CSCDetId(hitMapItr->first) ) ) continue;
00085 
00086     const CSCLayer * layer = findLayer(hitMapItr->first);
00087     const edm::PSimHitContainer & layerSimHits = hitMapItr->second;
00088 
00089     std::vector<CSCDetectorHit> newWireHits, newStripHits;
00090   
00091     LogTrace("CSCDigitizer") << "CSCDigitizer: found " << layerSimHits.size() <<" hit(s) in layer"
00092        << " E" << layer->id().endcap() << " S" << layer->id().station() << " R" << layer->id().ring()
00093        << " C" << layer->id().chamber() << " L" << layer->id().layer();
00094 
00095     // turn the edm::PSimHits into WireHits, using the WireHitSim
00096     {
00097       newWireHits.swap(theWireHitSim->simulate(layer, layerSimHits));
00098     }
00099     if(!newWireHits.empty()) {
00100       newStripHits.swap(theStripHitSim->simulate(layer, newWireHits));
00101     }
00102 
00103     // turn the hits into wire digis, using the electronicsSim
00104     {
00105       theWireElectronicsSim->simulate(layer, newWireHits);
00106       theWireElectronicsSim->fillDigis(wireDigis);
00107       wireDigiSimLinks.insert( theWireElectronicsSim->digiSimLinks() );
00108     }  
00109     {
00110       theStripElectronicsSim->simulate(layer, newStripHits);
00111       theStripElectronicsSim->fillDigis(stripDigis, comparators);
00112       stripDigiSimLinks.insert( theStripElectronicsSim->digiSimLinks() );
00113     }
00114   }
00115 
00116   // fill in the layers were missing from this chamber
00117   std::list<int> missingLayers = layersMissing(stripDigis);
00118   for(std::list<int>::const_iterator missingLayerItr = missingLayers.begin();
00119       missingLayerItr != missingLayers.end(); ++missingLayerItr)
00120   {
00121     const CSCLayer * layer = findLayer(*missingLayerItr);
00122     theStripElectronicsSim->fillMissingLayer(layer, comparators, stripDigis);
00123   }
00124 }
00125 
00126 
00127 std::list<int> CSCDigitizer::layersMissing(const CSCStripDigiCollection & stripDigis) const
00128 {
00129   std::list<int> result;
00130 
00131   std::map<int, std::list<int> > layersInChamberWithDigi;
00132   for (CSCStripDigiCollection::DigiRangeIterator j=stripDigis.begin(); 
00133        j!=stripDigis.end(); j++) 
00134   {
00135     CSCDetId layerId((*j).first);
00136     // make sure the vector of digis isn't empty
00137     if((*j).second.first != (*j).second.second)
00138     {
00139       int chamberId = layerId.chamberId();
00140       layersInChamberWithDigi[chamberId].push_back(layerId.layer());
00141     }
00142  } 
00143 
00144   std::list<int> oneThruSix;
00145   for(int i = 1; i <=6; ++i)
00146     oneThruSix.push_back(i);
00147 
00148   for(std::map<int, std::list<int> >::iterator layersInChamberWithDigiItr = layersInChamberWithDigi.begin();
00149       layersInChamberWithDigiItr != layersInChamberWithDigi.end(); ++ layersInChamberWithDigiItr)
00150   {
00151     std::list<int> & layersHit = layersInChamberWithDigiItr->second;
00152     if (layersHit.size() < 6 && layersHit.size() >= theLayersNeeded) 
00153     {
00154       layersHit.sort();
00155       std::list<int> missingLayers(6);
00156       std::list<int>::iterator lastLayerMissing =
00157         set_difference(oneThruSix.begin(), oneThruSix.end(),
00158                        layersHit.begin(), layersHit.end(), missingLayers.begin());
00159       int chamberId = layersInChamberWithDigiItr->first;
00160       for(std::list<int>::iterator layerMissingItr = missingLayers.begin();
00161           layerMissingItr != lastLayerMissing; ++layerMissingItr)
00162       {
00163         // got from layer 1-6 to layer ID
00164         result.push_back(chamberId + *layerMissingItr); 
00165       }
00166     }
00167   }
00168   return result;
00169 }
00170 
00171 
00172 void CSCDigitizer::setMagneticField(const MagneticField * field) {
00173   theDriftSim->setMagneticField(field);
00174 }
00175 
00176 
00177 void CSCDigitizer::setStripConditions(CSCStripConditions * cond)
00178 {
00179   theConditions = cond; // cache here
00180   theStripElectronicsSim->setStripConditions(cond); // percolate downwards
00181 }
00182 
00183 
00184 void CSCDigitizer::setParticleDataTable(const ParticleDataTable * pdt)
00185 {
00186   theWireHitSim->setParticleDataTable(pdt);
00187 }
00188 
00189 
00190 void CSCDigitizer::setRandomEngine(CLHEP::HepRandomEngine& engine)
00191 {
00192   theWireHitSim->setRandomEngine(engine);
00193   theWireElectronicsSim->setRandomEngine(engine);
00194   theStripElectronicsSim->setRandomEngine(engine);
00195   if(theNeutronReader) theNeutronReader->setRandomEngine(engine);
00196 }
00197 
00198 
00199 const CSCLayer * CSCDigitizer::findLayer(int detId) const {
00200   assert(theCSCGeometry != 0);
00201   const GeomDetUnit* detUnit = theCSCGeometry->idToDetUnit(CSCDetId(detId));
00202   if(detUnit == 0)
00203   {
00204     throw cms::Exception("CSCDigiProducer") << "Invalid DetUnit: " << CSCDetId(detId)
00205       << "\nPerhaps your signal or pileup dataset are not compatible with the current release?";
00206   }  
00207   return dynamic_cast<const CSCLayer *>(detUnit);
00208 }
00209