KaliVeda
Toolkit for HIC analysis
Loading...
Searching...
No Matches
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#include "TGeoMatrix.h"
24#include "TGeoBBox.h"
25
26
28
29#define ROOT_GEO_DO_NOT_USE(method,retval) \
30 if(ROOTGeo()){ \
31 ::Warning(method, "Does not work with ROOT geometries. Do not use."); \
32 return retval; \
33 }
34
35
37
38
39
42
44{
45 //default initialiser
46
47 fTheta = fPhi = -1.0;
49 fMatrix = 0;
50 fShape = 0;
51 fSolidAngle = 0;
52}
53
54
55
57
59{
60 if (fMatrix) {
61 delete fMatrix;
62 fMatrix = 0;
63 }
64}
65
66
67
69
74
75
76
78
80 Double_t phmax, Double_t dist)
81{
82 init();
83 SetPolarMinMax(thmin, thmax);
84 SetAzimuthalMinMax(phmin, phmax);
86};
87
88
89
90
95
97{
98 //Sets the polar angle corresponding to the centre of this telescope/solid angle element/etc.
99 //If the polar width has been set already (KVPosition::SetPolarWidth),
100 //the limits theta-min and theta-max are calculated.
101
102 fTheta = th;
103 if (fTheta_min == -180.) { // polar width of detector already set, calculate theta_min
104 // and theta_max
105 fTheta_min = fTheta - .5 * (fTheta_max + 180.);
107 }
108}
109
110
111
116
118{
119 //Sets the azimuthal angle corresponding to the centre of this telescope/solid angle element/etc.
120 //If the azimuthal width has been set already (KVPosition::SetAzimuthalWidth),
121 //the limits phi-min and phi-max are calculated.
122
123 fPhi = ph;
124 //make sure phi between 0 and 360
125 if (fPhi < 0.)
126 fPhi += 360.;
127 if (fPhi_min == -180.) { // azimuthal width of detector already set, calculate phi_min
128 // and phi_max
129 fPhi_min = fPhi - .5 * (fPhi_max + 180.);
130 fPhi_max = 2. * fPhi - fPhi_min;
131 //make sure phimin and phimax are between 0 and 360
132 if (fPhi_min < 0.)
133 fPhi_min += 360.;
134 if (fPhi_max >= 360.)
135 fPhi_max -= 360.;
136 }
137}
138
139
140
146
148{
149 //Set theta_min and theta_max from width (in degrees).
150 //If theta is already known, use to set theta_min and theta_max.
151 //If not, keep relative values (negative) of theta_min and theta_max,
152 //to be used when theta is set
153
154 ROOT_GEO_DO_NOT_USE("SetPolarWidth",)
155
156 if (fTheta > -1.0) {
157 fTheta_min = fTheta - .5 * pw;
158 fTheta_max = fTheta + .5 * pw;
159 }
160 else {
161 fTheta_min = -180.;
162 fTheta_max = fTheta_min + pw;
163 }
164}
165
166
167
170
172{
173 //Set min and max polar angles and calculate (mean) theta
174
175 ROOT_GEO_DO_NOT_USE("SetPolarMinMax",)
176 fTheta_min = min;
177 fTheta_max = max;
178 fTheta = .5 * (min + max);
179}
180
181
182
188
190{
191 //Set phi_min and phi_max from width (in degrees)
192 // If phi is already known, use to set phi_min and phi_max
193 // If not, keep relative values (negative) of phi_min and phi_max,
194 // to be used when phi is set
195
196 ROOT_GEO_DO_NOT_USE("SetAzimuthalWidth",)
197 if (fPhi > -1.0) {
198 fPhi_min = fPhi - .5 * aw;
199 if (fPhi_min < 0.)
200 fPhi_min += 360.;
201 fPhi_max = fPhi + .5 * aw;
202 if (fPhi_max >= 360.)
203 fPhi_max -= 360.;
204 }
205 else {
206 fPhi_min = -180.;
207 fPhi_max = fPhi_min + aw;
208 }
209}
210
211
212
215
217{
218 //Set min and max azimuthal angles and calculate (mean) phi
219
220 ROOT_GEO_DO_NOT_USE("SetAzimuthalMinMax",)
221 fPhi_min = min;
222 fPhi_max = max;
223 if (min > max)
224 max += 360;
225 fPhi = .5 * (min + max);
226 if (fPhi >= 360.)
227 fPhi -= 360.;
228}
229
230
231
241
243{
244 // Returns a unit vector in a random direction corresponding to this detector.
245 // Depending on the optional option string, the direction is either drawn at
246 // "random" among the corresponding angles, or "isotropic".
247 // By default, the direction is "isotropic".
248 //
249 // * ROOT Geometry *
250 // Direction corresponds to a random position on the entrance surface of the volume.
251 // The "isotropic" option has no effect.
252
253 if (ROOTGeo()) {
254 // * ROOT Geometry *
256 return r.Unit();
257 }
258
259 Double_t dtor = TMath::DegToRad();
260 Double_t th, ph;
261 GetRandomAngles(th, ph, t);
262 TVector3 dummy;
263 dummy.SetMagThetaPhi(1.0, th * dtor, ph * dtor); // a unit vector
264
265 return dummy;
266}
267
268
279
281{
282 // Set th and ph to random values between the max and min limits defining the
283 // solid angle element.
284 // Depending on the optional option string, the direction is either drawn at
285 // "random" among the corresponding angles, or "isotropic".
286 // By default, the direction is "isotropic".
287 //
288 // * ROOT Geometry *
289 // th and ph correspond to a random position on the detector's entrance window.
290 // The "isotropic" option has no effect.
291
292 Double_t dtor = TMath::DegToRad();
293
294 if (ROOTGeo()) {
295 // * ROOT Geometry *
297 th = r.Theta() / dtor;
298 ph = r.Phi() / dtor;
299 if (ph < 0) ph += 360.;
300 return;
301 }
302
303 Double_t phmin = fPhi_min; //phimin in radians
304 Double_t phmax = fPhi_max; //phimax in radians
305 if (phmax < phmin)
306 phmax += 360;
307
308 Double_t dphi = phmax - phmin;
309 Double_t thmin, thmax, dtheta;
310
311 if (!strcmp(t, "random")) {
312 thmin = fTheta_min * dtor;
313 thmax = fTheta_max * dtor;
314 dtheta = thmax - thmin;
315 th = gRandom->Uniform(dtheta) + thmin;
316 }
317 else {
318 thmin = TMath::Cos(fTheta_min * dtor);
319 thmax = TMath::Cos(fTheta_max * dtor);
320 dtheta = thmin - thmax;
321 th = TMath::ACos(gRandom->Uniform(dtheta) + thmax);
322 }
323 ph = gRandom->Uniform(dphi) + phmin;
324 if (ph > 360)
325 ph -= 360;
326 th /= dtor;
327
328}
329
330
331
335
337{
338 //kTRUE if given angle phi is within the azimuthal range of this solid
339 //angle element
340
341 ROOT_GEO_DO_NOT_USE("IsInPhiRange", kFALSE)
342
343 Double_t phimintest = fPhi_min;
344 Double_t phimaxtest = fPhi_max;
345 if (phimintest > phimaxtest) {
346 phimaxtest += 360.;
347 }
348 if (phi >= phimintest && phi <= phimaxtest) {
349 return kTRUE;
350 }
351 if ((phi + 360.) >= phimintest && (phi + 360.) <= phimaxtest) {
352 return kTRUE;
353 }
354 return kFALSE;
355}
356
357
358
361
363{
364 //kTRUE if given angle theta is within the polar range of this solid angle element
365
366 ROOT_GEO_DO_NOT_USE("IsInPolarRange", kFALSE)
367
368 if (theta >= fTheta_min && theta <= fTheta_max)
369 return kTRUE;
370 else
371 return kFALSE;
372}
373
374
375
378
380{
381 // kTRUE if "this" is entirely contained within "pos"
382
383 ROOT_GEO_DO_NOT_USE("IsSmallerThan", kFALSE)
384 return (pos->IsInPolarRange(GetThetaMin())
385 && pos->IsInPolarRange(GetThetaMax())
386 && pos->IsInPhiRange(GetPhiMin())
387 && pos->IsInPhiRange(GetPhiMax()));
388}
389
390
391
394
396{
397 //kTRUE if one of the two solid angle elements is completely contained within the other.
398
399 ROOT_GEO_DO_NOT_USE("IsAlignedWith", kFALSE)
400 return (IsSmallerThan(pos) || pos->IsSmallerThan(this));
401}
402
403
404
407
409{
410 //kTRUE if there is at least partial overlap between two solid angle elements
411
412 ROOT_GEO_DO_NOT_USE("IsOverlappingWith", kFALSE)
413 return (
414 //overlapping corners - case 1
415 (IsInPolarRange(other->GetThetaMin())
416 || IsInPolarRange(other->GetThetaMax()))
417 && (IsInPhiRange(other->GetPhiMin())
418 || IsInPhiRange(other->GetPhiMax()))
419 ) || (
420 //overlapping corners - case 2
421 (other->IsInPolarRange(GetThetaMin())
422 || other->IsInPolarRange(GetThetaMax()))
423 && (other->IsInPhiRange(GetPhiMin())
424 || other->IsInPhiRange(GetPhiMax()))
425 ) || (
426 //case where this is phi-contained by the other, but the other is theta-contained by this
427 (other->IsInPolarRange(GetThetaMin())
428 || other->IsInPolarRange(GetThetaMax()))
429 && (IsInPhiRange(other->GetPhiMin())
430 || IsInPhiRange(other->GetPhiMax()))
431 ) || (
432 //case where this is phi-contained by the other, but the other is theta-contained by this
433 (IsInPolarRange(other->GetThetaMin())
434 || IsInPolarRange(other->GetThetaMax()))
435 && (other->IsInPhiRange(GetPhiMin())
436 || other->IsInPhiRange(GetPhiMax()))
437 );
438}
439
440
441
445
447{
448 //kTRUE if "this" has larger azimuthal width than "pos".
449 //Takes care of cases where the solid angle straddles 0 degrees
450
451 ROOT_GEO_DO_NOT_USE("IsAzimuthallyWiderThan", kFALSE)
453 return kTRUE;
454 return kFALSE;
455}
456
457
458
462
464{
465 //Returns a unit vector corresponding to the direction of fTheta, fPhi
466 //i.e. the centre of the solid angle element.
467
468 TVector3 tmp(1.0, 0.0, 0.0);
469 tmp.SetTheta(fTheta * TMath::Pi() / 180.);
470 tmp.SetPhi(fPhi * TMath::Pi() / 180.);
471 return tmp;
472}
473
474
475
476
495
497{
498 // Fill the array (TVector3 corner[4]) with the coordinates of the 4 'corners' of the solid angle element.
499 //
500 // These 'corners' are the points of intersection between the plane defined by the normal
501 // to the centre of the solid angle (direction: theta,phi), at a distance fDistance [cm] from the
502 // origin, and the four lines starting at the origin with directions (thetamin,phimin),
503 // (thetamax,phimin), (thetamax,phimax), (thetamin,phimax).
504 //
505 // If optional argument 'depth' [cm] is given, the coordinates are calculated for the plane
506 // situated at distance (fDistance+depth) from the origin.
507 //
508 // The order of the 4 corners is as follows:
509 // corners[3] : theta-min, phi-min
510 // corners[2] : theta-max, phi-min
511 // corners[1] : theta-max, phi-max
512 // corners[0] : theta-min, phi-max
513 //
514 // Coordinates are in CENTIMETRES
515
516 ROOT_GEO_DO_NOT_USE("GetCornerCoordinates",)
517
518 // calculate unit vector normal to solid angle
519 Double_t pthR = GetTheta() * TMath::DegToRad();
520 Double_t pphR = GetPhi() * TMath::DegToRad();
521 TVector3 normal_to_plane(sin(pthR)*cos(pphR), sin(pthR)*sin(pphR), cos(pthR));
522
523 // the four directions/lines
528
529 // calculate intersection points
530 for (int i = 0; i < 4; i++) {
531 Double_t t = corners[i] * normal_to_plane;
532 if (t <= 0.0) corners[i].SetXYZ(0, 0, 0);
533 else corners[i] *= (fDistance + depth) / t;
534 }
535}
536
537
538
539
543
545{
546 // Like GetCornerCoordinates(), except that the coordinates correspond to a reference frame
547 // in which the +ve z-axis goes through the centre of the solid angle
548
549 ROOT_GEO_DO_NOT_USE("GetCornerCoordinatesInOwnFrame",)
550 GetCornerCoordinates(corners, depth);
551 TRotation rot_to_frame;
553 TVector3 displZ(0, 0, fDistance + depth);
554 for (int i = 0; i < 4; i++) {
555 corners[i] = rot_to_frame * corners[i] - displZ;
556 }
557}
558
559
560
566
568{
569 // Return values of the solid angle (in msr) seen by the geometric ensemble
570 // For simple geometries defined by theta_min/max etc., this is exact.
571 // For ROOT geometries we calculate the area of the entrance window and divide
572 // it by the square of the distance to the detector.
573
574 if (ROOTGeo()) {
575 if (!fSolidAngle) {
576 // TGeoArb8 shapes' solid angles calculated on demand as this requires
577 // a monte carlo calculation
578 // this takes into account any eventual "misalignment" i.e. if the vector from the
579 // origin to the centre of the volume is not perpendicular to the entrance surface,
580 // which reduces the effective area "seen" from the target
582 fSolidAngle = area / pow(GetDistance(), 2.) * 1.e3;
583 }
584 return fSolidAngle;
585 }
586
587 return (-1.*cos(GetThetaMax() * TMath::DegToRad()) +
589 * (GetAzimuthalWidth() * TMath::DegToRad()) * 1.e3;
590
591}
592
593
594
597
599{
600 // Returns kTRUE if ROOT geometry is used, kFALSE if not
601 return (fMatrix && fShape);
602}
603
604
605
611
613{
614 //Calculate azimuthal width taking phi-min as the most anticlockwise point of the
615 //element and phi-max the most clockwise.
616 //If no arguments are given, width calculated for this object
617 //Otherwise, width calculated for given phi-min and phi-max
618
619 ROOT_GEO_DO_NOT_USE("GetAzimuthalWidth", 0.)
620
621 if (phmin == -1.)
622 phmin = GetPhiMin();
623 if (phmax == -1.)
624 phmax = GetPhiMax();
625 if (phmin < phmax)
626 return (phmax - phmin);
627 else
628 return (phmax - phmin + 360.);
629}
630
631
632
633
638
640{
641 //Calculate azimuthal and polar widths for a square element placed at a
642 //given distance from the origin with linear dimension 'lin_dim' (in mm).
643 //SetDistance, SetTheta and SetPhi must already have been called.
644
645 if (GetDistance() <= 0.0) {
646 Error("GetWidthsFromDimension", "Distance not set");
647 return;
648 }
649 Double_t d__th =
650 2. * TMath::RadToDeg() * TMath::ATan(lin_dim /
651 (2. * GetDistance()));
652 Double_t d__ph =
653 TMath::RadToDeg() * lin_dim / (GetDistance() * GetSinTheta());
654 SetPolarWidth(d__th);
655 SetAzimuthalWidth(d__ph);
656}
657
658
659
664
666{
667 // Generates a rotation which, if applied to a unit vector in the Z-direction,
668 // will transform it into an isotropically-distributed vector in this
669 // angular range.
670
671 TRotation rr2;
672 ROOT_GEO_DO_NOT_USE("GetRandomIsotropicRotation", rr2)
673 Double_t a1min, a1max, a2min, a2max, a3min, a3max;
674 a1min = 0;
675 a1max = 2 * TMath::Pi();
676 a2min = GetThetaMin() * TMath::DegToRad();
677 a2max = GetThetaMax() * TMath::DegToRad();
678 a3min = GetPhiMin() * TMath::DegToRad();
679 a3max = GetPhiMax() * TMath::DegToRad();
680 a3min += TMath::Pi() / 2.;
681 a3max += TMath::Pi() / 2.;
682 rr2.SetXEulerAngles(gRandom->Uniform(a1min, a1max),
683 TMath::ACos(gRandom->Uniform(cos(a2max), cos(a2min))),
684 gRandom->Uniform(a3min, a3max));
685 return rr2;
686}
687
688
690
691
701
703{
704 // * ROOT Geometry *
705 // Set the global transformation matrix for this volume
706 // If shape has been set, we set the (theta,phi) angles
707 // corresponding to the centre of the volume, and
708 // the distance from the target corresponding to the distance
709 // along (theta,phi) to the entrance surface of the volume
710 // (not necessarily the same as the distance from the target to
711 // the centre of the entrance surface)
712
713 if (fMatrix) delete fMatrix;
714 fMatrix = new TGeoHMatrix(*m);
715 if (ROOTGeo()) {
716 TVector3 centre = GetVolumeCentre();
717 SetTheta(centre.Theta()*TMath::RadToDeg());
718 SetPhi(centre.Phi()*TMath::RadToDeg());
720 // solid angle calculated and set here only for non-TGeoArb8 shapes
721 // this takes into account any eventual "misalignment" i.e. if the vector from the
722 // origin to the centre of the volume is not perpendicular to the entrance surface,
723 // which reduces the effective area "seen" from the target
724 if (!GetShape()->InheritsFrom("TGeoArb8")) {
726 fSolidAngle = area / pow(GetDistance(), 2.) * 1.e3;
727 }
728 }
729}
730
731
732
742
744{
745 // * ROOT Geometry *
746 // Set the shape of this detector
747 // If matrix has been set, we set the (theta,phi) angles
748 // corresponding to the centre of the volume, and
749 // the distance from the target corresponding to the distance
750 // along (theta,phi) to the entrance surface of the volume
751 // (not necessarily the same as the distance from the target to
752 // the centre of the entrance surface)
753
754 fShape = b;
755 if (ROOTGeo()) {
756 TVector3 centre = GetVolumeCentre();
757 SetTheta(centre.Theta()*TMath::RadToDeg());
758 SetPhi(centre.Phi()*TMath::RadToDeg());
760 // solid angle calculated and set here only for non-TGeoArb8 shapes
761 // this takes into account any eventual "misalignment" i.e. if the vector from the
762 // origin to the centre of the volume is not perpendicular to the entrance surface,
763 // which reduces the effective area "seen" from the target
764 if (!GetShape()->InheritsFrom("TGeoArb8")) {
766 fSolidAngle = area / pow(GetDistance(), 2.) * 1.e3;
767 }
768 }
769}
770
771
772
776
778{
779 // * ROOT Geometry *
780 // Return global transformation matrix for this detector
781 return fMatrix;
782}
783
784
785
789
791{
792 // * ROOT Geometry *
793 // Return shape of this detector
794 return fShape;
795}
796
797
798
812
814{
815 // * ROOT Geometry *
816 // Generate a vector in the world (laboratory) frame from the origin
817 // to a random point on the entrance surface of this volume.
818 //
819 // It is assumed that the volume was defined in such a way
820 // that the entrance window corresponds to the facet in the X-Y plane
821 // placed at -dZ.
822 //
823 // NOTE: we force the use of TGeoBBox::GetPointsOnFacet.
824 // For TGeoArb8, the method has been overridden and does nothing.
825 // We use the TGeoBBox method, and then use TGeoShape::Contains
826 // to check that the point does actually correspond to the TGeoArb8.
827
828 if (!ROOTGeo()) {
829 ::Error("KVPosition::GetRandomPointOnSurface",
830 "ROOT Geometry has not been initialised");
831 return TVector3();
832 }
833 Double_t master[3 * 50];
834 Double_t points[3 * 50];
835 const Double_t* origin = GetShape()->GetOrigin();
836 Double_t dz = GetShape()->GetDZ();
837 // This will generate a point on the (-DZ) face of the bounding box of the shape
838 Bool_t ok1 = GetShape()->TGeoBBox::GetPointsOnFacet(1, 50, points);
839 // We move the point slightly inside the volume to test if it actually corresponds
840 // to a point on the shape's facet
841 points[2] += dz / 100.;
842 // Correct for offset of centre of shape
843 for (int i = 0; i < 3; i++) points[i] += origin[i];
844 Bool_t ok2 = GetShape()->Contains(points);
845 if (!ok1) {
846 ::Error("KVPosition::GetRandomPoint",
847 "TGeoBBox::GetPointsOnFacet returns kFALSE for shape %s. Returning coordinates of centre.", GetShape()->ClassName());
848 return GetSurfaceCentre();
849 }
850 Int_t np = 0;
851 if (!ok2) {
852 // try to find a point that works
853 np++;
854 while (np < 50) {
855 Double_t* npoint = points + 3 * np;
856 npoint[2] += dz / 100.;
857 // Correct for offset of centre of shape
858 for (int i = 0; i < 3; i++) npoint[i] += origin[i];
859 ok2 = GetShape()->Contains(npoint);
860 if (ok2) break;
861 np++;
862 }
863 if (!ok2) {
864 ::Error("KVPosition::GetRandomPointOnSurface",
865 "Cannot generate points for shape %s. Returning coordinates of surface centre.", GetShape()->ClassName());
866 return GetSurfaceCentre();
867 }
868 }
869 Double_t* npoint = points + 3 * np;
870 npoint[2] -= dz / 100.;
871 GetMatrix()->LocalToMaster(npoint, master);
872 return TVector3(master);
873}
874
875
876
885
887{
888 // * ROOT Geometry *
889 // Generate a vector in the world (laboratory) frame from the origin
890 // to the centre of the entrance surface of the volume.
891 //
892 // It is assumed that the volume was defined in such a way
893 // that the entrance surface corresponds to the facet in the X-Y plane
894 // placed at -dZ.
895
896 if (!ROOTGeo()) {
897 ::Error("KVPosition::GetSurfaceCentre",
898 "ROOT Geometry has not been initialised");
899 return TVector3();
900 }
901 Double_t master[3];
902 const Double_t* origin = GetShape()->GetOrigin();
903 Double_t points[] = {origin[0], origin[1], origin[2] - GetShape()->GetDZ()};
904 GetMatrix()->LocalToMaster(points, master);
905 return TVector3(master);
906}
907
908
909
914
916{
917 // * ROOT Geometry *
918 // Generate a vector in the world (laboratory) frame from the origin
919 // to the centre of the volume.
920
921 if (!ROOTGeo()) {
922 ::Error("KVPosition::GetVolumeCentre",
923 "ROOT Geometry has not been initialised");
924 return TVector3();
925 }
926 Double_t master[3];
927 const Double_t* origin = GetShape()->GetOrigin();
928 Double_t points[] = {origin[0], origin[1], origin[2]};
929 GetMatrix()->LocalToMaster(points, master);
930 return TVector3(master);
931}
932
933
934
944
946{
947 // * ROOT Geometry *
948 // Generate a vector in the world (laboratory) frame representing
949 // the normal to the entrance surface of the volume (pointing away
950 // from the target, i.e. towards the inside of the volume)
951 //
952 // It is assumed that the volume was defined in such a way
953 // that the entrance surface corresponds to the facet in the X-Y plane
954 // placed at -dZ.
955
956 if (!ROOTGeo()) {
957 ::Error("KVPosition::GetSurfaceNormal",
958 "ROOT Geometry has not been initialised");
959 return TVector3();
960 }
961 return GetSCVector().Unit();
962}
963
964
965
973
975{
976 // Monte Carlo calculation of entrance surface area for TGeoArb8 shapes
977 // Area is calculated as area of bounding box facet multiplied by the ratio between
978 // number of random points actually on the shape surface to the number of points
979 // npoints generated over the surface of the bounding box facet
980 //
981 // npoints is the number of points to test
982
983 Double_t* points = new Double_t[3 * npoints];
984 const Double_t* origin = GetShape()->GetOrigin();
985 Double_t dz = GetShape()->GetDZ();
986 // This will generate npoints points on the (-DZ) face of the bounding box of the shape
987 Bool_t ok1 = GetShape()->TGeoBBox::GetPointsOnFacet(1, npoints, points);
988 if (!ok1) {
989 ::Error("KVPosition::GetEntranceWindowArea",
990 "TGeoBBox::GetPointsOnFacet returns kFALSE for shape %s. Returning 0.0", GetShape()->ClassName());
991 delete [] points;
992 return 0.0;
993 }
994 Double_t points_on_facet = 0;
995 for (Int_t np = 0; np < npoints; ++np) {
996 Double_t* npoint = points + 3 * np;
997 // We move the point slightly inside the volume to test if it actually corresponds
998 // to a point on the shape's facet
999 npoint[2] += dz / 100.;
1000 // Correct for offset of centre of shape
1001 for (int i = 0; i < 3; i++) npoint[i] += origin[i];
1002 if (GetShape()->Contains(npoint)) ++points_on_facet;
1003 }
1004 delete [] points;
1005 return GetShape()->GetFacetArea(1) * (points_on_facet / Double_t(npoints));
1006}
1007
1008
1009
1013
1015{
1016 // Return angle (in deg.) between the vector from the target to the volume centre
1017 // and the normal to the volume surface
1019}
1020
1021
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
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:91
virtual void GetRandomAngles(Double_t &th, Double_t &ph, Option_t *t="isotropic")
Bool_t IsInPhiRange(const Double_t phi)
virtual void SetAzimuthalWidth(Double_t aw)
virtual TVector3 GetRandomDirection(Option_t *t="isotropic")
Bool_t IsAzimuthallyWiderThan(KVPosition *pos)
virtual void SetShape(TGeoBBox *)
virtual void SetAzimuthalMinMax(Double_t min, Double_t max)
Set min and max azimuthal angles and calculate (mean) phi.
virtual void SetAzimuthalAngle(Double_t ph)
virtual Double_t GetSolidAngle(void) const
virtual Double_t GetTheta() const
Definition KVPosition.h:160
Bool_t ROOTGeo() const
Returns kTRUE if ROOT geometry is used, kFALSE if not.
void GetCornerCoordinates(TVector3 *, Double_t=0)
Double_t fTheta
polar angle in degrees with respect to beam axis, corresponds to centre of telescope
Definition KVPosition.h:93
virtual TVector3 GetSurfaceCentre() const
virtual TGeoHMatrix * GetMatrix() const
void GetWidthsFromDimension(Double_t lin_dim)
void SetDistance(Double_t d)
Definition KVPosition.h:186
TRotation GetRandomIsotropicRotation()
virtual void SetPolarAngle(Double_t th)
virtual Double_t GetPhi() const
Definition KVPosition.h:172
Double_t GetPhiMax() const
Definition KVPosition.h:146
virtual Double_t GetDistance(void) const
Definition KVPosition.h:190
Double_t fSolidAngle
solid angle = area of entrance window / distance**2
Definition KVPosition.h:104
TGeoHMatrix * fMatrix
transform world<->detector coordinates
Definition KVPosition.h:102
Double_t GetPhiMin() const
Definition KVPosition.h:142
Bool_t IsSmallerThan(KVPosition *pos)
kTRUE if "this" is entirely contained within "pos"
virtual TVector3 GetVolumeCentre() const
virtual Double_t GetSurfaceArea(int npoints=100000) const
TVector3 GetSCVector() const
Definition KVPosition.h:106
Double_t GetThetaMin() const
Definition KVPosition.h:150
virtual Double_t GetSinTheta() const
Definition KVPosition.h:164
Double_t GetOC_SC_CosAngle() const
Definition KVPosition.h:110
virtual TVector3 GetSurfaceNormal() const
virtual Double_t GetMisalignmentAngle() const
Double_t fTheta_min
polar angle in degrees corresponding to edge of telescope closest to beam axis
Definition KVPosition.h:95
Double_t GetAzimuthalWidth(Double_t phmin=-1., Double_t phimax=-1.) const
Bool_t IsInPolarRange(const Double_t theta)
kTRUE if given angle theta is within the polar range of this solid angle element
virtual void SetPolarWidth(Double_t pw)
Bool_t IsAlignedWith(KVPosition *pos)
kTRUE if one of the two solid angle elements is completely contained within the other.
Double_t fTheta_max
polar angle in degrees of the edge furthest from the beam axis
Definition KVPosition.h:96
void SetTheta(Double_t t)
Definition KVPosition.h:178
Double_t fPhi
azimuthal angle in degrees with respect to 12 o'clock (=0 deg.), corresponds to centre of telescope
Definition KVPosition.h:94
TGeoBBox * fShape
shape of detector volume
Definition KVPosition.h:103
void SetPhi(Double_t p)
Definition KVPosition.h:182
virtual void SetPolarMinMax(Double_t min, Double_t max)
Set min and max polar angles and calculate (mean) theta.
virtual void SetMatrix(const TGeoHMatrix *)
virtual TGeoBBox * GetShape() const
Double_t fPhi_max
azimuthal angle in degrees corresponding to most clockwise edge of telescope
Definition KVPosition.h:98
Double_t fPhi_min
azimuthal angle in degrees corresponding to most anticlockwise edge of telescope
Definition KVPosition.h:97
virtual ~KVPosition()
Bool_t IsOverlappingWith(KVPosition *pos)
kTRUE if there is at least partial overlap between two solid angle elements
Double_t fDistance
distance in cm from centre of solid angle element to coordinate system origin (target)
Definition KVPosition.h:99
void GetCornerCoordinatesInOwnFrame(TVector3 *, Double_t=0)
void init()
default initialiser
Double_t GetThetaMax() const
Definition KVPosition.h:154
virtual TVector3 GetDirection()
virtual TVector3 GetRandomPointOnSurface() const
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
TVector3 Unit() const
Double_t Theta() const
void SetTheta(Double_t)
RooCmdArg ClassName(const char *name)
T Mag(const SVector< T, D > &rhs)
RVec< PromoteType< T > > cos(const RVec< T > &v)
RVec< PromoteTypes< T0, T1 > > pow(const RVec< T0 > &v, const T1 &y)
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)