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 "boost/io/ios_state.hpp"
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;
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 boost::io::ios_all_saver ias(std::cout);
399 const char *on = getenv("LARWHEELSOLID_TEST");
400 if(on == 0) return;
401 std::string test_mode = on;
402
403 std::cout << "============| LArWheelSolid test() routine |=============="
404 << std::endl;
405 std::cout << "Solid of type " << LArWheelSolidTypeString(m_Type)
406 << std::endl;
407 std::cout.precision(6);
408 std::cout << std::fixed;
409 const char *prec = getenv("LARWHEELSOLID_TEST_INTPRECISION");
410 if(prec) IntPrecision = atof(prec);
411 std::cout << "Int. precision " << IntPrecision << std::endl;
412 std::cout << "test mode " << test_mode << std::endl;
413
414 std::cout << "m_Rmin = " << m_Rmin << " m_Rmax = " << m_Rmax << std::endl
415 << "m_Zmin = " << m_Zmin << " m_Zmax = " << m_Zmax << std::endl;
416
417 // TFile *F = new TFile("LArWheelSolid_test.root", "RECREATE");
418 TFile *F = 0;
419 TNtupleD *T = 0;
420 if(test_mode.find("root") != std::string::npos){
421 F = new TFile("LArWheelSolid_test.root", "UPDATE");
422 T = new TNtupleD(GetName(), GetName(), "x:y:z");
423 }
424 int N = 1000000;
425 const int Nmax(1000000000);
426 char *NN = getenv("LARWHEELSOLID_TEST_NPOINTS");
427
428 if(NN) {
429 char *endptr;
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));
433 }
434 }
435 if (Nmax<N) {
436 std::cout << "Number of points from LARWHEELSOLID_TEST_NPOINTS environment variable ("<<N<<") is too large. Using " << Nmax << " instead." << std::endl;
437 N=Nmax;
438 }
439 if (N<0) {
440 std::cout << "Number of points from LARWHEELSOLID_TEST_NPOINTS environment variable ("<<N<<") is negative!!. Using 0 instead." << std::endl;
441 N=0;
442 }
443 if(test_mode.find("points") == std::string::npos){
444 N = 0;
445 } else {
446 std::cout << N << " points" << std::endl;
447 }
448 for(int i = 0; i < N; ++ i){
449 G4ThreeVector p = GetPointOnSurface();
450#ifdef LOCAL_DEBUG
451 EInside ii = Inside(p);
452 if(ii != kSurface){
453 std::cout << i << " "
454 << (ii == kInside? "inside": "outside")
455 << std::endl;
456 }
457#endif
458 if(T) T->Fill(p[0], p[1], p[2]);
459 }
460 if(F){
461 T->Write();
462 F->Write();
463 F->Close();
464 delete F;
465 }
466
467 if(test_mode.find("volume") != std::string::npos){
468 double cv = GetCubicVolume();
469 std::cout << "GetCubicVolume: " << cv/CLHEP::mm3 << " mm^3" << std::endl;
470 }
471
472 if(test_mode.find("area") != std::string::npos){
473 double sa = GetSurfaceArea();
474 std::cout << "GetSurfaceArea: " << sa/CLHEP::mm2 << " mm^2" << std::endl;
475 }
476
477 std::cout << "======= end of ArWheelSolid test() routine ============="
478 << std::endl;
479
481 if(test_mode.find("once") != std::string::npos) exit(0); }
482
483 ias.restore();
484}
485
487 if(m_f_area) {
488 delete m_f_area;
489 m_f_area = 0;
490 }
491 if(m_f_vol) {
492 delete m_f_vol;
493 m_f_vol = 0;
494 }
495
496 if(m_f_area_on_pc) {
497 delete m_f_area_on_pc;
498 m_f_area_on_pc = 0;
499 }
500
501 if(m_f_length) {
502 delete m_f_length;
503 m_f_length = 0;
504 }
505 if(m_f_side_area) {
506 delete m_f_side_area;
507 m_f_side_area = 0;
508 }
509}
510
511G4double LArWheelSolid::get_area_at_r(G4double r) const
512{
513 m_f_area->SetParameter(0, r);
514
515 double zmin = m_BoundingShape->DistanceToIn(
516 G4ThreeVector(0., r, m_Zmin), G4ThreeVector(0., 0., 1.)
517 );
518 double zmax = m_BoundingShape->DistanceToIn(
519 G4ThreeVector(0., r, m_Zmax), G4ThreeVector(0., 0., -1.)
520 );
521 zmax = m_Zmax - zmax;
522
523 double result = m_f_area->Integral(zmin, zmax);
524
525 return result;
526}
527
528static std::map<double, LArWheelSolid *> solid;
529
530double LArWheelSolid_fcn_area(double *x, double *p)
531{
532 const double &z = x[0];
533 const double &r = p[0];
534 const double &index = p[1];
535
536 G4ThreeVector a(0., r, z);
537 double b = solid[index]->GetCalculator()->AmplitudeOfSurface(a, -1, 121) // sagging ignored, effect should be negligible, use arbitrary fan number
538 - solid[index]->GetCalculator()->AmplitudeOfSurface(a, 1, 121);
539 return b;
540}
541
542double LArWheelSolid_fcn_vol(double *x, double *p)
543{
544 const double &r = x[0];
545 const double &index = p[0];
546
547 return solid[index]->get_area_at_r(r);
548}
549
550double LArWheelSolid_fcn_area_on_pc(double *x, double *p)
551{
552 const double &z = x[0];
553 const double &index = p[0];
554
555 G4double rmin, rmax;
556 get_r(solid[index]->m_BoundingShape, z, rmin, rmax);
557
558 double result = 0.;
559 G4ThreeVector a(0., rmin, z);
560 result += solid[index]->GetCalculator()->AmplitudeOfSurface(a, -1, 232) // sagging ignored, effect should be negligible, use arbitrary fan number
561 - solid[index]->GetCalculator()->AmplitudeOfSurface(a, 1, 232);
562 a[1] = rmax;
563 result += solid[index]->GetCalculator()->AmplitudeOfSurface(a, -1, 343)
564 - solid[index]->GetCalculator()->AmplitudeOfSurface(a, 1, 343);
565
566 return result;
567}
568
569
570double LArWheelSolid_get_dl(double *x, double *par, G4int side)
571{
572 const double &z = x[0];
573 const double &r = par[0];
574 const double &index = par[1];
575
576 const double h = 0.001;
577
578 //check what happens if z+h > m_Zmax etc
579 G4ThreeVector p(0., r, z + h);
580 G4double D1 = solid[index]->GetCalculator()->AmplitudeOfSurface(p, side, 5665); // sagging ignored, effect should be negligible, use arbitrary fan number
581 p[2] = z - h;
582 D1 -= solid[index]->GetCalculator()->AmplitudeOfSurface(p, side, 5665);
583 D1 /= 2 * h;
584
585 p[2] = z + h / 2;
586 G4double D2 = solid[index]->GetCalculator()->AmplitudeOfSurface(p, side, 5665);
587 p[2] = z - h / 2;
588 D2 -= solid[index]->GetCalculator()->AmplitudeOfSurface(p, side, 5665);
589 D2 /= h;
590
591 G4double D = (D2 * 4 - D1) / 3.;
592 G4double dl = sqrt(1 + D * D);
593
594 return dl;
595}
596
597static double fcn_length(double *x, double *p)
598{
599 return LArWheelSolid_get_dl(x, p, 1) + LArWheelSolid_get_dl(x, p, -1);
600}
601
602double LArWheelSolid_fcn_side_area(double *x, double *p)
603{
604 const double &r = x[0];
605 const double &index = p[0];
606
607 return solid[index]->get_length_at_r(r);
608}
609
611{
612 m_test_index = double(solid.size());
613 solid[m_test_index] = this;
614
615#ifdef DEBUG_LARWHEELSOLID
616 std::cout << "LArWheelSolid::init_tests: put " << this
617 << " with index " << m_test_index << std::endl;
618#endif
619
620 m_f_area = new TF1(
621 (GetName() + "_f_area").c_str(), &LArWheelSolid_fcn_area,
622 m_Zmin, m_Zmax, 2
623 );
624 m_f_area->FixParameter(1, m_test_index);
625
626 m_f_vol = new TF1(
627 (GetName() + "_f_vol").c_str(), &LArWheelSolid_fcn_vol,
628 m_Rmin, m_Rmax, 1
629 );
630 m_f_vol->FixParameter(0, m_test_index);
631
632 m_f_area_on_pc = new TF1(
633 (GetName() + "_f_area_pc").c_str(), &LArWheelSolid_fcn_area_on_pc,
634 m_Zmin, m_Zmax, 1
635 );
636 m_f_area_on_pc->FixParameter(0, m_test_index);
637
638 m_f_length = new TF1(
639 (GetName() + "_f_length").c_str(), &fcn_length,
640 m_Zmin, m_Zmax, 2
641 );
642 m_f_length->FixParameter(1, m_test_index);
643
644 m_f_side_area = new TF1(
645 (GetName() + "_f_side_area").c_str(), &LArWheelSolid_fcn_side_area,
646 m_Rmin, m_Rmax, 1
647 );
648 m_f_side_area->FixParameter(0, m_test_index);
649}
650
651#ifdef DEBUG_LARWHEELSOLID
652G4bool LArWheelSolid::test_dti(
653 const G4ThreeVector &inputP, const G4ThreeVector &inputV,
654 const G4double distance
655) const
656{
657 if(distance > 10.*CLHEP::m){
658 LWSDBG(1, std::cout << "DTI test skipped, distance > 10 m"
659 << std::endl);
660 return false;
661 }
662 unsigned long counter = 0;
663 counter ++;
664 G4ThreeVector p;
665 if(m_BoundingShape->Inside(inputP) == kOutside){
666 p = inputP + inputV * m_BoundingShape->DistanceToIn(inputP, inputV);
667 } else p = inputP;
668 const G4double phi0 = p.phi();
669 int p_fan = 0;
670 const G4double d = GetCalculator()->DistanceToTheNearestFan(p, p_fan);
671 if(fabs(d) < m_FHTplusT){
672 std::cout << "DTI test already inside" << MSG_VECTOR(p) << std::endl;
673 return false;
674 }
675 G4ThreeVector v( inputV );
676 v.rotateZ(p.phi() - phi0);
677 const G4double dd = s_IterationPrecision;
678 LWSDBG(1, std::cout << "Start DTI test, expect "
679 << long(distance / dd) << " iterations"
680 << std::endl);
681
682 G4int V = Verbose;
683 Verbose = 0;
684
685 const G4double d1 = distance - s_IterationPrecision;
686 bool first = true;
687 for(G4double t = s_IterationPrecision; t < d1; t += dd){
688 G4ThreeVector p1 = p + v * t;
689 if(fabs(GetCalculator()->DistanceToTheNeutralFibre(p1, p_fan)) < m_FHTplusT){
690 std::cout << "DTI test at " << MSG_VECTOR(inputP) << " -> "
691 << MSG_VECTOR(inputV) << ", translated to "
692 << MSG_VECTOR(p) << " - > " << MSG_VECTOR(v)
693 << " in range of "
694 << distance << ": found nearer intersection at local point"
695 << MSG_VECTOR(p1) << ", distance " << t
696 << ", call " << counter
697 << std::endl;
698 Verbose = V;
699
700 if(first){
701 first = false;
702 FILE *F = fopen("dti_error.dat", "w");
703 if(F){
704 fprintf(F, "%10e %10e %10e\n", p.x(), p.y(), p.z());
705 fprintf(F, "%10e %10e %10e\n", v.x(), v.y(), v.z());
706 for(G4double e = s_IterationPrecision; e < d1; e += dd){
707 p1 = p + v * e;
708 G4double f = fabs(GetCalculator()->DistanceToTheNeutralFibre(p1, p_fan)) - m_FanHalfThickness;
709 fprintf(F, "%10e %10e\n", e, f);
710 }
711 fclose(F);
712 }
713 }
714
715 return true;
716 }
717 }
718 Verbose = V;
719 LWSDBG(1, std::cout << "DTI test at " << MSG_VECTOR(p) << " -> "
720 << MSG_VECTOR(v) << " in range of "
721 << distance << ": allright" << std::endl);
722 return false;
723}
724
725G4bool LArWheelSolid::test_dto(
726 const G4ThreeVector &inputP, const G4ThreeVector &inputV,
727 const G4double distance
728) const
729{
730 if(distance > 10.*CLHEP::m){
731 LWSDBG(1, std::cout << "DTO test skipped, distance > 10 m"
732 << std::endl);
733 return false;
734 }
735 unsigned long counter = 0;
736 counter ++;
737 G4ThreeVector p( inputP );
738 const G4double phi0 = p.phi();
739 int p_fan = 0;
740 const G4double d = GetCalculator()->DistanceToTheNearestFan(p, p_fan);
741 if(fabs(d) > m_FHTplusT){
742 std::cout << "DTO test already outside" << MSG_VECTOR(p) << std::endl;
743 return false;
744 }
745 G4ThreeVector v( inputV );
746 v.rotateZ(p.phi() - phi0);
747 const G4double dd = s_IterationPrecision;
748 LWSDBG(1, std::cout << "Start DTO test, expect "
749 << long(distance / dd) << " iterations"
750 << std::endl);
751
752 G4int V = Verbose;
753 Verbose = 0;
754
755 const G4double d1 = distance - s_IterationPrecision;
756 static bool first = true;
757 for(G4double t = s_IterationPrecision; t < d1; t += dd){
758 G4ThreeVector p1 = p + v * t;
759 if(fabs(GetCalculator()->DistanceToTheNeutralFibre(p1, p_fan)) > m_FHTplusT){
760 std::cout << "DTO test at " << MSG_VECTOR(inputP) << " -> "
761 << MSG_VECTOR(inputV) << ", translated to "
762 << MSG_VECTOR(p) << " - > " << MSG_VECTOR(v)
763 << " in range of "
764 << distance << ": found nearer intersection at local point"
765 << MSG_VECTOR(p1) << ", distance " << t
766 << ", call " << counter
767 << std::endl;
768 Verbose = V;
769
770 if(first){
771 first = false;
772 FILE *F = fopen("dto_error.dat", "w");
773 if(F){
774 fprintf(F, "%10e %10e %10e\n", p.x(), p.y(), p.z());
775 fprintf(F, "%10e %10e %10e\n", v.x(), v.y(), v.z());
776 for(G4double e = s_IterationPrecision; e < d1; e += dd){
777 p1 = p + v * e;
778 G4double f = fabs(GetCalculator()->DistanceToTheNeutralFibre(p1, p_fan)) - m_FanHalfThickness;
779 fprintf(F, "%10e %10e\n", e, f);
780 }
781 fclose(F);
782 }
783 }
784
785 return true;
786 }
787 }
788 Verbose = V;
789 LWSDBG(1, std::cout << "DTO test at " << MSG_VECTOR(p) << " -> "
790 << MSG_VECTOR(v) << " in range of "
791 << distance << ": allright" << std::endl);
792 return false;
793}
794#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)