ATLAS Offline Software
Loading...
Searching...
No Matches
LArWheelSolidTests.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 "LArWheelSolid.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 LArWheelSolid::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; p[2] = m_Zmin;
47 int p_fan = 0;
48 GetCalculator()->DistanceToTheNearestFan(p, p_fan);
49
50#ifdef LOCAL_DEBUG
51 if(m) std::cout << m << std::endl;
52#endif
53 }
54
55static void get_r(const G4VSolid *p, G4double z,
56 G4double &rmin, G4double &rmax
57 )
58{
59 G4ThreeVector from(10.*CLHEP::m, 0., z);
60 rmax = from[0] - p->DistanceToIn(from, G4ThreeVector(-1., 0., 0.));
61 from[0] = 0.;
62 rmin = p->DistanceToIn(from, G4ThreeVector(1., 0., 0.));
63}
64
65static TRandom *rnd = 0;
66G4ThreeVector LArWheelSolid::GetPointOnSurface(void) const
67{
68 if(rnd == 0){
69 rnd = new TRandom3(0);
70 }
71
72 G4double r = rnd->Uniform();
73
74 G4ThreeVector p(0., 0., 0.);
75
76 G4double level1 = .980;
77 G4double level2 = .993;
78 const char *v = getenv("LARWHEELSOLID_TEST_MODE_LEVEL1");
79 if(v) level1 = atof(v);
80 const char *v1 = getenv("LARWHEELSOLID_TEST_MODE_LEVEL2");
81 if(v1) level2 = atof(v1);
82
83#if LOCAL_DEBUG > 1
84 std::cout << "LWS::GPOS " << r << std::endl;
85#endif
86
87 if(r <= level1){
89 } else if(r <= level2){
91 } else if(r <= 1.){
93 } else {
94 G4Exception("LArWheelSolid", "Rnd generator error", FatalException, "GetPointOnSurface: Wrong data from rnd generator");
95 }
96 return p;
97}
98
100{
101 p[0] = 0.;
102 p[1] = 0.;
103 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(m_MinPhi, m_MaxPhi));
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(m_MinPhi, m_MaxPhi));
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(m_MinPhi, m_MaxPhi));
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 = m_f_vol->Integral(m_Rmin, m_Rmax, IntPrecision)
320
321#ifndef LOCAL_DEBUG
323#endif
324 ;
325 return result;
326}
327
329{
330 return m_f_area_on_pc->Integral(m_Zmin, m_Zmax);
331}
332
334{
335 G4double result = 0.;
336 G4double rmin, rmax;
337 get_r(m_BoundingShape, m_Zmin, rmin, rmax);
338 result += rmax - rmin;
339 get_r(m_BoundingShape, m_Zmax, rmin, rmax);
340 result += rmax - rmin;
341 result *= GetCalculator()->GetFanHalfThickness() * 2.;
342 return result;
343}
344
345G4double LArWheelSolid::get_length_at_r(G4double r) const
346{
347 m_f_length->SetParameter(0, r);
348
349 double zmin = m_BoundingShape->DistanceToIn(
350 G4ThreeVector(0., r, -m_Zmin), G4ThreeVector(0., 0., 1.)
351 );
352 zmin -= m_Zmin * 2.;
353 double zmax = m_BoundingShape->DistanceToIn(
354 G4ThreeVector(0., r, m_Zmax), G4ThreeVector(0., 0., -1.)
355 );
356 zmax = m_Zmax - zmax;
357 double result = m_f_length->Integral(zmin, zmax);
358 return result;
359}
360
362{
363 return m_f_side_area->Integral(m_Rmin, m_Rmax, IntPrecision);
364}
365
367{
368 double result = 0.;
369
370 double a1 = get_area_on_polycone();
371 result += a1;
372#ifdef LOCAL_DEBUG
373 std::cout << "get_area_on_polycone: " << a1/mm2 << std::endl;
374#endif
375
376 double a2 = get_area_on_face();
377 result += a2;
378#ifdef LOCAL_DEBUG
379 std::cout << "get_area_on_face: " << a2/mm2 << std::endl;
380#endif
381
382 double a3 = get_area_on_side();
383 result += a3;
384#ifdef LOCAL_DEBUG
385 std::cout << "get_area_on_side: " << a3/mm2 << std::endl;
386#endif
387
388 // sagging ignored, effect should be negligible
389 return result
390#ifndef LOCAL_DEBUG
392#endif
393 ;
394}
395
397{
398 const char *on = getenv("LARWHEELSOLID_TEST");
399 if(on == 0) return;
400 std::string test_mode = on;
401
402 std::cout << "============| LArWheelSolid test() routine |=============="
403 << std::endl;
404 std::cout << "Solid of type " << LArWheelSolidTypeString(m_Type)
405 << std::endl;
406 const char *prec = getenv("LARWHEELSOLID_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("LArWheelSolid_test.root", "RECREATE");
415 TFile *F = 0;
416 TNtupleD *T = 0;
417 if(test_mode.find("root") != std::string::npos){
418 F = new TFile("LArWheelSolid_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("LARWHEELSOLID_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 LARWHEELSOLID_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 LARWHEELSOLID_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
478 if(test_mode.find("once") != std::string::npos) exit(0); }
479
480}
481
483 if(m_f_area) {
484 delete m_f_area;
485 m_f_area = 0;
486 }
487 if(m_f_vol) {
488 delete m_f_vol;
489 m_f_vol = 0;
490 }
491
492 if(m_f_area_on_pc) {
493 delete m_f_area_on_pc;
494 m_f_area_on_pc = 0;
495 }
496
497 if(m_f_length) {
498 delete m_f_length;
499 m_f_length = 0;
500 }
501 if(m_f_side_area) {
502 delete m_f_side_area;
503 m_f_side_area = 0;
504 }
505}
506
507G4double LArWheelSolid::get_area_at_r(G4double r) const
508{
509 m_f_area->SetParameter(0, r);
510
511 double zmin = m_BoundingShape->DistanceToIn(
512 G4ThreeVector(0., r, m_Zmin), G4ThreeVector(0., 0., 1.)
513 );
514 double zmax = m_BoundingShape->DistanceToIn(
515 G4ThreeVector(0., r, m_Zmax), G4ThreeVector(0., 0., -1.)
516 );
517 zmax = m_Zmax - zmax;
518
519 double result = m_f_area->Integral(zmin, zmax);
520
521 return result;
522}
523
524static std::map<double, LArWheelSolid *> solid;
525
526double LArWheelSolid_fcn_area(double *x, double *p)
527{
528 const double &z = x[0];
529 const double &r = p[0];
530 const double &index = p[1];
531
532 G4ThreeVector a(0., r, z);
533 double b = solid[index]->GetCalculator()->AmplitudeOfSurface(a, -1, 121) // sagging ignored, effect should be negligible, use arbitrary fan number
534 - solid[index]->GetCalculator()->AmplitudeOfSurface(a, 1, 121);
535 return b;
536}
537
538double LArWheelSolid_fcn_vol(double *x, double *p)
539{
540 const double &r = x[0];
541 const double &index = p[0];
542
543 return solid[index]->get_area_at_r(r);
544}
545
546double LArWheelSolid_fcn_area_on_pc(double *x, double *p)
547{
548 const double &z = x[0];
549 const double &index = p[0];
550
551 G4double rmin, rmax;
552 get_r(solid[index]->m_BoundingShape, z, rmin, rmax);
553
554 double result = 0.;
555 G4ThreeVector a(0., rmin, z);
556 result += solid[index]->GetCalculator()->AmplitudeOfSurface(a, -1, 232) // sagging ignored, effect should be negligible, use arbitrary fan number
557 - solid[index]->GetCalculator()->AmplitudeOfSurface(a, 1, 232);
558 a[1] = rmax;
559 result += solid[index]->GetCalculator()->AmplitudeOfSurface(a, -1, 343)
560 - solid[index]->GetCalculator()->AmplitudeOfSurface(a, 1, 343);
561
562 return result;
563}
564
565
566double LArWheelSolid_get_dl(double *x, double *par, G4int side)
567{
568 const double &z = x[0];
569 const double &r = par[0];
570 const double &index = par[1];
571
572 const double h = 0.001;
573
574 //check what happens if z+h > m_Zmax etc
575 G4ThreeVector p(0., r, z + h);
576 G4double D1 = solid[index]->GetCalculator()->AmplitudeOfSurface(p, side, 5665); // sagging ignored, effect should be negligible, use arbitrary fan number
577 p[2] = z - h;
578 D1 -= solid[index]->GetCalculator()->AmplitudeOfSurface(p, side, 5665);
579 D1 /= 2 * h;
580
581 p[2] = z + h / 2;
582 G4double D2 = solid[index]->GetCalculator()->AmplitudeOfSurface(p, side, 5665);
583 p[2] = z - h / 2;
584 D2 -= solid[index]->GetCalculator()->AmplitudeOfSurface(p, side, 5665);
585 D2 /= h;
586
587 G4double D = (D2 * 4 - D1) / 3.;
588 G4double dl = sqrt(1 + D * D);
589
590 return dl;
591}
592
593static double fcn_length(double *x, double *p)
594{
595 return LArWheelSolid_get_dl(x, p, 1) + LArWheelSolid_get_dl(x, p, -1);
596}
597
598double LArWheelSolid_fcn_side_area(double *x, double *p)
599{
600 const double &r = x[0];
601 const double &index = p[0];
602
603 return solid[index]->get_length_at_r(r);
604}
605
607{
608 m_test_index = double(solid.size());
609 solid[m_test_index] = this;
610
611#ifdef DEBUG_LARWHEELSOLID
612 std::cout << "LArWheelSolid::init_tests: put " << this
613 << " with index " << m_test_index << std::endl;
614#endif
615
616 m_f_area = new TF1(
617 (GetName() + "_f_area").c_str(), &LArWheelSolid_fcn_area,
618 m_Zmin, m_Zmax, 2
619 );
620 m_f_area->FixParameter(1, m_test_index);
621
622 m_f_vol = new TF1(
623 (GetName() + "_f_vol").c_str(), &LArWheelSolid_fcn_vol,
624 m_Rmin, m_Rmax, 1
625 );
626 m_f_vol->FixParameter(0, m_test_index);
627
628 m_f_area_on_pc = new TF1(
629 (GetName() + "_f_area_pc").c_str(), &LArWheelSolid_fcn_area_on_pc,
630 m_Zmin, m_Zmax, 1
631 );
632 m_f_area_on_pc->FixParameter(0, m_test_index);
633
634 m_f_length = new TF1(
635 (GetName() + "_f_length").c_str(), &fcn_length,
636 m_Zmin, m_Zmax, 2
637 );
638 m_f_length->FixParameter(1, m_test_index);
639
640 m_f_side_area = new TF1(
641 (GetName() + "_f_side_area").c_str(), &LArWheelSolid_fcn_side_area,
642 m_Rmin, m_Rmax, 1
643 );
644 m_f_side_area->FixParameter(0, m_test_index);
645}
646
647#ifdef DEBUG_LARWHEELSOLID
648G4bool LArWheelSolid::test_dti(
649 const G4ThreeVector &inputP, const G4ThreeVector &inputV,
650 const G4double distance
651) const
652{
653 if(distance > 10.*CLHEP::m){
654 LWSDBG(1, std::cout << "DTI test skipped, distance > 10 m"
655 << std::endl);
656 return false;
657 }
658 unsigned long counter = 0;
659 counter ++;
660 G4ThreeVector p;
661 if(m_BoundingShape->Inside(inputP) == kOutside){
662 p = inputP + inputV * m_BoundingShape->DistanceToIn(inputP, inputV);
663 } else p = inputP;
664 const G4double phi0 = p.phi();
665 int p_fan = 0;
666 const G4double d = GetCalculator()->DistanceToTheNearestFan(p, p_fan);
667 if(fabs(d) < m_FHTplusT){
668 std::cout << "DTI test already inside" << MSG_VECTOR(p) << std::endl;
669 return false;
670 }
671 G4ThreeVector v( inputV );
672 v.rotateZ(p.phi() - phi0);
673 const G4double dd = s_IterationPrecision;
674 LWSDBG(1, std::cout << "Start DTI test, expect "
675 << long(distance / dd) << " iterations"
676 << std::endl);
677
678 G4int V = Verbose;
679 Verbose = 0;
680
681 const G4double d1 = distance - s_IterationPrecision;
682 bool first = true;
683 for(G4double t = s_IterationPrecision; t < d1; t += dd){
684 G4ThreeVector p1 = p + v * t;
685 if(fabs(GetCalculator()->DistanceToTheNeutralFibre(p1, p_fan)) < m_FHTplusT){
686 std::cout << "DTI test at " << MSG_VECTOR(inputP) << " -> "
687 << MSG_VECTOR(inputV) << ", translated to "
688 << MSG_VECTOR(p) << " - > " << MSG_VECTOR(v)
689 << " in range of "
690 << distance << ": found nearer intersection at local point"
691 << MSG_VECTOR(p1) << ", distance " << t
692 << ", call " << counter
693 << std::endl;
694 Verbose = V;
695
696 if(first){
697 first = false;
698 FILE *F = fopen("dti_error.dat", "w");
699 if(F){
700 fprintf(F, "%10e %10e %10e\n", p.x(), p.y(), p.z());
701 fprintf(F, "%10e %10e %10e\n", v.x(), v.y(), v.z());
702 for(G4double e = s_IterationPrecision; e < d1; e += dd){
703 p1 = p + v * e;
704 G4double f = fabs(GetCalculator()->DistanceToTheNeutralFibre(p1, p_fan)) - m_FanHalfThickness;
705 fprintf(F, "%10e %10e\n", e, f);
706 }
707 fclose(F);
708 }
709 }
710
711 return true;
712 }
713 }
714 Verbose = V;
715 LWSDBG(1, std::cout << "DTI test at " << MSG_VECTOR(p) << " -> "
716 << MSG_VECTOR(v) << " in range of "
717 << distance << ": allright" << std::endl);
718 return false;
719}
720
721G4bool LArWheelSolid::test_dto(
722 const G4ThreeVector &inputP, const G4ThreeVector &inputV,
723 const G4double distance
724) const
725{
726 if(distance > 10.*CLHEP::m){
727 LWSDBG(1, std::cout << "DTO test skipped, distance > 10 m"
728 << std::endl);
729 return false;
730 }
731 unsigned long counter = 0;
732 counter ++;
733 G4ThreeVector p( inputP );
734 const G4double phi0 = p.phi();
735 int p_fan = 0;
736 const G4double d = GetCalculator()->DistanceToTheNearestFan(p, p_fan);
737 if(fabs(d) > m_FHTplusT){
738 std::cout << "DTO test already outside" << MSG_VECTOR(p) << std::endl;
739 return false;
740 }
741 G4ThreeVector v( inputV );
742 v.rotateZ(p.phi() - phi0);
743 const G4double dd = s_IterationPrecision;
744 LWSDBG(1, std::cout << "Start DTO test, expect "
745 << long(distance / dd) << " iterations"
746 << std::endl);
747
748 G4int V = Verbose;
749 Verbose = 0;
750
751 const G4double d1 = distance - s_IterationPrecision;
752 static bool first = true;
753 for(G4double t = s_IterationPrecision; t < d1; t += dd){
754 G4ThreeVector p1 = p + v * t;
755 if(fabs(GetCalculator()->DistanceToTheNeutralFibre(p1, p_fan)) > m_FHTplusT){
756 std::cout << "DTO test at " << MSG_VECTOR(inputP) << " -> "
757 << MSG_VECTOR(inputV) << ", translated to "
758 << MSG_VECTOR(p) << " - > " << MSG_VECTOR(v)
759 << " in range of "
760 << distance << ": found nearer intersection at local point"
761 << MSG_VECTOR(p1) << ", distance " << t
762 << ", call " << counter
763 << std::endl;
764 Verbose = V;
765
766 if(first){
767 first = false;
768 FILE *F = fopen("dto_error.dat", "w");
769 if(F){
770 fprintf(F, "%10e %10e %10e\n", p.x(), p.y(), p.z());
771 fprintf(F, "%10e %10e %10e\n", v.x(), v.y(), v.z());
772 for(G4double e = s_IterationPrecision; e < d1; e += dd){
773 p1 = p + v * e;
774 G4double f = fabs(GetCalculator()->DistanceToTheNeutralFibre(p1, p_fan)) - m_FanHalfThickness;
775 fprintf(F, "%10e %10e\n", e, f);
776 }
777 fclose(F);
778 }
779 }
780
781 return true;
782 }
783 }
784 Verbose = V;
785 LWSDBG(1, std::cout << "DTO test at " << MSG_VECTOR(p) << " -> "
786 << MSG_VECTOR(v) << " in range of "
787 << distance << ": allright" << std::endl);
788 return false;
789}
790#endif
const PlainObject unit() const
This is a plugin that makes Eigen look like CLHEP & defines some convenience methods.
static Double_t a
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 LArWheelSolid_get_dl(double *x, double *par, G4int side)
double LArWheelSolid_fcn_area(double *x, double *p)
double LArWheelSolid_fcn_vol(double *x, double *p)
double LArWheelSolid_fcn_side_area(double *x, double *p)
double LArWheelSolid_fcn_area_on_pc(double *x, double *p)
static double fcn_length(double *x, double *p)
static void get_r(const G4VSolid *p, G4double z, G4double &rmin, G4double &rmax)
#define LWSDBG(a, b)
const char * LArWheelSolidTypeString(LArWheelSolid_t type)
@ OuterAbsorberWheel
#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.
G4double get_area_on_face(void) const
void get_point_on_accordion_surface(G4ThreeVector &) const
G4double get_area_on_polycone(void) const
const LArWheelSolid_t m_Type
static const G4double s_IterationPrecision
G4double GetSurfaceArea(void)
static const G4double s_Tolerance
friend double LArWheelSolid_fcn_area(double *, double *)
G4double m_MinPhi
EInside Inside_accordion(const G4ThreeVector &) const
G4VSolid * m_BoundingShape
friend double LArWheelSolid_fcn_vol(double *, double *)
G4double get_area_at_r(G4double r) const
friend double LArWheelSolid_fcn_side_area(double *, double *)
G4double get_length_at_r(G4double r) const
friend double LArWheelSolid_fcn_area_on_pc(double *, double *)
void set_failover_point(G4ThreeVector &p, const char *m=0) const
G4double m_MaxPhi
G4double GetCubicVolume(void)
EInside Inside(const G4ThreeVector &) const
G4ThreeVector GetPointOnSurface(void) const
void get_point_on_flat_surface(G4ThreeVector &) const
G4double get_area_on_side(void) const
void get_point_on_polycone_surface(G4ThreeVector &) const
G4double m_FanHalfThickness
const LArWheelCalculator * GetCalculator(void) const
G4double m_FHTplusT
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)