CMS 3D CMS Logo

TrapezoidalCartesianMFGrid.cc
Go to the documentation of this file.
1 
7 #include "binary_ifstream.h"
10 #include <iostream>
11 
12 //#define DEBUG_GRID
13 
14 using namespace std;
15 
17  const GloballyPositioned<float>& vol)
18  : MFGrid3D(vol), increasingAlongX(false), convertToLocal(true)
19 {
20 
21  // The parameters read from the data files are given in global coordinates.
22  // In version 85l, local frame has the same orientation of global frame for the reference
23  // volume, i.e. the r.f. transformation is only a translation.
24  // There is therefore no need to convert the field values to local coordinates.
25 
26  // Check orientation of local reference frame:
27  GlobalVector localXDir(frame().toGlobal(LocalVector(1,0,0)));
28  GlobalVector localYDir(frame().toGlobal(LocalVector(0,1,0)));
29 
30  if (localXDir.dot(GlobalVector(1,0,0)) > 0.999999 &&
31  localYDir.dot(GlobalVector(0,1,0)) > 0.999999) {
32  // "null" rotation - requires no conversion...
33  convertToLocal = false;
34  } else if (localXDir.dot(GlobalVector(0,1,0)) > 0.999999 &&
35  localYDir.dot(GlobalVector(1,0,0)) > 0.999999) {
36  // Typical orientation if master volume is in sector 1
37  convertToLocal = true;
38  } else {
39  convertToLocal = true;
40  // Nothing wrong in principle, but this is not expected
41  cout << "WARNING: TrapezoidalCartesianMFGrid: unexpected orientation: x: "
42  << localXDir << " y: " << localYDir << endl;
43  }
44 
45  int n1, n2, n3;
46  inFile >> n1 >> n2 >> n3;
47  double xref, yref, zref;
48  inFile >> xref >> yref >> zref;
49  double step1, step2, step3;
50  inFile >> step1 >> step2 >> step3;
51 
52  double BasicDistance1[3][3]; // linear step
53  double BasicDistance2[3][3]; // linear offset
54  bool easya, easyb, easyc;
55 
56  inFile >> BasicDistance1[0][0] >> BasicDistance1[1][0] >> BasicDistance1[2][0];
57  inFile >> BasicDistance1[0][1] >> BasicDistance1[1][1] >> BasicDistance1[2][1];
58  inFile >> BasicDistance1[0][2] >> BasicDistance1[1][2] >> BasicDistance1[2][2];
59  inFile >> BasicDistance2[0][0] >> BasicDistance2[1][0] >> BasicDistance2[2][0];
60  inFile >> BasicDistance2[0][1] >> BasicDistance2[1][1] >> BasicDistance2[2][1];
61  inFile >> BasicDistance2[0][2] >> BasicDistance2[1][2] >> BasicDistance2[2][2];
62  inFile >> easya >> easyb >> easyc;
63 
64  vector<BVector> fieldValues;
65  float Bx, By, Bz;
66  int nLines = n1*n2*n3;
67  fieldValues.reserve(nLines);
68  for (int iLine=0; iLine<nLines; ++iLine){
69  inFile >> Bx >> By >> Bz;
70  if (convertToLocal) {
71  // Preserve double precision!
73  fieldValues.push_back(BVector(lB.x(), lB.y(), lB.z()));
74 
75  } else {
76  fieldValues.push_back(BVector(Bx,By,Bz));
77  }
78  }
79  // check completeness
80  string lastEntry;
81  inFile >> lastEntry;
82  if (lastEntry != "complete") {
83  cout << "ERROR during file reading: file is not complete" << endl;
84  }
85 
86  // In version 1103l the reference sector is at phi=0 so that local y is along global X.
87  // The increasing grid steps for the same volume are then along Y instead than along X.
88  // To use Trapezoid2RectangleMappingX to map the trapezoidal geometry to a rectangular
89  // cartesian geometry, we have to exchange (global) X and Y appropriately when constructing
90  // it.
91  int nx, ny;
92  double stepx, stepy, stepz;
93  double dstep, offset;
94  if (!easya && easyb && easyc) {
95  // Increasing grid spacing is on x
96  increasingAlongX = true;
97  nx = n1;
98  ny = n2;
99  stepx = step1;
100  stepy = step2;
101  stepz = step3;
102  dstep = BasicDistance1[0][1];
103  offset = BasicDistance2[0][1];
104  } else if (easya && !easyb && easyc) {
105  // Increasing grid spacing is on y
106  increasingAlongX = false;
107  nx = n2;
108  ny = n1;
109  stepx = step2;
110  stepy = step1;
111  stepz = -step3;
112  dstep = BasicDistance1[1][0];
113  offset = BasicDistance2[1][0];
114 
115  } else {
116  // Increasing spacing on z or on > 1 coordinate not supported
117  throw MagGeometryError("TrapezoidalCartesianMFGrid only implemented for first or second coordinate");
118  }
119 
120  double a = stepx * (nx -1); // first base
121  double b = a + dstep * (ny-1) * (nx-1); // second base
122  double h = stepy * (ny-1); // height
123  double delta = -offset * (ny-1); // offset between two bases
124  double baMinus1 = dstep*(ny-1) / stepx; // (b*a) - 1
125 
126  GlobalPoint grefp( xref, yref, zref);
127  LocalPoint lrefp = frame().toLocal( grefp);
128 
129  if (fabs(baMinus1) > 0.000001) {
130  double b_over_a = 1 + baMinus1;
131  double a1 = delta/baMinus1;
132 
133 #ifdef DEBUG_GRID
134  cout << "Trapeze size (a,b,h) = " << a << "," << b << "," << h << endl;
135  cout << "Global origin " << grefp << endl;
136  cout << "Local origin " << lrefp << endl;
137  cout << "a1 = " << a1 << endl;
138 #endif
139 
140  // FIXME ASSUMPTION: here we assume that the local reference frame is oriented with X along
141  // the direction of where the grid is not uniform. This is the case for all current geometries
142  double x0 = lrefp.x() + a1;
143  double y0 = lrefp.y() + h/2.;
144  mapping_ = Trapezoid2RectangleMappingX( x0, y0, b_over_a, h);
145  }
146  else { // parallelogram
147  mapping_ = Trapezoid2RectangleMappingX( 0, 0, delta/h);
148  }
149 
150  // transform reference point to grid frame
151  double xrec, yrec;
152  mapping_.rectangle( lrefp.x(), lrefp.y(), xrec, yrec);
153 
154  Grid1D gridX( xrec, xrec + (a+b)/2., nx);
155  Grid1D gridY( yrec, yrec + h, ny);
156  Grid1D gridZ( lrefp.z(), lrefp.z() + stepz*(n3-1), n3);
157 
158 #ifdef DEBUG_GRID
159  cout << " GRID X range: local " << gridX.lower() << " - " << gridX.upper()
160  <<" global: " << (frame().toGlobal(LocalPoint(gridX.lower(),0,0))).y() << " - "
161  << (frame().toGlobal(LocalPoint(gridX.upper(),0,0))).y() << endl;
162 
163  cout << " GRID Y range: local " << gridY.lower() << " - " << gridY.upper()
164  << " global: " << (frame().toGlobal(LocalPoint(0,gridY.lower(),0))).x() << " - "
165  << (frame().toGlobal(LocalPoint(0,gridY.upper(),0))).x() << endl;
166 
167  cout << " GRID Z range: local " << gridZ.lower() << " - " << gridZ.upper()
168  << " global: " << (frame().toGlobal(LocalPoint(0,0,gridZ.lower()))).z() << " "
169  << (frame().toGlobal(LocalPoint(0,0,gridZ.upper()))).z() << endl;
170 #endif
171 
172  if (increasingAlongX) {
173  grid_ = GridType( gridX, gridY, gridZ, fieldValues);
174  } else {
175  // The reason why gridY and gridX have to be exchanged is because Grid3D::index(i,j,k)
176  // assumes a specific order for the fieldValues, and we cannot rearrange this vector.
177  // Given that we exchange grids, we will have to exchange the outpouts of mapping_rectangle()
178  // and the inputs of mapping_.trapezoid() in the following...
179  grid_ = GridType( gridY, gridX, gridZ, fieldValues);
180  }
181 
182 
183 #ifdef DEBUG_GRID
184  dump();
185 #endif
186 }
187 
189 {
190 
191  cout << endl << "Dump of TrapezoidalCartesianMFGrid" << endl;
192 // cout << "Number of points from file "
193 // << n1 << " " << n2 << " " << n3 << endl;
194  cout << "Number of points from Grid1D "
195  << grid_.grida().nodes() << " " << grid_.gridb().nodes() << " " << grid_.gridc().nodes() << endl;
196 
197 // cout << "Reference Point from file "
198 // << xref << " " << yref << " " << zref << endl;
199  cout << "Reference Point from Grid1D "
200  << grid_.grida().lower() << " " << grid_.gridb().lower() << " " << grid_.gridc().lower() << endl;
201 
202 // cout << "Basic Distance from file "
203 // << stepx << " " << stepy << " " << stepz << endl;
204  cout << "Basic Distance from Grid1D "
205  << grid_.grida().step() << " " << grid_.gridb().step() << " " << grid_.gridc().step() << endl;
206 
207 
208  cout << "Dumping " << grid_.data().size() << " field values " << endl;
209  // grid_.dump();
210 
211 
212  // Dump ALL grid points and values
213  // CAVEAT: if convertToLocal = true in the ctor, points have been converted to LOCAL
214  // coordinates. To match those from .table files they have to be converted back to global
215 // for (int j=0; j < grid_.gridb().nodes(); j++) {
216 // for (int i=0; i < grid_.grida().nodes(); i++) {
217 // for (int k=0; k < grid_.gridc().nodes(); k++) {
218 // cout << i << " " << j << " " << k << " "
219 // << frame().toGlobal(LocalPoint(nodePosition(i,j,k))) << " "
220 // << nodeValue(i,j,k) << endl;
221 // }
222 // }
223 // }
224 
225 
226 }
227 
229 {
230 
231  double xrec, yrec;
232  mapping_.rectangle( p.x(), p.y(), xrec, yrec);
233 
234 
235 // cout << "TrapezoidalCartesianMFGrid::valueInTesla at local point " << p << endl;
236 // cout << p.x() << " " << p.y()
237 // << " transformed to grid frame: " << xrec << " " << yrec << endl;
238 
239  LinearGridInterpolator3D interpol( grid_);
240 
241  if (!increasingAlongX) {
242  std::swap(xrec,yrec);
243  // B values are already converted to local coord!!! otherwise we should:
244  // GridType::ValueType value = interpol.interpolate( xrec, yrec, p.z());
245  // return LocalVector(value.y(),value.x(),-value.z());
246  }
247 
248  return LocalVector(interpol.interpolate( xrec, yrec, p.z()));
249 }
250 
252  double& a, double& b, double& c) const
253 {
254  if (increasingAlongX) {
255  mapping_.rectangle( p.x(), p.y(), a, b);
256  } else {
257  mapping_.rectangle( p.x(), p.y(), b, a);
258  }
259 
260  c = p.z();
261 }
262 
264 {
265  double xtrap, ytrap;
266  if (increasingAlongX) {
267  mapping_.trapezoid( a, b, xtrap, ytrap);
268  } else {
269  mapping_.trapezoid( b, a, xtrap, ytrap);
270  }
271  return LocalPoint( xtrap, ytrap, c);
272 }
Scalar step() const
Definition: Grid1D.h:21
dbl * delta
Definition: mlp_gen.cc:36
const Grid1D & grida() const
Definition: Grid3D.h:67
void trapezoid(double xrec, double yrec, double &xtrap, double &ytrap) const
GloballyPositioned< float >::GlobalVector GlobalVector
Definition: MFGrid.h:33
GloballyPositioned< float >::LocalPoint LocalPoint
Definition: MFGrid.h:34
ReturnType interpolate(Scalar a, Scalar b, Scalar c)
void rectangle(double xtrap, double ytrap, double &xrec, double &yrec) const
int nodes() const
Definition: Grid1D.h:24
void swap(edm::DataFrameContainer &lhs, edm::DataFrameContainer &rhs)
LocalPoint toLocal(const GlobalPoint &gp) const
const Grid1D & gridc() const
Definition: Grid3D.h:69
Trapezoid2RectangleMappingX mapping_
const Container & data() const
Definition: Grid3D.h:71
GlobalPoint toGlobal(const LocalPoint &lp) const
Scalar lower() const
Definition: Grid1D.h:22
GridType grid_
Definition: MFGrid3D.h:62
Definition: Grid1D.h:7
virtual LocalPoint fromGridFrame(double a, double b, double c) const
find grid coordinates for point. For debugging and validation only.
GloballyPositioned< float >::GlobalPoint GlobalPoint
Definition: MFGrid.h:32
Grid3D GridType
Definition: MFGrid3D.h:59
Grid3D::BVector BVector
Definition: MFGrid3D.h:60
double b
Definition: hdecay.h:120
GloballyPositioned< float >::LocalVector LocalVector
Definition: MFGrid.h:35
virtual LocalVector uncheckedValueInTesla(const LocalPoint &p) const
Interpolated field value at given point; does not check for exceptions.
double a
Definition: hdecay.h:121
const GloballyPositioned< float > & frame() const
Local reference frame.
Definition: MFGrid.h:63
virtual void toGridFrame(const LocalPoint &p, double &a, double &b, double &c) const
find grid coordinates for point. For debugging and validation only.
TrapezoidalCartesianMFGrid(binary_ifstream &istr, const GloballyPositioned< float > &vol)
const Grid1D & gridb() const
Definition: Grid3D.h:68
Scalar upper() const
Definition: Grid1D.h:23