source: JEM-EUSO/esaf_cc_at_lal/packages/simulation/detector/G4Detector/G4fresnellens/src/ParabolicSurface.cc @ 114

Last change on this file since 114 was 114, checked in by moretto, 11 years ago

actual version of ESAF at CCin2p3

File size: 4.1 KB
Line 
1#include "ParabolicSurface.h"
2#include "LensUtils.h"
3
4using std::swap;
5using namespace G4FresnelLens;
6
7//______________________________________________________________________________
8ParabolicSurface::ParabolicSurface(double k, double z, double rhomax):
9ParametricSurface(z,rhomax),
10fK(k)
11{
12    //kHalfTolerance=kTolerance;
13    //kTolerance=2.*kHalfTolerance;
14    Configure();
15}
16
17//______________________________________________________________________________
18ParabolicSurface::~ParabolicSurface(){
19
20
21}
22
23//______________________________________________________________________________
24void ParabolicSurface::Configure(){
25    fZ1=fZmin=PointOnSurf(0.);
26    fZ2=fZmax=PointOnSurf(fR);
27    if ( fZmin>fZmax ) swap(fZmin,fZmax);
28}
29
30//__________________________________________________________________________________
31void ParabolicSurface::print(){
32    printf("paraboloid z=%g perp=%g k=%g min/max=%g/%g\n", fZpos, fR, fK, fZmin, fZmax);
33}
34
35//__________________________________________________________________________________
36void ParabolicSurface::GuessParameters(int n, int tn, int* idx, double* rho, double* z, bool minimum){
37    if ( fK!=DBL_MAX ) return;
38    int i1a=idx[1];
39    int i1b=i1a+1;
40    int i1=(z[i1a]>z[i1b])^minimum?i1a:i1b;
41
42    int i2a=idx[tn-1];
43    int i2b=i2a+1;
44    int i2=(z[i2a]>z[i2b])^minimum?i2a:i2b;
45
46    double dz=z[i2]-z[i1];
47    double dr2=rho[i2]*rho[i2]-rho[i1]*rho[i1];
48    fK=dr2?dz/dr2:0.;
49}
50
51//__________________________________________________________________________________
52void ParabolicSurface::GuessParameters(const std::vector<SSurface*>& surfaces, bool minimum){
53    if ( fK!=DBL_MAX ) return;
54
55    SSurface* s1=*(surfaces.begin());
56    SSurface* s2=*(surfaces.end()-1);
57    double r1,r2,z1,z2;
58    double za=s1->GetZ1();
59    double zb=s1->GetZ2();
60    if ( (za>zb)^minimum ){
61        z1=s1->GetZ1();
62        r1=s1->GetR1();
63    }
64    else {
65        z1=s1->GetZ2();
66        r1=s1->GetR2();
67    }
68
69    za=s2->GetZ1();
70    zb=s2->GetZ2();
71    if ( (za>zb)^minimum ){
72        z2=s2->GetZ1();
73        r2=s2->GetR1();
74    }
75    else {
76        z2=s2->GetZ2();
77        r2=s2->GetR2();
78    }
79
80    double dz=z2-z1;
81    double dr2=r2*r2-r1*r1;
82    fK=dr2?dz/dr2:0.;
83}
84
85//__________________________________________________________________________________
86double ParabolicSurface::DistanceToSurf(const G4ThreeVector& p, const G4ThreeVector& v){
87    double perp2=p.perp2();
88    double vperp2=v.perp2();
89    double a = fK*vperp2;
90    double b = 2.*fK*(p.x()*v.x()+p.y()*v.y())-v.z();
91    double c = fK*perp2-p.z()+fZpos;
92    double d1, d2;
93    int nroot=SolveQuadratic(a, b, c, d1, d2);
94
95    if ( !nroot ) return kInfinity;
96    #ifdef DEBUG
97        printf("pos(%.10g, %.10g, %.10g), dir(%.10g, %.10g, %.10g)\n", p.x(), p.y(), p.z(), v.x(), v.y(), v.z());
98        printf("abc: %.10g, %.10g, %.10g\n", a,b,c);
99        double d=sqrt(b*b-4*a*c);
100        double x1=(-b+d)/2./a;
101        printf("s(d)=%.10g, d1:d2: %.10g, %.10g\n",d, (-b-d)/2./a, x1);
102        printf("s(d)=%.10g, d1:d2: %.10g, %.10g\n",d, x1, -b/a-x1);
103        printf("%i roots: %.10g, %.10g\n", nroot, d1, d2);
104    #endif
105    G4ThreeVector pos;
106    if ( d1>=0. ) {
107        pos = p+v*d1;
108        double zpos=pos.z();
109        double perpa2=pos.perp2();
110        if ( perpa2<=fR*fR && zpos>=fZmin && zpos<=fZmax ) {
111            return d1;
112        }
113    }
114    if ( nroot==1 || d2<0. ) return kInfinity;
115
116    pos = p+v*d2;
117    double zpos=pos.z();
118    double perpa2=pos.perp2();
119    if ( perpa2<=fR*fR && zpos>=fZmin && zpos<=fZmax ) {
120        return d2;
121    }
122    return kInfinity;
123}
124
125//__________________________________________________________________________________
126double ParabolicSurface::DistanceToSurfSafe(const G4ThreeVector& p){
127    //
128    // return undirectional distance to surface
129    // can be underestimated
130    // thus returning distance to the bounding tube
131    //
132    double perp2=p.perp2();
133    double z=p.z();
134
135    if ( perp2<=fR*fR ) {
136        if ( z>fZmax ) return z-fZmax;
137        if ( z<fZmin ) return fZmin-z;
138        return 0.;
139    }
140    double perp=sqrt(perp2);
141    if ( z>fZmax ) return Hyp(perp, z, fR, fZmax);
142    if ( z<fZmin ) return Hyp(perp, z, fR, fZmin);
143    return perp-fR;
144}
Note: See TracBrowser for help on using the repository browser.