7 #include "boost/io/ios_state.hpp"
19 #include "CLHEP/Units/SystemOfUnits.h"
20 #include "CLHEP/Units/PhysicalConstants.h"
27 static double IntPrecision = 0.0001;
46 p[0] = 0.;
p[1] = m_Rmin;
47 if(m_Zmin < s_Tolerance)
p[2] = 0.;
48 else if(m_Calculator->GetWheelThickness() - m_Zmax < s_Tolerance)
p[2] = m_Zmax;
49 else p[2] = (m_Zmin + m_Zmax) * 0.5;
51 GetCalculator()->DistanceToTheNearestFan(
p, p_fan);
54 if(
m) std::cout <<
m << std::endl;
58 static void get_r(
const G4VSolid *
p, G4double
z,
59 G4double &rmin, G4double &rmax
63 rmax = from[0] -
p->DistanceToIn(from, G4ThreeVector(-1., 0., 0.));
65 rmin =
p->DistanceToIn(from, G4ThreeVector(1., 0., 0.));
68 static 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");
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);
110 G4double dphi =
p.phi();
116 if(
d < 0.)
side = -1;
117 if(
d >= 0.)
side = 1;
125 G4ThreeVector D =
p; D[2] = 0.;
137 G4ThreeVector
B =
p + D *
d1;
138 G4double dphi =
B.phi();
154 G4ThreeVector D1 = (
p -
B).
unit();
170 const bool inner = rnd->Uniform() > 0.5?
true:
false;
172 p[0] = 0.;
p[1] = inner? rmin: rmax;
p[2] =
z;
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();
223 if(inner)
step *= -2;
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();
277 G4double phiX = rnd->Uniform(phi1, phi2);
297 p[1] = rnd->Uniform(rmin, rmax);
299 G4double dphi =
p.phi();
351 G4ThreeVector(0.,
r, -
m_Zmin), G4ThreeVector(0., 0., 1.)
355 G4ThreeVector(0.,
r,
m_Zmax), G4ThreeVector(0., 0., -1.)
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 boost::io::ios_all_saver ias(std::cout);
400 const char *on =
getenv(
"LARWHEELSLICESOLID_TEST");
402 std::string test_mode = on;
404 std::cout <<
"============| LArWheelSliceSolid test() routine |=============="
406 std::cout <<
"Solid of type " <<
TypeStr() << std::endl;
407 std::cout.precision(6);
408 std::cout << std::fixed;
409 const char *
prec =
getenv(
"LARWHEELSLICESOLID_TEST_INTPRECISION");
411 std::cout <<
"Int. precision " << IntPrecision << std::endl;
412 std::cout <<
"test mode " << test_mode << std::endl;
414 std::cout <<
"m_Rmin = " <<
m_Rmin <<
" m_Rmax = " <<
m_Rmax << std::endl
415 <<
"m_Zmin = " <<
m_Zmin <<
" m_Zmax = " <<
m_Zmax << std::endl;
420 if(test_mode.find(
"root") != std::string::npos){
421 F =
new TFile(
"LArWheelSliceSolid_test.root",
"UPDATE");
422 T =
new TNtupleD(GetName(), GetName(),
"x:y:z");
425 const int Nmax(1000000000);
426 char *NN =
getenv(
"LARWHEELSLICESOLID_TEST_NPOINTS");
430 N = strtol(NN, &endptr, 0);
431 if (endptr[0] !=
'\0') {
432 throw std::invalid_argument(
"Could not convert string to int: " + std::string(NN));
436 std::cout <<
"Number of points from LARWHEELSLICESOLID_TEST_NPOINTS environment variable ("<<
N<<
") is too large. Using " << Nmax <<
" instead." << std::endl;
440 std::cout <<
"Number of points from LARWHEELSLICESOLID_TEST_NPOINTS environment variable ("<<
N<<
") is negative!!. Using 0 instead." << std::endl;
443 if(test_mode.find(
"points") == std::string::npos){
446 std::cout <<
N <<
" points" << std::endl;
448 for(
int i = 0;
i <
N; ++
i){
453 std::cout <<
i <<
" "
454 << (ii == kInside?
"inside":
"outside")
458 if(
T)
T->Fill(
p[0],
p[1],
p[2]);
467 if(test_mode.find(
"volume") != std::string::npos){
469 std::cout <<
"GetCubicVolume: " << cv/
CLHEP::mm3 <<
" mm^3" << std::endl;
472 if(test_mode.find(
"area") != std::string::npos){
474 std::cout <<
"GetSurfaceArea: " << sa/
CLHEP::mm2 <<
" mm^2" << std::endl;
477 std::cout <<
"======= end of ArWheelSolid test() routine ============="
480 if(test_mode.find(
"once") != std::string::npos)
exit(0);
514 G4ThreeVector(0.,
r,
m_Zmin), G4ThreeVector(0., 0., 1.)
517 G4ThreeVector(0.,
r,
m_Zmax), G4ThreeVector(0., 0., -1.)
526 static std::map<double, LArWheelSliceSolid *> solid;
530 const double &
z =
x[0];
531 const double &
r =
p[0];
532 const double &
index =
p[1];
534 G4ThreeVector
a(0.,
r,
z);
535 double b = solid[
index]->GetCalculator()->AmplitudeOfSurface(
a, -1, 121)
536 - solid[
index]->GetCalculator()->AmplitudeOfSurface(
a, 1, 121);
542 const double &
r =
x[0];
543 const double &
index =
p[0];
545 return solid[
index]->get_area_at_r(
r);
550 const double &
z =
x[0];
551 const double &
index =
p[0];
554 get_r(solid[
index]->m_BoundingShape,
z, rmin, rmax);
557 G4ThreeVector
a(0., rmin,
z);
558 result += solid[
index]->GetCalculator()->AmplitudeOfSurface(
a, -1, 232)
559 - solid[
index]->GetCalculator()->AmplitudeOfSurface(
a, 1, 232);
561 result += solid[
index]->GetCalculator()->AmplitudeOfSurface(
a, -1, 343)
562 - solid[
index]->GetCalculator()->AmplitudeOfSurface(
a, 1, 343);
570 const double &
z =
x[0];
571 const double &
r =
par[0];
574 const double h = 0.001;
577 G4ThreeVector
p(0.,
r,
z +
h);
578 G4double D1 = solid[
index]->GetCalculator()->AmplitudeOfSurface(
p,
side, 5665);
580 D1 -= solid[
index]->GetCalculator()->AmplitudeOfSurface(
p,
side, 5665);
584 G4double D2 = solid[
index]->GetCalculator()->AmplitudeOfSurface(
p,
side, 5665);
586 D2 -= solid[
index]->GetCalculator()->AmplitudeOfSurface(
p,
side, 5665);
589 G4double D = (D2 * 4 - D1) / 3.;
590 G4double
dl = sqrt(1 + D * D);
595 static double fcn_length(
double *
x,
double *
p)
602 const double &
r =
x[0];
603 const double &
index =
p[0];
605 return solid[
index]->get_length_at_r(
r);
613 #ifdef DEBUG_LARWHEELSLICESOLID
615 std::cout <<
"LArWheelSliceSolid::init_tests: put " <<
this
638 (GetName() +
"_f_length").c_str(), &fcn_length,
650 #ifdef DEBUG_LARWHEELSLICESOLID
651 G4bool LArWheelSliceSolid::test_dti(
652 const G4ThreeVector &inputP,
const G4ThreeVector &inputV,
657 LWSDBG(1, std::cout <<
"DTI test skipped, distance > 10 m"
667 const G4double
phi0 =
p.phi();
671 std::cout <<
"DTI test already inside" << MSG_VECTOR(
p) << std::endl;
674 G4ThreeVector
v( inputV );
675 v.rotateZ(
p.phi() -
phi0);
677 LWSDBG(1, std::cout <<
"Start DTI test, expect "
687 G4ThreeVector
p1 =
p +
v *
t;
689 std::cout <<
"DTI test at " << MSG_VECTOR(inputP) <<
" -> "
690 << MSG_VECTOR(inputV) <<
", translated to "
691 << MSG_VECTOR(
p) <<
" - > " << MSG_VECTOR(
v)
693 <<
distance <<
": found nearer intersection at local point"
694 << MSG_VECTOR(
p1) <<
", distance " <<
t
701 FILE *
F = fopen(
"dti_error.dat",
"w");
703 fprintf(
F,
"%10e %10e %10e\n",
p.x(),
p.y(),
p.z());
704 fprintf(
F,
"%10e %10e %10e\n",
v.x(),
v.y(),
v.z());
708 fprintf(
F,
"%10e %10e\n",
e,
f);
718 LWSDBG(1, std::cout <<
"DTI test at " << MSG_VECTOR(
p) <<
" -> "
719 << MSG_VECTOR(
v) <<
" in range of "
720 <<
distance <<
": allright" << std::endl);
724 G4bool LArWheelSliceSolid::test_dto(
725 const G4ThreeVector &inputP,
const G4ThreeVector &inputV,
730 LWSDBG(1, std::cout <<
"DTO test skipped, distance > 10 m"
736 G4ThreeVector
p( inputP );
737 const G4double
phi0 =
p.phi();
741 std::cout <<
"DTO test already outside" << MSG_VECTOR(
p) << std::endl;
744 G4ThreeVector
v( inputV );
745 v.rotateZ(
p.phi() -
phi0);
747 LWSDBG(1, std::cout <<
"Start DTO test, expect "
755 static bool first =
true;
757 G4ThreeVector
p1 =
p +
v *
t;
759 std::cout <<
"DTO test at " << MSG_VECTOR(inputP) <<
" -> "
760 << MSG_VECTOR(inputV) <<
", translated to "
761 << MSG_VECTOR(
p) <<
" - > " << MSG_VECTOR(
v)
763 <<
distance <<
": found nearer intersection at local point"
764 << MSG_VECTOR(
p1) <<
", distance " <<
t
771 FILE *
F = fopen(
"dto_error.dat",
"w");
773 fprintf(
F,
"%10e %10e %10e\n",
p.x(),
p.y(),
p.z());
774 fprintf(
F,
"%10e %10e %10e\n",
v.x(),
v.y(),
v.z());
778 fprintf(
F,
"%10e %10e\n",
e,
f);
788 LWSDBG(1, std::cout <<
"DTO test at " << MSG_VECTOR(
p) <<
" -> "
789 << MSG_VECTOR(
v) <<
" in range of "
790 <<
distance <<
": allright" << std::endl);