00001 #include "FastSimulation/CaloGeometryTools/interface/CaloGeometryHelper.h"
00002
00003
00004
00005
00006 #include "Geometry/CaloGeometry/interface/CaloCellGeometry.h"
00007 #include "Geometry/EcalAlgo/interface/EcalBarrelGeometry.h"
00008 #include "Geometry/EcalAlgo/interface/EcalEndcapGeometry.h"
00009 #include "Geometry/CaloTopology/interface/CaloSubdetectorTopology.h"
00010
00011 #include "DataFormats/EcalDetId/interface/EBDetId.h"
00012 #include "DataFormats/EcalDetId/interface/EEDetId.h"
00013 #include "DataFormats/EcalDetId/interface/ESDetId.h"
00014 #include "DataFormats/HcalDetId/interface/HcalDetId.h"
00015 #include "DataFormats/EcalDetId/interface/EcalSubdetector.h"
00016 #include "Geometry/EcalAlgo/interface/EcalPreshowerGeometry.h"
00017
00018 #include "FastSimulation/CaloGeometryTools/interface/DistanceToCell.h"
00019 #include "FastSimulation/CaloGeometryTools/interface/Crystal.h"
00020
00021 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00022
00023 #include <algorithm>
00024
00025 CaloGeometryHelper::CaloGeometryHelper():Calorimeter()
00026 {
00027 neighbourmapcalculated_= false;
00028 psLayer1Z_ = 303;
00029 psLayer2Z_ = 307;
00030 }
00031
00032 CaloGeometryHelper::CaloGeometryHelper(const edm::ParameterSet& fastCalo):Calorimeter(fastCalo)
00033 {
00034
00035 psLayer1Z_ = 303;
00036 psLayer2Z_ = 307;
00037 }
00038
00039 void CaloGeometryHelper::initialize(double bField)
00040 {
00041 buildCrystalArray();
00042 buildNeighbourArray();
00043 bfield_ = bField;
00044 preshowerPresent_=(getEcalPreshowerGeometry()!=0);
00045
00046 if(preshowerPresent_)
00047 {
00048 ESDetId cps1(getEcalPreshowerGeometry()->getClosestCellInPlane(GlobalPoint(80.,80.,303.),1));
00049 psLayer1Z_ = getEcalPreshowerGeometry()->getGeometry(cps1)->getPosition().z();
00050 ESDetId cps2(getEcalPreshowerGeometry()->getClosestCellInPlane(GlobalPoint(80.,80.,307.),2));
00051 psLayer2Z_ = getEcalPreshowerGeometry()->getGeometry(cps2)->getPosition().z();
00052 LogDebug("CaloGeometryTools") << " Preshower layer positions " << psLayer1Z_ << " " << psLayer2Z_ << std::endl;
00053 }
00054 else
00055 LogDebug("CaloGeometryTools") << " No preshower present" << std::endl;
00056
00057
00058
00059 }
00060
00061 CaloGeometryHelper::~CaloGeometryHelper()
00062 {;
00063 }
00064
00065 DetId CaloGeometryHelper::getClosestCell(const XYZPoint& point, bool ecal, bool central) const
00066 {
00067 DetId result;
00068 if(ecal)
00069 {
00070 if(central)
00071 {
00072
00073 result = EcalBarrelGeometry_->getClosestCell(GlobalPoint(point.X(),point.Y(),point.Z()));
00074 #ifdef DEBUGGCC
00075 if(result.null()) return result;
00076 GlobalPoint ip=GlobalPoint(point.X(),point.Y(),point.Z());
00077 GlobalPoint cc=EcalBarrelGeometry_->getGeometry(result)->getPosition();
00078 float deltaeta2 = ip.eta()-cc.eta();
00079 deltaeta2 *= deltaeta2;
00080 float deltaphi2 = acos(cos(ip.phi()-cc.phi()));
00081 deltaphi2 *= deltaphi2;
00082 Histos::instance()->fill("h100",point.eta(),sqrt(deltaeta2+deltaphi2));
00083 #endif
00084 }
00085 else
00086 {
00087 result = EcalEndcapGeometry_->getClosestCell(GlobalPoint(point.X(),point.Y(),point.Z()));
00088 #ifdef DEBUGGCC
00089 if(result.null())
00090 {
00091 return result;
00092 }
00093 GlobalPoint ip=GlobalPoint(point.X(),point.Y(),point.Z());
00094 GlobalPoint cc=EcalEndcapGeometry_->getGeometry(result)->getPosition();
00095 Histos::instance()->fill("h110",point.eta(),(ip-cc).perp());
00096 #endif
00097 }
00098 }
00099 else
00100 {
00101 result=HcalGeometry_->getClosestCell(GlobalPoint(point.X(),point.Y(),point.Z()));
00102 HcalDetId myDetId(result);
00103
00104
00105 if ( myDetId.subdetId() == HcalForward ) {
00106 int mylayer;
00107 if ( fabs(point.Z()) > 1132. ) {
00108 mylayer = 2;
00109 } else {
00110 mylayer = 1;
00111 }
00112 HcalDetId myDetId2((HcalSubdetector)myDetId.subdetId(),myDetId.ieta(),myDetId.iphi(),mylayer);
00113 result = myDetId2;
00114 return result;
00115 }
00116
00117
00118 if(result.subdetId()!=HcalEndcap) return result;
00119
00120 if(myDetId.depth()==3) return result;
00121
00122 int ieta=myDetId.ietaAbs();
00123 float azmin=400.458;
00124
00125 if(ieta<=17)
00126 return result;
00127 else if(ieta>=18 && ieta<=26)
00128 azmin += 35.0;
00129 else if(ieta>=27)
00130 azmin += 21.0;
00131
00132 HcalDetId first(HcalEndcap,myDetId.ieta(),myDetId.iphi(),1);
00133 bool layer2=(fabs(point.Z())>azmin);
00134 if(!layer2)
00135 {
00136 return first;
00137 }
00138 else
00139 {
00140 HcalDetId second(HcalEndcap,myDetId.ieta(),myDetId.iphi(),2);
00141 if(second!=HcalDetId()) result=second;
00142 }
00143 #ifdef DEBUGGCC
00144 if(result.null())
00145 {
00146 return result;
00147 }
00148 GlobalPoint ip=GlobalPoint(point.x(),point.y(),point.z());
00149 GlobalPoint cc=HcalGeometry_->getGeometry(result)->getPosition();
00150 float deltaeta2 = ip.eta()-cc.eta();
00151 deltaeta2 *= deltaeta2;
00152 float deltaphi2 = acos(cos(ip.phi()-cc.phi()));
00153 deltaphi2 *= deltaphi2;
00154
00155 Histos::instance()->fill("h120",point.eta(),sqrt(deltaeta2+deltaphi2));
00156 #endif
00157
00158 }
00159 return result;
00160 }
00161
00162 void CaloGeometryHelper::getWindow(const DetId& pivot,int s1,int s2,std::vector<DetId>& vec) const
00163 {
00164
00165
00166
00167 vec=getEcalTopology(pivot.subdetId())->getWindow(pivot,s1,s2);
00168 DistanceToCell distance(getEcalGeometry(pivot.subdetId()),pivot);
00169 sort(vec.begin(),vec.end(),distance);
00170 }
00171
00172 void CaloGeometryHelper::buildCrystal(const DetId & cell,Crystal& xtal) const
00173 {
00174 if(cell.subdetId()==EcalBarrel)
00175 {
00176 xtal=Crystal(cell,&barrelCrystals_[EBDetId(cell).hashedIndex()]);
00177 return;
00178 }
00179 if(cell.subdetId()==EcalEndcap)
00180 {
00181 xtal=Crystal(cell,&endcapCrystals_[EEDetId(cell).hashedIndex()]);
00182 return;
00183 }
00184 }
00185
00186
00187 void CaloGeometryHelper::buildNeighbourArray()
00188 {
00189
00190 static const CaloDirection orderedDir[8]={SOUTHWEST,SOUTH,SOUTHEAST,WEST,EAST,NORTHWEST,NORTH,
00191 NORTHEAST};
00192
00193 const unsigned nbarrel = EBDetId::kSizeForDenseIndexing;
00194
00195 barrelNeighbours_.resize(nbarrel);
00196
00197
00198
00199 const std::vector<DetId>& vec(EcalBarrelGeometry_->getValidDetIds(DetId::Ecal,EcalBarrel));
00200 unsigned size=vec.size();
00201 for(unsigned ic=0; ic<size; ++ic)
00202 {
00203
00204 std::vector<DetId> neighbours(EcalBarrelTopology_->getWindow(vec[ic],3,3));
00205
00206 unsigned nneighbours=neighbours.size();
00207
00208 unsigned hashedindex=EBDetId(vec[ic]).hashedIndex();
00209 if(hashedindex>=nbarrel)
00210 {
00211 LogDebug("CaloGeometryTools") << " Array overflow " << std::endl;
00212 }
00213
00214
00215
00216
00217
00218
00219
00220 if(nneighbours==9)
00221 {
00222 barrelNeighbours_[hashedindex].reserve(8);
00223 for(unsigned in=0;in<nneighbours;++in)
00224 {
00225
00226 if(neighbours[in]!=vec[ic])
00227 {
00228 barrelNeighbours_[hashedindex].push_back(neighbours[in]);
00229
00230 }
00231 }
00232 }
00233 else
00234 {
00235 DetId central(vec[ic]);
00236 barrelNeighbours_[hashedindex].resize(8,DetId(0));
00237 for(unsigned idir=0;idir<8;++idir)
00238 {
00239 DetId testid=central;
00240 bool status=move(testid,orderedDir[idir],false);
00241 if(status) barrelNeighbours_[hashedindex][idir]=testid;
00242 }
00243
00244 }
00245 }
00246
00247
00248
00249
00250
00251
00252
00253 const std::vector<DetId> & vece(EcalEndcapGeometry_->getValidDetIds(DetId::Ecal,EcalEndcap));
00254 size=vece.size();
00255
00256
00257 const unsigned nendcap=EEDetId::kSizeForDenseIndexing;
00258
00259 endcapNeighbours_.resize(nendcap);
00260 for(unsigned ic=0; ic<size; ++ic)
00261 {
00262
00263 std::vector<DetId> neighbours(EcalEndcapTopology_->getWindow(vece[ic],3,3));
00264 unsigned nneighbours=neighbours.size();
00265
00266 unsigned hashedindex=EEDetId(vece[ic]).hashedIndex();
00267
00268 if(hashedindex>=nendcap)
00269 {
00270 LogDebug("CaloGeometryTools") << " Array overflow " << std::endl;
00271 }
00272
00273 if(nneighbours==9)
00274 {
00275 endcapNeighbours_[hashedindex].reserve(8);
00276 for(unsigned in=0;in<nneighbours;++in)
00277 {
00278
00279 if(neighbours[in]!=vece[ic])
00280 {
00281 endcapNeighbours_[hashedindex].push_back(neighbours[in]);
00282 }
00283 }
00284 }
00285 else
00286 {
00287 DetId central(vece[ic]);
00288 endcapNeighbours_[hashedindex].resize(8,DetId(0));
00289 for(unsigned idir=0;idir<8;++idir)
00290 {
00291 DetId testid=central;
00292 bool status=move(testid,orderedDir[idir],false);
00293 if(status) endcapNeighbours_[hashedindex][idir]=testid;
00294 }
00295
00296 }
00297 }
00298
00299 neighbourmapcalculated_ = true;
00300 }
00301
00302 const std::vector<DetId>& CaloGeometryHelper::getNeighbours(const DetId& detid) const
00303 {
00304 return (detid.subdetId()==EcalBarrel)?barrelNeighbours_[EBDetId(detid).hashedIndex()]:
00305 endcapNeighbours_[EEDetId(detid).hashedIndex()];
00306 }
00307
00308 bool CaloGeometryHelper::move(DetId& cell, const CaloDirection&dir,bool fast) const
00309 {
00310 DetId originalcell = cell;
00311 if(dir==NONE || cell==DetId(0)) return false;
00312
00313
00314
00315
00316 static const int calodirections[9]={-1,1,2,0,4,3,7,5,6};
00317
00318 if(fast&&neighbourmapcalculated_)
00319 {
00320 DetId result = (originalcell.subdetId()==EcalBarrel) ?
00321 barrelNeighbours_[EBDetId(originalcell).hashedIndex()][calodirections[dir]]:
00322 endcapNeighbours_[EEDetId(originalcell).hashedIndex()][calodirections[dir]];
00323 bool status = !result.null();
00324 cell = result;
00325 return status;
00326 }
00327
00328 if(dir==NORTH || dir ==SOUTH || dir==EAST || dir==WEST)
00329 {
00330 return simplemove(cell,dir);
00331 }
00332 else
00333 {
00334 if(dir == NORTHEAST || dir==NORTHWEST || dir==SOUTHEAST || dir==SOUTHWEST)
00335 return diagonalmove(cell,dir);
00336 }
00337
00338 cell = DetId(0);
00339 return false;
00340 }
00341
00342
00343 bool CaloGeometryHelper::simplemove(DetId& cell, const CaloDirection& dir) const
00344 {
00345 std::vector<DetId> neighbours;
00346 if(cell.subdetId()==EcalBarrel)
00347 neighbours = EcalBarrelTopology_->getNeighbours(cell,dir);
00348 else if(cell.subdetId()==EcalEndcap)
00349 neighbours= EcalEndcapTopology_->getNeighbours(cell,dir);
00350
00351 if(neighbours.size()>0 && !neighbours[0].null())
00352 {
00353 cell = neighbours[0];
00354 return true;
00355 }
00356 else
00357 {
00358 cell = DetId(0);
00359 return false;
00360 }
00361 }
00362
00363 bool CaloGeometryHelper::diagonalmove(DetId& cell, const CaloDirection& dir) const
00364 {
00365 bool result;
00366
00367 if(dir==NORTHEAST)
00368 {
00369 result = simplemove(cell,NORTH);
00370 if(result)
00371 return simplemove(cell,EAST);
00372 else
00373 {
00374 result = simplemove(cell,EAST);
00375 if(result)
00376 return simplemove(cell,NORTH);
00377 else
00378 return false;
00379 }
00380 }
00381 else if(dir==NORTHWEST)
00382 {
00383 result = simplemove(cell,NORTH);
00384 if(result)
00385 return simplemove(cell,WEST);
00386 else
00387 {
00388 result = simplemove(cell,WEST);
00389 if(result)
00390 return simplemove(cell,NORTH);
00391 else
00392 return false;
00393 }
00394 }
00395 else if(dir == SOUTHEAST)
00396 {
00397 result = simplemove(cell,SOUTH);
00398 if(result)
00399 return simplemove(cell,EAST);
00400 else
00401 {
00402 result = simplemove(cell,EAST);
00403 if(result)
00404 return simplemove(cell,SOUTH);
00405 else
00406 return false;
00407 }
00408 }
00409 else if(dir == SOUTHWEST)
00410 {
00411 result = simplemove(cell,SOUTH);
00412 if(result)
00413 return simplemove(cell,WEST);
00414 else
00415 {
00416 result = simplemove(cell,SOUTH);
00417 if(result)
00418 return simplemove(cell,WEST);
00419 else
00420 return false;
00421 }
00422 }
00423 cell = DetId(0);
00424 return false;
00425 }
00426
00427 bool CaloGeometryHelper::borderCrossing(const DetId& c1, const DetId& c2) const
00428 {
00429 if(c1.subdetId()!=c2.subdetId()) return false;
00430
00431 if(c1.subdetId()==EcalBarrel)
00432 {
00433
00434
00435 EBDetId cc1(c1);
00436 EBDetId cc2(c2);
00437 return (cc1.im()!=cc2.im()||cc1.ism()!=cc2.ism() );
00438 }
00439
00440 if(c1.subdetId()==EcalEndcap)
00441 {
00442
00443
00444 return (EEDetId(c1).isc()!=EEDetId(c2).isc());
00445 }
00446 return false;
00447 }
00448
00449 void CaloGeometryHelper::buildCrystalArray()
00450 {
00451 const unsigned nbarrel = EBDetId::kSizeForDenseIndexing;
00452
00453 barrelCrystals_.resize(nbarrel,BaseCrystal());
00454
00455
00456 const std::vector<DetId>& vec(EcalBarrelGeometry_->getValidDetIds(DetId::Ecal,EcalBarrel));
00457 unsigned size=vec.size();
00458 const CaloCellGeometry * geom=0;
00459 for(unsigned ic=0; ic<size; ++ic)
00460 {
00461 unsigned hashedindex=EBDetId(vec[ic]).hashedIndex();
00462 geom = EcalBarrelGeometry_->getGeometry(vec[ic]);
00463 BaseCrystal xtal(vec[ic]);
00464 xtal.setCorners(geom->getCorners(),geom->getPosition());
00465 barrelCrystals_[hashedindex]=xtal;
00466 }
00467
00468
00469
00470
00471
00472 const std::vector<DetId>& vece(EcalEndcapGeometry_->getValidDetIds(DetId::Ecal,EcalEndcap));
00473 size=vece.size();
00474
00475
00476 const unsigned nendcap=EEDetId::kSizeForDenseIndexing;
00477
00478 endcapCrystals_.resize(nendcap,BaseCrystal());
00479 for(unsigned ic=0; ic<size; ++ic)
00480 {
00481 unsigned hashedindex=EEDetId(vece[ic]).hashedIndex();
00482 geom = EcalEndcapGeometry_->getGeometry(vece[ic]);
00483 BaseCrystal xtal(vece[ic]);
00484 xtal.setCorners(geom->getCorners(),geom->getPosition());
00485 endcapCrystals_[hashedindex]=xtal;
00486 }
00487
00488 }