38 #include <boost/algorithm/string/replace.hpp> 46 : tableSet_(tableSet),
48 theGridFiles_(nullptr),
50 useMergeFileIfAvailable_(mergeFile) {
51 LogTrace(
"MagGeoBuilder") <<
"Constructing a MagGeoBuilder";
66 int isurfaces = ivolumes * 6;
72 set<const void*> ptrs;
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 const string magfStr2{
"cmsMagneticField:MAGF"};
123 if (fv.
name() != magfStr && fv.
name() != magfStr2) {
125 LogTrace(
"MagGeoBuilder") <<
"Filtered view top node name is " << topNodeName <<
".";
128 bool doSubDets = fv.
next(0);
131 while (go && doSubDets) {
132 LogTrace(
"MagGeoBuilder") <<
"Next node name is " << fv.
name() <<
".";
133 if (fv.
name() == magfStr)
140 <<
" Neither the top node, nor any child node of the filtered view is \"MAGF\" but the top node is instead \"" 141 << topNodeName <<
"\"";
146 bool doSubDets = fv.
next(0);
147 if (doSubDets ==
false) {
148 LogError(
"MagGeoBuilder") <<
"Filtered view has no node. Cannot build.";
160 int key = (
v->volumeno) * 100 +
v->copyno;
163 key = (
v->volumeno) * 100;
168 string magFile = (*itable).second.first;
171 conv << setfill(
'0') << setw(3) <<
v->volumeno <<
" " << setw(2)
173 conv >> svol >> ssec;
174 boost::replace_all(magFile,
"[v]", svol);
175 boost::replace_all(magFile,
"[s]", ssec);
176 int masterSector = (*itable).second.second;
177 if (masterSector == 0)
178 masterSector =
v->copyno;
179 v->magFile = magFile;
180 v->masterSector = masterSector;
182 edm::LogError(
"MagGeoBuilderbuild") <<
"ERROR: no table spec found for V " <<
v->volumeno <<
":" <<
v->copyno;
187 float Z =
v->center().z();
188 float R =
v->center().perp();
189 LogTrace(
"MagGeoBuilder") <<
" Vol R and Z values determine barrel or endcap. R = " <<
R <<
", Z = " <<
Z;
197 if ((fabs(
Z) < 647. || (
R > 350. && fabs(
Z) < 662.)) &&
198 !(fabs(
Z) > 480 &&
R < 172)
203 LogTrace(
"MagGeoBuilder") <<
" (Barrel)";
209 if (
v->copyno ==
v->masterSector) {
212 bInterpolators[
v->magFile] =
i;
217 LogTrace(
"MagGeoBuilder") <<
" (Endcaps)";
219 if (
v->copyno ==
v->masterSector) {
222 eInterpolators[
v->magFile] =
i;
227 doSubDets = fv.
next(0);
231 <<
"Number of volumes (endcap): " <<
eVolumes_.size();
232 LogTrace(
"MagGeoBuilder") <<
"**********************************************************";
241 LogTrace(
"MagGeoBuilder") <<
"-----------------------";
242 LogTrace(
"MagGeoBuilder") <<
"SUMMARY: Barrel ";
245 LogTrace(
"MagGeoBuilder") <<
"SUMMARY: Endcaps ";
247 LogTrace(
"MagGeoBuilder") <<
"-----------------------";
254 LogError(
"MagGeoBuilder") <<
"Error: Barrel volumes are missing. Terminating build.";
266 LogTrace(
"MagGeoBuilder") <<
" R layers: " << rmin <<
" " << rmax;
276 handles::const_iterator ringStart =
first;
277 handles::const_iterator separ =
first;
279 for (
unsigned int i = 0;
i < rClust.size() - 1; ++
i) {
281 LogTrace(
"MagGeoBuilder") <<
" Layer at RN = " << rClust[
i];
282 float rSepar = (rClust[
i] + rClust[
i + 1]) / 2.
f;
283 while ((*separ)->RN() < rSepar)
287 layers.push_back(thislayer);
292 LogTrace(
"MagGeoBuilder") <<
" Layer at RN = " << rClust.back();
294 layers.push_back(thislayer);
297 LogTrace(
"MagGeoBuilder") <<
"Barrel: Found " << rClust.size() <<
" clusters in R, " <<
layers.size() <<
" layers ";
304 constexpr
float phireso = 0.05;
305 constexpr
int twoPiOverPhiReso =
static_cast<int>(2._pi / phireso) + 1;
309 hisPhi.
fill(
i->minPhi());
311 vector<float> phiClust = hisPhi.
clusterize(phireso);
312 int nESectors = phiClust.size();
313 if (nESectors <= 0) {
314 LogError(
"MagGeoBuilder") <<
"ERROR: Endcap sectors are missing. Terminating build.";
317 if (
debug_ && (nESectors % 12) != 0) {
318 LogTrace(
"MagGeoBuilder") <<
"ERROR: unexpected # of endcap sectors: " << nESectors;
326 float lastBinPhi = phiClust.back();
327 handles::reverse_iterator ri =
eVolumes_.rbegin();
328 while ((*ri)->center().phi() > lastBinPhi) {
334 handles::iterator newbeg = ri.base();
340 for (
int i = 0;
i < nESectors; ++
i) {
347 if (secCopyNo >= 0 && (*iv)->copyno != secCopyNo)
348 LogTrace(
"MagGeoBuilder") <<
"ERROR: volume copyno " << (*iv)->name <<
":" << (*iv)->copyno
349 <<
" differs from others in same sectors with copyno = " << secCopyNo;
350 secCopyNo = (*iv)->copyno;
357 LogTrace(
"MagGeoBuilder") <<
"Endcap: Found " <<
sectors.size() <<
" sectors ";
368 for (
const auto& ilay :
layers) {
369 mBLayers_.push_back(ilay.buildMagBLayer());
371 LogTrace(
"MagGeoBuilder") <<
"*** BARREL ********************************************" <<
newln 372 <<
"Number of different volumes = " << bVolCount <<
newln 373 <<
"Number of interpolators built = " << bInterpolators.size() <<
newln 374 <<
"Number of MagBLayers built = " <<
mBLayers_.size();
386 LogTrace(
"MagGeoBuilder") <<
"*** ENDCAP ********************************************" <<
newln 387 <<
"Number of different volumes = " << eVolCount <<
newln 388 <<
"Number of interpolators built = " << eInterpolators.size() <<
newln 389 <<
"Number of MagESector built = " <<
mESectors_.size();
396 const map<string, MagProviderInterpol*>& interpolators)
const {
400 auto found = interpolators.find(vol->magFile);
401 if (
found != interpolators.end()) {
404 edm::LogError(
"MagGeoBuilder") <<
"No interpolator found for file " << vol->magFile <<
" vol: " << vol->volumeno
406 << interpolators.size();
411 int key = (vol->volumeno) * 100 + vol->copyno;
414 key = (vol->volumeno) * 100;
422 LogTrace(
"MagGeoBuilder") <<
"Applying scaling factor " << sf <<
" to " << vol->volumeno <<
"[" << vol->copyno
423 <<
"] (key:" <<
key <<
")";
429 if (vol->copyno == vol->masterSector) {
433 vol->magVolume->setIsIron(vol->isIron());
436 vol->magVolume->volumeNo = vol->volumeno;
437 vol->magVolume->copyno = vol->copyno;
443 LogTrace(
"MagGeoBuilder") <<
"Building interpolator from " << vol->
volumeno <<
" copyno " << vol->
copyno <<
" at " 444 << vol->
center() <<
" phi: " <<
static_cast<double>(vol->
center().
phi()) / 1._pi
448 double masterSectorPhi = (vol->
masterSector - 1) * 1._pi / 6.;
450 if (
delta > (1._pi / 9.)) {
451 LogTrace(
"MagGeoBuilder") <<
"***WARNING wrong sector? Vol delta from master sector is " <<
delta / 1._pi
457 retValue = builder.
build(vol).release();
459 cerr <<
"MagGeoBuilder: exception in reading table; " << exc.
what() << endl;
476 if (
grid !=
nullptr) {
478 LogTrace(
"MagGeoBuilder") <<
"Grid has 3 dimensions " 479 <<
" number of nodes is " << sizes.
w <<
" " << sizes.
h <<
" " << sizes.
d;
483 size_t dumpCount = 0;
484 for (
int j = 0;
j < sizes.
h;
j++) {
485 for (
int k = 0;
k < sizes.
d;
k++) {
486 for (
int i = 0;
i < sizes.
w;
i++) {
489 if (++dumpCount < 2) {
491 LogTrace(
"MagGeoBuilder") <<
"GRID ERROR: " <<
i <<
" " <<
j <<
" " <<
k <<
" local: " << lp
492 <<
" global: " << gp <<
" R= " << gp.perp() <<
" phi=" << gp.phi();
500 <<
" : Number of grid points outside the MagVolume: " << dumpCount <<
"/" 501 << sizes.
w * sizes.
h * sizes.
d;
509 LogTrace(
"MagGeoBuilder") <<
"--------------------------------------------------";
510 LogTrace(
"MagGeoBuilder") <<
" inside(center) test";
516 if (
i->magVolume->inside(vol->center())) {
517 LogTrace(
"MagGeoBuilder") <<
"*** ERROR: center of V " << vol->volumeno <<
":" << vol->copyno <<
" is inside V " 518 <<
i->volumeno <<
":" <<
i->copyno;
522 if (vol->magVolume->inside(vol->center())) {
523 LogTrace(
"MagGeoBuilder") <<
"V " << vol->volumeno <<
":" << vol->copyno <<
" OK ";
525 LogTrace(
"MagGeoBuilder") <<
"*** ERROR: center of volume is not inside it, " << vol->volumeno <<
":" 529 LogTrace(
"MagGeoBuilder") <<
"--------------------------------------------------";
537 vector<MagVolume6Faces*>
v;
540 v.push_back(
i->magVolume);
546 vector<MagVolume6Faces*>
v;
549 v.push_back(
i->magVolume);
572 <<
"Invalid field scaling parameters 'scalingVolumes' and 'scalingFactors' ";
574 for (
unsigned int i = 0;
i <
keys.size(); ++
i) {
MagGeoBuilderFromDDD::volumeHandle volumeHandle
void buildMagVolumes(const handles &volumes, const std::map< std::string, MagProviderInterpol *> &interpolators) const
std::vector< MagBLayer * > barrelLayers() const
Get barrel layers.
Geom::Phi< T > phi() const
void summary(handles &volumes) const
GloballyPositioned< float >::LocalPoint LocalPoint
std::vector< MagESector * > mESectors_
Log< level::Error, false > LogError
const GlobalPoint & center() const
Return the center of the volume.
unsigned short volumeno
volume number
unsigned short copyno
copy number
U second(std::pair< T, U > const &p)
std::string_view name() const
std::unique_ptr< MagProviderInterpol > build(volumeHandle const *)
std::vector< MagBLayer * > mBLayers_
std::vector< float > clusterize(float resolution)
std::vector< BaseVolumeHandle * > handles
MagProviderInterpol * buildInterpolator(const volumeHandle *vol, InterpolatorBuilder &) const
const char * what() const override
Abs< T >::type abs(const T &t)
int masterSector
The sector for which an interpolator for this class of volumes should be built.
bool next(int)
set current node to the next node in the filtered tree
const TableFileMap * theGridFiles_
const bool useMergeFileIfAvailable_
void setGridFiles(const TableFileMap &gridFiles)
void precomputed_value_sort(RandomAccessIterator begin, RandomAccessIterator end, const Extractor &extr, const Compare &comp)
const PositionType & position() const
GloballyPositioned< float >::GlobalPoint GlobalPoint
dd4hep::Volume worldVolume() const
Handle to the world volume containing everything.
void testInside(handles &volumes) const
std::vector< MagESector * > endcapSectors() const
Get endcap layers.
std::map< int, double > theScalingFactors_
std::vector< MagVolume6Faces * > barrelVolumes() const
void build(const cms::DDDetector *det)
const PlacedVolume volume() const
The physical volume of the current node.
std::vector< VolumeSide > sides() const override
The surfaces and they orientation, as required to build a MagVolume.
void setScaling(const std::vector< int > &keys, const std::vector< double > &values)
const RotationType & rotation() const
char const * what() const noexcept override
std::map< int, std::pair< std::string, int > > TableFileMap
const GloballyPositioned< float > * placement() const
Position and rotation.
def rotate(angle, cx=0, cy=0)
std::vector< MagVolume6Faces * > endcapVolumes() const
std::string magFile
Name of magnetic field table file.
void ownsFieldProvider(bool o)