CMS 3D CMS Logo

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