CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_2_7_hltpatch1/src/MagneticField/GeomBuilder/src/MagGeoBuilderFromDDD.cc

Go to the documentation of this file.
00001 /*
00002  *  See header file for a description of this class.
00003  *
00004  *  $Date: 2011/10/13 16:31:37 $
00005  *  $Revision: 1.31 $
00006  *  \author N. Amapane - INFN Torino
00007  */
00008 
00009 #include "MagneticField/GeomBuilder/src/MagGeoBuilderFromDDD.h"
00010 #include "MagneticField/GeomBuilder/src/volumeHandle.h"
00011 #include "MagneticField/GeomBuilder/src/bSlab.h"
00012 #include "MagneticField/GeomBuilder/src/bRod.h"
00013 #include "MagneticField/GeomBuilder/src/bSector.h"
00014 #include "MagneticField/GeomBuilder/src/bLayer.h"
00015 #include "MagneticField/GeomBuilder/src/eSector.h"
00016 #include "MagneticField/GeomBuilder/src/eLayer.h"
00017 #include "MagneticField/GeomBuilder/src/FakeInterpolator.h"
00018 
00019 #include "MagneticField/Layers/interface/MagBLayer.h"
00020 #include "MagneticField/Layers/interface/MagESector.h"
00021 
00022 #include "FWCore/ParameterSet/interface/FileInPath.h"
00023 
00024 #include "DetectorDescription/Core/interface/DDCompactView.h"
00025 #include "DetectorDescription/Core/interface/DDFilteredView.h"
00026 #include "DetectorDescription/Core/interface/DDFilter.h"
00027 
00028 #include "Utilities/BinningTools/interface/ClusterizingHistogram.h"
00029 #include "CLHEP/Units/GlobalSystemOfUnits.h"
00030 
00031 #include "MagneticField/Interpolation/interface/MagProviderInterpol.h"
00032 #include "MagneticField/Interpolation/interface/MFGridFactory.h"
00033 #include "MagneticField/Interpolation/interface/MFGrid.h"
00034 
00035 #include "MagneticField/VolumeGeometry/interface/MagVolume6Faces.h"
00036 #include "MagneticField/VolumeGeometry/interface/MagExceptions.h"
00037 #include "MagneticField/Layers/interface/MagVerbosity.h"
00038 
00039 #include "DataFormats/GeometryVector/interface/Pi.h"
00040 
00041 #include "FWCore/Utilities/interface/Exception.h"
00042 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00043 
00044 #include <string>
00045 #include <vector>
00046 #include <iostream>
00047 #include <sstream>
00048 #include <algorithm>
00049 #include <iterator>
00050 #include <map>
00051 #include <set>
00052 #include <iomanip>
00053 #include "Utilities/General/interface/precomputed_value_sort.h"
00054 
00055 
00056 bool MagGeoBuilderFromDDD::debug;
00057 
00058 using namespace std;
00059 
00060 MagGeoBuilderFromDDD::MagGeoBuilderFromDDD(string tableSet_, bool debug_, bool overrideMasterSector_) :
00061   tableSet (tableSet_),
00062   geometryVersion(0),
00063   overrideMasterSector(overrideMasterSector_)
00064 {  
00065   debug = debug_;
00066   if (debug) cout << "Constructing a MagGeoBuilderFromDDD" <<endl;
00067 }
00068 
00069 MagGeoBuilderFromDDD::~MagGeoBuilderFromDDD(){
00070   for (handles::const_iterator i=bVolumes.begin();
00071        i!=bVolumes.end(); ++i){
00072     delete (*i);
00073   }
00074   
00075   for (handles::const_iterator i=eVolumes.begin();
00076        i!=eVolumes.end(); ++i){
00077     delete (*i);
00078   }
00079 }
00080 
00081 
00082 void MagGeoBuilderFromDDD::summary(handles & volumes){  
00083   // The final countdown.
00084   int ivolumes  = volumes.size();  // number of volumes
00085   int isurfaces = ivolumes*6;       // number of individual surfaces
00086   int iassigned = 0;                // How many have been assigned
00087   int iunique   = 0;                // number of unique surfaces
00088   int iref_ass  = 0;
00089   int iref_nass = 0;
00090 
00091   set<const void *> ptrs;
00092 
00093   handles::const_iterator first = volumes.begin();
00094   handles::const_iterator last = volumes.end();
00095 
00096   for (handles::const_iterator i=first; i!=last; ++i){
00097     if (int((*i)->shape())>4) continue; // FIXME: implement test for missing shapes...
00098     for (int side = 0; side < 6; ++side) {
00099       int references =  (*i)->references(side);
00100       if ((*i)->isPlaneMatched(side)) {
00101         ++iassigned;
00102         bool firstOcc = (ptrs.insert(&((*i)->surface(side)))).second;
00103         if (firstOcc) iref_ass+=references;
00104         if (references<2){  
00105           cout << "*** Only 1 ref, vol: " << (*i)->name << " # "
00106                << (*i)->copyno << " side: " << side << endl;
00107         }       
00108       } else {
00109         iref_nass+=references;
00110         if (references>1){
00111           cout << "*** Ref_nass >1 " <<endl;
00112         }
00113       }
00114     }
00115   }
00116   iunique = ptrs.size();
00117 
00118   cout << "    volumes   " << ivolumes  << endl
00119        << "    surfaces  " << isurfaces << endl
00120        << "    assigned  " << iassigned << endl
00121        << "    unique    " << iunique << endl
00122        << "    iref_ass  " << iref_ass << endl
00123        << "    iref_nass " << iref_nass << endl;
00124 }
00125 
00126 
00127 void MagGeoBuilderFromDDD::build(const DDCompactView & cpva)
00128 {
00129 //    DDCompactView cpv;
00130   DDExpandedView fv(cpva);
00131 
00132   if (debug) cout << "**********************************************************" <<endl;
00133 
00134   // The actual field interpolators
00135   map<string, MagProviderInterpol*> bInterpolators;
00136   map<string, MagProviderInterpol*> eInterpolators;
00137   
00138   // Counter of different volumes
00139   int bVolCount = 0;
00140   int eVolCount = 0;
00141 
00142   if (fv.logicalPart().name().name()!="MAGF") {
00143      std::string topNodeName(fv.logicalPart().name().name());
00144 
00145      //see if one of the children is MAGF
00146      bool doSubDets = fv.firstChild();
00147      
00148      bool go=true;
00149      while(go&& doSubDets) {
00150         if (fv.logicalPart().name().name()=="MAGF")
00151            break;
00152         else
00153            go = fv.nextSibling();
00154      }
00155      if (!go) {
00156         throw cms::Exception("NoMAGFinDDD")<<" Neither the top node, nor any child node of the DDCompactView is \"MAGF\" but the top node is instead \""<<topNodeName<<"\"";
00157      }
00158   }
00159   // Loop over MAGF volumes and create volumeHandles. 
00160   if (debug) { cout << endl << "*** MAGF: " << fv.geoHistory() << endl
00161                     << "translation: " << fv.translation() << endl
00162                     << " rotation: " << fv.rotation() << endl;
00163   }
00164   
00165   bool doSubDets = fv.firstChild();
00166   while (doSubDets){
00167     
00168     string name = fv.logicalPart().name().name();
00169     if (debug) cout << endl << "Name: " << name << endl
00170                                << "      " << fv.geoHistory() <<endl;
00171     
00172     // FIXME: single-volyme cylinders - this is feature has been removed 
00173     //        and should be revisited.
00174     //    bool mergeCylinders=false;
00175 
00176     // If true, In the barrel, cylinders sectors will be skipped to build full 
00177     // cylinders out of sector copyno #1.
00178     bool expand = false;
00179 
00180 //     if (mergeCylinders) {
00181 //       if (name == "V_ZN_1"
00182 //        || name == "V_ZN_2") {
00183 //      if (debug && fv.logicalPart().solid().shape()!=ddtubs) {
00184 //        cout << "ERROR: MagGeoBuilderFromDDD::build: volume " << name
00185 //             << " should be a cylinder" << endl;
00186 //      }
00187 //      if(fv.copyno()==1) {
00188 //        expand = true;
00189 //      } else {
00190 //        //cout << "... to be skipped: "
00191 //        //     << name << " " << fv.copyno() << endl;
00192 //      }
00193 //       }
00194 //     }
00195 
00196     volumeHandle* v = new volumeHandle(fv, expand);
00197     //FIXME: overrideMasterSector is a hack to allow switching between 
00198     // phi-symmetric maps and maps with sector-specific tables. 
00199     // It won't be necessary anymore once the geometry is decoupled from 
00200     // the specification of tables, ie when tables will come from the DB.
00201     if (overrideMasterSector && v->masterSector!=1) {
00202       v->masterSector=1;
00203       std::string::size_type ibeg, iend;
00204       ibeg = (v->magFile).rfind('/');
00205       iend = (v->magFile).size();
00206       v->magFile = (v->magFile).substr(ibeg+1,iend-ibeg-1);
00207     }
00208 
00209     // Select volumes, build volume handles.
00210     float Z = v->center().z();
00211     float R = v->center().perp();
00212 
00213     // v 85l: Barrel is everything up to |Z| = 661.0, excluding 
00214     // volume #7, centered at 6477.5
00215     // v 1103l: same numbers work fine. #16 instead of #7, same coords;
00216     // see comment below for V6,7
00217     //ASSUMPTION: no misalignment is applied to mag volumes.
00218     //FIXME: implement barrel/endcap flags as DDD SpecPars.
00219     if ((fabs(Z)<647. || (R>350. && fabs(Z)<662.)) &&
00220         !(fabs(Z)>480 && R<172) // in 1103l we place V_6 and V_7 in the 
00221                                 // endcaps to preserve nice layer structure
00222                                 // in the barrel. This does not hurt in v85l
00223                                 // where there is a single V1 
00224         ) { // Barrel
00225       if (debug) cout << " (Barrel)" <<endl;
00226       bVolumes.push_back(v);
00227 
00228 
00229       // Build the interpolator of the "master" volume (the one which is
00230       // not replicated in phi)
00231       // ASSUMPTION: copyno == sector. 
00232       //             Note this is not the case for obsolete grid_85l_030919 - 
00233       // In case in  future models this should no more be the case, can 
00234       // implement secotor numbers as SpecPars in the XML      
00235       if (v->copyno==v->masterSector) {
00236         buildInterpolator(v, bInterpolators);
00237         ++bVolCount;
00238       }
00239     } else {               // Endcaps
00240       if (debug) cout << " (Endcaps)" <<endl;
00241       eVolumes.push_back(v);
00242       if (v->copyno==v->masterSector) { 
00243         buildInterpolator(v, eInterpolators);
00244         ++eVolCount;
00245       }
00246     }
00247 
00248     doSubDets = fv.nextSibling(); // end of loop over MAGF
00249   }
00250     
00251   if (debug) {
00252     cout << "Number of volumes (barrel): " << bVolumes.size() <<endl
00253                   << "Number of volumes (endcap): " << eVolumes.size() <<endl;
00254     cout << "**********************************************************" <<endl;
00255   }
00256 
00257   // Now all volumeHandles are there, and parameters for each of the planes
00258   // are calculated.
00259 
00260   //----------------------------------------------------------------------
00261   // Print summary information
00262 
00263   if (debug) {
00264     cout << "-----------------------" << endl;
00265     cout << "SUMMARY: Barrel " << endl;
00266     summary(bVolumes);
00267     
00268     cout << endl << "SUMMARY: Endcaps " << endl;
00269     summary(eVolumes);
00270     cout << "-----------------------" << endl;
00271   }
00272 
00273 
00274   //----------------------------------------------------------------------
00275   // Find barrel layers.
00276 
00277   vector<bLayer> layers; // the barrel layers
00278   precomputed_value_sort(bVolumes.begin(), bVolumes.end(), ExtractRN());
00279 
00280   // Find the layers (in R)
00281   const float resolution = 1.; // cm
00282   float rmin = bVolumes.front()->RN()-resolution;
00283   float rmax = bVolumes.back()->RN()+resolution;
00284   ClusterizingHistogram  hisR( int((rmax-rmin)/resolution) + 1, rmin, rmax);
00285 
00286   if (debug) cout << " R layers: " << rmin << " " << rmax << endl;
00287 
00288   handles::const_iterator first = bVolumes.begin();
00289   handles::const_iterator last = bVolumes.end();  
00290 
00291   for (handles::const_iterator i=first; i!=last; ++i){
00292     hisR.fill((*i)->RN());
00293   }
00294   vector<float> rClust = hisR.clusterize(resolution);
00295 
00296   handles::const_iterator ringStart = first;
00297   handles::const_iterator separ = first;
00298 
00299   for (unsigned int i=0; i<rClust.size() - 1; ++i) {
00300     if (debug) cout << " Layer at RN = " << rClust[i];
00301     float rSepar = (rClust[i] + rClust[i+1])/2.f;
00302     while ((*separ)->RN() < rSepar) ++separ;
00303 
00304     bLayer thislayer(ringStart, separ);
00305     layers.push_back(thislayer);
00306     ringStart = separ;
00307   }
00308   {
00309     if (debug) cout << " Layer at RN = " << rClust.back();
00310     bLayer thislayer(separ, last);
00311     layers.push_back(thislayer);
00312   }
00313 
00314   if (debug) cout << "Barrel: Found " << rClust.size() << " clusters in R, "
00315                   << layers.size() << " layers " << endl << endl;
00316 
00317 
00318   //----------------------------------------------------------------------
00319   // Find endcap sectors
00320   vector<eSector> sectors; // the endcap sectors
00321 
00322   // Find the number of sectors (should be 12 or 24 depending on the geometry model)
00323   float phireso = 0.05; // rad
00324   ClusterizingHistogram hisPhi( int((Geom::ftwoPi())/phireso) + 1,
00325                                 -Geom::fpi(), Geom::fpi());
00326   
00327   for (handles::const_iterator i=eVolumes.begin(); i!=eVolumes.end(); ++i){
00328     hisPhi.fill((*i)->minPhi());
00329   }
00330   vector<float> phiClust = hisPhi.clusterize(phireso);
00331   int nESectors = phiClust.size();
00332   if (debug && (nESectors%12)!=0) cout << "ERROR: unexpected # of sectors: " << nESectors << endl;
00333 
00334   //Sort in phi
00335   precomputed_value_sort(eVolumes.begin(), eVolumes.end(), ExtractPhi());
00336 
00337   //Group volumes in sectors
00338   for (int i = 0; i<nESectors; ++i) {
00339     int offset = eVolumes.size()/nESectors;
00340     if (debug) cout << " Sector at phi = "
00341                     << (*(eVolumes.begin()+((i)*offset)))->center().phi()
00342                     << endl;
00343     sectors.push_back(eSector(eVolumes.begin()+((i)*offset),
00344                               eVolumes.begin()+((i+1)*offset)));
00345   }
00346    
00347   if (debug) cout << "Endcap: Found " 
00348                   << sectors.size() << " sectors " << endl;
00349 
00350 
00351   //----------------------------------------------------------------------  
00352   // Match surfaces.
00353 
00354 //  cout << "------------------" << endl << "Now associating planes..." << endl;
00355 
00356 //   // Loop on layers
00357 //   for (vector<bLayer>::const_iterator ilay = layers.begin();
00358 //        ilay!= layers.end(); ++ilay) {
00359 //     cout << "On Layer: " << ilay-layers.begin() << " RN: " << (*ilay).RN()
00360 //       <<endl;     
00361 
00362 //     // Loop on wheels
00363 //     for (vector<bWheel>::const_iterator iwheel = (*ilay).wheels.begin();
00364 //       iwheel != (*ilay).wheels.end(); ++iwheel) {
00365 //       cout << "  On Wheel: " << iwheel- (*ilay).wheels.begin()<< " Z: "
00366 //         << (*iwheel).minZ() << " " << (*iwheel).maxZ() << " " 
00367 //         << ((*iwheel).minZ()+(*iwheel).maxZ())/2. <<endl;
00368 
00369 //       // Loop on sectors.
00370 //       for (int isector = 0; isector<12; ++isector) {
00371 //      // FIXME: create new constructor...
00372 //      bSectorNavigator navy(layers,
00373 //                            ilay-layers.begin(),
00374 //                            iwheel-(*ilay).wheels.begin(),isector);
00375         
00376 //      const bSector & isect = (*iwheel).sector(isector);
00377         
00378 //      isect.matchPlanes(navy); //FIXME refcount
00379 //       }
00380 //     }
00381 //   }
00382 
00383 
00384   //----------------------------------------------------------------------
00385   // Build MagVolumes and the MagGeometry hierarchy.
00386 
00387   //--- Barrel
00388 
00389   // Build MagVolumes and associate interpolators to them
00390   buildMagVolumes(bVolumes, bInterpolators);
00391 
00392   // Build MagBLayers
00393   for (vector<bLayer>::const_iterator ilay = layers.begin();
00394        ilay!= layers.end(); ++ilay) {
00395     mBLayers.push_back((*ilay).buildMagBLayer());
00396   }
00397 
00398   if (debug) {  
00399     cout << "*** BARREL ********************************************" << endl
00400          << "Number of different volumes   = " << bVolCount << endl
00401          << "Number of interpolators built = " << bInterpolators.size() << endl
00402          << "Number of MagBLayers built    = " << mBLayers.size() << endl;
00403 
00404     testInside(bVolumes); // FIXME: all volumes should be checked in one go.
00405   }
00406   
00407   //--- Endcap
00408   // Build MagVolumes  and associate interpolators to them
00409   buildMagVolumes(eVolumes, eInterpolators);
00410 
00411   // Build the MagESectors
00412   for (vector<eSector>::const_iterator isec = sectors.begin();
00413        isec!= sectors.end(); ++isec) {
00414     mESectors.push_back((*isec).buildMagESector());
00415   }
00416 
00417   if (debug) {
00418     cout << "*** ENDCAP ********************************************" << endl
00419          << "Number of different volumes   = " << eVolCount << endl
00420          << "Number of interpolators built = " << eInterpolators.size() << endl
00421          << "Number of MagESector built    = " << mESectors.size() << endl;
00422 
00423     testInside(eVolumes); // FIXME: all volumes should be checked in one go.
00424   }
00425 }
00426 
00427 
00428 void MagGeoBuilderFromDDD::buildMagVolumes(const handles & volumes, map<string, MagProviderInterpol*> & interpolators) {
00429   // Build all MagVolumes setting the MagProviderInterpol
00430   for (handles::const_iterator vol=volumes.begin(); vol!=volumes.end();
00431        ++vol){
00432     const MagProviderInterpol* mp = 0;
00433     if (interpolators.find((*vol)->magFile)!=interpolators.end()) {
00434       mp = interpolators[(*vol)->magFile];
00435     } else {
00436       cout << "No interpolator found for file " << (*vol)->magFile
00437            << " vol: " << (*vol)->name << endl;
00438       cout << interpolators.size() <<endl;
00439     }
00440       
00441 
00442     // Get the volume number from the volume name.
00443     // ASSUMPTION: volume names ends with "_NUM" where NUM is the volume number
00444     int volNum;
00445     string name = (*vol)->name;
00446     name.erase(0,name.rfind('_')+1);
00447     stringstream str;    
00448     str << name;
00449     str >> volNum;
00450 
00451 
00452     // ASSUMPTION: copyno == sector. 
00453     //             Note this is not the case for obsolete grid_85l_030919 - 
00454     // In case in  future models this should no more be the case, can 
00455     // implement secotor numbers as SpecPars in the XML
00456     int key = volNum*100+(*vol)->copyno; 
00457     map<int, double>::const_iterator isf = theScalingFactors.find(key);
00458     if (isf == theScalingFactors.end()) {
00459       key = volNum*100;
00460       isf = theScalingFactors.find(key);
00461     }
00462     
00463     double sf = 1.;
00464     if (isf != theScalingFactors.end()) {
00465       sf = (*isf).second;
00466 
00467       edm::LogInfo("MagneticField|VolumeBasedMagneticFieldESProducer") << "Applying scaling factor " << sf << " to "<< (*vol)->name << "["<< (*vol)->copyno << "] (key:" << key << ")" << endl;
00468     }
00469 
00470     const GloballyPositioned<float> * gpos = (*vol)->placement();
00471     (*vol)->magVolume = new MagVolume6Faces(gpos->position(),
00472                                             gpos->rotation(),
00473                                             (*vol)->shape(),
00474                                             (*vol)->sides(),
00475                                             mp, sf);
00476 
00477     if ((*vol)->copyno==(*vol)->masterSector) {
00478       (*vol)->magVolume->ownsFieldProvider(true);
00479     }
00480 
00481     (*vol)->magVolume->setIsIron((*vol)->isIron());
00482 
00483     // The name and sector of the volume are saved for debug purposes only. They may be removed at some point...
00484     (*vol)->magVolume->name = (*vol)->name;
00485     (*vol)->magVolume->copyno = (*vol)->copyno;
00486   }
00487 }
00488 
00489 
00490 void MagGeoBuilderFromDDD::buildInterpolator(const volumeHandle * vol, map<string, MagProviderInterpol*> & interpolators){
00491 
00492   // Phi of the master sector
00493   double masterSectorPhi = (vol->masterSector-1)*Geom::pi()/6.;
00494 
00495   if (debug) {
00496     cout << "Building interpolator from "
00497          << vol->name << " copyno " << vol->copyno
00498          << " at " << vol->center()
00499          << " phi: " << vol->center().phi()
00500          << " file: " << vol->magFile
00501          << endl;
00502 
00503     if ( fabs(vol->center().phi() - masterSectorPhi) > Geom::pi()/9.) {
00504       cout << "***WARNING wrong sector? " << endl;
00505     }
00506   }
00507 
00508   if (tableSet == "fake") {
00509     interpolators[vol->magFile] = new magneticfield::FakeInterpolator();
00510     return;
00511   }
00512 
00513   string fullPath;
00514 
00515   try {
00516     edm::FileInPath mydata("MagneticField/Interpolation/data/"+tableSet+"/"+vol->magFile);
00517     fullPath = mydata.fullPath();
00518   } catch (edm::Exception& exc) {
00519     cerr << "MagGeoBuilderFromDDD: exception in reading table; " << exc.what() << endl;
00520     if (!debug) throw;
00521     return;
00522   }
00523   
00524   
00525   try{
00526     if (vol->toExpand()){
00527       //FIXME: see discussion on mergeCylinders above.
00528 //       interpolators[vol->magFile] =
00529 //      MFGridFactory::build( fullPath, *(vol->placement()), vol->minPhi(), vol->maxPhi());
00530     } else {
00531       // If the table is in "local" coordinates, must create a reference 
00532       // frame that is appropriately rotated along the CMS Z axis.
00533 
00534       GloballyPositioned<float> rf = *(vol->placement());
00535 
00536       if (vol->masterSector != 1) {
00537         typedef Basic3DVector<float> Vector;
00538 
00539         GloballyPositioned<float>::RotationType rot(Vector(0,0,1), -masterSectorPhi);
00540         Vector vpos(vol->placement()->position());
00541         
00542 
00543         rf = GloballyPositioned<float>(GloballyPositioned<float>::PositionType(rot.multiplyInverse(vpos)), vol->placement()->rotation()*rot);
00544       }
00545 
00546       interpolators[vol->magFile] =
00547         MFGridFactory::build( fullPath, rf);
00548     }
00549   } catch (MagException& exc) {
00550     cout << exc.what() << endl;
00551     interpolators.erase(vol->magFile);
00552     if (!debug) throw; 
00553     return;
00554   }
00555 
00556 
00557     if (debug) {
00558     // Check that all grid points of the interpolator are inside the volume.
00559       const MagVolume6Faces tempVolume(vol->placement()->position(),
00560                                  vol->placement()->rotation(),
00561                                  vol->shape(),
00562                                  vol->sides(), 
00563                                  interpolators[vol->magFile]);
00564 
00565       const MFGrid* grid = dynamic_cast<const MFGrid*>(interpolators[vol->magFile]);
00566       if (grid!=0) {
00567         
00568         Dimensions sizes = grid->dimensions();
00569         cout << "Grid has 3 dimensions " 
00570              << " number of nodes is " << sizes.w << " " << sizes.h
00571              << " " << sizes.d << endl;
00572       
00573         const double tolerance = 0.03;
00574 
00575 
00576         size_t dumpCount = 0;
00577         for (int j=0; j < sizes.h; j++) {
00578           for (int k=0; k < sizes.d; k++) {
00579             for (int i=0; i < sizes.w; i++) {
00580               MFGrid::LocalPoint lp = grid->nodePosition( i, j, k);
00581               if (! tempVolume.inside(lp, tolerance)) {
00582                 if (++dumpCount < 2) {
00583                   MFGrid::GlobalPoint gp = tempVolume.toGlobal(lp);
00584                   cout << "GRID ERROR: " << i << " " << j << " " << k
00585                        << " local: " << lp
00586                        << " global: " << gp
00587                        << " R= " << gp.perp() << " phi=" << gp.phi() << endl;
00588                 }
00589               }
00590             }
00591           }
00592         }
00593     
00594         cout << vol->name << " : Number of grid points outside the MagVolume: " << dumpCount << "/" << sizes.w*sizes.h*sizes.d << endl;
00595       }
00596     }
00597 }
00598 
00599 
00600 
00601 void MagGeoBuilderFromDDD::testInside(handles & volumes) {
00602   // test inside() for all volumes.
00603   cout << "--------------------------------------------------" << endl;
00604   cout << " inside(center) test" << endl;
00605   for (handles::const_iterator vol=volumes.begin(); vol!=volumes.end();
00606        ++vol){
00607     for (handles::const_iterator i=volumes.begin(); i!=volumes.end();
00608          ++i){
00609       if ((*i)==(*vol)) continue;
00610       //if ((*i)->magVolume == 0) continue;
00611       if ((*i)->magVolume->inside((*vol)->center())) {
00612         cout << "*** ERROR: center of " << (*vol)->name << " is inside " 
00613              << (*i)->name <<endl;
00614       }
00615     }
00616     
00617     if ((*vol)->magVolume->inside((*vol)->center())) {
00618       cout << (*vol)->name << " OK " << endl;
00619     } else {
00620       cout << "*** ERROR: center of volume is not inside it, "
00621            << (*vol)->name << endl;
00622     }
00623   }
00624   cout << "--------------------------------------------------" << endl;
00625 }
00626 
00627 
00628 vector<MagBLayer*> MagGeoBuilderFromDDD::barrelLayers() const{
00629   return mBLayers;
00630 }
00631 
00632 vector<MagESector*> MagGeoBuilderFromDDD::endcapSectors() const{
00633   return mESectors;
00634 }
00635 
00636 vector<MagVolume6Faces*> MagGeoBuilderFromDDD::barrelVolumes() const{
00637   vector<MagVolume6Faces*> v;
00638   v.reserve(bVolumes.size());
00639   for (handles::const_iterator i=bVolumes.begin();
00640        i!=bVolumes.end(); ++i){
00641     v.push_back((*i)->magVolume);
00642   }
00643   return v;
00644 }
00645 
00646 vector<MagVolume6Faces*> MagGeoBuilderFromDDD::endcapVolumes() const{
00647   vector<MagVolume6Faces*> v;
00648   v.reserve(eVolumes.size());
00649   for (handles::const_iterator i=eVolumes.begin();
00650        i!=eVolumes.end(); ++i){
00651     v.push_back((*i)->magVolume);
00652   }
00653   return v;
00654 }
00655 
00656 
00657 float MagGeoBuilderFromDDD::maxR() const{
00658   //FIXME: should get it from the actual geometry - MAGF is an option, 
00659   //       but that is not changed together the geometry itself 
00660   //       (it lives in cmsMagneticField.xml in CMSCommonData)
00661   return 900.;
00662 }
00663 
00664 float MagGeoBuilderFromDDD::maxZ() const{
00665   //FIXME: should get it from the actual geometry - see above
00666   return 1600.;
00667 }
00668 
00669 
00670 void MagGeoBuilderFromDDD::setScaling(std::vector<int> keys, 
00671                                       std::vector<double> values)
00672 {
00673   if (keys.size() != values.size()) {
00674     throw cms::Exception("InvalidParameter") << "Invalid field scaling parameters 'scalingVolumes' and 'scalingFactors' ";
00675   }
00676   for (unsigned int i=0; i<keys.size(); ++i) {
00677     theScalingFactors[keys[i]] = values[i];
00678   }
00679 }
00680 
00681 
00682