Jpp  15.0.1-rc.1-highqe
the software that should make you happy
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
JAlignDetector.cc
Go to the documentation of this file.
1 #include <string>
2 #include <iostream>
3 #include <iomanip>
4 #include <cmath>
5 #include <vector>
6 
7 #include "JMath/JMath.hh"
8 #include "JDetector/JDetector.hh"
11 #include "JDetector/JTripod.hh"
12 
13 #include "JFit/JSimplex.hh"
14 #include "JLang/JException.hh"
15 #include "JSupport/JMeta.hh"
16 #include "JTools/JRange.hh"
17 
18 #include "Jeep/JContainer.hh"
19 #include "Jeep/JParser.hh"
20 #include "Jeep/JMessage.hh"
21 
22 
23 namespace {
24 
25  using namespace JPP;
26 
27  typedef JRange<int> JRange_t;
28 
29 
30  /**
31  * Model for detector alignment.
32  *
33  * The model allows for a global offset of the detector position, a rotation around the z-axis and a tilt of the (x,y) plane.
34  */
35  struct JModel_t :
36  JMath<JModel_t>
37  {
38  /**
39  * Default constructor.
40  */
41  JModel_t() :
42  x (0.0),
43  y (0.0),
44  z (0.0),
45  phi(0.0),
46  tx (0.0),
47  ty (0.0)
48  {}
49 
50 
51  /**
52  * Constructor.
53  *
54  * \param x x
55  * \param y y
56  * \param z z
57  * \param phi phi
58  * \param tx Tx
59  * \param ty Ty
60  */
61  JModel_t(const double x,
62  const double y,
63  const double z,
64  const double phi,
65  const double tx,
66  const double ty) :
67  x (x),
68  y (y),
69  z (z),
70  phi(phi),
71  tx (tx),
72  ty (ty)
73  {}
74 
75 
76  /**
77  * Negate model.
78  *
79  * \return this model
80  */
81  JModel_t& negate()
82  {
83  x = -x;
84  y = -y;
85  z = -z;
86  phi = -phi;
87  tx = -tx;
88  ty = -ty;
89 
90  return *this;
91  }
92 
93 
94  /**
95  * Add model.
96  *
97  * \param model model
98  * \return this model
99  */
100  JModel_t& add(const JModel_t& model)
101  {
102  x += model.x;
103  y += model.y;
104  z += model.z;
105  phi += model.phi;
106  tx += model.tx;
107  ty += model.ty;
108 
109  return *this;
110  }
111 
112 
113  /**
114  * Subtract model.
115  *
116  * \param model model
117  * \return this model
118  */
119  JModel_t& sub(const JModel_t& model)
120  {
121  x -= model.x;
122  y -= model.y;
123  z -= model.z;
124  phi -= model.phi;
125  tx -= model.tx;
126  ty -= model.ty;
127 
128  return *this;
129  }
130 
131 
132  /**
133  * Scale model.
134  *
135  * \param factor multiplication factor
136  * \return this model
137  */
138  JModel_t& mul(const double factor)
139  {
140  x *= factor;
141  y *= factor;
142  z *= factor;
143  phi *= factor;
144  tx *= factor;
145  ty *= factor;
146 
147  return *this;
148  }
149 
150 
151  /**
152  * Scale model.
153  *
154  * \param factor division factor
155  * \return this model
156  */
157  JModel_t& div(const double factor)
158  {
159  x /= factor;
160  y /= factor;
161  z /= factor;
162  phi /= factor;
163  tx /= factor;
164  ty /= factor;
165 
166  return *this;
167  }
168 
169 
170  double x; //!< x-offset
171  double y; //!< y-offset
172  double z; //!< z-offset
173  double phi; //!< rotation around z-axis [rad]
174  double tx; //!< tilt angle [rad]
175  double ty; //!< tilt angle [rad]
176  };
177 
178 
179  /**
180  * Fit function.
181  */
182  class JFit_t :
183  public JModuleRouter
184  {
185  public:
186  /**
187  * Constructor.
188  *
189  * \param detector detector (reference)
190  * \param sigma_m resolution [m]
191  * \param option option to keep strings vertical
192  * \param range range of floors used in fit
193  */
194  JFit_t(const JDetector& detector,
195  const double sigma_m,
196  const bool option,
197  const JRange_t range) :
198  JModuleRouter(detector),
199  sigma(sigma_m),
200  option(option)
201  {
202  using namespace JPP;
203 
204  center = getAverage(make_array(detector.begin(), detector.end(), &JModule::getPosition));
205 
206  center.setPosition(JPosition3D(center.getX(), center.getY(), 0.0));
207  }
208 
209 
210  /**
211  * Get chi2.
212  *
213  * \param model model
214  * \param module module
215  * \return chi2
216  */
217  double operator()(const JModel_t& model, const JModule& module) const
218  {
219  if (this->hasModule(module.getID()) && range(module.getFloor())) {
220 
221  const JPosition3D p1 = this->getModule(module.getID()).getPosition();
222  const JPosition3D p2 = this->getPosition(model, module.getPosition());
223 
224  return p2.getDistanceSquared(p1) / (sigma*sigma);
225  }
226 
227  return 0.0;
228  }
229 
230 
231  /**
232  * Get position according model.
233  *
234  * \param model model
235  * \param pos position
236  * \return position
237  */
238  JPosition3D getPosition(const JModel_t& model, const JPosition3D& pos) const
239  {
240  using namespace std;
241  using namespace JPP;
242 
243  JPosition3D p1 = pos;
244 
245  p1 -= center;
246 
247  p1.rotate(JRotation3Z(model.phi));
248 
249  {
250  const double tx = model.tx;
251  const double tz = sqrt((1.0 + tx) * (1.0 - tx));
252 
253  if (!option)
254  p1 = JPosition3D(tz * p1.getX() + tx * p1.getZ(), p1.getY(), tz * p1.getZ() - tx * p1.getX());
255  else
256  p1 = JPosition3D(tz * p1.getX(), p1.getY(), p1.getZ() - tx * p1.getX());
257  }
258  {
259  const double ty = model.ty;
260  const double tz = sqrt((1.0 + ty) * (1.0 - ty));
261 
262  if (!option)
263  p1 = JPosition3D(p1.getX(), tz * p1.getY() + ty * p1.getZ(), tz * p1.getZ() - ty * p1.getY());
264  else
265  p1 = JPosition3D(p1.getX(), tz * p1.getY(), p1.getZ() - ty * p1.getY());
266  }
267 
268  p1 += JPosition3D(model.x, model.y, model.z);
269  p1 += center;
270 
271  return p1;
272  }
273 
274  double sigma;
275  bool option;
276  JRange_t range;
277  JPosition3D center;
278  };
279 }
280 
281 
282 /**
283  * \file
284  *
285  * Auxiliary program to align two detectors.\n
286  * \author mjongen
287  */
288 int main(int argc, char **argv)
289 {
290  using namespace std;
291  using namespace JPP;
292 
293  string detectorFile_a;
294  string detectorFile_b;
295  bool overwriteDetector;
296  string tripodFile;
297  double sigma_m;
298  bool option;
299  JRange_t range;
300  int debug;
301 
302  try {
303 
304  JParser<> zap("Auxiliary program to align two detectors.");
305 
306  zap['a'] = make_field(detectorFile_a, "detector - subject to alignment (option -A)");
307  zap['b'] = make_field(detectorFile_b, "detector - reference for alignment");
308  zap['A'] = make_field(overwriteDetector, "overwrite detector file provided through '-a' with modified positions.");
309  zap['T'] = make_field(tripodFile, "tripods") = "";
310  zap['s'] = make_field(sigma_m) = 0.2;
311  zap['O'] = make_field(option, "keep strings vertical");
312  zap['r'] = make_field(range, "range of floors used in fit") = JRange_t();
313  zap['d'] = make_field(debug) = 2;
314 
315  zap(argc, argv);
316  }
317  catch(const exception &error) {
318  FATAL(error.what() << endl);
319  }
320 
321 
322  if (overwriteDetector) {
323  if (tripodFile == "") {
324  FATAL("No tripod file.");
325  }
326  }
327 
328 
329  JDetector detector_a;
330  JDetector detector_b;
331 
332  try {
333  load(detectorFile_a, detector_a);
334  }
335  catch(const JException& error) {
336  FATAL(error);
337  }
338 
339  try {
340  load(detectorFile_b, detector_b);
341  }
342  catch(const JException& error) {
343  FATAL(error);
344  }
345 
346 
347  const JFit_t fit(detector_b, sigma_m, option, range);
348 
349  vector<JModule> data;
350 
351  for (JDetector::const_iterator module = detector_a.begin(); module != detector_a.end(); ++module) {
352  if (fit.hasModule(module->getID()) && module->getFloor() != 0) {
353  data.push_back(*module);
354  }
355  }
356 
357 
358  JSimplex<JModel_t> simplex;
359 
362 
363  simplex.value = JModel_t(0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
364 
365  simplex.step.resize(6);
366 
367  simplex.step[0] = JModel_t(0.01, 0.00, 0.00, 0.0, 0.0, 0.0);
368  simplex.step[1] = JModel_t(0.00, 0.01, 0.00, 0.0, 0.0, 0.0);
369  simplex.step[2] = JModel_t(0.00, 0.00, 0.01, 0.0, 0.0, 0.0);
370  simplex.step[3] = JModel_t(0.00, 0.00, 0.00, 5.0e-4, 0.0, 0.0);
371  simplex.step[4] = JModel_t(0.00, 0.00, 0.00, 0.0, 1.0e-4, 0.0);
372  simplex.step[5] = JModel_t(0.00, 0.00, 0.00, 0.0, 0.0, 1.0e-4);
373 
374  const double chi2 = simplex(fit, data.begin(), data.end());
375 
376  cout << "Number of iterations " << simplex.numberOfIterations << endl;
377  cout << "chi2/NDF " << FIXED(7,3) << chi2 << '/' << (detector_a.size() - simplex.step.size()) << endl;
378 
379  cout << "model:" << endl;
380 
381  cout << "x " << FIXED(7,3) << simplex.value.x << endl;
382  cout << "y " << FIXED(7,3) << simplex.value.y << endl;
383  cout << "z " << FIXED(7,3) << simplex.value.z << endl;
384  cout << "phi " << FIXED(9,5) << simplex.value.phi << endl;
385  cout << "Tx " << FIXED(9,5) << simplex.value.tx << endl;
386  cout << "Ty " << FIXED(9,5) << simplex.value.ty << endl;
387 
388 
389  if (overwriteDetector) {
390 
391  NOTICE("Store alignment data on files " << detectorFile_a << " and " << tripodFile << endl);
392 
393  detector_a.comment.add(JMeta(argc,argv));
394 
395  for (JDetector::iterator module = detector_a.begin(); module != detector_a.end(); ++module) {
396 
397  const JPosition3D p1 = module->getPosition();
398  const JPosition3D p2 = fit.getPosition(simplex.value, p1);
399 
400  module->add(p2 - p1);
401  }
402 
403  try {
404  store(detectorFile_a, detector_a);
405  }
406  catch(const JException& error) {
407  FATAL(error);
408  }
409 
410  JContainer< vector<JTripod> > tripods;
411 
412  tripods.load(tripodFile.c_str());
413 
414  tripods.comment.add(JMeta(argc,argv));
415 
416  for (vector<JTripod>::iterator tripod = tripods.begin(); tripod != tripods.end(); ++tripod) {
417 
418  const JPosition3D p1 = tripod->getUTMPosition() - detector_a.getUTMPosition();
419  const JPosition3D p2 = fit.getPosition(simplex.value, p1);
420 
421  tripod->add(p2 - p1);
422  }
423 
424  tripods.store(tripodFile.c_str());
425  }
426 }
Auxiliary class for ROOT I/O of application specific meta data.
Definition: JMeta.hh:70
Utility class to parse command line options.
Definition: JParser.hh:1500
JFit_t
Enumeration for fit algorithms.
Definition: JKatoomba.hh:44
General exception.
Definition: JException.hh:23
Exceptions.
int main(int argc, char *argv[])
Definition: Main.cc:15
Auxiliary base class for aritmetic operations of derived class types.
Definition: JMath.hh:110
TPaveText * p1
int getFloor() const
Get floor number.
Definition: JLocation.hh:145
JModel_t & negate()
Negate model.
Definition: JMath/JModel.hh:94
Data structure for a composite optical module.
Definition: JModule.hh:68
Detector data structure.
Definition: JDetector.hh:89
JModel_t & add(const JModel_t &model)
Add model.
Router for direct addressing of module data in detector data structure.
double getDistanceSquared(const JVector3D &pos) const
Get squared of distance to point.
Definition: JVector3D.hh:258
std::iterator_traits< T >::value_type getAverage(T __begin, T __end)
Get average.
Definition: JMath.hh:497
JModel_t & mul(const double factor)
Scale model.
Auxiliary data structure for floating point format specification.
Definition: JManip.hh:446
Data structure for detector geometry and calibration.
Rotation around Z-axis.
Definition: JRotation3D.hh:85
Detector file.
Definition: JHead.hh:196
Auxiliary wrapper for I/O of container with optional comment (see JComment).
Definition: JContainer.hh:39
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object
Definition: JParser.hh:1961
const array_type< JValue_t > & make_array(const JValue_t(&array)[N])
Method to create array of values.
Definition: JVectorize.hh:54
int getID() const
Get identifier.
Definition: JObjectID.hh:50
void store(const std::string &file_name, const JDetector &detector)
Store detector to output file.
ROOT I/O of application specific meta data.
JPosition3D getPosition(const Vec &pos)
Get position.
#define NOTICE(A)
Definition: JMessage.hh:64
double getY() const
Get y position.
Definition: JVector3D.hh:104
JModel_t & sub(const JModel_t &model)
Subtract model.
int debug
debug level
Definition: JSirene.cc:63
const JPosition3D & getPosition() const
Get position.
Definition: JPosition3D.hh:130
JModel_t value
Definition: JSimplex.hh:240
General purpose messaging.
#define FATAL(A)
Definition: JMessage.hh:67
void load(const char *file_name)
Load from input file.
Direct access to module in detector data structure.
z range($ZMAX-$ZMIN)< $MINIMAL_DZ." fi fi typeset -Z 4 STRING typeset -Z 2 FLOOR JPlot1D -f $
p2
Definition: module-Z:fit.sh:74
void load(const std::string &file_name, JDetector &detector)
Load detector from input file.
Auxiliary class to define a range between two values.
Simple fit method based on Powell&#39;s algorithm, see reference: Numerical Recipes in C++...
Definition: JSimplex.hh:42
Utility class to parse command line options.
void store(const char *file_name) const
Store to output file.
JComment comment
Definition: JContainer.hh:90
Fit model.
Definition: JMath/JModel.hh:29
double getX() const
Get x position.
Definition: JVector3D.hh:94
JModel_t & div(const double factor)
Scale model.
Base class for data structures with artithmetic capabilities.
Data structure for position in three dimensions.
Definition: JPosition3D.hh:36
JComment & add(const std::string &comment)
Add comment.
Definition: JComment.hh:100
Data structure for tripod.
JPosition3D & rotate(const JRotation3D &R)
Rotate.
Definition: JPosition3D.hh:186
double getZ() const
Get z position.
Definition: JVector3D.hh:115
Container I/O.
const JModule & getModule(const JDetector &detector, const JModuleLocation &location)
find module with a given string and floor number
JModule & add(const JVector3D &pos)
Add position.
Definition: JModule.hh:424