Skip to content

Commit

Permalink
refactor: modularize
Browse files Browse the repository at this point in the history
  • Loading branch information
c-dilks committed Jun 1, 2023
1 parent f1b50bd commit 7ca5acd
Show file tree
Hide file tree
Showing 6 changed files with 223 additions and 5 deletions.
75 changes: 75 additions & 0 deletions src/algorithms/pid/MergeTracks.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// Copyright 2023, Christopher Dilks
// Subject to the terms in the LICENSE file found in the top-level directory.

#include "MergeTracks.h"

// AlgorithmInit
//---------------------------------------------------------------------------
void eicrecon::MergeTracks::AlgorithmInit(std::shared_ptr<spdlog::logger>& logger)
{
m_log = logger;
}


// AlgorithmChangeRun
//---------------------------------------------------------------------------
void eicrecon::MergeTracks::AlgorithmChangeRun() {
}


// AlgorithmProcess
//---------------------------------------------------------------------------
std::unique_ptr<edm4eic::TrackSegmentCollection> eicrecon::MergeTracks::AlgorithmProcess(
std::vector<const edm4eic::TrackSegmentCollection*> in_track_collections
)
{
// logging
m_log->trace("{:=^70}"," call MergeTracks::AlgorithmProcess ");

// start output collection
auto out_tracks = std::make_unique<edm4eic::TrackSegmentCollection>();

// check that all input collections have the same size
std::size_t n_tracks = -1;
for(const auto& in_track_collection : in_track_collections) {
if(n_tracks == -1)
n_tracks = in_track_collection->size();
else if(n_tracks != in_track_collection->size()) {
m_log->error("input track collections do not have the same size; cannot merge");
return out_tracks;
}
}

// loop over track collection elements
for(std::size_t i_track=0; i_track<n_tracks; i_track++) {

// create a new output track, and a local container to hold its track points
auto out_track = out_tracks->create();
std::vector<edm4eic::TrackPoint> out_track_points;

// loop over collections for this track, and add each track's points to `out_track_points`
for(const auto& in_track_collection : in_track_collections) {
const auto& in_track = in_track_collection->at(i_track);
for(const auto& point : in_track.getPoints())
out_track_points.push_back(point);
}

// sort all `out_track_points` by time
std::sort(
out_track_points.begin(),
out_track_points.end(),
[] (edm4eic::TrackPoint& a, edm4eic::TrackPoint& b) { return a.time < b.time; }
);

// add these sorted points to `out_track`
for(const auto& point : out_track_points)
out_track.addToPoints(point);

/* FIXME: merge other members, such as `length` and `lengthError`;
* currently not needed for RICH tracks, so such members are left as default
*/

} // end loop over tracks

return out_tracks;
}
43 changes: 43 additions & 0 deletions src/algorithms/pid/MergeTracks.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright 2023, Christopher Dilks
// Subject to the terms in the LICENSE file found in the top-level directory.

// merge together TrackSegments, sorting their TrackPoints by time
/* FIXME: only VectorMember `points` is combined, which is all that is needed
* for the RICH detectors. If using this algorithm for any other purpose, you
* may want to combine the other members and relations in `TrackSegment`.
*/

#pragma once

#include <cstddef>
#include <algorithm>

// data model
#include <edm4eic/TrackSegmentCollection.h>

// EICrecon
#include <spdlog/spdlog.h>

namespace eicrecon {

class MergeTracks {

public:
MergeTracks() = default;
~MergeTracks() {}

void AlgorithmInit(std::shared_ptr<spdlog::logger>& logger);
void AlgorithmChangeRun();

// AlgorithmProcess
// - input: a list of TrackSegment collections
// - output: the merged TrackSegment collections, effectively the "zip" of the input collections
std::unique_ptr<edm4eic::TrackSegmentCollection> AlgorithmProcess(
std::vector<const edm4eic::TrackSegmentCollection*> in_track_collections
);

private:
std::shared_ptr<spdlog::logger> m_log;

};
}
5 changes: 5 additions & 0 deletions src/detectors/DRICH/DRICH.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
// factories
#include <global/digi/PhotoMultiplierHitDigi_factory.h>
#include <global/pid/RichTrack_factory.h>
#include <global/pid/MergeTrack_factory.h>

// algorithm configurations
#include <algorithms/digi/PhotoMultiplierHitDigiConfig.h>
Expand Down Expand Up @@ -81,6 +82,10 @@ extern "C" {
track_cfg,
app
));
app->Add(new JChainFactoryGeneratorT<MergeTrack_factory>(
{"DRICHAerogelTracks", "DRICHGasTracks"},
"DRICHMergedTracks"
));

// clang-format on
}
Expand Down
45 changes: 45 additions & 0 deletions src/global/pid/MergeTrack_factory.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright (C) 2022, 2023, Christopher Dilks
// Subject to the terms in the LICENSE file found in the top-level directory.

#include "MergeTrack_factory.h"

//-----------------------------------------------------------------------------
void eicrecon::MergeTrack_factory::Init() {

// get plugin name and tag
auto app = GetApplication();
auto detector_name = eicrecon::str::ReplaceAll(GetPluginName(), ".so", "");
auto param_prefix = detector_name + ":" + GetTag();
InitDataTags(param_prefix);

// services
InitLogger(param_prefix, "info");
m_algo.AlgorithmInit(m_log);
m_log->debug("detector_name='{}' param_prefix='{}'", detector_name, param_prefix);

}

//-----------------------------------------------------------------------------
void eicrecon::MergeTrack_factory::BeginRun(const std::shared_ptr<const JEvent> &event) {
}

//-----------------------------------------------------------------------------
void eicrecon::MergeTrack_factory::Process(const std::shared_ptr<const JEvent> &event) {

// get input collections
std::vector<const edm4eic::TrackSegmentCollection*> in_track_collections;
for(auto& input_tag : GetInputTags())
in_track_collections.push_back(
static_cast<const edm4eic::TrackSegmentCollection*>(event->GetCollectionBase(input_tag))
);

// call the MergeTracks algorithm
try {
auto out_track_collection = m_algo.AlgorithmProcess(in_track_collections);
SetCollection(std::move(out_track_collection));
}
catch(std::exception &e) {
m_log->warn("Exception in underlying algorithm: {}. Event data will be skipped", e.what());
}

}
50 changes: 50 additions & 0 deletions src/global/pid/MergeTrack_factory.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Copyright (C) 2022, 2023 Christopher Dilks
// Subject to the terms in the LICENSE file found in the top-level directory.

#pragma once

// JANA
#include <extensions/jana/JChainFactoryT.h>
#include <JANA/JEvent.h>

// data model
#include <edm4eic/TrackSegmentCollection.h>

// algorithms
#include <algorithms/pid/MergeTracks.h>

// services
#include <services/log/Log_service.h>
#include <extensions/spdlog/SpdlogExtensions.h>
#include <extensions/spdlog/SpdlogMixin.h>
#include <extensions/string/StringHelpers.h>

namespace eicrecon {

class MergeTracks;

class MergeTrack_factory :
public JChainFactoryT<edm4eic::TrackSegment>,
public SpdlogMixin<MergeTrack_factory>
{

public:

explicit MergeTrack_factory(std::vector<std::string> default_input_tags) :
JChainFactoryT<edm4eic::TrackSegment>(std::move(default_input_tags)) {}

/** One time initialization **/
void Init() override;

/** On run change preparations **/
void BeginRun(const std::shared_ptr<const JEvent> &event) override;

/** Event by event processing **/
void Process(const std::shared_ptr<const JEvent> &event) override;

private:

// underlying algorithm
eicrecon::MergeTracks m_algo;
};
}
10 changes: 5 additions & 5 deletions src/global/pid/RichTrack_factory.cc
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ void eicrecon::RichTrack_factory::Init() {
output_tag,
m_actsGeo->TrackingPlanes(radiator_id, cfg.numPlanes.at(radiator_name))
});

}

//-----------------------------------------------------------------------------
Expand All @@ -55,7 +56,7 @@ void eicrecon::RichTrack_factory::BeginRun(const std::shared_ptr<const JEvent> &
//-----------------------------------------------------------------------------
void eicrecon::RichTrack_factory::Process(const std::shared_ptr<const JEvent> &event) {

// collect all trajectories all input tags
// collect all trajectories from all input tags
std::vector<const eicrecon::TrackingResultTrajectory*> trajectories;
for(const auto& input_tag : GetInputTags()) {
try {
Expand All @@ -67,16 +68,15 @@ void eicrecon::RichTrack_factory::Process(const std::shared_ptr<const JEvent> &e
}
}

// run algorithm, for each radiator
// run track propagator algorithm, for each radiator
for(auto& [output_tag, radiator_tracking_planes] : m_tracking_planes) {
try {
// propagate trajectories to RICH planes (discs)
auto result = m_propagation_algo.propagateToSurfaceList(trajectories, radiator_tracking_planes);
// set factory output propagated tracks
SetCollection<edm4eic::TrackSegment>(output_tag, std::move(result));
}
catch(std::exception &e) {
m_log->warn("Exception in underlying algorithm: {}. Event data will be skipped", e.what());
m_log->warn("Exception in underlying propagator algorithm: {}. Event data will be skipped", e.what());
}
}

}

0 comments on commit 7ca5acd

Please sign in to comment.