CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/MagneticField/Interpolation/src/SpecialCylindricalMFGrid.cc

Go to the documentation of this file.
00001 #include "SpecialCylindricalMFGrid.h"
00002 #include "binary_ifstream.h"
00003 #include "LinearGridInterpolator3D.h"
00004 
00005 
00006 #include <iostream>
00007 
00008 using namespace std;
00009 
00010 SpecialCylindricalMFGrid::SpecialCylindricalMFGrid( binary_ifstream& inFile, 
00011                                                     const GloballyPositioned<float>& vol, int gridType)
00012   : MFGrid3D(vol)
00013 {
00014   if (gridType == 5 ) {
00015     sector1 = false;
00016   } else if (gridType == 6 ) {
00017     sector1 = true;
00018   } else {
00019     cout << "ERROR wrong SpecialCylindricalMFGrid type " << gridType << endl;
00020     sector1 = false;
00021   }
00022 
00023   int n1, n2, n3;
00024   inFile >> n1 >> n2 >> n3;
00025 #ifdef DEBUG_GRID
00026   cout << "n1 " << n1 << " n2 " << n2 << " n3 " << n3 << endl;
00027 #endif
00028   double xref, yref, zref;
00029   inFile >> xref >> yref >> zref;
00030   double stepx, stepy, stepz;
00031   inFile >> stepx    >> stepy    >> stepz;
00032 
00033   double RParAsFunOfPhi[4];  // R = f(phi) or const. (0,2: const. par. ; 1,3: const./sin(phi));
00034   inFile >> RParAsFunOfPhi[0] >> RParAsFunOfPhi[1] >> RParAsFunOfPhi[2] >> RParAsFunOfPhi[3];
00035 
00036   vector<BVector> fieldValues;
00037   float Bx, By, Bz;
00038   int nLines = n1*n2*n3;
00039   fieldValues.reserve(nLines);
00040   for (int iLine=0; iLine<nLines; ++iLine){
00041     inFile >> Bx >> By >> Bz;
00042     // This would be fine only if local r.f. has the axes oriented as the global r.f.
00043     // For this volume we know that the local and global r.f. have different axis
00044     // orientation, so we do not try to be clever.
00045     //    fieldValues.push_back(BVector(Bx,By,Bz));
00046     
00047     // Preserve double precision!
00048     Vector3DBase<double, LocalTag>  lB = frame().toLocal(Vector3DBase<double, GlobalTag>(Bx,By,Bz));
00049     fieldValues.push_back(BVector(lB.x(), lB.y(), lB.z()));
00050   }
00051   // check completeness
00052   string lastEntry;
00053   inFile >> lastEntry;
00054   if (lastEntry != "complete"){
00055     cout << "ERROR during file reading: file is not complete" << endl;
00056   }
00057 
00058   GlobalPoint grefp( GlobalPoint::Cylindrical( xref, yref, zref));
00059 
00060 #ifdef DEBUG_GRID
00061   LocalPoint lrefp = frame().toLocal( grefp);
00062   cout << "Grid reference point in grid system: " << xref << "," << yref << "," << zref << endl;
00063   cout << "Grid reference point in global x,y,z: " << grefp << endl;
00064   cout << "Grid reference point in local x,y,z: " << lrefp << endl;
00065   cout << "steps " << stepx << "," <<  stepy << "," << stepz << endl;
00066   cout << "RParAsFunOfPhi[0...4] = ";
00067   for (int i=0; i<4; ++i) cout << RParAsFunOfPhi[i] << " "; cout << endl;
00068 #endif
00069 
00070   Grid1D gridX( 0, n1-1, n1); // offset and step size not constant
00071   Grid1D gridY( yref, yref + stepy*(n2-1), n2);
00072   Grid1D gridZ( grefp.z(), grefp.z() + stepz*(n3-1), n3);
00073 
00074   grid_ = GridType( gridX, gridY, gridZ, fieldValues);
00075 
00076   stepConstTerm_ = (RParAsFunOfPhi[0] - RParAsFunOfPhi[2]) / (n1-1);
00077   stepPhiTerm_   = (RParAsFunOfPhi[1] - RParAsFunOfPhi[3]) / (n1-1);
00078   startConstTerm_ = RParAsFunOfPhi[2];
00079   startPhiTerm_   = RParAsFunOfPhi[3];
00080 
00081   // Activate/deactivate timers
00082 //   static SimpleConfigurable<bool> timerOn(false,"MFGrid:timing");
00083 //   (*TimingReport::current()).switchOn("MagneticFieldProvider::valueInTesla(SpecialCylindricalMFGrid)",timerOn);
00084 }
00085  
00086 
00087 MFGrid::LocalVector SpecialCylindricalMFGrid::uncheckedValueInTesla( const LocalPoint& p) const
00088 {
00089 //   static TimingReport::Item & timer= (*TimingReport::current())["MagneticFieldProvider::valueInTesla(SpecialCylindricalMFGrid)"];
00090 //   TimeMe t(timer,false);
00091 
00092   LinearGridInterpolator3D interpol( grid_);
00093   double a, b, c;
00094   toGridFrame( p, a, b, c);
00095   // the following holds if B values was not converted to local coords -- see ctor
00096 //   GlobalVector gv( interpol.interpolate( a, b, c)); // grid in global frame
00097 //   return frame().toLocal(gv);           // must return a local vector
00098   return LocalVector(interpol.interpolate( a, b, c));
00099 }
00100 
00101 void SpecialCylindricalMFGrid::dump() const {}
00102 
00103 
00104 MFGrid::LocalPoint SpecialCylindricalMFGrid::fromGridFrame( double a, double b, double c) const
00105 {
00106   double sinPhi; // sin or cos depending on wether we are at phi=0 or phi=pi/2
00107   if (sector1) {
00108     sinPhi = cos(b);
00109   } else {
00110     sinPhi = sin(b);
00111   }
00112   
00113   double R = a*stepSize(sinPhi) + startingPoint(sinPhi);
00114   // "OLD" convention of phi.
00115   //  GlobalPoint gp( GlobalPoint::Cylindrical(R, Geom::pi() - b, c));
00116   GlobalPoint gp( GlobalPoint::Cylindrical(R, b, c));
00117   return frame().toLocal(gp);
00118 }
00119 
00120 void SpecialCylindricalMFGrid::toGridFrame( const LocalPoint& p, 
00121                                             double& a, double& b, double& c) const
00122 {
00123   GlobalPoint gp = frame().toGlobal(p);
00124   double sinPhi; // sin or cos depending on wether we are at phi=0 or phi=pi/2
00125   if (sector1) {
00126     sinPhi = cos(gp.phi());
00127   } else {
00128     sinPhi = sin(gp.phi());
00129   }
00130   a = (gp.perp()-startingPoint(sinPhi))/stepSize(sinPhi);
00131   // FIXME: "OLD" convention of phi.
00132   // b = Geom::pi() - gp.phi();
00133   b = gp.phi();
00134   c = gp.z();
00135 
00136 #ifdef DEBUG_GRID
00137   if (sector1) {
00138     cout << "toGridFrame: sinPhi " ;
00139   } else {
00140     cout << "toGridFrame: cosPhi " ;
00141   }
00142   cout << sinPhi << " LocalPoint " << p 
00143        << " GlobalPoint " << gp << endl 
00144        << " a " << a << " b " << b << " c " << c << endl;
00145     
00146 #endif
00147 }
00148