/* This file is part of MAUS: http://micewww.pp.rl.ac.uk:8080/projects/maus
*
* MAUS is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* MAUS is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MAUS. If not, see .
*
*/
#include
#include "src/common_cpp/Recon/SciFi/SciFiTools.hh"
#include "src/common_cpp/DataStructure/ThreeVector.hh"
namespace SciFiTools {
void calc_straight_residual(const MAUS::SciFiSpacePoint *sp,
const MAUS::SimpleLine &line_x,
const MAUS::SimpleLine &line_y, double &dx, double &dy) {
MAUS::ThreeVector pos = sp->get_position();
dx = pos.x() - ( line_x.get_c() + ( pos.z() * line_x.get_m() ) );
dy = pos.y() - ( line_y.get_c() + ( pos.z() * line_y.get_m() ) );
} // ~calc_straight_residual(...)
double calc_circle_residual(const MAUS::SciFiSpacePoint *sp,
const MAUS::SimpleCircle &c) {
MAUS::ThreeVector pos = sp->get_position();
double delta = sqrt(((pos.x()-c.get_x0()) * (pos.x()-c.get_x0())) +
((pos.y()-c.get_y0()) * (pos.y()-c.get_y0()))) - c.get_R();
return delta;
} // ~calc_circle_residual(...)
double calc_phi(double xpos, double ypos, const MAUS::SimpleCircle &circle) {
// Note this function returns phi_i + phi_0, unless using x0, y0 in which case it returns phi_0
double angle = atan2(ypos - circle.get_y0(), xpos - circle.get_x0());
if ( angle < 0. ) angle += 2. * CLHEP::pi; // TODO is this ok if have different sign particles?
// std::cerr << "calc_phi: x is " << xpos << ", y is " << ypos << ", R is " << circle.get_R();
// std::cerr << ", X0 is " << circle.get_x0() << ", Y0 is " << circle.get_y0();
// std::cerr << ", phi is " << angle << "\n";
return angle;
} // ~calculate_phi(...)
void draw_line(const MAUS::SciFiSpacePoint *sp1, const MAUS::SciFiSpacePoint *sp2,
MAUS::SimpleLine &line_x, MAUS::SimpleLine &line_y) {
MAUS::ThreeVector pos_outer = sp1->get_position();
MAUS::ThreeVector pos_inner = sp2->get_position();
line_x.set_m(( pos_inner.x() - pos_outer.x()) / (pos_inner.z() - pos_outer.z() ));
line_x.set_c(pos_outer.x() - ( pos_outer.z() * line_x.get_m()) );
line_y.set_m(( pos_inner.y() - pos_outer.y()) / (pos_inner.z() - pos_outer.z() ));
line_y.set_c(pos_outer.y() - ( pos_outer.z() * line_y.get_m() ));
} // ~draw_line(...)
double det3by3(const TMatrixD &m) {
if ( m.GetNrows() == 3 && m.GetNcols() == 3 ) {
double det = m(0, 0)*(m(1, 1)*m(2, 2)-m(1, 2)*m(2, 1)) +
m(0, 1)*(m(1, 2)*m(2, 0)-m(1, 0)*m(2, 2)) +
m(0, 2)*(m(1, 0)*m(2, 1)-m(1, 1)*m(2, 0));
return det;
} else {
std::cerr << "Error: SciFiTools::det3by3 says: Bad matrix given" << std::endl;
return 0;
}
} // ~det3by3(...)
MAUS::SimpleCircle make_3pt_circle(const MAUS::SciFiSpacePoint *sp1,
const MAUS::SciFiSpacePoint *sp2,
const MAUS::SciFiSpacePoint *sp3) {
MAUS::SimpleCircle c;
MAUS::ThreeVector pos1 = sp1->get_position();
MAUS::ThreeVector pos2 = sp2->get_position();
MAUS::ThreeVector pos3 = sp3->get_position();
// Calculate alpha
Double_t arr_a[] = {pos1.x(), pos1.y(), 1.0,
pos2.x(), pos2.y(), 1.0,
pos3.x(), pos3.y(), 1.0};
TMatrixD mat_a(3, 3, arr_a);
double alpha = det3by3(mat_a);
c.set_alpha(alpha);
// Calculate beta
Double_t arr_b[] = {(pos1.x()*pos1.x())+(pos1.y()*pos1.y()), pos1.y(), 1.0,
(pos2.x()*pos2.x())+(pos2.y()*pos2.y()), pos2.y(), 1.0,
(pos3.x()*pos3.x())+(pos3.y()*pos3.y()), pos3.y(), 1.0};
TMatrixD mat_b(3, 3, arr_b);
double beta = - det3by3(mat_b);
c.set_beta(beta);
// Calculate gamma
Double_t arr_g[] = {(pos1.x()*pos1.x())+(pos1.y()*pos1.y()), pos1.x(), 1.0,
(pos2.x()*pos2.x())+(pos2.y()*pos2.y()), pos2.x(), 1.0,
(pos3.x()*pos3.x())+(pos3.y()*pos3.y()), pos3.x(), 1.0};
TMatrixD mat_g(3, 3, arr_g);
double gamma = det3by3(mat_g);
c.set_gamma(gamma);
// Calculate kappa
Double_t arr_k[] = {(pos1.x()*pos1.x())+(pos1.y()*pos1.y()), pos1.x(), pos1.y(),
(pos2.x()*pos2.x())+(pos2.y()*pos2.y()), pos2.x(), pos2.y(),
(pos3.x()*pos3.x())+(pos3.y()*pos3.y()), pos3.x(), pos3.y()};
TMatrixD mat_k(3, 3, arr_k);
double kappa = - det3by3(mat_k);
c.set_kappa(kappa);
// Calculate the dependent parameters
double x0 = - beta / (2 * alpha);
c.set_x0(x0);
double y0 = - gamma / (2 * alpha);
c.set_y0(y0);
double R = sqrt(((beta*beta+gamma*gamma)/(4*alpha*alpha))-(kappa/alpha));
c.set_R(R);
return c;
} // ~make_3pt_circle
double my_mod(const double num, const double denom) {
return num - (denom * floor(num / denom));
} // ~my_mod(...)
std::vector phi_to_s(const double R, const std::vector &phi) {
std::vector s_i;
for ( int i = 0; i < static_cast(phi.size()); ++i ) {
s_i.push_back(phi[i] * R);
}
return s_i;
} // ~phi_to_s(...)
int num_stations_with_unused_spnts(const MAUS::SpacePoint2dPArray &spnts_by_station) {
int stations_hit = 0;
for ( int i = 0; i < static_cast(spnts_by_station.size()); ++i ) {
int unused_sp = 0;
for ( int j = 0; j < static_cast(spnts_by_station[i].size()); ++j ) {
if ( !spnts_by_station[i][j]->get_used() ) {
++unused_sp;
}
}
if ( unused_sp > 0 ) {
++stations_hit;
}
}
return stations_hit;
} // ~num_stations_with_unused_spnts(...)
void print_spacepoint_xyz(const std::vector &spnts) {
for ( size_t i = 0; i < spnts.size(); ++i ) {
MAUS::ThreeVector pos = spnts[i]->get_position();
std::cout << "( " << pos.x() << ", " << pos.y() << ", " << pos.z() << ") ";
}
std::cout << std::endl;
} // print_spacepoint_xyz(...)
void sort_by_station(const std::vector &spnts,
MAUS::SpacePoint2dPArray &spnts_by_station) {
for ( int st_num = 0; st_num < static_cast(spnts_by_station.size()); ++st_num ) {
for ( int i = 0; i < static_cast(spnts.size()); ++i ) {
if ( spnts[i]->get_station() == st_num + 1 ) {
spnts_by_station[st_num].push_back(spnts[i]);
}
}
}
} // ~sort_by_station(...)
MAUS::SpacePoint2dPArray sort_by_tracker(const MAUS::SciFiSpacePointPArray &spnts) {
const int n_trackers = 2;
MAUS::SpacePoint2dPArray spnts_by_tracker(n_trackers);
for ( int trker_no = 0; trker_no < n_trackers; ++trker_no ) {
for ( size_t i = 0; i < spnts.size(); ++i ) {
if ( spnts[i]->get_tracker() == trker_no ) {
spnts_by_tracker[trker_no].push_back(spnts[i]);
}
}
}
return spnts_by_tracker;
} // ~sort_by_tracker(...)
void stations_with_unused_spnts(const MAUS::SpacePoint2dPArray &spnts_by_station,
std::vector &stations_hit,
std::vector &stations_not_hit) {
stations_hit.clear();
stations_not_hit.clear();
for ( int i = 0; i < static_cast(spnts_by_station.size()); ++i ) {
int unused_sp = 0;
for ( int j = 0; j < static_cast(spnts_by_station[i].size()); ++j ) {
if ( !spnts_by_station[i][j]->get_used() ) {
++unused_sp;
}
}
if ( unused_sp > 0 ) {
stations_hit.push_back(i);
} else if ( unused_sp == 0 ) {
stations_not_hit.push_back(i);
}
}
} // ~stations_with_unused_spnts(...)
} // ~namespace SciFiTools