CMS 3D CMS Logo

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