00001
00008 #include "MagneticField/Interpolation/src/TrapezoidalCartesianMFGrid.h"
00009 #include "MagneticField/Interpolation/src/binary_ifstream.h"
00010 #include "MagneticField/Interpolation/src/LinearGridInterpolator3D.h"
00011 #include "MagneticField/VolumeGeometry/interface/MagExceptions.h"
00012 #include <iostream>
00013
00014
00015
00016 using namespace std;
00017
00018 TrapezoidalCartesianMFGrid::TrapezoidalCartesianMFGrid( binary_ifstream& inFile,
00019 const GloballyPositioned<float>& vol)
00020 : MFGrid3D(vol), increasingAlongX(false), convertToLocal(true)
00021 {
00022
00023
00024
00025
00026
00027
00028
00029 GlobalVector localXDir(frame().toGlobal(LocalVector(1,0,0)));
00030 GlobalVector localYDir(frame().toGlobal(LocalVector(0,1,0)));
00031
00032 if (localXDir.dot(GlobalVector(1,0,0)) > 0.999999 &&
00033 localYDir.dot(GlobalVector(0,1,0)) > 0.999999) {
00034
00035 convertToLocal = false;
00036 } else if (localXDir.dot(GlobalVector(0,1,0)) > 0.999999 &&
00037 localYDir.dot(GlobalVector(1,0,0)) > 0.999999) {
00038
00039 convertToLocal = true;
00040 } else {
00041 convertToLocal = true;
00042
00043 cout << "WARNING: TrapezoidalCartesianMFGrid: unexpected orientation: x: "
00044 << localXDir << " y: " << localYDir << endl;
00045 }
00046
00047 int n1, n2, n3;
00048 inFile >> n1 >> n2 >> n3;
00049 double xref, yref, zref;
00050 inFile >> xref >> yref >> zref;
00051 double step1, step2, step3;
00052 inFile >> step1 >> step2 >> step3;
00053
00054 double BasicDistance1[3][3];
00055 double BasicDistance2[3][3];
00056 bool easya, easyb, easyc;
00057
00058 inFile >> BasicDistance1[0][0] >> BasicDistance1[1][0] >> BasicDistance1[2][0];
00059 inFile >> BasicDistance1[0][1] >> BasicDistance1[1][1] >> BasicDistance1[2][1];
00060 inFile >> BasicDistance1[0][2] >> BasicDistance1[1][2] >> BasicDistance1[2][2];
00061 inFile >> BasicDistance2[0][0] >> BasicDistance2[1][0] >> BasicDistance2[2][0];
00062 inFile >> BasicDistance2[0][1] >> BasicDistance2[1][1] >> BasicDistance2[2][1];
00063 inFile >> BasicDistance2[0][2] >> BasicDistance2[1][2] >> BasicDistance2[2][2];
00064 inFile >> easya >> easyb >> easyc;
00065
00066 vector<BVector> fieldValues;
00067 float Bx, By, Bz;
00068 int nLines = n1*n2*n3;
00069 fieldValues.reserve(nLines);
00070 for (int iLine=0; iLine<nLines; ++iLine){
00071 inFile >> Bx >> By >> Bz;
00072 if (convertToLocal) {
00073
00074 Vector3DBase<double, LocalTag> lB = frame().toLocal(Vector3DBase<double, GlobalTag>(Bx,By,Bz));
00075 fieldValues.push_back(BVector(lB.x(), lB.y(), lB.z()));
00076
00077 } else {
00078 fieldValues.push_back(BVector(Bx,By,Bz));
00079 }
00080 }
00081
00082 string lastEntry;
00083 inFile >> lastEntry;
00084 if (lastEntry != "complete") {
00085 cout << "ERROR during file reading: file is not complete" << endl;
00086 }
00087
00088
00089
00090
00091
00092
00093 int nx, ny;
00094 double stepx, stepy, stepz;
00095 double dstep, offset;
00096 if (!easya && easyb && easyc) {
00097
00098 increasingAlongX = true;
00099 nx = n1;
00100 ny = n2;
00101 stepx = step1;
00102 stepy = step2;
00103 stepz = step3;
00104 dstep = BasicDistance1[0][1];
00105 offset = BasicDistance2[0][1];
00106 } else if (easya && !easyb && easyc) {
00107
00108 increasingAlongX = false;
00109 nx = n2;
00110 ny = n1;
00111 stepx = step2;
00112 stepy = step1;
00113 stepz = -step3;
00114 dstep = BasicDistance1[1][0];
00115 offset = BasicDistance2[1][0];
00116
00117 } else {
00118
00119 throw MagGeometryError("TrapezoidalCartesianMFGrid only implemented for first or second coordinate");
00120 }
00121
00122 double a = stepx * (nx -1);
00123 double b = a + dstep * (ny-1) * (nx-1);
00124 double h = stepy * (ny-1);
00125 double delta = -offset * (ny-1);
00126 double baMinus1 = dstep*(ny-1) / stepx;
00127
00128 GlobalPoint grefp( xref, yref, zref);
00129 LocalPoint lrefp = frame().toLocal( grefp);
00130
00131 if (fabs(baMinus1) > 0.000001) {
00132 double b_over_a = 1 + baMinus1;
00133 double a1 = delta/baMinus1;
00134
00135 #ifdef DEBUG_GRID
00136 cout << "Trapeze size (a,b,h) = " << a << "," << b << "," << h << endl;
00137 cout << "Global origin " << grefp << endl;
00138 cout << "Local origin " << lrefp << endl;
00139 cout << "a1 = " << a1 << endl;
00140 #endif
00141
00142
00143
00144 double x0 = lrefp.x() + a1;
00145 double y0 = lrefp.y() + h/2.;
00146 mapping_ = Trapezoid2RectangleMappingX( x0, y0, b_over_a, h);
00147 }
00148 else {
00149 mapping_ = Trapezoid2RectangleMappingX( 0, 0, delta/h);
00150 }
00151
00152
00153 double xrec, yrec;
00154 mapping_.rectangle( lrefp.x(), lrefp.y(), xrec, yrec);
00155
00156 Grid1D gridX( xrec, xrec + (a+b)/2., nx);
00157 Grid1D gridY( yrec, yrec + h, ny);
00158 Grid1D gridZ( lrefp.z(), lrefp.z() + stepz*(n3-1), n3);
00159
00160 #ifdef DEBUG_GRID
00161 cout << " GRID X range: local " << gridX.lower() << " - " << gridX.upper()
00162 <<" global: " << (frame().toGlobal(LocalPoint(gridX.lower(),0,0))).y() << " - "
00163 << (frame().toGlobal(LocalPoint(gridX.upper(),0,0))).y() << endl;
00164
00165 cout << " GRID Y range: local " << gridY.lower() << " - " << gridY.upper()
00166 << " global: " << (frame().toGlobal(LocalPoint(0,gridY.lower(),0))).x() << " - "
00167 << (frame().toGlobal(LocalPoint(0,gridY.upper(),0))).x() << endl;
00168
00169 cout << " GRID Z range: local " << gridZ.lower() << " - " << gridZ.upper()
00170 << " global: " << (frame().toGlobal(LocalPoint(0,0,gridZ.lower()))).z() << " "
00171 << (frame().toGlobal(LocalPoint(0,0,gridZ.upper()))).z() << endl;
00172 #endif
00173
00174 if (increasingAlongX) {
00175 grid_ = GridType( gridX, gridY, gridZ, fieldValues);
00176 } else {
00177
00178
00179
00180
00181 grid_ = GridType( gridY, gridX, gridZ, fieldValues);
00182 }
00183
00184
00185 #ifdef DEBUG_GRID
00186 dump();
00187 #endif
00188 }
00189
00190 void TrapezoidalCartesianMFGrid::dump() const
00191 {
00192
00193 cout << endl << "Dump of TrapezoidalCartesianMFGrid" << endl;
00194
00195
00196 cout << "Number of points from Grid1D "
00197 << grid_.grida().nodes() << " " << grid_.gridb().nodes() << " " << grid_.gridc().nodes() << endl;
00198
00199
00200
00201 cout << "Reference Point from Grid1D "
00202 << grid_.grida().lower() << " " << grid_.gridb().lower() << " " << grid_.gridc().lower() << endl;
00203
00204
00205
00206 cout << "Basic Distance from Grid1D "
00207 << grid_.grida().step() << " " << grid_.gridb().step() << " " << grid_.gridc().step() << endl;
00208
00209
00210 cout << "Dumping " << grid_.data().size() << " field values " << endl;
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228 }
00229
00230 MFGrid::LocalVector TrapezoidalCartesianMFGrid::uncheckedValueInTesla( const LocalPoint& p) const
00231 {
00232
00233 double xrec, yrec;
00234 mapping_.rectangle( p.x(), p.y(), xrec, yrec);
00235
00236
00237
00238
00239
00240
00241 LinearGridInterpolator3D interpol( grid_);
00242
00243 if (!increasingAlongX) {
00244 std::swap(xrec,yrec);
00245
00246
00247
00248 }
00249
00250 return LocalVector(interpol.interpolate( xrec, yrec, p.z()));
00251 }
00252
00253 void TrapezoidalCartesianMFGrid::toGridFrame( const LocalPoint& p,
00254 double& a, double& b, double& c) const
00255 {
00256 if (increasingAlongX) {
00257 mapping_.rectangle( p.x(), p.y(), a, b);
00258 } else {
00259 mapping_.rectangle( p.x(), p.y(), b, a);
00260 }
00261
00262 c = p.z();
00263 }
00264
00265 MFGrid::LocalPoint TrapezoidalCartesianMFGrid::fromGridFrame( double a, double b, double c) const
00266 {
00267 double xtrap, ytrap;
00268 if (increasingAlongX) {
00269 mapping_.trapezoid( a, b, xtrap, ytrap);
00270 } else {
00271 mapping_.trapezoid( b, a, xtrap, ytrap);
00272 }
00273 return LocalPoint( xtrap, ytrap, c);
00274 }