00001 #include "FastSimulation/CaloHitMakers/interface/HcalHitMaker.h"
00002 #include "FastSimulation/CaloGeometryTools/interface/CaloGeometryHelper.h"
00003 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00004 #include "DataFormats/HcalDetId/interface/HcalDetId.h"
00005 #include <algorithm>
00006 #include <cmath>
00007
00008 typedef ROOT::Math::Transform3DPJ::Point Point;
00009
00010 HcalHitMaker::HcalHitMaker(EcalHitMaker& grid,unsigned shower)
00011 :CaloHitMaker(grid.getCalorimeter(),DetId::Hcal,HcalHitMaker::getSubHcalDet(grid.getFSimTrack()),
00012 grid.getFSimTrack()->onHcal()?grid.getFSimTrack()->onHcal():grid.getFSimTrack()->onVFcal()+1,shower),
00013 myGrid(grid), myTrack((grid.getFSimTrack()))
00014 {
00015
00016 ecalEntrance_=myGrid.ecalEntrance();
00017 particleDirection=myTrack->ecalEntrance().Vect().Unit();
00018 radiusFactor_=(EMSHOWER)? moliereRadius:interactionLength;
00019 mapCalculated_=false;
00020
00021 if(EMSHOWER&&(abs(grid.getFSimTrack()->type())!=11 && grid.getFSimTrack()->type()!=22))
00022 {
00023 std::cout << " FamosHcalHitMaker : Strange. The following shower has EM type" << std::endl <<* grid.getFSimTrack() << std::endl;
00024 }
00025 }
00026
00027 bool
00028 HcalHitMaker::addHit(double r,double phi,unsigned layer)
00029 {
00030
00031
00032
00033 XYZPoint point(r*radiusFactor_*std::cos(phi),r*radiusFactor_*std::sin(phi),0.);
00034
00035
00036
00037 point = locToGlobal_((Point)point);
00038
00039
00040
00041 if(fabs(point.Z())>2000 || fabs(point.X())>2000 || fabs(point.Y())>2000)
00042 {
00043 if(EMSHOWER)
00044 edm::LogWarning("HcalHitMaker") << "received a hit very far from the detector " << point << " coming from an electromagnetic shower. - Ignoring it" << std::endl;
00045 else
00046 edm::LogWarning("HcalHitMaker") << "received a hit very far from the detector " << point << " coming from an hadron shower. - Ignoring it" << std::endl;
00047 return false;
00048 }
00049
00050
00051 double pointeta = fabs(point.eta());
00052 if(pointeta > 5.19) return false;
00053
00054 DetId thecellID(myCalorimeter->getClosestCell(point,false,false));
00055
00056 HcalDetId myDetId(thecellID);
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072 if ( myDetId.subdetId() == HcalForward ) {
00073 int mylayer = layer;
00074 if ( myDetId.depth()==2 ) {
00075 mylayer = (int)layer;
00076 } else {
00077 mylayer = 1;
00078 }
00079 HcalDetId myDetId2((HcalSubdetector)myDetId.subdetId(),myDetId.ieta(),myDetId.iphi(),mylayer);
00080 thecellID = myDetId2;
00081 }
00082
00083
00084
00085 if(!thecellID.null())
00086 {
00087 uint32_t cell(thecellID.rawId());
00088
00089
00090
00091
00092 std::map<uint32_t,float>::iterator cellitr;
00093 cellitr = hitMap_.find(cell);
00094 if(cellitr==hitMap_.end())
00095 {
00096 hitMap_.insert(std::pair<uint32_t,float>(cell,spotEnergy));
00097 }
00098 else
00099 {
00100 cellitr->second+=spotEnergy;
00101 }
00102 return true;
00103 }
00104 return false;
00105 }
00106
00107 bool
00108 HcalHitMaker::setDepth(double depth)
00109 {
00110 currentDepth_=depth;
00111 std::vector<CaloSegment>::const_iterator segiterator;
00112 if(EMSHOWER)
00113 segiterator = find_if(myGrid.getSegments().begin(),myGrid.getSegments().end(),CaloSegment::inX0Segment(currentDepth_));
00114
00115
00116 if(HADSHOWER)
00117 segiterator = find_if(myGrid.getSegments().begin(),myGrid.getSegments().end(),CaloSegment::inL0Segment(currentDepth_));
00118 if(segiterator==myGrid.getSegments().end())
00119 {
00120
00121 if(depth > myGrid.getSegments().back().sL0Exit())
00122 {
00123 segiterator= find_if(myGrid.getSegments().begin(),myGrid.getSegments().end(),CaloSegment::inL0Segment(myGrid.getSegments().back().sL0Exit()-1.));
00124 depth=segiterator->sL0Exit()-1.;
00125 currentDepth_=depth;
00126 if(segiterator==myGrid.getSegments().end())
00127 {
00128 std::cout << " Could not go at such depth " << EMSHOWER << " " << currentDepth_ << std::endl;
00129 std::cout << " Track " << *(myGrid.getFSimTrack()) << std::endl;
00130 return false;
00131 }
00132 }
00133 else
00134 {
00135 std::cout << " Could not go at such depth " << EMSHOWER << " " << currentDepth_ << " " << myGrid.getSegments().back().sL0Exit() << std::endl;
00136 std::cout << " Track " << *(myGrid.getFSimTrack()) << std::endl;
00137 return false;
00138 }
00139 }
00140
00141
00142 XYZPoint origin;
00143 if(EMSHOWER)
00144 origin=segiterator->positionAtDepthinX0(currentDepth_);
00145 if(HADSHOWER)
00146 origin=segiterator->positionAtDepthinL0(currentDepth_);
00147
00148 XYZVector zaxis(0,0,1);
00149 XYZVector planeVec1=(zaxis.Cross(particleDirection)).Unit();
00150 locToGlobal_=Transform3D(Point(0,0,0),
00151 Point(0,0,1),
00152 Point(1,0,0),
00153 (Point)origin,
00154 (Point)(origin+particleDirection),
00155 (Point)(origin+planeVec1));
00156 return true;
00157 }