Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "MagneticField/VolumeBasedEngine/interface/MagGeometry.h"
00010 #include "MagneticField/VolumeGeometry/interface/MagVolume.h"
00011 #include "MagneticField/VolumeGeometry/interface/MagVolume6Faces.h"
00012 #include "MagneticField/Layers/interface/MagBLayer.h"
00013 #include "MagneticField/Layers/interface/MagESector.h"
00014
00015 #include "Utilities/BinningTools/interface/PeriodicBinFinderInPhi.h"
00016
00017 #include <FWCore/ParameterSet/interface/ParameterSet.h>
00018
00019 #include "MagneticField/Layers/interface/MagVerbosity.h"
00020 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00021
00022 using namespace std;
00023 using namespace edm;
00024
00025 MagGeometry::MagGeometry(const edm::ParameterSet& config, std::vector<MagBLayer *> tbl,
00026 std::vector<MagESector *> tes,
00027 std::vector<MagVolume6Faces*> tbv,
00028 std::vector<MagVolume6Faces*> tev) :
00029 lastVolume(0), theBLayers(tbl), theESectors(tes), theBVolumes(tbv), theEVolumes(tev), geometryVersion(0)
00030 {
00031
00032 cacheLastVolume = config.getUntrackedParameter<bool>("cacheLastVolume", true);
00033
00034
00035 if (config.exists("geometryVersion")) {
00036 geometryVersion = config.getParameter<int>("geometryVersion");
00037 } else {
00038 geometryVersion = 90322;
00039 }
00040
00041 vector<double> rBorders;
00042
00043 for (vector<MagBLayer *>::const_iterator ilay = theBLayers.begin();
00044 ilay != theBLayers.end(); ++ilay) {
00045 if (verbose::debugOut) cout << " Barrel layer at " << (*ilay)->minR() <<endl;
00046
00047 rBorders.push_back((*ilay)->minR());
00048 }
00049
00050 theBarrelBinFinder = new MagBinFinders::GeneralBinFinderInR<double>(rBorders);
00051
00052 if (verbose::debugOut) {
00053 for (vector<MagESector *>::const_iterator isec = theESectors.begin();
00054 isec != theESectors.end(); ++isec) {
00055 cout << " Endcap sector at " << (*isec)->minPhi() << endl;
00056 }
00057 }
00058
00059
00060
00061 int nEBins = theESectors.size();
00062 theEndcapBinFinder = new PeriodicBinFinderInPhi<float>(theESectors.front()->minPhi()+Geom::pi()/nEBins, nEBins);
00063
00064 }
00065
00066 MagGeometry::~MagGeometry(){
00067 delete theBarrelBinFinder;
00068 delete theEndcapBinFinder;
00069
00070 for (vector<MagBLayer *>::const_iterator ilay = theBLayers.begin();
00071 ilay != theBLayers.end(); ++ilay) {
00072 delete (*ilay);
00073 }
00074
00075 for (vector<MagESector *>::const_iterator ilay = theESectors.begin();
00076 ilay != theESectors.end(); ++ilay) {
00077 delete (*ilay);
00078 }
00079 }
00080
00081
00082
00083 GlobalVector MagGeometry::fieldInTesla(const GlobalPoint & gp) const {
00084 MagVolume * v = 0;
00085
00086
00087 v = findVolume(gp);
00088 if (v!=0) {
00089 return v->fieldInTesla(gp);
00090 }
00091
00092
00093
00094 if (isnan(gp.mag())) {
00095 LogWarning("InvalidInput") << "Input value invalid (not a number): " << gp << endl;
00096
00097 } else {
00098 LogWarning("MagneticField") << "MagGeometry::fieldInTesla: failed to find volume for " << gp << endl;
00099 }
00100 return GlobalVector();
00101 }
00102
00103
00104
00105 MagVolume*
00106 MagGeometry::findVolume1(const GlobalPoint & gp, double tolerance) const {
00107
00108 MagVolume6Faces * found = 0;
00109
00110 if (inBarrel(gp)) {
00111 for (vector<MagVolume6Faces*>::const_iterator v = theBVolumes.begin();
00112 v!=theBVolumes.end(); ++v){
00113 if ((*v)==0) {
00114 cout << endl << "***ERROR: MagGeometry::findVolume: MagVolume not set" << endl;
00115 continue;
00116 }
00117 if ((*v)->inside(gp,tolerance)) {
00118 found = (*v);
00119 break;
00120 }
00121 }
00122
00123 } else {
00124 for (vector<MagVolume6Faces*>::const_iterator v = theEVolumes.begin();
00125 v!=theEVolumes.end(); ++v){
00126 if ((*v)==0) {
00127 cout << endl << "***ERROR: MagGeometry::findVolume: MagVolume not set" << endl;
00128 continue;
00129 }
00130 if ((*v)->inside(gp,tolerance)) {
00131 found = (*v);
00132 break;
00133 }
00134 }
00135 }
00136
00137 return found;
00138 }
00139
00140
00141 MagVolume*
00142 MagGeometry::findVolume(const GlobalPoint & gp, double tolerance) const{
00143
00144 if (lastVolume!=0 && lastVolume->inside(gp)){
00145 return lastVolume;
00146 }
00147
00148 MagVolume * result=0;
00149 if (inBarrel(gp)) {
00150 double R = gp.perp();
00151 int bin = theBarrelBinFinder->binIndex(R);
00152
00153 for (int bin1 = bin; bin1 >= max(0,bin-2); --bin1) {
00154 if (verbose::debugOut) cout << "Trying layer at R " << theBLayers[bin1]->minR()
00155 << " " << R << endl ;
00156 result = theBLayers[bin1]->findVolume(gp, tolerance);
00157 if (verbose::debugOut) cout << "***In blayer " << bin1-bin << " "
00158 << (result==0? " failed " : " OK ") <<endl;
00159 if (result != 0) break;
00160 }
00161
00162 } else {
00163 Geom::Phi<float> phi = gp.phi();
00164 int bin = theEndcapBinFinder->binIndex(phi);
00165 if (verbose::debugOut) cout << "Trying endcap sector at phi "
00166 << theESectors[bin]->minPhi() << " " << phi << endl ;
00167 result = theESectors[bin]->findVolume(gp, tolerance);
00168 if (verbose::debugOut) cout << "***In guessed esector "
00169 << (result==0? " failed " : " OK ") <<endl;
00170 }
00171
00172
00173 if (result==0 && tolerance < 0.0001) {
00174
00175
00176
00177 if (verbose::debugOut) cout << "Increasing the tolerance to 0.03" <<endl;
00178 result = findVolume(gp, 0.03);
00179 }
00180
00181 if (cacheLastVolume) lastVolume = result;
00182
00183 return result;
00184 }
00185
00186
00187
00188
00189 bool MagGeometry::inBarrel(const GlobalPoint& gp) const {
00190 float Z = fabs(gp.z());
00191 float R = gp.perp();
00192
00193
00194 if (geometryVersion>=90812) {
00195 return (Z<350. ||
00196 (R>172.4 && Z<633.89) ||
00197 (R>308.755 && Z<662.01));
00198 } else {
00199 return (Z<350. ||
00200 (R>172.4 && Z<633.29) ||
00201 (R>308.755 && Z<661.01));
00202 }
00203 }
00204