CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_2_SLHC4_patch1/src/SimRomanPot/SimFP420/src/FP420DigiMain.cc

Go to the documentation of this file.
00001 
00002 // File: FP420DigiMain.cc
00003 // Date: 12.2006
00004 // Description: FP420DigiMain for FP420
00005 // Modifications: 
00007 #include "SimDataFormats/TrackingHit/interface/PSimHit.h"
00008 #include "SimDataFormats/TrackingHit/interface/PSimHitContainer.h"
00009 
00010 //#include "SimG4CMS/FP420/interface/FP420G4HitCollection.h"
00011 //#include "SimG4CMS/FP420/interface/FP420G4Hit.h"
00012 //#include "SimRomanPot/SimFP420/interface/SimRPUtil.h"
00013 #include "SimRomanPot/SimFP420/interface/FP420DigiMain.h"
00014 
00015 #include "SimRomanPot/SimFP420/interface/ChargeDrifterFP420.h"
00016 #include "SimRomanPot/SimFP420/interface/ChargeDividerFP420.h"
00017 
00018 //#include "SimRomanPot/SimFP420/interface/HDigiFP420.h"
00019 #include "DataFormats/FP420Digi/interface/HDigiFP420.h"
00020 //#include "DataFormats/SiStripDigi/interface/SiStripDigi.h"
00021 //#include "DataFormats/Common/interface/DetSetVector.h"
00022 //#include "SimDataFormats/TrackerDigiSimLink/interface/StripDigiSimLink.h"
00023 
00024 
00025 
00026 
00027 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00028 #include <gsl/gsl_sf_erf.h>
00029 #include "CLHEP/Random/RandGauss.h"
00030 #include "CLHEP/Random/RandFlat.h"
00031 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00032 
00033 #include <vector>
00034 #include <iostream>
00035 using namespace std;
00036 
00037 //#define CBOLTZ (1.38E-23)
00038 //#define e_SI (1.6E-19)
00039 
00040 
00041 
00042 FP420DigiMain::FP420DigiMain(const edm::ParameterSet& conf):conf_(conf){
00043   std::cout << "Creating a FP420DigiMain" << std::endl;
00044   ndigis=0;
00045   verbosity        = conf_.getUntrackedParameter<int>("VerbosityLevel");
00046   theElectronPerADC= conf_.getParameter<double>("ElectronFP420PerAdc");
00047   theThreshold     = conf_.getParameter<double>("AdcFP420Threshold");
00048   noNoise          = conf_.getParameter<bool>("NoFP420Noise");
00049   addNoisyPixels   = conf_.getParameter<bool>("AddNoisyPixels");
00050   thez420          = conf_.getParameter<double>("z420");
00051   thezD2           = conf_.getParameter<double>("zD2");
00052   thezD3           = conf_.getParameter<double>("zD3");
00053   theApplyTofCut   = conf_.getParameter<bool>("ApplyTofCut");
00054   tofCut           = conf_.getParameter<double>("LowtofCutAndTo200ns");
00055   //  sn0              = 3;// number of stations
00056   // pn0              = 6;// number of superplanes
00057   // rn0              = 3; // number of sensors in superlayer
00058   xytype           = 2;
00059   if(verbosity>0) {
00060     std::cout << "theApplyTofCut=" << theApplyTofCut << " tofCut=" << tofCut << std::endl;
00061     std::cout << "FP420DigiMain theElectronPerADC=" << theElectronPerADC << " theThreshold=" << theThreshold << " noNoise=" << noNoise << std::endl;
00062   }
00063   // X (or Y)define type of sensor (xytype=1 or 2 used to derive it: 1-Y, 2-X)
00064   // for every type there is normal pixel size=0.05 and Wide 0.400 mm
00065   Thick300 = 0.300;       // = 0.300 mm  normalized to 300micron Silicon
00066   //ENC= 2160.;             //          EquivalentNoiseCharge300um = 2160. + other sources of noise
00067   ENC= 960.;             //          EquivalentNoiseCharge300um = 2160. + other sources of noise
00068   
00069   ldriftX = 0.050;        // in mm(xytype=1)
00070   ldriftY = 0.050;        // in mm(xytype=2)
00071   moduleThickness = 0.250; // mm(xytype=1)(xytype=2)
00072   
00073   pitchY= 0.050;          // in mm(xytype=1)
00074   pitchX= 0.050;          // in mm(xytype=2)
00075   //numStripsY = 200;        // Y plate number of strips:200*0.050=10mm (xytype=1)
00076   //numStripsX = 400;        // X plate number of strips:400*0.050=20mm (xytype=2)
00077   numStripsY = 144;        // Y plate number of strips:144*0.050=7.2mm (xytype=1)
00078   numStripsX = 160;        // X plate number of strips:160*0.050=8.0mm (xytype=2)
00079   
00080   pitchYW= 0.400;          // in mm(xytype=1)
00081   pitchXW= 0.400;          // in mm(xytype=2)
00082   //numStripsYW = 50;        // Y plate number of W strips:50 *0.400=20mm (xytype=1) - W have ortogonal projection
00083   //numStripsXW = 25;        // X plate number of W strips:25 *0.400=10mm (xytype=2) - W have ortogonal projection
00084   numStripsYW = 20;        // Y plate number of W strips:20 *0.400=8.0mm (xytype=1) - W have ortogonal projection
00085   numStripsXW = 18;        // X plate number of W strips:18 *0.400=7.2mm (xytype=2) - W have ortogonal projection
00086   
00087   //  tofCut = 1350.;           // Cut on the particle TOF range  = 1380 - 1500
00088   elossCut = 0.00003;           // Cut on the particle TOF   = 100 or 50
00089   
00090   if(verbosity>0) std::cout << "FP420DigiMain moduleThickness=" << moduleThickness << std::endl;
00091   
00092   theFP420NumberingScheme = new FP420NumberingScheme();
00093   
00094   float noiseRMS = ENC*moduleThickness/Thick300;
00095   
00096 
00097 
00099   // Y:
00100   if (xytype ==1) {
00101     numStrips = numStripsY;  // Y plate number of strips:200*0.050=10mm --> 100*0.100=10mm
00102     pitch= pitchY;
00103     ldrift = ldriftX; // because drift is in local coordinates which 90 degree rotated ( for correct timeNormalization & noiseRMS calculations)
00104     numStripsW = numStripsYW;  // Y plate number of strips:200*0.050=10mm --> 100*0.100=10mm
00105     pitchW= pitchYW;
00106   }
00107   // X:
00108   if (xytype ==2) {
00109     numStrips = numStripsX;  // X plate number of strips:400*0.050=20mm --> 200*0.100=20mm
00110     pitch= pitchX;
00111     ldrift = ldriftY; // because drift is in local coordinates which 90 degree rotated ( for correct timeNormalization & noiseRMS calculations)
00112     numStripsW = numStripsXW;  // X plate number of strips:400*0.050=20mm --> 200*0.100=20mm
00113     pitchW= pitchXW;
00114   }
00115   
00116   //  float noiseRMS = ENC*moduleThickness/Thick300;
00117   
00118   
00119   theHitDigitizerFP420 = new HitDigitizerFP420(moduleThickness,ldrift,ldriftY,ldriftX,thez420,thezD2,thezD3,verbosity);
00120   int numPixels = numStrips*numStripsW;
00121   theGNoiseFP420 = new GaussNoiseFP420(numPixels,noiseRMS,theThreshold,addNoisyPixels,verbosity);
00122   //  theGNoiseFP420 = new GaussNoiseFP420(numStrips,noiseRMS,theThreshold,addNoisyPixels);
00124 
00125 
00126 
00127 
00128   theZSuppressFP420 = new ZeroSuppressFP420(conf_,noiseRMS/theElectronPerADC); 
00129   thePileUpFP420 = new PileUpFP420();
00130   theDConverterFP420 = new DigiConverterFP420(theElectronPerADC,verbosity);
00131   
00132   if(verbosity>0) std::cout << "FP420DigiMain end of constructor" << std::endl;
00133 
00134 }
00135 
00136 
00137 
00138 
00139 
00140 
00141 
00142 FP420DigiMain::~FP420DigiMain(){
00143   if(verbosity>0) {
00144     std::cout << "Destroying a FP420DigiMain" << std::endl;
00145   }
00146   delete theGNoiseFP420;
00147   delete theZSuppressFP420;
00148   delete theHitDigitizerFP420;
00149   delete thePileUpFP420;
00150   delete theDConverterFP420;
00151   
00152 }
00153 
00154 
00155 
00156 //  Run the algorithm
00157 //  ------------------
00158 
00159 vector <HDigiFP420> FP420DigiMain::run(const std::vector<PSimHit> &input,
00160                                        G4ThreeVector bfield, unsigned int iu )  {
00161 
00162   /*  
00163   int det, zside, sector, zmodule;
00164   //  theFP420NumberingScheme->FP420NumberingScheme::unpackMYIndex(iu, rn0, pn0, sn0, det, zside, sector, zmodule);
00165   theFP420NumberingScheme->unpackMYIndex(iu, rn0, pn0, sn0, det, zside, sector, zmodule);
00166 */  
00167   thePileUpFP420->reset();
00168   //  unsigned int detID = det->globalId().rawId();
00169   //  unsigned int detID = 1;
00170   bool first = true;
00171   
00172   // main loop 
00173   //
00174   // First: loop on the SimHits
00175   //
00176   std::vector<PSimHit>::const_iterator simHitIter = input.begin();
00177   std::vector<PSimHit>::const_iterator simHitIterEnd = input.end();
00178   for (;simHitIter != simHitIterEnd; ++simHitIter) {
00179     
00180     const PSimHit ihit = *simHitIter;
00181 
00182     if ( first ) {
00183       //       detID = ihit.detUnitId();
00184       first = false;
00185     }
00186 
00187     // main part here:
00188     double  losenergy = ihit.energyLoss();
00189     float   tof = ihit.tof();
00190 
00191     if(verbosity>1) {
00192       unsigned int unitID = ihit.detUnitId();
00193       std::cout << " *******FP420DigiMain:                           intindex= " << iu << std::endl;
00194       std::cout << " tof= " << tof << "  EnergyLoss= " << losenergy  << "  pabs= " <<  ihit.pabs() << std::endl;
00195       std::cout << " EntryLocalP x= " << ihit.entryPoint().x() << " EntryLocalP y= " << ihit.entryPoint().y() << std::endl;
00196       std::cout << " ExitLocalP x= " << ihit.exitPoint().x() << " ExitLocalP y= " << ihit.exitPoint().y() << std::endl;
00197       std::cout << " EntryLocalP z= " << ihit.entryPoint().z() << " ExitLocalP z= " << ihit.exitPoint().z() << std::endl;
00198       std::cout << " unitID= " << unitID << "  xytype= " << xytype << " particleType= " << ihit.particleType() << " trackId= " << ihit.trackId() << std::endl;
00199       //    std::cout << " det= " << det << " sector= " << sector << "  zmodule= " << zmodule << std::endl;
00200       std::cout << "  bfield= " << bfield << std::endl;
00201     }
00202   if(verbosity>0) {
00203       std::cout << " *******FP420DigiMain:                           theApplyTofCut= " << theApplyTofCut << std::endl;
00204       std::cout << " tof= " << tof << "  EnergyLoss= " << losenergy  << "  pabs= " <<  ihit.pabs() << std::endl;
00205       std::cout << " particleType= " << ihit.particleType() << std::endl;
00206   }
00207 
00208   //
00209 
00210   //  if ( ( !(theApplyTofCut)  ||  (theApplyTofCut &&   tofCut < abs(tof) < (tofCut+200.)) ) && losenergy > elossCut) {
00211     if ( ( !(theApplyTofCut)  ||  ( theApplyTofCut &&   abs(tof) > tofCut && abs(tof) < (tofCut+200.)) ) && losenergy > elossCut) {
00212       //    if ( abs(tof) < tofCut && losenergy > elossCut) {
00213       // if ( losenergy>0) {
00214       if(verbosity>0) std::cout << " inside tof: OK " << std::endl;
00215       
00216       //   xytype = 1 - Y strips;   =2 - X strips;
00217       //          HitDigitizerFP420::hit_map_type _temp = theHitDigitizerFP420->processHit(ihit,bfield,xytype,numStrips,pitch);
00218       HitDigitizerFP420::hit_map_type _temp = theHitDigitizerFP420->processHit(ihit,bfield,xytype,numStrips,pitch,numStripsW,pitchW,moduleThickness,verbosity); 
00219       
00220       
00221       
00222       thePileUpFP420->add(_temp,ihit,verbosity);
00223       
00224     }// if
00225 
00226     else {
00227       //    std::cout << " *******FP420DigiMain: ERROR???  losenergy =  " <<  losenergy  << std::endl;
00228     }
00229     // main part end (AZ) 
00230   } //for
00231   // main loop end (AZ) 
00232   
00233   PileUpFP420::signal_map_type theSignal = thePileUpFP420->dumpSignal();
00234   PileUpFP420::HitToDigisMapType theLink = thePileUpFP420->dumpLink();  
00235   
00236   
00237   PileUpFP420::signal_map_type afterNoise;
00238   
00239   if (noNoise) {
00240     afterNoise = theSignal;
00241   } else {
00242     afterNoise = theGNoiseFP420->addNoise(theSignal);
00243     //    add_noise();
00244   }
00245   
00246   //  if((pixelInefficiency>0) && (_signal.size()>0)) 
00247   //  pixel_inefficiency(); // Kill some pixels
00248   
00249   
00250   
00251   digis.clear();
00252   
00253   
00254   
00255   //                                                                                                                !!!!!
00256   push_digis(theZSuppressFP420->zeroSuppress(theDConverterFP420->convert(afterNoise),verbosity),
00257              theLink,afterNoise);
00258   
00259   
00260   
00261   return digis; // to HDigiFP420
00262 }
00263 
00264 
00265 
00266 
00267 
00268 void FP420DigiMain::push_digis(const DigitalMapType& dm,
00269                                const HitToDigisMapType& htd,
00270                                const PileUpFP420::signal_map_type& afterNoise
00271                                )        {
00272   //  
00273   if(verbosity>0) {
00274     std::cout << " ****FP420DigiMain: push_digis start: do for loop dm.size()=" <<  dm.size() << std::endl;
00275   }
00276   
00277   
00278   digis.reserve(50); 
00279   digis.clear();
00280   //   link_coll.clear();
00281   for ( DigitalMapType::const_iterator i=dm.begin(); i!=dm.end(); i++) {
00282     
00283     // Load digis
00284     // push to digis the content of first and second words of HDigiFP420 vector for every strip pointer (*i)
00285     digis.push_back( HDigiFP420( (*i).first, (*i).second));
00286     ndigis++; 
00287     // very useful check:
00288     if(verbosity>0) {
00289       std::cout << " ****FP420DigiMain:push_digis:  ndigis = " << ndigis << std::endl;
00290       std::cout << "push_digis: strip  = " << (*i).first << "  adc = " << (*i).second << std::endl;
00291     }    
00292     
00293   }
00294   
00296   /*       
00297   //
00298   // reworked to access the fraction of amplitude per simhit PSimHit
00299   //
00300   for ( HitToDigisMapType::const_iterator mi=htd.begin(); mi!=htd.end(); mi++) {
00301   #ifdef mydigidebug1
00302   std::cout << " ****push_digis:first for:  (*mi).first = " << (*mi).first << std::endl;
00303   std::cout << " if condition   = " << (*((const_cast<DigitalMapType * >(&dm))))[(*mi).first] << std::endl;
00304   #endif
00305   //    if ((*((const_cast<DigitalMapType * >(&dm))))[(*mi).first] != 0){
00306   if ((*((const_cast<DigitalMapType * >(&dm)))).find((*mi).first) != (*((const_cast<DigitalMapType * >(&dm)))).end() ){
00307   //
00308   // For each channel, sum up the signals from a simtrack
00309   //
00310   std::map<const PSimHit *, Amplitude> totalAmplitudePerSimHit;
00311   for (std::vector < std::pair < const PSimHit*, Amplitude > >::const_iterator simul = 
00312   (*mi).second.begin() ; simul != (*mi).second.end(); simul ++){
00313   #ifdef mydigidebug1
00314   std::cout << " ****push_digis:inside last for: (*simul).second= " << (*simul).second << std::endl;
00315   #endif
00316   totalAmplitudePerSimHit[(*simul).first] += (*simul).second;
00317   } // for
00318   }  // if
00319   } // for
00320   */
00321   
00323     
00324     // reworked to access the fraction of amplitude per simhit
00325     
00326     for ( HitToDigisMapType::const_iterator mi=htd.begin(); mi!=htd.end(); mi++) {
00327       //      
00328       if ((*((const_cast<DigitalMapType * >(&dm)))).find((*mi).first) != (*((const_cast<DigitalMapType * >(&dm)))).end() ){
00329         // --- For each channel, sum up the signals from a simtrack
00330         //
00331         map<const PSimHit *, Amplitude> totalAmplitudePerSimHit;
00332         for (std::vector < std::pair < const PSimHit*, Amplitude > >::const_iterator simul =
00333                (*mi).second.begin() ; simul != (*mi).second.end(); simul ++){
00334           totalAmplitudePerSimHit[(*simul).first] += (*simul).second;
00335         }
00336         /*      
00337         //--- include the noise as well
00338         
00339         PileUpFP420::signal_map_type& temp1 = const_cast<PileUpFP420::signal_map_type&>(afterNoise);
00340         float totalAmplitude1 = temp1[(*mi).first];
00341         
00342         //--- digisimlink
00343         for (std::map<const PSimHit *, Amplitude>::const_iterator iter = totalAmplitudePerSimHit.begin();
00344         iter != totalAmplitudePerSimHit.end(); iter++){
00345         
00346         float threshold = 0.;
00347         if (totalAmplitudePerSimHit[(*iter).first]/totalAmplitude1 >= threshold) {
00348         float fraction = totalAmplitudePerSimHit[(*iter).first]/totalAmplitude1;
00349         
00350         //Noise fluctuation could make fraction>1. Unphysical, set it by hand.
00351         if(fraction >1.) fraction = 1.;
00352         
00353         link_coll.push_back(StripDigiSimLink( (*mi).first,   //channel
00354         ((*iter).first)->trackId(), //simhit
00355         fraction));    //fraction
00356         }//if
00357         }//for
00358         */
00359         //
00360       }//if
00361     }//for
00362     //
00363     //
00365       //      
00366       //      
00367       //      
00368       }