// Copyright 2008-2011 Chris Rogers
//
// This file is a part of 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 in the doc folder. If not, see
// .
#include "CLHEP/Random/RandFlat.h"
#include "TCanvas.h"
#include "TH2D.h"
#include "TStyle.h"
#include "gtest/gtest.h"
#include "Utils/Squeak.hh"
#include "BeamTools/BTSolenoid.hh"
#include "BeamTools/BTFieldConstructor.hh"
#include "BeamTools/BTTracker.hh"
#include "BeamTools/BTFieldGroup.hh"
#include "Utils/Exception.hh"
namespace {
const double mu_mass = 105.658367;
BTSolenoid * _sol = NULL;
std::string _var[] = {"t", "x", "y", "z", "energy", "px", "py", "pz"};
class BTTrackerTest : public ::testing::Test {
protected:
BTTrackerTest();
~BTTrackerTest() {
// delete _sol;
delete _rot_pb;
}
std::vector MakeVector
(double t, double x, double y, double z, double px, double py, double pz);
std::string Print8Vector(double x[8]);
std::vector< std::vector > _particles;
double _zStep;
double _endZ;
double _endT;
double _tStep;
BTPillBox* _pb;
BTFieldGroup* _rot_pb;
};
BTTrackerTest::BTTrackerTest() {
BTFieldConstructor::SetDefaults();
_zStep = 100.;
_endZ = 1000.;
_endT = 3.34445340;
_tStep = _endT*(_zStep/_endZ);
_particles.push_back(MakeVector(0., 0., 10., -220., 0., 0., 200.) );
_particles.push_back(MakeVector(0., 0., 0., 0., 100., 0., 2000.) );
_particles.push_back(MakeVector(0., 0., 0., 0., 0., 0., -200.) );
_particles.push_back(MakeVector(0., 0., 0., 0., 0., 0., 0.) );
if(_sol == NULL)
_sol = new BTSolenoid (5000., 21.3, 258., 150.5, false, 1e-5, "testcoil1", "LinearCubic");
_pb = new BTPillBox (1000., 0.01, 600.); //length, peak field [GV], radius (electrostatic)
_rot_pb = new BTFieldGroup();
_rot_pb->AddField(_pb, Hep3Vector(), HepRotationY(90.*CLHEP::degree));
BTTracker::absoluteError(1e-8);
BTTracker::relativeError(1e-8);
}
std::vector BTTrackerTest::MakeVector
(double t, double x, double y, double z, double px, double py, double pz) {
double energy = sqrt(px*px + py*py + pz*pz + mu_mass*mu_mass);
std::vector vec(8);
vec[0] = t;
vec[1] = x;
vec[2] = y;
vec[3] = z;
vec[4] = energy;
vec[5] = px;
vec[6] = py;
vec[7] = pz;
return vec;
}
std::string BTTrackerTest::Print8Vector(double x[8]) {
std::stringstream ioss;
for (size_t i=0; i<8; ++i) {
ioss << _var[i] << ": " << x[i] << " ";
}
return ioss.str();
}
TEST_F(BTTrackerTest, SolenoidTest_z) {
double results_sol_z[] = {
3.7725, -0.0030, 10.0031, 780.0000, 226.1939, -0.0024, 0.0036, 200.0000,
3.3445, 47.0543, -14.5537, 1000.0000, 2005.2839, 82.5650, -56.3923, 2000.0007,
-3.7725, 0.0000, 0.0000, 1000.0000, 226.1939, 0.0000, 0.0000, -200.0000,
0.0000, 0.0000, 0.0000, 0.0000, 105.6584, 0.0000, 0.0000, 0.0000
};
for (size_t p = 0; p < _particles.size(); ++p) {
std::vector x = std::vector(_particles[p]);
try {
for (double z = x[3]; z-_particles[p][3] < _endZ+_endZ/1e3;
z += _zStep) {
BTTracker::integrate(z, &x[0], _sol, BTTracker::z, 0.1, 1.);
}
}
catch(MAUS::Exceptions::Exception exc) {EXPECT_EQ(p, (size_t) 3);} // p of particle 3 is 0 => exception
for(size_t i=0; i<8; ++i) {
ASSERT_NEAR(results_sol_z[p*8+i], x[i], 1e-3) << "particle " << p
<< " var " << _var[i] << "\nParticle coords: " << Print8Vector(&x[0]);
}
}
}
TEST_F(BTTrackerTest, SolenoidTest_u) {
double results_sol_u[] = {
3.7725, -0.0030, 10.0031, 780.0000, 226.1939, -0.0024, 0.0036, 200.0000,
3.3445, 47.0543, -14.5537, 1000.0000, 2005.2839, 82.5650, -56.3923, 2000.0007,
-3.7725, 0.0000, 0.0000, 1000.0000, 226.1939, 0.0000, 0.0000, -200.0000,
0.0000, 0.0000, 0.0000, 0.0000, 105.6584, 0.0000, 0.0000, 0.0000
};
for (size_t p = 0; p < _particles.size(); ++p) {
std::vector x = std::vector(_particles[p]);
try {
for (double u = x[3]; fabs(u)-_endZ-_particles[p][3] < _endZ/1e3;
u += _zStep) {
BTTracker::integrate(u, &x[0], _sol, BTTracker::u, 0.1, 1.);
}
}
catch(MAUS::Exceptions::Exception exc) {EXPECT_EQ(p, (size_t) 3);} // p of particle 3 is 0 => exception
for(size_t i=0; i<8; ++i) {
ASSERT_NEAR(results_sol_u[p*8+i], x[i], 1e-3) << "particle " << p
<< " var " << _var[i] << "\nParticle coords: " << Print8Vector(&x[0]);
}
CLHEP::Hep3Vector origin(x[1],x[2],x[3]);
try {
for (double u = 0; u-_endZ < _endZ/1e3; u += _zStep) {
BTTracker::integrate(u, &x[0], _sol, BTTracker::u, 0.1, 1.,
origin, CLHEP::HepRotationY(180*degree));
}
}
catch(MAUS::Exceptions::Exception exc) {EXPECT_EQ(p, (size_t) 3);} // p of particle 3 is 0 => exception
for(size_t i=0; i<8; ++i) {
ASSERT_NEAR(_particles[p][i], x[i], 1e-3) << "particle " << p
<< " var " << _var[i] << "\nParticle coords: " << Print8Vector(&x[0]);
}
}
}
TEST_F(BTTrackerTest, SolenoidTest_t) {
double results[] = {
3.7725085528427788617, -0.0030, 10.0031, 780.0000, 226.1939, -0.0024, 0.0036, 200.0000,
3.3444534351854149357, 47.0543, -14.5537, 1000.0000, 2005.2839, 82.5650, -56.3923, 2000.0007,
0.0000, 0.0000, 0.0000, 0.0000, 226.1939, 0.0000, 0.0000, -200.0000,
0.0000, 0.0000, 0.0000, 0.0000, 105.6584, 0.0000, 0.0000, 0.0000
};
for (size_t p = 0; p < _particles.size(); ++p) {
std::vector x = std::vector(_particles[p]);
try {
double t_m = results[8*p+0];
double t_step = (t_m-x[0])/100.;
if (t_step < 1e-3) t_step = 0.001;
for (double t = x[0]; t < t_m+t_m/1e4; t += t_step) {
BTTracker::integrate(t, &x[0], _sol, BTTracker::t, 0.01, 1.);
}
for (size_t i=0; i<8; ++i) {
ASSERT_NEAR(results[p*8+i], x[i], 1e-2) << "particle " << p
<< " var " << _var[i] << "\nParticle coords: " << Print8Vector(&x[0]);
}
}
// pz of particle 2,3 <= 0 =>Exception
catch(MAUS::Exceptions::Exception exc) {EXPECT_TRUE(p == 2 || p == 2);}
}
}
//////////////////////////// PILLBOX /////////////////////////////
TEST_F(BTTrackerTest, PillBoxTest_z) {
double results[] = {
3.7739, -27.3603, 10.0000, 780.0000, 226.3839, -9.2733, 0.0000, 200.0000,
3.3441, 47.8946, 0.0000, 1000.0000, 2004.9930, 93.9845, 0.0000, 2000.0000,
-3.7735, 23.7533, 0.0000, 1000.0000, 226.2957, -6.7869, 0.0000, -200.0000,
0.0000, 0.0000, 0.0000, 0.0000, 105.6584, 0.0000, 0.0000, 0.0000
};
for (size_t p = 0; p < _particles.size(); ++p) {
std::vector x = std::vector(_particles[p]);
try {
for (double z = x[3]; z-_particles[p][3] < _endZ+_endZ/1e3;
z += _zStep) {
BTTracker::integrate(z, &x[0], _rot_pb, BTTracker::z, 0.1, 1.);
}
}
catch(MAUS::Exceptions::Exception exc) {EXPECT_EQ(p, size_t(3));} // p of particle 3 is 0 => exception
for(size_t i=0; i<8; ++i) {
ASSERT_NEAR(results[p*8+i], x[i], 1e-3) << "particle " << p
<< " var " << _var[i] << "\nParticle coords: " << Print8Vector(&x[0]);
}
}
}
TEST_F(BTTrackerTest, PillBoxTest_u) {
double results[] = {
3.7739, -27.3603, 10.0000, 780.0000, 226.3839, -9.2733, 0.0000, 200.0000,
3.3441, 47.8946, 0.0000, 1000.0000, 2004.9930, 93.9845, 0.0000, 2000.0000,
-3.7735, -23.7533, 0.0000, 1000.0000, 226.2957, 6.7869, 0.0000, -200.0000,
0.0000, 0.0000, 0.0000, 0.0000, 105.6584, 0.0000, 0.0000, 0.0000
};
for (size_t p = 0; p < _particles.size(); ++p) {
std::vector x = std::vector(_particles[p]);
try {
for (double u = x[3]; fabs(u)-_endZ-_particles[p][3] < _endZ/1e3;
u += _zStep) {
BTTracker::integrate(u, &x[0], _rot_pb, BTTracker::u, 0.1, 1.);
}
}
catch(MAUS::Exceptions::Exception exc) {EXPECT_EQ(p, size_t(3));} // p of particle 3 is 0 => exception
for(size_t i=0; i<8; ++i) {
ASSERT_NEAR(results[p*8+i], x[i], 1e-3) << "(no rot) particle " << p
<< " var " << _var[i] << "\nParticle coords: " << Print8Vector(&x[0]);
}
CLHEP::Hep3Vector origin(x[1],x[2],x[3]);
try {
for (double u = 0; u-_endZ < _endZ/1e3; u += _zStep) {
BTTracker::integrate(u, &x[0], _rot_pb, BTTracker::u, 0.1, 1.,
origin, CLHEP::HepRotationY(180*degree));
}
}
catch(MAUS::Exceptions::Exception exc) {EXPECT_EQ(p, size_t(3));} // p of particle 3 is 0 => exception
for(size_t i=0; i<8; ++i) {
ASSERT_NEAR(_particles[p][i], x[i], 1e-1) << "(rot) particle " << p
<< " var " << _var[i] << "\nParticle coords: " << Print8Vector(&x[0]);
}
}
}
// Particle coords: t: 9.52933e-07 x: -0.0139323 y: 10 z: -220 energy: 226.194 px: 0.00339696 py: 0 pz: 200
TEST_F(BTTrackerTest, PillBoxTest_t) {
double results[] = {
3.773946426431249, -27.3644, 10.0000, 779.9998, 226.3841, -9.2780, 0.0000, 200.0000,
3.3441123976151883, 47.8896, 0.0000, 1000.0002, 2004.9918, 93.9598, 0.0000, 2000,
0.0000, 0.0000, 0.0000, 0.0000, 226.194, 0.0000, 0.0000, -200.0000,
0.0000, 0.0000, 0.0000, 0.0000, 105.6584, 0.0000, 0.0000, 0.0000
};
for (size_t p = 0; p < _particles.size(); ++p) {
std::vector x = std::vector(_particles[p]);
try {
double t_m = results[8*p+0];
double t_step = (t_m-x[0])/100.;
if (t_step < 1e-3) t_step = 0.001;
for (double t = x[0]; t < t_m+t_m/1e4; t += t_step) {
BTTracker::integrate(t, &x[0], _rot_pb, BTTracker::t, 0.001, 1.);
}
for(size_t i=0; i<8; ++i) {
ASSERT_NEAR(results[p*8+i], x[i], 1e-1) << "particle " << p << " t_m " << t_m
<< " var " << _var[i] << "\nParticle coords: " << Print8Vector(&x[0]);
}
}
// pz of particle 2,3 <= 0 =>Exception
catch(MAUS::Exceptions::Exception exc) {EXPECT_TRUE(p == 2 || p == 2);}
}
}
}