File indexing completed on 2024-04-06 12:22:35
0001
0002
0003
0004
0005
0006
0007 #include "MagneticField/VolumeBasedEngine/interface/MagGeometry.h"
0008 #include "MagneticField/VolumeGeometry/interface/MagVolume.h"
0009 #include "MagneticField/VolumeGeometry/interface/MagVolume6Faces.h"
0010 #include "MagneticField/Layers/interface/MagBLayer.h"
0011 #include "MagneticField/Layers/interface/MagESector.h"
0012
0013 #include "Utilities/BinningTools/interface/PeriodicBinFinderInPhi.h"
0014
0015 #include "FWCore/Utilities/interface/isFinite.h"
0016 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0017
0018 #include <iostream>
0019
0020 using namespace std;
0021 using namespace edm;
0022
0023 namespace {
0024
0025
0026
0027 std::atomic<int> instanceCounter(0);
0028 thread_local int localInstance = 0;
0029 thread_local MagVolume const* lastVolume = nullptr;
0030 }
0031
0032 MagGeometry::MagGeometry(int geomVersion,
0033 const std::vector<MagBLayer*>& tbl,
0034 const std::vector<MagESector*>& tes,
0035 const std::vector<MagVolume6Faces*>& tbv,
0036 const std::vector<MagVolume6Faces*>& tev)
0037 : MagGeometry(geomVersion,
0038 reinterpret_cast<std::vector<MagBLayer const*> const&>(tbl),
0039 reinterpret_cast<std::vector<MagESector const*> const&>(tes),
0040 reinterpret_cast<std::vector<MagVolume6Faces const*> const&>(tbv),
0041 reinterpret_cast<std::vector<MagVolume6Faces const*> const&>(tev)) {}
0042
0043 MagGeometry::MagGeometry(int geomVersion,
0044 const std::vector<MagBLayer const*>& tbl,
0045 const std::vector<MagESector const*>& tes,
0046 const std::vector<MagVolume6Faces const*>& tbv,
0047 const std::vector<MagVolume6Faces const*>& tev)
0048 : me_(++instanceCounter),
0049 theBLayers(tbl),
0050 theESectors(tes),
0051 theBVolumes(tbv),
0052 theEVolumes(tev),
0053 cacheLastVolume(true),
0054 geometryVersion(geomVersion) {
0055 vector<double> rBorders;
0056
0057 for (vector<MagBLayer const*>::const_iterator ilay = theBLayers.begin(); ilay != theBLayers.end(); ++ilay) {
0058 LogTrace("MagGeoBuilder") << " Barrel layer at " << (*ilay)->minR() << endl;
0059
0060 rBorders.push_back((*ilay)->minR() * (*ilay)->minR());
0061 }
0062
0063 theBarrelBinFinder = new MagBinFinders::GeneralBinFinderInR<double>(rBorders);
0064
0065 #ifdef EDM_ML_DEBUG
0066 for (vector<MagESector const*>::const_iterator isec = theESectors.begin(); isec != theESectors.end(); ++isec) {
0067 LogTrace("MagGeoBuilder") << " Endcap sector at " << (*isec)->minPhi() << endl;
0068 }
0069 #endif
0070
0071
0072
0073 int nEBins = theESectors.size();
0074 if (nEBins > 0)
0075 theEndcapBinFinder = new PeriodicBinFinderInPhi<float>(theESectors.front()->minPhi() + Geom::pi() / nEBins, nEBins);
0076
0077
0078
0079 switch (geomVersion >= 120812 ? 0 : (geomVersion >= 90812 ? 1 : 2)) {
0080 case 0:
0081 theBarrelRsq1 = 172.400 * 172.400;
0082 theBarrelRsq2 = 308.735 * 308.735;
0083 theBarrelZ0 = 350.000;
0084 theBarrelZ1 = 633.290;
0085 theBarrelZ2 = 662.010;
0086 break;
0087 case 1:
0088 theBarrelRsq1 = 172.400 * 172.400;
0089 theBarrelRsq2 = 308.755 * 308.755;
0090 theBarrelZ0 = 350.000;
0091 theBarrelZ1 = 633.890;
0092 theBarrelZ2 = 662.010;
0093 break;
0094 case 2:
0095 theBarrelRsq1 = 172.400 * 172.400;
0096 theBarrelRsq2 = 308.755 * 308.755;
0097 theBarrelZ0 = 350.000;
0098 theBarrelZ1 = 633.290;
0099 theBarrelZ2 = 661.010;
0100 break;
0101 }
0102
0103 LogTrace("MagGeometry_cache") << "*** In MagGeometry ctor: me_=" << me_ << " instanceCounter=" << instanceCounter
0104 << endl;
0105 }
0106
0107 MagGeometry::~MagGeometry() {
0108 if (theBarrelBinFinder != nullptr)
0109 delete theBarrelBinFinder;
0110 if (theEndcapBinFinder != nullptr)
0111 delete theEndcapBinFinder;
0112
0113 for (vector<MagBLayer const*>::const_iterator ilay = theBLayers.begin(); ilay != theBLayers.end(); ++ilay) {
0114 delete (*ilay);
0115 }
0116
0117 for (vector<MagESector const*>::const_iterator ilay = theESectors.begin(); ilay != theESectors.end(); ++ilay) {
0118 delete (*ilay);
0119 }
0120 }
0121
0122
0123 GlobalVector MagGeometry::fieldInTesla(const GlobalPoint& gp) const {
0124 MagVolume const* v = nullptr;
0125
0126 v = findVolume(gp);
0127 if (v != nullptr) {
0128 return v->fieldInTesla(gp);
0129 }
0130
0131
0132
0133 if (edm::isNotFinite(gp.mag())) {
0134 LogWarning("MagneticField") << "Input value invalid (not a number): " << gp << endl;
0135
0136 } else {
0137 LogWarning("MagneticField") << "MagGeometry::fieldInTesla: failed to find volume for " << gp << endl;
0138 }
0139 return GlobalVector();
0140 }
0141
0142
0143 MagVolume const* MagGeometry::findVolume1(const GlobalPoint& gp, double tolerance) const {
0144 MagVolume6Faces const* found = nullptr;
0145
0146 int errCnt = 0;
0147 if (inBarrel(gp)) {
0148 for (vector<MagVolume6Faces const*>::const_iterator v = theBVolumes.begin(); v != theBVolumes.end(); ++v) {
0149 if ((*v) == nullptr) {
0150 LogError("MagGeometry") << endl << "***ERROR: MagGeometry::findVolume: MagVolume for barrel not set" << endl;
0151 ++errCnt;
0152 if (errCnt < 3)
0153 continue;
0154 else
0155 break;
0156 }
0157 if ((*v)->inside(gp, tolerance)) {
0158 found = (*v);
0159 break;
0160 }
0161 }
0162
0163 } else {
0164 for (vector<MagVolume6Faces const*>::const_iterator v = theEVolumes.begin(); v != theEVolumes.end(); ++v) {
0165 if ((*v) == nullptr) {
0166 LogError("MagGeometry") << endl << "***ERROR: MagGeometry::findVolume: MagVolume for endcap not set" << endl;
0167 ++errCnt;
0168 if (errCnt < 3)
0169 continue;
0170 else
0171 break;
0172 }
0173 if ((*v)->inside(gp, tolerance)) {
0174 found = (*v);
0175 break;
0176 }
0177 }
0178 }
0179
0180 return found;
0181 }
0182
0183
0184 MagVolume const* MagGeometry::findVolume(const GlobalPoint& gp, double tolerance) const {
0185
0186 if (me_ != localInstance) {
0187 LogTrace("MagGeometry_cache") << "*** In MagGeometry::findVolume resetting cache: me=" << me_
0188 << " localInstance=" << localInstance << endl;
0189 localInstance = me_;
0190 lastVolume = nullptr;
0191 }
0192
0193 if (lastVolume != nullptr && lastVolume->inside(gp)) {
0194 return lastVolume;
0195 }
0196
0197 MagVolume const* result = nullptr;
0198 if (inBarrel(gp)) {
0199 double aRsq = gp.perp2();
0200 int bin = theBarrelBinFinder->binIndex(aRsq);
0201
0202
0203 for (int bin1 = bin; bin1 >= max(0, bin - 3); --bin1) {
0204 LogTrace("MagGeometry") << "Trying layer at R " << theBLayers[bin1]->minR() << " " << sqrt(aRsq) << endl;
0205 result = theBLayers[bin1]->findVolume(gp, tolerance);
0206 LogTrace("MagGeometry") << "***In blayer " << bin1 - bin << " " << (result == nullptr ? " failed " : " OK ")
0207 << endl;
0208 if (result != nullptr)
0209 break;
0210 }
0211
0212 } else {
0213 Geom::Phi<float> phi = gp.phi();
0214 if (theEndcapBinFinder != nullptr && !theESectors.empty()) {
0215 int bin = theEndcapBinFinder->binIndex(phi);
0216 LogTrace("MagGeometry") << "Trying endcap sector at phi " << theESectors[bin]->minPhi() << " " << phi << endl;
0217 result = theESectors[bin]->findVolume(gp, tolerance);
0218 LogTrace("MagGeometry") << "***In guessed esector " << (result == nullptr ? " failed " : " OK ") << endl;
0219 } else
0220 edm::LogError("MagGeometry") << "Endcap empty";
0221 }
0222
0223 if (result == nullptr && tolerance < 0.0001) {
0224
0225
0226
0227 LogTrace("MagGeometry") << "Increasing the tolerance to 0.03" << endl;
0228 result = findVolume(gp, 0.03);
0229 }
0230
0231 if (cacheLastVolume)
0232 lastVolume = result;
0233
0234 return result;
0235 }
0236
0237 bool MagGeometry::inBarrel(const GlobalPoint& gp) const {
0238 double aZ = fabs(gp.z());
0239 double aRsq = gp.perp2();
0240
0241 return ((aZ < theBarrelZ0) || (aZ < theBarrelZ1 && aRsq > theBarrelRsq1) ||
0242 (aZ < theBarrelZ2 && aRsq > theBarrelRsq2));
0243 }