CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_14/src/MagneticField/GeomBuilder/src/bLayer.cc

Go to the documentation of this file.
00001 // #include "Utilities/Configuration/interface/Architecture.h"
00002 
00003 /*
00004  *  See header file for a description of this class.
00005  *
00006  *  $Date: 2009/04/07 15:09:45 $
00007  *  $Revision: 1.8 $
00008  *  \author N. Amapane - INFN Torino
00009  */
00010 
00011 #include "MagneticField/GeomBuilder/src/bLayer.h"
00012 #include "MagneticField/VolumeGeometry/interface/MagVolume6Faces.h"
00013 #include "MagneticField/Layers/interface/MagBLayer.h"
00014 #include "MagneticField/Layers/interface/MagVerbosity.h"
00015 
00016 #include "Utilities/General/interface/precomputed_value_sort.h"
00017 
00018 using namespace SurfaceOrientation;
00019 
00020 //The ctor is in charge of finding sectors inside the layer.
00021 MagGeoBuilderFromDDD::bLayer::bLayer(handles::const_iterator begin,
00022                                         handles::const_iterator end) :
00023   size(end-begin),
00024   theVolumes(begin,end),
00025   mlayer(0) 
00026 {
00027   // Sort in phi
00028   precomputed_value_sort(theVolumes.begin(), theVolumes.end(), ExtractPhi());
00029   
00030   if (MagGeoBuilderFromDDD::debug) {
00031     std::cout << " elements: " << theVolumes.size() << " unique volumes: ";
00032     volumeHandle::printUniqueNames(theVolumes.begin(), theVolumes.end());
00033   }
00034   
00035 
00036   // Find sectors in phi
00037   handles::iterator secBegin = theVolumes.begin();
00038   handles::iterator secEnd;
00039   int binOffset = 0;
00040 
00041   const Surface & refSurf = (*secBegin)->surface(outer);
00042 
00043   int newbegin=0;
00044   int newend=0;  
00045 
00046   // A sector is made of several volumes in R, and, for planar layers
00047   // (box and traps) also in phi, so it might cross the -phi boundary. 
00048   // For those, we have to look for the end of first sector and rotate the 
00049   // vector of volumes.
00050   // ASSUMPTION: all volumes in a layer must be of compatible type.
00051 
00052 
00053   if (size==1) { // Only one volume; this is the case for barrel
00054     // cylinders.
00055     // FIXME sectors.push_back(bSector(theVolumes.begin(),theVolumes.end());
00056     if (MagGeoBuilderFromDDD::debug) std::cout <<"      Sector is just one volume." << std::endl;
00057 
00058   } else if (size==12 || // In this case, each volume is a sector.
00059              (((*secBegin)->shape()!=ddtrap) && (*secBegin)->shape()!=ddbox)) {
00060     secEnd = secBegin+size/12;
00061 
00062   }  else { // there are more than one volume per sector.
00063     float tolerance = 0.025; // 250 micron
00064     do {
00065       if (MagGeoBuilderFromDDD::debug) std::cout << (*secBegin)->name 
00066                                  << " " << (*secBegin)->copyno << std::endl;
00067       ++secBegin;
00068     } while ((secBegin != theVolumes.end()) &&
00069              (*secBegin)->sameSurface(refSurf,outer, tolerance)); // This works only if outer surface is a plane, otherwise sameSurface returns always true!
00070     
00071     secEnd = secBegin;
00072     secBegin = theVolumes.begin()+bin((secEnd-theVolumes.begin())-size/12);;
00073     newend   = secEnd-theVolumes.begin();
00074     newbegin = secBegin-theVolumes.begin();
00075     
00076     // Rotate the begin of the first sector to the vector beginning.
00077     rotate(theVolumes.begin(),secBegin,theVolumes.end());
00078     secBegin = theVolumes.begin();
00079     secEnd   = secBegin+size/12;
00080 
00081     // Test it is correct...
00082     if (!((*secBegin)->sameSurface((*(secEnd-1))->surface(outer),
00083                                    outer, tolerance))) {
00084       std::cout << "*** ERROR: Big mess while looking for sectors "
00085                 << (*secBegin)->name << " " << (*secBegin)->copyno << " "
00086                 << (*(secEnd-1))->name << " " << (*(secEnd-1))->copyno
00087                 << std::endl;
00088     }
00089   }
00090 
00091   if (MagGeoBuilderFromDDD::debug) {
00092     std::cout << "      First sector: volumes " << secEnd-theVolumes.begin()
00093          << " from " << newbegin
00094          << " (phi = " << (*secBegin)->center().phi() << ") "
00095          << " to " << newend
00096          << " (phi = " << (*secEnd)->center().phi() << ") "
00097          << " # " << (*secBegin)->copyno << " ";
00098     std::cout << GlobalVector( refSurf.rotation().zx(), refSurf.rotation().zy(),
00099                           refSurf.rotation().zz()) << std::endl;
00100   }
00101 
00102   if (size!=1) { // Build the 12 sectors
00103     int offset = size/12;
00104     sectors.resize(12);
00105     for (int i = 0; i<12; ++i) {
00106       int isec = (i+binOffset)%12;
00107       sectors[isec>=0?isec:isec+12] = bSector(theVolumes.begin()+((i)*offset),
00108                                               theVolumes.begin()+((i+1)*offset));
00109     }
00110   }
00111 
00112   if (MagGeoBuilderFromDDD::debug) std::cout << "-----------------------" << std::endl;
00113 
00114 }
00115 
00116 MagGeoBuilderFromDDD::bLayer::~bLayer(){}
00117 
00118 int MagGeoBuilderFromDDD::bLayer::bin(int i) const {
00119   i = i%size;
00120   return (i>=0?i:i+size);
00121 }
00122 
00123 // const MagGeoBuilderFromDDD::bSector &
00124 // MagGeoBuilderFromDDD::bLayer::sector(int i) const {
00125 //   i = i%12;
00126 //   return sectors[i>=0?i:i+12];
00127 // }
00128 
00129 
00130 double MagGeoBuilderFromDDD::bLayer::minR() const {
00131   // ASSUMPTION: a layer is only 1 volume thick (by construction). 
00132   return theVolumes.front()->minR();
00133 }
00134 
00135 // double MagGeoBuilderFromDDD::bLayer::maxR() const {
00136 //   // ASSUMPTION: a layer is only 1 volume thick (by construction). 
00137 //   return theVolumes.front()->maxR();
00138 // }
00139 
00140 MagBLayer * MagGeoBuilderFromDDD::bLayer::buildMagBLayer() const {
00141   if (mlayer==0) {
00142 
00143     // If we have only one volume, do not build any MagBSector.
00144     if (sectors.size()==0) {
00145       if (MagGeoBuilderFromDDD::debug && size!=0) {
00146         std::cout << "ERROR: bLayer::buildMagBLayer, 0 sectors but "
00147              << size << " volumes" << std::endl;
00148       }
00149       // Technically we might have only one bSector built and we would
00150       // not need a separate MagBLayer constructor...
00151       mlayer = new MagBLayer(theVolumes.front()->magVolume, minR());
00152     }
00153 
00154     // If we have several sectors, create the MagBSector
00155     std::vector<MagBSector*> mSectors;
00156     for (unsigned int i=0; i<sectors.size(); ++i) {
00157       mSectors.push_back(sectors[i].buildMagBSector());
00158     }
00159     mlayer = new MagBLayer(mSectors, minR());
00160   }
00161   return mlayer;
00162 }
00163