CMS 3D CMS Logo

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