Jpp  17.3.0
the software that should make you happy
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
JDrawDetector2D.cc
Go to the documentation of this file.
1 #include <string>
2 #include <iostream>
3 #include <limits>
4 #include <vector>
5 #include <map>
6 #include <set>
7 
8 #include "TROOT.h"
9 #include "TH2D.h"
10 #include "TApplication.h"
11 #include "TGraph.h"
12 #include "TEllipse.h"
13 #include "TCanvas.h"
14 #include "TMarker.h"
15 #include "TText.h"
16 #include "TStyle.h"
17 #include "TLegend.h"
18 #include "TError.h"
19 
20 #include "JLang/JSinglePointer.hh"
21 #include "JROOT/JCanvas.hh"
22 #include "JROOT/JStyle.hh"
24 #include "JROOT/JLegend.hh"
25 #include "JDetector/JDetector.hh"
27 #include "JDetector/JTripod.hh"
30 #include "JGeometry2D/JCircle2D.hh"
31 
32 #include "Jeep/JeepToolkit.hh"
33 #include "Jeep/JContainer.hh"
34 #include "Jeep/JProperties.hh"
35 #include "Jeep/JParser.hh"
36 #include "Jeep/JMessage.hh"
37 
38 namespace {
39 
41 
42  /**
43  * Marker with text.
44  */
45  struct JPoint_t :
46  public JPosition2D
47  {
48  /**
49  * Constructor.
50  *
51  * \param title title
52  * \param pos position
53  * \param marker marker attributes
54  * \param text text attributes
55  * \param offset text ofset
56  */
57  JPoint_t(const std::string& title,
58  const JPosition2D& pos,
59  const TAttMarker& marker,
60  const TAttText& text,
61  const double offset) :
62  JPosition2D(pos),
63  offset(offset * cos(text.GetTextAngle()),
64  offset * sin(text.GetTextAngle()))
65  {
66  static_cast<TAttMarker&>(this->marker) = marker;
67  static_cast<TAttText&> (this->text) = text;
68 
69  this->text.SetTitle(title.c_str());
70  this->text.SetTextAngle(0.0); // overwrite text attributes
71  this->text.SetTextColor(marker.GetMarkerColor()); //
72  }
73 
74  /**
75  * Add offset.
76  *
77  * \param x x-position
78  * \param y y-position
79  */
80  void add(const double x, const double y)
81  {
82  static_cast<JPosition2D&>(*this).add(JPosition2D(x,y));
83 
84  configure();
85  }
86 
87  /**
88  * Subtract offset.
89  *
90  * \param x x-position
91  * \param y y-position
92  */
93  void sub(const double x, const double y)
94  {
95  static_cast<JPosition2D&>(*this).sub(JPosition2D(x,y));
96 
97  configure();
98  }
99 
100  /**
101  * Draw.
102  */
103  void Draw()
104  {
105  marker.Draw();
106  text .Draw();
107  }
108 
109  /**
110  * Configure.
111  */
112  void configure()
113  {
114  this->marker.SetX(this->getX());
115  this->marker.SetY(this->getY());
116  this->text .SetX(this->getX() + offset.getX());
117  this->text .SetY(this->getY() + offset.getY());
118  }
119 
120  TMarker marker;
121  TText text;
122 
123  private:
124  JPosition2D offset;
125  };
126 
127 
128  /**
129  * Container of markers.
130  */
131  struct JGraph_t :
132  public std::vector<JPoint_t>
133  {
134  /**
135  * Add offset.
136  *
137  * \param x x-position
138  * \param y y-position
139  */
140  void add(const double x, const double y)
141  {
142  for (iterator i = begin(); i != end(); ++i) {
143  i->add(x, y);
144  }
145  }
146 
147  /**
148  * Subtract offset.
149  *
150  * \param x x-position
151  * \param y y-position
152  */
153  void sub(const double x, const double y)
154  {
155  for (iterator i = begin(); i != end(); ++i) {
156  i->sub(x, y);
157  }
158  }
159 
160  /**
161  * Draw.
162  */
163  void Draw()
164  {
165  for (iterator i = begin(); i != end(); ++i) {
166  i->Draw();
167  }
168  }
169  };
170 }
171 
172 
173 /**
174  * \file
175  * Auxiliary program to draw the footprint of detector(s).
176  * \author mdejong
177  */
178 int main(int argc, char**argv)
179 {
180  using namespace std;
181  using namespace JPP;
182 
183  typedef JContainer< vector<JTripod> > tripods_container;
184  typedef JContainer< vector<JTransmitter> > transmitters_container;
185 
186  vector<string> detectorFile;
187  vector<string> tripodsFile;
188  vector<string> transmittersFile;
189  string outputFile;
190  JCanvas canvas;
191  JCircle2D focus;
192  string legend;
193  double markerSize;
194  double textSize;
195  bool drawCircle;
196  bool batch;
197  int debug;
198 
199  try {
200 
201  JProperties properties;
202 
203  properties["focus"] = focus;
204 
205  JParser<> zap("Auxiliary program to draw the footprint of detector(s).");
206 
207  zap['w'] = make_field(canvas, "size of canvas <nx>x<ny> [pixels]") = JCanvas(500, 500);
208  zap['@'] = make_field(properties, "properties") = JPARSER::initialised();
209  zap['a'] = make_field(detectorFile, "detector file") = JPARSER::initialised();
210  zap['T'] = make_field(tripodsFile, "tripod file") = JPARSER::initialised();
211  zap['Y'] = make_field(transmittersFile, "transmitter file") = JPARSER::initialised();
212  zap['o'] = make_field(outputFile, "graphics output") = "";
213  zap['L'] = make_field(legend, "position legend e.g. TR") = "", "TL", "TR", "BR", "BL";
214  zap['S'] = make_field(markerSize, "marker size") = 1.0;
215  zap['s'] = make_field(textSize, "text size") = 0.02;
216  zap['C'] = make_field(drawCircle, "draw smallest enclosing cicrle");
217  zap['B'] = make_field(batch, "batch processing");
218  zap['d'] = make_field(debug) = 1;
219 
220  zap(argc, argv);
221  }
222  catch(const exception &error) {
223  FATAL(error.what() << endl);
224  }
225 
226 
227  if (detectorFile.empty() && tripodsFile.empty()) {
228  FATAL("No detector elements." << endl);
229  }
230 
231 
232  gROOT->SetBatch(batch);
233 
234  gErrorIgnoreLevel = kWarning;
235 
236  TApplication* tp = new TApplication("user", NULL, NULL);
237  TCanvas* cv = new TCanvas("detector", "", canvas.x, canvas.y);
238 
239  JSinglePointer<TStyle> gStyle(new JStyle("gplot", cv->GetWw(), cv->GetWh()));
240 
241  gROOT->SetStyle("gplot");
242  gROOT->ForceStyle();
243 
244  cv->SetFillStyle(4000);
245  cv->SetFillColor(kWhite);
246  cv->Divide(1, 1);
247  cv->cd(1);
248 
249  JMarkerAttributes::getInstance().setMarkerSize(markerSize);
250 
251  vector<TAttText> text_attributes = {
252  TAttText(kHAlignLeft + kVAlignBottom, 0.25*PI, kBlack, 62, textSize),
253  TAttText(kHAlignRight + kVAlignBottom, 0.75*PI, kBlack, 62, textSize),
254  TAttText(kHAlignRight + kVAlignTop, 1.25*PI, kBlack, 62, textSize),
255  TAttText(kHAlignLeft + kVAlignTop, 1.75*PI, kBlack, 62, textSize)
256  };
257 
258  map<string, JGraph_t> data; // graphics data
259  JUTMPosition position; // UTM position
260  double offset = 0.0; // text offset
261 
262  for (size_t i = 0; i != detectorFile.size(); ++i) {
263 
265 
266  try {
267  load(detectorFile[i], detector);
268  }
269  catch(const JException& error) {
270  FATAL(error);
271  }
272 
273  position = detector.getUTMPosition();
274 
275  const TAttMarker& marker = *JMarkerAttributes::getInstance().next();
276  const TAttText& text = text_attributes[(0+i)%text_attributes.size()];
277  vector<JPoint_t>& buffer = data[getFilename(detectorFile[i])];
278 
279  if (offset == 0.0) {
280  offset = 3.0 * textSize * JCircle2D(detector.begin(), detector.end()).getRadius();
281  }
282 
283  set<int> counter;
284 
285  for (JDetector::const_iterator module = detector.begin(); module != detector.end(); ++module) {
286 
287  if (counter.count(module->getString()) == 0) {
288 
289  buffer.push_back(JPoint_t(MAKE_STRING(module->getString()),
290  JPosition2D(module->getX(), module->getY()),
291  marker,
292  text,
293  offset));
294 
295  counter.insert(module->getString());
296  }
297  }
298  }
299 
300  for (size_t i = 0; i != tripodsFile.size(); ++i) {
301 
302  tripods_container tripods;
303 
304  tripods.load(tripodsFile[i].c_str());
305 
306  const TAttMarker& marker = *JMarkerAttributes::getInstance().next();
307  const TAttText& text = text_attributes[(0+i)%text_attributes.size()];
308  vector<JPoint_t>& buffer = data[getFilename(tripodsFile[i])];
309 
310  if (offset == 0.0) {
311  offset = 3.0 * textSize * JCircle2D(tripods.begin(), tripods.end()).getRadius();
312  }
313 
314  for (tripods_container::iterator i = tripods.begin(); i != tripods.end(); ++i) {
315 
316  buffer.push_back(JPoint_t(MAKE_STRING(i->getID()),
317  JPosition2D(i->getUTMEast() - position.getUTMEast(), i->getUTMNorth() - position.getUTMNorth()),
318  marker,
319  text,
320  offset));
321  }
322  }
323 
324  if (!transmittersFile.empty()) {
325 
326  if (transmittersFile.size() == detectorFile.size()) {
327 
328  for (size_t i = 0; i != transmittersFile.size(); ++i) {
329 
330  transmitters_container transmitters;
331 
332  transmitters.load(transmittersFile[i].c_str());
333 
335 
336  load(detectorFile[i], detector);
337 
338  const TAttMarker& marker = *JMarkerAttributes::getInstance().next();
339  const TAttText& text = text_attributes[(2+i)%text_attributes.size()];
340  vector<JPoint_t>& buffer = data[getFilename(transmittersFile[i])];
341 
342  if (offset == 0.0) {
343  offset = 3.0 * textSize * JCircle2D(transmitters.begin(), transmitters.end()).getRadius();
344  }
345 
346  for (transmitters_container::iterator i = transmitters.begin(); i != transmitters.end(); ++i) {
347 
348  const JPosition3D pos = detector.getModule(i->getLocation()).getPosition();
349 
350  buffer.push_back(JPoint_t(MAKE_STRING(i->getID()),
351  JPosition2D(pos.getX() + i->getX(), pos.getY() + i->getY()),
352  marker,
353  text,
354  offset));
355  }
356  }
357 
358  } else {
359 
360  FATAL("Tranmitter files and detector files should match one-to-one." << endl);
361  }
362  }
363 
364  vector<JPosition2D> buffer;
365 
366  for (map<string, JGraph_t>::iterator i = data.begin(); i != data.end(); ++i) {
367  copy(i->second.begin(), i->second.end(), back_inserter(buffer));
368  }
369 
370  JCircle2D circle(buffer.begin(), buffer.end()); // enclosing circle
371 
372  if (focus.getRadius() > 0.0) {
373  circle = focus;
374  }
375 
376  NOTICE("focus = " << FIXED(12,3) << circle.getX() << ' ' << FIXED(12,3) << circle.getY() << ' ' << FIXED(9,3) << circle.getRadius() << endl);
377 
378  // center
379 
380  for (map<string, JGraph_t>::iterator i = data.begin(); i != data.end(); ++i) {
381  i->second.sub(circle.getX(), circle.getY());
382  }
383 
384  circle.sub(circle.getPosition());
385 
386 
387  // draw
388 
389  cv->cd(1);
390 
391  const Double_t xmin = circle.getX() - 1.15 * circle.getRadius();
392  const Double_t xmax = circle.getX() + 1.15 * circle.getRadius();
393  const Double_t ymin = circle.getY() - 1.15 * circle.getRadius();
394  const Double_t ymax = circle.getY() + 1.15 * circle.getRadius();
395 
396  TH2D h2("h2", "", 1, xmin, xmax, 1, ymin, ymax);
397 
398  h2.GetXaxis()->SetTitle("x [m]");
399  h2.GetYaxis()->SetTitle("y [m]");
400 
401  h2.GetXaxis()->CenterTitle(true);
402  h2.GetYaxis()->CenterTitle(true);
403 
404  h2.SetStats(kFALSE);
405  h2.Draw("AXIS");
406 
407 
408  TEllipse ellipse(circle.getX(), circle.getY(), circle.getRadius());
409 
410  if (drawCircle) {
411  ellipse.Draw();
412  }
413 
414  for (map<string, JGraph_t>::iterator i = data.begin(); i != data.end(); ++i) {
415  i->second.Draw();
416  }
417 
418  if (legend != "") {
419 
420  Ssiz_t height = data.size();
421  Ssiz_t width = 1;
422 
423  for (map<string, JGraph_t>::const_iterator i = data.begin(); i != data.end(); ++i) {
424  width = max(width, (Ssiz_t) i->first.size());
425  }
426 
427  TLegend* lg = getLegend(width, height, legend);
428 
429  lg->SetTextSize(textSize);
430 
431  for (map<string, JGraph_t>::const_iterator i = data.begin(); i != data.end(); ++i) {
432  if (!i->second.empty()) {
433  lg->AddEntry(&i->second[0].marker, i->first.c_str(), "P");
434  }
435  }
436 
437  lg->Draw();
438  }
439 
440  cv->Update();
441 
442  if (outputFile != "") {
443  cv->SaveAs(outputFile.c_str());
444  }
445 
446  if (!batch) {
447  tp->Run();
448  }
449 }
const double xmax
Definition: JQuadrature.cc:24
Utility class to parse command line options.
Definition: JParser.hh:1517
General exception.
Definition: JException.hh:23
int main(int argc, char *argv[])
Definition: Main.cc:15
JPosition2D()
Default constructor.
Definition: JPosition2D.hh:44
char text[TEXT_SIZE]
Definition: elog.cc:72
const JUTMPosition & getUTMPosition() const
Get UTM position.
Definition: JUTMPosition.hh:84
Data structure for circle in two dimensions.
Definition: JCircle2D.hh:33
Data structure for graph data.
Definition: JGraph.hh:21
Detector data structure.
Definition: JDetector.hh:89
Utility class to parse parameter values.
Definition: JProperties.hh:496
then fatal Number of tripods
Definition: JFootprint.sh:45
Empty structure for specification of parser element that is initialised (i.e. does not require input)...
Definition: JParser.hh:83
Auxiliary data structure for floating point format specification.
Definition: JManip.hh:446
string outputFile
double getY() const
Get y position.
Definition: JVector2D.hh:74
Data structure for detector geometry and calibration.
Data structure for UTM position.
Definition: JUTMPosition.hh:36
Utility class to parse parameter values.
#define MAKE_STRING(A)
Make string.
Definition: JPrint.hh:127
JVector2D & sub(const JVector2D &vector)
Subtract vector.
Definition: JVector2D.hh:115
then usage set_variable ACOUSTICS_WORKDIR $WORKDIR set_variable FORMULA sin([0]+2 *$PI *([1]+[2]*x)*x)" set_variable DY 1.0e-8 mkdir $WORKDIR for DETECTOR in $DETECTORS[*]
The template JSinglePointer class can be used to hold a pointer to an object.
Data structure for transmitter.
T & getInstance(const T &object)
Get static instance from temporary object.
Definition: JObject.hh:75
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:1993
Auxiliary methods for handling file names, type names and environment.
double getX() const
Get x position.
Definition: JVector2D.hh:63
TLegend * getLegend(const Int_t width, const Int_t height, const std::string option, const Double_t factor=1.0)
Get legend.
Definition: JLegend.hh:29
JPosition3D getPosition(const Vec &pos)
Get position.
#define NOTICE(A)
Definition: JMessage.hh:64
then awk string
static const double PI
Mathematical constants.
double getY() const
Get y position.
Definition: JVector3D.hh:104
General purpose messaging.
#define FATAL(A)
Definition: JMessage.hh:67
const JModule & getModule(const JModuleAddress &address) const
Get module parameters.
Definition: JDetector.hh:270
const double xmin
Definition: JQuadrature.cc:23
Data structure for position in two dimensions.
Definition: JPosition2D.hh:31
void configure(const T &value, const JAbstractCollection< JAbscissa_t > &bounds, JBool< false > option)
Configuration of value.
void load(const std::string &file_name, JDetector &detector)
Load detector from input file.
JVector2D & add(const JVector2D &vector)
Add vector.
Definition: JVector2D.hh:100
Utility class to parse command line options.
double getX() const
Get x position.
Definition: JVector3D.hh:94
void copy(const Head &from, JHead &to)
Copy header from from to to.
Definition: JHead.cc:162
std::string getFilename(const std::string &file_name)
Get file name part, i.e. part after last JEEP::PATHNAME_SEPARATOR if any.
Definition: JeepToolkit.hh:128
Data structure for position in three dimensions.
Definition: JPosition3D.hh:36
do set_variable DETECTOR_TXT $WORKDIR detector
Data structure for tripod.
Wrapper class around ROOT TStyle.
Definition: JStyle.hh:20
Container I/O.
int debug
debug level
Data structure for size of TCanvas.
Definition: JCanvas.hh:26