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