Skip to content
Snippets Groups Projects
THcTrigDet.cxx 7.81 KiB
Newer Older
  • Learn to ignore specific revisions
  • /**
    \class THcTrigDet
    \ingroup Detectors
    
    \brief A mock detector to hold trigger related data.
    
    This class behaves as a detector, but it does not correspond to any physical
    detector in the hall. Its purpose is to gather all the trigger related data
    comming from a specific source, like HMS.
    
    
    Can hold up to 100 ADC and TDC channels, though the limit can be changed if
    needed. It just seemed like a reasonable starting value.
    
    # Defined variables
    
    For ADC channels it defines:
      - ADC value: `var_adc`
      - pedestal: `var_adcPed`
      - multiplicity: `var_adcMult`
    
    For TDC channels it defines:
      - TDC value: `var_tdc`
      - multiplicity: `var_tdcMult`
    
    # Parameter file variables
    
    The names and number of channels is defined in a parameter file. The detector
    looks for next variables:
      - `prefix_numAdc = number_of_ADC_channels`
      - `prefix_numTdc = number_of_TDC_channels`
      - `prefix_adcNames = "varName1 varName2 ... varNameNumAdc"`
      - `prefix_tdcNames = "varName1 varName2 ... varNameNumTdc"`
    
    # Map file information
    
    ADC channels must be assigned plane `1` and signal `0` while TDC channels must
    be assigned plane `2` and signal `1`.
    
    Each channel within a plane must be assigned a consecutive "bar" number, which
    is then used to get the correct variable name from parameter file.
    
    Use only with THcTrigApp class.
    
    */
    
    /**
    \fn THcTrigDet::THcTrigDet(
      const char* name, const char* description="",
      THaApparatus* app=NULL)
    
    \brief A constructor.
    
    \param[in] name Name of the apparatus. Is typically named after spectrometer
      whose trigger data is collecting; like "HMS".
    \param[in] description Description of the apparatus.
    \param[in] app The parent apparatus pointer.
    */
    
    /**
    \fn virtual THcTrigDet::~THcTrigDet()
    
    \brief A destructor.
    */
    
    /**
    \fn virtual THaAnalysisObject::EStatus THcTrigDet::Init(const TDatime& date)
    
    \brief Initializes the detector variables.
    
    \param[in] date Time of the current run.
    */
    
    /**
    \fn virtual void THcTrigDet::Clear(Option_t* opt="")
    
    \brief Clears variables before next event.
    
    
    \param[in] opt Maybe used in base clas... Not sure.
    
    */
    
    /**
    \fn Int_t THcTrigDet::Decode(const THaEvData& evData)
    
    \brief Decodes and processes events.
    
    \param[in] evData Raw data to decode.
    */
    
    
    //TODO: Check if fNumAdc < fMaxAdcChannels && fNumTdc < fMaxTdcChannels.
    
    
    #include "THcTrigDet.h"
    
    
    #include <algorithm>
    #include <iostream>
    #include <stdexcept>
    
    
    #include "TDatime.h"
    
    
    #include "THaApparatus.h"
    #include "THaEvData.h"
    
    #include "THcDetectorMap.h"
    #include "THcGlobals.h"
    #include "THcParmList.h"
    #include "THcTrigApp.h"
    #include "THcTrigRawHit.h"
    
    
    THcTrigDet::THcTrigDet() {}
    
    
    THcTrigDet::THcTrigDet(
      const char* name, const char* description, THaApparatus* app
    ) :
      THaDetector(name, description, app), THcHitList(),
      fKwPrefix(""),
      fNumAdc(0), fNumTdc(0), fAdcNames(), fTdcNames(),
    
      fAdcVal(), fAdcPedestal(), fAdcMultiplicity(),
      fTdcVal(), fTdcMultiplicity()
    
    {}
    
    
    THcTrigDet::~THcTrigDet() {}
    
    
    THaAnalysisObject::EStatus THcTrigDet::Init(const TDatime& date) {
      // Call `Setup` before everything else.
      Setup(GetName(), GetTitle());
    
      // Initialize all variables.
    
      for (int i=0; i<fMaxAdcChannels; ++i) fAdcVal[i] = -1.0;
      for (int i=0; i<fMaxTdcChannels; ++i) fTdcVal[i] = -1.0;
    
    
      // Call initializer for base class.
      // This also calls `ReadDatabase` and `DefineVariables`.
      EStatus status = THaDetector::Init(date);
      if (status) {
        fStatus = status;
        return fStatus;
      }
    
      // Initialize hitlist part of the class.
      InitHitList(fDetMap, "THcTrigRawHit", 100);
    
      // Fill in detector map.
      string EngineDID = string(GetApparatus()->GetName()).substr(0, 1) + GetName();
    
      std::transform(EngineDID.begin(), EngineDID.end(), EngineDID.begin(), ::toupper);
    
      if (gHcDetectorMap->FillMap(fDetMap, EngineDID.c_str()) < 0) {
        static const char* const here = "Init()";
        Error(Here(here), "Error filling detectormap for %s.", EngineDID.c_str());
        return kInitError;
      }
    
      fStatus = kOK;
      return fStatus;
    }
    
    
    void THcTrigDet::Clear(Option_t* opt) {
    
      THaAnalysisObject::Clear(opt);
    
    
      // Reset all data.
    
      for (int i=0; i<fNumAdc; ++i) fAdcVal[i] = 0.0;
      for (int i=0; i<fNumTdc; ++i) fTdcVal[i] = 0.0;
    
    }
    
    
    Int_t THcTrigDet::Decode(const THaEvData& evData) {
      // Decode raw data for this event.
      Int_t numHits = DecodeToHitList(evData);
    
      // Process each hit and fill variables.
      Int_t iHit = 0;
      while (iHit < numHits) {
        THcTrigRawHit* hit = dynamic_cast<THcTrigRawHit*>(fRawHitList->At(iHit));
    
    
        if (hit->fPlane == 1) {
          fAdcVal[hit->fCounter-1] = hit->GetData(0, 0);
          fAdcPedestal[hit->fCounter-1] = hit->GetAdcPedestal(0);
          fAdcMultiplicity[hit->fCounter-1] = hit->GetMultiplicity(0);
        }
        else if (hit->fPlane == 2) {
          fTdcVal[hit->fCounter-1] = hit->GetData(1, 0);
          fTdcMultiplicity[hit->fCounter-1] = hit->GetMultiplicity(1);
        }
    
        else {
          throw std::out_of_range(
            "`THcTrigDet::Decode`: only planes `1` and `2` available!"
          );
        }
    
        ++iHit;
      }
    
      return 0;
    }
    
    
    void THcTrigDet::Setup(const char* name, const char* description) {
      // Prefix for parameters in `param` file.
      string kwPrefix = string(GetApparatus()->GetName()) + "_" + name;
    
      std::transform(kwPrefix.begin(), kwPrefix.end(), kwPrefix.begin(), ::tolower);
    
      fKwPrefix = kwPrefix;
    }
    
    
    Int_t THcTrigDet::ReadDatabase(const TDatime& date) {
      std::string adcNames, tdcNames;
    
      DBRequest list[] = {
        {"_numAdc", &fNumAdc, kInt},  // Number of ADC channels.
        {"_numTdc", &fNumTdc, kInt},  // Number of TDC channels.
        {"_adcNames", &adcNames, kString},  // Names of ADC channels.
        {"_tdcNames", &tdcNames, kString},  // Names of TDC channels.
        {0}
      };
      gHcParms->LoadParmValues(list, fKwPrefix.c_str());
    
      // Split the names to std::vector<std::string>.
      fAdcNames = vsplit(adcNames);
      fTdcNames = vsplit(tdcNames);
    
      return kOK;
    }
    
    
    Int_t THcTrigDet::DefineVariables(THaAnalysisObject::EMode mode) {
      if (mode == kDefine && fIsSetup) return kOK;
      fIsSetup = (mode == kDefine);
    
      std::vector<RVarDef> vars;
    
    
      //Push the variable names for ADC channels.
      std::vector<TString> adcValTitle(fNumAdc), adcValVar(fNumAdc);
      std::vector<TString> adcPedestalTitle(fNumAdc), adcPedestalVar(fNumAdc);
      std::vector<TString> adcMultiplicityTitle(fNumAdc), adcMultiplicityVar(fNumAdc);
    
    
      for (int i=0; i<fNumAdc; ++i) {
    
        adcValTitle.at(i) = fAdcNames.at(i) + "_adc";
        adcValVar.at(i) = TString::Format("fAdcVal[%d]", i);
        vars.push_back({
          adcValTitle.at(i).Data(),
          adcValTitle.at(i).Data(),
          adcValVar.at(i).Data()
        });
    
        adcPedestalTitle.at(i) = fAdcNames.at(i) + "_adcPed";
        adcPedestalVar.at(i) = TString::Format("fAdcPedestal[%d]", i);
        vars.push_back({
          adcPedestalTitle.at(i).Data(),
          adcPedestalTitle.at(i).Data(),
          adcPedestalVar.at(i).Data()
        });
    
        adcMultiplicityTitle.at(i) = fAdcNames.at(i) + "_adcMult";
        adcMultiplicityVar.at(i) = TString::Format("fAdcMultiplicity[%d]", i);
    
        vars.push_back({
    
          adcMultiplicityTitle.at(i).Data(),
          adcMultiplicityTitle.at(i).Data(),
          adcMultiplicityVar.at(i).Data()
    
      // Push the variable names for TDC channels.
    
      std::vector<TString> tdcValTitle(fNumTdc), tdcValVar(fNumTdc);
      std::vector<TString> tdcMultiplicityTitle(fNumTdc), tdcMultiplicityVar(fNumTdc);
    
      for (int i=0; i<fNumTdc; ++i) {
    
        tdcValTitle.at(i) = fTdcNames.at(i) + "_tdc";
        tdcValVar.at(i) = TString::Format("fTdcVal[%d]", i);
        vars.push_back({
          tdcValTitle.at(i).Data(),
          tdcValTitle.at(i).Data(),
          tdcValVar.at(i).Data()
        });
    
        tdcMultiplicityTitle.at(i) = fTdcNames.at(i) + "_tdcMult";
        tdcMultiplicityVar.at(i) = TString::Format("fTdcMultiplicity[%d]", i);
    
        vars.push_back({
    
          tdcMultiplicityTitle.at(i).Data(),
          tdcMultiplicityTitle.at(i).Data(),
          tdcMultiplicityVar.at(i).Data()
    
        });
      }
    
      vars.push_back({0});
    
      return DefineVarsFromList(vars.data(), mode);
    }
    
    
    ClassImp(THcTrigDet)