42 #include <boost/algorithm/string/replace.hpp> 50 : tableSet_(tableSet), geometryVersion_(geometryVersion), theGridFiles_(
nullptr), debug_(debug) {
51 LogTrace(
"MagGeoBuilder") <<
"Constructing a MagGeoBuilder";
65 int ivolumes = volumes.size();
66 int isurfaces = ivolumes * 6;
72 set<const void*> ptrs;
74 for (
auto i : volumes) {
78 for (
int side = 0; side < 6; ++side) {
79 int references =
i->references(side);
80 if (
i->isPlaneMatched(side)) {
82 bool firstOcc = (ptrs.insert(&(
i->surface(side)))).
second;
84 iref_ass += references;
86 LogTrace(
"MagGeoBuilder") <<
"*** Only 1 ref, vol: " <<
i->volumeno <<
" # " <<
i->copyno
90 iref_nass += references;
92 LogTrace(
"MagGeoBuilder") <<
"*** Ref_nass >1 ";
98 iunique = ptrs.size();
100 LogTrace(
"MagGeoBuilder") <<
" volumes " << ivolumes <<
newln <<
" surfaces " << isurfaces <<
newln 101 <<
" assigned " << iassigned <<
newln <<
" unique " << iunique <<
newln 102 <<
" iref_ass " << iref_ass <<
newln <<
" iref_nass " << iref_nass;
108 if (fv.
next(0) ==
false) {
109 LogError(
"MagGeoBuilder") <<
"Filtered view is empty. Cannot build.";
114 map<string, MagProviderInterpol*> bInterpolators;
115 map<string, MagProviderInterpol*> eInterpolators;
121 const string magfStr{
"MAGF"};
122 if (fv.
name() != magfStr) {
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 ";
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 (
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 (
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];
395 <<
"No interpolator found for file " << vol->magFile <<
" vol: " << vol->volumeno <<
"\n" 396 << interpolators.size();
401 int key = (vol->volumeno) * 100 + vol->copyno;
404 key = (vol->volumeno) * 100;
412 LogTrace(
"MagGeoBuilder|buildMagVolumes") <<
"Applying scaling factor " << sf <<
" to " << vol->volumeno <<
"[" 413 << vol->copyno <<
"] (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
void buildInterpolator(const volumeHandle *vol, std::map< std::string, MagProviderInterpol * > &interpolators)
const char * what() const override
std::vector< MagVolume6Faces * > endcapVolumes() const
static HepMC::IO_HEPEVT conv
ROOT::Math::Plane3D::Vector Vector
Geom::Phi< T > phi() const
GloballyPositioned< float >::LocalPoint LocalPoint
char const * what() const override
std::vector< MagESector * > mESectors_
Volume worldVolume() const
Handle to the world volume containing everything.
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
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.
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)
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
def rotate(angle, cx=0, cy=0)
std::string magFile
Name of magnetic field table file.
void testInside(handles &volumes)
void ownsFieldProvider(bool o)
std::vector< VolumeSide > sides() const override
The surfaces and they orientation, as required to build a MagVolume.