19#include "CLHEP/Units/SystemOfUnits.h"
20#include "CLHEP/Units/PhysicalConstants.h"
54 if(m) std::cout << m << std::endl;
58static void get_r(
const G4VSolid *p, G4double
z,
59 G4double &rmin, G4double &rmax
62 G4ThreeVector from(10.*CLHEP::m, 0.,
z);
63 rmax = from[0] - p->DistanceToIn(from, G4ThreeVector(-1., 0., 0.));
65 rmin = p->DistanceToIn(from, G4ThreeVector(1., 0., 0.));
68static TRandom *
rnd = 0;
71 if(
rnd == 0)
rnd =
new TRandom3(0);
72 G4double
r =
rnd->Uniform();
73 G4ThreeVector p(0., 0., 0.);
75 G4double level1 = .980;
76 G4double level2 = .993;
77 const char *v = getenv(
"LARWHEELSLICESOLID_TEST_MODE_LEVEL1");
78 if(v) level1 = atof(v);
79 const char *v1 = getenv(
"LARWHEELSLICESOLID_TEST_MODE_LEVEL2");
80 if(v1) level2 = atof(v1);
83 std::cout <<
"LWS::GPOS " <<
r << std::endl;
88 }
else if(
r <= level2){
94 "LArWheelSliceSolid",
"Rnd generator error",
95 FatalException,
"GetPointOnSurface: Wrong data from rnd generator"
108 p[1] =
rnd->Uniform(rmin, rmax);
109 p.setPhi(
rnd->Uniform(0., CLHEP::twopi));
110 G4double dphi = p.phi();
116 if(d < 0.) side = -1;
117 if(d >= 0.) side = 1;
125 G4ThreeVector D = p; D[2] = 0.;
127 if(d1 > 10.*CLHEP::m){
131 if(d1 > 10.*CLHEP::m){
137 G4ThreeVector B = p + D * d1;
138 G4double dphi = B.phi();
154 G4ThreeVector D1 = (p - B).
unit();
156 if(
Inside(X) == kSurface){
170 const bool inner =
rnd->Uniform() > 0.5?
true:
false;
172 p[0] = 0.; p[1] = inner? rmin: rmax; p[2] =
z;
173 p.setPhi(
rnd->Uniform(0., CLHEP::twopi));
174 G4double dphi = p.phi();
179 const G4double
r = p[1];
181 G4ThreeVector A1(0.,
r,
z);
193 G4ThreeVector A2(0.,
r,
z);
211 G4ThreeVector d = (A2 - A1).
unit();
222 step = d1 > d2? d1 : d2;
223 if(inner) step *= -2;
228 step = d1 > d2? d1 : d2;
233 G4ThreeVector B1(0.,
r + step,
z);
244 G4ThreeVector B2(0.,
r + step,
z);
256 if(B1i == A1i || B2i == A1i){
268 G4ThreeVector d1 = (A1 - B1).
unit();
270 G4ThreeVector d2 = (A2 - B2).
unit();
273 G4ThreeVector X = X1;
274 G4double phi1 = X1.phi(), phi2 = X2.phi();
276 if(phi1 > 0. && phi2 < 0.) phi2 += CLHEP::twopi;
277 G4double phiX =
rnd->Uniform(phi1, phi2);
278 if(phiX > CLHEP::pi) phiX -= CLHEP::twopi;
281 if(
Inside(X) == kSurface){
297 p[1] =
rnd->Uniform(rmin, rmax);
298 p.setPhi(
rnd->Uniform(0., CLHEP::twopi));
299 G4double dphi = p.phi();
336 G4double result = 0.;
339 result += rmax - rmin;
341 result += rmax - rmin;
351 G4ThreeVector(0.,
r, -
m_Zmin), G4ThreeVector(0., 0., 1.)
355 G4ThreeVector(0.,
r,
m_Zmax), G4ThreeVector(0., 0., -1.)
358 double result =
m_f_length->Integral(zmin, zmax);
374 std::cout <<
"get_area_on_polycone: " << a1/mm2 << std::endl;
380 std::cout <<
"get_area_on_face: " << a2/mm2 << std::endl;
386 std::cout <<
"get_area_on_side: " << a3/mm2 << std::endl;
399 const char *on = getenv(
"LARWHEELSLICESOLID_TEST");
401 std::string test_mode = on;
403 std::cout <<
"============| LArWheelSliceSolid test() routine |=============="
405 std::cout <<
"Solid of type " <<
TypeStr() << std::endl;
406 const char *prec = getenv(
"LARWHEELSLICESOLID_TEST_INTPRECISION");
408 std::cout << std::format(
"Int. precision {:.6f}\n",
IntPrecision);
409 std::cout <<
"test mode " << test_mode << std::endl;
411 std::cout << std::format(
"m_Rmin = {:.6f} m_Rmax = {:.6f}\n",
m_Rmin,
m_Rmax)
412 << std::format(
"m_Zmin = {:.6f} m_Zmax = {:.6f}\n",
m_Zmin,
m_Zmax);
417 if(test_mode.find(
"root") != std::string::npos){
418 F =
new TFile(
"LArWheelSliceSolid_test.root",
"UPDATE");
419 T =
new TNtupleD(GetName(), GetName(),
"x:y:z");
422 const int Nmax(1000000000);
423 char *NN = getenv(
"LARWHEELSLICESOLID_TEST_NPOINTS");
427 N = strtol(NN, &endptr, 0);
428 if (endptr[0] !=
'\0') {
429 throw std::invalid_argument(
"Could not convert string to int: " + std::string(NN));
433 std::cout <<
"Number of points from LARWHEELSLICESOLID_TEST_NPOINTS environment variable ("<<N<<
") is too large. Using " << Nmax <<
" instead." << std::endl;
437 std::cout <<
"Number of points from LARWHEELSLICESOLID_TEST_NPOINTS environment variable ("<<N<<
") is negative!!. Using 0 instead." << std::endl;
440 if(test_mode.find(
"points") == std::string::npos){
443 std::cout << N <<
" points" << std::endl;
445 for(
int i = 0; i < N; ++ i){
450 std::cout << i <<
" "
451 << (ii == kInside?
"inside":
"outside")
455 if(T) T->Fill(p[0], p[1], p[2]);
464 if(test_mode.find(
"volume") != std::string::npos){
466 std::cout <<
"GetCubicVolume: " << cv/CLHEP::mm3 <<
" mm^3" << std::endl;
469 if(test_mode.find(
"area") != std::string::npos){
471 std::cout <<
"GetSurfaceArea: " << sa/CLHEP::mm2 <<
" mm^2" << std::endl;
474 std::cout <<
"======= end of ArWheelSolid test() routine ============="
477 if(test_mode.find(
"once") != std::string::npos) exit(0);
510 G4ThreeVector(0.,
r,
m_Zmin), G4ThreeVector(0., 0., 1.)
513 G4ThreeVector(0.,
r,
m_Zmax), G4ThreeVector(0., 0., -1.)
517 double result =
m_f_area->Integral(zmin, zmax);
522static std::map<double, LArWheelSliceSolid *>
solid;
526 const double &
z =
x[0];
527 const double &
r = p[0];
528 const double &
index = p[1];
530 G4ThreeVector
a(0.,
r,
z);
531 double b =
solid[
index]->GetCalculator()->AmplitudeOfSurface(
a, -1, 121)
532 -
solid[
index]->GetCalculator()->AmplitudeOfSurface(
a, 1, 121);
538 const double &
r =
x[0];
539 const double &
index = p[0];
546 const double &
z =
x[0];
547 const double &
index = p[0];
553 G4ThreeVector
a(0., rmin,
z);
554 result +=
solid[
index]->GetCalculator()->AmplitudeOfSurface(
a, -1, 232)
555 -
solid[
index]->GetCalculator()->AmplitudeOfSurface(
a, 1, 232);
557 result +=
solid[
index]->GetCalculator()->AmplitudeOfSurface(
a, -1, 343)
558 -
solid[
index]->GetCalculator()->AmplitudeOfSurface(
a, 1, 343);
566 const double &
z =
x[0];
567 const double &
r = par[0];
568 const double &
index = par[1];
570 const double h = 0.001;
573 G4ThreeVector p(0.,
r,
z +
h);
574 G4double D1 =
solid[
index]->GetCalculator()->AmplitudeOfSurface(p, side, 5665);
576 D1 -=
solid[
index]->GetCalculator()->AmplitudeOfSurface(p, side, 5665);
580 G4double D2 =
solid[
index]->GetCalculator()->AmplitudeOfSurface(p, side, 5665);
582 D2 -=
solid[
index]->GetCalculator()->AmplitudeOfSurface(p, side, 5665);
585 G4double D = (D2 * 4 - D1) / 3.;
586 G4double dl = sqrt(1 + D * D);
598 const double &
r =
x[0];
599 const double &
index = p[0];
609#ifdef DEBUG_LARWHEELSLICESOLID
611 std::cout <<
"LArWheelSliceSolid::init_tests: put " <<
this
634 (GetName() +
"_f_length").c_str(), &
fcn_length,
646#ifdef DEBUG_LARWHEELSLICESOLID
647G4bool LArWheelSliceSolid::test_dti(
648 const G4ThreeVector &inputP,
const G4ThreeVector &inputV,
649 const G4double distance
652 if(distance > 10.*CLHEP::m){
653 LWSDBG(1, std::cout <<
"DTI test skipped, distance > 10 m"
663 const G4double
phi0 =
p.phi();
667 std::cout <<
"DTI test already inside" << MSG_VECTOR(p) << std::endl;
670 G4ThreeVector
v( inputV );
671 v.rotateZ(
p.phi() - phi0);
673 LWSDBG(1, std::cout <<
"Start DTI test, expect "
674 <<
long(distance / dd) <<
" iterations"
683 G4ThreeVector
p1 =
p +
v *
t;
685 std::cout <<
"DTI test at " << MSG_VECTOR(inputP) <<
" -> "
686 << MSG_VECTOR(inputV) <<
", translated to "
687 << MSG_VECTOR(p) <<
" - > " << MSG_VECTOR(v)
689 <<
distance <<
": found nearer intersection at local point"
690 << MSG_VECTOR(p1) <<
", distance " <<
t
697 FILE *
F = fopen(
"dti_error.dat",
"w");
699 fprintf(
F,
"%10e %10e %10e\n",
p.x(),
p.y(),
p.z());
700 fprintf(
F,
"%10e %10e %10e\n",
v.x(),
v.y(),
v.z());
704 fprintf(
F,
"%10e %10e\n", e, f);
714 LWSDBG(1, std::cout <<
"DTI test at " << MSG_VECTOR(p) <<
" -> "
715 << MSG_VECTOR(v) <<
" in range of "
716 << distance <<
": allright" << std::endl);
720G4bool LArWheelSliceSolid::test_dto(
721 const G4ThreeVector &inputP,
const G4ThreeVector &inputV,
722 const G4double distance
725 if(distance > 10.*CLHEP::m){
726 LWSDBG(1, std::cout <<
"DTO test skipped, distance > 10 m"
732 G4ThreeVector
p( inputP );
733 const G4double
phi0 =
p.phi();
737 std::cout <<
"DTO test already outside" << MSG_VECTOR(p) << std::endl;
740 G4ThreeVector
v( inputV );
741 v.rotateZ(
p.phi() - phi0);
743 LWSDBG(1, std::cout <<
"Start DTO test, expect "
744 <<
long(distance / dd) <<
" iterations"
751 static bool first =
true;
753 G4ThreeVector
p1 =
p +
v *
t;
755 std::cout <<
"DTO test at " << MSG_VECTOR(inputP) <<
" -> "
756 << MSG_VECTOR(inputV) <<
", translated to "
757 << MSG_VECTOR(p) <<
" - > " << MSG_VECTOR(v)
759 <<
distance <<
": found nearer intersection at local point"
760 << MSG_VECTOR(p1) <<
", distance " <<
t
767 FILE *
F = fopen(
"dto_error.dat",
"w");
769 fprintf(
F,
"%10e %10e %10e\n",
p.x(),
p.y(),
p.z());
770 fprintf(
F,
"%10e %10e %10e\n",
v.x(),
v.y(),
v.z());
774 fprintf(
F,
"%10e %10e\n", e, f);
784 LWSDBG(1, std::cout <<
"DTO test at " << MSG_VECTOR(p) <<
" -> "
785 << MSG_VECTOR(v) <<
" in range of "
786 << distance <<
": allright" << std::endl);
const PlainObject unit() const
This is a plugin that makes Eigen look like CLHEP & defines some convenience methods.
double LArWheelSliceSolid_fcn_vol(double *x, double *p)
double LArWheelSliceSolid_fcn_area_on_pc(double *x, double *p)
double LArWheelSliceSolid_fcn_side_area(double *x, double *p)
double LArWheelSliceSolid_fcn_area(double *x, double *p)
static std::map< double, LArWheelSliceSolid * > solid
static double fcn_length(double *x, double *p)
static void get_r(const G4VSolid *p, G4double z, G4double &rmin, G4double &rmax)
static double IntPrecision
double LArWheelSliceSolid_get_dl(double *x, double *par, G4int side)
Define macros for attributes used to control the static checker.
#define ATLAS_NO_CHECK_FILE_THREAD_SAFETY
Header file for AthHistogramAlgorithm.
int GetNumberOfFans() const
double AmplitudeOfSurface(const CLHEP::Hep3Vector &P, int side, int fan_number) const
double GetFanHalfThickness(LArG4::LArWheelCalculator_t) const
double DistanceToTheNearestFan(CLHEP::Hep3Vector &p, int &out_fan_number) const
Determines the nearest to the input point fan.
friend double LArWheelSliceSolid_fcn_vol(double *, double *)
static const G4double s_IterationPrecision
friend double LArWheelSliceSolid_fcn_area_on_pc(double *, double *)
const LArWheelCalculator * m_Calculator
friend double LArWheelSliceSolid_fcn_side_area(double *, double *)
G4double get_area_on_side(void) const
G4double get_area_at_r(G4double r) const
void get_point_on_polycone_surface(G4ThreeVector &) const
const LArWheelCalculator * GetCalculator(void) const
friend double LArWheelSliceSolid_fcn_area(double *, double *)
G4double GetCubicVolume(void)
static const G4double s_Tolerance
G4double m_FanHalfThickness
void set_failover_point(G4ThreeVector &p, const char *m=0) const
EInside Inside_accordion(const G4ThreeVector &) const
G4double get_length_at_r(G4double r) const
void get_point_on_flat_surface(G4ThreeVector &) const
EInside Inside(const G4ThreeVector &) const
G4double get_area_on_polycone(void) const
G4double get_area_on_face(void) const
G4double GetSurfaceArea(void)
G4String TypeStr(void) const
G4ThreeVector GetPointOnSurface(void) const
void get_point_on_accordion_surface(G4ThreeVector &) const
G4VSolid * m_BoundingShape
float distance(const Amg::Vector3D &p1, const Amg::Vector3D &p2)
calculates the distance between two point in 3D space
void swap(ElementLinkVector< DOBJ > &lhs, ElementLinkVector< DOBJ > &rhs)