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