Program Listing for File SCBoundary.cxx¶
↰ Return to documentation for file (larflow/SCBoundary/SCBoundary.cxx
)
#include "SCBoundary.h"
#include <cmath>
namespace larflow {
namespace scb {
template float SCBoundary::dist2boundary<float>( const std::vector<float>& pos, Boundary_t& boundary_type ) const;
template double SCBoundary::dist2boundary<double>( const std::vector<double>& pos, Boundary_t& boundary_type ) const;
template float SCBoundary::pointLineDistance( const std::vector<float>& linept1,
const std::vector<float>& linept2,
const std::vector<float>& testpt ) const;
template double SCBoundary::pointLineDistance( const std::vector<double>& linept1,
const std::vector<double>& linept2,
const std::vector<double>& testpt ) const;
template float SCBoundary::XatBoundary<float>( const std::vector<float>& pos ) const;
template double SCBoundary::XatBoundary<double>( const std::vector<double>& pos ) const;
double SCBoundary::YX_TOP_x1_array[10] = {150.00, 132.56, 122.86, 119.46, 114.22, 110.90, 115.85, 113.48, 126.36, 144.21};
double SCBoundary::YX_TOP_y2_array[10] = {110.00, 108.14, 106.77, 105.30, 103.40, 102.18, 101.76, 102.27, 102.75, 105.10};
double SCBoundary::YX_BOT_x1_array[10] = {115.71, 98.05, 92.42, 91.14, 92.25, 85.38, 78.19, 74.46, 78.86, 108.90};
double SCBoundary::YX_BOT_y2_array[10] = {-101.72, -99.46, -99.51, -100.43, -99.55, -98.56, -98.00, -98.30, -99.32, -104.20};
double SCBoundary::ZX_Dw_x1_array[10] = {120.00, 115.24, 108.50, 110.67, 120.90, 126.43, 140.51, 157.15, 120.00, 120.00};
double SCBoundary::ZX_Dw_z2_array[10] = {1029.00, 1029.12, 1027.21, 1026.01, 1024.91, 1025.27, 1025.32, 1027.61, 1026.00, 1026.00};
template <class T> T SCBoundary::dist2boundary( const std::vector<T>& pos,
Boundary_t& boundary_type ) const
{
// first calculate the dist to the TPC boundaries
T dx1 = pos[0];
T dx2 = 256-pos[0];
T dy1 = 116.0-pos[1];
T dy2 = pos[1]+115.0;
T dz1 = pos[2];
T dz2 = 1037.0-pos[2];
T dwall = 1.0e9;
boundary_type = kNumBoundaries;
if ( fabs(dy1)<fabs(dwall) ) {
dwall = dy1;
boundary_type = kTop; // top
}
if ( fabs(dy2)<fabs(dwall) ) {
dwall = dy2;
boundary_type = kBottom; // bottom
}
if ( fabs(dz1)<fabs(dwall) ) {
dwall = dz1;
boundary_type = kUpstream; // upstream
}
if ( fabs(dz2)<fabs(dwall) ) {
dwall = dz2;
boundary_type = kDownstream; // downstream
}
if ( fabs(dx1)<fabs(dwall) ) {
dwall = dx1;
boundary_type = kAnode; // anode
}
if ( fabs(dx2)<fabs(dwall) ) {
dwall = dx2;
boundary_type = kCathode; // cathode
}
// if outside the box, we just return the distance from the TPC wall
// if ( dwall<0 )
// return dwall;
int zbox = pos[2]/100.0;
if ( zbox>9 ) zbox = 9;
// top SCE boundary in the XY-view
float topxy = 1e3;
if ( pos[0]>YX_TOP_x1_array[zbox] && pos[1]>0.0 ) {
std::vector<double> xyproj = { (double)pos[0], (double)pos[1], 0.0 };
std::vector<double> xy_topline1 = { YX_TOP_x1_array[zbox], YX_TOP_y1_array, 0.0 };
std::vector<double> xy_topline2 = { YX_TOP_x2_array, YX_TOP_y2_array[zbox], 0.0 };
//double topxy = pointLineDistance<double>( xy_topline1, xy_topline2, xyproj ); //< perpendicular distance to line
//float dtop = (pos[0]-YX_TOP_x1_array[zbox])*(YX_TOP_y2_array[zbox]-YX_TOP_y1_array)
//- (pos[1]-YX_TOP_y1_array)*(YX_TOP_x2_array-YX_TOP_x1_array[zbox]);
float topline_y = (xy_topline2[1]-xy_topline1[1])/(xy_topline2[0]-xy_topline1[0])*(xyproj[0]-xy_topline1[0]) + xy_topline1[1]; //< y-pos, given x of test point
topxy = topline_y-pos[1];
}
// bot SCE boundary in the XY-view
float botxy = 1e3;
if ( pos[0]>YX_BOT_x1_array[zbox] && pos[1]<0.0 ) {
std::vector<double> xy_botline1 = { YX_BOT_x1_array[zbox], YX_BOT_y1_array, 0.0 };
std::vector<double> xy_botline2 = { YX_BOT_x2_array, YX_BOT_y2_array[zbox], 0.0 };
// double botxy = pointLineDistance<double>( xy_botline1, xy_botline2, xyproj );
// float dbot = (pos[0]-YX_BOT_x1_array[zbox])*(YX_BOT_y2_array[zbox]-YX_BOT_y1_array)
// - (pos[1]-YX_BOT_y1_array)*(YX_BOT_x2_array-YX_BOT_x1_array[zbox]);
// if ( dbot>0 ) botxy *= -1.0; // outside boundary
float botline_y = (xy_botline2[1]-xy_botline1[1])/(xy_botline2[0]-xy_botline1[0])*(pos[0]-xy_botline1[0]) + xy_botline1[1]; //< y-pos, given x of test point
botxy = pos[1] - botline_y;
}
// xz-view boundary dist
int ybox = (int)(pos[1]-(-116.0))/24.0;
if ( ybox>9 ) ybox = 9;
float dwnxz = 1e3;
if ( pos[2]>1024 && pos[0]>ZX_Dw_x1_array[ybox] && pos[0]<ZX_Dw_x2_array) {
std::vector<double> xz_proj = { (double)pos[0], 0.0, (double)pos[2] };
std::vector<double> xz_line1 = { ZX_Dw_x1_array[ybox], 0.0, ZX_Dw_z1_array };
std::vector<double> xz_line2 = { ZX_Dw_x2_array, 0.0, ZX_Dw_z2_array[ybox] };
// double topxz = pointLineDistance<double>( xz_line1, xz_line2, xz_proj );
// double dtopxz = (pos[0]-ZX_Dw_x1_array[ybox])*(ZX_Dw_z2_array[ybox]-ZX_Dw_z1_array)
// - (pos[2]-ZX_Dw_z1_array)*(ZX_Dw_x2_array-ZX_Dw_x1_array[ybox]);
// if ( dtopxz<0.0 ) topxz *= -1.0;
float dwnline_z = (xz_line2[2]-xz_line1[2])/(xz_line2[0]-xz_line1[0])*(pos[0]-xz_line1[0]) + xz_line1[2]; //< y-pos, given x of test point
float dwnxz = dwnline_z-pos[2];
// location of x, makes sce boundary irrelevant
if ( pos[0]<ZX_Dw_x1_array[ybox] || pos[0]>ZX_Dw_x2_array )
dwnxz = 1.0e3;
}
float upxz = 1e3;
if ( pos[2]<11.0 && pos[0]>ZX_Up_x1_array && pos[0]<ZX_Up_x2_array ) {
std::vector<double> xz_proj = { (double)pos[0], 0.0, (double)pos[2] };
std::vector<double> xz_line1 = { ZX_Up_x1_array, 0.0, ZX_Up_z1_array };
std::vector<double> xz_line2 = { ZX_Up_x2_array, 0.0, ZX_Up_z2_array };
// double topxz = pointLineDistance<double>( xz_line1, xz_line2, xz_proj );
// double dtopxz = ( pos[0]-ZX_Up_x1_array )*( ZX_Up_z2_array-ZX_Up_z1_array )
// - ( pos[2]-ZX_Up_z1_array )*( ZX_Up_x2_array-ZX_Up_x1_array );
// if ( dtopxz>0.0 ) topxz *= -1.0;
float upline_z = (xz_line2[2]-xz_line1[2])/(xz_line2[0]-xz_line1[0])*(xz_proj[0]-xz_line1[0]) + xz_line1[2]; //< y-pos, given x of test point
upxz = pos[2]-upline_z;
}
// put it all together
T dists[5] = { (T)dwall, (T)topxy, (T)botxy, (T)upxz, (T)dwnxz };
T mindist = 1.0e9;
int minidx = 0;
for (int i=0; i<5; i++) {
if ( dists[i]<mindist ) {
mindist = dists[i];
minidx = i;
}
}
switch ( minidx ) {
case 1:
boundary_type = kTop;
break;
case 2:
boundary_type = kBottom;
break;
case 3:
boundary_type = kUpstream;
break;
case 4:
boundary_type = kDownstream;
break;
default:
break;
}
return dists[minidx];
}
template <class T> T SCBoundary::pointLineDistance( const std::vector<T>& linept1,
const std::vector<T>& linept2,
const std::vector<T>& pt ) const
{
std::vector<T> d1(3);
std::vector<T> d2(3);
T len1 = 0.;
T linelen = 0.;
for (int i=0; i<3; i++ ) {
d1[i] = pt[i] - linept1[i];
d2[i] = pt[i] - linept2[i];
len1 += d1[i]*d1[i];
linelen += (linept1[i]-linept2[i])*(linept1[i]-linept2[i]);
}
len1 = sqrt(len1);
linelen = sqrt(linelen);
if ( linelen<1.0e-4 ) {
// short cluster, use distance to end point
return len1;
}
// cross-product
std::vector<T> d1xd2(3);
d1xd2[0] = d1[1]*d2[2] - d1[2]*d2[1];
d1xd2[1] = -d1[0]*d2[2] + d1[2]*d2[0];
d1xd2[2] = d1[0]*d2[1] - d1[1]*d2[0];
T len1x2 = 0.;
for ( int i=0; i<3; i++ ) {
len1x2 += d1xd2[i]*d1xd2[i];
}
len1x2 = sqrt(len1x2);
T r = len1x2/linelen;
return r;
}
float SCBoundary::dist2boundary( float x, float y, float z ) const {
std::vector<float> pos = { x, y, z };
Boundary_t btype;
return dist2boundary<float>(pos, btype);
}
double SCBoundary::dist2boundary( double x, double y, double z ) const {
std::vector<double> pos = { x, y, z };
Boundary_t btype;
return dist2boundary<double>(pos, btype);
}
float SCBoundary::dist2boundary( float x, float y, float z, int& ibtype ) const {
std::vector<float> pos = { x, y, z };
Boundary_t btype;
float dist = dist2boundary<float>(pos, btype);
ibtype = (int)btype;
return dist;
}
double SCBoundary::dist2boundary( double x, double y, double z, int& ibtype ) const {
std::vector<double> pos = { x, y, z };
Boundary_t btype;
float dist = dist2boundary<double>(pos, btype);
ibtype = (int)btype;
return dist;
}
template<class T>
T SCBoundary::XatBoundary( const std::vector<T>& pos ) const
{
T z = pos[2];
if ( z<0 ) z = 0.0;
else if ( z>1036.0 ) z = 1036.;
T y = pos[1];
if ( y<-116 ) y = -116.0;
else if ( y>116.0 ) y = 116.0;
int zbox = z/100.0;
if ( zbox>9 ) zbox = 9;
T x_y = (T)YX_TOP_x2_array;
if ( y > YX_TOP_y2_array[zbox] ) {
x_y = (T)( (y-YX_TOP_y1_array)*(YX_TOP_x2_array-YX_TOP_x1_array[zbox])/(YX_TOP_y2_array[zbox]-YX_TOP_y1_array) + YX_TOP_x1_array[zbox] );
}
else if ( y < YX_BOT_y2_array[zbox] ) {
x_y = (T)( (y-YX_BOT_y1_array)*(YX_BOT_x2_array-YX_BOT_x1_array[zbox])/(YX_BOT_y2_array[zbox]-YX_BOT_y1_array) + YX_BOT_x1_array[zbox] );
}
int ybox = (int)(pos[1]-(-116.0))/24.0;
if ( ybox>9 ) ybox = 9;
T x_z = (T)ZX_Dw_x2_array;
if ( z>1024.0 ) {
x_z = (T)( (z-ZX_Dw_z1_array)*( ZX_Dw_x2_array-ZX_Dw_x1_array[ybox] )/(ZX_Dw_z2_array[ybox]-ZX_Dw_z1_array) + ZX_Dw_x1_array[ybox] );
}
else if ( z<11.0 ) {
x_z = (T)( (z-ZX_Up_z1_array)*( ZX_Up_x2_array-ZX_Up_x1_array )/(ZX_Up_z2_array-ZX_Up_z1_array) + ZX_Up_x1_array );
}
if ( x_z>(T)ZX_Dw_x2_array ) x_z = (T)ZX_Dw_x2_array;
if ( x_y<x_z )
return x_y;
else
return x_z;
// should not reach here
return pos[0];
}
float SCBoundary::XatBoundary( float x, float y, float z ) const
{
std::vector<float> pos = {x,y,z};
return XatBoundary<float>(pos);
}
double SCBoundary::XatBoundary( double x, double y, double z ) const
{
std::vector<double> pos = {x,y,z};
return XatBoundary<double>(pos);
}
}
}