CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_1/src/FastSimulation/Calorimetry/src/CalorimetryManager.cc

Go to the documentation of this file.
00001 //Framework headers 
00002 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00003 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00004 
00005 // Fast Simulation headers
00006 #include "FastSimulation/Calorimetry/interface/CalorimetryManager.h"
00007 #include "FastSimulation/Event/interface/FSimEvent.h"
00008 #include "FastSimulation/Event/interface/FSimTrack.h"
00009 #include "FastSimulation/ShowerDevelopment/interface/EMECALShowerParametrization.h"
00010 #include "FastSimulation/ShowerDevelopment/interface/EMShower.h"
00011 #include "FastSimulation/ShowerDevelopment/interface/HDShowerParametrization.h"
00012 #include "FastSimulation/ShowerDevelopment/interface/HDShower.h"
00013 #include "FastSimulation/ShowerDevelopment/interface/HFShower.h"
00014 #include "FastSimulation/ShowerDevelopment/interface/HDRShower.h"
00015 #include "FastSimulation/ShowerDevelopment/interface/HSParameters.h"
00016 #include "FastSimulation/CaloGeometryTools/interface/CaloGeometryHelper.h"
00017 #include "FastSimulation/CaloHitMakers/interface/EcalHitMaker.h"
00018 #include "FastSimulation/CaloHitMakers/interface/HcalHitMaker.h"
00019 #include "FastSimulation/CaloHitMakers/interface/PreshowerHitMaker.h"
00020 //#include "FastSimulation/Utilities/interface/Histos.h"
00021 #include "FastSimulation/Utilities/interface/RandomEngine.h"
00022 #include "FastSimulation/Utilities/interface/GammaFunctionGenerator.h"
00023 #include "FastSimulation/Utilities/interface/LandauFluctuationGenerator.h"
00024 #include "DataFormats/HcalDetId/interface/HcalSubdetector.h"
00025 #include "Geometry/CaloGeometry/interface/CaloSubdetectorGeometry.h"  
00026 #include "DataFormats/HcalDetId/interface/HcalDetId.h"
00027 #include "DataFormats/EcalDetId/interface/EBDetId.h"
00028 #include "DataFormats/EcalDetId/interface/EEDetId.h"
00029 #include "FastSimulation/Event/interface/FSimTrackEqual.h"
00030 // New headers for Muon Mip Simulation
00031 #include "FastSimulation/MaterialEffects/interface/MaterialEffects.h"
00032 #include "FastSimulation/MaterialEffects/interface/EnergyLossSimulator.h"
00033 // Muon Brem
00034 #include "FastSimulation/MaterialEffects/interface/MuonBremsstrahlungSimulator.h"
00035 
00036 //Gflash Hadronic Model
00037 #include "SimGeneral/GFlash/interface/GflashHadronShowerProfile.h"
00038 #include "SimGeneral/GFlash/interface/GflashPiKShowerProfile.h"
00039 #include "SimGeneral/GFlash/interface/GflashProtonShowerProfile.h"
00040 #include "SimGeneral/GFlash/interface/GflashAntiProtonShowerProfile.h"
00041 #include "SimGeneral/GFlash/interface/GflashTrajectoryPoint.h"
00042 #include "SimGeneral/GFlash/interface/GflashHit.h"
00043 #include "SimGeneral/GFlash/interface/Gflash3Vector.h"
00044 // STL headers 
00045 #include <vector>
00046 #include <iostream>
00047 
00048 //DQM
00049 #include "FWCore/ServiceRegistry/interface/Service.h"
00050 #include "DQMServices/Core/interface/DQMStore.h"
00051 #include "DQMServices/Core/interface/MonitorElement.h"
00052 
00053 //CMSSW headers 
00054 #include "DataFormats/DetId/interface/DetId.h"
00055 #include "DataFormats/HcalDetId/interface/HcalDetId.h"
00056 //#include "DataFormats/EcalDetId/interface/EcalDetId.h"
00057 
00058 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00059 
00060 //ROOT headers
00061 #include "TROOT.h"
00062 #include "TH1.h"
00063 
00064 using namespace edm;
00065 
00066 typedef math::XYZVector XYZVector;
00067 typedef math::XYZVector XYZPoint;
00068 
00069 std::vector<std::pair<int,float> > CalorimetryManager::myZero_ = std::vector<std::pair<int,float> >
00070 (1,std::pair<int,float>(0,0.));
00071 
00072 CalorimetryManager::CalorimetryManager() : 
00073   myCalorimeter_(0),
00074   //  myHistos(0),
00075   random(0),initialized_(false)
00076 {;}
00077 
00078 CalorimetryManager::CalorimetryManager(FSimEvent * aSimEvent, 
00079                                        const edm::ParameterSet& fastCalo,
00080                                        const edm::ParameterSet& fastMuECAL,
00081                                        const edm::ParameterSet& fastMuHCAL,
00082                                        const edm::ParameterSet& parGflash,
00083                                        const RandomEngine* engine)
00084   : 
00085   mySimEvent(aSimEvent), 
00086   random(engine), initialized_(false),
00087   theMuonEcalEffects(0), theMuonHcalEffects (0), bFixedLength_(false)
00088 
00089 {
00090 
00091   aLandauGenerator = new LandauFluctuationGenerator(random);
00092   aGammaGenerator = new GammaFunctionGenerator(random);
00093 
00094   //Gflash
00095   theProfile = new GflashHadronShowerProfile(parGflash);
00096   thePiKProfile = new GflashPiKShowerProfile(parGflash);
00097   theProtonProfile = new GflashProtonShowerProfile(parGflash);
00098   theAntiProtonProfile = new GflashAntiProtonShowerProfile(parGflash);
00099 
00100   readParameters(fastCalo);
00101 
00102 //  EBMapping_.resize(62000,myZero_);
00103 //  EEMapping_.resize(20000,myZero_);
00104 //  HMapping_.resize(10000,myZero_);
00105   EBMapping_.resize(62000);
00106   EEMapping_.resize(20000);
00107 
00108   unsigned s=(unfoldedMode_)?5:1;
00109   for(unsigned ic=0;ic<62000;++ic)
00110     {
00111       EBMapping_[ic].reserve(s);
00112       if(ic<20000)
00113         EEMapping_[ic].reserve(s);
00114     }
00115 
00116   //  myHistos = 0; 
00117 
00118   dbe = edm::Service<DQMStore>().operator->();
00119 
00120   if (useDQM_){
00121         TH1::SetDefaultSumw2(true); //turn on histo errors
00122   
00123         //ECAL histos
00124     dbe->setCurrentFolder("EMShower");
00125      // please keep the binning with fixed width and coherent between ShapeRhoZ and Tr/Lo shapes. Also check if you 
00126      // change the binning that the weight changes in the filling in EMShower.cc
00127     dbe->book1D("TransverseShape","Transverse Shape; #rho / Moliere radius; 1/E dE/d#rho",70, 0., 7.);
00128     dbe->book1D("LongitudinalShape","Longitudinal Shape; z / X0; 1/E dE/dz",40, 0.01, 40.01);
00129     dbe->book1D("LongitudinalShapeLayers","Longitudinal Shape in number of layers; z / Layers; 1/E dE/dz", 26, 0.01, 26.01);
00130     dbe->book2D("ShapeRhoZ","2D Shape; #rho / Moliere radius; z / X0", 70, 0., 7., 26, 0.01, 26.01);
00131     dbe->book1D("NumberOfParticles","Number Of Particles entering the Shower; #Particles; #Events", 6, -0.5, 5.5);
00132     dbe->book1D("ParticlesEnergy","Log Particles Energy; log10(E / GeV); #Particles", 30, 0, 3);
00133         
00134         //HCAL histos
00135     dbe->setCurrentFolder("HDShower");
00136 
00137     dbe->book1D("TransverseShapeECAL","ECAL Transverse Shape; #rho / #lambda_{int}; 1/E dE/d#rho",70, 0., 7.);
00138     dbe->book1D("LongitudinalShapeECAL","ECAL Longitudinal Shape; z / #lambda_{int}; 1/E dE/dz",20, 0., 2.);
00139     dbe->book1D("TransverseShapeHCAL","HCAL Transverse Shape; #rho / #lambda_{int}; 1/E dE/d#rho",70, 0., 7.);
00140     dbe->book1D("LongitudinalShapeHCAL","HCAL Longitudinal Shape; z / #lambda_{int}; 1/E dE/dz",120, 0., 12.);       
00141     dbe->book1D("ParticlesEnergy","Log Particles Energy; log10(E / GeV); #Particles", 30, 0, 3);
00142 
00143     dbe->setCurrentFolder("HDEnergies");
00144     dbe->book1D("EpECAL","ECAL perfect energy; E / Egen; # events",200,0,2);
00145     dbe->book1D("EsECAL","ECAL smeared energy; E / Egen; # events",200,0,2);
00146     dbe->book1D("EpHCAL","HCAL perfect energy; E / Egen; # events",200,0,2);
00147     dbe->book1D("EsHCAL","HCAL smeared energy; E / Egen; # events",200,0,2);
00148     dbe->book1D("EpTot","Total perfect energy; E / Egen; # events",200,0,2);
00149     dbe->book1D("EsTot","Total smeared energy; E / Egen; # events",200,0,2);
00150         
00151   }
00152 
00153 //   myHistos = Histos::instance();
00154 //   myHistos->book("h10",140,-3.5,3.5,100,-0.5,99.5);
00155 //   myHistos->book("h20",150,0,150.,100,-0.5,99.5);
00156 //   myHistos->book("h100",140,-3.5,3.5,100,0,0.1);
00157 //   myHistos->book("h110",140,-3.5,3.5,100,0,10.);
00158 //   myHistos->book("h120",200,-5.,5.,100,0,0.5);
00159 
00160 //   myHistos->book("h200",300,0,3.,100,0.,35.);
00161 //   myHistos->book("h210",720,-M_PI,M_PI,100,0,35.);
00162 //   myHistos->book("h212",720,-M_PI,M_PI,100,0,35.);
00163 
00164 //   myHistos->bookByNumber("h30",0,7,300,-3.,3.,100,0.,35.);
00165 //   myHistos->book("h310",75,-3.,3.,"");
00166 //   myHistos->book("h400",100,-10.,10.,100,0.,35.);
00167 //   myHistos->book("h410",720,-M_PI,M_PI);
00168 
00169   myCalorimeter_ = 
00170     new CaloGeometryHelper(fastCalo);
00171   myHDResponse_ = 
00172     new HCALResponse(fastCalo.getParameter<edm::ParameterSet>("HCALResponse"),
00173                      random);
00174   myHSParameters_ = 
00175     new HSParameters(fastCalo.getParameter<edm::ParameterSet>("HSParameters"));
00176 
00177   // Material Effects for Muons in ECAL (only EnergyLoss implemented so far)
00178 
00179   if ( fastMuECAL.getParameter<bool>("PairProduction") || 
00180        fastMuECAL.getParameter<bool>("Bremsstrahlung") ||
00181        fastMuECAL.getParameter<bool>("MuonBremsstrahlung") ||
00182        fastMuECAL.getParameter<bool>("EnergyLoss") || 
00183        fastMuECAL.getParameter<bool>("MultipleScattering") )
00184     theMuonEcalEffects = new MaterialEffects(fastMuECAL,random);
00185 
00186   // Material Effects for Muons in HCAL (only EnergyLoss implemented so far)
00187 
00188   if ( fastMuHCAL.getParameter<bool>("PairProduction") || 
00189        fastMuHCAL.getParameter<bool>("Bremsstrahlung") ||
00190        fastMuHCAL.getParameter<bool>("MuonBremsstrahlung") ||
00191        fastMuHCAL.getParameter<bool>("EnergyLoss") || 
00192        fastMuHCAL.getParameter<bool>("MultipleScattering") )
00193     theMuonHcalEffects = new MaterialEffects(fastMuHCAL,random);
00194 
00195 
00196 }
00197 
00198 void CalorimetryManager::clean()
00199 {
00200   unsigned size=firedCellsEB_.size();
00201   for(unsigned ic=0;ic<size;++ic)
00202     {
00203       EBMapping_[firedCellsEB_[ic]].clear();
00204     }
00205   firedCellsEB_.clear();
00206 
00207   size=firedCellsEE_.size();
00208   for(unsigned ic=0;ic<size;++ic)
00209     {
00210       EEMapping_[firedCellsEE_[ic]].clear();
00211     }
00212   firedCellsEE_.clear();
00213   
00214   HMapping_.clear();
00215   firedCellsHCAL_.clear();
00216 
00217   ESMapping_.clear();
00218   muonSimTracks.clear();
00219 }
00220 
00221 CalorimetryManager::~CalorimetryManager()
00222 {
00223   if(myCalorimeter_) delete myCalorimeter_;
00224   if(myHDResponse_) delete myHDResponse_;
00225 
00226   if ( theMuonEcalEffects ) delete theMuonEcalEffects;
00227   if ( theMuonHcalEffects ) delete theMuonHcalEffects;
00228 
00229   if ( theProfile ) delete theProfile;
00230 }
00231 
00232 void CalorimetryManager::reconstruct()
00233 {
00234 
00235   if(evtsToDebug_.size())
00236     {
00237       std::vector<unsigned int>::const_iterator itcheck=find(evtsToDebug_.begin(),evtsToDebug_.end(),mySimEvent->id().event());
00238       debug_=(itcheck!=evtsToDebug_.end());
00239       if(debug_)
00240         mySimEvent->print();
00241     }
00242   // Clear the content of the calorimeters 
00243   if(!initialized_)
00244     {
00245       
00246       // Check if the preshower is really available
00247       if(simulatePreshower_ && !myCalorimeter_->preshowerPresent())
00248         {
00249           std::cout << " WARNING " << std::endl;
00250           std::cout << " The preshower simulation has been turned on; but no preshower geometry is available " << std::endl;
00251           std::cout << " Disabling the preshower simulation " << std::endl;
00252           simulatePreshower_ = false;
00253         }
00254 
00255       initialized_=true;
00256     }
00257   clean();
00258 
00259   LogInfo("FastCalorimetry") << "Reconstructing " << (int) mySimEvent->nTracks() << " tracks." << std::endl;
00260   for( int fsimi=0; fsimi < (int) mySimEvent->nTracks() ; ++fsimi) {
00261 
00262     FSimTrack& myTrack = mySimEvent->track(fsimi);
00263 
00264     int pid = abs(myTrack.type());
00265 
00266     if (debug_) {
00267       LogInfo("FastCalorimetry") << " ===> pid = "  << pid << std::endl;      
00268     }
00269     
00270     
00271     // Check that the particle hasn't decayed
00272     if(myTrack.noEndVertex()) {
00273       // Simulate energy smearing for photon and electrons
00274       if ( pid == 11 || pid == 22 ) {
00275           
00276           
00277            if ( myTrack.onEcal() ) 
00278             EMShowerSimulation(myTrack);
00279           else if ( myTrack.onVFcal() )
00280             reconstructHCAL(myTrack);
00281            
00282       } // electron or photon
00283       else if (pid==13)
00284         {
00285           MuonMipSimulation(myTrack);
00286         }
00287       // Simulate energy smearing for hadrons (i.e., everything 
00288       // but muons... and SUSY particles that deserve a special 
00289       // treatment.
00290       else if ( pid < 1000000 ) {
00291         if ( myTrack.onHcal() || myTrack.onVFcal() ) {    
00292           if(optionHDSim_ == 0 )  reconstructHCAL(myTrack);
00293           else HDShowerSimulation(myTrack);
00294         }
00295       } // pid < 1000000 
00296     } // myTrack.noEndVertex()
00297   } // particle loop
00298   //  LogInfo("FastCalorimetry") << " Number of  hits (barrel)" << EBMapping_.size() << std::endl;
00299   //  LogInfo("FastCalorimetry") << " Number of  hits (Hcal)" << HMapping_.size() << std::endl;
00300   //  std::cout << " Nombre de hit (endcap)" << EEMapping_.size() << std::endl;
00301 
00302 } // reconstruct
00303 
00304 // Simulation of electromagnetic showers in PS, ECAL, HCAL 
00305 void CalorimetryManager::EMShowerSimulation(const FSimTrack& myTrack) {
00306   std::vector<const RawParticle*> thePart;
00307   double X0depth;
00308 
00309   if (debug_) {
00310     LogInfo("FastCalorimetry") << " EMShowerSimulation "  <<myTrack << std::endl;      
00311   }
00312   
00313   //  std::cout << " Simulating " << myTrack << std::endl;
00314 
00315   // The Particle at ECAL entrance
00316   //  std::cout << " Before ecalEntrance " << std::endl;
00317   myPart = myTrack.ecalEntrance(); 
00318 
00319   // protection against infinite loop.  
00320   if ( myTrack.type() == 22 && myPart.e()<0.055) return; 
00321 
00322 
00323   // Barrel or Endcap ?
00324   int onEcal = myTrack.onEcal();
00325   int onHcal = myTrack.onHcal();
00326   int onLayer1 = myTrack.onLayer1();
00327   int onLayer2 = myTrack.onLayer2();
00328 
00329   // The entrance in ECAL
00330   XYZPoint ecalentrance = myPart.vertex().Vect();
00331   
00332   //  std::cout << " Ecal entrance " << ecalentrance << std::endl;
00333   
00334   // The preshower
00335   PreshowerHitMaker * myPreshower = NULL ;
00336   if(simulatePreshower_ && (onLayer1 || onLayer2))
00337     {
00338       XYZPoint layer1entrance,layer2entrance;
00339       XYZVector dir1,dir2;
00340       if(onLayer1) 
00341         {
00342           layer1entrance = XYZPoint(myTrack.layer1Entrance().vertex().Vect());
00343           dir1 = XYZVector(myTrack.layer1Entrance().Vect().Unit());
00344         }
00345       if(onLayer2) 
00346         {
00347           layer2entrance = XYZPoint(myTrack.layer2Entrance().vertex().Vect());
00348           dir2 = XYZVector(myTrack.layer2Entrance().Vect().Unit());
00349         }
00350       //      std::cout << " Layer1entrance " << layer1entrance << std::endl;
00351       //      std::cout << " Layer2entrance " << layer2entrance << std::endl;
00352       myPreshower = new PreshowerHitMaker(myCalorimeter_,
00353                                           layer1entrance,
00354                                           dir1,
00355                                           layer2entrance,
00356                                           dir2,
00357                                           aLandauGenerator);
00358       myPreshower->setMipEnergy(mipValues_[0],mipValues_[1]);
00359     }
00360 
00361   // The ECAL Properties
00362   EMECALShowerParametrization 
00363     showerparam(myCalorimeter_->ecalProperties(onEcal), 
00364                 myCalorimeter_->hcalProperties(onHcal), 
00365                 myCalorimeter_->layer1Properties(onLayer1), 
00366                 myCalorimeter_->layer2Properties(onLayer2),
00367                 theCoreIntervals_,
00368                 theTailIntervals_,
00369                 RCFactor_,
00370                 RTFactor_);
00371 
00372   // Photons : create an e+e- pair
00373   if ( myTrack.type() == 22 ) {
00374     
00375     // Depth for the first e+e- pair creation (in X0)
00376     X0depth = -log(random->flatShoot()) * (9./7.);
00377     
00378     // Initialization
00379     double eMass = 0.000510998902; 
00380     double xe=0;
00381     double xm=eMass/myPart.e();
00382     double weight = 0.;
00383     
00384     // Generate electron energy between emass and eGamma-emass
00385     do {
00386       xe = random->flatShoot()*(1.-2.*xm) + xm;
00387       weight = 1. - 4./3.*xe*(1.-xe);
00388     } while ( weight < random->flatShoot() );
00389     
00390     // Protection agains infinite loop in Famos Shower
00391     if ( myPart.e()*xe < 0.055 || myPart.e()*(1.-xe) < 0.055 ) {
00392       
00393       if ( myPart.e() > 0.055 ) thePart.push_back(&myPart);
00394       
00395     } else {      
00396       
00397       myElec = (myPart) * xe;
00398       myPosi = (myPart) * (1.-xe);
00399       myElec.setVertex(myPart.vertex());
00400       myPosi.setVertex(myPart.vertex());
00401       thePart.push_back(&myElec);
00402       thePart.push_back(&myPosi);
00403     }
00404   // Electrons
00405   } else {  
00406     
00407     X0depth = 0.;
00408     if ( myPart.e() > 0.055 ) thePart.push_back(&myPart);
00409     
00410   } 
00411   
00412   // After the different protections, this shouldn't happen. 
00413   if(thePart.size()==0) 
00414     { 
00415       if(myPreshower==NULL) return; 
00416       delete myPreshower; 
00417       return; 
00418     } 
00419 
00420   // find the most energetic particle
00421   double maxEnergy=-1.;
00422   for(unsigned ip=0;ip < thePart.size();++ip)
00423     if(thePart[ip]->e() > maxEnergy) maxEnergy = thePart[ip]->e();
00424   
00425   // Initialize the Grid in ECAL
00426   int size = gridSize_;
00427   if(maxEnergy>100) size=11;
00428 //  if ( maxEnergy < threshold5x5 ) size = 5;
00429 //  if ( maxEnergy < threshold3x3 ) size = 3;
00430 
00431 
00432   EMShower theShower(random,aGammaGenerator,&showerparam,&thePart, dbe, NULL, NULL, bFixedLength_);
00433 
00434 
00435   double maxShower = theShower.getMaximumOfShower();
00436   if (maxShower > 20.) maxShower = 2.; // simple pivot-searching protection 
00437 
00438   double depth((X0depth + maxShower) * 
00439                myCalorimeter_->ecalProperties(onEcal)->radLenIncm());
00440   XYZPoint meanShower = ecalentrance + myPart.Vect().Unit()*depth;
00441   
00442   //  if(onEcal!=1) return ; 
00443 
00444   // The closest crystal
00445   DetId pivot(myCalorimeter_->getClosestCell(meanShower, true, onEcal==1));
00446 
00447   if(pivot.subdetId() == 0) {   // further protection against avbsence of pivot
00448     edm::LogWarning("CalorimetryManager") <<  "Pivot for egamma  e = "  << myTrack.hcalEntrance().e() << " is not found at depth " << depth << " and meanShower coordinates = " << meanShower << std::endl; 
00449     if(myPreshower) delete myPreshower;
00450     return;
00451   }
00452   
00453   EcalHitMaker myGrid(myCalorimeter_,ecalentrance,pivot,onEcal,size,0,random);
00454   //                                             ^^^^
00455   //                                         for EM showers
00456   myGrid.setPulledPadSurvivalProbability(pulledPadSurvivalProbability_);
00457   myGrid.setCrackPadSurvivalProbability(crackPadSurvivalProbability_);
00458 
00459   //maximumdepth dependence of the radiusfactorbehindpreshower
00460   //First tuning: Shilpi Jain (Mar-Apr 2010); changed after tuning - Feb-July - Shilpi Jain
00461   /* **************
00462   myGrid.setRadiusFactor(radiusFactor_);
00463   if(onLayer1 || onLayer2)
00464     {
00465       float b               = radiusPreshowerCorrections_[0];
00466       float a               = radiusFactor_*( 1.+radiusPreshowerCorrections_[1]*radiusPreshowerCorrections_[0] );
00467       float maxdepth        = X0depth+theShower.getMaximumOfShower();
00468       float newRadiusFactor = radiusFactor_;
00469       if(myPart.e()<=250.)
00470         {
00471           newRadiusFactor = a/(1.+b*maxdepth); 
00472         }
00473       myGrid.setRadiusFactor(newRadiusFactor);
00474     }
00475   else // otherwise use the normal radius factor
00476     {
00477       myGrid.setRadiusFactor(radiusFactor_);
00478     }
00479   ************** */
00480   if(myTrack.onEcal() == 2) // if on EE  
00481      {
00482        if( (onLayer1 || onLayer2) && myPart.e()<=250.)
00483          {
00484            double maxdepth        = X0depth+theShower.getMaximumOfShower();
00485            double newRadiusFactor = radiusFactorEE_ * aTerm/(1.+bTerm*maxdepth);
00486            myGrid.setRadiusFactor(newRadiusFactor);
00487          }
00488        else // otherwise use the normal radius factor
00489          {
00490            myGrid.setRadiusFactor(radiusFactorEE_);
00491          }
00492      }//if(myTrack.onEcal() == 2)
00493   else                      // else if on EB
00494     {
00495       myGrid.setRadiusFactor(radiusFactorEB_);
00496     }
00497   //(end of) changed after tuning - Feb-July - Shilpi Jain
00498 
00499   myGrid.setPreshowerPresent(simulatePreshower_);
00500   
00501   // The shower simulation
00502   myGrid.setTrackParameters(myPart.Vect().Unit(),X0depth,myTrack);
00503 
00504 //  std::cout << " PS ECAL GAP HCAL X0 " << myGrid.ps1TotalX0()+myGrid.ps2TotalX0() << " " << myGrid.ecalTotalX0();
00505 //  std::cout << " " << myGrid.ecalHcalGapTotalX0() << " " << myGrid.hcalTotalX0() << std::endl;
00506 //  std::cout << " PS ECAL GAP HCAL L0 " << myGrid.ps1TotalL0()+myGrid.ps2TotalL0() << " " << myGrid.ecalTotalL0();
00507 //  std::cout << " " << myGrid.ecalHcalGapTotalL0() << " " << myGrid.hcalTotalL0() << std::endl;
00508 //  std::cout << "ECAL-HCAL " << myTrack.momentum().eta() << " " <<  myGrid.ecalHcalGapTotalL0() << std::endl;
00509 //
00510 //  std::cout << " Grid created " << std::endl;
00511   if(myPreshower) theShower.setPreshower(myPreshower);
00512   
00513   HcalHitMaker myHcalHitMaker(myGrid,(unsigned)0); 
00514 
00515   theShower.setGrid(&myGrid);
00516   theShower.setHcal(&myHcalHitMaker);
00517   theShower.compute();
00518   //myHistos->fill("h502", myPart->eta(),myGrid.totalX0());
00519   
00520   // Save the hits !
00521   std::map<uint32_t,float>::const_iterator mapitr;
00522   std::map<uint32_t,float>::const_iterator endmapitr=myGrid.getHits().end();
00523   for(mapitr=myGrid.getHits().begin();mapitr!=endmapitr;++mapitr)
00524     {
00525       if(onEcal==1)
00526         {
00527           updateMap(EBDetId(mapitr->first).hashedIndex(), mapitr->second,myTrack.id(),EBMapping_,firedCellsEB_);
00528         }
00529             
00530       else if(onEcal==2)
00531         updateMap(EEDetId(mapitr->first).hashedIndex(), mapitr->second,myTrack.id(),EEMapping_,firedCellsEE_);
00532       //      std::cout << " Adding " <<mapitr->first << " " << mapitr->second <<std::endl; 
00533     }
00534 
00535   // Now fill the HCAL hits
00536   endmapitr=myHcalHitMaker.getHits().end();
00537   for(mapitr=myHcalHitMaker.getHits().begin();mapitr!=endmapitr;++mapitr)
00538     { 
00539      updateMap(HcalDetId(mapitr->first).rawId(),mapitr->second,myTrack.id(),HMapping_);
00540       //      std::cout << " Adding " <<mapitr->first << " " << mapitr->second <<std::endl; 
00541     }
00542 
00543   // delete the preshower
00544   if(myPreshower!=0)
00545     {
00546       endmapitr=myPreshower->getHits().end();
00547       for(mapitr=myPreshower->getHits().begin();mapitr!=endmapitr;++mapitr)
00548         {
00549           updateMap(mapitr->first,mapitr->second,myTrack.id(),ESMapping_);
00550           //      std::cout << " Adding " <<mapitr->first << " " << mapitr->second <<std::endl; 
00551         }
00552       delete myPreshower;
00553   //  std::cout << " Deleting myPreshower " << std::endl;
00554     }
00555   
00556 }
00557 
00558 
00559 
00560 // Simulation of electromagnetic showers in VFCAL
00561 void CalorimetryManager::reconstructECAL(const FSimTrack& track) {
00562   if(debug_) {
00563     XYZTLorentzVector moment = track.momentum();
00564     std::cout << "FASTEnergyReconstructor::reconstructECAL - " << std::endl
00565          << "  eta " << moment.eta() << std::endl
00566          << "  phi " << moment.phi() << std::endl
00567          << "   et " << moment.Et()  << std::endl;
00568   }
00569   
00570   int hit; 
00571   
00572   bool central=track.onEcal()==1;
00573   
00574   //Reconstruct only electrons and photons. 
00575 
00576   //deal with different conventions
00577   // ParticlePropagator 1 <-> Barrel
00578   //                    2 <-> EC
00579   // whereas for Artur(this code):
00580   //                    0 <-> Barrel
00581   //                    1 <-> EC
00582   //                    2 <-> VF
00583   XYZTLorentzVector trackPosition;
00584   if( track.onEcal() ) {
00585     hit=track.onEcal()-1;
00586     trackPosition=track.ecalEntrance().vertex();
00587   } else {
00588     hit=2;
00589     trackPosition=track.vfcalEntrance().vertex();
00590   }
00591   
00592   double pathEta   = trackPosition.eta();
00593   double pathPhi   = trackPosition.phi();       
00594   double EGen      = track.ecalEntrance().e();
00595   
00596 
00597   double e=0.;
00598   double sigma=0.;
00599   // if full simulation and in HF, but without showering anyway...
00600   if(hit == 2 && optionHDSim_ == 2 ) { 
00601     std::pair<double,double> response =
00602       myHDResponse_->responseHCAL(0, EGen, pathEta, 0); // last par.= 0 = e/gamma 
00603     e     = response.first;
00604     sigma = response.second;
00605   }
00606 
00607   double emeas = 0.;
00608   if(sigma>0.) emeas = gaussShootNoNegative(e,sigma);
00609 
00610   if(debug_)
00611     std::cout << "FASTEnergyReconstructor::reconstructECAL : " 
00612          << "  on-calo  eta, phi  = " << pathEta << " " << pathPhi << std::endl 
00613          << "  Egen  = " << EGen << std::endl 
00614          << "  Eres  = " << e << std::endl 
00615          << " sigma  = " << sigma << std::endl 
00616          << "  Emeas = " << emeas << std::endl; 
00617 
00618 
00619   if(debug_)
00620     std::cout << "FASTEnergyReconstructor::reconstructECAL : " 
00621          << " Track position - " << trackPosition.Vect() 
00622          << "   bool central - " << central
00623          << "   hit - " << hit   << std::endl;  
00624 
00625   DetId detid;  
00626   if( hit==2 ) 
00627       detid = myCalorimeter_->getClosestCell(trackPosition.Vect(),false,central);
00628   // Check that the detid is HCAL forward
00629   HcalDetId hdetid(detid);
00630   if(!hdetid.subdetId()!=HcalForward) return;
00631 
00632   if(debug_)
00633     std::cout << "FASTEnergyReconstructor::reconstructECAL : " 
00634               << " CellID - " <<  detid.rawId() << std::endl;
00635 
00636   if( hit != 2  || emeas > 0.) 
00637     if(!detid.null()) 
00638       {
00639 
00640         updateMap(hdetid.rawId(),emeas,track.id(),HMapping_);
00641       }
00642 
00643 }
00644 
00645 
00646 void CalorimetryManager::reconstructHCAL(const FSimTrack& myTrack)
00647 {
00648   int hit;
00649   int pid = abs(myTrack.type());
00650   if (debug_) {
00651     LogInfo("FastCalorimetry") << " reconstructHCAL "  << myTrack << std::endl;      
00652   }
00653 
00654   //  FSimTrack myTrack = mySimEvent.track(fsimi);
00655 
00656   //  int pid=abs(myTrack.type());
00657   //  std::cout << "reconstructHCAL " << std::endl;
00658   
00659   XYZTLorentzVector trackPosition;
00660   if (myTrack.onHcal()) {
00661     trackPosition=myTrack.hcalEntrance().vertex();
00662     hit = myTrack.onHcal()-1;
00663   } else {
00664     trackPosition=myTrack.vfcalEntrance().vertex();
00665     hit = 2;
00666   }
00667 
00668   double pathEta   = trackPosition.eta();
00669   double pathPhi   = trackPosition.phi();       
00670   //  double pathTheta = trackPosition.theta();
00671 
00672   double EGen  = myTrack.hcalEntrance().e();
00673   double e     = 0.;
00674   double sigma = 0.;
00675   double emeas = 0.;
00676   //double emeas = -0.0001;
00677  
00678   if(pid == 13) { 
00679     //    std::cout << " We should not be here " << std::endl;
00680     std::pair<double,double> response =
00681       myHDResponse_->responseHCAL(0, EGen, pathEta, 2); // 2=muon 
00682     emeas  = response.first;
00683     if(debug_)
00684       LogInfo("FastCalorimetry") << "CalorimetryManager::reconstructHCAL - MUON !!!" << std::endl;
00685   }
00686   else if( pid == 22 || pid == 11)
00687     {
00688       
00689       std::pair<double,double> response =
00690         myHDResponse_->responseHCAL(0, EGen, pathEta, 0); // last par. = 0 = e/gamma
00691       e     = response.first;              //
00692       sigma = response.second;             //
00693       emeas = gaussShootNoNegative(e,sigma);
00694 
00695       //  cout <<  "CalorimetryManager::reconstructHCAL - e/gamma !!!" << std::endl;
00696       if(debug_)
00697         LogInfo("FastCalorimetry") << "CalorimetryManager::reconstructHCAL - e/gamma !!!" << std::endl;
00698     }
00699     else {
00700       e     = myHDResponse_->getHCALEnergyResponse(EGen,hit);
00701       sigma = myHDResponse_->getHCALEnergyResolution(EGen, hit);
00702       
00703       emeas = gaussShootNoNegative(e,sigma);
00704     }
00705     
00706 
00707   if(debug_)
00708     LogInfo("FastCalorimetry") << "CalorimetryManager::reconstructHCAL - on-calo "   
00709                                 << "  eta = " << pathEta 
00710                                 << "  phi = " << pathPhi 
00711                                 << "  Egen = " << EGen 
00712                                 << "  Eres = " << e 
00713                                 << "  sigma = " << sigma 
00714                                 << "  Emeas = " << emeas << std::endl;
00715 
00716   if(emeas > 0.) {  
00717     DetId cell = myCalorimeter_->getClosestCell(trackPosition.Vect(),false,false);
00718 
00719     updateMap(cell.rawId(), emeas, myTrack.id(),HMapping_);
00720   }
00721 }
00722 
00723 void CalorimetryManager::HDShowerSimulation(const FSimTrack& myTrack){//, 
00724                                             // const edm::ParameterSet& fastCalo){
00725 
00726   //  TimeMe t(" FASTEnergyReconstructor::HDShower");
00727   XYZTLorentzVector moment = myTrack.momentum();
00728   
00729   if(debug_)
00730     LogInfo("FastCalorimetry") 
00731       << "CalorimetryManager::HDShowerSimulation - track param."
00732       << std::endl
00733       << "  eta = " << moment.eta() << std::endl
00734       << "  phi = " << moment.phi() << std::endl
00735       << "   et = " << moment.Et()  << std::endl
00736       << "   e  = " << myTrack.hcalEntrance().e() << std::endl;
00737 
00738   if (debug_) {
00739       LogInfo("FastCalorimetry") << " HDShowerSimulation "  << myTrack << std::endl;      
00740     }
00741 
00742 
00743   int hit;
00744   //  int pid = abs(myTrack.type());
00745 
00746   XYZTLorentzVector trackPosition;
00747   if ( myTrack.onEcal() ) {
00748     trackPosition=myTrack.ecalEntrance().vertex();
00749     hit = myTrack.onEcal()-1;                               //
00750     myPart = myTrack.ecalEntrance();
00751   } else if ( myTrack.onVFcal()) {
00752     trackPosition=myTrack.vfcalEntrance().vertex();
00753     hit = 2;
00754     myPart = myTrack.vfcalEntrance();
00755   }
00756   else
00757     {
00758       LogInfo("FastCalorimetry") << " The particle is not in the acceptance " << std::endl;
00759       return;
00760     }
00761 
00762   // int onHCAL = hit + 1; - specially for myCalorimeter->hcalProperties(onHCAL)
00763   // (below) to get VFcal properties ...
00764   int onHCAL = hit + 1;
00765   int onECAL = myTrack.onEcal();
00766   
00767   double pathEta   = trackPosition.eta();
00768   double pathPhi   = trackPosition.phi();       
00769   //  double pathTheta = trackPosition.theta();
00770 
00771   double eint  = moment.e();
00772   double eGen  = myTrack.hcalEntrance().e();
00773   double e     = 0.;
00774   double sigma = 0.;
00775 
00776   double emeas = 0.;  
00777   //double emeas = -0.000001; 
00778 
00779   //===========================================================================
00780   if(eGen > 0.) {  
00781 
00782     // ECAL and HCAL properties to get
00783     HDShowerParametrization 
00784       theHDShowerparam(myCalorimeter_->ecalProperties(onECAL),
00785                        myCalorimeter_->hcalProperties(onHCAL),
00786                        myHSParameters_);
00787     
00788     //Making ECAL Grid (and segments calculation)
00789     XYZPoint caloentrance;
00790     XYZVector direction;
00791     if(myTrack.onEcal()) 
00792       { 
00793         caloentrance = myTrack.ecalEntrance().vertex().Vect();
00794         direction = myTrack.ecalEntrance().Vect().Unit();
00795       }
00796     else if(myTrack.onHcal())
00797       {
00798         caloentrance = myTrack.hcalEntrance().vertex().Vect();
00799         direction = myTrack.hcalEntrance().Vect().Unit();
00800       }
00801     else
00802       {
00803         caloentrance = myTrack.vfcalEntrance().vertex().Vect();
00804         direction = myTrack.vfcalEntrance().Vect().Unit();
00805       }
00806 
00807   if(debug_)
00808     LogInfo("FastCalorimetry") 
00809       << "CalorimetryManager::HDShowerSimulation - on-calo 1 "
00810       << std::endl
00811       << "  onEcal    = " <<  myTrack.onEcal()  << std::endl
00812       << "  onHcal    = " <<  myTrack.onHcal()  << std::endl
00813       << "  onVFcal   = " <<  myTrack.onVFcal() << std::endl
00814       << "  position  = " << caloentrance << std::endl;
00815 
00816 
00817     DetId pivot;
00818     if(myTrack.onEcal())
00819       {
00820         pivot=myCalorimeter_->getClosestCell(caloentrance,
00821                                              true, myTrack.onEcal()==1);
00822       }
00823     else if(myTrack.onHcal())
00824       {
00825         //      std::cout << " CalorimetryManager onHcal " <<  myTrack.onHcal() << " caloentrance" << caloentrance  << std::endl;
00826         pivot=myCalorimeter_->getClosestCell(caloentrance,                                           
00827                                             false, false);
00828       }
00829 
00830     EcalHitMaker myGrid(myCalorimeter_,caloentrance,pivot,
00831                         pivot.null()? 0 : myTrack.onEcal(),hdGridSize_,1,
00832                         random);
00833     // 1=HAD shower
00834 
00835     myGrid.setTrackParameters(direction,0,myTrack);
00836     // Build the FAMOS HCAL 
00837     HcalHitMaker myHcalHitMaker(myGrid,(unsigned)1); 
00838     
00839     // Shower simulation
00840     bool status = false;
00841     int  mip = 2;
00842     // Use HFShower for HF
00843     if ( !myTrack.onEcal() && !myTrack.onHcal() ) {
00844       //      std::cout << "CalorimetryManager::HDShowerSimulation(): track entrance = "
00845       //                << myTrack.vfcalEntrance().vertex().X() << " "
00846       //                << myTrack.vfcalEntrance().vertex().Y() << " "
00847       //                << myTrack.vfcalEntrance().vertex().Z() << " "
00848       //                << " , Energy (Gen/Scale) = " << eGen << " " << e << std::endl;
00849 
00850       // Warning : We give here the particle energy with the response
00851       //           but without the resolution/gaussian smearing
00852       //           For HF, the resolution is due to the PE statistic
00853 
00854       HFShower theShower(random,
00855                          &theHDShowerparam,
00856                          &myGrid,
00857                          &myHcalHitMaker,
00858                          onECAL,
00859                          eGen);
00860                          //                      eGen);
00861                          //                      e); // PV Warning : temporarly set the energy to the generated E
00862 
00863       status = theShower.compute();
00864     } else { 
00865       if(hdSimMethod_ == 0) {
00866         HDShower theShower(random,
00867                            &theHDShowerparam,
00868                            &myGrid,
00869                            &myHcalHitMaker,
00870                            onECAL,
00871                            eGen,
00872                            dbe);
00873         status = theShower.compute();
00874         mip    = theShower.getmip();
00875       }
00876       else if (hdSimMethod_ == 1) {
00877         HDRShower theShower(random,
00878                             &theHDShowerparam,
00879                             &myGrid,
00880                             &myHcalHitMaker,
00881                             onECAL,
00882                             eGen);
00883         status = theShower.computeShower();
00884         mip = 2;
00885       }
00886       else if (hdSimMethod_ == 2 ) {
00887         //        std::cout << "Using GflashHadronShowerProfile hdSimMethod_ == 2" << std::endl;
00888 
00889         //dynamically loading a corresponding profile by the particle type
00890         int particleType = myTrack.type();
00891         theProfile = thePiKProfile;
00892         if(particleType == -2212) theProfile = theAntiProtonProfile;
00893         else if(particleType == 2212) theProfile = theProtonProfile;
00894 
00895         //input variables for GflashHadronShowerProfile
00896         int showerType = 99 + myTrack.onEcal();
00897         double globalTime = 150.0; // a temporary reference hit time in nanosecond
00898         float charge = (float)(myTrack.charge());
00899         Gflash3Vector gfpos(trackPosition.X(),trackPosition.Y(),trackPosition.Z());
00900         Gflash3Vector gfmom(moment.X(),moment.Y(),moment.Z());
00901 
00902         theProfile->initialize(showerType,eGen,globalTime,charge,gfpos,gfmom);
00903         theProfile->loadParameters();
00904         theProfile->hadronicParameterization();
00905 
00906         //make hits
00907         std::vector<GflashHit>& gflashHitList = theProfile->getGflashHitList();
00908         std::vector<GflashHit>::const_iterator spotIter    = gflashHitList.begin();
00909         std::vector<GflashHit>::const_iterator spotIterEnd = gflashHitList.end();
00910 
00911         Gflash::CalorimeterNumber whichCalor = Gflash::kNULL;
00912 
00913         for( ; spotIter != spotIterEnd; spotIter++){
00914 
00915           double pathLength = theProfile->getGflashShowino()->getPathLengthAtShower()
00916             + (30*100/eGen)*(spotIter->getTime() - globalTime);
00917 
00918           double currentDepth = std::max(0.0,pathLength - theProfile->getGflashShowino()->getPathLengthOnEcal());
00919 
00920           //find the the showino position at the currentDepth
00921           GflashTrajectoryPoint trajectoryPoint;
00922           theProfile->getGflashShowino()->getHelix()->getGflashTrajectoryPoint(trajectoryPoint,pathLength);
00923           Gflash3Vector positionAtCurrentDepth = trajectoryPoint.getPosition();
00924           //find radial distrance
00925           Gflash3Vector lateralDisplacement = positionAtCurrentDepth - spotIter->getPosition()/CLHEP::cm;
00926           double rShower = lateralDisplacement.r();
00927           double azimuthalAngle = lateralDisplacement.phi();
00928 
00929           whichCalor = Gflash::getCalorimeterNumber(positionAtCurrentDepth);
00930 
00931           if(whichCalor==Gflash::kESPM || whichCalor==Gflash::kENCA) {
00932             bool statusPad = myGrid.getPads(currentDepth,true);
00933             if(!statusPad) continue;
00934             myGrid.setSpotEnergy(1.2*spotIter->getEnergy()/CLHEP::GeV);
00935             myGrid.addHit(rShower/Gflash::intLength[Gflash::kESPM],azimuthalAngle,0);
00936           }
00937           else if(whichCalor==Gflash::kHB || whichCalor==Gflash::kHE) {
00938             bool setHDdepth = myHcalHitMaker.setDepth(currentDepth,true);
00939             if(!setHDdepth) continue;
00940             myHcalHitMaker.setSpotEnergy(1.4*spotIter->getEnergy()/CLHEP::GeV);
00941             myHcalHitMaker.addHit(rShower/Gflash::intLength[Gflash::kHB],azimuthalAngle,0);
00942           }
00943         }
00944         status = true;
00945       }
00946       else {
00947         edm::LogInfo("FastSimulationCalorimetry") << " SimMethod " << hdSimMethod_ <<" is NOT available ";
00948       }
00949     }
00950 
00951 
00952     if(status) {
00953 
00954       // Here to switch between simple formulae and parameterized response
00955       if(optionHDSim_ == 1) {
00956         e     = myHDResponse_->getHCALEnergyResponse  (eGen, hit);
00957         sigma = myHDResponse_->getHCALEnergyResolution(eGen, hit);
00958       }
00959       else { // optionHDsim == 2
00960         std::pair<double,double> response =
00961           myHDResponse_->responseHCAL(mip, eGen, pathEta, 1); // 1=hadron
00962         e     = response.first;
00963         sigma = response.second;
00964       }
00965       
00966       emeas = gaussShootNoNegative(e,sigma);
00967       double correction = emeas / eGen;
00968       
00969       // RespCorrP factors (ECAL and HCAL separately) calculation
00970       respCorr(eint);     
00971 
00972       if(debug_)
00973         LogInfo("FastCalorimetry") 
00974           << "CalorimetryManager::HDShowerSimulation - on-calo 2" << std::endl
00975           << "   eta  = " << pathEta << std::endl
00976           << "   phi  = " << pathPhi << std::endl
00977           << "  Egen  = " << eGen << std::endl
00978           << "  Eres  = " << e << std::endl
00979           << " sigma  = " << sigma << std::endl
00980           << " Emeas  = " << emeas << std::endl
00981           << "  corr  = " << correction << std::endl
00982           << "   mip  = " << mip << std::endl;
00983       
00984       //perfect and smeared energy vars
00985       double EpE, EsE, EpH, EsH;
00986       EpE = EsE = EpH = EsH = 0;          
00987       
00988       // was map<unsigned,double> but CaloHitMaker uses float
00989       std::map<unsigned,float>::const_iterator mapitr;
00990       std::map<unsigned,float>::const_iterator endmapitr;
00991       if(myTrack.onEcal() > 0) {
00992         // Save ECAL hits 
00993         endmapitr=myGrid.getHits().end();
00994         for(mapitr=myGrid.getHits().begin(); mapitr!=endmapitr; ++mapitr) {
00995           double energy = mapitr->second;
00996           EpE += energy;
00997           energy *= correction;              // RESCALING 
00998           energy *= ecorr;
00999           EsE += energy;
01000 
01001           if(energy > 0.000001) { 
01002             if(onECAL==1)
01003                 updateMap(EBDetId(mapitr->first).hashedIndex(),energy,myTrack.id(),EBMapping_,firedCellsEB_);
01004 
01005             else if(onECAL==2)
01006               updateMap(EEDetId(mapitr->first).hashedIndex(),energy,myTrack.id(),EEMapping_,firedCellsEE_);
01007 
01008             if(debug_)
01009               LogInfo("FastCalorimetry") << " ECAL cell " << mapitr->first << " added,  E = " 
01010                    << energy << std::endl;  
01011           }
01012         }
01013       }
01014       
01015       // Save HCAL hits
01016       endmapitr=myHcalHitMaker.getHits().end();
01017       for(mapitr=myHcalHitMaker.getHits().begin(); mapitr!=endmapitr; ++mapitr) {
01018         double energy = mapitr->second;
01019         EpH += energy;
01020         energy *= correction;               // RESCALING 
01021         energy *= hcorr;
01022         
01023         if(HcalDigitizer_){
01024           HcalDetId hdetid = HcalDetId(mapitr->first);
01025           if (hdetid.subdetId()== HcalBarrel || hdetid.subdetId()== HcalEndcap ) energy /= samplingHBHE_[hdetid.ietaAbs()-1]; //re-convert to GeV
01026           
01027           else if (hdetid.subdetId()== HcalForward){
01028             if(hdetid.depth()== 1) energy /= samplingHF_[0];
01029             if(hdetid.depth()== 2) energy /= samplingHF_[1];
01030           }  
01031           
01032           else if (hdetid.subdetId()== HcalOuter  )  energy /= samplingHO_[hdetid.ietaAbs()-1];         
01033         }
01034         
01035         EsH += energy;
01036 
01037       HcalDetId hId(mapitr->first);
01038       if ( hId.depth()>0 ){
01039         updateMap(HcalDetId(mapitr->first).rawId(),energy,myTrack.id(),HMapping_);
01040         if(debug_)
01041           LogInfo("FastCalorimetry") << " HCAL cell "  
01042                << mapitr->first << " added    E = " 
01043                << mapitr->second << std::endl;  
01044       }
01045       }
01046           
01047           if(useDQM_){
01048             //fill energy histos
01049             dbe->get("HDEnergies/EpECAL")->Fill(EpE/eGen);
01050             dbe->get("HDEnergies/EsECAL")->Fill(EsE/eGen);
01051             dbe->get("HDEnergies/EpHCAL")->Fill(EpH/eGen);
01052             dbe->get("HDEnergies/EsHCAL")->Fill(EsH/eGen);
01053             dbe->get("HDEnergies/EpTot")->Fill((EpE + EpH)/eGen);
01054             dbe->get("HDEnergies/EsTot")->Fill((EsE + EsH)/eGen);
01055           }
01056           
01057     }      
01058     else {  // shower simulation failed  
01059 //      std::cout << " Shower simulation failed " << trackPosition.Vect() << std::endl;
01060 //      std::cout << " The FSimTrack " << myTrack << std::endl;
01061 //      std::cout << " HF entrance on VFcal" << myTrack.onVFcal() << std::endl;
01062 //      std::cout << " trackPosition.eta() " << trackPosition.eta() << std::endl;
01063       if(myTrack.onHcal() || myTrack.onVFcal())
01064         {
01065           DetId cell = myCalorimeter_->getClosestCell(trackPosition.Vect(),false,false);
01066 
01067           updateMap(cell.rawId(),emeas,myTrack.id(),HMapping_);
01068           if(debug_)
01069             LogInfo("FastCalorimetry") << " HCAL simple cell "   
01070                                         << cell.rawId() << " added    E = " 
01071                                         << emeas << std::endl;  
01072         }
01073     }
01074 
01075   } // e > 0. ...
01076 
01077   if(debug_)
01078     LogInfo("FastCalorimetry") << std::endl << " FASTEnergyReconstructor::HDShowerSimulation  finished "
01079          << std::endl;
01080 }
01081 
01082 
01083 void CalorimetryManager::MuonMipSimulation(const FSimTrack& myTrack)
01084 {
01085   //  TimeMe t(" FASTEnergyReconstructor::HDShower");
01086   XYZTLorentzVector moment = myTrack.momentum();
01087 
01088   // Backward compatibility behaviour
01089   if(!theMuonHcalEffects) 
01090     {
01091       if(myTrack.onHcal() || myTrack.onVFcal() ) 
01092         reconstructHCAL(myTrack);
01093 
01094       return;
01095     }
01096 
01097   if(debug_)
01098     LogInfo("FastCalorimetry") << "CalorimetryManager::MuonMipSimulation - track param."
01099          << std::endl
01100          << "  eta = " << moment.eta() << std::endl
01101          << "  phi = " << moment.phi() << std::endl
01102          << "   et = " << moment.Et()  << std::endl;
01103 
01104   //  int hit;
01105   //  int pid = abs(myTrack.type());
01106 
01107   XYZTLorentzVector trackPosition;
01108   if ( myTrack.onEcal() ) {
01109     trackPosition=myTrack.ecalEntrance().vertex();
01110     //    hit = myTrack.onEcal()-1;                               //
01111     myPart = myTrack.ecalEntrance();
01112   } else if ( myTrack.onVFcal()) {
01113     trackPosition=myTrack.vfcalEntrance().vertex();
01114     //    hit = 2;
01115     myPart = myTrack.vfcalEntrance();
01116   }
01117   else
01118     {
01119       LogInfo("FastCalorimetry") << " The particle is not in the acceptance " << std::endl;
01120       return;
01121     }
01122 
01123   // int onHCAL = hit + 1; - specially for myCalorimeter->hcalProperties(onHCAL)
01124   // (below) to get VFcal properties ...
01125   // not needed ? 
01126   //  int onHCAL = hit + 1; 
01127   int onECAL = myTrack.onEcal();
01128   
01129   //  double pathEta   = trackPosition.eta();
01130   //  double pathPhi   = trackPosition.phi();   
01131   //  double pathTheta = trackPosition.theta();
01132   
01133   //===========================================================================
01134 
01135   // ECAL and HCAL properties to get
01136       
01137   //Making ECAL Grid (and segments calculation)
01138   XYZPoint caloentrance;
01139   XYZVector direction;
01140   if(myTrack.onEcal()) 
01141     {   
01142       caloentrance = myTrack.ecalEntrance().vertex().Vect();
01143       direction = myTrack.ecalEntrance().Vect().Unit();
01144     }
01145   else if(myTrack.onHcal())
01146     {
01147       caloentrance = myTrack.hcalEntrance().vertex().Vect();
01148       direction = myTrack.hcalEntrance().Vect().Unit();
01149     }
01150   else
01151     {
01152       caloentrance = myTrack.vfcalEntrance().vertex().Vect();
01153       direction = myTrack.vfcalEntrance().Vect().Unit();
01154     }
01155   
01156   DetId pivot;
01157   if(myTrack.onEcal())
01158     {
01159       pivot=myCalorimeter_->getClosestCell(caloentrance,
01160                                            true, myTrack.onEcal()==1);
01161     }
01162   else if(myTrack.onHcal())
01163     {
01164       //        std::cout << " CalorimetryManager onHcal " <<  myTrack.onHcal() << " caloentrance" << caloentrance  << std::endl;
01165       pivot=myCalorimeter_->getClosestCell(caloentrance,                                             
01166                                            false, false);
01167     }
01168   
01169   EcalHitMaker myGrid(myCalorimeter_,caloentrance,pivot,
01170                       pivot.null()? 0 : myTrack.onEcal(),hdGridSize_,0,
01171                       random);
01172   // 0 =EM shower -> Unit = X0
01173   
01174   myGrid.setTrackParameters(direction,0,myTrack);
01175   
01176   // Now get the path in the Preshower, ECAL and HCAL along a straight line extrapolation 
01177   // but only those in the ECAL are used 
01178  
01179   const std::vector<CaloSegment>& segments=myGrid.getSegments();
01180   unsigned nsegments=segments.size();
01181   
01182   int ifirstHcal=-1;
01183   int ilastEcal=-1;
01184  
01185   EnergyLossSimulator* energyLossECAL = 0;
01186   if (theMuonEcalEffects) energyLossECAL = theMuonEcalEffects->energyLossSimulator();
01187   //  // Muon brem in ECAL
01188   //  MuonBremsstrahlungSimulator* muonBremECAL = 0;
01189   //  if (theMuonEcalEffects) muonBremECAL = theMuonEcalEffects->muonBremsstrahlungSimulator();
01190 
01191   for(unsigned iseg=0;iseg<nsegments&&ifirstHcal<0;++iseg)
01192     {
01193       
01194       // in the ECAL, there are two types of segments: PbWO4 and GAP
01195       float segmentSizeinX0=segments[iseg].X0length();
01196 
01197       // Martijn - insert your computations here
01198       float energy=0.0;
01199       if (segmentSizeinX0>0.001 && segments[iseg].material()==CaloSegment::PbWO4 ) {
01200         // The energy loss simulator
01201         float charge = (float)(myTrack.charge());
01202         ParticlePropagator theMuon(moment,trackPosition,charge,0);
01203         theMuon.setID(-(int)charge*13);
01204         if ( energyLossECAL ) { 
01205           energyLossECAL->updateState(theMuon, segmentSizeinX0);
01206           energy = energyLossECAL->deltaMom().E();
01207           moment -= energyLossECAL->deltaMom();
01208         }
01209       } 
01210       // that's all for ECAL, Florian
01211       // Save the hit only if it is a crystal
01212       if(segments[iseg].material()==CaloSegment::PbWO4)
01213         {
01214           myGrid.getPads(segments[iseg].sX0Entrance()+segmentSizeinX0*0.5);
01215           myGrid.setSpotEnergy(energy);
01216           myGrid.addHit(0.,0.);
01217           ilastEcal=iseg;
01218         }
01219       // Check for end of loop:
01220       if(segments[iseg].material()==CaloSegment::HCAL)
01221         {
01222           ifirstHcal=iseg;
01223         }
01224     }
01225   
01226 
01227   // Build the FAMOS HCAL 
01228   HcalHitMaker myHcalHitMaker(myGrid,(unsigned)2);     
01229   // float mipenergy=0.1;
01230   // Create the helix with the stepping helix propagator
01231   // to add a hit, just do
01232   // myHcalHitMaker.setSpotEnergy(mipenergy);
01233   // math::XYZVector hcalEntrance;
01234   // if(ifirstHcal>=0) hcalEntrance=segments[ifirstHcal].entrance();
01235   // myHcalHitMaker.addHit(hcalEntrance);
01239   int ilastHcal=-1;
01240   float mipenergy=0.0;
01241  
01242   EnergyLossSimulator* energyLossHCAL = 0;
01243   if (theMuonHcalEffects) energyLossHCAL = theMuonHcalEffects->energyLossSimulator();
01244   //  // Muon Brem effect
01245   //  MuonBremsstrahlungSimulator* muonBremHCAL = 0;
01246   //  if (theMuonHcalEffects) muonBremHCAL = theMuonHcalEffects->muonBremsstrahlungSimulator(); 
01247  
01248   if(ifirstHcal>0 && energyLossHCAL){
01249     for(unsigned iseg=ifirstHcal;iseg<nsegments;++iseg)
01250       {
01251         float segmentSizeinX0=segments[iseg].X0length();
01252         if(segments[iseg].material()==CaloSegment::HCAL) {
01253           ilastHcal=iseg;
01254           if (segmentSizeinX0>0.001) {
01255             // The energy loss simulator
01256             float charge = (float)(myTrack.charge());
01257             ParticlePropagator theMuon(moment,trackPosition,charge,0);
01258             theMuon.setID(-(int)charge*13);
01259             energyLossHCAL->updateState(theMuon, segmentSizeinX0);
01260             mipenergy = energyLossHCAL->deltaMom().E();
01261             moment -= energyLossHCAL->deltaMom();
01262             myHcalHitMaker.setSpotEnergy(mipenergy);
01263             myHcalHitMaker.addHit(segments[iseg].entrance());
01264           }
01265         } 
01266       }
01267   }
01268   
01273   //
01274 
01275 
01276 
01277   // Copy the muon SimTrack (Only for Energy loss)
01278   FSimTrack muonTrack(myTrack);
01279   if(energyLossHCAL && ilastHcal>=0) {
01280     math::XYZVector hcalExit=segments[ilastHcal].exit();
01281     muonTrack.setTkPosition(hcalExit);
01282     muonTrack.setTkMomentum(moment);
01283   } else if(energyLossECAL && ilastEcal>=0) {
01284     math::XYZVector ecalExit=segments[ilastEcal].exit();
01285     muonTrack.setTkPosition(ecalExit);
01286     muonTrack.setTkMomentum(moment);
01287   } // else just leave tracker surface position and momentum...  
01288 
01289   muonSimTracks.push_back(muonTrack);
01290 
01291 
01292   // no need to change below this line
01293   std::map<unsigned,float>::const_iterator mapitr;
01294   std::map<unsigned,float>::const_iterator endmapitr;
01295   if(myTrack.onEcal() > 0) {
01296     // Save ECAL hits 
01297     endmapitr=myGrid.getHits().end();
01298     for(mapitr=myGrid.getHits().begin(); mapitr!=endmapitr; ++mapitr) {
01299       double energy = mapitr->second;
01300       if(onECAL==1)
01301         {
01302           updateMap(EBDetId(mapitr->first).hashedIndex(),energy,myTrack.id(),EBMapping_,firedCellsEB_);
01303         }      
01304       else if(onECAL==2)
01305         {
01306           updateMap(EEDetId(mapitr->first).hashedIndex(),energy,myTrack.id(),EEMapping_,firedCellsEE_);
01307         }
01308       
01309       if(debug_)
01310         LogInfo("FastCalorimetry") << " ECAL cell " << mapitr->first << " added,  E = " 
01311                                     << energy << std::endl;  
01312     }
01313   }
01314       
01315   // Save HCAL hits
01316   endmapitr=myHcalHitMaker.getHits().end();
01317   for(mapitr=myHcalHitMaker.getHits().begin(); mapitr!=endmapitr; ++mapitr) {
01318     double energy = mapitr->second;
01319     {
01320       updateMap(HcalDetId(mapitr->first).rawId(),energy,myTrack.id(),HMapping_);
01321     }
01322     if(debug_)
01323       LogInfo("FastCalorimetry") << " HCAL cell "  
01324                                   << mapitr->first << " added    E = " 
01325                                   << mapitr->second << std::endl;  
01326   }
01327   
01328   if(debug_)
01329     LogInfo("FastCalorimetry") << std::endl << " FASTEnergyReconstructor::MipShowerSimulation  finished "
01330          << std::endl;
01331 }
01332 
01333 
01334 void CalorimetryManager::readParameters(const edm::ParameterSet& fastCalo) {
01335 
01336   edm::ParameterSet ECALparameters = fastCalo.getParameter<edm::ParameterSet>("ECAL");
01337 
01338   evtsToDebug_ = fastCalo.getUntrackedParameter<std::vector<unsigned int> >("EvtsToDebug",std::vector<unsigned>());
01339   debug_ = fastCalo.getUntrackedParameter<bool>("Debug");
01340   useDQM_ = fastCalo.getUntrackedParameter<bool>("useDQM");
01341 
01342   bFixedLength_ = ECALparameters.getParameter<bool>("bFixedLength");
01343   //   std::cout << "bFixedLength_ = " << bFixedLength_ << std::endl;
01344 
01345   gridSize_ = ECALparameters.getParameter<int>("GridSize");
01346   spotFraction_ = ECALparameters.getParameter<double>("SpotFraction");
01347   pulledPadSurvivalProbability_ = ECALparameters.getParameter<double>("FrontLeakageProbability");
01348   crackPadSurvivalProbability_ = ECALparameters.getParameter<double>("GapLossProbability");
01349   theCoreIntervals_ = ECALparameters.getParameter<std::vector<double> >("CoreIntervals");
01350   theTailIntervals_ = ECALparameters.getParameter<std::vector<double> >("TailIntervals");
01351   
01352   RCFactor_ = ECALparameters.getParameter<double>("RCFactor");
01353   RTFactor_ = ECALparameters.getParameter<double>("RTFactor");
01354   //changed after tuning - Feb-July - Shilpi Jain
01355   //  radiusFactor_ = ECALparameters.getParameter<double>("RadiusFactor");
01356   radiusFactorEE_ = ECALparameters.getParameter<double>("RadiusFactorEE");
01357   radiusFactorEB_ = ECALparameters.getParameter<double>("RadiusFactorEB");
01358   //(end of) changed after tuning - Feb-July - Shilpi Jain
01359   radiusPreshowerCorrections_ = ECALparameters.getParameter<std::vector<double> >("RadiusPreshowerCorrections");
01360   aTerm = 1.+radiusPreshowerCorrections_[1]*radiusPreshowerCorrections_[0];
01361   bTerm = radiusPreshowerCorrections_[0];
01362   mipValues_ = ECALparameters.getParameter<std::vector<double> >("MipsinGeV");
01363   simulatePreshower_ = ECALparameters.getParameter<bool>("SimulatePreshower");
01364 
01365   if(gridSize_ <1) gridSize_= 7;
01366   if(pulledPadSurvivalProbability_ <0. || pulledPadSurvivalProbability_>1 ) pulledPadSurvivalProbability_= 1.;
01367   if(crackPadSurvivalProbability_ <0. || crackPadSurvivalProbability_>1 ) crackPadSurvivalProbability_= 0.9;
01368   
01369   LogInfo("FastCalorimetry") << " Fast ECAL simulation parameters " << std::endl;
01370   LogInfo("FastCalorimetry") << " =============================== " << std::endl;
01371   if(simulatePreshower_)
01372     LogInfo("FastCalorimetry") << " The preshower is present " << std::endl;
01373   else
01374     LogInfo("FastCalorimetry") << " The preshower is NOT present " << std::endl;
01375   LogInfo("FastCalorimetry") << " Grid Size : " << gridSize_  << std::endl; 
01376   if(spotFraction_>0.) 
01377     LogInfo("FastCalorimetry") << " Spot Fraction : " << spotFraction_ << std::endl;
01378   else
01379     {
01380       LogInfo("FastCalorimetry") << " Core of the shower " << std::endl;
01381       for(unsigned ir=0; ir < theCoreIntervals_.size()/2;++ir)
01382         {
01383           LogInfo("FastCalorimetry") << " r < " << theCoreIntervals_[ir*2] << " R_M : " << theCoreIntervals_[ir*2+1] << "        ";
01384         }
01385       LogInfo("FastCalorimetry") << std::endl;
01386         
01387       LogInfo("FastCalorimetry") << " Tail of the shower " << std::endl;
01388       for(unsigned ir=0; ir < theTailIntervals_.size()/2;++ir)
01389         {
01390           LogInfo("FastCalorimetry") << " r < " << theTailIntervals_[ir*2] << " R_M : " << theTailIntervals_[ir*2+1] << "        ";
01391         }
01392   //changed after tuning - Feb-July - Shilpi Jain
01393       //      LogInfo("FastCalorimetry") << "Radius correction factor " << radiusFactor_ << std::endl;
01394       LogInfo("FastCalorimetry") << "Radius correction factors:  EB & EE " << radiusFactorEB_ << " : "<< radiusFactorEE_ << std::endl;
01395   //(end of) changed after tuning - Feb-July - Shilpi Jain
01396       LogInfo("FastCalorimetry") << std::endl;
01397       if(mipValues_.size()>2)   {
01398         LogInfo("FastCalorimetry") << "Improper number of parameters for the preshower ; using 95keV" << std::endl;
01399         mipValues_.clear();
01400         mipValues_.resize(2,0.000095);
01401         }
01402     }
01403 
01404   LogInfo("FastCalorimetry") << " FrontLeakageProbability : " << pulledPadSurvivalProbability_ << std::endl;
01405   LogInfo("FastCalorimetry") << " GapLossProbability : " << crackPadSurvivalProbability_ << std::endl;
01406 
01407   
01408   // RespCorrP: p (momentum), ECAL and HCAL corrections = f(p)
01409   edm::ParameterSet CalorimeterParam = fastCalo.getParameter<edm::ParameterSet>("CalorimeterProperties");
01410 
01411   rsp = CalorimeterParam.getParameter<std::vector<double> >("RespCorrP");
01412    LogInfo("FastCalorimetry") << " RespCorrP (rsp) size " << rsp.size() << std::endl;
01413 
01414   if( rsp.size()%3 !=0 )  {
01415     LogInfo("FastCalorimetry") 
01416       << " RespCorrP size is wrong -> no corrections applied !!!" 
01417       << std::endl;
01418 
01419       p_knots.push_back(14000.);
01420       k_e.push_back    (1.);
01421       k_h.push_back    (1.);
01422   }
01423   else {
01424     for(unsigned i = 0; i < rsp.size(); i += 3) { 
01425      LogInfo("FastCalorimetry") << "i = " << i/3 << "   p = " << rsp [i] 
01426                                 << "   k_e(p) = " << rsp[i+1] 
01427                                 << "   k_e(p) = " << rsp[i+2] << std::endl; 
01428       
01429       p_knots.push_back(rsp[i]);
01430       k_e.push_back    (rsp[i+1]);
01431       k_h.push_back    (rsp[i+2]); 
01432     }
01433   }  
01434  
01435 
01436   //FR
01437   edm::ParameterSet HCALparameters = fastCalo.getParameter<edm::ParameterSet>("HCAL");
01438   optionHDSim_ = HCALparameters.getParameter<int>("SimOption");
01439   hdGridSize_  = HCALparameters.getParameter<int>("GridSize");
01440   hdSimMethod_ = HCALparameters.getParameter<int>("SimMethod");
01441   //RF
01442 
01443   unfoldedMode_ = fastCalo.getUntrackedParameter<bool>("UnfoldedMode",false);
01444 
01445   EcalDigitizer_    = ECALparameters.getUntrackedParameter<bool>("Digitizer",false);
01446   HcalDigitizer_    = HCALparameters.getUntrackedParameter<bool>("Digitizer",false);
01447   samplingHBHE_ = HCALparameters.getParameter< std::vector<double> >("samplingHBHE");
01448   samplingHF_   = HCALparameters.getParameter< std::vector<double> >("samplingHF");
01449   samplingHO_   = HCALparameters.getParameter< std::vector<double> >("samplingHO");
01450   smearTimeHF_  = HCALparameters.getUntrackedParameter<bool>("smearTimeHF",false);
01451   timeShiftHF_  = HCALparameters.getUntrackedParameter<double>("timeShiftHF",17.);
01452   timeSmearingHF_  = HCALparameters.getUntrackedParameter<double>("timeSmearingHF",2.);
01453 }
01454 
01455 
01456 void CalorimetryManager::updateMap(uint32_t cellid,float energy,int id,std::map<uint32_t,std::vector<std::pair<int,float> > > & mymap)
01457 {
01458   //  std::cout << " updateMap " << std::endl;
01459   std::map<unsigned,std::vector<std::pair<int,float> > >::iterator cellitr;
01460   cellitr = mymap.find(cellid);
01461   if(!unfoldedMode_) id=0;
01462   if( cellitr==mymap.end())
01463     {      
01464       std::vector<std::pair<int,float> > myElement;
01465       myElement.push_back(std::pair<int,float> (id,energy));
01466       mymap[cellid]=myElement;
01467     }
01468   else
01469     {
01470       if(!unfoldedMode_)
01471         {
01472           cellitr->second[0].second+=energy;
01473         }
01474       else
01475         cellitr->second.push_back(std::pair<int,float>(id,energy));
01476     }
01477 }
01478 
01479 void CalorimetryManager::updateMap(int hi,float energy,int tid,std::vector<std::vector<std::pair<int,float> > > & mymap, std::vector<int>& firedCells)
01480 {
01481   // Standard case first : one entry per cell 
01482   if(!unfoldedMode_)
01483     {
01484       // if new entry, update the list 
01485       if(mymap[hi].size()==0)
01486         {
01487           firedCells.push_back(hi);
01488           mymap[hi].push_back(std::pair<int,float>(0,energy));
01489         }
01490       else
01491         mymap[hi][0].second+=energy;
01492     }
01493   else
01494     {
01495       //      std::cout << "update map " << mymap[hi].size() << " " << hi << std::setw(8) << std::setprecision(6) <<  energy ;
01496       //      std::cout << " " << mymap[hi][0].second << std::endl;
01497       // the minimal size is always 1 ; in this case, no push_back 
01498       if(mymap[hi].size()==0)
01499         {
01500           //      if(tid==0) std::cout << " Shit ! " << std::endl;
01501           firedCells.push_back(hi);
01502         }
01503 
01504       mymap[hi].push_back(std::pair<int,float>(tid,energy));
01505     }
01506   
01507 }
01508 
01509 
01510 void CalorimetryManager::respCorr(double p) {
01511 
01512   int sizeP = p_knots.size();
01513 
01514   if(sizeP <= 1) {
01515     ecorr = 1.;
01516     hcorr = 1.;
01517   }
01518   else {
01519     int ip = -1;    
01520     for (int i = 0; i < sizeP; i++) { 
01521       if (p < p_knots[i]) { ip = i; break;}
01522     }
01523     if (ip == 0) {
01524       ecorr = k_e[0];
01525       hcorr = k_h[0];
01526     }
01527     else {
01528       if(ip == -1) {
01529         ecorr = k_e[sizeP-1];
01530         hcorr = k_h[sizeP-1];
01531       } 
01532       else {
01533         double x1 =  p_knots[ip-1];
01534         double x2 =  p_knots[ip];
01535         double y1 =  k_e[ip-1];
01536         double y2 =  k_e[ip];
01537         
01538         if(x1 == x2) {
01539           //        std::cout << " equal p_knots values!!! " << std::endl;
01540         }       
01541       
01542         ecorr = (y1 + (y2 - y1) * (p - x1)/(x2 - x1));
01543         
01544         y1 =  k_h[ip-1];
01545         y2 =  k_h[ip];
01546         hcorr = (y1 + (y2 - y1) * (p - x1)/(x2 - x1)); 
01547         
01548       }
01549     }
01550   }
01551 
01552   if(debug_)
01553     LogInfo("FastCalorimetry") << " p, ecorr, hcorr = " << p << " "  
01554                                 << ecorr << "  " << hcorr << std::endl;
01555         
01556 }
01557 
01558 
01559 void CalorimetryManager::loadFromEcalBarrel(edm::PCaloHitContainer & c) const
01560 { 
01561   unsigned size = firedCellsEB_.size();
01562   double time = 0.;
01563   for(unsigned ic=0;ic<size;++ic){ 
01564     int hi = firedCellsEB_[ic];
01565     if(!unfoldedMode_){
01566       if(EcalDigitizer_) time = (myCalorimeter_->getEcalGeometry(1)->getGeometry(EBDetId::unhashIndex(hi))->getPosition().mag())/29.98;//speed of light
01567       else time = 0.;
01568       c.push_back(PCaloHit(EBDetId::unhashIndex(hi),EBMapping_[hi][0].second,time,0));
01569       //          std::cout << "Adding " << hi << " " << EBDetId::unhashIndex(hi) << " " ;
01570       //          std::cout << EBMapping_[hi][0].second << " " << EBMapping_[hi][0].first << std::endl;
01571     }
01572     else{
01573       unsigned npart=EBMapping_[hi].size();
01574       for(unsigned ip=0;ip<npart;++ip){
01575         // get the time
01576         if(EcalDigitizer_) time = (myCalorimeter_->getEcalGeometry(1)->getGeometry(EBDetId::unhashIndex(hi))->getPosition().mag())/29.98;//speed of light
01577         else time = 0.;
01578         //            std::cout << " Barrel " << time  << std::endl;
01579         c.push_back(PCaloHit(EBDetId::unhashIndex(hi),EBMapping_[hi][ip].second,time,EBMapping_[hi][ip].first));
01580       }
01581     }
01582     
01583     //      sum+=cellit->second;
01584   }
01585   
01586   //  for(unsigned ic=0;ic<61200;++ic) 
01587 //    { 
01588 //      EBDetId myCell(EBDetId::unhashIndex(ic)); 
01589 //      if(!myCell.null()) 
01590 //        { 
01591 //        float total=0.;
01592 //        for(unsigned id=0;id<EBMapping_[ic].size();++id)
01593 //          total+=EBMapping_[ic][id].second;
01594 //        if(EBMapping_[ic].size()>0)
01595 //          std::cout << "Adding " << ic << " " << myCell << " " << std::setprecision(8) <<total << std::endl; 
01596 //        } 
01597 //    } 
01598 
01599 
01600   //  std::cout << " SUM : " << sum << std::endl;
01601   //  std::cout << " Added " <<c.size() << " hits " <<std::endl;
01602 }
01603 
01604 
01605 void CalorimetryManager::loadFromEcalEndcap(edm::PCaloHitContainer & c) const
01606 {
01607   unsigned size=firedCellsEE_.size();
01608   double time;
01609   
01610   for(unsigned ic=0;ic<size;++ic){
01611     int hi=firedCellsEE_[ic];
01612     if(!unfoldedMode_) {
01613       if(EcalDigitizer_) time=(myCalorimeter_->getEcalGeometry(2)->getGeometry(EEDetId::unhashIndex(hi))->getPosition().mag())/29.98;//speed of light
01614       else time = 0.;
01615       c.push_back(PCaloHit(EEDetId::unhashIndex(hi),EEMapping_[hi][0].second,time,0));
01616     }
01617     else{
01618       unsigned npart=EEMapping_[hi].size();
01619       for(unsigned ip=0;ip<npart;++ip) {
01620         if(EcalDigitizer_) time=(myCalorimeter_->getEcalGeometry(2)->getGeometry(EEDetId::unhashIndex(hi))->getPosition().mag())/29.98;//speed of light
01621         else time = 0.;    
01622         c.push_back(PCaloHit(EEDetId::unhashIndex(hi),EEMapping_[hi][ip].second,time,EEMapping_[hi][ip].first));
01623       }
01624     }
01625     
01626     //      sum+=cellit->second;
01627   }
01628   //  std::cout << " SUM : " << sum << std::endl;
01629   //  std::cout << " Added " <<c.size() << " hits " <<std::endl;
01630 }
01631 
01632 void CalorimetryManager::loadFromHcal(edm::PCaloHitContainer & c) const
01633 {
01634 
01635   double time;
01636   std::map<uint32_t,std::vector<std::pair< int,float> > >::const_iterator cellit;
01637   for (cellit=HMapping_.begin(); cellit!=HMapping_.end(); cellit++) {
01638     DetId hi=DetId(cellit->first);
01639     if(!unfoldedMode_){
01640       if(HcalDigitizer_) {
01641         time=(myCalorimeter_->getHcalGeometry()->getGeometry(hi)->getPosition().mag())/29.98;//speed of light
01642         if (smearTimeHF_ && hi.subdetId()== HcalForward){ // shift and smearing for HF
01643           time = random->gaussShoot((time+timeShiftHF_),timeSmearingHF_);
01644         }
01645       } else time = 0.;
01646       c.push_back(PCaloHit(hi,cellit->second[0].second,time,0));
01647     }
01648     else{
01649       unsigned npart=cellit->second.size();
01650       for(unsigned ip=0;ip<npart;++ip){
01651         if(HcalDigitizer_) {
01652           time=(myCalorimeter_->getHcalGeometry()->getGeometry(hi)->getPosition().mag())/29.98;//speed of light
01653           if (smearTimeHF_ && hi.subdetId()== HcalForward){ // shift and smearing for HF
01654             time = random->gaussShoot((time+timeShiftHF_),timeSmearingHF_);
01655           }
01656         } else time = 0.;
01657         c.push_back(PCaloHit(hi,cellit->second[ip].second, time, cellit->second[ip].first));
01658       }
01659     }
01660   }
01661   
01662 }
01663 
01664 
01665 void CalorimetryManager::loadFromPreshower(edm::PCaloHitContainer & c) const
01666 {
01667   std::map<uint32_t,std::vector<std::pair< int,float> > >::const_iterator cellit;
01668   std::map<uint32_t,std::vector<std::pair <int,float> > >::const_iterator preshEnd=ESMapping_.end();
01669   
01670   for(cellit=ESMapping_.begin();cellit!=preshEnd;++cellit)
01671     {
01672       if(!unfoldedMode_)        
01673         c.push_back(PCaloHit(cellit->first,cellit->second[0].second,0.,0));
01674       else
01675         {
01676           unsigned npart=cellit->second.size();
01677           for(unsigned ip=0;ip<npart;++ip)
01678             {
01679               c.push_back(PCaloHit(cellit->first,cellit->second[ip].second,0.,cellit->second[ip].first));
01680             }
01681         }
01682     }
01683 }
01684 
01685 // Remove (most) hits with negative energies
01686 double CalorimetryManager::gaussShootNoNegative(double e, double sigma) 
01687 {
01688   double out = -0.0001;
01689   if (e >= 0.) {
01690     while (out < 0.) out = random->gaussShoot(e,sigma);
01691   } else { // give up on re-trying, otherwise too much time can be lost before emeas comes out positive
01692     out = random->gaussShoot(e,sigma);
01693   }
01694   /*
01695       if (out < 0.) {
01696         std::cout << "e = " << e << " - sigma = " << sigma << " - emeas < 0 (!)" << std::endl;
01697       } else {
01698         std::cout << "e = " << e << " - sigma = " << sigma << " - emeas > 0 " << std::endl;
01699       }
01700   */
01701   return out;
01702 }
01703 
01704 
01705 // The main danger in this method is to screw up to relationships between particles
01706 // So, the muon FSimTracks created by FSimEvent.cc are simply to be updated 
01707 void CalorimetryManager::loadMuonSimTracks(edm::SimTrackContainer &muons) const
01708 {
01709   unsigned size=muons.size();
01710   for(unsigned i=0; i<size;++i)
01711     {
01712       int id=muons[i].trackId();
01713       if(abs(muons[i].type())!=13) continue;
01714       // identify the corresponding muon in the local collection
01715 
01716       std::vector<FSimTrack>::const_iterator itcheck=find_if(muonSimTracks.begin(),muonSimTracks.end(),FSimTrackEqual(id));
01717       if(itcheck!=muonSimTracks.end())
01718         {
01719           muons[i].setTkPosition(itcheck->trackerSurfacePosition());
01720           muons[i].setTkMomentum(itcheck->trackerSurfaceMomentum());
01721 //        std::cout << " Found the SimTrack " << std::endl;
01722 //        std::cout << *itcheck << std::endl;
01723 //        std::cout << "SimTrack Id "<< id << " " << muons[i] << " " << std::endl;
01724         }
01725 //      else
01726 //      {
01727 //        std::cout << " Calorimetery Manager : this should really not happen " << std::endl;
01728 //        std::cout << " Was looking for " << id << " " << muons[i] << std::endl;
01729 //        for(unsigned i=0;i<muonSimTracks.size();++i)
01730 //          std::cout << muonSimTracks[i] << std::endl;
01731 //      }
01732     }
01733 
01734 }
01735