Skip to content
Snippets Groups Projects
Commit 5257e8dc authored by Volker Friese's avatar Volker Friese
Browse files

EventBuilder: add missing include. Use std::transform instead of...

EventBuilder: add missing include. Use std::transform instead of std::vector::emplace_back. Refs #2267.
parent 84137ec5
No related branches found
No related tags found
1 merge request!567First algo formulation of EventBuilder (STS only). Refs #2267
Pipeline #13898 passed
add_subdirectory (data)
# Create a library libCbmAlgo
set(SRCS
evbuild/EventBuilder.cxx
)
add_library(Algo SHARED ${SRCS})
target_include_directories(Algo
PUBLIC ${CMAKE_SOURCE_DIR}/core/data
PUBLIC ${CMAKE_SOURCE_DIR}/core/data/base
PUBLIC ${CMAKE_SOURCE_DIR}/core/data/global
PUBLIC ${CMAKE_SOURCE_DIR}/core/data/sts
PUBLIC ${CMAKE_SOURCE_DIR}/external/ipc/ipc/lib/fles_ipc
)
target_include_directories(Algo SYSTEM
PUBLIC ${Boost_INCLUDE_DIR}
)
target_compile_definitions(Algo PUBLIC NO_ROOT)
/* Copyright (C) 2021 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
SPDX-License-Identifier: GPL-3.0-only
Authors: Volker Friese [committer] */
#include "EventBuilder.h"
#include <algorithm>
#include <cassert>
#include <vector>
using std::is_sorted;
using std::vector;
namespace cbm
{
namespace algo
{
// --- Execution
std::vector<CbmDigiEvent> EventBuilder::operator()(const CbmDigiTimeslice& ts, const vector<double> triggers) const
{
assert(is_sorted(triggers.begin(), triggers.end()));
vector<CbmDigiEvent> eventVec(triggers.size());
std::transform(triggers.begin(), triggers.end(), eventVec.begin(),
[&ts, this](const double& trigger) { return BuildEvent(ts, trigger); });
return eventVec;
}
// --- Build a single event
CbmDigiEvent EventBuilder::BuildEvent(const CbmDigiTimeslice& ts, double trigger) const
{
CbmDigiEvent event;
event.fTime = trigger;
double tMin = trigger + fTriggerWindows.find(ECbmModuleId::kSts)->second.first;
double tMax = trigger + fTriggerWindows.find(ECbmModuleId::kSts)->second.second;
assert(is_sorted(ts.fData.fSts.fDigis.begin(), ts.fData.fSts.fDigis.end(), IsBefore<CbmStsDigi, CbmStsDigi>));
event.fData.fSts.fDigis = CopyRange(ts.fData.fSts.fDigis, tMin, tMax);
return event;
}
} // namespace algo
} // namespace cbm
/* Copyright (C) 2021 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
SPDX-License-Identifier: GPL-3.0-only
Authors: Volker Friese [committer] */
#ifndef CBM_ALGO_EVENTBUILDER_H
#define CBM_ALGO_EVENTBUILDER_H 1
#include "CbmDefs.h"
#include "CbmDigiEvent.h"
#include "CbmDigiTimeslice.h"
#include <algorithm>
#include <map>
#include <vector>
namespace cbm
{
namespace algo
{
/** @brief Time comparison of two objects with time stamps (class implementing GetTime()) **/
template<typename Data1, typename Data2>
bool IsBefore(const Data1& obj1, const Data2& obj2)
{
return obj1.GetTime() < obj2.GetTime();
}
/** @class EventBuilder
** @author Volker Friese <v.friese@gsi.de>
** @since 2021
** @brief Constructs CbmDigiEvents out of CbmDigiTimeslices
**
** Events are constructed by copying digi data from the source (CbmDigiTimeslice).
** Digis are selected in trigger windows, the sizes of which relative to a trigger time are configurable.
** For each trigger time, an event is generated. The time intervals may overlap, resulting in digis
** being attributed to multiple events.
**
** The source digi vectors (in CbmDigiTimeslice) must be sorted w.r.t. time, otherwise the behaviour is
** undefined.
**
** The trigger vector must be sorted.
**/
class EventBuilder {
public:
/** @brief Constructor **/
EventBuilder() {};
/** @brief Destructor **/
virtual ~EventBuilder() {};
/** @brief Execution
** @param ts Digi source (timeslice)
** @param triggers List of trigger times
** @return Vector of constructed events
**/
std::vector<CbmDigiEvent> operator()(const CbmDigiTimeslice& ts, const std::vector<double> triggers) const;
/** @brief Build a single event from a trigger time
** @param ts Digi source (timeslice)
** @param trigger Trigger time
** @return Digi event
**/
CbmDigiEvent BuildEvent(const CbmDigiTimeslice& ts, double trigger) const;
/** @brief Configure the trigger windows
** @param system Detector system identifier
** @param tMin Trigger window start time w.r.t. trigger time
** @param tMax Trigger window end time w.r.t. trigger time
**/
void SetTriggerWindow(ECbmModuleId system, double tMin, double tMax)
{
fTriggerWindows[system] = std::make_pair(tMin, tMax);
}
private: // methods
/** @brief Copy data objects in a given time interval from the source to the target vector
** @param source Source data vector
** @param tMin Minimal time
** @param tMax Maximal time
** @return Target data vector
**
** The Data class specialisation must implement the method double GetTime(), which is used to
** check whether the Data object falls into the specified time interval.
**
** The source vector must be ordered w.r.t. GetTime(), otherwise the behaviour is undefined.
**
** TODO: The current implementation searches, for each trigger, the entire source vector. This
** can surely be optimised when the contract that the trigger vector be sorted is properly exploited,
** e.g., by starting the search for the first digi in the trigger window from the start of the
** previous trigger window. This, however, requires bookkeeping hardly to be realised without
** changing the state of the class. I leave this for the future and for bright specialists.
**/
template<typename Data>
static typename std::vector<Data> CopyRange(const std::vector<Data>& source, double tMin, double tMax)
{
auto comp = [](const Data& obj, double value) { return obj.GetTime() < value; };
auto lower = std::lower_bound(source.begin(), source.end(), tMin, comp);
auto upper = std::lower_bound(lower, source.end(), tMax, comp);
return std::vector<Data>(lower, upper);
}
private: // data members
std::map<ECbmModuleId, std::pair<double, double>> fTriggerWindows;
};
} // namespace algo
} // namespace cbm
#endif /* CBM_ALGO_EVENTBUILDER_H */
......@@ -12,4 +12,3 @@ add_subdirectory(littrack)
add_subdirectory(steer)
add_subdirectory(tracking)
add_subdirectory(qa)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment