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 for (int iLine=0; iLine<nLines; ++iLine){
00070 inFile >> Bx >> By >> Bz;
00071 if (convertToLocal) {
00072
00073 Vector3DBase<double, LocalTag> lB = frame().toLocal(Vector3DBase<double, GlobalTag>(Bx,By,Bz));
00074 fieldValues.push_back(BVector(lB.x(), lB.y(), lB.z()));
00075
00076 } else {
00077 fieldValues.push_back(BVector(Bx,By,Bz));
00078 }
00079 }
00080
00081 string lastEntry;
00082 inFile >> lastEntry;
00083 if (lastEntry != "complete") {
00084 cout << "ERROR during file reading: file is not complete" << endl;
00085 }
00086
00087
00088
00089
00090
00091
00092 int nx, ny;
00093 double stepx, stepy, stepz;
00094 double dstep, offset;
00095 if (!easya && easyb && easyc) {
00096
00097 increasingAlongX = true;
00098 nx = n1;
00099 ny = n2;
00100 stepx = step1;
00101 stepy = step2;
00102 stepz = step3;
00103 dstep = BasicDistance1[0][1];
00104 offset = BasicDistance2[0][1];
00105 } else if (easya && !easyb && easyc) {
00106
00107 increasingAlongX = false;
00108 nx = n2;
00109 ny = n1;
00110 stepx = step2;
00111 stepy = step1;
00112 stepz = -step3;
00113 dstep = BasicDistance1[1][0];
00114 offset = BasicDistance2[1][0];
00115
00116 } else {
00117
00118 throw MagGeometryError("TrapezoidalCartesianMFGrid only implemented for first or second coordinate");
00119 }
00120
00121 double a = stepx * (nx -1);
00122 double b = a + dstep * (ny-1) * (nx-1);
00123 double h = stepy * (ny-1);
00124 double delta = -offset * (ny-1);
00125 double baMinus1 = dstep*(ny-1) / stepx;
00126
00127 GlobalPoint grefp( xref, yref, zref);
00128 LocalPoint lrefp = frame().toLocal( grefp);
00129
00130 if (fabs(baMinus1) > 0.000001) {
00131 double b_over_a = 1 + baMinus1;
00132 double a1 = delta/baMinus1;
00133
00134 #ifdef DEBUG_GRID
00135 cout << "Trapeze size (a,b,h) = " << a << "," << b << "," << h << endl;
00136 cout << "Global origin " << grefp << endl;
00137 cout << "Local origin " << lrefp << endl;
00138 cout << "a1 = " << a1 << endl;
00139 #endif
00140
00141
00142
00143 double x0 = lrefp.x() + a1;
00144 double y0 = lrefp.y() + h/2.;
00145 mapping_ = Trapezoid2RectangleMappingX( x0, y0, b_over_a, h);
00146 }
00147 else {
00148 mapping_ = Trapezoid2RectangleMappingX( 0, 0, delta/h);
00149 }
00150
00151
00152 double xrec, yrec;
00153 mapping_.rectangle( lrefp.x(), lrefp.y(), xrec, yrec);
00154
00155 Grid1D<double> gridX( xrec, xrec + (a+b)/2., nx);
00156 Grid1D<double> gridY( yrec, yrec + h, ny);
00157 Grid1D<double> gridZ( lrefp.z(), lrefp.z() + stepz*(n3-1), n3);
00158
00159 #ifdef DEBUG_GRID
00160 cout << " GRID X range: local " << gridX.lower() << " - " << gridX.upper()
00161 <<" global: " << (frame().toGlobal(LocalPoint(gridX.lower(),0,0))).y() << " - "
00162 << (frame().toGlobal(LocalPoint(gridX.upper(),0,0))).y() << endl;
00163
00164 cout << " GRID Y range: local " << gridY.lower() << " - " << gridY.upper()
00165 << " global: " << (frame().toGlobal(LocalPoint(0,gridY.lower(),0))).x() << " - "
00166 << (frame().toGlobal(LocalPoint(0,gridY.upper(),0))).x() << endl;
00167
00168 cout << " GRID Z range: local " << gridZ.lower() << " - " << gridZ.upper()
00169 << " global: " << (frame().toGlobal(LocalPoint(0,0,gridZ.lower()))).z() << " "
00170 << (frame().toGlobal(LocalPoint(0,0,gridZ.upper()))).z() << endl;
00171 #endif
00172
00173 if (increasingAlongX) {
00174 grid_ = GridType( gridX, gridY, gridZ, fieldValues);
00175 } else {
00176
00177
00178
00179
00180 grid_ = GridType( gridY, gridX, gridZ, fieldValues);
00181 }
00182
00183
00184 #ifdef DEBUG_GRID
00185 dump();
00186 #endif
00187 }
00188
00189 void TrapezoidalCartesianMFGrid::dump() const
00190 {
00191
00192 cout << endl << "Dump of TrapezoidalCartesianMFGrid" << endl;
00193
00194
00195 cout << "Number of points from Grid1D "
00196 << grid_.grida().nodes() << " " << grid_.gridb().nodes() << " " << grid_.gridc().nodes() << endl;
00197
00198
00199
00200 cout << "Reference Point from Grid1D "
00201 << grid_.grida().lower() << " " << grid_.gridb().lower() << " " << grid_.gridc().lower() << endl;
00202
00203
00204
00205 cout << "Basic Distance from Grid1D "
00206 << grid_.grida().step() << " " << grid_.gridb().step() << " " << grid_.gridc().step() << endl;
00207
00208
00209 cout << "Dumping " << grid_.data().size() << " field values " << endl;
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227 }
00228
00229 MFGrid::LocalVector TrapezoidalCartesianMFGrid::uncheckedValueInTesla( const LocalPoint& p) const
00230 {
00231
00232 double xrec, yrec;
00233 mapping_.rectangle( p.x(), p.y(), xrec, yrec);
00234
00235
00236
00237
00238
00239
00240 LinearGridInterpolator3D<GridType::ValueType, GridType::Scalar> interpol( grid_);
00241
00242 if (!increasingAlongX) {
00243 std::swap(xrec,yrec);
00244
00245
00246
00247 }
00248
00249 return LocalVector(interpol.interpolate( xrec, yrec, p.z()));
00250 }
00251
00252 void TrapezoidalCartesianMFGrid::toGridFrame( const LocalPoint& p,
00253 double& a, double& b, double& c) const
00254 {
00255 if (increasingAlongX) {
00256 mapping_.rectangle( p.x(), p.y(), a, b);
00257 } else {
00258 mapping_.rectangle( p.x(), p.y(), b, a);
00259 }
00260
00261 c = p.z();
00262 }
00263
00264 MFGrid::LocalPoint TrapezoidalCartesianMFGrid::fromGridFrame( double a, double b, double c) const
00265 {
00266 double xtrap, ytrap;
00267 if (increasingAlongX) {
00268 mapping_.trapezoid( a, b, xtrap, ytrap);
00269 } else {
00270 mapping_.trapezoid( b, a, xtrap, ytrap);
00271 }
00272 return LocalPoint( xtrap, ytrap, c);
00273 }