CMS 3D CMS Logo

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