/* 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 .
*/
/* Author: Peter Lane
*/
#include "Optics/LinearApproximationOpticsModel.hh"
#include
#include
#include
#include "CLHEP/Units/PhysicalConstants.h"
#include "src/common_cpp/Optics/CovarianceMatrix.hh"
#include "src/common_cpp/Optics/PhaseSpaceVector.hh"
#include "src/common_cpp/Recon/Global/Particle.hh"
#include "Maths/Vector.hh"
#include "Utils/Exception.hh"
namespace MAUS {
const TransferMap * LinearApproximationOpticsModel::CalculateTransferMap(
const std::vector & start_plane_hits,
const std::vector & station_hits)
const {
const MAUS::DataStructure::Global::PID particle_id
= MAUS::DataStructure::Global::PID(reference_primary_.GetParticleId());
const double mass
= recon::global::Particle::GetInstance().GetMass(particle_id);
double start_plane = reference_primary_.GetPosition().z();
double hit_total = 0.0;
std::vector::const_iterator hit;
for (hit = station_hits.begin(); hit != station_hits.end(); ++hit) {
const double energy = hit->energy();
const double momentum = ::sqrt(energy*energy - mass*mass);
const double beta = momentum / energy;
const double delta_t = hit->time() - time_offset_
- reference_primary_.GetTime();
const double delta_z = beta * ::CLHEP::c_light * delta_t;
hit_total += (reference_primary_.GetPosition().z() + delta_z);
}
double end_plane = hit_total / station_hits.size();
return new LinearApproximationTransferMap(start_plane, end_plane, mass);
}
TransferMap * LinearApproximationTransferMap::Inverse() const {
return new LinearApproximationTransferMap(end_plane_, start_plane_, mass_);
}
CovarianceMatrix LinearApproximationTransferMap::Transport(
const CovarianceMatrix & covariances) const {
// This method of transport is too stupid to handle covariance matrices,
// so just return what was given.
return covariances;
}
PhaseSpaceVector LinearApproximationTransferMap::Transport(
const PhaseSpaceVector & vector) const {
// Use the energy and momentum to determine when and where the particle would
// be if it were traveling in free space from start_plane_ to end_plane_.
PhaseSpaceVector transported_vector(vector);
double delta_z = end_plane_ - start_plane_;
const double px = vector.Px();
const double py = vector.Py();
double energy = vector.E();
if (mass_ > energy) {
throw(Exceptions::Exception(Exceptions::nonRecoverable,
"Attempting to transport a particle that is off mass shell.",
"MAUS::LinearApproximationOpticsModel::Transport()"));
}
const double momentum = ::sqrt(energy*energy - mass_*mass_);
const double beta = momentum / energy;
// delta_t = delta_z / v_z ~= delta_z / velocity
double delta_t = delta_z / beta / ::CLHEP::c_light;
const double gamma = energy / mass_;
// delta_x = v_x * delta_t, px = gamma * m * v_x
double delta_x = px * delta_t / gamma / mass_;
// delta_y = v_y * delta_t, py = gamma * m v_y
double delta_y = py * delta_t / gamma / mass_;
transported_vector[0] += delta_t;
transported_vector[2] += delta_x;
transported_vector[4] += delta_y;
return transported_vector;
}
} // namespace MAUS