CMS 3D CMS Logo

TrapezoidalCylindricalMFGrid.cc

Go to the documentation of this file.
00001 #include "MagneticField/Interpolation/src/TrapezoidalCylindricalMFGrid.h"
00002 #include "MagneticField/Interpolation/src/binary_ifstream.h"
00003 #include "MagneticField/Interpolation/src/LinearGridInterpolator3D.h"
00004 #include "MagneticField/VolumeGeometry/interface/MagExceptions.h"
00005 
00006 #include <iostream>
00007 
00008 using namespace std;
00009 
00010 TrapezoidalCylindricalMFGrid::TrapezoidalCylindricalMFGrid( binary_ifstream& inFile,
00011                                                         const GloballyPositioned<float>& vol)
00012   : MFGrid3D(vol)
00013 {
00014   // The parameters read from the data files are given in global coordinates.
00015   // In version 85l, local frame has the same orientation of global frame for the reference
00016   // volume, i.e. the r.f. transformation is only a translation.
00017   // There is therefore no need to convert the field values to local coordinates.
00018   // Check this assumption: 
00019   GlobalVector localXDir(frame().toGlobal(LocalVector(1,0,0)));
00020   GlobalVector localYDir(frame().toGlobal(LocalVector(0,1,0)));
00021 
00022   if (localXDir.dot(GlobalVector(1,0,0)) > 0.999999 &&
00023       localYDir.dot(GlobalVector(0,1,0)) > 0.999999) {
00024     // "null" rotation - requires no conversion...
00025   } else {
00026     cout << "ERROR: TrapezoidalCylindricalMFGrid: unexpected orientation: x: " 
00027          << localXDir << " y: " << localYDir << endl;
00028   }
00029 
00030   int n1, n2, n3;
00031   inFile >> n1 >> n2 >> n3;
00032   double xref, yref, zref;
00033   inFile >> xref >> yref >> zref;
00034   double stepx, stepy, stepz;
00035   inFile >> stepx    >> stepy    >> stepz;
00036 
00037   double BasicDistance1[3][3];  // linear step
00038   double BasicDistance2[3][3];  // linear offset
00039   bool   easya, easyb, easyc;
00040 
00041   inFile >> BasicDistance1[0][0] >> BasicDistance1[1][0] >> BasicDistance1[2][0];
00042   inFile >> BasicDistance1[0][1] >> BasicDistance1[1][1] >> BasicDistance1[2][1];
00043   inFile >> BasicDistance1[0][2] >> BasicDistance1[1][2] >> BasicDistance1[2][2];
00044   inFile >> BasicDistance2[0][0] >> BasicDistance2[1][0] >> BasicDistance2[2][0];
00045   inFile >> BasicDistance2[0][1] >> BasicDistance2[1][1] >> BasicDistance2[2][1];
00046   inFile >> BasicDistance2[0][2] >> BasicDistance2[1][2] >> BasicDistance2[2][2];
00047   inFile >> easya >> easyb >> easyc;
00048 
00049   vector<BVector> fieldValues;
00050   float Bx, By, Bz;
00051   int nLines = n1*n2*n3;
00052   for (int iLine=0; iLine<nLines; ++iLine){
00053     inFile >> Bx >> By >> Bz;
00054     fieldValues.push_back(BVector(Bx,By,Bz));
00055   }
00056   // check completeness
00057   string lastEntry;
00058   inFile >> lastEntry;
00059   if (lastEntry != "complete") {
00060     cout << "ERROR during file reading: file is not complete" << endl;
00061   }
00062 
00063 #ifdef DEBUG_GRID
00064   cout << "easya " << easya << " easyb " << easyb << " easyc " << easyc << endl;
00065 #endif
00066 
00067   if (!easyb || !easyc) {
00068     throw MagGeometryError("TrapezoidalCartesianMFGrid only implemented for first coordinate");
00069   }
00070 
00071 #ifdef DEBUG_GRID
00072   cout << "Grid reference point in grid system: " << xref << "," << yref << "," << zref << endl;
00073   cout << "steps " << stepx << "," <<  stepy << "," << stepz << endl;
00074   cout << "ns " << n1 << "," <<  n2 << "," << n3 << endl;
00075 
00076   for (int i=0; i<3; ++i) for (int j=0; j<3; ++j) {
00077     cout << "BasicDistance1[" << i << "][" << j << "] = " << BasicDistance1[i][j]
00078          << "BasicDistance2[" << i << "][" << j << "] = " << BasicDistance2[i][j] << endl;
00079   }
00080 #endif
00081 
00082   // the "not easy" coordinate is x
00083   double a = stepx * (n1 -1);
00084   double b = a + BasicDistance1[0][1] * (n2-1)*(n1-1) + BasicDistance1[0][2] * (n3-1)*(n1-1);
00085   //  double h = stepy * (n2-1);
00086   double h = stepz * (n3-1);
00087   double delta = -BasicDistance2[0][1] * (n2-1) -BasicDistance2[0][2] * (n3-1);
00088 
00089 #ifdef DEBUG_GRID
00090   cout << "Trapeze size (a,b,h) = " << a << "," << b << "," << h << endl;
00091 #endif
00092 
00093   GlobalPoint grefp( GlobalPoint::Cylindrical( xref, Geom::pi() - yref, zref));
00094   LocalPoint lrefp = frame().toLocal( grefp);
00095 
00096 #ifdef DEBUG_GRID
00097   cout << "Global origin " << grefp << endl;
00098   cout << "Local origin  " << lrefp << endl;
00099 #endif
00100 
00101   double baMinus1 = BasicDistance1[0][2]*(n3-1) / stepx;
00102   if (abs(baMinus1) > 0.000001) {
00103     double b_over_a = 1 + baMinus1;
00104     double a1 = abs(baMinus1) > 0.000001 ? delta / baMinus1 : a/2;
00105 #ifdef DEBUG_GRID
00106    cout << "a1 = " << a1 << endl;
00107 #endif
00108 
00109     // transform reference point to grid frame
00110     double x0 = lrefp.perp() + a1;
00111     double y0 = lrefp.z() + h/2.;
00112     mapping_ = Trapezoid2RectangleMappingX( x0, y0, b_over_a, h);
00113   }
00114   else { // parallelogram
00115     mapping_ = Trapezoid2RectangleMappingX( 0, 0, delta/h);
00116   }
00117   double xrec, yrec;
00118   mapping_.rectangle( lrefp.perp(), lrefp.z(), xrec, yrec);
00119 
00120   Grid1D<double> gridX( xrec, xrec + (a+b)/2., n1);
00121   Grid1D<double> gridY( yref, yref + stepy*(n2-1), n2);
00122   Grid1D<double> gridZ( yrec, yrec + h, n3);
00123   grid_ = GridType( gridX, gridY, gridZ, fieldValues);
00124     
00125   // Activate/deactivate timers
00126 //   static SimpleConfigurable<bool> timerOn(false,"MFGrid:timing");
00127 //   (*TimingReport::current()).switchOn("MagneticFieldProvider::valueInTesla(TrapezoidalCylindricalMFGrid)",timerOn);
00128 }
00129 
00130 void TrapezoidalCylindricalMFGrid::dump() const
00131 {}
00132 
00133 MFGrid::LocalVector 
00134 TrapezoidalCylindricalMFGrid::uncheckedValueInTesla( const LocalPoint& p) const
00135 {
00136 //   static TimingReport::Item & timer= (*TimingReport::current())["MagneticFieldProvider::valueInTesla(TrapezoidalCylindricalMFGrid)"];
00137 //   TimeMe t(timer,false);
00138 
00139   LinearGridInterpolator3D<GridType::ValueType, GridType::Scalar> interpol( grid_);
00140   double a, b, c;
00141   toGridFrame( p, a, b, c);
00142   GlobalVector gv( interpol.interpolate( a, b, c)); // grid in global frame
00143   return frame().toLocal(gv);           // must return a local vector
00144 }
00145 
00146 void TrapezoidalCylindricalMFGrid::toGridFrame( const LocalPoint& p, 
00147                                               double& a, double& b, double& c) const
00148 {
00149   mapping_.rectangle( p.perp(), p.z(), a, c);
00150   // FIXME: "OLD" convention of phi.
00151   //  b = Geom::pi() - p.phi();
00152   b = p.phi();
00153 }
00154 
00155 MFGrid::LocalPoint 
00156 TrapezoidalCylindricalMFGrid::fromGridFrame( double a, double b, double c) const
00157 {
00158   double rtrap, ztrap;
00159   mapping_.trapezoid( a, c, rtrap, ztrap);
00160   // FIXME: "OLD" convention of phi.
00161   //  return LocalPoint(LocalPoint::Cylindrical(rtrap, Geom::pi() - b, ztrap));
00162   return LocalPoint(LocalPoint::Cylindrical(rtrap, b, ztrap));
00163 }

Generated on Tue Jun 9 17:40:36 2009 for CMSSW by  doxygen 1.5.4