ATLAS Offline Software
Loading...
Searching...
No Matches
LArWheelSliceSolidTests.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include <iostream>
6#include <stdexcept>
7#include <format>
8#include <map>
9
10#include "TRandom3.h"
11#include "TF1.h"
12#include "TNtupleD.h"
13#include "TFile.h"
14// For root version ifdef
15#include "TROOT.h"
16
18#include "LArWheelSliceSolid.h"
19#include "CLHEP/Units/SystemOfUnits.h"
20#include "CLHEP/Units/PhysicalConstants.h"
21//#define LOCAL_DEBUG 1
22#include<stdlib.h>
23
26
27static double IntPrecision = 0.0001;
28
29EInside LArWheelSliceSolid::Inside_accordion(const G4ThreeVector &p) const
30{
31 G4ThreeVector p1 = p;
32 int p1_fan = 0;
33 G4double d = m_FanHalfThickness - fabs(GetCalculator()->DistanceToTheNearestFan(p1, p1_fan));
34 if(d > s_Tolerance) return kInside;
35 if(d > -s_Tolerance) return kSurface;
36 return kOutside;
37}
38
40#ifdef LOCAL_DEBUG
41 const char *m) const
42#else
43 const char *) const
44#endif
45 {
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;
50 int p_fan = 0;
51 GetCalculator()->DistanceToTheNearestFan(p, p_fan);
52
53#ifdef LOCAL_DEBUG
54 if(m) std::cout << m << std::endl;
55#endif
56 }
57
58static void get_r(const G4VSolid *p, G4double z,
59 G4double &rmin, G4double &rmax
60 )
61{
62 G4ThreeVector from(10.*CLHEP::m, 0., z);
63 rmax = from[0] - p->DistanceToIn(from, G4ThreeVector(-1., 0., 0.));
64 from[0] = 0.;
65 rmin = p->DistanceToIn(from, G4ThreeVector(1., 0., 0.));
66}
67
68static TRandom *rnd = 0;
70{
71 if(rnd == 0) rnd = new TRandom3(0);
72 G4double r = rnd->Uniform();
73 G4ThreeVector p(0., 0., 0.);
74
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);
81
82#if LOCAL_DEBUG > 1
83 std::cout << "LWS::GPOS " << r << std::endl;
84#endif
85
86 if(r <= level1){
88 } else if(r <= level2){
90 } else if(r <= 1.){
92 } else {
93 G4Exception(
94 "LArWheelSliceSolid", "Rnd generator error",
95 FatalException, "GetPointOnSurface: Wrong data from rnd generator"
96 );
97 }
98 return p;
99}
100
102{
103 p[0] = 0.; p[1] = 0.; p[2] = rnd->Uniform(m_Zmin, m_Zmax);
104
105 G4double rmin, rmax;
106 get_r(m_BoundingShape, p[2], rmin, rmax);
107
108 p[1] = rnd->Uniform(rmin, rmax);
109 p.setPhi(rnd->Uniform(0., CLHEP::twopi));
110 G4double dphi = p.phi();
111 int p_fan = 0;
112 G4double d = GetCalculator()->DistanceToTheNearestFan(p, p_fan);
113 dphi -= p.phi();
114
115 G4int side = 0;
116 if(d < 0.) side = -1;
117 if(d >= 0.) side = 1;
118
119 G4double a = GetCalculator()->AmplitudeOfSurface(p, side, p_fan);
120 p[0] = a;
121
122 p.rotateZ(dphi);
123
124 if(m_BoundingShape->Inside(p) == kOutside){
125 G4ThreeVector D = p; D[2] = 0.;
126 G4double d1 = m_BoundingShape->DistanceToIn(p, D);
127 if(d1 > 10.*CLHEP::m){
128 D *= -1;
129 d1 = m_BoundingShape->DistanceToIn(p, D);
130 }
131 if(d1 > 10.*CLHEP::m){
132 set_failover_point(p, "acc fail0");
133 return;
134 }
135 d1 *= 2.;
136
137 G4ThreeVector B = p + D * d1;
138 G4double dphi = B.phi();
139 int B_fan = 0;
141 dphi -= B.phi();
142
143 B[0] = GetCalculator()->AmplitudeOfSurface(B, side, B_fan);
144 B.rotateZ(dphi);
145 EInside Bi = m_BoundingShape->Inside(B);
146 if(Bi == kSurface){
147 p = B;
148 return;
149 }
150 if(Bi == kOutside){
151 set_failover_point(p, "acc fail1");
152 return;
153 }
154 G4ThreeVector D1 = (p - B).unit();
155 G4ThreeVector X = B + D1 * m_BoundingShape->DistanceToOut(B, D1);
156 if(Inside(X) == kSurface){
157 p = X;
158 } else { // failed
159 set_failover_point(p, "acc fail2");
160 return;
161 }
162 }
163}
164
166{
167 const G4double z = rnd->Uniform(m_Zmin, m_Zmax);
168 G4double rmin, rmax;
169 get_r(m_BoundingShape, z, rmin, rmax);
170 const bool inner = rnd->Uniform() > 0.5? true: false;
171
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();
175 int p_fan = 0;
177 dphi -= p.phi();
178
179 const G4double r = p[1];
180
181 G4ThreeVector A1(0., r, z);
182 A1[0] = GetCalculator()->AmplitudeOfSurface(A1, -1, p_fan);
183 A1.rotateZ(dphi);
184 EInside A1i = m_BoundingShape->Inside(A1);
185 // EInside A1a = Inside_accordion(A1);
186 //std::cout << "A1: " << A1i << " " << A1a << std::endl;
187 if(A1i == kSurface){
188 //std::cout << "got A1" << std::endl;
189 p = A1;
190 return;
191 }
192
193 G4ThreeVector A2(0., r, z);
194 A2[0] = GetCalculator()->AmplitudeOfSurface(A2, 1, p_fan);
195 A2.rotateZ(dphi);
196 EInside A2i = m_BoundingShape->Inside(A2);
197 // EInside A2a = Inside_accordion(A2);
198 //std::cout << "A2: " << A2i << " " << A2a << std::endl;
199 if(A2i == kSurface){
200 //std::cout << "got A2" << std::endl;
201 p = A2;
202 return;
203 }
204
205 if(A1i != A2i){
206 if(A2i == kOutside){
207 std::swap(A1, A2);
208 std::swap(A1i, A2i);
209 }
210 // here A1 is outside BP, A2 is inside BP
211 G4ThreeVector d = (A2 - A1).unit();
212 p = A1 + d * m_BoundingShape->DistanceToIn(A1, d);
213 //std::cout << "got A1<->A2" << std::endl;
214 return;
215 }
216 // here A1i == A2i
217
218 G4double step;
219 if(A1i == kInside){
220 G4double d1 = m_BoundingShape->DistanceToOut(A1);
221 G4double d2 = m_BoundingShape->DistanceToOut(A2);
222 step = d1 > d2? d1 : d2;
223 if(inner) step *= -2;
224 else step *= 2;
225 } else {
226 G4double d1 = m_BoundingShape->DistanceToIn(A1);
227 G4double d2 = m_BoundingShape->DistanceToIn(A2);
228 step = d1 > d2? d1 : d2;
229 if(inner) step *= 2;
230 else step *= -2;
231 }
232
233 G4ThreeVector B1(0., r + step, z);
234 B1[0] = GetCalculator()->AmplitudeOfSurface(B1, -1, p_fan);
235 B1.rotateZ(dphi);
236 EInside B1i = m_BoundingShape->Inside(B1);
237 // EInside B1a = Inside_accordion(B1);
238 //std::cout << "B1: " << B1i << " " << B1a << std::endl;
239 if(B1i == kSurface){
240 //std::cout << "got B1" << std::endl;
241 p = B1;
242 return;
243 }
244 G4ThreeVector B2(0., r + step, z);
245 B2[0] = GetCalculator()->AmplitudeOfSurface(B2, 1, p_fan);
246 B2.rotateZ(dphi);
247 EInside B2i = m_BoundingShape->Inside(B2);
248 // EInside B2a = Inside_accordion(B2);
249 //std::cout << "B2: " << B2i << " " << B2a << std::endl;
250 if(B2i == kSurface){
251 //std::cout << "got B2" << std::endl;
252 p = B2;
253 return;
254 }
255
256 if(B1i == A1i || B2i == A1i){ // failed
257 set_failover_point(p, "pol fail1");
258 return;
259 }
260 if(A1i == kInside){
261 std::swap(A1, B1);
262 std::swap(A2, B2);
263 std::swap(A1i, B1i);
264 std::swap(A2i, B2i);
265 }
266 // here A* outside, B* inside, all on accordion surface
267
268 G4ThreeVector d1 = (A1 - B1).unit();
269 G4ThreeVector X1 = B1 + d1 * m_BoundingShape->DistanceToOut(B1, d1);
270 G4ThreeVector d2 = (A2 - B2).unit();
271 G4ThreeVector X2 = B2 + d2 * m_BoundingShape->DistanceToOut(B2, d2);
272
273 G4ThreeVector X = X1;
274 G4double phi1 = X1.phi(), phi2 = X2.phi();
275 // X1 corresponds to side = -, X2 to side = +
276 if(phi1 > 0. && phi2 < 0.) phi2 += CLHEP::twopi;
277 G4double phiX = rnd->Uniform(phi1, phi2);
278 if(phiX > CLHEP::pi) phiX -= CLHEP::twopi;
279 X.setPhi(phiX);
280
281 if(Inside(X) == kSurface){
282 p = X;
283 } else { // failed
284 set_failover_point(p, "pol fail2");
285 }
286}
287
289{
290 p[0] = 0.;
291 p[1] = 0.;
292 p[2] = rnd->Uniform() > 0.5? m_Zmin: m_Zmax;
293
294 G4double rmin, rmax;
295 get_r(m_BoundingShape, p[2], rmin, rmax);
296
297 p[1] = rnd->Uniform(rmin, rmax);
298 p.setPhi(rnd->Uniform(0., CLHEP::twopi));
299 G4double dphi = p.phi();
300 int p_fan = 0;
302 dphi -= p.phi();
303
304 p[0] = rnd->Uniform(
305 GetCalculator()->AmplitudeOfSurface(p, -1, p_fan),
306 GetCalculator()->AmplitudeOfSurface(p, 1, p_fan)
307 );
308
309 p.rotateZ(dphi);
310
311 if(m_BoundingShape->Inside(p) != kSurface){
312 set_failover_point(p, "flat fail");
313 }
314}
315
317{
318 // sagging ignored, effect should be negligible
319 double result =
320 m_f_vol->Integral(m_Rmin, m_Rmax, IntPrecision)
321
322#ifndef LOCAL_DEBUG
324#endif
325 ;
326 return result;
327}
328
330{
331 return m_f_area_on_pc->Integral(m_Zmin, m_Zmax);
332}
333
335{
336 G4double result = 0.;
337 G4double rmin, rmax;
338 get_r(m_BoundingShape, m_Zmin, rmin, rmax);
339 result += rmax - rmin;
340 get_r(m_BoundingShape, m_Zmax, rmin, rmax);
341 result += rmax - rmin;
342 result *= GetCalculator()->GetFanHalfThickness() * 2.;
343 return result;
344}
345
347{
348 m_f_length->SetParameter(0, r);
349
350 double zmin = m_BoundingShape->DistanceToIn(
351 G4ThreeVector(0., r, -m_Zmin), G4ThreeVector(0., 0., 1.)
352 );
353 zmin -= m_Zmin * 2.;
354 double zmax = m_BoundingShape->DistanceToIn(
355 G4ThreeVector(0., r, m_Zmax), G4ThreeVector(0., 0., -1.)
356 );
357 zmax = m_Zmax - zmax;
358 double result = m_f_length->Integral(zmin, zmax);
359 return result;
360}
361
363{
364 return m_f_side_area->Integral(m_Rmin, m_Rmax, IntPrecision);
365}
366
368{
369 double result = 0.;
370
371 double a1 = get_area_on_polycone();
372 result += a1;
373#ifdef LOCAL_DEBUG
374 std::cout << "get_area_on_polycone: " << a1/mm2 << std::endl;
375#endif
376
377 double a2 = get_area_on_face();
378 result += a2;
379#ifdef LOCAL_DEBUG
380 std::cout << "get_area_on_face: " << a2/mm2 << std::endl;
381#endif
382
383 double a3 = get_area_on_side();
384 result += a3;
385#ifdef LOCAL_DEBUG
386 std::cout << "get_area_on_side: " << a3/mm2 << std::endl;
387#endif
388
389 // sagging ignored, effect should be negligible
390 return result
391#ifndef LOCAL_DEBUG
393#endif
394 ;
395}
396
398{
399 const char *on = getenv("LARWHEELSLICESOLID_TEST");
400 if(on == 0) return;
401 std::string test_mode = on;
402
403 std::cout << "============| LArWheelSliceSolid test() routine |=============="
404 << std::endl;
405 std::cout << "Solid of type " << TypeStr() << std::endl;
406 const char *prec = getenv("LARWHEELSLICESOLID_TEST_INTPRECISION");
407 if(prec) IntPrecision = atof(prec);
408 std::cout << std::format("Int. precision {:.6f}\n", IntPrecision);
409 std::cout << "test mode " << test_mode << std::endl;
410
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);
413
414 // TFile *F = new TFile("LArWheelSliceSolid_test.root", "RECREATE");
415 TFile *F = 0;
416 TNtupleD *T = 0;
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");
420 }
421 int N = 1000000;
422 const int Nmax(1000000000);
423 char *NN = getenv("LARWHEELSLICESOLID_TEST_NPOINTS");
424
425 if(NN) {
426 char *endptr;
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));
430 }
431 }
432 if (Nmax<N) {
433 std::cout << "Number of points from LARWHEELSLICESOLID_TEST_NPOINTS environment variable ("<<N<<") is too large. Using " << Nmax << " instead." << std::endl;
434 N=Nmax;
435 }
436 if (N<0) {
437 std::cout << "Number of points from LARWHEELSLICESOLID_TEST_NPOINTS environment variable ("<<N<<") is negative!!. Using 0 instead." << std::endl;
438 N=0;
439 }
440 if(test_mode.find("points") == std::string::npos){
441 N = 0;
442 } else {
443 std::cout << N << " points" << std::endl;
444 }
445 for(int i = 0; i < N; ++ i){
446 G4ThreeVector p = GetPointOnSurface();
447#ifdef LOCAL_DEBUG
448 EInside ii = Inside(p);
449 if(ii != kSurface){
450 std::cout << i << " "
451 << (ii == kInside? "inside": "outside")
452 << std::endl;
453 }
454#endif
455 if(T) T->Fill(p[0], p[1], p[2]);
456 }
457 if(F){
458 T->Write();
459 F->Write();
460 F->Close();
461 delete F;
462 }
463
464 if(test_mode.find("volume") != std::string::npos){
465 double cv = GetCubicVolume();
466 std::cout << "GetCubicVolume: " << cv/CLHEP::mm3 << " mm^3" << std::endl;
467 }
468
469 if(test_mode.find("area") != std::string::npos){
470 double sa = GetSurfaceArea();
471 std::cout << "GetSurfaceArea: " << sa/CLHEP::mm2 << " mm^2" << std::endl;
472 }
473
474 std::cout << "======= end of ArWheelSolid test() routine ============="
475 << std::endl;
476
477 if(test_mode.find("once") != std::string::npos) exit(0);
478}
479
481 if(m_f_area) {
482 delete m_f_area;
483 m_f_area = 0;
484 }
485 if(m_f_vol) {
486 delete m_f_vol;
487 m_f_vol = 0;
488 }
489
490 if(m_f_area_on_pc) {
491 delete m_f_area_on_pc;
492 m_f_area_on_pc = 0;
493 }
494
495 if(m_f_length) {
496 delete m_f_length;
497 m_f_length = 0;
498 }
499 if(m_f_side_area) {
500 delete m_f_side_area;
501 m_f_side_area = 0;
502 }
503}
504
505G4double LArWheelSliceSolid::get_area_at_r(G4double r) const
506{
507 m_f_area->SetParameter(0, r);
508
509 double zmin = m_BoundingShape->DistanceToIn(
510 G4ThreeVector(0., r, m_Zmin), G4ThreeVector(0., 0., 1.)
511 );
512 double zmax = m_BoundingShape->DistanceToIn(
513 G4ThreeVector(0., r, m_Zmax), G4ThreeVector(0., 0., -1.)
514 );
515 zmax = m_Zmax - zmax;
516
517 double result = m_f_area->Integral(zmin, zmax);
518
519 return result;
520}
521
522static std::map<double, LArWheelSliceSolid *> solid;
523
524double LArWheelSliceSolid_fcn_area(double *x, double *p)
525{
526 const double &z = x[0];
527 const double &r = p[0];
528 const double &index = p[1];
529
530 G4ThreeVector a(0., r, z);
531 double b = solid[index]->GetCalculator()->AmplitudeOfSurface(a, -1, 121) // sagging ignored, effect should be negligible, use arbitrary fan number
532 - solid[index]->GetCalculator()->AmplitudeOfSurface(a, 1, 121);
533 return b;
534}
535
536double LArWheelSliceSolid_fcn_vol(double *x, double *p)
537{
538 const double &r = x[0];
539 const double &index = p[0];
540
541 return solid[index]->get_area_at_r(r);
542}
543
544double LArWheelSliceSolid_fcn_area_on_pc(double *x, double *p)
545{
546 const double &z = x[0];
547 const double &index = p[0];
548
549 G4double rmin, rmax;
550 get_r(solid[index]->m_BoundingShape, z, rmin, rmax);
551
552 double result = 0.;
553 G4ThreeVector a(0., rmin, z);
554 result += solid[index]->GetCalculator()->AmplitudeOfSurface(a, -1, 232) // sagging ignored, effect should be negligible, use arbitrary fan number
555 - solid[index]->GetCalculator()->AmplitudeOfSurface(a, 1, 232);
556 a[1] = rmax;
557 result += solid[index]->GetCalculator()->AmplitudeOfSurface(a, -1, 343)
558 - solid[index]->GetCalculator()->AmplitudeOfSurface(a, 1, 343);
559
560 return result;
561}
562
563
564double LArWheelSliceSolid_get_dl(double *x, double *par, G4int side)
565{
566 const double &z = x[0];
567 const double &r = par[0];
568 const double &index = par[1];
569
570 const double h = 0.001;
571
572 //check what happens if z+h > m_Zmax etc
573 G4ThreeVector p(0., r, z + h);
574 G4double D1 = solid[index]->GetCalculator()->AmplitudeOfSurface(p, side, 5665); // sagging ignored, effect should be negligible, use arbitrary fan number
575 p[2] = z - h;
576 D1 -= solid[index]->GetCalculator()->AmplitudeOfSurface(p, side, 5665);
577 D1 /= 2 * h;
578
579 p[2] = z + h / 2;
580 G4double D2 = solid[index]->GetCalculator()->AmplitudeOfSurface(p, side, 5665);
581 p[2] = z - h / 2;
582 D2 -= solid[index]->GetCalculator()->AmplitudeOfSurface(p, side, 5665);
583 D2 /= h;
584
585 G4double D = (D2 * 4 - D1) / 3.;
586 G4double dl = sqrt(1 + D * D);
587
588 return dl;
589}
590
591static double fcn_length(double *x, double *p)
592{
594}
595
596double LArWheelSliceSolid_fcn_side_area(double *x, double *p)
597{
598 const double &r = x[0];
599 const double &index = p[0];
600
601 return solid[index]->get_length_at_r(r);
602}
603
605{
606 m_test_index = double(solid.size());
607 solid[m_test_index] = this;
608
609#ifdef DEBUG_LARWHEELSLICESOLID
610 if(Verbose > 0)
611 std::cout << "LArWheelSliceSolid::init_tests: put " << this
612 << " with index " << m_test_index << std::endl;
613#endif
614
615 m_f_area = new TF1(
616 (GetName() + "_f_area").c_str(), &LArWheelSliceSolid_fcn_area,
617 m_Zmin, m_Zmax, 2
618 );
619 m_f_area->FixParameter(1, m_test_index);
620
621 m_f_vol = new TF1(
622 (GetName() + "_f_vol").c_str(), &LArWheelSliceSolid_fcn_vol,
623 m_Rmin, m_Rmax, 1
624 );
625 m_f_vol->FixParameter(0, m_test_index);
626
627 m_f_area_on_pc = new TF1(
628 (GetName() + "_f_area_pc").c_str(), &LArWheelSliceSolid_fcn_area_on_pc,
629 m_Zmin, m_Zmax, 1
630 );
631 m_f_area_on_pc->FixParameter(0, m_test_index);
632
633 m_f_length = new TF1(
634 (GetName() + "_f_length").c_str(), &fcn_length,
635 m_Zmin, m_Zmax, 2
636 );
637 m_f_length->FixParameter(1, m_test_index);
638
639 m_f_side_area = new TF1(
640 (GetName() + "_f_side_area").c_str(), &LArWheelSliceSolid_fcn_side_area,
641 m_Rmin, m_Rmax, 1
642 );
643 m_f_side_area->FixParameter(0, m_test_index);
644}
645
646#ifdef DEBUG_LARWHEELSLICESOLID
647G4bool LArWheelSliceSolid::test_dti(
648 const G4ThreeVector &inputP, const G4ThreeVector &inputV,
649 const G4double distance
650) const
651{
652 if(distance > 10.*CLHEP::m){
653 LWSDBG(1, std::cout << "DTI test skipped, distance > 10 m"
654 << std::endl);
655 return false;
656 }
657 unsigned long counter = 0;
658 counter ++;
659 G4ThreeVector p;
660 if(m_BoundingShape->Inside(inputP) == kOutside){
661 p = inputP + inputV * m_BoundingShape->DistanceToIn(inputP, inputV);
662 } else p = inputP;
663 const G4double phi0 = p.phi();
664 int p_fan = 0;
665 const G4double d = GetCalculator()->DistanceToTheNearestFan(p, p_fan);
666 if(fabs(d) < m_FHTplusT){
667 std::cout << "DTI test already inside" << MSG_VECTOR(p) << std::endl;
668 return false;
669 }
670 G4ThreeVector v( inputV );
671 v.rotateZ(p.phi() - phi0);
672 const G4double dd = s_IterationPrecision;
673 LWSDBG(1, std::cout << "Start DTI test, expect "
674 << long(distance / dd) << " iterations"
675 << std::endl);
676
677 G4int V = Verbose;
678 Verbose = 0;
679
680 const G4double d1 = distance - s_IterationPrecision;
681 bool first = true;
682 for(G4double t = s_IterationPrecision; t < d1; t += dd){
683 G4ThreeVector p1 = p + v * t;
684 if(fabs(GetCalculator()->DistanceToTheNeutralFibre(p1, p_fan)) < m_FHTplusT){
685 std::cout << "DTI test at " << MSG_VECTOR(inputP) << " -> "
686 << MSG_VECTOR(inputV) << ", translated to "
687 << MSG_VECTOR(p) << " - > " << MSG_VECTOR(v)
688 << " in range of "
689 << distance << ": found nearer intersection at local point"
690 << MSG_VECTOR(p1) << ", distance " << t
691 << ", call " << counter
692 << std::endl;
693 Verbose = V;
694
695 if(first){
696 first = false;
697 FILE *F = fopen("dti_error.dat", "w");
698 if(F){
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());
701 for(G4double e = s_IterationPrecision; e < d1; e += dd){
702 p1 = p + v * e;
703 G4double f = fabs(GetCalculator()->DistanceToTheNeutralFibre(p1, p_fan)) - m_FanHalfThickness;
704 fprintf(F, "%10e %10e\n", e, f);
705 }
706 fclose(F);
707 }
708 }
709
710 return true;
711 }
712 }
713 Verbose = V;
714 LWSDBG(1, std::cout << "DTI test at " << MSG_VECTOR(p) << " -> "
715 << MSG_VECTOR(v) << " in range of "
716 << distance << ": allright" << std::endl);
717 return false;
718}
719
720G4bool LArWheelSliceSolid::test_dto(
721 const G4ThreeVector &inputP, const G4ThreeVector &inputV,
722 const G4double distance
723) const
724{
725 if(distance > 10.*CLHEP::m){
726 LWSDBG(1, std::cout << "DTO test skipped, distance > 10 m"
727 << std::endl);
728 return false;
729 }
730 unsigned long counter = 0;
731 counter ++;
732 G4ThreeVector p( inputP );
733 const G4double phi0 = p.phi();
734 int p_fan = 0;
735 const G4double d = GetCalculator()->DistanceToTheNearestFan(p, p_fan);
736 if(fabs(d) > m_FHTplusT){
737 std::cout << "DTO test already outside" << MSG_VECTOR(p) << std::endl;
738 return false;
739 }
740 G4ThreeVector v( inputV );
741 v.rotateZ(p.phi() - phi0);
742 const G4double dd = s_IterationPrecision;
743 LWSDBG(1, std::cout << "Start DTO test, expect "
744 << long(distance / dd) << " iterations"
745 << std::endl);
746
747 G4int V = Verbose;
748 Verbose = 0;
749
750 const G4double d1 = distance - s_IterationPrecision;
751 static bool first = true;
752 for(G4double t = s_IterationPrecision; t < d1; t += dd){
753 G4ThreeVector p1 = p + v * t;
754 if(fabs(GetCalculator()->DistanceToTheNeutralFibre(p1, p_fan)) > m_FHTplusT){
755 std::cout << "DTO test at " << MSG_VECTOR(inputP) << " -> "
756 << MSG_VECTOR(inputV) << ", translated to "
757 << MSG_VECTOR(p) << " - > " << MSG_VECTOR(v)
758 << " in range of "
759 << distance << ": found nearer intersection at local point"
760 << MSG_VECTOR(p1) << ", distance " << t
761 << ", call " << counter
762 << std::endl;
763 Verbose = V;
764
765 if(first){
766 first = false;
767 FILE *F = fopen("dto_error.dat", "w");
768 if(F){
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());
771 for(G4double e = s_IterationPrecision; e < d1; e += dd){
772 p1 = p + v * e;
773 G4double f = fabs(GetCalculator()->DistanceToTheNeutralFibre(p1, p_fan)) - m_FanHalfThickness;
774 fprintf(F, "%10e %10e\n", e, f);
775 }
776 fclose(F);
777 }
778 }
779
780 return true;
781 }
782 }
783 Verbose = V;
784 LWSDBG(1, std::cout << "DTO test at " << MSG_VECTOR(p) << " -> "
785 << MSG_VECTOR(v) << " in range of "
786 << distance << ": allright" << std::endl);
787 return false;
788}
789#endif
const PlainObject unit() const
This is a plugin that makes Eigen look like CLHEP & defines some convenience methods.
static Double_t a
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 TRandom * rnd
static double IntPrecision
double LArWheelSliceSolid_get_dl(double *x, double *par, G4int side)
#define LWSDBG(a, b)
#define F(x, y, z)
Definition MD5.cxx:112
#define x
#define z
Define macros for attributes used to control the static checker.
#define ATLAS_NO_CHECK_FILE_THREAD_SAFETY
Header file for AthHistogramAlgorithm.
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 *)
static const G4double s_Tolerance
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
G4String TypeStr(void) const
G4ThreeVector GetPointOnSurface(void) const
void get_point_on_accordion_surface(G4ThreeVector &) const
int r
Definition globals.cxx:22
float distance(const Amg::Vector3D &p1, const Amg::Vector3D &p2)
calculates the distance between two point in 3D space
bool first
Definition DeMoScan.py:534
@ Verbose
Definition ZDCMsg.h:18
Definition index.py:1
void swap(ElementLinkVector< DOBJ > &lhs, ElementLinkVector< DOBJ > &rhs)