00001
00002
00003
00004
00005
00006
00007
00008
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
00025 MagGeoBuilderFromDDD::bSector::bSector(){}
00026
00027 MagGeoBuilderFromDDD::bSector::~bSector(){}
00028
00029
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
00047
00048
00049
00050
00051
00052
00053
00054 precomputed_value_sort(volumes.begin(), volumes.end(),
00055 ExtractPhiMax(), LessDPhi());
00056
00057 const Geom::Phi<float> resolution(0.01);
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
00102
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 ) {
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) {
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());
00144 }
00145 return msector;
00146 }