/** * @file SWaveformMerger.cpp * @author Yamiel Abreu, on behalf of the SoLid collaboration. * @date 1 Dec 2016 */ #include "SWaveformMerger.h" //============================================================================== //! Constructor setting up default values. SWaveformMerger::SWaveformMerger(SDetector * dtr, SClipboard * cb) : ISAlgorithm(dtr, cb, "SWaveformMerger"), nMergedWaveforms(0) {} //============================================================================== //! Initialize. void SWaveformMerger::initialize() {} //============================================================================== //! Find waveform spanned in two blocks and merge them as a single waveform. /*! Loop over all channels, then loop over the waveforms on each channel * (note: for this container, they're already time ordered) * If the number of samples between two sequential waveforms (call them wi and wj, wi arrived first) * is equal to the size of wi, then: * Add the samples from wj into wi, delete waveform j, and set pointer to NULL. * * Remove NULL waveforms from all related containers: * SClipboard::waveforms, SChannel::waveforms, SWaveformBlock::waveforms from STimeBlock::waveformblock */ void SWaveformMerger::execute() { for (auto ch : (*dtr()->channels())){ //Loop over detector channels auto wfs = ch->waveforms(); uint totalWFs = wfs->size(); if (totalWFs<2) continue; //Too few waveforms on this channel, at least 2 WFs are needed for merge, if needed //std::cout << "[Note]: Number of initial waveforms: " << totalWFs << std::endl; //For debugging for (uint iWF=0; iWFat(iWF); //Actual waveform auto wfj = wfs->at(iWF+1); //Next waveform as they are ordered in time //Calc number of samples between the two sequential waveforms uint64_t samplesDiff = wfj->time() - wfi->time(); if (samplesDiff == wfi->samples()->size()){ nMergedWaveforms++; //Count merged waveforms //Add samples from wfj to wfi uint wfjSize = wfj->samples()->size(); for (uint i=0; isamples()->emplace_back(wfj->samples()->at(i)); } //Remove samples from merged waveform and delete waveform wfj->samples()->clear(); delete wfj; wfj = NULL; } } } //Remove empty waveforms from containers //Waveforms in clipboard removeReduandantWaveforms(cb()->waveforms()); //Waveforms in detector channels for (auto ch : (*dtr()->channels())){ //!Loop over detector channels removeReduandantWaveforms(ch->waveforms()); } //Waveforms in time blocks for (auto tb : (*cb()->timeblocks())){ //!Loop over time blocks for (auto wb : (*tb->waveformblocks())){ //!Loop over waveform blocks removeReduandantWaveforms(&wb->waveforms); //This can be changed if the waveform() access function is implemented in SWaveformBlock } } } //============================================================================== //! Function to delete NULL waveforms, they were previouly merged int SWaveformMerger::removeReduandantWaveforms(std::vector* wfs) { auto w = wfs->begin(); uint delCount = 0; while (w != wfs->end()) { // Do some stuff if ((*w) == NULL) { w = wfs->erase(w); delCount++; } else { w++; } } return delCount; } //============================================================================== //! Finalize. void SWaveformMerger::finalize() { //Inform about the merged waveforms std::cout << "[Note]: Number waveforms merged: " << nMergedWaveforms << std::endl; } //==============================================================================