49 #include "TTimeStamp.h" 66 using std::istringstream;
67 using std::ostringstream;
145 const Name myname =
"DataPrepByApaModule::ctor: ";
153 cout << myname <<
"Module will not produce RDTimeStamps." <<
endl;
161 cout << myname <<
"Module will not produce RawDigits." <<
endl;
169 cout << myname <<
"Module will not produce Wires." <<
endl;
187 const string myname =
"DataPrepByApaModule::reconfigure: ";
205 cout << myname <<
" DecoderTool: " << m_DecoderTool <<
endl;
206 cout << myname <<
" OutputTimeStampName: " << m_OutputTimeStampName <<
endl;
207 cout << myname <<
" OutputDigitName: " << m_OutputDigitName <<
endl;
208 cout << myname <<
" OutputWireName: " << m_OutputWireName <<
endl;
209 cout << myname <<
" ChannelGroups: [";
211 for (
Name rnam : m_ChannelGroups ) {
212 if ( first ) first =
false;
217 cout << myname <<
" BeamEventLabel: " << m_BeamEventLabel <<
endl;
219 cout << myname <<
" KeepChannels: " <<
"[";
222 if ( first ) first =
false;
227 cout << myname <<
" SkipChannels: " <<
"[";
230 if ( first ) first =
false;
235 cout << myname <<
" SkipEmptyChannels: " << (m_SkipEmptyChannels ?
"true" :
"false") << endl;
236 cout << myname <<
" DeltaTickCount: " << m_DeltaTickCount <<
endl;
237 cout << myname <<
" ApaChannelCounts: " <<
"[";
240 if ( first ) first =
false;
250 cout << myname <<
"WARNING: Channel status provider not found." <<
endl;
256 if ( ptm ==
nullptr ) {
257 cout << myname <<
"ERROR: Unable to retrieve tool manager." <<
endl;
259 if ( m_DecoderTool.size() ) {
262 cout << myname <<
"ERROR: Decoder tool not found: " << m_DecoderTool <<
endl;
270 if ( pcrt ==
nullptr ) {
271 cout << myname <<
"ERROR: Channel range tool channelRanges not found." <<
endl;
275 if ( pcgt ==
nullptr ) {
276 cout << myname <<
"WARNING: Channel group tool channelGroups not found." <<
endl;
282 bool useGroups = pcgt !=
nullptr;
284 for (
Name groupName : m_ChannelGroups ) {
286 if ( useGroups ) grp = pcgt->
get(groupName);
289 rangeNames.push_back(ran.
name);
292 rangeNames.push_back(groupName);
298 for (
Index icha : m_SkipChannels ) skipChans.insert(icha);
300 for (
Index icha : m_KeepChannels ) keepChans.insert(icha);
305 for (
Name crn : rangeNames ) {
308 if ( crn ==
"all" ) {
314 }
else if ( crn.substr(0,2) ==
"cr" ) {
317 string::size_type ipos = string::npos;
318 if ( crn.substr(0,3) ==
"apa" ) ipos = 3;
319 if ( crn.substr(0,4) ==
"femb" ) ipos = 4;
320 if ( ipos == string::npos ) {
321 cout << myname <<
"WARNING: Skipping no-APA channel range: " << crn <<
endl;
324 std::istringstream ssapa(crn.substr(ipos,1));
335 cout << myname <<
"WARNING: No channels taken from invalid channel range " << ran.
name <<
endl;
336 cout << myname <<
"WARNING: Note that channel ranges are defined by tool channelRanges." <<
endl;
341 bool keep = (keepChans.size() == 0 || keepChans.count(icha)) && skipChans.count(icha) == 0;
345 nchaAll = ran.
size();
353 cout << myname <<
"WARNING: No channels will be processed." <<
endl;
355 cout << myname <<
"The following APAs will be processed." <<
endl;
356 cout << myname <<
"-------------------------------------" <<
endl;
357 cout << myname <<
" APA # chan Channel ranges" <<
endl;
358 for ( ApaChannelSetMap::value_type iapa :
m_apachsets ) {
359 cout << myname <<
setw(4);
360 if ( iapa.first == -1 ) cout <<
"all";
361 else cout << iapa.first;
362 cout <<
setw(9) << iapa.second.size() <<
" {";
365 if ( first ) first =
false;
371 cout << myname <<
"-------------------------------------" <<
endl;
378 if ( m_ApaChannelCounts.size() == 0 ) {
379 cout << myname <<
"WARNING: No APA channel counts have been provided. Using " << nchaDefault <<
endl;
381 nchaDefault = m_ApaChannelCounts.back();
383 for (
const ApaChannelSetMap::value_type& csmPair :
m_apachsets ) {
384 int iapaSigned = csmPair.first;
386 if ( iapaSigned >= 0 ) {
387 Index iapa = iapaSigned;
388 nchaApa = iapa < m_ApaChannelCounts.size() ? m_ApaChannelCounts[iapa] : nchaDefault;
391 nchaOut += csmPair.second.size();
397 cout << myname <<
" Max # read channels: " << nchaIn <<
endl;
398 cout << myname <<
" Max # processed channels: " << nchaOut <<
endl;
408 const string myname =
"DataPrepByApaModule::beginJob: ";
417 const string myname =
"DataPrepByApaModule::endJob: ";
419 cout << myname <<
"# events processed: " <<
m_nproc <<
endl;
420 cout << myname <<
" # events skipped: " <<
m_nskip <<
endl;
427 const string myname =
"DataPrepByApaModule::produce: ";
433 unsigned long triggerPerTick = 25;
436 bool skipAllEvents =
false;
437 bool skipEventsWithCorruptDataDropped =
false;
442 int itimrem = beginTime.
timeLow();
444 if ( itim == 0 && itimrem != 0 ) {
451 cout << myname <<
"Run " << evt.
run();
453 cout <<
", event " << evt.
event();
459 TTimeStamp rtim(itim, itimrem);
460 string stim =
string(rtim.AsString(
"s")) +
" UTC";
461 cout << myname <<
"Real data event time: " << itim <<
" (" << stim <<
")" <<
endl;
467 cout << myname <<
"Event time high, low: " << beginTime.
timeHigh() <<
", " << beginTime.
timeLow() <<
endl;
473 using TimeStampVector = std::vector<raw::RDTimeStamp>;
474 const TimeStampVector* ptims =
nullptr;
477 auto htims = evt.
getHandle<TimeStampVector>(itag1);
480 if ( ptims->size() == 0 ) {
481 cout << myname <<
"No timing clocks found." <<
endl;
482 for (
unsigned int itim=0; itim<ptims->size() && itim<50; ++itim ) {
483 cout << myname <<
" " << ptims->at(itim).GetTimeStamp() <<
endl;
485 }
else if ( ptims->size() > 1 ) {
486 cout << myname <<
"ERROR: Too many timing clocks: " << ptims->size() <<
endl;
487 for (
unsigned int itim=0; itim<ptims->size() && itim<50; ++itim ) {
488 cout << myname <<
" " << ptims->at(itim).GetTimeStamp() <<
endl;
492 if ( logInfo ) cout << myname <<
"Timing clock: " << tim.
GetTimeStamp() <<
endl;
496 if (
m_LogLevel >= 2 ) cout << myname <<
"Trigger flag: " << trigFlag <<
" (";
497 bool isBeam = trigFlag == 0xc;
498 bool isCrt = trigFlag == 13;
499 bool isFake = trigFlag >= 0x8 && trigFlag <= 0xb;
501 if ( isBeam ) cout <<
"Beam";
502 else if ( isCrt ) cout <<
"CRT";
503 else if ( isFake ) cout <<
"Fake";
504 else cout <<
"Unexpected";
510 cout << myname <<
"WARNING: Event timing clocks product not found." <<
endl;
518 std::vector< art::Ptr<beam::ProtoDUNEBeamEvent> > beaminfo;
520 if ( pdbeamHandle ) {
522 if ( beaminfo.size() == 0 ) {
523 cout << myname <<
"WARNING: Beam event vector is empty." <<
endl;
525 if ( beaminfo.size() > 1 ) {
526 cout << myname <<
"WARNING: Beam event vector has size " << beaminfo.size() <<
endl;
528 AdcIndex beamTrigFlag = beaminfo[0]->GetTimingTrigger();
529 if ( beamTrigFlag != trigFlag ) {
530 if ( logInfo ) cout << myname <<
"Beam event and timing trigger flags differ: " << beamTrigFlag <<
" != " << trigFlag <<
endl;
531 }
else if ( beamTrigFlag != 12 ) {
532 if ( logInfo ) cout << myname <<
"Beam event trigger is not beam: it is " << beamTrigFlag <<
endl;
535 }
else if ( beaminfo[0]->GetTOFChan() == -1 ) {
536 if ( logInfo ) cout << myname <<
"Beam event does not have a TOF match." <<
endl;
538 int beamChan = beaminfo[0]->GetTOFChan();
539 beamTof = beaminfo[0]->GetTOF();
540 if ( logInfo ) cout << myname <<
"Beam event TOF[" << beamChan <<
"]: " << beamTof <<
endl;
542 const std::vector<double>& momenta = beaminfo[0]->GetRecoBeamMomenta();
544 cout << myname <<
"Beam momenta:";
545 for (
double pval : momenta ) cout <<
" " <<
pval;
550 if ( logInfo ) cout << myname <<
"Beam event data product not found: " <<
m_BeamEventLabel <<
endl;
555 using DigitVector = std::vector<raw::RawDigit>;
556 std::unique_ptr<DigitVector> pdigitsAll;
558 pdigitsAll.reset(
new DigitVector);
561 std::unique_ptr<TimeStampVector> ptimsAll;
563 ptimsAll.reset(
new TimeStampVector);
567 std::unique_ptr<std::vector<recob::Wire>> pwires;
572 using StatVector = std::vector<raw::RDStatus>;
573 std::unique_ptr<StatVector> pstatusAll;
575 pstatusAll.reset(
new StatVector);
589 if ( bstat ) cout << myname <<
"WARNING: Event initialization failed." <<
endl;
594 if ( ptm ==
nullptr ) {
595 cout << myname <<
"ERROR: Tool manager not found." <<
endl;
599 if ( pcrt ==
nullptr ) {
600 cout << myname <<
"ERROR: Channel range tool channelRanges not found." <<
endl;
605 for (
const ApaChannelSetMap::value_type& csmPair :
m_apachsets ) {
606 int iapa = csmPair.first;
611 ssapa <<
"APA " << iapa;
613 Name sapa = ssapa.str();
614 std::vector<int> apas = {iapa};
616 if ( logInfo ) cout << myname <<
"Fetching digits and clocks for " << sapa <<
"." <<
endl;
617 using StatVector = std::vector<raw::RDStatus>;
618 TimeStampVector timsCrn;
620 DigitVector digitsCrn;
623 retrieveDataForSpecifiedAPAs(evt, digitsCrn, timsCrn, statsCrn, apas);
625 cout << myname <<
"INFO: Decoder tool for APA " << iapa <<
" returned " << decodeStat <<
endl;
628 cout << myname <<
" " << sapa <<
" digit count from tool: " << digitsCrn.size() <<
endl;
629 cout << myname <<
" " << sapa <<
" stats count from tool: " << statsCrn.size() <<
endl;
630 cout << myname <<
" " << sapa <<
" clock count from tool: " << timsCrn.size() <<
endl;
634 bool skipEvent = skipAllEvents;
635 if ( statsCrn.size() != 1 ) cout << myname <<
"WARNING: Read status has unexpected size: " 636 << statsCrn.size() <<
endl;
637 const RDStatus rdstat = statsCrn.at(0);
639 cout << myname <<
"Raw data status: " << rdstat.
GetStatWord();
648 vector<AdcLongIndex> channelClocks;
649 vector<ULong64_t> tzeroClockCandidates;
650 float trigTickOffset = -500.5;
651 using ClockCounter = std::map<ULong64_t, AdcIndex>;
652 using ClockDiffs = std::map<ULong64_t, long>;
653 using ClockTickDiffs = std::map<ULong64_t, float>;
654 using ClockMessages = std::map<ULong64_t, Name>;
655 using NtickCounter = std::map<AdcIndex, AdcIndex>;
656 ClockCounter clockCounts;
657 ClockDiffs clockDiffs;
658 ClockTickDiffs tickDiffs;
659 ClockMessages clockMessages;
660 NtickCounter ntickCounter;
661 ULong64_t chClock = 0;
662 ULong64_t maxdiff = 99999999;
663 float tickdiff = maxdiff;
665 unsigned int ntim = timsCrn.size();
666 unsigned int ndigi = digitsCrn.size();
667 if ( ntim > 0 && ntim != ndigi ) {
668 cout <<
"ERROR: Channel clock count differs from digit count: " << ntim <<
" !' " << ndigi <<
endl;
671 for (
unsigned int idig=0; idig<ntim; ++idig ) {
675 if ( ntickCounter.count(ntick) == 0 ) ntickCounter[ntick] = 1;
676 else ++ntickCounter[ntick];
682 channelClocks.push_back(chClock);
683 bool sign = chClock > timingClock;
684 ULong64_t chClockAbsDiff = sign ? chClock - timingClock
685 : timingClock - chClock;
686 bool badDiff = chClockAbsDiff > maxdiff;
687 if ( badDiff ) chClockAbsDiff = maxdiff;
688 long chClockDiff = sign ? chClockAbsDiff : -chClockAbsDiff;
689 tickdiff = chClockDiff/triggerPerTick;
690 bool nearTrigger = fabs(tickdiff - trigTickOffset) < 1.0;
691 if ( clockCounts.find(chClock) == clockCounts.end() ) {
692 clockCounts[chClock] = 1;
693 clockDiffs[chClock] = chClockDiff;
694 tickDiffs[chClock] = tickdiff;
696 if ( chClock == 0 ) msg =
"Channel clock is zero.";
697 else if ( badDiff ) msg =
"Channel clock is very far from timing clock.";
698 clockMessages[chClock] =
msg;
699 if ( nearTrigger ) tzeroClockCandidates.push_back(chClock);
701 ++clockCounts[chClock];
703 if ( ! nearTrigger && timingClock != 0 ) {
705 cout << myname <<
"WARNING: Channel timing difference: " << chClockDiff
706 <<
" (" << tickdiff <<
" ticks)." <<
endl;
710 if ( clockCounts.size() > 1 ) {
712 cout << myname <<
"WARNING: Channel clocks for " << sapa <<
" are not consistent." <<
endl;
713 cout << myname <<
"WARNING: Clock ticks count" <<
endl;
714 for ( ClockCounter::value_type iclk : clockCounts ) {
715 ULong64_t chClock = iclk.first;
717 long chClockDiff = clockDiffs[chClock];
718 float tickdiff = tickDiffs[chClock];
719 Name msg = clockMessages[chClock];
721 cout << myname <<
"WARNING:" <<
setw(10) << chClockDiff <<
setw(10) << tickdiff
723 if ( msg.size() ) cout <<
" " << msg;
728 cout << myname <<
"WARNING: No ADC samples:" <<
setw(8) << nskipEmpty <<
endl;
731 }
else if ( clockCounts.size() == 1 ) {
733 cout << myname <<
"Channel clocks for " << sapa <<
" are consistent with an offset of " 734 << tickdiff <<
" ticks";
735 if ( nskipEmpty ) cout <<
" (" << nskipEmpty <<
" channels skipped)";
738 }
else if ( ntim > 0 ) {
740 if ( logInfo ) cout << myname <<
"WARNING: Channel clocks not found." <<
endl;
745 for ( NtickCounter::value_type ent : ntickCounter ) {
746 if ( ent.second > nchanMaxCount ) {
747 ntickMaxCount = ent.first;
748 nchanMaxCount = ent.second;
751 AdcIndex ntickPrimary = ntickMaxCount;
756 minTickCount = ntickPrimary;
757 maxTickCount = ntickPrimary;
761 minTickCount = tcmin > 0.0 ? tcmin : 0;
762 maxTickCount = tcmax > 0.0 ? tcmax : 0;
763 cout << myname <<
"Allowed tick count range is (" << minTickCount <<
", " << maxTickCount <<
")" <<
endl;
767 if ( maxTickCount > 0 ) {
769 while ( ient != ntickCounter.end() ) {
771 if ( ntick < minTickCount || ntick > maxTickCount ) {
772 ient = ntickCounter.erase(ient);
779 if ( logInfo && ntickCounter.size() ) {
780 if ( ntickCounter.size() == 1 ) {
781 cout << myname <<
"Tick count for all channels is " << ntickCounter.begin()->first <<
endl;
785 cout << myname << slev <<
"Retaining inconsistent tick counts:" <<
endl;
786 cout << myname << slev <<
" Ntick Nchan" <<
endl;
787 for ( NtickCounter::value_type ent : ntickCounter ) {
788 cout << myname << slev <<
setw(8) << ent.first <<
setw(8) << ent.second <<
endl;
795 cout << myname <<
"# digits read for " << sapa <<
": " << digitsCrn.size() <<
endl;
799 unsigned int nproc = 0;
800 unsigned int nkeep = 0;
801 unsigned int nskip = 0;
802 unsigned int nempty = 0;
803 unsigned int nbadtc = 0;
804 for (
unsigned int idig=0; idig<ndigi; ++idig ) {
807 if ( csmKeepChans.count(chan) == 0 ) {
821 if ( maxTickCount > minTickCount ) {
822 if ( ntick < minTickCount || ntick > maxTickCount ) {
830 if ( ! its.second ) {
831 cout << myname <<
"ERROR: Ignoring duplicate digit for channel " << chan <<
"." <<
endl;
850 fembChannel = ichOn % 128;
858 if ( channelClocks.size() > idig ) {
868 cout << myname <<
" " << sapa <<
" # input digits: " << ndigi <<
endl;
869 cout << myname <<
" " << sapa <<
" # channels selected: " << nkeep;
872 cout << myname <<
" " << sapa <<
" # channels skipped: " << nskip;
873 bool havebad =
false;
875 cout <<
" (" << nempty <<
" empty";
879 cout << (havebad ?
", " :
" (") << nbadtc <<
" bad tick count";
882 if ( havebad ) cout <<
")";
884 cout << myname <<
" " << sapa <<
" # channels to be processed: " << nproc <<
endl;
887 Index nacd = datamap.size();
890 if ( logInfo ) cout << myname <<
"Skipping empty data map." <<
endl;
897 WireVector* pwiresCrn = pwires ? pwires.get() : &wiresTmp;
901 cout << myname <<
"Preparing " << nacd <<
" channel" << (nacd == 1 ?
"" :
"s") <<
"." << endl;
905 cout << myname <<
"ERROR: Data preparation service returned error " << rstat;
910 if ( pdigitsAll )
for (
raw::RawDigit& dig : digitsCrn ) pdigitsAll->emplace_back(dig);
911 if ( ptimsAll )
for (
raw::RDTimeStamp& tst : timsCrn ) ptimsAll->emplace_back(tst);
918 if ( estat ) cout << myname <<
"WARNING: Event finalization failed." <<
endl;
922 if ( logInfo ) cout << myname <<
"Created wire count: " << pwires->size() <<
endl;
923 if ( pwires->size() == 0 ) cout << myname <<
"WARNING: No wires made for this event." << endl;
926 if ( logInfo ) cout << myname <<
"Wire output was not requested." <<
endl;
932 if ( logInfo ) cout << myname <<
"Created digit count: " << pdigitsAll->size() <<
endl;
935 cout << myname <<
"WARNING: Digits are not written because container was not created." <<
endl;
938 if ( logInfo ) cout << myname <<
"Digit output was not requested." <<
endl;
943 if ( logInfo ) cout << myname <<
"Created time stamp count: " << ptimsAll->size() <<
endl;
946 cout << myname <<
"WARNING: Output time stamp container was not created." <<
endl;
949 if ( logInfo ) cout << myname <<
"Time stamp output was not requested." <<
endl;
954 if ( logInfo ) cout << myname <<
"Created digit count: " << pstatusAll->size() <<
endl;
957 cout << myname <<
"WARNING: Output status container was not created." <<
endl;
960 if ( logInfo ) cout << myname <<
"Status output was not requested." <<
endl;
virtual bool IsBad(raw::ChannelID_t channel) const =0
Returns whether the specified channel is bad in the current run.
void reconfigure(fhicl::ParameterSet const &p)
void produce(art::Event &evt)
constexpr std::uint32_t timeLow() const
EventNumber_t event() const
ULong64_t Samples() const
Number of samples in the uncompressed ADC data.
uint16_t GetFlags() const
Collection of charge vs time digitized from a single readout channel.
void msg(const char *fmt,...)
const AdcIndex AdcChannelStatusNoisy
static std::string toString(art::Timestamp tart)
Handle< PROD > getHandle(SelectorBase const &) const
virtual bool IsNoisy(raw::ChannelID_t channel) const =0
Returns whether the specified channel is noisy in the current run.
EDProducer(fhicl::ParameterSet const &pset)
constexpr std::uint32_t timeHigh() const
ChannelID_t Channel() const
DAQ channel this raw data was read from.
AdcChannelVector m_SkipChannels
std::shared_ptr< const EventInfo > EventInfoPtr
const raw::RawDigit * digit
virtual int prepare(detinfo::DetectorClocksData const &clockData, AdcChannelDataMap &prepdigs, std::vector< recob::Wire > *pwires=nullptr, WiredAdcChannelDataMap *pwiredData=nullptr) const =0
std::vector< AdcChannel > AdcChannelVector
std::vector< Name > NameVector
std::unique_ptr< IndexMapTool > m_onlineChannelMapTool
AdcChannelVector m_KeepChannels
std::string m_OnlineChannelMapTool
bool GetCorruptDataDroppedFlag() const
std::unique_ptr< PDSPTPCDataInterfaceParent > m_pDecoderTool
void setChannelInfo(ChannelInfoPtr pchi)
std::set< Index > ApaChannelSet
std::map< int, ApaChannelSet > ApaChannelSetMap
#define DEFINE_ART_MODULE(klass)
const lariov::ChannelStatusProvider * m_pChannelStatusProvider
std::map< int, NameVector > ApaNamesMap
std::string m_BeamEventLabel
Name m_OutputTimeStampName
T get(std::string const &key) const
void setEventInfo(EventInfoPtr pevi)
RawDigitPrepService * m_pRawDigitPrepService
SubRunNumber_t subRun() const
ProductID put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
Class providing information about the quality of channels.
NameVector m_ChannelGroups
Name m_OutputWireName
Second field in full label for the output wire container.
ULong64_t GetTimeStamp() const
Q_EXPORT QTSManip setw(int w)
Index m_maxOutputDigitChannelCount
virtual int beginEvent(const DuneEventInfo &) const
std::string m_DigitProducer
unsigned long AdcLongIndex
std::vector< art::Ptr< recob::Wire > > WireVector
std::optional< T > get_if_present(std::string const &key) const
const AdcIndex AdcChannelStatusGood
virtual int endEvent(const DuneEventInfo &) const
AdcLongIndex channelClock
Index m_maxOutputWireChannelCount
Interface for experiment-specific channel quality info provider.
bool GetCorruptDataKeptFlag() const
AdcChannelVector m_ApaChannelCounts
Declaration of basic channel signal object.
std::map< AdcChannel, AdcChannelData > AdcChannelDataMap
const AdcIndex AdcChannelStatusBad
void fill_ptr_vector(std::vector< Ptr< T >> &ptrs, H const &h)
Interface for experiment-specific service for channel quality info.
ApaChannelSetMap m_apachsets
Index m_maxOutputTimeStampChannelCount
unsigned int GetStatWord() const
std::string to_string(ModuleType const mt)
DataPrepByApaModule(fhicl::ParameterSet const &pset)
QTextStream & endl(QTextStream &s)