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
void toGridFrame(const LocalPoint &p, double &a, double &b, double &c) const override
find grid coordinates for point. For debugging and validation only.
LocalPoint fromGridFrame(double a, double b, double c) const override
find grid coordinates for point. For debugging and validation only.
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
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
double a
Definition: hdecay.h:121
const GloballyPositioned< float > & frame() const
Local reference frame.
Definition: MFGrid.h:63
TrapezoidalCartesianMFGrid(binary_ifstream &istr, const GloballyPositioned< float > &vol)
LocalVector uncheckedValueInTesla(const LocalPoint &p) const override
Interpolated field value at given point; does not check for exceptions.
const Grid1D & gridb() const
Definition: Grid3D.h:68
Scalar upper() const
Definition: Grid1D.h:23