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
00015
00016
00017
00018
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
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];
00038 double BasicDistance2[3][3];
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 fieldValues.reserve(nLines);
00053 for (int iLine=0; iLine<nLines; ++iLine){
00054 inFile >> Bx >> By >> Bz;
00055 fieldValues.push_back(BVector(Bx,By,Bz));
00056 }
00057
00058 string lastEntry;
00059 inFile >> lastEntry;
00060 if (lastEntry != "complete") {
00061 cout << "ERROR during file reading: file is not complete" << endl;
00062 }
00063
00064 #ifdef DEBUG_GRID
00065 cout << "easya " << easya << " easyb " << easyb << " easyc " << easyc << endl;
00066 #endif
00067
00068 if (!easyb || !easyc) {
00069 throw MagGeometryError("TrapezoidalCartesianMFGrid only implemented for first coordinate");
00070 }
00071
00072 #ifdef DEBUG_GRID
00073 cout << "Grid reference point in grid system: " << xref << "," << yref << "," << zref << endl;
00074 cout << "steps " << stepx << "," << stepy << "," << stepz << endl;
00075 cout << "ns " << n1 << "," << n2 << "," << n3 << endl;
00076
00077 for (int i=0; i<3; ++i) for (int j=0; j<3; ++j) {
00078 cout << "BasicDistance1[" << i << "][" << j << "] = " << BasicDistance1[i][j]
00079 << "BasicDistance2[" << i << "][" << j << "] = " << BasicDistance2[i][j] << endl;
00080 }
00081 #endif
00082
00083
00084 double a = stepx * (n1 -1);
00085 double b = a + BasicDistance1[0][1] * (n2-1)*(n1-1) + BasicDistance1[0][2] * (n3-1)*(n1-1);
00086
00087 double h = stepz * (n3-1);
00088 double delta = -BasicDistance2[0][1] * (n2-1) -BasicDistance2[0][2] * (n3-1);
00089
00090 #ifdef DEBUG_GRID
00091 cout << "Trapeze size (a,b,h) = " << a << "," << b << "," << h << endl;
00092 #endif
00093
00094 GlobalPoint grefp( GlobalPoint::Cylindrical( xref, Geom::pi() - yref, zref));
00095 LocalPoint lrefp = frame().toLocal( grefp);
00096
00097 #ifdef DEBUG_GRID
00098 cout << "Global origin " << grefp << endl;
00099 cout << "Local origin " << lrefp << endl;
00100 #endif
00101
00102 double baMinus1 = BasicDistance1[0][2]*(n3-1) / stepx;
00103 if (std::abs(baMinus1) > 0.000001) {
00104 double b_over_a = 1 + baMinus1;
00105 double a1 = std::abs(baMinus1) > 0.000001 ? delta / baMinus1 : a/2;
00106 #ifdef DEBUG_GRID
00107 cout << "a1 = " << a1 << endl;
00108 #endif
00109
00110
00111 double x0 = lrefp.perp() + a1;
00112 double y0 = lrefp.z() + h/2.;
00113 mapping_ = Trapezoid2RectangleMappingX( x0, y0, b_over_a, h);
00114 }
00115 else {
00116 mapping_ = Trapezoid2RectangleMappingX( 0, 0, delta/h);
00117 }
00118 double xrec, yrec;
00119 mapping_.rectangle( lrefp.perp(), lrefp.z(), xrec, yrec);
00120
00121 Grid1D gridX( xrec, xrec + (a+b)/2., n1);
00122 Grid1D gridY( yref, yref + stepy*(n2-1), n2);
00123 Grid1D gridZ( yrec, yrec + h, n3);
00124 grid_ = GridType( gridX, gridY, gridZ, fieldValues);
00125
00126
00127
00128
00129 }
00130
00131 void TrapezoidalCylindricalMFGrid::dump() const
00132 {}
00133
00134 MFGrid::LocalVector
00135 TrapezoidalCylindricalMFGrid::uncheckedValueInTesla( const LocalPoint& p) const
00136 {
00137
00138
00139
00140 LinearGridInterpolator3D interpol( grid_);
00141 double a, b, c;
00142 toGridFrame( p, a, b, c);
00143 GlobalVector gv( interpol.interpolate( a, b, c));
00144 return frame().toLocal(gv);
00145 }
00146
00147 void TrapezoidalCylindricalMFGrid::toGridFrame( const LocalPoint& p,
00148 double& a, double& b, double& c) const
00149 {
00150 mapping_.rectangle( p.perp(), p.z(), a, c);
00151
00152
00153 b = p.phi();
00154 }
00155
00156 MFGrid::LocalPoint
00157 TrapezoidalCylindricalMFGrid::fromGridFrame( double a, double b, double c) const
00158 {
00159 double rtrap, ztrap;
00160 mapping_.trapezoid( a, c, rtrap, ztrap);
00161
00162
00163 return LocalPoint(LocalPoint::Cylindrical(rtrap, b, ztrap));
00164 }