CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/MagneticField/GeomBuilder/src/bSector.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: 2007/03/09 14:38:23 $
00007  *  $Revision: 1.5 $
00008  *  \author N. Amapane - INFN Torino
00009  */
00010 
00011 #include "MagneticField/GeomBuilder/src/bSector.h"
00012 #include "Utilities/BinningTools/interface/ClusterizingHistogram.h"
00013 #include "MagneticField/Layers/interface/MagBSector.h"
00014 #include "MagneticField/Layers/interface/MagVerbosity.h"
00015 
00016 #include "Utilities/General/interface/precomputed_value_sort.h"
00017 
00018 #include <algorithm>
00019 
00020 using namespace SurfaceOrientation;
00021 using namespace std;
00022 
00023 
00024 // Default ctor needed to have arrays.
00025 MagGeoBuilderFromDDD::bSector::bSector(){}
00026 
00027 MagGeoBuilderFromDDD::bSector::~bSector(){}
00028 
00029 // The ctor is in charge of finding rods inside the sector.
00030 MagGeoBuilderFromDDD::bSector::bSector(handles::const_iterator begin,
00031                                         handles::const_iterator end) :
00032   volumes(begin,end),
00033   msector(0)
00034 {
00035   if (MagGeoBuilderFromDDD::debug) cout << "   Sector at Phi  " <<  volumes.front()->center().phi() << " " 
00036                   << volumes.back()->center().phi() <<  endl;
00037 
00038   if (volumes.size() == 1) {
00039     if (MagGeoBuilderFromDDD::debug) { 
00040       cout << "   Rod at: 0 elements: " << end-begin
00041            << " unique volumes: ";
00042       volumeHandle::printUniqueNames(begin,end);
00043     }
00044     rods.push_back(bRod(begin,end));
00045   } else {
00046     // Clusterize in phi. Use bin edge so that complete clusters can be 
00047     // easily found (not trivial using bin centers!)
00048     // Unfortunately this makes the result more sensitive to the 
00049     // "resolution" parameter...
00050     // To avoid +-pi boundary problems, take phi distance from min phi.
00051     // Caveat of implicit conversions of Geom::Phi!!!
00052 
00053     // Sort volumes in DELTA phi - i.e. phi(j)-phi(i) > 0 if j>1.
00054     precomputed_value_sort(volumes.begin(), volumes.end(),
00055                            ExtractPhiMax(), LessDPhi());
00056 
00057     const Geom::Phi<float> resolution(0.01); // rad
00058     Geom::Phi<float> phi0 = volumes.front()->maxPhi();
00059     float phiMin = -(float) resolution;
00060     float phiMax = volumes.back()->maxPhi() - phi0 + resolution; 
00061 
00062     ClusterizingHistogram hisPhi( int((phiMax-phiMin)/resolution) + 1,
00063                                   phiMin, phiMax);
00064     
00065     handles::const_iterator first = volumes.begin();
00066     handles::const_iterator last = volumes.end();  
00067 
00068     for (handles::const_iterator i=first; i!=last; ++i){
00069       hisPhi.fill((*i)->maxPhi()-phi0);
00070     }
00071     vector<float> phiClust = hisPhi.clusterize(resolution);
00072 
00073     if (MagGeoBuilderFromDDD::debug) cout << "     Found " << phiClust.size() << " clusters in Phi, "
00074                     << " rods: " << endl;
00075 
00076     handles::const_iterator rodStart = first;
00077     handles::const_iterator separ = first;
00078     
00079     float DZ = (*max_element(first,last,LessZ()))->maxZ() -
00080       (*min_element(first,last,LessZ()))->minZ();    
00081 
00082     float DZ1 = 0.;
00083     for (unsigned int i=0; i<phiClust.size(); ++i) {
00084       float phiSepar;
00085       if (i<phiClust.size()-1) {
00086         phiSepar = (phiClust[i] + phiClust[i+1])/2.f;
00087       } else {
00088         phiSepar = phiMax;
00089       }
00090       if (MagGeoBuilderFromDDD::debug) cout << "       cluster " << i
00091                       << " phisepar " << phiSepar <<endl;
00092       while (separ < last && (*separ)->maxPhi()-phi0 < phiSepar ) {
00093         DZ1 += ((*separ)->maxZ() - (*separ)->minZ());
00094         if (MagGeoBuilderFromDDD::debug) cout << "         " << (*separ)->name << " "
00095                         << (*separ)->maxPhi()-phi0  << " "
00096                         << (*separ)->maxZ() << " " << (*separ)->minZ() << " "
00097                         << DZ1 << endl;
00098         ++separ;
00099       }
00100 
00101       // FIXME: print warning for small discrepancies. Tolerance (below)
00102       // had to be increased since discrepancies sum to up to ~ 2 mm.
00103       if (fabs(DZ-DZ1) > 0.001 && fabs(DZ-DZ1) < 0.5) {
00104         if (MagGeoBuilderFromDDD::debug) cout << "*** WARNING: Z lenght mismatch by " << DZ-DZ1
00105                         << " " << DZ << " " << DZ1 << endl;
00106 
00107       }
00108       if (fabs(DZ-DZ1) > 0.25 ) { // FIXME hardcoded tolerance
00109         if (MagGeoBuilderFromDDD::debug) cout << "       Incomplete, use also next cluster: " 
00110                         << DZ << " " << DZ1 << " " << DZ-DZ1 << endl;
00111         DZ1 = 0.;
00112         continue;
00113       } else if (DZ1>DZ+0.05) { // Wrong: went past max lenght // FIXME hardcoded tolerance
00114         cout << " *** ERROR: bSector finding messed up." << endl;
00115         volumeHandle::printUniqueNames(rodStart, separ);
00116         DZ1 = 0.;
00117       } else {
00118         if (MagGeoBuilderFromDDD::debug) {
00119           cout << "       Rod at: " << phiClust[i] <<" elements: "
00120                << separ-rodStart << " unique volumes: ";
00121           volumeHandle::printUniqueNames(rodStart, separ);
00122         }
00123         
00124         rods.push_back(bRod(rodStart, separ));
00125         rodStart = separ;
00126         DZ1 = 0.;
00127       }
00128     }
00129 
00130     if (MagGeoBuilderFromDDD::debug) cout << "-----------------------" << endl;
00131 
00132   }
00133 }
00134 
00135 
00136 MagBSector* MagGeoBuilderFromDDD::bSector::buildMagBSector() const{
00137   if (msector==0) {
00138     vector<MagBRod*> mRods;
00139     for (vector<bRod>::const_iterator rod = rods.begin();
00140          rod!=rods.end(); ++rod) {
00141       mRods.push_back((*rod).buildMagBRod());
00142     }
00143     msector = new MagBSector(mRods, volumes.front()->minPhi()); //FIXME
00144   }
00145   return msector;
00146 }