CbmRoot
CbmRichRonchiAna.cxx
Go to the documentation of this file.
1 #include "CbmRichRonchiAna.h"
2 
3 #include <boost/gil/extension/io/tiff.hpp>
4 #include <boost/gil/gil_all.hpp>
5 //#include <boost/gil/extension/io/tiff_dynamic_io.hpp>
6 
7 
8 #include "CbmDrawHist.h"
9 #include "TCanvas.h"
10 #include "TEllipse.h"
11 #include "TGeoArb8.h"
12 #include "TGeoManager.h"
13 #include "TH2D.h"
14 #include "TH3D.h"
15 #include "TLine.h"
16 #include "TVector3.h"
17 #include <iostream>
18 #include <math.h>
19 #include <set>
20 
21 using namespace boost::gil;
22 using namespace std;
23 
24 // For Ubuntu one needs dev version of libtiff
25 // sudo apt-get install libtiff-dev
26 
28  : // constructor
29 
30  // constant values
31  fPi(3.141592654)
32  , fRadiusMirror(3000000)
33  , // in microns !!! MIGHT HAVE TO BE CHANGED TO DISTANCE_MIRROR-POINTSOURCE IF IT IS NOT IN THE CENTER OF CURVATURE
34  fEdgeLengthCCD(13300)
35  , // in microns
36  fCcdPixelSize(13)
37  , // in microns
38  fPitchGrid(200)
39  , // in microns
40  fImageWidth(1024)
41  , // in pixels
42 
43  // values to be measured first
44  fDistRulingCCD(21200)
45  , // in microns
46  fDistMirrorCCD(3118500)
47  , // in microns
48  fDistMirrorRuling(fDistMirrorCCD - fDistRulingCCD)
49  , // in microns
50  fOffsetCCDOptAxisX(0)
51  , //(7500), // in microns
52  fOffsetCCDOptAxisY(-58000)
53  , // in microns
54  fOffsetLEDOpticalAxisX(0)
55  , //(14500), //(13000), // in microns
56  fOffsetLEDOpticalAxisY(57000)
57  , // in microns
58  fCenterCcdX(0)
59  , // in pixels
60  fCenterCcdY(0) // in pixels
61 {}
62 
64 
66  // Initialization
67  vector<vector<double>> dataV;
68  vector<vector<double>> dataH;
69 
70  if (fTiffFileNameV == "" || fTiffFileNameH == "") {
71  Fatal("CbmRichRonchiAna::Run:", "No FileNameV or FileNameH!");
72  } else {
73  cout << "FileNameV: " << fTiffFileNameV << endl
74  << "FileNameH: " << fTiffFileNameH << endl;
77  }
78 
79  int width = dataV.size();
80  int height = dataV[0].size();
81 
82 
84  // initialisierung der histogramme: name, groesse usw
85  TH2D* hInitH = new TH2D("hInitH",
86  "hInitH;X [pixel];Y [pixel];Intensity",
87  width,
88  -.5,
89  width - 0.5,
90  height,
91  -0.5,
92  height - 0.5);
93  TH2D* hMeanIntensityH =
94  new TH2D("hMeanIntensityH",
95  "hMeanIntensityH;X [pixel];Y [pixel];Intensity",
96  width,
97  -.5,
98  width - 0.5,
99  height,
100  -0.5,
101  height - 0.5);
102  TH2D* hPeakH = new TH2D("hPeakH",
103  "hPeakH;X [pixel];Y [pixel];Intensity",
104  width,
105  -.5,
106  width - 0.5,
107  height,
108  -0.5,
109  height - 0.5);
110  TH2D* hSmoothLinesH = new TH2D("hSmoothLinesH",
111  "hSmoothLinesH;X [pixel];Y [pixel];Intensity",
112  width,
113  -.5,
114  width - 0.5,
115  height,
116  -0.5,
117  height - 0.5);
118  TH2D* hLineSearchH = new TH2D("hLineSearchH",
119  "hLineSearchH;X [pixel];Y [pixel];Intensity",
120  width,
121  -.5,
122  width - 0.5,
123  height,
124  -0.5,
125  height - 0.5);
126 
127  TH2D* hInitV = new TH2D("hInitV",
128  "hInitV;X [pixel];Y [pixel];Intensity",
129  width,
130  -.5,
131  width - 0.5,
132  height,
133  -0.5,
134  height - 0.5);
135  TH2D* hMeanIntensityV =
136  new TH2D("hMeanIntensityV",
137  "hMeanIntensityV;X [pixel];Y [pixel];Intensity",
138  width,
139  -.5,
140  width - 0.5,
141  height,
142  -0.5,
143  height - 0.5);
144  TH2D* hPeakV = new TH2D("hPeakV",
145  "hPeakV;X [pixel];Y [pixel];Intensity",
146  width,
147  -.5,
148  width - 0.5,
149  height,
150  -0.5,
151  height - 0.5);
152  TH2D* hSmoothLinesV = new TH2D("hSmoothLinesV",
153  "hSmoothLinesV;X [pixel];Y [pixel];Intensity",
154  width,
155  -.5,
156  width - 0.5,
157  height,
158  -0.5,
159  height - 0.5);
160  TH2D* hLineSearchV = new TH2D("hLineSearchV",
161  "hLineSearchV;X [pixel];Y [pixel];Intensity",
162  width,
163  -.5,
164  width - 0.5,
165  height,
166  -0.5,
167  height - 0.5);
168 
169  TH2D* hSuperpose = new TH2D("hSuperpose",
170  "hSuperpose;X [pixel];Y [pixel];Intensity",
171  width,
172  -.5,
173  width - 0.5,
174  height,
175  -0.5,
176  height - 0.5);
177 
178  // vertical image
179  DoRotation(dataV);
180  FillH2WithVector(hInitV, dataV);
181  DoMeanIntensityY(dataV);
182  FillH2WithVector(hMeanIntensityV, dataV);
183  DoPeakFinderY(dataV);
184  FillH2WithVector(hPeakV, dataV);
185  DoSmoothLines(dataV);
186  FillH2WithVector(hSmoothLinesV, dataV);
187  DoLineSearch(dataV);
188  FillH2WithVector(hLineSearchV, dataV);
189  DoRotation(dataV);
190 
191 
192  // horizontal image
193  FillH2WithVector(hInitH, dataH);
194  DoMeanIntensityY(dataH);
195  FillH2WithVector(hMeanIntensityH, dataH);
196  DoPeakFinderY(dataH);
197  FillH2WithVector(hPeakH, dataH);
198  DoSmoothLines(dataH);
199  FillH2WithVector(hSmoothLinesH, dataH);
200  DoLineSearch(dataH);
201  FillH2WithVector(hLineSearchH, dataH);
202 
203  // finding intersections
204  vector<CbmRichRonchiIntersectionData> intersections =
205  DoIntersection(dataH, dataV);
206  vector<vector<double>> dataSup = DoSuperpose(dataH, dataV);
207  FillH2WithVector(hSuperpose, dataSup);
208 
209  DoOrderLines(intersections, "x");
210  DoOrderLines(intersections, "y");
211 
212  DoLocalNormal(intersections);
213  DoSphere(intersections);
214 
215  // DrawGeomanager();
216 
217  DoDeviation(intersections);
218 
219  {
220  TCanvas* c =
221  new TCanvas("ronchi_2d_horizontal", "ronchi_2d_horizontal", 1500, 1000);
222  c->Divide(3, 2);
223  c->cd(1);
224  DrawH2(hInitH);
225  c->cd(2);
226  DrawH2(hMeanIntensityH);
227  c->cd(3);
228  DrawH2(hPeakH);
229  c->cd(4);
230  DrawH2(hSmoothLinesH);
231  c->cd(5);
232  DrawH2(hLineSearchH);
233  }
234 
235  {
236  TCanvas* c =
237  new TCanvas("ronchi_2d_vertical", "ronchi_2d_vertical", 1500, 1000);
238  c->Divide(3, 2);
239  c->cd(1);
240  DrawH2(hInitV);
241  c->cd(2);
242  DrawH2(hMeanIntensityV);
243  c->cd(3);
244  DrawH2(hPeakV);
245  c->cd(4);
246  DrawH2(hSmoothLinesV);
247  c->cd(5);
248  DrawH2(hLineSearchV);
249  }
250 
251  {
252  TCanvas* c2 = new TCanvas(
253  "ronchi_1d_slices_horizontal", "ronchi_1d_slices_horizontal", 1200, 600);
254  c2->Divide(2, 1);
255 
256  TH1D* h1 = hInitH->ProjectionY("_py2", 250, 250);
257  TH1D* h2 = hInitH->ProjectionY("_py3", 300, 300);
258  TH1D* hM1 = hMeanIntensityH->ProjectionY("_pyM1", 250, 250);
259  TH1D* hM2 = hMeanIntensityH->ProjectionY("_pyM2", 300, 300);
260  TH1D* hP1 = hPeakH->ProjectionY("_pyP1", 250, 250);
261  TH1D* hP2 = hPeakH->ProjectionY("_pyP2", 300, 300);
262  c2->cd(1);
263  DrawH1({h1, hM1, hP1}, {"Init", "Mean", "Peak"});
264  c2->cd(2);
265  DrawH1({h2, hM2, hP2}, {"Init", "Mean", "Peak"});
266  }
267 
268 
269  {
270  TCanvas* c = new TCanvas(
271  "ronchi_2d_intersection", "ronchi_2d_intersection", 1000, 1000);
272  DrawH2(hSuperpose);
273  for (size_t i = 0; i < intersections.size(); i++) {
274  TEllipse* center =
275  new TEllipse(intersections[i].fPixelX, intersections[i].fPixelY, 5);
276  center->Draw();
277  }
278  }
279 
280  vector<int> colors = {kBlack,
281  kGreen,
282  kBlue,
283  kRed,
284  kYellow,
285  kOrange,
286  kCyan,
287  kGray,
288  kMagenta,
289  kYellow + 2,
290  kRed + 3};
291  {
292  TCanvas* c = new TCanvas(
293  "ronchi_2d_intersection_x", "ronchi_2d_intersection_x", 1000, 1000);
294  DrawH2(hSuperpose);
295  for (size_t i = 0; i < intersections.size(); i++) {
296  TEllipse* center =
297  new TEllipse(intersections[i].fPixelX, intersections[i].fPixelY, 5);
298  center->SetFillColor(
299  colors[intersections[i].fOrderedLineX % colors.size()]);
300  center->Draw();
301  }
302  }
303 
304  {
305  TCanvas* c = new TCanvas(
306  "ronchi_2d_intersection_y", "ronchi_2d_intersection_y", 1000, 1000);
307  DrawH2(hSuperpose);
308  for (size_t i = 0; i < intersections.size(); i++) {
309  TEllipse* center =
310  new TEllipse(intersections[i].fPixelX, intersections[i].fPixelY, 5);
311  center->SetFillColor(
312  colors[intersections[i].fOrderedLineY % colors.size()]);
313  center->Draw();
314  }
315  }
316 }
317 
318 vector<vector<double>> CbmRichRonchiAna::ReadTiffFile(const string& fileName) {
319  cout << "ReadTiffFile:" << fileName << endl;
320  vector<vector<double>> data;
321  //rgba8_image_t img;
322  rgb16_image_t img;
323  read_and_convert_image(fileName, img, boost::gil::tiff_tag());
324  // tiff_read_and_convert_image(fileName, img);
325  int height = img.height();
326  int width = img.width();
327 
328  data.resize(width);
329 
330  auto view = const_view(img);
331  for (int x = 0; x < width; ++x) {
332  auto it = view.col_begin(x);
333  data[x].resize(height);
334  for (int y = 0; y < height; ++y) {
335  int r = boost::gil::at_c<0>(it[y]);
336  //int g = boost::gil::at_c<1>(it[y]);
337  //int b = boost::gil::at_c<2>(it[y]);
338  //int a = boost::gil::at_c<3>(it[y]);
339  data[x][y] = r;
340  }
341  }
342  return data;
343 }
344 
345 // rotating the image (actually flipping diagonally arranged corners)
346 void CbmRichRonchiAna::DoRotation(vector<vector<double>>& data) {
347  int nX = data.size();
348  int nY = data[0].size();
349  for (int x = 0; x < nX; x++) {
350  for (int y = x + 1; y < nY; y++) {
351  swap(data[x][y], data[y][x]);
352  }
353  }
354 }
355 
356 // drawing histogram
358  const vector<vector<double>>& data) {
359  int nX = data.size();
360  int nY = data[0].size();
361 
362  for (int x = 0; x < nX; x++) {
363  for (int y = 0; y < nY; y++) {
364  if (data[x][y] != 0) { hist->SetBinContent(x, y, data[x][y]); }
365  }
366  }
367 }
368 
369 // averaging intensity with neighboured values
370 void CbmRichRonchiAna::DoMeanIntensityY(vector<vector<double>>& data) {
371  int nX = data.size();
372  int nY = data[0].size();
373 
374  int halfAvWindow =
375  5; // number of neighbour pixels to each side to average over
376  double threshold =
377  6500; // threshold for average intensity to delete areas that are too dark (and so don't belong to mirror image)
378  vector<double> weightsX = {
379  1.,
380  0.75,
381  0.4,
382  0.2,
383  0.08,
384  0.04}; // weightings in dependence of distance of current pixel
385  vector<double> weightsY = {1., 0.75, 0.4, 0.2, 0.08, 0.04};
386 
387  vector<vector<double>> dataNew(nX, std::vector<double>(nY, 0.));
388 
389  for (int x = 0; x < nX; x++) {
390  for (int y = 0; y < nY; y++) {
391  double total = 0.;
392  double weightSum = 0.;
393  for (
394  int xW = -halfAvWindow; xW <= halfAvWindow;
395  xW++) { // scanning window around current pixel to calculate average intensity
396  for (int yW = -halfAvWindow; yW <= halfAvWindow; yW++) {
397 
398  int xWAbs = std::abs(xW);
399  int yWAbs = std::abs(yW);
400 
401  double weightX =
402  (xWAbs < (int) weightsX.size())
403  ? weightsX[xWAbs]
404  : weightsX
405  [weightsX.size()
406  - 1]; // if corresponding pixel is farther away than number of weights, take smallest ...
407  double weightY =
408  (yWAbs < (int) weightsY.size())
409  ? weightsY[yWAbs]
410  : weightsY[weightsY.size() - 1]; // ... weight value
411 
412  double weight = weightX * weightY;
413  weightSum += weight;
414  int indX = x + xW;
415  if (indX < 0)
416  indX = 0; // preventing counting not existing pixels (beyond image)
417  if (indX >= nX) indX = nX - 1;
418  int indY = y + yW;
419  if (indY < 0) indY = 0;
420  if (indY >= nY) indY = nY - 1;
421 
422  total += data[indX][indY] * weight;
423  }
424  }
425 
426  dataNew[x][y] = total / weightSum; // averaged intensity
427  if (dataNew[x][y] <= threshold)
428  dataNew[x][y] =
429  0.; // deleting pixels that are too dark; to yield only data for mirror and not background
430  }
431  }
432  data = dataNew;
433 }
434 
435 // getting a one dimensional line
436 void CbmRichRonchiAna::DoPeakFinderY(vector<vector<double>>& data) {
437  int nX = data.size();
438  int nY = data[0].size();
439  int halfWindow = 5;
440  int samePeakCounterCut = 5;
441 
442  vector<vector<double>> dataNew(nX, std::vector<double>(nY, 0.));
443 
444  for (int x = 0; x < nX; x++) {
445  for (int y = halfWindow; y < nY - halfWindow; y++) {
446  bool isPeak =
447  (data[x][y] > 0. && data[x][y] >= data[x][y - 1])
448  && (data[x][y] >= data
449  [x]
450  [y
451  + 1]); // comparing current pixel with direct neighbours in y direction
452  if (!isPeak) continue;
453 
454  // check if it is a plateau
455  int samePeakCounter = 0;
456  for (int yS = y; yS < nY; yS++) {
457  if (data[x][y] == data[x][yS]) {
458  samePeakCounter++;
459  } else {
460  break;
461  }
462  }
463  if (samePeakCounter
464  >= samePeakCounterCut) { // if plateau, then jump beyond it
465  y = y + samePeakCounter + 1;
466  continue;
467  }
468 
469  bool isBiggest = true;
470  for (int iW = -halfWindow; iW <= halfWindow;
471  iW++) { // comparing current pixel with 'halfWindow' next neighbours
472  if (iW == 0) continue;
473  if (data[x][y + iW] > data[x][y]) {
474  isBiggest = false;
475  break;
476  }
477  }
478  bool hasNeighbourPeak =
479  (dataNew[x][y - 2] > 0. || dataNew[x][y - 1] > 0.
480  || dataNew[x][y + 1] > 0. || dataNew[x][y + 2] > 0.);
481 
482  if (isBiggest && isPeak && !hasNeighbourPeak)
483  dataNew[x][y] = data
484  [x]
485  [y]; // set value if is the biggest of 'halfWindow' neighbours and has no neighboured peak
486  }
487  }
488  data = dataNew;
489 }
490 
491 // smoothing lines by calculating mean position in y
492 void CbmRichRonchiAna::DoSmoothLines(vector<vector<double>>& data) {
493  int meanHalfLength = 8;
494  int meanHalfHeight = 3;
495  int nX = data.size();
496  int nY = data[0].size();
497 
498  vector<vector<double>> dataNew(nX, std::vector<double>(nY, 0.));
499 
500  for (int x = meanHalfLength; x < nX - meanHalfLength;
501  x++) { // scanning whole image (except small border)
502  for (int y = meanHalfHeight; y < nY - meanHalfHeight; y++) {
503  if (data[x][y] == 0.) continue;
504  double sumY = 0.;
505  int counter = 0;
506  for (
507  int x2 = -meanHalfLength; x2 <= meanHalfLength;
508  x2++) { // scanning small window around current pixel and summing up positions in y of current and neighboured pixels
509  for (int y2 = -meanHalfHeight; y2 <= meanHalfHeight; y2++) {
510  if (data[x + x2][y + y2] > 0) {
511  sumY += y + y2;
512  counter++;
513  }
514  }
515  }
516  int newY = (int) sumY / counter; // average y-value of pixel
517  dataNew[x][newY] = data[x][y];
518  }
519  }
520 
521  data = dataNew;
522 }
523 
524 void CbmRichRonchiAna::DoLineSearch(vector<vector<double>>& data) {
525  int nX = data.size();
526  int nY = data[0].size();
527 
528  int missingCounterCut = 15;
529  int missingCounterTotalCut = 25;
530  int halfWindowY = 2;
531 
532  vector<vector<double>> dataNew(nX, std::vector<double>(nY, 0.));
533  double curIndex = 0.; // why double?
534 
535  for (int x = 0; x < nX; x++) { // scanning whole image
536  for (int y = 0; y < nY; y++) {
537  if (data[x][y] > 0.
538  && dataNew[x][y]
539  == 0.) { // if this line pixel is not filled yet in 'dataNew'
540  curIndex++; // line index
541  dataNew[x][y] = curIndex; // found line is indexed
542  int missingCounterTotal = 0.;
543  int missingCounter = 0.;
544  int curY = y;
545  for (
546  int x1 = x + 1; x1 < nX;
547  x1++) { // drawing line in x; values are not intensity but line index
548  bool isFound = false;
549  for (int y1 = -halfWindowY; y1 <= halfWindowY; y1++) {
550  if (data[x1][curY + y1] > 0.
551  && dataNew[x1][curY + y1]
552  == 0.) { // if pixel of line in next column is found ...
553  dataNew[x1][curY + y1] =
554  curIndex; // ... fill current pixel with line index
555  curY += y1;
556  isFound = true;
557  break;
558  }
559  }
560  if (
561  !isFound) { // to prevent indexing lines with wrong index (e.g. if gap is too big and next found line would not be continuation of current line)
562  missingCounterTotal++;
563  missingCounter++;
564  } else {
565  missingCounter = 0;
566  }
567  if (missingCounterTotal >= missingCounterTotalCut
568  || missingCounter >= missingCounterCut)
569  break;
570  }
571  }
572  }
573  }
574  cout << "curIndex:" << curIndex << endl;
575  data = dataNew;
576 }
577 
578 
579 // finding intersections
580 vector<CbmRichRonchiIntersectionData>
581 CbmRichRonchiAna::DoIntersection(vector<vector<double>>& dataH,
582  const vector<vector<double>>& dataV) {
583  int nX = dataV.size();
584  int nY = dataV[0].size();
585 
586  vector<CbmRichRonchiIntersectionData> intersections;
587 
588  for (int x = 0; x < nX; x++) {
589  for (int y = 0; y < nY; y++) {
590  if (
591  dataH[x][y] > 0.
592  && dataV[x][y]
593  > 0.) { // filling vector with data if both vertical and horizontal image have data greater ZERO here
595  data.fPixelX = x;
596  data.fPixelY = y;
597  data.fLineY = dataH
598  [x]
599  [y]; // 'data[x][y]' contains the line index now, not intensity (see prev. function 'DoLineSearch')
600  data.fLineX = dataV[x][y];
601  intersections.push_back(data);
602  }
603  }
604  }
605  cout << "intersections.size(): " << intersections.size() << endl;
606 
607  // remove close intersections
608  set<int> removeSet;
609  for (size_t i1 = 0; i1 < intersections.size(); i1++) {
610  for (size_t i2 = i1 + 1; i2 < intersections.size(); i2++) {
611  double dX =
612  intersections[i1].fPixelX
613  - intersections[i2]
614  .fPixelX; // distances in x and y of current observed intersections
615  double dY = intersections[i1].fPixelY - intersections[i2].fPixelY;
616  double dist = std::sqrt(dX * dX + dY * dY);
617  if (
618  dist
619  <= 10.) { // if their distance is below a certain threshold, insert content to 'removeSet'
620  // cout << i1 << " " << i2 << " " << intersections[i1].fPixelX << " " << intersections[i1].fPixelY << " "
621  // << intersections[i2].fPixelX << " " << intersections[i2].fPixelY << " " << dist << endl;
622  removeSet.insert(
623  i2); // set of values from one of both close intersections is stored in 'removeSet'
624  }
625  }
626  }
627 
628  set<int>::iterator it;
629  for (it = removeSet.begin(); it != removeSet.end(); ++it) {
630  swap(
631  intersections[*it],
632  intersections
633  [intersections.size()
634  - 1]); // move one of both double counted intersections to the end of vector and remove these afterwards
635  intersections.resize(intersections.size() - 1);
636  }
637  cout << "removeSet.size():" << removeSet.size()
638  << " intersections.size(): " << intersections.size() << endl;
639 
640  return intersections;
641 }
642 
643 // superposing horizontal and vertical image
644 vector<vector<double>>
645 CbmRichRonchiAna::DoSuperpose(const vector<vector<double>>& dataH,
646  const vector<vector<double>>& dataV) {
647  int nX = dataV.size();
648  int nY = dataV[0].size();
649 
650  vector<vector<double>> dataSup(nX, std::vector<double>(nY, 0.));
651  for (int x = 0; x < nX; x++) {
652  for (int y = 0; y < nY; y++) {
653  dataSup[x][y] =
654  dataH[x][y]
655  + dataV[x]
656  [y]; // data of horizontal and vertical image are being summed
657  }
658  }
659  return dataSup;
660 }
661 
663  vector<CbmRichRonchiIntersectionData>& intersections,
664  const string& option) {
665  map<int, CbmRichRonchiLineData> linesMap; // lineIndex to lineData
666  vector<CbmRichRonchiLineData> lines;
667 
668  // indexing intersection points with either 'x' or 'y' and assign values from class 'Cbm...LineData' and storing in map
669  for (auto const& curIntr : intersections) {
670  int lineInd =
671  (option == "x")
672  ? curIntr.fLineX
673  : curIntr.fLineY; // fLineX/Y is the line index, set in 'DoLineSearch'
674  linesMap[lineInd].fMeanPrimary +=
675  (option == "x")
676  ? curIntr.fPixelX
677  : curIntr
678  .fPixelY; // fPixelX/Y are the x/y-values, set in 'DoIntersection')
679  linesMap[lineInd].fMeanSecondary +=
680  (option == "x") ? curIntr.fPixelY : curIntr.fPixelX;
681  linesMap[lineInd].fNofPoints++; //fNofPoints is never set back?
682  linesMap[lineInd].fLineInd = lineInd;
683  }
684 
685  for (auto& kv : linesMap) {
686  kv.second.fMeanPrimary =
687  (double) kv.second.fMeanPrimary
688  / kv.second
689  .fNofPoints; // calculating mean values of x and y positions to enable sorting
690  kv.second.fMeanSecondary =
691  (double) kv.second.fMeanSecondary / kv.second.fNofPoints;
692  lines.push_back(kv.second);
693  //cout << kv.first << " mean:" << kv.second.fMean << " nPoints:" << kv.second.fNofPoints << " lineInd:" << kv.second.fLineInd<< endl;
694  }
695 
696  sort(lines.begin(),
697  lines.end(),
698  [](const CbmRichRonchiLineData& lhs, const CbmRichRonchiLineData& rhs) {
699  return lhs.fMeanPrimary < rhs.fMeanPrimary;
700  });
701 
702  // find first line with many points
703  int lineIndMany = 0;
704  for (size_t i = 0; i < lines.size() - 1; i++) {
705  if (lines[i].fNofPoints >= 35) {
706  lineIndMany = i; //dataSup
707  break;
708  }
709  }
710 
711  // for the left edges we need to go other direction
712  for (int i = lineIndMany - 1; i >= 1; i--) {
713  if (AreTwoSegmentsSameLine(&lines[i], &lines[i - 1])) {
715  intersections, &lines[i], &lines[i - 1], option);
716  i--; // skip next line
717  }
718  }
719 
720  for (size_t i = lineIndMany; i < lines.size() - 1; i++) {
721  if (AreTwoSegmentsSameLine(&lines[i], &lines[i + 1])) {
723  intersections, &lines[i], &lines[i + 1], option);
724  i++; // skip next line
725  }
726  }
727 
728  // now we need to assign numbers in correct order
729  int newLineIndex = 1;
730  set<int> duplicateLines; // duplicates can occure for line segments
731  for (auto& curLine : lines) {
732  if (duplicateLines.find(curLine.fLineInd) != duplicateLines.end()) continue;
733  duplicateLines.insert(curLine.fLineInd);
734  for (auto& curIntr : intersections) {
735  if (option == "x" && curIntr.fLineX == curLine.fLineInd)
736  curIntr.fOrderedLineX = newLineIndex;
737  if (option == "y" && curIntr.fLineY == curLine.fLineInd)
738  curIntr.fOrderedLineY = newLineIndex;
739  }
740  newLineIndex++;
741  }
742  cout << "newLineIndex:" << newLineIndex << endl;
743 }
744 
746  const CbmRichRonchiLineData* line1,
747  const CbmRichRonchiLineData* line2) {
748  int nofPointsMergeCut = 25;
749  double pixelDistMergeCut = 200.;
750  double pixelDiffMergeCut = 15.;
751 
752  return (
753  line1->fNofPoints < nofPointsMergeCut
754  && line2->fNofPoints < nofPointsMergeCut
755  && abs(line1->fMeanSecondary - line2->fMeanSecondary) > pixelDistMergeCut
756  && abs(line1->fMeanPrimary - line2->fMeanPrimary) <= pixelDiffMergeCut);
757 }
758 
760  vector<CbmRichRonchiIntersectionData>& intersections,
761  CbmRichRonchiLineData* line1,
762  CbmRichRonchiLineData* line2,
763  const string& option) {
764  for (auto& curIntr : intersections) {
765  if (option == "x" && curIntr.fLineX == line2->fLineInd)
766  curIntr.fLineX = line1->fLineInd;
767  if (option == "y" && curIntr.fLineY == line2->fLineInd)
768  curIntr.fLineY = line1->fLineInd;
769  }
770  line2->fLineInd = line1->fLineInd;
771 }
772 
774  vector<CbmRichRonchiIntersectionData>& data) {
775  int xMin = 1000;
776  int xMax = -1000;
777  int yMin = 1000;
778  int yMax = -1000;
779 
780  // extracting minimal and maximum x and y values
781  for (size_t i = 0; i < data.size(); i++) {
782  if (data[i].fOrderedLineX < xMin) xMin = data[i].fOrderedLineX;
783  if (data[i].fOrderedLineX > xMax) xMax = data[i].fOrderedLineX;
784  if (data[i].fOrderedLineY < yMin) yMin = data[i].fOrderedLineY;
785  if (data[i].fOrderedLineY > yMax) yMax = data[i].fOrderedLineY;
786  }
787 
788  int centerLineX = (xMax - xMin) / 2; // horizontal and vertical
789  int centerLineY = (yMax - yMin) / 2;
790 
791  fCenterCcdX = -1;
792  fCenterCcdY = -1;
793  // defining reference point to calculate slopes
794  for (size_t i = 0; i < data.size(); i++) {
795  if (fCenterCcdX == -1 && data[i].fOrderedLineX == centerLineX) {
796  fCenterCcdX = data[i].fPixelX + 20; // correction parameter in X
797  }
798  if (fCenterCcdY == -1 && data[i].fOrderedLineY == centerLineY) {
799  fCenterCcdY = data[i].fPixelY + 20; // correction parameter in Y
800  }
801  }
802 
803  cout << "xMin:" << xMin << " xMax:" << xMax << " yMin:" << yMin
804  << " yMax:" << yMax << endl;
805  cout << "centerLineX:" << centerLineX << " centerLineY:" << centerLineY
806  << endl;
807  cout << "fCenterCcdX:" << fCenterCcdX << " fCenterCcdY:" << fCenterCcdY
808  << endl;
809 
810  for (size_t i = 0; i < data.size(); i++) {
811  // X and Y positions on CCD in microns
812  int ccdX = (data[i].fPixelX - fCenterCcdX) * fCcdPixelSize;
813  int ccdY = (data[i].fPixelY - fCenterCcdY) * fCcdPixelSize;
814 
815  data[i].fCcdV.SetXYZ(ccdX, ccdY, 0.);
816 
817  // XYZ positions on ronchi ruling in microns
818  data[i].fRulingV.SetXYZ((data[i].fOrderedLineX - centerLineX) * fPitchGrid,
819  (data[i].fOrderedLineY - centerLineY) * fPitchGrid,
821 
822  // slopes in X and Y direction of reflected beam
823  double sRefX = -(data[i].fRulingV.X() - data[i].fCcdV.X())
824  / fDistRulingCCD; // 'minus' because Ruling is behind CoC
825  double sRefY = -(data[i].fRulingV.Y() - data[i].fCcdV.Y()) / fDistRulingCCD;
826 
827  // extrapolating X and Y positions on mirror in microns
828  data[i].fMirrorV.SetXYZ(ccdX + (sRefX * fDistMirrorRuling),
829  ccdY + (sRefY * fDistMirrorRuling),
831 
832  //cout << "fMirrorV_xyz = [" << data[i].fMirrorV.X() << ", " << data[i].fMirrorV.Y() << ", " << data[i].fMirrorV.Z() << "]" << endl;
833 
834  // calculating angles between optical axis of mirror and incident resp. reflected beam
835  double mirrorCenterDist =
836  sqrt(pow(data[i].fMirrorV.X() + fOffsetCCDOptAxisX, 2)
837  + pow(data[i].fMirrorV.Y() + fOffsetCCDOptAxisY,
838  2)); // distance from mirrors center in microns
839  double sagitta =
841  - sqrt(pow(fRadiusMirror, 2)
842  - pow(mirrorCenterDist, 2)); // to calculate cathetus length
843  double cathetus =
845  - sagitta; // if point source is in the center of curvature !!
846 
847  double angleIncX = atan(
848  data[i].fMirrorV.X()
849  / cathetus); // if point source is in the center of curvature (CoC), otherwise add offset in Z direction !!
850  double angleIncY =
851  atan((data[i].fMirrorV.Y()
854  / cathetus);
855  double angleRefX = atan(sRefX);
856  double angleRefY = atan(sRefY);
857  data[i].fNormalRadX = ((angleIncX + angleRefX) / 2.0);
858  data[i].fNormalRadY = ((angleIncY + angleRefY) / 2.0);
859 
860  // data[i].fNormalX = tan(angleNormalX);
861  // data[i].fNormalY = tan(angleNormalY);
862 
863  double segmentSize =
864  3500; // half segment size; for the moment just assume that all segments have the same size
865  data[i].fTL.SetXYZ(data[i].fMirrorV.X() - segmentSize,
866  data[i].fMirrorV.Y() + segmentSize,
867  data[i].fMirrorV.Z());
868  RotatePointImpl(&data[i].fTL,
869  &data[i].fTLRot,
870  data[i].fNormalRadX,
871  data[i].fNormalRadY,
872  &data[i].fMirrorV);
873 
874  data[i].fTR.SetXYZ(data[i].fMirrorV.X() + segmentSize,
875  data[i].fMirrorV.Y() + segmentSize,
876  data[i].fMirrorV.Z());
877  RotatePointImpl(&data[i].fTR,
878  &data[i].fTRRot,
879  data[i].fNormalRadX,
880  data[i].fNormalRadY,
881  &data[i].fMirrorV);
882 
883  data[i].fBL.SetXYZ(data[i].fMirrorV.X() - segmentSize,
884  data[i].fMirrorV.Y() - segmentSize,
885  data[i].fMirrorV.Z());
886  RotatePointImpl(&data[i].fBL,
887  &data[i].fBLRot,
888  data[i].fNormalRadX,
889  data[i].fNormalRadY,
890  &data[i].fMirrorV);
891 
892  data[i].fBR.SetXYZ(data[i].fMirrorV.X() + segmentSize,
893  data[i].fMirrorV.Y() - segmentSize,
894  data[i].fMirrorV.Z());
895  RotatePointImpl(&data[i].fBR,
896  &data[i].fBRRot,
897  data[i].fNormalRadX,
898  data[i].fNormalRadY,
899  &data[i].fMirrorV);
900  }
901 
902  /*// correction value to ZERO reference point at center of mirror
903  for (int i = 0; i < data.size(); i++) {
904  if (data[i].fOrderedLineX == centerLineX && data[i].fOrderedLineY == centerLineY) {
905  double radius = sqrt(pow(data[i].fTL.X(),2) + pow(data[i].fTL.Y(),2));
906  double sagitta2 = fRadiusMirror - sqrt(pow(fRadiusMirror,2) - pow(radius,2));
907  fCorrection = (double)(data[i].fTL.Z() - sagitta2 - fRadiusMirror);
908  cout << "fTL.Z_Sagitta = " << fRadiusMirror - data[i].fTL.Z() << ", sagitta2 = " << sagitta2 << endl;
909  cout << "CORRECTION = " << (double)fCorrection << endl << endl;
910  }
911  }*/
912 
913  { DrawXYMum(data); }
914 
915  {
916  TCanvas* c =
917  new TCanvas("ronchi_xz_mum_lineY20", "ronchi_xz_mum_lineY20", 1800, 900);
918  c->Divide(2, 1);
919  c->cd(1);
920  DrawXZProjection(data, 20, 1.);
921  c->cd(2);
922  DrawXZProjection(data, 20, 0.025);
923  }
924 
925  { DrawMirrorSegments(data, 20, 20); }
926 }
927 
928 // constructing spherical surface
929 void CbmRichRonchiAna::DoSphere(vector<CbmRichRonchiIntersectionData>& data) {
930  int xMin = 1000;
931  int xMax = -1000;
932  int yMin = 1000;
933  int yMax = -1000;
934 
935  // extracting minimal and maximum x and y values
936  for (size_t i = 0; i < data.size(); i++) {
937  if (data[i].fOrderedLineX < xMin) xMin = data[i].fOrderedLineX;
938  if (data[i].fOrderedLineX > xMax) xMax = data[i].fOrderedLineX;
939  if (data[i].fOrderedLineY < yMin) yMin = data[i].fOrderedLineY;
940  if (data[i].fOrderedLineY > yMax) yMax = data[i].fOrderedLineY;
941  }
942 
943  // assigning segments to their position on mirror plane (according to their values after rotation, before sphere construction)
944  // in X direction
945  for (int iX = xMin; iX <= xMax; iX++) {
946  int iPX = GetMinIndexForLineX(
947  iX,
948  data); // 'GetMinIndex..' to get index of 'data' for current intersection
949  int iPX0 = GetMinIndexForLineX(iX - 1, data);
950  if (iPX < 0 || iPX0 < 0) continue;
951  double shiftX =
952  data[iPX0].fTRRot.X()
953  - data[iPX]
954  .fTLRot.X(); // horizontal distance between neighboured corners
955  data[iPX].fTLRot.SetXYZ(data[iPX].fTLRot.X() + shiftX,
956  data[iPX].fTLRot.Y(),
957  data[iPX].fTLRot.Z());
958  data[iPX].fTRRot.SetXYZ(data[iPX].fTRRot.X() + shiftX,
959  data[iPX].fTRRot.Y(),
960  data[iPX].fTRRot.Z());
961  data[iPX].fBLRot.SetXYZ(data[iPX].fBLRot.X() + shiftX,
962  data[iPX].fBLRot.Y(),
963  data[iPX].fBLRot.Z());
964  data[iPX].fBRRot.SetXYZ(data[iPX].fBRRot.X() + shiftX,
965  data[iPX].fBRRot.Y(),
966  data[iPX].fBRRot.Z());
967  }
968 
969  // in Y direction
970  for (int iY = yMin; iY <= yMax; iY++) {
971  int iPY = GetMinIndexForLineY(iY, data);
972  int iPY0 = GetMinIndexForLineY(iY - 1, data);
973  if (iPY < 0 || iPY0 < 0) continue;
974  double shiftY = data[iPY0].fTRRot.Y() - data[iPY].fBRRot.Y();
975  data[iPY].fTLRot.SetXYZ(data[iPY].fTLRot.X(),
976  data[iPY].fTLRot.Y() + shiftY,
977  data[iPY].fTLRot.Z());
978  data[iPY].fTRRot.SetXYZ(data[iPY].fTRRot.X(),
979  data[iPY].fTRRot.Y() + shiftY,
980  data[iPY].fTRRot.Z());
981  data[iPY].fBLRot.SetXYZ(data[iPY].fBLRot.X(),
982  data[iPY].fBLRot.Y() + shiftY,
983  data[iPY].fBLRot.Z());
984  data[iPY].fBRRot.SetXYZ(data[iPY].fBRRot.X(),
985  data[iPY].fBRRot.Y() + shiftY,
986  data[iPY].fBRRot.Z());
987  }
988 
989  DrawMirrorSegments(data, 32, 32);
990 
991  // inserting X and Y shifts in f..Sph vectors
992  for (int iX = xMin; iX <= xMax; iX++) {
993  int iPX = GetMinIndexForLineX(iX, data);
994  if (iPX < 0) continue;
995  for (int iY = yMin; iY <= yMax; iY++) {
996  int iC = GetIndexForLineXLineY(iX, iY, data);
997  if (iC < 0) continue;
998  int iPY = GetMinIndexForLineY(iY, data);
999  if (iPY < 0) continue;
1000 
1001  double shiftX = data[iPX].fTLRot.X() - data[iC].fTLRot.X();
1002  double shiftY = data[iPY].fTLRot.Y() - data[iC].fTLRot.Y();
1003 
1004  data[iC].fTLSph.SetXYZ(data[iC].fTLRot.X() + shiftX,
1005  data[iC].fTLRot.Y() + shiftY,
1006  data[iC].fTLRot.Z());
1007  data[iC].fTRSph.SetXYZ(data[iC].fTRRot.X() + shiftX,
1008  data[iC].fTRRot.Y() + shiftY,
1009  data[iC].fTRRot.Z());
1010  data[iC].fBLSph.SetXYZ(data[iC].fBLRot.X() + shiftX,
1011  data[iC].fBLRot.Y() + shiftY,
1012  data[iC].fBLRot.Z());
1013  data[iC].fBRSph.SetXYZ(data[iC].fBRRot.X() + shiftX,
1014  data[iC].fBRRot.Y() + shiftY,
1015  data[iC].fBRRot.Z());
1016  }
1017  }
1018 
1019  // align Z positions in Y
1020  for (int iX = xMin; iX <= xMax; iX++) {
1021  for (int iY = yMin; iY <= yMax; iY++) {
1022  int iC = GetIndexForLineXLineY(iX, iY, data);
1023  //int iPX = GetIndexForLineXLineY(iX - 1, iY, data);
1024  int iPY = GetIndexForLineXLineY(iX, iY - 1, data);
1025  if (iPY < 0)
1026  iPY = GetIndexForLineXLineY(
1027  iX, iY - 2, data); // one missing measurement is allowed
1028  if (iC < 0) continue;
1029 
1030  if (iPY >= 0) {
1031  //double shiftZAdd = (iPX > 0)?data[iPX].fTRSph.Z() - data[iC].fTLSph.Z():0;
1032  double shiftZ = data[iPY].fTLSph.Z() - data[iC].fBLSph.Z();
1033  data[iC].fTLSph.SetZ(data[iC].fTLSph.Z() + shiftZ);
1034  data[iC].fTRSph.SetZ(data[iC].fTRSph.Z() + shiftZ);
1035  data[iC].fBLSph.SetZ(data[iC].fBLSph.Z() + shiftZ);
1036  data[iC].fBRSph.SetZ(data[iC].fBRSph.Z() + shiftZ);
1037  }
1038  }
1039  }
1040 
1041  // align Z positions in X
1042  for (int iX = xMin; iX <= xMax; iX++) {
1043  int iPX = GetIndexForLineXLineY(iX, 30, data);
1044  int iPX0 = GetIndexForLineXLineY(iX - 1, 30, data);
1045  if (iPX0 < 0)
1046  iPX0 = GetIndexForLineXLineY(
1047  iX - 2, 30, data); // one missing measurement is allowed
1048  if (iPX < 0 || iPX0 < 0) continue;
1049  double shiftZ = data[iPX0].fTRSph.Z() - data[iPX].fTLSph.Z();
1050  for (int iY = yMin; iY <= yMax; iY++) {
1051  int iC = GetIndexForLineXLineY(iX, iY, data);
1052  data[iC].fTLSph.SetZ(data[iC].fTLSph.Z() + shiftZ);
1053  data[iC].fTRSph.SetZ(data[iC].fTRSph.Z() + shiftZ);
1054  data[iC].fBLSph.SetZ(data[iC].fBLSph.Z() + shiftZ);
1055  data[iC].fBRSph.SetZ(data[iC].fBRSph.Z() + shiftZ);
1056  }
1057  }
1058 
1059  {
1061  DrawMirrorSegmentsSphere(data, 21, 21);
1062  DrawMirrorSegmentsSphere(data, 30, 30);
1063  DrawMirrorSegmentsSphere(data, 40, 40);
1064  }
1065 }
1066 
1068  int lineX,
1069  vector<CbmRichRonchiIntersectionData>& data) {
1070  int ind = -1;
1071  for (int iY = 0; iY < 2000; iY++) {
1072  ind = GetIndexForLineXLineY(lineX, iY, data);
1073  if (ind != -1) return ind;
1074  }
1075  return ind;
1076 }
1077 
1078 
1080  int lineY,
1081  vector<CbmRichRonchiIntersectionData>& data) {
1082  int ind = -1;
1083  for (int iX = 0; iX < 2000; iX++) {
1084  ind = GetIndexForLineXLineY(iX, lineY, data);
1085  if (ind != -1) return ind;
1086  }
1087  return ind;
1088 }
1089 
1090 
1092  int lineX,
1093  int lineY,
1094  vector<CbmRichRonchiIntersectionData>& data) {
1095  for (size_t i = 0; i < data.size(); i++) {
1096  if (data[i].fOrderedLineX == lineX && data[i].fOrderedLineY == lineY)
1097  return i; // returns 'data' index of currently investigated intersection
1098  }
1099  return -1;
1100 }
1101 
1103  vector<CbmRichRonchiIntersectionData>& data) {
1104  double mirX = 0.;
1105  double mirY = 0.;
1106  double mirZ = 0.;
1107 
1108  int correctionValue = 11800;
1109  int threshold = 0; //-50000;
1110 
1111  for (size_t i = 0; i < data.size(); i++) {
1112  double meanX = 0.25
1113  * (data[i].fTLSph.X() + data[i].fTRSph.X()
1114  + data[i].fBLSph.X() + data[i].fBRSph.X());
1115  double meanY = 0.25
1116  * (data[i].fTLSph.Y() + data[i].fTRSph.Y()
1117  + data[i].fBLSph.Y() + data[i].fBRSph.Y());
1118  double meanZ = 0.25
1119  * (data[i].fTLSph.Z() + data[i].fTRSph.Z()
1120  + data[i].fBLSph.Z() + data[i].fBRSph.Z());
1121  double dX = mirX - meanX;
1122  double dY = mirY - meanY;
1123  double dZ = mirZ - meanZ;
1124  double d = sqrt(dZ * dZ); //sqrt(dX*dX + dY*dY + dZ*dZ);
1125 
1126  // cout << "dX/dY/dZ = " << dX << "/" << dY << "/" << dZ << endl;
1127  // cout << "d = " << d << endl;
1128 
1129  //double mirrorCenterDist = sqrt(pow(data[i].fMirrorV.X(), 2) + pow(data[i].fMirrorV.Y(), 2)); // distance from mirrors center in microns
1130  double mirrorCenterDist =
1131  sqrt(pow(meanX, 2)
1132  + pow(meanY, 2)); // distance from mirrors center in microns
1133  double sagitta =
1134  fRadiusMirror - sqrt(pow(fRadiusMirror, 2) - pow(mirrorCenterDist, 2));
1135  //data[i].fDeviation = d - fRadiusMirror + sagitta;
1136 
1137  data[i].fDeviation =
1138  d - (fDistMirrorCCD - sagitta); // (Ist-Soll) !! change to fDistMIrrorCCD
1139  }
1140  TH2D* hMirrorHeight =
1141  new TH2D("hMirrorDeviation",
1142  "hMirrorDeviation;index X;index Y;Deviation [mum]",
1143  60,
1144  -0.5,
1145  59.5,
1146  60,
1147  -0.5,
1148  59.5);
1149  TCanvas* c = new TCanvas("mirror_deviation", "mirror_deviation", 1000, 1000);
1150  for (size_t i = 0; i < data.size(); i++) {
1151  if (data[i].fDeviation > threshold) {
1152  hMirrorHeight->SetBinContent(data[i].fOrderedLineX,
1153  data[i].fOrderedLineY,
1154  data[i].fDeviation - correctionValue);
1155  }
1156  }
1157  DrawH2(hMirrorHeight);
1158 }
1159 
1160 void CbmRichRonchiAna::DrawXYMum(vector<CbmRichRonchiIntersectionData>& data) {
1161  vector<int> colors = {kBlack,
1162  kGreen,
1163  kBlue,
1164  kRed,
1165  kYellow,
1166  kOrange,
1167  kCyan,
1168  kGray,
1169  kMagenta,
1170  kYellow + 2,
1171  kRed + 3};
1172  TH2D* hCcdXY = new TH2D("hCcdXY",
1173  "hCcdXY;CCD_X [mum];CCD_Y [mum];",
1174  1,
1175  -7000,
1176  7000,
1177  1,
1178  -7000,
1179  7000);
1180  TH2D* hRulingXY = new TH2D("hRulingXY",
1181  "hRulingXY;Ruling_X [mum];Ruling_Y [mum];",
1182  1,
1183  -7000,
1184  7000,
1185  1,
1186  -7000,
1187  7000);
1188  TH2D* hMirrorXY = new TH2D("hMirrorXY",
1189  "hMirrorXY;Mirror_X [mum];Mirror_Y [mum];",
1190  1,
1191  -250000,
1192  250000,
1193  1,
1194  -250000,
1195  250000);
1196  TCanvas* c = new TCanvas("ronchi_xy_mum", "ronchi_xy_mum", 1800, 600);
1197  c->Divide(3, 1);
1198  c->cd(1);
1199  DrawH2(hCcdXY);
1200  gPad->SetRightMargin(0.10);
1201  for (size_t i = 0; i < data.size(); i++) {
1202  TEllipse* center = new TEllipse(data[i].fCcdV.X(), data[i].fCcdV.Y(), 50);
1203  center->SetFillColor(colors[data[i].fOrderedLineX % colors.size()]);
1204  center->Draw();
1205  }
1206 
1207  c->cd(2);
1208  DrawH2(hRulingXY);
1209  gPad->SetRightMargin(0.10);
1210  for (size_t i = 0; i < data.size(); i++) {
1211  TEllipse* center =
1212  new TEllipse(data[i].fRulingV.X(), data[i].fRulingV.Y(), 50);
1213  center->SetFillColor(colors[data[i].fOrderedLineX % colors.size()]);
1214  center->Draw();
1215  }
1216 
1217  c->cd(3);
1218  DrawH2(hMirrorXY);
1219  gPad->SetRightMargin(0.10);
1220  for (size_t i = 0; i < data.size(); i++) {
1221  TEllipse* center =
1222  new TEllipse(data[i].fMirrorV.X(), data[i].fMirrorV.Y(), 2500);
1223  center->SetFillColor(colors[data[i].fOrderedLineX % colors.size()]);
1224  center->Draw();
1225  }
1226 }
1227 
1229  vector<CbmRichRonchiIntersectionData>& data,
1230  int orderedLineY,
1231  double scale) {
1232  string histName =
1233  "hZX_lineY" + to_string(orderedLineY) + "_scale" + to_string(scale);
1234 
1235  TH2D* hZX = new TH2D(histName.c_str(),
1236  (histName + ";Z [mum];X [mum];").c_str(),
1237  100,
1238  -0.02 * scale * fDistMirrorRuling,
1239  1.05 * scale * fDistMirrorRuling,
1240  100,
1241  scale * -250000,
1242  scale * 250000);
1243  DrawH2(hZX);
1244  gPad->SetRightMargin(0.10);
1245  for (size_t i = 0; i < data.size(); i++) {
1246  if (data[i].fOrderedLineY != orderedLineY) continue;
1247 
1248  TEllipse* ccdEllipse = new TEllipse(
1249  data[i].fCcdV.Z(), data[i].fCcdV.X(), scale * 20000, scale * 2000);
1250  ccdEllipse->SetFillColor(kRed);
1251  ccdEllipse->Draw();
1252 
1253  TEllipse* rulingEllipse = new TEllipse(
1254  data[i].fRulingV.Z(), data[i].fRulingV.X(), scale * 20000, scale * 2000);
1255  rulingEllipse->SetFillColor(kBlue);
1256  rulingEllipse->Draw();
1257 
1258  TEllipse* mirrorEllipse = new TEllipse(
1259  data[i].fMirrorV.Z(), data[i].fMirrorV.X(), scale * 20000, scale * 2000);
1260  mirrorEllipse->SetFillColor(kGreen);
1261  mirrorEllipse->Draw();
1262 
1263  TLine* rulingLine = new TLine(data[i].fCcdV.Z(),
1264  data[i].fCcdV.X(),
1265  data[i].fRulingV.Z(),
1266  data[i].fRulingV.X());
1267  rulingLine->Draw();
1268 
1269  TLine* mirrorLine = new TLine(data[i].fRulingV.Z(),
1270  data[i].fRulingV.X(),
1271  data[i].fMirrorV.Z(),
1272  data[i].fMirrorV.X());
1273  mirrorLine->Draw();
1274 
1275  double xNorm =
1276  data[i].fMirrorV.X() - fDistMirrorRuling * tan(data[i].fNormalRadX);
1277  TLine* mirrorLineNorm = new TLine(
1278  fDistRulingCCD, xNorm, data[i].fMirrorV.Z(), data[i].fMirrorV.X());
1279  mirrorLineNorm->SetLineColor(kBlue);
1280  mirrorLineNorm->Draw();
1281  }
1282 }
1283 
1284 
1286  vector<CbmRichRonchiIntersectionData>& data,
1287  int orderedLineX,
1288  int orderedLineY) {
1289  string cName = "ronchi_mirror_segments_rot_lineX" + to_string(orderedLineX)
1290  + "_lineY" + to_string(orderedLineY);
1291  TCanvas* c = new TCanvas(cName.c_str(), cName.c_str(), 1800, 900);
1292  c->Divide(2, 1);
1293 
1294  string histNameXY = "hXY_mirror_segments_rot_lineX" + to_string(orderedLineX)
1295  + "_lineY" + to_string(orderedLineY);
1296  TH2D* hXY = new TH2D(histNameXY.c_str(),
1297  (histNameXY + "hXY;X [mum];Y [mum];").c_str(),
1298  1,
1299  -250000,
1300  250000,
1301  1,
1302  -250000,
1303  250000);
1304  vector<int> colors = {kBlack,
1305  kGreen,
1306  kBlue,
1307  kRed,
1308  kYellow,
1309  kOrange,
1310  kCyan,
1311  kGray,
1312  kMagenta,
1313  kYellow + 2,
1314  kRed + 3};
1315  c->cd(1);
1316  DrawH2(hXY); // boxes
1317  gPad->SetRightMargin(0.10);
1318  for (size_t i = 0; i < data.size(); i++) {
1319  int color = colors[data[i].fOrderedLineY % colors.size()];
1321  data[i].fTLRot, data[i].fTRRot, data[i].fBLRot, data[i].fBRRot, color);
1322  }
1323 
1324  double hSize = 250000;
1325  string histNameZX = "hZX_mirror_segments_lrot_ineX" + to_string(orderedLineX)
1326  + "_lineY" + to_string(orderedLineY);
1327  TH2D* hZX = new TH2D(histNameZX.c_str(),
1328  (histNameZX + ";Z [mum];X [mum];").c_str(),
1329  100,
1330  fDistMirrorRuling - hSize,
1331  fDistMirrorRuling + hSize,
1332  100,
1333  -1. * hSize,
1334  hSize);
1335  c->cd(2);
1336  DrawH2(hZX);
1337  gPad->SetRightMargin(0.10);
1338  for (size_t i = 0; i < data.size(); i++) {
1339  if (data[i].fOrderedLineY != orderedLineY) continue;
1340 
1341  TEllipse* mirrorEllipse =
1342  new TEllipse(data[i].fMirrorV.Z(), data[i].fMirrorV.X(), 2000, 2000);
1343  mirrorEllipse->SetFillColor(kGreen);
1344  mirrorEllipse->Draw();
1345 
1346  TLine* rulingLine = new TLine(data[i].fCcdV.Z(),
1347  data[i].fCcdV.X(),
1348  data[i].fRulingV.Z(),
1349  data[i].fRulingV.X());
1350  rulingLine->Draw();
1351 
1352  TLine* mirrorLine = new TLine(data[i].fRulingV.Z(),
1353  data[i].fRulingV.X(),
1354  data[i].fMirrorV.Z(),
1355  data[i].fMirrorV.X());
1356  mirrorLine->Draw();
1357 
1358  double xNorm =
1359  data[i].fMirrorV.X() - fDistMirrorRuling * tan(data[i].fNormalRadX);
1360  TLine* mirrorLineNorm = new TLine(
1361  fDistRulingCCD, xNorm, data[i].fMirrorV.Z(), data[i].fMirrorV.X());
1362  mirrorLineNorm->SetLineColor(kBlue);
1363  mirrorLineNorm->Draw();
1364 
1365  TLine* mirrorLineSeg = new TLine(data[i].fTRRot.Z(),
1366  data[i].fTRRot.X(),
1367  data[i].fTLRot.Z(),
1368  data[i].fTLRot.X());
1369  mirrorLineSeg->SetLineColor(kRed);
1370  mirrorLineSeg->Draw();
1371  }
1372 }
1373 
1375  vector<CbmRichRonchiIntersectionData>& data) {
1376  string cName = "ronchi_mirror_segments_sphere_all";
1377  TCanvas* c = new TCanvas(cName.c_str(), cName.c_str(), 900, 900);
1378 
1379  string histNameXY = "hXY_mirror_segments_sphere_all";
1380  TH2D* hXY = new TH2D(histNameXY.c_str(),
1381  (histNameXY + "hXY;X [mum];Y [mum];").c_str(),
1382  1,
1383  -250000,
1384  250000,
1385  1,
1386  -250000,
1387  250000);
1388  vector<int> colors = {kBlack,
1389  kGreen,
1390  kBlue,
1391  kRed,
1392  kYellow,
1393  kOrange,
1394  kCyan,
1395  kGray,
1396  kMagenta,
1397  kYellow + 2,
1398  kRed + 3};
1399  DrawH2(hXY); // boxes
1400  gPad->SetRightMargin(0.10);
1401  for (size_t i = 0; i < data.size(); i++) {
1402  int color = colors[data[i].fOrderedLineY % colors.size()];
1404  data[i].fTLSph, data[i].fTRSph, data[i].fBLSph, data[i].fBRSph, color);
1405  }
1406 }
1407 
1409  vector<CbmRichRonchiIntersectionData>& data,
1410  int orderedLineX,
1411  int orderedLineY) {
1412  string cName = "ronchi_mirror_segments_sphere_lineX" + to_string(orderedLineX)
1413  + "_lineY" + to_string(orderedLineY);
1414  TCanvas* c = new TCanvas(cName.c_str(), cName.c_str(), 1800, 900);
1415  c->Divide(2, 1);
1416 
1417  string histNameXY = "hXY_mirror_segments_sphere_lineX"
1418  + to_string(orderedLineX) + "_lineY"
1419  + to_string(orderedLineY);
1420  TH2D* hXY = new TH2D(histNameXY.c_str(),
1421  (histNameXY + "hXY;X [mum];Y [mum];").c_str(),
1422  1,
1423  -250000,
1424  250000,
1425  1,
1426  -250000,
1427  250000);
1428  vector<int> colors = {kBlack,
1429  kGreen,
1430  kBlue,
1431  kRed,
1432  kYellow,
1433  kOrange,
1434  kCyan,
1435  kGray,
1436  kMagenta,
1437  kYellow + 2,
1438  kRed + 3};
1439  c->cd(1);
1440  DrawH2(hXY); // boxes
1441  gPad->SetRightMargin(0.10);
1442  for (size_t i = 0; i < data.size(); i++) {
1443  if (data[i].fOrderedLineX == orderedLineX)
1445  data[i].fTLSph, data[i].fTRSph, data[i].fBLSph, data[i].fBRSph, kBlue);
1446  if (data[i].fOrderedLineY == orderedLineY)
1448  data[i].fTLSph, data[i].fTRSph, data[i].fBLSph, data[i].fBRSph, kRed);
1449  }
1450 
1451  double hSize = 20000;
1452  string histNameZX = "hZX_mirror_segments_sphere_lineX"
1453  + to_string(orderedLineX) + "_lineY"
1454  + to_string(orderedLineY);
1455  TH2D* hZX = new TH2D(histNameZX.c_str(),
1456  (histNameZX + ";Z [mum];X(Y) [mum];").c_str(),
1457  100,
1458  data[0].fBRSph.Z() - 0.25 * hSize,
1459  data[0].fBRSph.Z() + hSize,
1460  100,
1461  -1. * 250000,
1462  250000);
1463  c->cd(2);
1464  DrawH2(hZX);
1465  gPad->SetRightMargin(0.10);
1466  for (size_t i = 0; i < data.size(); i++) {
1467  if (data[i].fOrderedLineX == orderedLineX) {
1468  TLine* mirrorLineSeg = new TLine(data[i].fBRSph.Z(),
1469  data[i].fBRSph.Y(),
1470  data[i].fTRSph.Z(),
1471  data[i].fTRSph.Y());
1472  mirrorLineSeg->SetLineColor(kBlue);
1473  mirrorLineSeg->Draw();
1474  }
1475 
1476  if (data[i].fOrderedLineY == orderedLineY) {
1477  TLine* mirrorLineSeg = new TLine(data[i].fTRSph.Z(),
1478  data[i].fTRSph.X(),
1479  data[i].fTLSph.Z(),
1480  data[i].fTLSph.X());
1481  mirrorLineSeg->SetLineColor(kRed);
1482  mirrorLineSeg->Draw();
1483  }
1484  }
1485 }
1486 
1487 // void CbmRichRonchiAna::DrawMirrorSegmentsSphere(vector<CbmRichRonchiIntersectionData> &data, int orderedLineX, int orderedLineY)
1488 // {
1489 // string cName = "ronchi_mirror_segments_sphere_lineX" + to_string(orderedLineX) + "_lineY" + to_string(orderedLineY);
1490 // TCanvas *c = new TCanvas(cName.c_str(), cName.c_str(), 1800, 900);
1491 // c->Divide(2, 1);
1492 
1493 // string histNameXY = "hXY_mirror_segments_sphere_lineX" + to_string(orderedLineX) + "_lineY" + to_string(orderedLineY);
1494 // TH2D *hXY = new TH2D(histNameXY.c_str(), (histNameXY + "hXY;X [mum];Y [mum];").c_str(), 1, -250000, 250000, 1, -250000, 250000);
1495 // vector<int> colors = {kBlack, kGreen, kBlue, kRed, kYellow, kOrange, kCyan, kGray, kMagenta, kYellow + 2, kRed + 3};
1496 // c->cd(1);
1497 // DrawH2(hXY); // boxes
1498 // gPad->SetRightMargin(0.10);
1499 // for (size_t i = 0; i < data.size(); i++){
1500 // if (data[i].fOrderedLineX == orderedLineX) DrawOneMirrorSegment(data[i].fTLSph, data[i].fTRSph, data[i].fBLSph, data[i].fBRSph, kBlue);
1501 // if (data[i].fOrderedLineY == orderedLineY) DrawOneMirrorSegment(data[i].fTLSph, data[i].fTRSph, data[i].fBLSph, data[i].fBRSph, kRed);
1502 // }
1503 
1504 // double hSize = 10000;
1505 // int corr = 9400;
1506 
1507 // string histNameZX = "hZX_mirror_segments_sphere_lineX" + to_string(orderedLineX) + "_lineY" + to_string(orderedLineY);
1508 // TH2D *hZX = new TH2D(histNameZX.c_str(), (histNameZX + ";Z [mum];X(Y) [mum];").c_str(), 100, data[0].fBRSph.Z()-(fDistMirrorCCD) - 1.0*hSize, data[0].fBRSph.Z()-(fDistMirrorCCD) + 1.0*hSize, 100, -1. * 250000, 250000);
1509 // c->cd(2);
1510 // DrawH2(hZX);
1511 // gPad->SetRightMargin(0.10);
1512 // for (size_t i = 0; i < data.size(); i++) {
1513 
1514 // double meanX = 0.25 * ( data[i].fTLSph.X() + data[i].fTRSph.X() + data[i].fBLSph.X() + data[i].fBRSph.X() );
1515 // double meanY = 0.25 * ( data[i].fTLSph.Y() + data[i].fTRSph.Y() + data[i].fBLSph.Y() + data[i].fBRSph.Y() );
1516 // double meanZ = 0.25 * ( data[i].fTLSph.Z() + data[i].fTRSph.Z() + data[i].fBLSph.Z() + data[i].fBRSph.Z() );
1517 // double mirrorCenterDist = sqrt(pow(meanX, 2) + pow(meanY-fOffsetCCDOptAxisY, 2)); // distance from mirrors center in microns
1518 // double sagitta = fRadiusMirror - sqrt(pow(fRadiusMirror, 2) - pow(mirrorCenterDist, 2));
1519 // double zIdeal = (fDistMirrorCCD) - sagitta;
1520 
1521 // if (data[i].fOrderedLineX == orderedLineX) {
1522 // //TLine *mirrorLineSeg = new TLine(data[i].fBRSph.Z(), data[i].fBRSph.Y(), data[i].fTRSph.Z(), data[i].fTRSph.Y());
1523 // TLine *mirrorLineSeg = new TLine(data[i].fBRSph.Z()-zIdeal-corr, data[i].fBRSph.Y(), data[i].fTRSph.Z()-zIdeal-corr, data[i].fTRSph.Y());
1524 // mirrorLineSeg->SetLineColor(kBlue);
1525 // mirrorLineSeg->Draw();
1526 // }
1527 
1528 // if (data[i].fOrderedLineY == orderedLineY) {
1529 // TLine *mirrorLineSeg = new TLine(data[i].fTRSph.Z()-zIdeal, data[i].fTRSph.X(), data[i].fTLSph.Z()-zIdeal, data[i].fTLSph.X());
1530 // mirrorLineSeg->SetLineColor(kRed);
1531 // mirrorLineSeg->Draw();
1532 // }
1533 // }
1534 // }
1535 
1537  const TVector3& tr,
1538  const TVector3& bl,
1539  const TVector3& br,
1540  int color) {
1541  TLine* line1 = new TLine(tl.X(), tl.Y(), tr.X(), tr.Y());
1542  line1->SetLineColor(color);
1543  line1->Draw();
1544 
1545  TLine* line2 = new TLine(tr.X(), tr.Y(), br.X(), br.Y());
1546  line2->SetLineColor(color);
1547  line2->Draw();
1548 
1549  TLine* line3 = new TLine(br.X(), br.Y(), bl.X(), bl.Y());
1550  line3->SetLineColor(color);
1551  line3->Draw();
1552 
1553  TLine* line4 = new TLine(bl.X(), bl.Y(), tl.X(), tl.Y());
1554  line4->SetLineColor(color);
1555  line4->Draw();
1556 }
1557 
1558 
1560  TVector3* outPos,
1561  Double_t rotX,
1562  Double_t rotY,
1563  TVector3* cV) {
1564  double x = inPos->X() - cV->X();
1565  double y = inPos->Y() - cV->Y();
1566  double z = inPos->Z() - cV->Z();
1567 
1568  double sinY = sin(rotY);
1569  double cosY = cos(rotY);
1570  double sinX = sin(rotX);
1571  double cosX = cos(rotX);
1572 
1573  double xNew = x * cosX - y * sinX * sinY + z * cosY * sinX + cV->X();
1574  double yNew = y * cosY + z * sinY + cV->Y();
1575  double zNew = -x * sinX - y * sinY * cosX + z * cosY * cosX + cV->Z();
1576 
1577  outPos->SetXYZ(xNew, yNew, zNew);
1578 }
1579 
sin
friend F32vec4 sin(const F32vec4 &a)
Definition: L1/vectors/P4_F32vec4.h:136
CbmRichRonchiAna::DrawMirrorSegments
void DrawMirrorSegments(vector< CbmRichRonchiIntersectionData > &data, int orderedLineX, int orderedLineY)
Definition: CbmRichRonchiAna.cxx:1285
CbmRichRonchiAna::DrawXZProjection
void DrawXZProjection(vector< CbmRichRonchiIntersectionData > &data, int orderedLineY, double scale)
Definition: CbmRichRonchiAna.cxx:1228
sqrt
friend F32vec4 sqrt(const F32vec4 &a)
Definition: L1/vectors/P4_F32vec4.h:41
CbmRichRonchiAna::~CbmRichRonchiAna
virtual ~CbmRichRonchiAna()
Definition: CbmRichRonchiAna.cxx:63
CbmRichRonchiAna::GetMinIndexForLineX
int GetMinIndexForLineX(int lineX, vector< CbmRichRonchiIntersectionData > &data)
Definition: CbmRichRonchiAna.cxx:1067
CbmRichRonchiAna::Run
void Run()
Definition: CbmRichRonchiAna.cxx:65
CbmRichRonchiAna::DrawMirrorSegmentsSphereAll
void DrawMirrorSegmentsSphereAll(vector< CbmRichRonchiIntersectionData > &data)
Definition: CbmRichRonchiAna.cxx:1374
CbmRichRonchiAna::fDistRulingCCD
double fDistRulingCCD
Definition: CbmRichRonchiAna.h:127
CbmRichRonchiIntersectionData::fPixelX
int fPixelX
Definition: CbmRichRonchiAna.h:51
CbmRichRonchiLineData::fMeanSecondary
double fMeanSecondary
Definition: CbmRichRonchiAna.h:99
CbmRichRonchiIntersectionData::fLineY
int fLineY
Definition: CbmRichRonchiAna.h:54
i
int i
Definition: L1/vectors/P4_F32vec4.h:25
CbmRichRonchiIntersectionData::fPixelY
int fPixelY
Definition: CbmRichRonchiAna.h:52
CbmRichRonchiAna::DoSuperpose
vector< vector< double > > DoSuperpose(const vector< vector< double >> &dataH, const vector< vector< double >> &dataV)
Definition: CbmRichRonchiAna.cxx:645
CbmRichRonchiAna::FillH2WithVector
void FillH2WithVector(TH2 *hist, const vector< vector< double >> &data)
Definition: CbmRichRonchiAna.cxx:357
CbmRichRonchiAna
Definition: CbmRichRonchiAna.h:103
CbmRichRonchiAna::DoIntersection
vector< CbmRichRonchiIntersectionData > DoIntersection(vector< vector< double >> &dataH, const vector< vector< double >> &dataV)
Definition: CbmRichRonchiAna.cxx:581
CbmRichRonchiAna::DoSmoothLines
void DoSmoothLines(vector< vector< double >> &data)
Definition: CbmRichRonchiAna.cxx:492
CbmRichRonchiLineData::fLineInd
int fLineInd
Definition: CbmRichRonchiAna.h:100
CbmRichRonchiAna::fCenterCcdY
double fCenterCcdY
Definition: CbmRichRonchiAna.h:143
CbmRichRonchiAna::GetIndexForLineXLineY
int GetIndexForLineXLineY(int lineX, int lineY, vector< CbmRichRonchiIntersectionData > &data)
Definition: CbmRichRonchiAna.cxx:1091
CbmDrawHist.h
Helper functions for drawing 1D and 2D histograms and graphs.
CbmRichRonchiAna::ReadTiffFile
vector< vector< double > > ReadTiffFile(const string &fileName)
Definition: CbmRichRonchiAna.cxx:318
CbmRichRonchiAna::DoDeviation
void DoDeviation(vector< CbmRichRonchiIntersectionData > &data)
Definition: CbmRichRonchiAna.cxx:1102
DrawH1
void DrawH1(TH1 *hist, HistScale logx, HistScale logy, const string &drawOpt, Int_t color, Int_t lineWidth, Int_t lineStyle, Int_t markerSize, Int_t markerStyle)
Definition: CbmDrawHist.cxx:49
CbmRichRonchiAna::DoMeanIntensityY
void DoMeanIntensityY(vector< vector< double >> &data)
Definition: CbmRichRonchiAna.cxx:370
CbmRichRonchiLineData
Definition: CbmRichRonchiAna.h:92
CbmRichRonchiAna::DrawXYMum
void DrawXYMum(vector< CbmRichRonchiIntersectionData > &data)
Definition: CbmRichRonchiAna.cxx:1160
CbmRichRonchiAna.h
CbmRichRonchiAna::RotatePointImpl
void RotatePointImpl(TVector3 *inPos, TVector3 *outPos, Double_t rotX, Double_t rotY, TVector3 *cV)
Definition: CbmRichRonchiAna.cxx:1559
CbmRichRonchiAna::DrawMirrorSegmentsSphere
void DrawMirrorSegmentsSphere(vector< CbmRichRonchiIntersectionData > &data, int orderedLineX, int orderedLineY)
Definition: CbmRichRonchiAna.cxx:1408
CbmRichRonchiIntersectionData::fLineX
int fLineX
Definition: CbmRichRonchiAna.h:53
CbmRichRonchiAna::fOffsetLEDOpticalAxisY
double fOffsetLEDOpticalAxisY
Definition: CbmRichRonchiAna.h:136
d
double d
Definition: P4_F64vec2.h:24
CbmRichRonchiAna::GetMinIndexForLineY
int GetMinIndexForLineY(int lineY, vector< CbmRichRonchiIntersectionData > &data)
Definition: CbmRichRonchiAna.cxx:1079
CbmRichRonchiAna::DoPeakFinderY
void DoPeakFinderY(vector< vector< double >> &data)
Definition: CbmRichRonchiAna.cxx:436
CbmRichRonchiAna::fOffsetCCDOptAxisY
double fOffsetCCDOptAxisY
Definition: CbmRichRonchiAna.h:133
CbmRichRonchiAna::UpdateIntersectionLineInd
void UpdateIntersectionLineInd(vector< CbmRichRonchiIntersectionData > &intersections, CbmRichRonchiLineData *line1, CbmRichRonchiLineData *line2, const string &option)
Definition: CbmRichRonchiAna.cxx:759
CbmRichRonchiAna::fTiffFileNameV
string fTiffFileNameV
Definition: CbmRichRonchiAna.h:115
ClassImp
ClassImp(CbmConverterManager) InitStatus CbmConverterManager
Definition: CbmConverterManager.cxx:12
CbmRichRonchiAna::AreTwoSegmentsSameLine
bool AreTwoSegmentsSameLine(const CbmRichRonchiLineData *line1, const CbmRichRonchiLineData *line2)
Definition: CbmRichRonchiAna.cxx:745
CbmRichRonchiAna::DoOrderLines
void DoOrderLines(vector< CbmRichRonchiIntersectionData > &intersections, const string &option)
Definition: CbmRichRonchiAna.cxx:662
CbmRichRonchiAna::fCenterCcdX
double fCenterCcdX
Definition: CbmRichRonchiAna.h:142
CbmRichRonchiLineData::fMeanPrimary
double fMeanPrimary
Definition: CbmRichRonchiAna.h:98
counter
int counter
Definition: CbmMvdSensorDigiToHitTask.cxx:72
CbmRichRonchiLineData::fNofPoints
int fNofPoints
Definition: CbmRichRonchiAna.h:97
CbmRichRonchiAna::DoLineSearch
void DoLineSearch(vector< vector< double >> &data)
Definition: CbmRichRonchiAna.cxx:524
CbmRichRonchiAna::DrawOneMirrorSegment
void DrawOneMirrorSegment(const TVector3 &tl, const TVector3 &tr, const TVector3 &bl, const TVector3 &br, int color)
Definition: CbmRichRonchiAna.cxx:1536
CbmRichRonchiAna::fDistMirrorRuling
double fDistMirrorRuling
Definition: CbmRichRonchiAna.h:129
x
Double_t x
Definition: CbmMvdSensorDigiToHitTask.cxx:68
CbmRichRonchiAna::fCcdPixelSize
double fCcdPixelSize
Definition: CbmRichRonchiAna.h:122
CbmRichRonchiAna::fPitchGrid
double fPitchGrid
Definition: CbmRichRonchiAna.h:123
y
Double_t y
Definition: CbmMvdSensorDigiToHitTask.cxx:68
cos
friend F32vec4 cos(const F32vec4 &a)
Definition: L1/vectors/P4_F32vec4.h:137
CbmRichRonchiAna::fTiffFileNameH
string fTiffFileNameH
Definition: CbmRichRonchiAna.h:116
CbmRichRonchiAna::CbmRichRonchiAna
CbmRichRonchiAna()
Definition: CbmRichRonchiAna.cxx:27
CbmRichRonchiAna::fOffsetCCDOptAxisX
double fOffsetCCDOptAxisX
Definition: CbmRichRonchiAna.h:131
DrawH2
void DrawH2(TH2 *hist, HistScale logx, HistScale logy, HistScale logz, const string &drawOpt)
Definition: CbmDrawHist.cxx:84
SetDefaultDrawStyle
void SetDefaultDrawStyle()
Definition: CbmDrawHist.cxx:33
CbmRichRonchiAna::DoLocalNormal
void DoLocalNormal(vector< CbmRichRonchiIntersectionData > &data)
Definition: CbmRichRonchiAna.cxx:773
CbmRichRonchiAna::fDistMirrorCCD
double fDistMirrorCCD
Definition: CbmRichRonchiAna.h:128
CbmRichRonchiIntersectionData
Definition: CbmRichRonchiAna.h:14
CbmRichRonchiAna::DoSphere
void DoSphere(vector< CbmRichRonchiIntersectionData > &intersections)
Definition: CbmRichRonchiAna.cxx:929
CbmRichRonchiAna::DoRotation
void DoRotation(vector< vector< double >> &data)
Definition: CbmRichRonchiAna.cxx:346
CbmRichRonchiAna::fRadiusMirror
double fRadiusMirror
Definition: CbmRichRonchiAna.h:120