/* 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 "TRef.h"
#include "TRefArray.h"
#include "Utils/Exception.hh"
#include "DataStructure/Global/Track.hh"
namespace MAUS {
namespace DataStructure {
namespace Global {
/// Global function to sort MAUS::DataStructure::Global::TrackPoint's based on
/// their Z coordinate.
bool SortByZ(const MAUS::DataStructure::Global::TrackPoint* tp1,
const MAUS::DataStructure::Global::TrackPoint* tp2) {
return (tp1->get_position().Z() < tp2->get_position().Z());
}
// Default constructor
Track::Track()
: _mapper_name(""),
_pid(MAUS::DataStructure::Global::kNoPID),
_charge(0),
_detectorpoints(0),
_pid_logL_values(0),
_emr_range_primary(0.),
_emr_range_secondary(0.),
_emr_plane_density(0.),
_pid_confidence_level(0.),
_goodness_of_fit(0.),
_p_value(0.),
_tracker_clusters(0) {
_track_points = new TRefArray();
_constituent_tracks = new TRefArray();
}
// Copy contructor
Track::Track(const Track &track)
: _mapper_name(track.get_mapper_name()),
_pid(track.get_pid()),
_charge(track.get_charge()),
_track_points(track.get_track_points()),
_detectorpoints(track.get_detectorpoints()),
_geometry_paths(track.get_geometry_paths()),
_pid_logL_values(track.get_pid_logL_values()),
_constituent_tracks(track.get_constituent_tracks()),
_emr_range_primary(track.get_emr_range_primary()),
_emr_range_secondary(track.get_emr_range_secondary()),
_emr_plane_density(track.get_emr_plane_density()),
_pid_confidence_level(track.get_pid_confidence_level()),
_goodness_of_fit(track.get_goodness_of_fit()),
_p_value(track.get_p_value()),
_tracker_clusters(track.get_tracker_clusters()) {
_track_points = new TRefArray(*track.get_track_points());
_constituent_tracks = new TRefArray(*track.get_constituent_tracks());
}
// Destructor
Track::~Track() {
delete _track_points;
delete _constituent_tracks;
}
// Assignment operator
Track& Track::operator=(const Track &track) {
if (this == &track) {
return *this;
}
_mapper_name = track.get_mapper_name();
_pid = track.get_pid();
_charge = track.get_charge();
_track_points = new TRefArray(*track.get_track_points());
_constituent_tracks = new TRefArray(*track.get_constituent_tracks());
_detectorpoints = track.get_detectorpoints();
_geometry_paths = track.get_geometry_paths();
_pid_logL_values = track.get_pid_logL_values();
_emr_range_primary = track.get_emr_range_primary();
_emr_range_secondary = track.get_emr_range_secondary();
_emr_plane_density = track.get_emr_plane_density();
_pid_confidence_level = track.get_pid_confidence_level();
_goodness_of_fit = track.get_goodness_of_fit();
_p_value = track.get_p_value();
_tracker_clusters = track.get_tracker_clusters();
return *this;
}
// Create a new Track, identical to the original, but separate. All
// TrackPoints are also cloned.
Track* Track::Clone() const {
MAUS::DataStructure::Global::Track* trackNew =
new MAUS::DataStructure::Global::Track();
trackNew->set_mapper_name(get_mapper_name());
trackNew->set_pid(get_pid());
trackNew->set_charge(get_charge());
trackNew->set_pid_logL_values(get_pid_logL_values());
trackNew->set_emr_range_primary(get_emr_range_primary());
trackNew->set_emr_range_secondary(get_emr_range_secondary());
trackNew->set_emr_plane_density(get_emr_plane_density());
// Track points may be edited, so we clone the original points
MAUS::DataStructure::Global::TrackPoint* tp = NULL;
for (int i = 0; i < _track_points->GetLast()+1; ++i) {
tp = (MAUS::DataStructure::Global::TrackPoint*) _track_points->At(i);
if (!tp) continue;
trackNew->PushBackTrackPoint(tp->Clone());
}
trackNew->set_detectorpoints(this->get_detectorpoints());
trackNew->set_geometry_paths(this->get_geometry_paths());
// This is just book-keeping, so we copy the TRefArray whole.
MAUS::DataStructure::Global::Track* t = NULL;
for (int i = 0; i < _constituent_tracks->GetLast()+1; ++i) {
t = (MAUS::DataStructure::Global::Track*) _constituent_tracks->At(i);
if (!t) continue;
trackNew->AddTrack(t);
}
trackNew->set_pid_confidence_level(this->get_pid_confidence_level());
trackNew->set_goodness_of_fit(this->get_goodness_of_fit());
trackNew->set_p_value(this->get_p_value());
trackNew->set_tracker_clusters(this->get_tracker_clusters());
return trackNew;
}
void Track::set_mapper_name(std::string mapper_name) {
_mapper_name = mapper_name;
}
std::string Track::get_mapper_name() const {
return _mapper_name;
}
void Track::set_pid(PID pid) {
_pid = pid;
}
PID Track::get_pid() const {
return _pid;
}
void Track::set_charge(int charge) {
_charge = charge;
}
int Track::get_charge() const {
return _charge;
}
void Track::set_emr_range_primary(double range) {
_emr_range_primary = range;
}
double Track::get_emr_range_primary() const {
return _emr_range_primary;
}
void Track::set_emr_range_secondary(double range) {
_emr_range_secondary = range;
}
double Track::get_emr_range_secondary() const {
return _emr_range_secondary;
}
void Track::set_emr_plane_density(double density) {
_emr_plane_density = density;
}
double Track::get_emr_plane_density() const {
return _emr_plane_density;
}
// Trackpoint methods
void Track::AddTrackPoint(MAUS::DataStructure::Global::TrackPoint* track_point) {
if (!track_point) {
throw(Exceptions::Exception(Exceptions::recoverable,
"Attempting to add a NULL TrackPoint",
"DataStructure::Global::Track::AddTrackPoint()"));
}
if (track_point->get_detector() == MAUS::DataStructure::Global::kVirtual) {
AddGeometryPath(track_point->get_geometry_path());
}
SetDetector(track_point->get_detector());
PushBackTrackPoint(track_point);
}
void Track::PushBackTrackPoint(
MAUS::DataStructure::Global::TrackPoint* track_point) {
_track_points->Add(track_point);
}
// Correctly remove the track_point, unsetting the detector bit and/or
// removing the geometry path if appropriate.
void Track::RemoveTrackPoint(
MAUS::DataStructure::Global::TrackPoint* track_point) {
if (!track_point) {
throw(Exceptions::Exception(Exceptions::recoverable,
"No matching TrackPoint: pointer is NULL",
"DataStructure::Global::Track::RemoveTrackPoint()"));
}
// Remove track_point from TRefArray
TObject* result = _track_points->FindObject(track_point);
if (!result) {
throw(Exceptions::Exception(Exceptions::recoverable,
"No matching TrackPoint ",
"DataStructure::Global::Track::RemoveTrackPoint()"));
} else {
_track_points->Remove(result);
_track_points->Compress();
}
// Check if track_point detector point should still be set.
MAUS::DataStructure::Global::DetectorPoint targetDP =
track_point->get_detector();
MAUS::DataStructure::Global::TrackPoint *eachTP;
bool stillNeeded = false;
for (int i = 0; i < _track_points->GetLast()+1; ++i) {
eachTP = (MAUS::DataStructure::Global::TrackPoint*) _track_points->At(i);
if (!eachTP) continue;
if (eachTP->get_detector() == targetDP) {
stillNeeded = true;
break;
}
}
if (!stillNeeded) {
RemoveDetector(targetDP);
}
// If we have an associated geometry path, remove that as well
if (targetDP == MAUS::DataStructure::Global::kVirtual) {
RemoveGeometryPath(track_point->get_geometry_path());
}
}
void Track::SortTrackPointsByZ() {
std::vector temp_track_points;
MAUS::DataStructure::Global::TrackPoint* tp = NULL;
for (int i = 0; i < _track_points->GetLast()+1; ++i) {
tp = (MAUS::DataStructure::Global::TrackPoint*) _track_points->At(i);
if (!tp) continue;
temp_track_points.push_back(tp);
}
std::sort(temp_track_points.begin(), temp_track_points.end(), SortByZ);
_track_points->Clear();
_track_points->Expand(temp_track_points.size()); // Can be used to shrink too
for (size_t i = 0; i < temp_track_points.size(); ++i) {
_track_points->AddAt(temp_track_points.at(i), i);
}
}
std::vector
Track::GetTrackPoints() const {
std::vector temp_track_points;
if (!_track_points) return temp_track_points;
const MAUS::DataStructure::Global::TrackPoint* tp = NULL;
for (int i = 0; i < _track_points->GetSize(); ++i) {
tp = (const MAUS::DataStructure::Global::TrackPoint*) _track_points->At(i);
if (!tp) continue;
temp_track_points.push_back(tp);
}
return temp_track_points;
}
std::vector
Track::GetTrackPoints(DetectorPoint detector) const {
std::vector temp_track_points;
if (!_track_points) return temp_track_points;
const MAUS::DataStructure::Global::TrackPoint* tp = NULL;
for (int i = 0; i < _track_points->GetSize(); ++i) {
tp = (const MAUS::DataStructure::Global::TrackPoint*) _track_points->At(i);
if (!tp) continue;
// Need to make sure that requests for the main detector (e.g. Tracker0)
// return points that are tagged with subdetectors as well
DetectorPoint tp_main_detector = tp->get_detector();
if ((tp_main_detector == kTOF0_1) or
(tp_main_detector == kTOF0_2)) {
tp_main_detector = kTOF0;
} else if ((tp_main_detector == kTOF1_1) or
(tp_main_detector == kTOF1_2)) {
tp_main_detector = kTOF1;
} else if ((tp_main_detector == kTOF2_1) or
(tp_main_detector == kTOF2_2)) {
tp_main_detector = kTOF2;
} else if ((tp_main_detector == kTracker0_1) or
(tp_main_detector == kTracker0_2) or
(tp_main_detector == kTracker0_3) or
(tp_main_detector == kTracker0_4) or
(tp_main_detector == kTracker0_5)) {
tp_main_detector = kTracker0;
} else if ((tp_main_detector == kTracker1_1) or
(tp_main_detector == kTracker1_2) or
(tp_main_detector == kTracker1_3) or
(tp_main_detector == kTracker1_4) or
(tp_main_detector == kTracker1_5)) {
tp_main_detector = kTracker1;
}
if ((tp->get_detector() == detector) or tp_main_detector == detector) {
temp_track_points.push_back(tp);
}
}
return temp_track_points;
}
void Track::set_track_points(TRefArray* track_points) {
if (_track_points != NULL) {
delete _track_points;
}
_track_points = track_points;
}
TRefArray* Track::get_track_points() const {
return _track_points;
}
// Detector Point Methods
void Track::SetDetector(MAUS::DataStructure::Global::DetectorPoint detector) {
// Set the Nth bit of the integer, where N is the value of the
// DetectorPoint enumerator.
_detectorpoints |= (int64_t(1) << detector);
}
void Track::RemoveDetector(
MAUS::DataStructure::Global::DetectorPoint detector) {
// Clear the Nth bit of the integer, where N is the value of the
// DetectorPoint enumerator.
_detectorpoints &= ~(int64_t(1) << detector);
}
bool Track::HasDetector(MAUS::DataStructure::Global::DetectorPoint detector)
const {
// Return the Nth bit of the integer, where N is the value of the
// DetectorPoint enumerator.
return (_detectorpoints & (int64_t(1) << detector));
}
void Track::ClearDetectors() {
// Set all bits to 0, i.e. set int 0.
_detectorpoints = 0;
}
std::vector
Track::GetDetectorPoints() const {
std::vector result;
MAUS::DataStructure::Global::DetectorPoint test;
for (int i = 0; i < MAUS::DataStructure::Global::kDetectorPointSize; ++i) {
test = static_cast(i);
if (HasDetector(test)) result.push_back(test);
}
return result;
}
void Track::set_detectorpoints(uint64_t detectorpoints) {
_detectorpoints = detectorpoints;
}
uint64_t Track::get_detectorpoints() const {
return _detectorpoints;
}
// Geometry Path methods
void Track::AddGeometryPath(std::string geometry_path) {
_geometry_paths.push_back(geometry_path);
}
void Track::RemoveGeometryPath(std::string geometry_path) {
std::vector::iterator result =
find(_geometry_paths.begin(), _geometry_paths.end(), geometry_path);
if (result == _geometry_paths.end()) {
throw(Exceptions::Exception(Exceptions::recoverable,
"Attempting to remove a geometry path not stored in Track",
"DataStructure::Global::Track::RemoveGeometryPath()"));
} else {
_geometry_paths.erase(result);
}
}
bool Track::HasGeometryPath(std::string geometry_path) const {
std::vector::const_iterator result =
find(_geometry_paths.begin(), _geometry_paths.end(), geometry_path);
return (result != _geometry_paths.end());
}
void Track::ClearGeometryPaths() {
_geometry_paths.clear();
}
void Track::set_geometry_paths(std::vector geometry_paths) {
_geometry_paths = geometry_paths;
}
std::vector Track::get_geometry_paths() const {
return _geometry_paths;
}
// Object to hold pid hypotheses and the log-likelihood that they are the
// correct hypothesis
void Track::set_pid_logL_values(std::vector
pid_logL_values) {
_pid_logL_values = pid_logL_values;
}
std::vector Track::get_pid_logL_values() const {
return _pid_logL_values;
}
// Method to fill pid_logL_values
void Track::AddPIDLogLValues(MAUS::DataStructure::Global::PIDLogLPair pid_logL) {
_pid_logL_values.push_back(pid_logL);
}
// Constituent Tracks methods
void Track::AddTrack(MAUS::DataStructure::Global::Track* track) {
_constituent_tracks->Add(track);
}
void Track::RemoveTrack(MAUS::DataStructure::Global::Track* track) {
TObject *result = _constituent_tracks->FindObject(track);
if (!result) {
throw(Exceptions::Exception(Exceptions::recoverable,
"Attempting to remove a constituent track not stored in Track",
"DataStructure::Global::Track::RemoveTrack()"));
} else {
_constituent_tracks->Remove(track);
}
}
bool Track::HasTrack(MAUS::DataStructure::Global::Track* track) const {
TObject *result = _constituent_tracks->FindObject(track);
return (result != NULL);
}
std::vector
Track::GetConstituentTracks() const {
std::vector temp_tracks;
const MAUS::DataStructure::Global::Track* t = NULL;
for (int i = 0; i < _constituent_tracks->GetLast()+1; ++i) {
t = (const MAUS::DataStructure::Global::Track*) _constituent_tracks->At(i);
if (!t) continue;
temp_tracks.push_back(t);
}
return temp_tracks;
}
std::vector
Track::GetConstituentTracks(MAUS::DataStructure::Global::DetectorPoint detector) const {
std::vector temp_tracks;
const MAUS::DataStructure::Global::Track* t = NULL;
for (int i = 0; i < _constituent_tracks->GetLast()+1; ++i) {
t = (const MAUS::DataStructure::Global::Track*) _constituent_tracks->At(i);
if (!t) continue;
if (t->HasDetector(detector)) {
temp_tracks.push_back(t);
}
}
return temp_tracks;
}
void Track::ClearTracks() {
_constituent_tracks->Clear();
}
void Track::set_constituent_tracks(TRefArray* constituent_tracks) {
_constituent_tracks = constituent_tracks;
}
TRefArray* Track::get_constituent_tracks() const {
return _constituent_tracks;
}
void Track::set_pid_confidence_level(double confidence_level) {
_pid_confidence_level = confidence_level;
}
double Track::get_pid_confidence_level() const {
return _pid_confidence_level;
}
void Track::set_goodness_of_fit(double goodness_of_fit) {
_goodness_of_fit = goodness_of_fit;
}
double Track::get_goodness_of_fit() const {
return _goodness_of_fit;
}
void Track::set_p_value(double p_value) {
_p_value = p_value;
}
double Track::get_p_value() const {
return _p_value;
}
void Track::set_tracker_clusters(unsigned int tracker_clusters) {
_tracker_clusters = tracker_clusters;
}
unsigned int Track::get_tracker_clusters() const {
return _tracker_clusters;
}
} // ~namespace Global
} // ~namespace DataStructure
} // ~namespace MAUS