CMS 3D CMS Logo

bLayer.cc
Go to the documentation of this file.
1 /*
2  * See header file for a description of this class.
3  *
4  * \author N. Amapane - INFN Torino
5  */
6 
7 #include "bLayer.h"
8 #include "printUniqueNames.h"
11 
13 
14 #include <iostream>
15 
16 using namespace SurfaceOrientation;
17 using namespace magneticfield;
18 
19 //The ctor is in charge of finding sectors inside the layer.
20 bLayer::bLayer(handles::const_iterator begin, handles::const_iterator end, bool debugFlag)
21  : size(end - begin), theVolumes(begin, end), mlayer(nullptr), debug(debugFlag) {
22  // Sort in phi
24 
25  if (debug) {
26  std::cout << " elements: " << theVolumes.size() << " unique volumes: ";
27  printUniqueNames(theVolumes.begin(), theVolumes.end());
28  }
29 
30  // Find sectors in phi
31  handles::iterator secBegin = theVolumes.begin();
32  handles::iterator secEnd = secBegin;
33  int binOffset = 0;
34 
35  const Surface& refSurf = (*secBegin)->surface(outer);
36 
37  int newbegin = 0;
38  int newend = 0;
39 
40  // A sector is made of several volumes in R, and, for planar layers
41  // (box and traps) also in phi, so it might cross the -phi boundary.
42  // For those, we have to look for the end of first sector and rotate the
43  // vector of volumes.
44  // ASSUMPTION: all volumes in a layer must be of compatible type.
45 
46  if (size == 1) { // Only one volume; this is the case for barrel
47  // cylinders.
48  // FIXME sectors.push_back(bSector(theVolumes.begin(),theVolumes.end());
49  if (debug)
50  std::cout << " Sector is just one volume." << std::endl;
51 
52  } else if (size == 12 || // In this case, each volume is a sector.
53  (((*secBegin)->shape() != DDSolidShape::ddtrap) && (*secBegin)->shape() != DDSolidShape::ddbox)) {
54  secEnd = secBegin + size / 12;
55 
56  } else { // there are more than one volume per sector.
57  float tolerance = 0.025; // 250 micron
58  do {
59  if (debug)
60  std::cout << (*secBegin)->name << " " << (*secBegin)->copyno << std::endl;
61  ++secBegin;
62  } while (
63  (secBegin != theVolumes.end()) &&
64  (*secBegin)->sameSurface(
65  refSurf,
66  outer,
67  tolerance)); // This works only if outer surface is a plane, otherwise sameSurface returns always true!
68 
69  secEnd = secBegin;
70  secBegin = theVolumes.begin() + bin((secEnd - theVolumes.begin()) - size / 12);
71  ;
72  newend = secEnd - theVolumes.begin();
73  newbegin = secBegin - theVolumes.begin();
74 
75  // Rotate the begin of the first sector to the vector beginning.
76  rotate(theVolumes.begin(), secBegin, theVolumes.end());
77  secBegin = theVolumes.begin();
78  secEnd = secBegin + size / 12;
79 
80  // Test it is correct...
81  if (!((*secBegin)->sameSurface((*(secEnd - 1))->surface(outer), outer, tolerance))) {
82  std::cout << "*** ERROR: Big mess while looking for sectors " << (*secBegin)->name << " " << (*secBegin)->copyno
83  << " " << (*(secEnd - 1))->name << " " << (*(secEnd - 1))->copyno << std::endl;
84  }
85  }
86 
87  if (debug) {
88  std::cout << " First sector: volumes " << secEnd - theVolumes.begin() << " from " << newbegin
89  << " (phi = " << (*secBegin)->center().phi() << ") "
90  << " to " << newend << " (phi = " << (*secEnd)->center().phi() << ") "
91  << " # " << (*secBegin)->copyno << " ";
92  std::cout << GlobalVector(refSurf.rotation().zx(), refSurf.rotation().zy(), refSurf.rotation().zz()) << std::endl;
93  }
94 
95  if (size != 1) { // Build the 12 sectors
96  int offset = size / 12;
97  sectors.resize(12);
98  for (int i = 0; i < 12; ++i) {
99  int isec = (i + binOffset) % 12;
100  sectors[isec >= 0 ? isec : isec + 12] =
101  bSector(theVolumes.begin() + ((i)*offset), theVolumes.begin() + ((i + 1) * offset), debug);
102  }
103  }
104 
105  if (debug)
106  std::cout << "-----------------------" << std::endl;
107 }
108 
109 int bLayer::bin(int i) const {
110  i = i % size;
111  return (i >= 0 ? i : i + size);
112 }
113 
114 // const bSector &
115 // bLayer::sector(int i) const {
116 // i = i%12;
117 // return sectors[i>=0?i:i+12];
118 // }
119 
120 double bLayer::minR() const {
121  // ASSUMPTION: a layer is only 1 volume thick (by construction).
122  return theVolumes.front()->minR();
123 }
124 
125 // double bLayer::maxR() const {
126 // // ASSUMPTION: a layer is only 1 volume thick (by construction).
127 // return theVolumes.front()->maxR();
128 // }
129 
131  if (mlayer == nullptr) {
132  // If we have only one volume, do not build any MagBSector.
133  if (sectors.empty()) {
134  if (debug && size != 0) {
135  std::cout << "ERROR: bLayer::buildMagBLayer, 0 sectors but " << size << " volumes" << std::endl;
136  }
137  // Technically we might have only one bSector built and we would
138  // not need a separate MagBLayer constructor...
139  mlayer = new MagBLayer(theVolumes.front()->magVolume, minR());
140  }
141 
142  // If we have several sectors, create the MagBSector
143  std::vector<MagBSector*> mSectors;
144  for (unsigned int i = 0; i < sectors.size(); ++i) {
145  mSectors.push_back(sectors[i].buildMagBSector());
146  }
147  mlayer = new MagBLayer(mSectors, minR());
148  }
149  return mlayer;
150 }
void printUniqueNames(handles::const_iterator begin, handles::const_iterator end, bool uniq=true)
Just for debugging...
const bool debug
Definition: bLayer.h:54
const double tolerance
std::vector< bSector > sectors
Definition: bLayer.h:50
T zz() const
int bin(int i) const
Definition: bLayer.cc:109
T zx() const
T zy() const
double minR() const
Return sector at i (handling periodicity)
Definition: bLayer.cc:120
#define debug
Definition: HDRShower.cc:19
void precomputed_value_sort(RandomAccessIterator begin, RandomAccessIterator end, const Extractor &extr, const Compare &comp)
handles theVolumes
Definition: bLayer.h:51
const RotationType & rotation() const
MagBLayer * mlayer
Definition: bLayer.h:53
def rotate(angle, cx=0, cy=0)
Definition: svgfig.py:705
Global3DVector GlobalVector
Definition: GlobalVector.h:10
MagBLayer * buildMagBLayer() const
Construct the MagBLayer upon request.
Definition: bLayer.cc:130