Skip to content
Snippets Groups Projects
CbmTaskMakeRecoEvents.cxx 6.23 KiB
/* Copyright (C) 2021 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
   SPDX-License-Identifier: GPL-3.0-only
   Authors: Volker Friese [committer] */


#include "CbmTaskMakeRecoEvents.h"

#include "CbmDefs.h"
#include "CbmEvent.h"

#include <FairLogger.h>

#include <TClonesArray.h>
#include <TStopwatch.h>

#include <algorithm>
#include <cassert>
#include <iomanip>
#include <vector>


using namespace std;


// -----   Constructor   -----------------------------------------------------
CbmTaskMakeRecoEvents::CbmTaskMakeRecoEvents() : FairTask("MakeRecoEvents") {}
// ---------------------------------------------------------------------------


// -----   Destructor   ------------------------------------------------------
CbmTaskMakeRecoEvents::~CbmTaskMakeRecoEvents() {}
// ---------------------------------------------------------------------------


// -----   Execution   -------------------------------------------------------
void CbmTaskMakeRecoEvents::Exec(Option_t*)
{

  // --- Timer and counters
  TStopwatch timer;
  timer.Start();

  // --- No action if no DigiEvent branch is present
  if (!fDigiEvents) return;

  // --- Clear output arrays
  fT0Digis->clear();
  fStsDigis->clear();
  fRichDigis->clear();
  fMuchDigis->clear();
  fTrdDigis->clear();
  fTofDigis->clear();
  fPsdDigis->clear();

  //fRecoEvents->Clear(); //causes memory leak
  fRecoEvents->Delete();

  // --- Event loop
  Int_t eventNr = 0;
  for (auto& digiEvent : *fDigiEvents) {

    // --- Create CbmEvent object
    CbmEvent* recoEvent = new ((*fRecoEvents)[eventNr]) CbmEvent(eventNr);

    // --- Copy T0 digis
    FillTree<CbmTofDigi>(digiEvent.fData.fT0.fDigis, fT0Digis, recoEvent, ECbmDataType::kT0Digi);

    // --- Copy STS digis
    FillTree<CbmStsDigi>(digiEvent.fData.fSts.fDigis, fStsDigis, recoEvent, ECbmDataType::kStsDigi);
    // --- Copy RICH digis
    FillTree<CbmRichDigi>(digiEvent.fData.fRich.fDigis, fRichDigis, recoEvent, ECbmDataType::kRichDigi);

    // --- Copy MUCH digis
    FillTree<CbmMuchDigi>(digiEvent.fData.fMuch.fDigis, fMuchDigis, recoEvent, ECbmDataType::kMuchDigi);

    // --- Copy TRD digis
    FillTree<CbmTrdDigi>(digiEvent.fData.fTrd.fDigis, fTrdDigis, recoEvent, ECbmDataType::kTrdDigi);

    // --- Copy TOF digis
    FillTree<CbmTofDigi>(digiEvent.fData.fTof.fDigis, fTofDigis, recoEvent, ECbmDataType::kTofDigi);

    // --- Copy PSD digis
    FillTree<CbmPsdDigi>(digiEvent.fData.fPsd.fDigis, fPsdDigis, recoEvent, ECbmDataType::kPsdDigi);

    eventNr++;
  }  //# events

  // --- Timeslice log
  timer.Stop();
  stringstream logOut;
  logOut << setw(20) << left << GetName() << " [";
  logOut << fixed << setw(8) << setprecision(1) << right << timer.RealTime() * 1000. << " ms] ";
  logOut << "TS " << fNumTs << ", events " << fDigiEvents->size() << ", Digis: T0 " << fT0Digis->size() << " STS "
         << fStsDigis->size() << " RICH " << fRichDigis->size() << " MUCH " << fMuchDigis->size() << " TRD "
         << fTrdDigis->size() << " TOF " << fTofDigis->size() << " PSD" << fPsdDigis->size();
  LOG(info) << logOut.str();

  // --- Run statistics
  fNumTs++;
  fTimeTot += timer.RealTime();
  assert(fDigiEvents->size() == static_cast<size_t>(fRecoEvents->GetEntriesFast()));
  fNumEvents += fDigiEvents->size();
}
// ----------------------------------------------------------------------------


// -----   End-of-timeslice action   ------------------------------------------
void CbmTaskMakeRecoEvents::Finish()
{
  LOG(info) << "=====================================";
  LOG(info) << GetName() << ": Run summary";
  LOG(info) << "Timeslices         : " << fNumTs;
  LOG(info) << "Events             : " << fNumEvents;
  LOG(info) << "Time  / TS         : " << fixed << setprecision(2) << 1000. * fTimeTot / double(fNumTs) << " ms";
  LOG(info) << "=====================================";
}
// ----------------------------------------------------------------------------


// -----   Initialisation   ---------------------------------------------------
InitStatus CbmTaskMakeRecoEvents::Init()
{

  LOG(info) << "==================================================";
  LOG(info) << GetName() << ": Initialising ";

  // --- Get FairRootManager instance
  FairRootManager* frm = FairRootManager::Instance();
  assert(frm);

  // --- Try to get input vector (CbmDigiEvent)
  fDigiEvents = frm->InitObjectAs<const std::vector<CbmDigiEvent>*>("DigiEvent");

  // --- If DigiEvents are present, create Digi and CbmEvent branches
  if (fDigiEvents) {
    LOG(info) << GetName() << ": Found branch DigiEvent";

    // --- Event
    if (frm->GetObject("CbmEvent")) {
      LOG(error) << GetName() << ": Found branch CbmEvent! Aborting...";
      return kFATAL;
    }
    fRecoEvents = new TClonesArray("CbmEvent", 1);
    frm->Register("CbmEvent", "Reco events", fRecoEvents, IsOutputBranchPersistent("CbmEvent"));
    if (frm->GetObject("StsDigi")) {
      LOG(error) << GetName() << ": Found branch StsDigi! Aborting...";
      return kFATAL;
    }

    // --- T0 digis
    fT0Digis = new std::vector<CbmTofDigi>;
    frm->RegisterAny("T0Digi", fT0Digis, kFALSE);

    // --- STS digis
    fStsDigis = new std::vector<CbmStsDigi>;
    frm->RegisterAny("StsDigi", fStsDigis, kFALSE);

    // --- RICH digis
    fRichDigis = new std::vector<CbmRichDigi>;
    frm->RegisterAny("RichDigi", fRichDigis, kFALSE);

    // --- MUCH digis
    fMuchDigis = new std::vector<CbmMuchDigi>;
    frm->RegisterAny("MuchDigi", fMuchDigis, kFALSE);

    // --- TRD digis
    fTrdDigis = new std::vector<CbmTrdDigi>;
    frm->RegisterAny("TrdDigi", fTrdDigis, kFALSE);

    // --- TOF digis
    fTofDigis = new std::vector<CbmTofDigi>;
    frm->RegisterAny("TofDigi", fTofDigis, kFALSE);

    // --- PSD digis
    fPsdDigis = new std::vector<CbmPsdDigi>;
    frm->RegisterAny("PsdDigi", fPsdDigis, kFALSE);
  }

  // --- If no DigiEvent branch is present, there must be a CbmEvent branch
  else {
    fRecoEvents = dynamic_cast<TClonesArray*>(frm->GetObject("CbmEvent"));
    if (fRecoEvents == nullptr) {
      LOG(error) << GetName() << ": Neither DigiEvent nor CbmEvent branch found! Aborting...";
      return kFATAL;
    }
  }

  LOG(info) << "==================================================";

  return kSUCCESS;
}
// ----------------------------------------------------------------------------

ClassImp(CbmTaskMakeRecoEvents)