Skip to content
Snippets Groups Projects
Forked from faser / calypso
1225 commits behind the upstream repository.
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
ScintWaveformDecoderTool.cxx 5.07 KiB
/*
  Copyright (C) 2020 CERN for the benefit of the FASER collaboration
*/

#include "ScintWaveformDecoderTool.h"
#include "AthenaBaseComps/AthAlgTool.h"

#include "ScintRawEvent/ScintWaveform.h"
#include "EventFormats/DigitizerDataFragment.hpp"

static const InterfaceID IID_IScintWaveformDecoderTool("ScintWaveformDecoderTool", 1, 0);

const InterfaceID& ScintWaveformDecoderTool::interfaceID() {
  return IID_IScintWaveformDecoderTool;
}

ScintWaveformDecoderTool::ScintWaveformDecoderTool(const std::string& type, 
      const std::string& name,const IInterface* parent)
  : AthAlgTool(type, name, parent)
{
  declareInterface<ScintWaveformDecoderTool>(this);

  declareProperty("CaloChannels", m_caloChannels);
  m_caloChannels.push_back(0);
  m_caloChannels.push_back(1);
  m_caloChannels.push_back(2);
  m_caloChannels.push_back(3);

  declareProperty("VetoChannels", m_vetoChannels);
  m_vetoChannels.push_back(4);
  m_vetoChannels.push_back(5);
  m_vetoChannels.push_back(6);
  m_vetoChannels.push_back(7);

  declareProperty("TriggerChannels", m_triggerChannels);
  m_triggerChannels.push_back(8);
  m_triggerChannels.push_back(9);
  m_triggerChannels.push_back(10);
  m_triggerChannels.push_back(11);

  declareProperty("PreshowerChannels", m_preshowerChannels);
  m_preshowerChannels.push_back(12);
  m_preshowerChannels.push_back(13);

  declareProperty("TestChannels", m_testChannels);
  m_testChannels.push_back(14);

  declareProperty("ClockChannels", m_clockChannels);
  m_clockChannels.push_back(15);

}

ScintWaveformDecoderTool::~ScintWaveformDecoderTool()
{
}

StatusCode
ScintWaveformDecoderTool::initialize() 
{
  ATH_MSG_DEBUG("ScintWaveformDecoderTool::initialize()");
  return StatusCode::SUCCESS;
}

StatusCode
ScintWaveformDecoderTool::finalize() 
{
  ATH_MSG_DEBUG("ScintWaveformDecoderTool::finalize()");
  return StatusCode::SUCCESS;
}
StatusCode
ScintWaveformDecoderTool::convert(const DAQFormats::EventFull* re, 
				  ScintWaveformContainer* container,
				  const std::string key)
{
  ATH_MSG_DEBUG("ScintWaveformDecoderTool::convert("+key+")");

  if (!re) {
    ATH_MSG_ERROR("EventFull passed to convert() is null!");
    return StatusCode::FAILURE;
  }

  if (!container) {
    ATH_MSG_ERROR("ScintWaveformContainer passed to convert() is null!");
    return StatusCode::FAILURE;
  }

  // Find the Waveform fragment
  const DigitizerDataFragment* digitizer = NULL;
  const DAQFormats::EventFragment* frag = NULL;
  for(const auto &id : re->getFragmentIDs()) {
    frag=re->find_fragment(id);

    if ((frag->source_id()&0xFFFF0000) != DAQFormats::SourceIDs::PMTSourceID) continue;
    ATH_MSG_DEBUG("Fragment:\n" << *frag);

    digitizer = new DigitizerDataFragment(frag->payload<const uint32_t*>(), frag->payload_size()); 

    break;
  }

  if (!digitizer) {
    ATH_MSG_WARNING("Failed to find digitizer fragment in raw event!");
    return StatusCode::SUCCESS;
  }

  // Check validity here, try to continue, as perhaps not all channels are bad
  if (!digitizer->valid()) {
    ATH_MSG_WARNING("Found invalid digitizer fragment:\n" << *digitizer);
  } else {
    ATH_MSG_DEBUG("Found valid digitizer fragment");
  }

  std::vector<unsigned int>* channelList;

  if (key == std::string("CaloWaveforms")) {
    channelList = &m_caloChannels;
  } else if (key == std::string("VetoWaveforms")) {
    channelList = &m_vetoChannels;
  } else if (key == std::string("TriggerWaveforms")) {
    channelList = &m_triggerChannels;
  } else if (key == std::string("PreshowerWaveforms")) {
    channelList = &m_preshowerChannels;
  } else if (key == std::string("TestWaveforms")) {
    channelList = &m_testChannels;
  } else if (key == std::string("ClockWaveforms")) {
    channelList = &m_clockChannels;
  } else {
    ATH_MSG_ERROR("Unknown key " << key);
    return StatusCode::FAILURE;
  }

  for (unsigned int channel: *channelList) {
    ATH_MSG_DEBUG("Converting channel "+std::to_string(channel)+" for "+key);

    // Check if this has data
    if (!digitizer->channel_has_data(channel)) {
      ATH_MSG_INFO("Channel " << channel << " has no data - skipping!");
      continue;
    } 

    ScintWaveform* wfm = new ScintWaveform();

    try {
      wfm->setWaveform( channel, digitizer->channel_adc_counts( channel ) );
    } catch ( DigitizerDataException& e ) {
      ATH_MSG_WARNING("ScintWaveformDecoderTool:\n"
		   <<e.what()
		   << "\nChannel "
		   << channel
		   << " not filled!\n");
    }

    try {
      wfm->setHeader( digitizer );

    } catch ( DigitizerDataException& e ) {
      ATH_MSG_WARNING("ScintWaveformDecoderTool:\n"
		      << e.what()
		      << "\nCorrupted Digitizer data!\n"
		      << *frag);
    }

    container->push_back(wfm);    

    // Sanity check
    if (wfm->adc_counts().size() != wfm->n_samples()) {
      ATH_MSG_WARNING("Created waveform channel" << channel << "with length " << wfm->adc_counts().size() << " but header reports n_samples = " << wfm->n_samples() << "!");
      ATH_MSG_WARNING(*wfm);
    }

  }

  // Don't spring a leak
  delete digitizer;

  ATH_MSG_DEBUG( "ScintWaveformDecoderTool created container " << key 
		 << " with size=" << container->size());
  return StatusCode::SUCCESS; 
}