41 #include <boost/algorithm/string/replace.hpp>
44 using namespace magneticfield;
46 using namespace angle_units::operators;
48 MagGeoBuilder::MagGeoBuilder(
string tableSet,
int geometryVersion,
bool debug)
49 : tableSet_(tableSet), geometryVersion_(geometryVersion), theGridFiles_(nullptr),
debug_(debug) {
50 LogTrace(
"MagGeoBuilder") <<
"Constructing a MagGeoBuilder";
64 int ivolumes = volumes.size();
65 int isurfaces = ivolumes * 6;
71 set<const void*> ptrs;
73 for (
auto i : volumes) {
77 for (
int side = 0; side < 6; ++side) {
78 int references =
i->references(side);
79 if (
i->isPlaneMatched(side)) {
81 bool firstOcc = (ptrs.insert(&(
i->surface(side)))).
second;
83 iref_ass += references;
85 LogTrace(
"MagGeoBuilder") <<
"*** Only 1 ref, vol: " <<
i->volumeno <<
" # " <<
i->copyno
89 iref_nass += references;
91 LogTrace(
"MagGeoBuilder") <<
"*** Ref_nass >1 ";
97 iunique = ptrs.size();
99 LogTrace(
"MagGeoBuilder") <<
" volumes " << ivolumes <<
newln <<
" surfaces " << isurfaces <<
newln
100 <<
" assigned " << iassigned <<
newln <<
" unique " << iunique <<
newln
101 <<
" iref_ass " << iref_ass <<
newln <<
" iref_nass " << iref_nass;
107 if (fv.
next(0) ==
false) {
108 LogError(
"MagGeoBuilder") <<
"Filtered view is empty. Cannot build.";
113 map<string, MagProviderInterpol*> bInterpolators;
114 map<string, MagProviderInterpol*> eInterpolators;
120 const string magfStr{
"MAGF"};
121 const string magfStr2{
"cmsMagneticField:MAGF"};
122 if (fv.
name() != magfStr && fv.
name() != magfStr2) {
124 LogTrace(
"MagGeoBuilder") <<
"Filtered view top node name is " << topNodeName <<
".";
127 bool doSubDets = fv.
next(0);
130 while (go && doSubDets) {
131 LogTrace(
"MagGeoBuilder") <<
"Next node name is " << fv.
name() <<
".";
132 if (fv.
name() == magfStr)
139 <<
" Neither the top node, nor any child node of the filtered view is \"MAGF\" but the top node is instead \""
140 << topNodeName <<
"\"";
145 bool doSubDets = fv.
next(0);
146 if (doSubDets ==
false) {
147 LogError(
"MagGeoBuilder") <<
"Filtered view has no node. Cannot build.";
159 TableFileMap::const_iterator itable =
theGridFiles_->find(key);
166 string magFile = (*itable).second.first;
169 conv << setfill(
'0') << setw(3) << v->
volumeno <<
" " << setw(2)
171 conv >> svol >> ssec;
172 boost::replace_all(magFile,
"[v]", svol);
173 boost::replace_all(magFile,
"[s]", ssec);
174 int masterSector = (*itable).second.second;
175 if (masterSector == 0)
187 LogTrace(
"MagGeoBuilder") <<
" Vol R and Z values determine barrel or endcap. R = " << R <<
", Z = " <<
Z;
195 if ((fabs(Z) < 647. || (R > 350. && fabs(Z) < 662.)) &&
196 !(fabs(Z) > 480 && R < 172)
201 LogTrace(
"MagGeoBuilder") <<
" (Barrel)";
212 LogTrace(
"MagGeoBuilder") <<
" (Endcaps)";
219 doSubDets = fv.
next(0);
223 <<
"Number of volumes (endcap): " <<
eVolumes_.size();
224 LogTrace(
"MagGeoBuilder") <<
"**********************************************************";
233 LogTrace(
"MagGeoBuilder") <<
"-----------------------";
234 LogTrace(
"MagGeoBuilder") <<
"SUMMARY: Barrel ";
237 LogTrace(
"MagGeoBuilder") <<
"SUMMARY: Endcaps ";
239 LogTrace(
"MagGeoBuilder") <<
"-----------------------";
246 LogError(
"MagGeoBuilder") <<
"Error: Barrel volumes are missing. Terminating build.";
258 LogTrace(
"MagGeoBuilder") <<
" R layers: " << rmin <<
" " << rmax;
266 vector<float> rClust = hisR.
clusterize(resolution);
268 handles::const_iterator ringStart =
first;
269 handles::const_iterator separ =
first;
271 for (
unsigned int i = 0;
i < rClust.size() - 1; ++
i) {
273 LogTrace(
"MagGeoBuilder") <<
" Layer at RN = " << rClust[
i];
274 float rSepar = (rClust[
i] + rClust[
i + 1]) / 2.
f;
275 while ((*separ)->RN() < rSepar)
279 layers.push_back(thislayer);
284 LogTrace(
"MagGeoBuilder") <<
" Layer at RN = " << rClust.back();
286 layers.push_back(thislayer);
289 LogTrace(
"MagGeoBuilder") <<
"Barrel: Found " << rClust.size() <<
" clusters in R, " << layers.size() <<
" layers ";
296 constexpr
float phireso = 0.05;
297 constexpr
int twoPiOverPhiReso =
static_cast<int>(2._pi / phireso) + 1;
301 hisPhi.
fill(
i->minPhi());
303 vector<float> phiClust = hisPhi.
clusterize(phireso);
304 int nESectors = phiClust.size();
305 if (nESectors <= 0) {
306 LogError(
"MagGeoBuilder") <<
"ERROR: Endcap sectors are missing. Terminating build.";
309 if (
debug_ && (nESectors % 12) != 0) {
310 LogTrace(
"MagGeoBuilder") <<
"ERROR: unexpected # of endcap sectors: " << nESectors;
318 float lastBinPhi = phiClust.back();
319 handles::reverse_iterator ri = eVolumes_.rbegin();
320 while ((*ri)->center().phi() > lastBinPhi) {
323 if (ri != eVolumes_.rbegin()) {
326 handles::iterator newbeg = ri.base();
327 rotate(eVolumes_.begin(), newbeg, eVolumes_.end());
331 int offset = eVolumes_.size() / nESectors;
332 for (
int i = 0;
i < nESectors; ++
i) {
334 LogTrace(
"MagGeoBuilder") <<
" Sector at phi = " << (*(eVolumes_.begin() + ((
i)*offset)))->center().phi();
337 for (handles::const_iterator
iv = eVolumes_.begin() + ((
i)*offset);
iv != eVolumes_.begin() + ((
i + 1) * offset);
339 if (secCopyNo >= 0 && (*iv)->copyno != secCopyNo)
340 LogTrace(
"MagGeoBuilder") <<
"ERROR: volume copyno " << (*iv)->name <<
":" << (*iv)->copyno
341 <<
" differs from others in same sectors with copyno = " << secCopyNo;
342 secCopyNo = (*iv)->copyno;
346 sectors.push_back(
eSector(eVolumes_.begin() + ((
i)*offset), eVolumes_.begin() + ((
i + 1) * offset),
debug_));
349 LogTrace(
"MagGeoBuilder") <<
"Endcap: Found " << sectors.size() <<
" sectors ";
360 for (
const auto& ilay : layers) {
361 mBLayers_.push_back(ilay.buildMagBLayer());
363 LogTrace(
"MagGeoBuilder") <<
"*** BARREL ********************************************" <<
newln
364 <<
"Number of different volumes = " << bVolCount <<
newln
365 <<
"Number of interpolators built = " << bInterpolators.size() <<
newln
366 <<
"Number of MagBLayers built = " <<
mBLayers_.size();
375 for (
const auto& isec : sectors) {
378 LogTrace(
"MagGeoBuilder") <<
"*** ENDCAP ********************************************" <<
newln
379 <<
"Number of different volumes = " << eVolCount <<
newln
380 <<
"Number of interpolators built = " << eInterpolators.size() <<
newln
381 <<
"Number of MagESector built = " <<
mESectors_.size();
389 for (
auto vol : volumes) {
391 if (interpolators.find(vol->magFile) != interpolators.end()) {
392 mp = interpolators[vol->magFile];
394 edm::LogError(
"MagGeoBuilder") <<
"No interpolator found for file " << vol->magFile <<
" vol: " << vol->volumeno
396 << interpolators.size();
401 int key = (vol->volumeno) * 100 + vol->copyno;
404 key = (vol->volumeno) * 100;
412 LogTrace(
"MagGeoBuilder") <<
"Applying scaling factor " << sf <<
" to " << vol->volumeno <<
"[" << vol->copyno
413 <<
"] (key:" << key <<
")";
419 if (vol->copyno == vol->masterSector) {
423 vol->magVolume->setIsIron(vol->isIron());
426 vol->magVolume->volumeNo = vol->volumeno;
427 vol->magVolume->copyno = vol->copyno;
433 double masterSectorPhi = (vol->
masterSector - 1) * 1._pi / 6.;
435 LogTrace(
"MagGeoBuilder") <<
"Building interpolator from " << vol->
volumeno <<
" copyno " << vol->
copyno <<
" at "
436 << vol->
center() <<
" phi: " <<
static_cast<double>(vol->
center().
phi()) / 1._pi
440 if (delta > (1._pi / 9.)) {
441 LogTrace(
"MagGeoBuilder") <<
"***WARNING wrong sector? Vol delta from master sector is " << delta / 1._pi
457 cerr <<
"MagGeoBuilder: exception in reading table; " << exc.
what() << endl;
488 interpolators.erase(vol->
magFile);
500 if (grid !=
nullptr) {
502 LogTrace(
"MagGeoBuilder") <<
"Grid has 3 dimensions "
503 <<
" number of nodes is " << sizes.
w <<
" " << sizes.
h <<
" " << sizes.
d;
507 size_t dumpCount = 0;
508 for (
int j = 0;
j < sizes.
h;
j++) {
509 for (
int k = 0;
k < sizes.
d;
k++) {
510 for (
int i = 0;
i < sizes.
w;
i++) {
512 if (!tempVolume.inside(lp, tolerance)) {
513 if (++dumpCount < 2) {
515 LogTrace(
"MagGeoBuilder") <<
"GRID ERROR: " <<
i <<
" " <<
j <<
" " <<
k <<
" local: " << lp
516 <<
" global: " << gp <<
" R= " << gp.perp() <<
" phi=" << gp.phi();
524 <<
" : Number of grid points outside the MagVolume: " << dumpCount <<
"/"
525 << sizes.
w * sizes.
h * sizes.
d;
532 LogTrace(
"MagGeoBuilder") <<
"--------------------------------------------------";
533 LogTrace(
"MagGeoBuilder") <<
" inside(center) test";
534 for (
auto vol : volumes) {
535 for (
auto i : volumes) {
539 if (
i->magVolume->inside(vol->center())) {
540 LogTrace(
"MagGeoBuilder") <<
"*** ERROR: center of V " << vol->volumeno <<
":" << vol->copyno <<
" is inside V "
541 <<
i->volumeno <<
":" <<
i->copyno;
545 if (vol->magVolume->inside(vol->center())) {
546 LogTrace(
"MagGeoBuilder") <<
"V " << vol->volumeno <<
":" << vol->copyno <<
" OK ";
548 LogTrace(
"MagGeoBuilder") <<
"*** ERROR: center of volume is not inside it, " << vol->volumeno <<
":"
552 LogTrace(
"MagGeoBuilder") <<
"--------------------------------------------------";
560 vector<MagVolume6Faces*>
v;
563 v.push_back(
i->magVolume);
569 vector<MagVolume6Faces*>
v;
572 v.push_back(
i->magVolume);
593 if (keys.size() != values.size()) {
595 <<
"Invalid field scaling parameters 'scalingVolumes' and 'scalingFactors' ";
597 for (
unsigned int i = 0;
i < keys.size(); ++
i) {
MagGeoBuilderFromDDD::volumeHandle volumeHandle
std::vector< LayerSetAndLayers > layers(const SeedingLayerSetsHits &sets)
void buildInterpolator(const volumeHandle *vol, std::map< std::string, MagProviderInterpol * > &interpolators)
std::vector< MagVolume6Faces * > endcapVolumes() const
ROOT::Math::Plane3D::Vector Vector
Geom::Phi< T > phi() const
GloballyPositioned< float >::LocalPoint LocalPoint
std::vector< MagESector * > mESectors_
Log< level::Error, false > LogError
const PlacedVolume volume() const
The physical volume of the current node.
unsigned short volumeno
volume number
unsigned short copyno
copy number
U second(std::pair< T, U > const &p)
std::vector< MagBLayer * > mBLayers_
std::vector< float > clusterize(float resolution)
std::vector< BaseVolumeHandle * > handles
const char * what() const override
if(conf_.getParameter< bool >("UseStripCablingDB"))
tuple key
prepare the HTCondor submission files and eventually submit them
char const * what() const noexceptoverride
Abs< T >::type abs(const T &t)
int masterSector
The sector for which an interpolator for this class of volumes should be built.
std::string_view name() const
static MFGrid * build(const std::string &name, const GloballyPositioned< float > &vol)
Build interpolator for a binary grid file.
bool next(int)
set current node to the next node in the filtered tree
Point3DBase< T, GlobalTag > PositionType
void summary(handles &volumes) const
const GlobalPoint & center() const
Return the center of the volume.
const TableFileMap * theGridFiles_
void setGridFiles(const TableFileMap &gridFiles)
void precomputed_value_sort(RandomAccessIterator begin, RandomAccessIterator end, const Extractor &extr, const Compare &comp)
GloballyPositioned< float >::GlobalPoint GlobalPoint
std::vector< MagBLayer * > barrelLayers() const
Get barrel layers.
dd4hep::Volume worldVolume() const
Handle to the world volume containing everything.
std::vector< MagESector * > endcapSectors() const
Get endcap layers.
std::map< int, double > theScalingFactors_
std::vector< MagVolume6Faces * > barrelVolumes() const
const GloballyPositioned< float > * placement() const
Position and rotation.
void buildMagVolumes(const handles &volumes, std::map< std::string, MagProviderInterpol * > &interpolators)
void build(const cms::DDDetector *det)
std::vector< VolumeSide > sides() const override
The surfaces and they orientation, as required to build a MagVolume.
const RotationType & rotation() const
std::string fullPath() const
void setScaling(const std::vector< int > &keys, const std::vector< double > &values)
std::map< int, std::pair< std::string, int > > TableFileMap
const PositionType & position() const
std::string magFile
Name of magnetic field table file.
void testInside(handles &volumes)
void ownsFieldProvider(bool o)