Skip to content

Instantly share code, notes, and snippets.

@YanzhaoW
Last active April 10, 2024 17:01
Show Gist options
  • Save YanzhaoW/351e4d0cc52b72d37ff1a1b408c983ce to your computer and use it in GitHub Desktop.
Save YanzhaoW/351e4d0cc52b72d37ff1a1b408c983ce to your computer and use it in GitHub Desktop.
R3BRoot template for a task class
/******************************************************************************
* Copyright (C) 2019 GSI Helmholtzzentrum für Schwerionenforschung GmbH *
* Copyright (C) 2019-2024 Members of R3B Collaboration *
* *
* This software is distributed under the terms of the *
* GNU General Public Licence (GPL) version 3, *
* copied verbatim in the file "LICENSE". *
* *
* In applying this license GSI does not waive the privileges and immunities *
* granted to it by virtue of its status as an Intergovernmental Organization *
* or submit itself to any jurisdiction. *
******************************************************************************/
#pragma once
#include <TNamed.h>
// if needed
#include <fmt/format.h>
namespace R3B
{
struct DetectorData : public TNamed
{
public:
explicit DetectorData(std::string_view name = "DefaultName")
: TNamed(name.data(), ""){};
int module_num = 0; // starts from 1
int module_id = 0; // starts from 0
double energy = 0.;
uint32_t tpat = 0U;
void reset()
{
module_num = 0;
module_id = 0;
energy = 0.;
tpat = 0U;
}
ClassDefOverride(DetectorData, 1);
};
struct DetectorCalData : public TObject
{
public:
DetectorCalData() = default;
int module_num = 0; // starts from 1
double left_time = 0.;
double right_time = 0.;
ClassDefOverride(DetectorCalData, 1);
};
struct DetectorHitData : public TObject
{
public:
DetectorHitData() = default;
int module_num = 0; // starts from 1
double energy = 0.;
double time = 0.;
double position = 0.;
ClassDefOverride(DetectorHitData, 1);
};
} // namespace R3B
// optional for the nice printing
template <>
class fmt::formatter<R3B::DetectorData>
{
public:
static constexpr auto parse(format_parse_context& ctx) { return ctx.end(); }
template <typename FmtContent>
constexpr auto format(const R3B::DetectorData& data, FmtContent& ctn) const
{
return format_to(
ctn.out(), "{{module_id: {}, energy: {}, tpat: {:x}}}", data.module_id, data.energy, data.tpat);
}
};
// clang-format off
/******************************************************************************
* Copyright (C) 2019 GSI Helmholtzzentrum für Schwerionenforschung GmbH *
* Copyright (C) 2019-2024 Members of R3B Collaboration *
* *
* This software is distributed under the terms of the *
* GNU General Public Licence (GPL) version 3, *
* copied verbatim in the file "LICENSE". *
* *
* In applying this license GSI does not waive the privileges and immunities *
* granted to it by virtue of its status as an Intergovernmental Organization *
* or submit itself to any jurisdiction. *
******************************************************************************/
#ifdef __CINT__
#pragma link off all globals;
#pragma link off all classes;
#pragma link off all functions;
#pragma link C++ class R3B::DetectorData+;
#pragma link C++ class R3B::DetectorCalData+;
#pragma link C++ class R3B::DetectorHitData+;
#pragma link C++ class vector<R3B::DetectorCalData>+;
#pragma link C++ class vector<R3B::DetectorHitData>+;
#endif
/******************************************************************************
* Copyright (C) 2019 GSI Helmholtzzentrum für Schwerionenforschung GmbH *
* Copyright (C) 2019-2024 Members of R3B Collaboration *
* *
* This software is distributed under the terms of the *
* GNU General Public Licence (GPL) version 3, *
* copied verbatim in the file "LICENSE". *
* *
* In applying this license GSI does not waive the privileges and immunities *
* granted to it by virtue of its status as an Intergovernmental Organization *
* or submit itself to any jurisdiction. *
******************************************************************************/
// NOTE: comments below are only meant for eduational purpose. DO NOT include them in your code!
// ROOT headers
#include <TClonesArray.h>
#include <TMath.h>
#include <TRandom.h>
// Fair headers
#include <FairLogger.h>
#include <FairRootManager.h>
#include <FairRunAna.h>
#include <FairRuntimeDb.h>
// R3B headers
#include "NewTask.h"
#include <R3BEventHeader.h>
#include <R3BLogger.h>
#include <fmt/core.h>
namespace R3B
{
// ---- Standard Constructor ------------------------------------------
NewTask::NewTask(const std::string& name, int iVerbose)
: FairTask(name.c_str(), iVerbose)
{
}
// ---- Default constructor -------------------------------------------
// use constructor delegation
NewTask::NewTask()
: NewTask("NewTask", 1)
{
}
// ---- Initialisation ----------------------------------------------
void NewTask::SetParContainers()
{
R3BLOG(debug2, "SetParContainers of NewTask");
// Load all necessary parameter containers from the runtime data base
}
// ---- Init ----------------------------------------------------------
auto NewTask::Init() -> InitStatus
{
R3BLOG(debug2, "NewTask::Init()");
// Get a handle from the IO manager
auto* ioman = FairRootManager::Instance();
if (ioman == nullptr)
{
return kFATAL;
}
// ---------------- input initialisation ---------------
// Case 1. Input std::vector:
input_data_vector_.init();
// Case 2. Input TClonesArray (NOT RECOMMENDED):
input_data_TCA_ = dynamic_cast<TClonesArray*>(ioman->GetObject("DetectorCalData"));
if (input_data_TCA_ == nullptr)
{
throw R3B::runtime_error("DetectorCalData is not found!");
}
// Case 3. Input a TObject:
if (eventHeader_ = dynamic_cast<R3BEventHeader*>(ioman->GetObject("EventHeader.")); eventHeader_ == nullptr)
{
throw R3B::runtime_error("R3BEventHeader is nullptr!");
}
// ---------------- output initialisation ---------------
// Case 1. Output std::vector
output_data_vector_.init();
// Case 2. Ouput TClonesArray (NOT RECOMMENDED)
ioman->Register("DetectorHitData", "Detector", output_data_TCA_, kTRUE);
// Case 3. Output a TObject
output_data_ = std::make_unique<DetectorData>().release();
ioman->Register(output_data_->GetName(), "Detector", output_data_, kTRUE);
// Do whatever else is needed at the initilization stage
// Create histograms to be filled
// initialize variables
return kSUCCESS;
}
// ---- Exec ----------------------------------------------------------
void NewTask::Exec(Option_t* /*opt*/)
{
R3BLOG(debug, "Exec of NewTask");
output_data_vector_.clear();
output_data_TCA_->Clear();
output_data_->reset();
// --------- input data reading -------------
// Case 1: read std::vector
for (const auto& calData : input_data_vector_)
{
// do something with calData
fmt::print("qdc value: {}\n", calData.left_time);
}
// Case 2: read TClonesArray:
for (const auto* calData_ptr : TRangeDynCast<DetectorCalData>(input_data_TCA_))
{
// do something with calData
fmt::print("qdc value: {}\n", (*calData_ptr).left_time);
}
// Case 3: read TObject:
fmt::print("Event number: {}\n", eventHeader_->GetEventno());
// --------- output data writing -------------
// Case 1: write std::vector:
auto& hit_data = output_data_vector_.get().emplace_back();
hit_data.energy = 0.;
hit_data.time = 1;
hit_data.position = 0.;
// Case 2: write TClonesArray:
auto* hit_data_ptr =
dynamic_cast<DetectorHitData*>(output_data_TCA_->ConstructedAt(output_data_TCA_->GetEntriesFast()));
if (hit_data_ptr != nullptr)
{
(*hit_data_ptr).energy = 0.;
(*hit_data_ptr).time = 1;
(*hit_data_ptr).position = 0.;
}
// Case 3: write TObject:
if (output_data_ != nullptr)
{
(*output_data_).energy = 0.;
}
}
// ---- Finish --------------------------------------------------------
void NewTask::Finish() { R3BLOG(debug2, "Finish of NewTask"); }
} // namespace R3B
ClassImp(R3B::NewTask);
/******************************************************************************
* Copyright (C) 2019 GSI Helmholtzzentrum für Schwerionenforschung GmbH *
* Copyright (C) 2019-2024 Members of R3B Collaboration *
* *
* This software is distributed under the terms of the *
* GNU General Public Licence (GPL) version 3, *
* copied verbatim in the file "LICENSE". *
* *
* In applying this license GSI does not waive the privileges and immunities *
* granted to it by virtue of its status as an Intergovernmental Organization *
* or submit itself to any jurisdiction. *
******************************************************************************/
#pragma once
// NOTE: comments below are only meant for eduational purpose. DO NOT include them in your code!
#include <FairTask.h>
#include <R3BIOConnector.h>
#include <R3BNeulandCalData.h>
#include <R3BNeulandHit.h>
#include <string>
#include "DetectorData.h"
class R3BEventHeader;
// namespace here is optional.
namespace R3B
{
// If R3B namespace is not used, the task should be named with R3BNewTask
class NewTask : public FairTask
{
public:
// Default constructor
NewTask();
// Standard constructor
explicit NewTask(const std::string& name, int iVerbose = 1);
// Other speical functions. Either define all these 5 functions or none of them (rule of 5).
// Defining none of them is preferred (rule of 0).
// ~NewTask() override;
// NewTask(const NewTask&) = delete;
// NewTask(NewTask&&) = delete;
// NewTask& operator=(const NewTask&) = delete;
// NewTask& operator=(NewTask&&) = delete;
// Method to setup online mode
void SetOnline(bool is_online) { is_online_ = is_online; }
private:
// NOTE: all member variables should be default initiliazed
// Store data for online
// Naming convenction of a boolean variable should be started with is_ or has_
bool is_online_ = false;
// -----------------Input data from previous already existing data level---------------
// Case 1: Input data from std::vector container
R3B::InputVectorConnector<DetectorCalData> input_data_vector_{ "DetectorCalData" };
// or
// InputConnector<std::vector<R3BNeulandCalData>> input_data_{ "DetectorCalData" };
//
// Case 2: Input data from TClonesArray container
TClonesArray* input_data_TCA_ = nullptr;
//
// Case 3: Input a TObject
R3BEventHeader* eventHeader_ = nullptr;
// -----------------Output array to new data level-----------------
// Case 1: Ouput data container in std::vector (RECOMMENDED)
R3B::OutputVectorConnector<DetectorHitData> output_data_vector_{ "DetectorHitData" };
// or
// OutputConnector<std::vector<R3BNeulandHit>> output_data_{ "DetectorHitData" };
//
// Case 2: Output data container in TClonesArray (NOT RECOMMENDED)
TClonesArray* output_data_TCA_ = nullptr;
//
// Case 3: Output a TObject
DetectorData* output_data_ = nullptr;
// virtual functions should be private
// Initiliazation of task at the beginning of a run
auto Init() -> InitStatus override;
// Executed for each event
void Exec(Option_t* opt) override;
// Load the parameter container from the runtime database
void SetParContainers() override;
// Finish task called at the end of the run
void Finish() override;
public:
// Class definition
ClassDefOverride(NewTask, 1); // NOLINT
};
} // namespace R3B
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment