KaliVeda
Toolkit for HIC analysis
KVPosition.cpp
1 /***************************************************************************
2 $Id: KVPosition.cpp,v 1.21 2008/12/17 13:01:26 franklan Exp $
3  kvposition.cpp - description
4  -------------------
5  begin : Sun May 19 2002
6  copyright : (C) 2002 by J.D. Frankland
7  email : frankland@ganil.fr
8  ***************************************************************************/
9 
10 /***************************************************************************
11  * *
12  * This program is free software; you can redistribute it and/or modify *
13  * it under the terms of the GNU General Public License as published by *
14  * the Free Software Foundation; either version 2 of the License, or *
15  * (at your option) any later version. *
16  * *
17  ***************************************************************************/
18 
19 #include "KVPosition.h"
20 #include "TRandom3.h"
21 #include "Riostream.h"
22 #include "TMath.h"
23 
24 
26 
27 #define ROOT_GEO_DO_NOT_USE(method,retval) \
28  if(ROOTGeo()){ \
29  ::Warning(method, "Does not work with ROOT geometries. Do not use."); \
30  return retval; \
31  }
32 
33 
35 
36 
38 
40  Double_t phmax, Double_t dist)
41 {
42  SetPolarMinMax(thmin, thmax);
43  SetAzimuthalMinMax(phmin, phmax);
45 }
46 
47 
48 
53 
55 {
56  //Sets the polar angle corresponding to the centre of this telescope/solid angle element/etc.
57  //If the polar width has been set already (KVPosition::SetPolarWidth),
58  //the limits theta-min and theta-max are calculated.
59 
60  fTheta = th;
61  if (fTheta_min == -180.) { // polar width of detector already set, calculate theta_min
62  // and theta_max
63  fTheta_min = fTheta - .5 * (fTheta_max + 180.);
64  fTheta_max = 2. * fTheta - fTheta_min;
65  }
66 }
67 
68 
69 
74 
76 {
77  //Sets the azimuthal angle corresponding to the centre of this telescope/solid angle element/etc.
78  //If the azimuthal width has been set already (KVPosition::SetAzimuthalWidth),
79  //the limits phi-min and phi-max are calculated.
80 
81  fPhi = ph;
82  //make sure phi between 0 and 360
83  if (fPhi < 0.)
84  fPhi += 360.;
85  if (fPhi_min == -180.) { // azimuthal width of detector already set, calculate phi_min
86  // and phi_max
87  fPhi_min = fPhi - .5 * (fPhi_max + 180.);
88  fPhi_max = 2. * fPhi - fPhi_min;
89  //make sure phimin and phimax are between 0 and 360
90  if (fPhi_min < 0.)
91  fPhi_min += 360.;
92  if (fPhi_max >= 360.)
93  fPhi_max -= 360.;
94  }
95 }
96 
97 
98 
104 
106 {
107  //Set theta_min and theta_max from width (in degrees).
108  //If theta is already known, use to set theta_min and theta_max.
109  //If not, keep relative values (negative) of theta_min and theta_max,
110  //to be used when theta is set
111 
112  ROOT_GEO_DO_NOT_USE("SetPolarWidth",)
113 
114  if (fTheta > -1.0) {
115  fTheta_min = fTheta - .5 * pw;
116  fTheta_max = fTheta + .5 * pw;
117  }
118  else {
119  fTheta_min = -180.;
120  fTheta_max = fTheta_min + pw;
121  }
122 }
123 
124 
125 
128 
130 {
131  //Set min and max polar angles and calculate (mean) theta
132 
133  ROOT_GEO_DO_NOT_USE("SetPolarMinMax",)
134  fTheta_min = min;
135  fTheta_max = max;
136  fTheta = .5 * (min + max);
137 }
138 
139 
140 
146 
148 {
149  //Set phi_min and phi_max from width (in degrees)
150  // If phi is already known, use to set phi_min and phi_max
151  // If not, keep relative values (negative) of phi_min and phi_max,
152  // to be used when phi is set
153 
154  ROOT_GEO_DO_NOT_USE("SetAzimuthalWidth",)
155  if (fPhi > -1.0) {
156  fPhi_min = fPhi - .5 * aw;
157  if (fPhi_min < 0.)
158  fPhi_min += 360.;
159  fPhi_max = fPhi + .5 * aw;
160  if (fPhi_max >= 360.)
161  fPhi_max -= 360.;
162  }
163  else {
164  fPhi_min = -180.;
165  fPhi_max = fPhi_min + aw;
166  }
167 }
168 
169 
170 
173 
175 {
176  //Set min and max azimuthal angles and calculate (mean) phi
177 
178  ROOT_GEO_DO_NOT_USE("SetAzimuthalMinMax",)
179  fPhi_min = min;
180  fPhi_max = max;
181  if (min > max)
182  max += 360;
183  fPhi = .5 * (min + max);
184  if (fPhi >= 360.)
185  fPhi -= 360.;
186 }
187 
188 
189 
199 
201 {
202  // Returns a unit vector in a random direction corresponding to this detector.
203  // Depending on the optional option string, the direction is either drawn at
204  // "random" among the corresponding angles, or "isotropic".
205  // By default, the direction is "isotropic".
206  //
207  // * ROOT Geometry *
208  // Direction corresponds to a random position on the entrance surface of the volume.
209  // The "isotropic" option has no effect.
210 
211  if (ROOTGeo()) {
212  // * ROOT Geometry *
214  return r.Unit();
215  }
216 
217  Double_t dtor = TMath::DegToRad();
218  Double_t th, ph;
219  GetRandomAngles(th, ph, t);
220  TVector3 dummy;
221  dummy.SetMagThetaPhi(1.0, th * dtor, ph * dtor); // a unit vector
222 
223  return dummy;
224 }
225 
226 
237 
239 {
240  // Set th and ph to random values between the max and min limits defining the
241  // solid angle element.
242  // Depending on the optional option string, the direction is either drawn at
243  // "random" among the corresponding angles, or "isotropic".
244  // By default, the direction is "isotropic".
245  //
246  // * ROOT Geometry *
247  // th and ph correspond to a random position on the detector's entrance window.
248  // The "isotropic" option has no effect.
249 
250  Double_t dtor = TMath::DegToRad();
251 
252  if (ROOTGeo()) {
253  // * ROOT Geometry *
255  th = r.Theta() / dtor;
256  ph = r.Phi() / dtor;
257  if (ph < 0) ph += 360.;
258  return;
259  }
260 
261  Double_t phmin = fPhi_min; //phimin in radians
262  Double_t phmax = fPhi_max; //phimax in radians
263  if (phmax < phmin)
264  phmax += 360;
265 
266  Double_t dphi = phmax - phmin;
267  Double_t thmin, thmax, dtheta;
268 
269  if (!strcmp(t, "random")) {
270  thmin = fTheta_min * dtor;
271  thmax = fTheta_max * dtor;
272  dtheta = thmax - thmin;
273  th = gRandom->Uniform(dtheta) + thmin;
274  }
275  else {
276  thmin = TMath::Cos(fTheta_min * dtor);
277  thmax = TMath::Cos(fTheta_max * dtor);
278  dtheta = thmin - thmax;
279  th = TMath::ACos(gRandom->Uniform(dtheta) + thmax);
280  }
281  ph = gRandom->Uniform(dphi) + phmin;
282  if (ph > 360)
283  ph -= 360;
284  th /= dtor;
285 
286 }
287 
288 
289 
293 
295 {
296  // For ROOT geometries, perform a Monte-Carlo sampling in order to estimate the min/max
297  // polar and azimuthal angles of this volume
298 
299  fTheta_min=fPhi_min=999;
300  fTheta_max=fPhi_max=-1;
301  fMaxMisalignment=-1;
302  while(N--)
303  {
305  auto th = r.Theta() / TMath::RadToDeg();
306  auto ph = r.Phi() / TMath::RadToDeg();
307  if (ph < 0) ph += 360.;
308  fTheta_max = std::max(fTheta_max,th);
309  fPhi_max = std::max(fPhi_max,ph);
310  fTheta_min = std::min(fTheta_min,th);
311  fPhi_min = std::min(fPhi_min,ph);
312  auto misalign = TMath::ACos(r.Dot(GetNormalIntoShape()))*TMath::RadToDeg();
313  fMaxMisalignment = std::max(fMaxMisalignment,misalign);
314  }
315 }
316 
317 
318 
322 
324 {
325  //kTRUE if given angle phi is within the azimuthal range of this solid
326  //angle element
327 
328  ROOT_GEO_DO_NOT_USE("IsInPhiRange", kFALSE)
329 
330  Double_t phimintest = fPhi_min;
331  Double_t phimaxtest = fPhi_max;
332  if (phimintest > phimaxtest) {
333  phimaxtest += 360.;
334  }
335  if (phi >= phimintest && phi <= phimaxtest) {
336  return kTRUE;
337  }
338  if ((phi + 360.) >= phimintest && (phi + 360.) <= phimaxtest) {
339  return kTRUE;
340  }
341  return kFALSE;
342 }
343 
344 
345 
348 
350 {
351  //kTRUE if given angle theta is within the polar range of this solid angle element
352 
353  ROOT_GEO_DO_NOT_USE("IsInPolarRange", kFALSE)
354 
355  if (theta >= fTheta_min && theta <= fTheta_max)
356  return kTRUE;
357  else
358  return kFALSE;
359 }
360 
361 
362 
365 
367 {
368  // kTRUE if "this" is entirely contained within "pos"
369 
370  ROOT_GEO_DO_NOT_USE("IsSmallerThan", kFALSE)
371  return (pos->IsInPolarRange(GetThetaMin())
372  && pos->IsInPolarRange(GetThetaMax())
373  && pos->IsInPhiRange(GetPhiMin())
374  && pos->IsInPhiRange(GetPhiMax()));
375 }
376 
377 
378 
381 
383 {
384  //kTRUE if one of the two solid angle elements is completely contained within the other.
385 
386  ROOT_GEO_DO_NOT_USE("IsAlignedWith", kFALSE)
387  return (IsSmallerThan(pos) || pos->IsSmallerThan(this));
388 }
389 
390 
391 
394 
396 {
397  //kTRUE if there is at least partial overlap between two solid angle elements
398 
399  ROOT_GEO_DO_NOT_USE("IsOverlappingWith", kFALSE)
400  return (
401  //overlapping corners - case 1
402  (IsInPolarRange(other->GetThetaMin())
403  || IsInPolarRange(other->GetThetaMax()))
404  && (IsInPhiRange(other->GetPhiMin())
405  || IsInPhiRange(other->GetPhiMax()))
406  ) || (
407  //overlapping corners - case 2
408  (other->IsInPolarRange(GetThetaMin())
409  || other->IsInPolarRange(GetThetaMax()))
410  && (other->IsInPhiRange(GetPhiMin())
411  || other->IsInPhiRange(GetPhiMax()))
412  ) || (
413  //case where this is phi-contained by the other, but the other is theta-contained by this
414  (other->IsInPolarRange(GetThetaMin())
415  || other->IsInPolarRange(GetThetaMax()))
416  && (IsInPhiRange(other->GetPhiMin())
417  || IsInPhiRange(other->GetPhiMax()))
418  ) || (
419  //case where this is phi-contained by the other, but the other is theta-contained by this
420  (IsInPolarRange(other->GetThetaMin())
421  || IsInPolarRange(other->GetThetaMax()))
422  && (other->IsInPhiRange(GetPhiMin())
423  || other->IsInPhiRange(GetPhiMax()))
424  );
425 }
426 
427 
428 
432 
434 {
435  //kTRUE if "this" has larger azimuthal width than "pos".
436  //Takes care of cases where the solid angle straddles 0 degrees
437 
438  ROOT_GEO_DO_NOT_USE("IsAzimuthallyWiderThan", kFALSE)
439  if (GetAzimuthalWidth() > pos->GetAzimuthalWidth())
440  return kTRUE;
441  return kFALSE;
442 }
443 
444 
445 
449 
451 {
452  //Returns a unit vector corresponding to the direction of fTheta, fPhi
453  //i.e. the centre of the solid angle element.
454 
455  TVector3 tmp(1.0, 0.0, 0.0);
456  tmp.SetTheta(fTheta * TMath::Pi() / 180.);
457  tmp.SetPhi(fPhi * TMath::Pi() / 180.);
458  return tmp;
459 }
460 
461 
462 
463 
482 
484 {
485  // Fill the array (TVector3 corner[4]) with the coordinates of the 4 'corners' of the solid angle element.
486  //
487  // These 'corners' are the points of intersection between the plane defined by the normal
488  // to the centre of the solid angle (direction: theta,phi), at a distance fDistance [cm] from the
489  // origin, and the four lines starting at the origin with directions (thetamin,phimin),
490  // (thetamax,phimin), (thetamax,phimax), (thetamin,phimax).
491  //
492  // If optional argument 'depth' [cm] is given, the coordinates are calculated for the plane
493  // situated at distance (fDistance+depth) from the origin.
494  //
495  // The order of the 4 corners is as follows:
496  // corners[3] : theta-min, phi-min
497  // corners[2] : theta-max, phi-min
498  // corners[1] : theta-max, phi-max
499  // corners[0] : theta-min, phi-max
500  //
501  // Coordinates are in CENTIMETRES
502 
503  ROOT_GEO_DO_NOT_USE("GetCornerCoordinates",)
504 
505  // calculate unit vector normal to solid angle
506  Double_t pthR = GetTheta() * TMath::DegToRad();
507  Double_t pphR = GetPhi() * TMath::DegToRad();
508  TVector3 normal_to_plane(sin(pthR)*cos(pphR), sin(pthR)*sin(pphR), cos(pthR));
509 
510  // the four directions/lines
515 
516  // calculate intersection points
517  for (int i = 0; i < 4; i++) {
518  Double_t t = corners[i] * normal_to_plane;
519  if (t <= 0.0) corners[i].SetXYZ(0, 0, 0);
520  else corners[i] *= (fDistance + depth) / t;
521  }
522 }
523 
524 
525 
526 
530 
532 {
533  // Like GetCornerCoordinates(), except that the coordinates correspond to a reference frame
534  // in which the +ve z-axis goes through the centre of the solid angle
535 
536  ROOT_GEO_DO_NOT_USE("GetCornerCoordinatesInOwnFrame",)
537  GetCornerCoordinates(corners, depth);
538  TRotation rot_to_frame;
539  rot_to_frame.SetYEulerAngles(-GetPhi()*TMath::DegToRad(), -GetTheta()*TMath::DegToRad(), 0.);
540  TVector3 displZ(0, 0, fDistance + depth);
541  for (int i = 0; i < 4; i++) {
542  corners[i] = rot_to_frame * corners[i] - displZ;
543  }
544 }
545 
546 
547 
553 
555 {
556  // Return values of the solid angle (in msr) seen by the geometric ensemble
557  // For simple geometries defined by theta_min/max etc., this is exact.
558  // For ROOT geometries we calculate the area of the entrance window and divide
559  // it by the square of the distance to the detector.
560 
561  if (ROOTGeo()) {
562  if (!fSolidAngle) {
563  // TGeoArb8 shapes' solid angles calculated on demand as this requires
564  // a monte carlo calculation
565  // this takes into account any eventual "misalignment" i.e. if the vector from the
566  // origin to the centre of the volume is not perpendicular to the entrance surface,
567  // which reduces the effective area "seen" from the target
569  fSolidAngle = area / pow(GetDistance(), 2.) * 1.e3;
570  }
571  return fSolidAngle;
572  }
573 
574  return (-1.*cos(GetThetaMax() * TMath::DegToRad()) +
576  * (GetAzimuthalWidth() * TMath::DegToRad()) * 1.e3;
577 
578 }
579 
580 
581 
582 
583 
589 
591 {
592  //Calculate azimuthal width taking phi-min as the most anticlockwise point of the
593  //element and phi-max the most clockwise.
594  //If no arguments are given, width calculated for this object
595  //Otherwise, width calculated for given phi-min and phi-max
596 
597  ROOT_GEO_DO_NOT_USE("GetAzimuthalWidth", 0.)
598 
599  if (phmin == -1.)
600  phmin = GetPhiMin();
601  if (phmax == -1.)
602  phmax = GetPhiMax();
603  if (phmin < phmax)
604  return (phmax - phmin);
605  else
606  return (phmax - phmin + 360.);
607 }
608 
609 
610 
611 
616 
618 {
619  //Calculate azimuthal and polar widths for a square element placed at a
620  //given distance from the origin with linear dimension 'lin_dim' (in mm).
621  //SetDistance, SetTheta and SetPhi must already have been called.
622 
623  if (GetDistance() <= 0.0) {
624  Error("GetWidthsFromDimension", "Distance not set");
625  return;
626  }
627  Double_t d__th =
628  2. * TMath::RadToDeg() * TMath::ATan(lin_dim /
629  (2. * GetDistance()));
630  Double_t d__ph =
631  TMath::RadToDeg() * lin_dim / (GetDistance() * GetSinTheta());
632  SetPolarWidth(d__th);
633  SetAzimuthalWidth(d__ph);
634 }
635 
636 
637 
642 
644 {
645  // Generates a rotation which, if applied to a unit vector in the Z-direction,
646  // will transform it into an isotropically-distributed vector in this
647  // angular range.
648 
649  TRotation rr2;
650  ROOT_GEO_DO_NOT_USE("GetRandomIsotropicRotation", rr2)
651  Double_t a1min, a1max, a2min, a2max, a3min, a3max;
652  a1min = 0;
653  a1max = 2 * TMath::Pi();
654  a2min = GetThetaMin() * TMath::DegToRad();
655  a2max = GetThetaMax() * TMath::DegToRad();
656  a3min = GetPhiMin() * TMath::DegToRad();
657  a3max = GetPhiMax() * TMath::DegToRad();
658  a3min += TMath::Pi() / 2.;
659  a3max += TMath::Pi() / 2.;
660  rr2.SetXEulerAngles(gRandom->Uniform(a1min, a1max),
661  TMath::ACos(gRandom->Uniform(cos(a2max), cos(a2min))),
662  gRandom->Uniform(a3min, a3max));
663  return rr2;
664 }
665 
666 
668 
669 
679 
681 {
682  // Initialization of ROOT geometry object
683  //
684  // We set the \f$(\theta,\phi)\f$ angles
685  // corresponding to the centre of the volume, and
686  // the distance from the target corresponding to the distance
687  // along \f$(\theta,\phi)\f$ to the entrance surface of the volume
688  // (not necessarily the same as the distance from the target to
689  // the centre of the entrance surface)
690 
694  TVector3 centre = GetVolumeCentre();
695  SetTheta(centre.Theta()*TMath::RadToDeg());
696  SetPhi(centre.Phi()*TMath::RadToDeg());
698  // solid angle calculated and set here only for non-TGeoArb8 shapes
699  // this takes into account any eventual "misalignment" i.e. if the vector from the
700  // origin to the centre of the volume is not perpendicular to the entrance surface,
701  // which reduces the effective area "seen" from the target
702  if (!GetShape()->InheritsFrom("TGeoArb8")) {
704  fSolidAngle = area / pow(GetDistance(), 2.) * 1.e3;
705  }
706 }
707 
708 
709 
712 
714 {
715  // Set the global transformation matrix for this volume
716 
717  fMatrix.reset(new TGeoHMatrix(*m));
718  if (ROOTGeo()) {
720  }
721 }
722 
723 
724 
728 
730 {
731  // Set the shape of this volume
732  //
733 
734  fShape = b;
735  if (ROOTGeo()) {
737  }
738 }
739 
740 
741 
745 
747 {
748  // * ROOT Geometry *
749  // Return global transformation matrix for this detector
750  return fMatrix.get();
751 }
752 
753 
754 
758 
760 {
761  // * ROOT Geometry *
762  // Return shape of this detector
763  return fShape;
764 }
765 
766 
767 
781 
783 {
784  // * ROOT Geometry *
785  // Generate a vector in the world (laboratory) frame from the origin
786  // to a random point on the entrance surface of this volume.
787  //
788  // It is assumed that the volume was defined in such a way
789  // that the entrance window corresponds to the facet in the X-Y plane
790  // placed at -dZ.
791  //
792  // NOTE: we force the use of TGeoBBox::GetPointsOnFacet.
793  // For TGeoArb8, the method has been overridden and does nothing.
794  // We use the TGeoBBox method, and then use TGeoShape::Contains
795  // to check that the point does actually correspond to the TGeoArb8.
796 
797  if (!ROOTGeo()) {
798  ::Error("KVPosition::GetRandomPointOnSurface",
799  "ROOT Geometry has not been initialised");
800  return TVector3();
801  }
802  Double_t master[3 * 50];
803  Double_t points[3 * 50];
804  const Double_t* origin = GetShape()->GetOrigin();
805  Double_t dz = GetShape()->GetDZ();
806  // This will generate a point on the (-DZ) face of the bounding box of the shape
807  Bool_t ok1 = GetShape()->TGeoBBox::GetPointsOnFacet(1, 50, points);
808  // We move the point slightly inside the volume to test if it actually corresponds
809  // to a point on the shape's facet
810  points[2] += dz / 100.;
811  // Correct for offset of centre of shape
812  for (int i = 0; i < 3; i++) points[i] += origin[i];
813  Bool_t ok2 = GetShape()->Contains(points);
814  if (!ok1) {
815  ::Error("KVPosition::GetRandomPoint",
816  "TGeoBBox::GetPointsOnFacet returns kFALSE for shape %s. Returning coordinates of centre.", GetShape()->ClassName());
817  return GetSurfaceCentre();
818  }
819  Int_t np = 0;
820  if (!ok2) {
821  // try to find a point that works
822  np++;
823  while (np < 50) {
824  Double_t* npoint = points + 3 * np;
825  npoint[2] += dz / 100.;
826  // Correct for offset of centre of shape
827  for (int i = 0; i < 3; i++) npoint[i] += origin[i];
828  ok2 = GetShape()->Contains(npoint);
829  if (ok2) break;
830  np++;
831  }
832  if (!ok2) {
833  ::Error("KVPosition::GetRandomPointOnSurface",
834  "Cannot generate points for shape %s. Returning coordinates of surface centre.", GetShape()->ClassName());
835  return GetSurfaceCentre();
836  }
837  }
838  Double_t* npoint = points + 3 * np;
839  npoint[2] -= dz / 100.;
840  GetMatrix()->LocalToMaster(npoint, master);
841  return TVector3(master);
842 }
843 
844 
845 
854 
856 {
857  // * ROOT Geometry *
858  // Generate a vector in the world (laboratory) frame from the origin
859  // to the centre of the entrance surface of the volume.
860  //
861  // It is assumed that the volume was defined in such a way
862  // that the entrance surface corresponds to the facet in the X-Y plane
863  // placed at -dZ.
864 
865  Double_t master[3];
866  const Double_t* origin = GetShape()->GetOrigin();
867  Double_t points[] = {origin[0], origin[1], origin[2] - GetShape()->GetDZ()};
868  GetMatrix()->LocalToMaster(points, master);
869  fSurfaceCentre = TVector3(master);
870 }
871 
872 
873 
878 
880 {
881  // * ROOT Geometry *
882  // Generate a vector in the world (laboratory) frame from the origin
883  // to the centre of the volume.
884 
885  Double_t master[3];
886  const Double_t* origin = GetShape()->GetOrigin();
887  Double_t points[] = {origin[0], origin[1], origin[2]};
888  GetMatrix()->LocalToMaster(points, master);
889  fVolumeCentre = TVector3(master);
890 }
891 
892 
893 
901 
903 {
904  // Monte Carlo calculation of entrance surface area for TGeoArb8 shapes
905  // Area is calculated as area of bounding box facet multiplied by the ratio between
906  // number of random points actually on the shape surface to the number of points
907  // npoints generated over the surface of the bounding box facet
908  //
909  // npoints is the number of points to test
910 
911  Double_t* points = new Double_t[3 * npoints];
912  const Double_t* origin = GetShape()->GetOrigin();
913  Double_t dz = GetShape()->GetDZ();
914  // This will generate npoints points on the (-DZ) face of the bounding box of the shape
915  Bool_t ok1 = GetShape()->TGeoBBox::GetPointsOnFacet(1, npoints, points);
916  if (!ok1) {
917  ::Error("KVPosition::GetEntranceWindowArea",
918  "TGeoBBox::GetPointsOnFacet returns kFALSE for shape %s. Returning 0.0", GetShape()->ClassName());
919  delete [] points;
920  return 0.0;
921  }
922  Double_t points_on_facet = 0;
923  for (Int_t np = 0; np < npoints; ++np) {
924  Double_t* npoint = points + 3 * np;
925  // We move the point slightly inside the volume to test if it actually corresponds
926  // to a point on the shape's facet
927  npoint[2] += dz / 100.;
928  // Correct for offset of centre of shape
929  for (int i = 0; i < 3; i++) npoint[i] += origin[i];
930  if (GetShape()->Contains(npoint)) ++points_on_facet;
931  }
932  delete [] points;
933  return GetShape()->GetFacetArea(1) * (points_on_facet / Double_t(npoints));
934 }
935 
936 
937 
938 
939 
940 
941 
942 
int Int_t
ROOT::R::TRInterface & r
bool Bool_t
constexpr Bool_t kFALSE
double Double_t
constexpr Bool_t kTRUE
const char Option_t
#define N
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t b
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t np
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t points
R__EXTERN TRandom * gRandom
Base class used for handling geometry in a multidetector array.
Definition: KVPosition.h:92
virtual void GetRandomAngles(Double_t &th, Double_t &ph, Option_t *t="isotropic")
Definition: KVPosition.cpp:238
Bool_t IsInPhiRange(const Double_t phi)
Definition: KVPosition.cpp:323
void set_surface_centre()
Definition: KVPosition.cpp:855
virtual void SetAzimuthalWidth(Double_t aw)
Definition: KVPosition.cpp:147
virtual TVector3 GetRandomDirection(Option_t *t="isotropic")
Definition: KVPosition.cpp:200
Bool_t IsAzimuthallyWiderThan(KVPosition *pos)
Definition: KVPosition.cpp:433
virtual void SetShape(TGeoBBox *)
Definition: KVPosition.cpp:729
virtual void SetAzimuthalMinMax(Double_t min, Double_t max)
Set min and max azimuthal angles and calculate (mean) phi.
Definition: KVPosition.cpp:174
virtual void SetAzimuthalAngle(Double_t ph)
Definition: KVPosition.cpp:75
virtual Double_t GetSolidAngle(void) const
Definition: KVPosition.cpp:554
virtual Double_t GetTheta() const
Definition: KVPosition.h:216
void GetCornerCoordinates(TVector3 *, Double_t=0)
Definition: KVPosition.cpp:483
void initialize_root_geo()
Definition: KVPosition.cpp:680
Double_t fTheta
Definition: KVPosition.h:94
TVector3 fNormal
Definition: KVPosition.h:108
virtual TGeoHMatrix * GetMatrix() const
Definition: KVPosition.cpp:746
virtual TVector3 GetSurfaceCentre() const
Definition: KVPosition.h:267
void GetWidthsFromDimension(Double_t lin_dim)
Definition: KVPosition.cpp:617
void SetDistance(Double_t d)
Definition: KVPosition.h:242
TRotation GetRandomIsotropicRotation()
Definition: KVPosition.cpp:643
virtual TVector3 GetVolumeCentre() const
Definition: KVPosition.h:271
virtual void SetPolarAngle(Double_t th)
Definition: KVPosition.cpp:54
virtual Double_t GetPhi() const
Definition: KVPosition.h:228
Double_t GetPhiMax() const
Definition: KVPosition.h:196
virtual Double_t GetDistance(void) const
Definition: KVPosition.h:246
Double_t fSolidAngle
Definition: KVPosition.h:105
Double_t GetPhiMin() const
Definition: KVPosition.h:190
Bool_t IsSmallerThan(KVPosition *pos)
kTRUE if "this" is entirely contained within "pos"
Definition: KVPosition.cpp:366
Double_t fMaxMisalignment
Definition: KVPosition.h:109
std::unique_ptr< TGeoHMatrix > fMatrix
transform world<->detector coordinates
Definition: KVPosition.h:103
virtual Double_t GetSurfaceArea(int npoints=100000) const
Definition: KVPosition.cpp:902
Double_t GetThetaMin() const
Definition: KVPosition.h:202
void set_volume_centre()
Definition: KVPosition.cpp:879
virtual Double_t GetSinTheta() const
Definition: KVPosition.h:220
TVector3 fVolumeCentre
Definition: KVPosition.h:106
Double_t GetOC_SC_CosAngle() const
Definition: KVPosition.h:111
virtual TVector3 GetNormalIntoShape() const
Definition: KVPosition.h:275
Double_t fTheta_min
Definition: KVPosition.h:96
Double_t GetAzimuthalWidth(Double_t phmin=-1., Double_t phimax=-1.) const
Definition: KVPosition.cpp:590
Bool_t IsInPolarRange(const Double_t theta)
kTRUE if given angle theta is within the polar range of this solid angle element
Definition: KVPosition.cpp:349
virtual void SetPolarWidth(Double_t pw)
Definition: KVPosition.cpp:105
Bool_t IsAlignedWith(KVPosition *pos)
kTRUE if one of the two solid angle elements is completely contained within the other.
Definition: KVPosition.cpp:382
Double_t fTheta_max
Definition: KVPosition.h:97
void SetTheta(Double_t t)
Definition: KVPosition.h:234
void CalculateEstimatedAngularLimits(int N=10000)
Definition: KVPosition.cpp:294
Double_t fPhi
Definition: KVPosition.h:95
TGeoBBox * fShape
Definition: KVPosition.h:104
TVector3 fSurfaceCentre
Definition: KVPosition.h:107
void SetPhi(Double_t p)
Definition: KVPosition.h:238
virtual void SetPolarMinMax(Double_t min, Double_t max)
Set min and max polar angles and calculate (mean) theta.
Definition: KVPosition.cpp:129
virtual void SetMatrix(const TGeoHMatrix *)
Set the global transformation matrix for this volume.
Definition: KVPosition.cpp:713
KVPosition()=default
virtual TGeoBBox * GetShape() const
Definition: KVPosition.cpp:759
Double_t fPhi_max
Definition: KVPosition.h:99
Double_t fPhi_min
Definition: KVPosition.h:98
Bool_t IsOverlappingWith(KVPosition *pos)
kTRUE if there is at least partial overlap between two solid angle elements
Definition: KVPosition.cpp:395
virtual Bool_t ROOTGeo() const
Definition: KVPosition.h:257
Double_t fDistance
Definition: KVPosition.h:100
void GetCornerCoordinatesInOwnFrame(TVector3 *, Double_t=0)
Definition: KVPosition.cpp:531
Double_t GetThetaMax() const
Definition: KVPosition.h:208
virtual TVector3 GetDirection()
Definition: KVPosition.cpp:450
virtual TVector3 GetRandomPointOnSurface() const
Definition: KVPosition.cpp:782
virtual const Double_t * GetOrigin() const
virtual Double_t GetFacetArea(Int_t index=0) const
virtual Double_t GetDZ() const
Bool_t Contains(const Double_t *point) const override
virtual void LocalToMaster(const Double_t *local, Double_t *master) const
virtual Double_t Uniform(Double_t x1, Double_t x2)
TRotation & SetXEulerAngles(Double_t phi, Double_t theta, Double_t psi)
TRotation & SetYEulerAngles(Double_t phi, Double_t theta, Double_t psi)
void SetMagThetaPhi(Double_t mag, Double_t theta, Double_t phi)
void SetXYZ(Double_t x, Double_t y, Double_t z)
void SetPhi(Double_t)
Double_t Phi() const
Double_t Theta() const
void SetTheta(Double_t)
RooCmdArg ClassName(const char *name)
SVector< T, D > Unit(const SVector< T, D > &rhs)
T Mag(const SVector< T, D > &rhs)
RVec< PromoteType< T > > cos(const RVec< T > &v)
RVec< PromoteTypes< T0, T1 > > pow(const T0 &x, const RVec< T1 > &v)
RVec< PromoteType< T > > sin(const RVec< T > &v)
double dist(AxisAngle const &r1, AxisAngle const &r2)
void Error(const char *location, const char *fmt,...)
double min(double x, double y)
double max(double x, double y)
Double_t ACos(Double_t)
Double_t ATan(Double_t)
constexpr Double_t DegToRad()
Double_t Cos(Double_t)
constexpr Double_t Pi()
constexpr Double_t RadToDeg()
TMarker m
ClassImp(TPyArg)