CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/SimTracker/SiStripDigitizer/plugins/SiStripDigitizer.cc

Go to the documentation of this file.
00001 // File: SiStripDigitizerAlgorithm.cc
00002 // Description:  Class for digitization.
00003 
00004 // Modified 15/May/2013 mark.grimes@bristol.ac.uk - Modified so that the digi-sim link has the correct
00005 // index for the sim hits stored. It was previously always set to zero (I won't mention that it was
00006 // me who originally wrote that).
00007 
00008 // system include files
00009 #include <memory>
00010 
00011 #include "SimTracker/Common/interface/SimHitSelectorFromDB.h"
00012 
00013 #include "SiStripDigitizer.h"
00014 #include "SiStripDigitizerAlgorithm.h"
00015 #include "SimGeneral/MixingModule/interface/PileUpEventPrincipal.h"
00016 
00017 #include "DataFormats/Common/interface/DetSetVector.h"
00018 #include "DataFormats/SiStripDigi/interface/SiStripDigi.h"
00019 #include "DataFormats/SiStripDigi/interface/SiStripRawDigi.h"
00020 #include "SimDataFormats/TrackerDigiSimLink/interface/StripDigiSimLink.h"
00021 
00022 // user include files
00023 #include "FWCore/Framework/interface/Frameworkfwd.h"
00024 #include "FWCore/Framework/interface/EDProducer.h"
00025 
00026 #include "FWCore/Framework/interface/Event.h"
00027 #include "FWCore/Framework/interface/MakerMacros.h"
00028 
00029 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00030 #include "SimDataFormats/TrackingHit/interface/PSimHitContainer.h"
00031 #include "SimDataFormats/TrackingHit/interface/PSimHit.h"
00032 
00033 //needed for the geometry:
00034 #include "FWCore/Framework/interface/EventSetup.h"
00035 #include "FWCore/Framework/interface/ESHandle.h"
00036 #include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h"
00037 #include "Geometry/CommonDetUnit/interface/GeomDetType.h"
00038 #include "Geometry/Records/interface/TrackerDigiGeometryRecord.h"
00039 #include "Geometry/TrackerNumberingBuilder/interface/GeometricDet.h"
00040 #include "Geometry/CommonTopologies/interface/StripTopology.h"
00041 #include "Geometry/TrackerGeometryBuilder/interface/StripGeomDetType.h"
00042 #include "Geometry/TrackerGeometryBuilder/interface/StripGeomDetUnit.h"
00043 //needed for the magnetic field:
00044 #include "MagneticField/Engine/interface/MagneticField.h"
00045 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
00046 
00047 #include "DataFormats/SiStripDetId/interface/StripSubdetector.h"
00048 
00049 //Data Base infromations
00050 #include "CalibFormats/SiStripObjects/interface/SiStripDetCabling.h"
00051 #include "CalibTracker/Records/interface/SiStripDependentRecords.h"
00052 #include "CondFormats/DataRecord/interface/SiStripCondDataRecords.h"
00053 
00054 //Random Number
00055 #include "FWCore/ServiceRegistry/interface/Service.h"
00056 #include "FWCore/Utilities/interface/RandomNumberGenerator.h"
00057 #include "FWCore/Utilities/interface/Exception.h"
00058 #include "CLHEP/Random/RandomEngine.h"
00059 
00060 SiStripDigitizer::SiStripDigitizer(const edm::ParameterSet& conf, edm::EDProducer& mixMod) : 
00061   gainLabel(conf.getParameter<std::string>("Gain")),
00062   hitsProducer(conf.getParameter<std::string>("hitsProducer")),
00063   trackerContainers(conf.getParameter<std::vector<std::string> >("ROUList")),
00064   ZSDigi(conf.getParameter<edm::ParameterSet>("DigiModeList").getParameter<std::string>("ZSDigi")),
00065   SCDigi(conf.getParameter<edm::ParameterSet>("DigiModeList").getParameter<std::string>("SCDigi")),
00066   VRDigi(conf.getParameter<edm::ParameterSet>("DigiModeList").getParameter<std::string>("VRDigi")),
00067   PRDigi(conf.getParameter<edm::ParameterSet>("DigiModeList").getParameter<std::string>("PRDigi")),
00068   geometryType(conf.getParameter<std::string>("GeometryType")),
00069   useConfFromDB(conf.getParameter<bool>("TrackerConfigurationFromDB")),
00070   zeroSuppression(conf.getParameter<bool>("ZeroSuppression")),
00071   makeDigiSimLinks_(conf.getUntrackedParameter<bool>("makeDigiSimLinks", false))
00072 { 
00073   const std::string alias("simSiStripDigis");
00074   
00075   mixMod.produces<edm::DetSetVector<SiStripDigi> >(ZSDigi).setBranchAlias(ZSDigi);
00076   mixMod.produces<edm::DetSetVector<SiStripRawDigi> >(SCDigi).setBranchAlias(alias + SCDigi);
00077   mixMod.produces<edm::DetSetVector<SiStripRawDigi> >(VRDigi).setBranchAlias(alias + VRDigi);
00078   mixMod.produces<edm::DetSetVector<SiStripRawDigi> >(PRDigi).setBranchAlias(alias + PRDigi);
00079   mixMod.produces<edm::DetSetVector<StripDigiSimLink> >().setBranchAlias(alias + "siStripDigiSimLink");
00080   edm::Service<edm::RandomNumberGenerator> rng;
00081   if ( ! rng.isAvailable()) {
00082     throw cms::Exception("Configuration")
00083       << "SiStripDigitizer requires the RandomNumberGeneratorService\n"
00084       "which is not present in the configuration file.  You must add the service\n"
00085       "in the configuration file or remove the modules that require it.";
00086   }
00087   
00088   rndEngine = &(rng->getEngine());
00089   theDigiAlgo.reset(new SiStripDigitizerAlgorithm(conf,(*rndEngine)));
00090 
00091 }
00092 
00093 // Virtual destructor needed.
00094 SiStripDigitizer::~SiStripDigitizer() { 
00095 }  
00096 
00097 void SiStripDigitizer::accumulateStripHits(edm::Handle<std::vector<PSimHit> > hSimHits,
00098                                            const TrackerTopology *tTopo, size_t globalSimHitIndex ) {
00099   // globalSimHitIndex is the index the sim hit will have when it is put in a collection
00100   // of sim hits for all crossings. This is only used when creating digi-sim links if
00101   // configured to do so.
00102 
00103   if(hSimHits.isValid()) {
00104     std::set<unsigned int> detIds;
00105     std::vector<PSimHit> const& simHits = *hSimHits.product();
00106     for(std::vector<PSimHit>::const_iterator it = simHits.begin(), itEnd = simHits.end(); it != itEnd; ++it, ++globalSimHitIndex ) {
00107       unsigned int detId = (*it).detUnitId();
00108       if(detIds.insert(detId).second) {
00109         // The insert succeeded, so this detector element has not yet been processed.
00110         unsigned int isub = DetId(detId).subdetId();
00111         if((isub == StripSubdetector::TIB) || (isub == StripSubdetector::TID) || (isub == StripSubdetector::TOB) || (isub == StripSubdetector::TEC)) {
00112           StripGeomDetUnit* stripdet = detectorUnits[detId];
00113           //access to magnetic field in global coordinates
00114           GlobalVector bfield = pSetup->inTesla(stripdet->surface().position());
00115           LogDebug ("Digitizer ") << "B-field(T) at " << stripdet->surface().position() << "(cm): "
00116                                   << pSetup->inTesla(stripdet->surface().position());
00117           theDigiAlgo->accumulateSimHits(it, itEnd, globalSimHitIndex, stripdet, bfield, tTopo);
00118         }
00119       }
00120     } // end of loop over sim hits
00121   }
00122 }
00123 
00124 // Functions that gets called by framework every event
00125   void
00126   SiStripDigitizer::accumulate(edm::Event const& iEvent, edm::EventSetup const& iSetup) {
00127     //Retrieve tracker topology from geometry
00128     edm::ESHandle<TrackerTopology> tTopoHand;
00129     iSetup.get<IdealGeometryRecord>().get(tTopoHand);
00130     const TrackerTopology *tTopo=tTopoHand.product();
00131 
00132     // Step A: Get Inputs
00133     for(vstring::const_iterator i = trackerContainers.begin(), iEnd = trackerContainers.end(); i != iEnd; ++i) {
00134       edm::Handle<std::vector<PSimHit> > simHits;
00135       edm::InputTag tag(hitsProducer, *i);
00136 
00137       iEvent.getByLabel(tag, simHits);
00138       accumulateStripHits(simHits,tTopo,crossingSimHitIndexOffset_[tag.encode()]);
00139       // Now that the hits have been processed, I'll add the amount of hits in this crossing on to
00140       // the global counter. Next time accumulateStripHits() is called it will count the sim hits
00141       // as though they were on the end of this collection.
00142       // Note that this is only used for creating digi-sim links (if configured to do so).
00143       if( simHits.isValid() ) crossingSimHitIndexOffset_[tag.encode()]+=simHits->size();
00144     }
00145   }
00146 
00147   void
00148   SiStripDigitizer::accumulate(PileUpEventPrincipal const& iEvent, edm::EventSetup const& iSetup) {
00149 
00150     edm::ESHandle<TrackerTopology> tTopoHand;
00151     iSetup.get<IdealGeometryRecord>().get(tTopoHand);
00152     const TrackerTopology *tTopo=tTopoHand.product();
00153 
00154     // Step A: Get Inputs
00155     for(vstring::const_iterator i = trackerContainers.begin(), iEnd = trackerContainers.end(); i != iEnd; ++i) {
00156       edm::Handle<std::vector<PSimHit> > simHits;
00157       edm::InputTag tag(hitsProducer, *i);
00158 
00159       iEvent.getByLabel(tag, simHits);
00160       accumulateStripHits(simHits,tTopo,crossingSimHitIndexOffset_[tag.encode()]);
00161       // Now that the hits have been processed, I'll add the amount of hits in this crossing on to
00162       // the global counter. Next time accumulateStripHits() is called it will count the sim hits
00163       // as though they were on the end of this collection.
00164       // Note that this is only used for creating digi-sim links (if configured to do so).
00165       if( simHits.isValid() ) crossingSimHitIndexOffset_[tag.encode()]+=simHits->size();
00166     }
00167   }
00168 
00169 
00170 void SiStripDigitizer::initializeEvent(edm::Event const& iEvent, edm::EventSetup const& iSetup) {
00171   // Make sure that the first crossing processed starts indexing the sim hits from zero.
00172   // This variable is used so that the sim hits from all crossing frames have sequential
00173   // indices used to create the digi-sim link (if configured to do so) rather than starting
00174   // from zero for each crossing.
00175   crossingSimHitIndexOffset_.clear();
00176 
00177   // Step A: Get Inputs
00178 
00179   if(useConfFromDB){
00180     edm::ESHandle<SiStripDetCabling> detCabling;
00181     iSetup.get<SiStripDetCablingRcd>().get(detCabling);
00182     detCabling->addConnected(theDetIdList);
00183   }
00184 
00185   theDigiAlgo->initializeEvent(iSetup);
00186 
00187   iSetup.get<TrackerDigiGeometryRecord>().get(geometryType,pDD);
00188   iSetup.get<IdealMagneticFieldRecord>().get(pSetup);
00189 
00190   // FIX THIS! We only need to clear and (re)fill detectorUnits when the geometry type IOV changes.  Use ESWatcher to determine this.
00191   bool changes = true;
00192   if(changes) { // Replace with ESWatcher
00193     detectorUnits.clear();
00194   }
00195   for(TrackingGeometry::DetUnitContainer::const_iterator iu = pDD->detUnits().begin(); iu != pDD->detUnits().end(); ++iu) {
00196     unsigned int detId = (*iu)->geographicalId().rawId();
00197     DetId idet=DetId(detId);
00198     unsigned int isub=idet.subdetId();
00199     if((isub == StripSubdetector::TIB) ||
00200        (isub == StripSubdetector::TID) ||
00201        (isub == StripSubdetector::TOB) ||
00202        (isub == StripSubdetector::TEC)) {
00203       StripGeomDetUnit* stripdet = dynamic_cast<StripGeomDetUnit*>((*iu));
00204       assert(stripdet != 0);
00205       if(changes) { // Replace with ESWatcher
00206         detectorUnits.insert(std::make_pair(detId, stripdet));
00207       }
00208       theDigiAlgo->initializeDetUnit(stripdet, iSetup);
00209     }
00210   }
00211 }
00212 
00213 void SiStripDigitizer::finalizeEvent(edm::Event& iEvent, edm::EventSetup const& iSetup) {
00214   edm::ESHandle<SiStripGain> gainHandle;
00215   edm::ESHandle<SiStripNoises> noiseHandle;
00216   edm::ESHandle<SiStripThreshold> thresholdHandle;
00217   edm::ESHandle<SiStripPedestals> pedestalHandle;
00218   iSetup.get<SiStripGainSimRcd>().get(gainLabel,gainHandle);
00219   iSetup.get<SiStripNoisesRcd>().get(noiseHandle);
00220   iSetup.get<SiStripThresholdRcd>().get(thresholdHandle);
00221   iSetup.get<SiStripPedestalsRcd>().get(pedestalHandle);
00222 
00223   std::vector<edm::DetSet<SiStripDigi> > theDigiVector;
00224   std::vector<edm::DetSet<SiStripRawDigi> > theRawDigiVector;
00225   std::auto_ptr< edm::DetSetVector<StripDigiSimLink> > pOutputDigiSimLink( new edm::DetSetVector<StripDigiSimLink> );
00226   
00227   // Step B: LOOP on StripGeomDetUnit
00228   theDigiVector.reserve(10000);
00229   theDigiVector.clear();
00230 
00231   for(TrackingGeometry::DetUnitContainer::const_iterator iu = pDD->detUnits().begin(); iu != pDD->detUnits().end(); iu ++){
00232     if(useConfFromDB){
00233       //apply the cable map _before_ digitization: consider only the detis that are connected 
00234       if(theDetIdList.find((*iu)->geographicalId().rawId())==theDetIdList.end())
00235         continue;
00236     }
00237     StripGeomDetUnit* sgd = dynamic_cast<StripGeomDetUnit*>((*iu));
00238     if (sgd != 0){
00239       edm::DetSet<SiStripDigi> collectorZS((*iu)->geographicalId().rawId());
00240       edm::DetSet<SiStripRawDigi> collectorRaw((*iu)->geographicalId().rawId());
00241       edm::DetSet<StripDigiSimLink> collectorLink((*iu)->geographicalId().rawId());
00242       theDigiAlgo->digitize(collectorZS,collectorRaw,collectorLink,sgd,
00243                        gainHandle,thresholdHandle,noiseHandle,pedestalHandle);
00244       if(zeroSuppression){
00245         if(collectorZS.data.size()>0){
00246           theDigiVector.push_back(collectorZS);
00247           if( !collectorLink.data.empty() ) pOutputDigiSimLink->insert(collectorLink);
00248         }
00249       }else{
00250         if(collectorRaw.data.size()>0){
00251           theRawDigiVector.push_back(collectorRaw);
00252           if( !collectorLink.data.empty() ) pOutputDigiSimLink->insert(collectorLink);
00253         }
00254       }
00255     }
00256   }
00257 
00258   if(zeroSuppression){
00259     // Step C: create output collection
00260     std::auto_ptr<edm::DetSetVector<SiStripRawDigi> > output_virginraw(new edm::DetSetVector<SiStripRawDigi>());
00261     std::auto_ptr<edm::DetSetVector<SiStripRawDigi> > output_scopemode(new edm::DetSetVector<SiStripRawDigi>());
00262     std::auto_ptr<edm::DetSetVector<SiStripRawDigi> > output_processedraw(new edm::DetSetVector<SiStripRawDigi>());
00263     std::auto_ptr<edm::DetSetVector<SiStripDigi> > output(new edm::DetSetVector<SiStripDigi>(theDigiVector) );
00264     // Step D: write output to file
00265     iEvent.put(output, ZSDigi);
00266     iEvent.put(output_scopemode, SCDigi);
00267     iEvent.put(output_virginraw, VRDigi);
00268     iEvent.put(output_processedraw, PRDigi);
00269     if( makeDigiSimLinks_ ) iEvent.put( pOutputDigiSimLink ); // The previous EDProducer didn't name this collection so I won't either
00270   }else{
00271     // Step C: create output collection
00272     std::auto_ptr<edm::DetSetVector<SiStripRawDigi> > output_virginraw(new edm::DetSetVector<SiStripRawDigi>(theRawDigiVector));
00273     std::auto_ptr<edm::DetSetVector<SiStripRawDigi> > output_scopemode(new edm::DetSetVector<SiStripRawDigi>());
00274     std::auto_ptr<edm::DetSetVector<SiStripRawDigi> > output_processedraw(new edm::DetSetVector<SiStripRawDigi>());
00275     std::auto_ptr<edm::DetSetVector<SiStripDigi> > output(new edm::DetSetVector<SiStripDigi>() );
00276     // Step D: write output to file
00277     iEvent.put(output, ZSDigi);
00278     iEvent.put(output_scopemode, SCDigi);
00279     iEvent.put(output_virginraw, VRDigi);
00280     iEvent.put(output_processedraw, PRDigi);
00281     if( makeDigiSimLinks_ ) iEvent.put( pOutputDigiSimLink ); // The previous EDProducer didn't name this collection so I won't either
00282   }
00283 }