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