aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/likelihood.c2
-rw-r--r--src/solid_angle.c19
-rw-r--r--src/solid_angle.h1
-rw-r--r--src/test.c26
4 files changed, 47 insertions, 1 deletions
diff --git a/src/likelihood.c b/src/likelihood.c
index 2340fb1..ed07826 100644
--- a/src/likelihood.c
+++ b/src/likelihood.c
@@ -424,7 +424,7 @@ static double get_total_charge_approx(double T0, double *pos, double *dir, parti
sin_theta = sqrt(1-pow(cos_theta,2));
/* Get the solid angle of the PMT at the position `s` along the track. */
- omega = get_solid_angle_approx(tmp,pmts[i].pos,pmts[i].normal,PMT_RADIUS);
+ omega = get_solid_angle_fast(tmp,pmts[i].pos,pmts[i].normal,PMT_RADIUS);
theta0 = fmax(theta0*sqrt(s),MIN_THETA0);
diff --git a/src/solid_angle.c b/src/solid_angle.c
index a929938..dbac045 100644
--- a/src/solid_angle.c
+++ b/src/solid_angle.c
@@ -3,6 +3,7 @@
#include <math.h>
#include <gsl/gsl_interp2d.h>
#include <gsl/gsl_spline2d.h>
+#include "vector.h"
static double hd[11] = {0.1,0.125,0.150,0.175,0.2,0.3,0.4,0.5,0.6,0.8,1.0};
static double Rd[13] = {0.1,0.5,0.6,0.7,0.8,0.9,1.0,1.1,1.2,1.3,1.4,1.5,2.0};
@@ -23,6 +24,24 @@ static double lookupTable[13][11] = {
{1.0041,1.0051,1.0061,1.0070,1.0078,1.0106,1.0120,1.0122,1.0116,1.0097,1.0084}
};
+double get_solid_angle_fast(double *pos, double *pmt, double *n, double r)
+{
+ /* Returns a *very* fast approximation of the solid angle subtended by a
+ * circular disk of radius r at a position `pmt` with a normal vector `n` from
+ * a position `pos`. */
+ double dir[3];
+ double R, cos_theta_pmt;
+
+ SUB(dir,pos,pmt);
+
+ /* Distance to the PMT. */
+ R = NORM(dir);
+
+ cos_theta_pmt = fabs(DOT(dir,n)/R);
+
+ return pow(r,2)*cos_theta_pmt/pow(R,2);
+}
+
static double A(double u, double a, double h)
{
return atan(((a*a-h*h)*u - 2*a*a*h*h)/(2*a*h*sqrt((u-h*h)*(u+a*a))));
diff --git a/src/solid_angle.h b/src/solid_angle.h
index aacb692..654f605 100644
--- a/src/solid_angle.h
+++ b/src/solid_angle.h
@@ -3,6 +3,7 @@
#include <math.h>
+double get_solid_angle_fast(double *pos, double *pmt, double *n, double r);
double get_solid_angle_approx(double *pos, double *pmt, double *n, double r);
double get_solid_angle(double *pos, double *pmt, double *n, double r);
diff --git a/src/test.c b/src/test.c
index f8cedb9..16756ad 100644
--- a/src/test.c
+++ b/src/test.c
@@ -970,6 +970,31 @@ err:
return 1;
}
+int test_solid_angle_fast(char *err)
+{
+ /* Tests the get_solid_angle_fast() function. */
+ int i;
+ double pmt[3] = {0,0,0};
+ double pos[3] = {0,0,1};
+ double n[3] = {0,0,-1};
+ double r = 1.0;
+ double solid_angle;
+
+ for (i = 0; i < sizeof(solid_angle_results)/sizeof(struct solid_angle_results); i++) {
+ pos[0] = solid_angle_results[i].r0*r;
+ pos[2] = solid_angle_results[i].L*r;
+
+ solid_angle = get_solid_angle_approx(pos,pmt,n,r);
+
+ if (!isclose(solid_angle, solid_angle_results[i].omega, 1e-2, 0)) {
+ sprintf(err, "solid angle = %.5f, but expected %.5f", solid_angle, solid_angle_results[i].omega);
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
struct tests {
testFunction *test;
char *name;
@@ -999,6 +1024,7 @@ struct tests {
{test_log_norm, "test_log_norm"},
{test_trapz, "test_trapz"},
{test_interp2d, "test_interp2d"},
+ {test_solid_angle_fast, "test_solid_angle_fast"},
};
int main(int argc, char **argv)