1
/* This file is part of MAUS: http://micewww.pp.rl.ac.uk:8080/projects/maus
3
* MAUS is free software: you can redistribute it and/or modify
4
* it under the terms of the GNU General Public License as published by
5
* the Free Software Foundation, either version 3 of the License, or
6
* (at your option) any later version.
8
* MAUS is distributed in the hope that it will be useful,
9
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
* GNU General Public License for more details.
13
* You should have received a copy of the GNU General Public License
14
* along with MAUS. If not, see <http://www.gnu.org/licenses/>.
20
#include "src/map/MapCppGlobalTrackReconstructor/MapCppGlobalTrackReconstructor.hh"
29
#include "TLorentzVector.h"
31
#include "CLHEP/Units/PhysicalConstants.h"
32
#include "json/json.h"
35
#include "Utils/Exception.hh"
38
#include "Converter/DataConverters/JsonCppSpillConverter.hh"
39
#include "Converter/DataConverters/CppJsonSpillConverter.hh"
40
#include "DataStructure/GlobalEvent.hh"
41
#include "DataStructure/ReconEvent.hh"
42
#include "DataStructure/Spill.hh"
43
#include "DataStructure/Global/Track.hh"
44
#include "DataStructure/Global/TrackPoint.hh"
45
#include "DataStructure/ThreeVector.hh"
46
#include "src/common_cpp/Optics/CovarianceMatrix.hh"
47
#include "src/common_cpp/Optics/LinearApproximationOpticsModel.hh"
48
#include "src/common_cpp/Optics/PolynomialOpticsModel.hh"
49
#include "Recon/Global/DataStructureHelper.hh"
50
#include "Recon/Global/Detector.hh"
51
#include "Recon/Global/MinuitTrackFitter.hh"
52
#include "Recon/Global/Particle.hh"
53
#include "Recon/Global/TrackFitter.hh"
54
#include "Simulation/MAUSGeant4Manager.hh"
55
#include "Utils/JsonWrapper.hh"
56
#include "Utils/CppErrorHandler.hh"
60
using MAUS::recon::global::DataStructureHelper;
61
using MAUS::recon::global::Detector;
62
using MAUS::recon::global::MinuitTrackFitter;
63
using MAUS::recon::global::Particle;
64
using MAUS::recon::global::TrackFitter;
65
namespace GlobalDS = MAUS::DataStructure::Global;
67
MapCppGlobalTrackReconstructor::MapCppGlobalTrackReconstructor()
68
: optics_model_(NULL), track_fitter_(NULL) {
71
MapCppGlobalTrackReconstructor::~MapCppGlobalTrackReconstructor() {
72
if (optics_model_ != NULL) {
76
if (track_fitter_ != NULL) {
81
bool MapCppGlobalTrackReconstructor::birth(std::string configuration_string) {
82
// parse the JSON document.
84
configuration_ = JsonWrapper::StringToJson(configuration_string);
85
Json::Value physics_processes = configuration_["physics_processes"];
86
if ((physics_processes != Json::Value("mean_energy_loss"))
87
&& (physics_processes != Json::Value("none"))) {
88
throw(Exception(Exception::nonRecoverable,
89
"The \"physics_processes\" configuration variable should be "
90
"set to \"mean_energy_loss\" or \"none\" to avoid collisions "
91
"of the test particles with walls.",
92
"MAUS::MapCppGlobalTrackReconstructor::birth()"));
94
DataStructureHelper::GetInstance().GetDetectorAttributes(
95
configuration_, detectors_);
98
} catch(Exception& exc) {
99
MAUS::CppErrorHandler::getInstance()->HandleExceptionNoJson(
100
exc, MapCppGlobalTrackReconstructor::kClassname);
102
} catch(std::exception& exc) {
103
MAUS::CppErrorHandler::getInstance()->HandleStdExcNoJson(
104
exc, MapCppGlobalTrackReconstructor::kClassname);
108
return true; // Sucessful parsing
111
std::string MapCppGlobalTrackReconstructor::process(
112
std::string run_data_string) {
113
// parse the JSON document.
114
Json::Value run_data_json
115
= Json::Value(JsonWrapper::StringToJson(run_data_string));
116
if (run_data_json.isNull() || run_data_json.empty()) {
117
return std::string("{\"errors\":{\"bad_json_document\":"
118
"\"Failed to parse input document\"}}");
121
JsonCppSpillConverter deserialize;
122
MAUS::Data * run_data = deserialize(&run_data_json);
124
return std::string("{\"errors\":{\"failed_json_cpp_conversion\":"
125
"\"Failed to convert Json to C++ Data object\"}}");
128
const MAUS::Spill * spill = run_data->GetSpill();
129
MAUS::ReconEventPArray * recon_events = spill->GetReconEvents();
131
return run_data_string;
134
MAUS::ReconEventPArray::const_iterator recon_event;
135
for (recon_event = recon_events->begin();
136
recon_event != recon_events->end();
138
MAUS::GlobalEvent * const global_event = (*recon_event)->GetGlobalEvent();
140
GlobalDS::TrackPArray raw_tracks;
141
LoadRawTracks(global_event, raw_tracks);
142
std::cerr << "Loaded " << raw_tracks.size() << " raw tracks." << std::endl;
143
// Fit each raw track and store best fit track in global_event
144
GlobalDS::TrackPArray::const_iterator raw_track;
145
for (raw_track = raw_tracks.begin();
146
raw_track != raw_tracks.end();
148
GlobalDS::Track * best_fit_track = new GlobalDS::Track();
149
best_fit_track->set_mapper_name(kClassname);
150
best_fit_track->AddTrack(*raw_track);
152
std::cout << "DEBUG MapCppGlobalTrackReconstructor::process: "
153
<< "raw track PID: " << (*raw_track)->get_pid() << std::endl;
154
track_fitter_->Fit(*raw_track, best_fit_track, kClassname);
156
InsertIntermediateTrackPoints(best_fit_track);
158
global_event->add_track_recursive(best_fit_track);
161
std::vector<MAUS::DataStructure::Global::Track*>* tracks
162
= global_event->get_tracks();
163
std::cout << "Added " << (tracks->size()-1)<< " reconstructed tracks:"
167
// Serialize the Spill for passing on to the next map in the workflow
168
CppJsonSpillConverter serialize;
169
Json::FastWriter writer;
170
std::string output = writer.write(*serialize(run_data));
171
std::cout << "DEBUG MapCppGlobalRawTracks::process(): "
172
<< "Output: " << std::endl
173
<< output << std::endl;
180
bool MapCppGlobalTrackReconstructor::death() {
181
return true; // successful
184
void MapCppGlobalTrackReconstructor::SetupOpticsModel() {
185
fprintf(stdout, "CHECKPOINT: SetupOpticsModel() 0\n");
187
Json::Value optics_model_names = JsonWrapper::GetProperty(
189
"global_recon_optics_models",
190
JsonWrapper::arrayValue);
191
Json::Value optics_model_name = JsonWrapper::GetProperty(
193
"global_recon_optics_model",
194
JsonWrapper::stringValue);
196
for (model = 0; model < optics_model_names.size(); ++model) {
197
if (optics_model_name == optics_model_names[model]) {
198
break; // leave the current index into optics_model_names in model
202
fprintf(stdout, "CHECKPOINT: SetupOpticsModel() 1\n");
207
/* TODO(plane1@hawk.iit.edu)
208
optics_model_ = new DifferentiatingOpticsModel();
210
throw(Exception(Exception::nonRecoverable,
211
"DifferentiatingOpticsModel is not yet implemented.",
212
"MapCppGlobalTrackReconstructor::SetupOpticsModel()"));
217
/* TODO(plane1@hawk.iit.edu)
218
optics_model_ = new IntegratingOpticsModel();
220
throw(Exception(Exception::nonRecoverable,
221
"IntegratingOpticsModel is not yet implemented.",
222
"MapCppGlobalTrackReconstructor::SetupOpticsModel()()"));
226
fprintf(stdout, "CHECKPOINT SetupOpticsModel() 1.1c\n");
228
optics_model_ = new PolynomialOpticsModel(&configuration_);
233
/* TODO(plane1@hawk.iit.edu)
234
optics_model_ = new RungeKuttaOpticsModel();
236
throw(Exception(Exception::nonRecoverable,
237
"RungeKuttaOpticsModel is not yet implemented.",
238
"MapCppGlobalTrackReconstructor::SetupOpticsModel()()"));
242
// "Linear Approximation"
243
fprintf(stdout, "CHECKPOINT SetupOpticsModel() 1.1e\n");
245
optics_model_ = new LinearApproximationOpticsModel(&configuration_);
249
std::string message("Unsupported optics model \"");
250
message += optics_model_name.asString();
251
message += std::string("\" in recon configuration.");
252
throw(Exception(Exception::nonRecoverable,
254
"MapCppGlobalTrackReconstructor::SetupOpticsModel()()"));
257
fprintf(stdout, "CHECKPOINT: SetupOpticsModel() 2\n");
259
optics_model_->Build();
261
fprintf(stdout, "CHECKPOINT: SetupOpticsModel() 3\n");
265
void MapCppGlobalTrackReconstructor::SetupTrackFitter() {
266
Json::Value fitter_names = JsonWrapper::GetProperty(
268
"global_recon_track_fitters",
269
JsonWrapper::arrayValue);
270
Json::Value fitter_name = JsonWrapper::GetProperty(
272
"global_recon_track_fitter",
273
JsonWrapper::stringValue);
275
for (fitter = 0; fitter < fitter_names.size(); ++fitter) {
276
if (fitter_name == fitter_names[fitter]) {
277
break; // leave the current index into fitter_names in fitter
284
double start_plane = optics_model_->primary_plane();
285
track_fitter_ = new MinuitTrackFitter(optics_model_, start_plane);
290
/* TODO(plane1@hawk.iit.edu)
291
track_fitter_ = new KalmanFilterTrackFitter(optics_model_);
293
throw(Exception(Exception::nonRecoverable,
294
"KalmanFilterTrackFitter is not yet implemented.",
295
"MapCppGlobalTrackReconstructor::SetupTrackFitter()"));
300
/* TODO(plane1@hawk.iit.edu)
301
track_fitter_ = new TOFTrackFitter(optics_model_);
303
throw(Exception(Exception::nonRecoverable,
304
"TOFTrackFitter is not yet implemented.",
305
"MapCppGlobalTrackReconstructor::SetupTrackFitter()"));
309
std::string message("Unsupported track fitter \"");
310
message += fitter_name.asString();
311
message += std::string("\" in recon configuration.");
312
throw(Exception(Exception::nonRecoverable,
314
"MapCppGlobalTrackReconstructor::SetupTrackFitter()"));
319
void MapCppGlobalTrackReconstructor::LoadRawTracks(
320
GlobalEvent const * const global_event,
321
GlobalDS::TrackPArray & tracks) const {
322
GlobalDS::TrackPArray * global_tracks = global_event->get_tracks();
323
GlobalDS::TrackPArray::iterator global_track;
324
const std::string recon_mapper_name("MapCppGlobalRawTracks");
325
for (global_track = global_tracks->begin();
326
global_track != global_tracks->end();
328
if ((*global_track)->get_mapper_name() == recon_mapper_name) {
329
tracks.push_back(*global_track);
334
void MapCppGlobalTrackReconstructor::InsertIntermediateTrackPoints(
335
GlobalDS::Track * track) const {
336
PolynomialOpticsModel * const optics_model
337
= static_cast<MAUS::PolynomialOpticsModel*>(optics_model_);
338
if (optics_model == NULL) {
339
throw(Exception(Exception::nonRecoverable,
340
"Could not reconstruct intermediate track points: the optics "
341
"model being used is not yet fully supported.",
342
"MAUS::MapCppGlobalTrackReconstructor::"
343
"InsertIntermediateTrackPoints()"));
346
// Get the fit track points
347
GlobalDS::TrackPointCPArray fit_points = track->GetTrackPoints();
349
// Convert the first fit track point into a PhaseSpaceVector for transporting
350
GlobalDS::TrackPoint const * const fit_primary_track_point = fit_points[0];
351
size_t particle_event = fit_primary_track_point->get_particle_event();
352
DataStructureHelper helper = DataStructureHelper::GetInstance();
353
PhaseSpaceVector fit_primary
354
= helper.TrackPoint2PhaseSpaceVector(*fit_primary_track_point);
356
// Construct a list of detector z-keys (z-position rounded to nearest integer)
357
std::vector<int64_t> z_keys;
358
GlobalDS::TrackPointCPArray::const_iterator fit_point
359
= fit_points.begin();
360
for (fit_point = fit_points.begin();
361
fit_point != fit_points.end();
363
// calculate the next guess
364
const double z = (*fit_point)->get_position().Z();
365
int64_t z_key = (z >= 0?static_cast<int64_t>(z+.5):static_cast<int64_t>(z-.5));
366
z_keys.push_back(z_key);
369
// Reconstruct the intermediate track points by transporting the fit primary
370
// to all desired intermediate z-positions
371
const GlobalDS::PID particle_id = track->get_pid();
372
std::vector<int64_t>::const_iterator z_key = z_keys.begin();
373
const std::vector<int64_t> map_positions
374
= optics_model->GetAvailableMapPositions();
375
std::vector<int64_t>::const_iterator map_z;
376
for (map_z = map_positions.begin(); map_z != map_positions.end(); ++map_z) {
377
// locate the next detector z-position
378
while (z_key != z_keys.end() && (*z_key) < (*map_z)) {
382
// transport the fit primary to the desired z-position
383
const PhaseSpaceVector point = optics_model_->Transport(fit_primary,
385
std::cout << "DEBUG MapCppGlobalTrackReconstructor"
386
<< "::InsertIntermediateTrackPoints: track point: "
387
<< point << std::endl;
389
// skip if we've already added this point to the track during fitting
390
if ((*z_key) == (*map_z)) {
394
// add the reconstructed intermediate to the track
395
GlobalDS::TrackPoint track_point;
398
= helper.PhaseSpaceVector2TrackPoint(point, *map_z, particle_id);
399
} catch (Exception exc) {
400
std::cerr << "DEBUG MapCppGlobalTrackReconstructor"
401
<< "::InsertIntermediateTrackPoints: "
402
<< "something bad happened during track fitting: "
403
<< exc.what() << std::endl;
406
track_point.set_mapper_name(kClassname);
407
track_point.set_particle_event(particle_event);
408
track->AddTrackPoint(new GlobalDS::TrackPoint(track_point));
410
track->SortTrackPointsByZ();
413
const std::string MapCppGlobalTrackReconstructor::kClassname
414
= "MapCppGlobalTrackReconstructor";