Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CaloDataVerifier improved #18

Merged
merged 2 commits into from
Dec 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
302 changes: 190 additions & 112 deletions otsdaq-mu2e-calorimeter/ArtModules/CaloDataVerifier_module.cc
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@ namespace mu2e {
(static_cast<long int>(ewt[2]) << 32);
return eventWindow;
}

artdaq::Fragments getFragments(art::Event& event);
void processCaloData(mu2e::DTCEventFragment& eventFragment, std::unique_ptr<std::vector<mu2e::CalorimeterDataDecoder>> const& caloDecoderColl);

bool checkAndUpdateDTCEWT(const DTCLib::DTC_SubEvent& subevent);
bool checkAndUpdateROCEWT(const DTCLib::DTC_DataBlock& dataBlock);


private:
Expand All @@ -58,6 +64,12 @@ namespace mu2e {
bool produceCaloDecoders_;
DTCLib::DTC_Subsystem subsystem_;
bool isFirstEvent_;

std::map<int, int> lastDTCEventWindow;
std::map<int, std::map<int, int>> lastROCEventWindow;

size_t nCaloEvents;
size_t nCaloHits;
};
} // namespace mu2e

Expand All @@ -77,6 +89,8 @@ mu2e::CaloDataVerifier::CaloDataVerifier(const art::EDFilter::Table<Config>& con
if (produceCaloDecoders_) {
produces<std::vector<mu2e::CalorimeterDataDecoder>>();
}

TLOG(TLVL_DEBUG) << "Reading data type " << data_type_;
}

bool mu2e::CaloDataVerifier::filter(art::Event& event){
Expand All @@ -87,6 +101,39 @@ bool mu2e::CaloDataVerifier::filter(art::Event& event){
//Prepare vector of output data decoders
std::unique_ptr<std::vector<mu2e::CalorimeterDataDecoder>> caloDecoderColl(new std::vector<mu2e::CalorimeterDataDecoder>);

nCaloEvents = 0;
nCaloHits = 0;

artdaq::Fragments fragments = getFragments(event);
TLOG(TLVL_DEBUG) << "Iterating through " << fragments.size() << " fragments\n";
for (const auto& frag : fragments) {
mu2e::DTCEventFragment eventFragment(frag);
processCaloData(eventFragment, caloDecoderColl);
}

TLOG(TLVL_DEBUG) << "[CaloDataVerifier::filter] found " << nCaloEvents << " calo subevents in event" << (int)eventNumber;
TLOG(TLVL_DEBUG) << "[CaloDataVerifier::filter] found " << nCaloHits << " calo hits in event" << (int)eventNumber;

if (nCaloEvents == 0) {
TLOG(TLVL_WARNING) << "[CaloDataVerifier::filter] found no calo subevents in event" << (int)eventNumber << "!";
}
if (produceCaloDecoders_) {
event.put(std::move(caloDecoderColl));
}

TLOG(TLVL_INFO) << "mu2e::CaloDataVerifier::filter exiting eventNumber=" << (int)eventNumber;
return true;
}


bool mu2e::CaloDataVerifier::endRun( art::Run& ) {
return true;
}




artdaq::Fragments mu2e::CaloDataVerifier::getFragments(art::Event& event){
artdaq::Fragments fragments;
artdaq::FragmentPtrs containerFragments;

Expand Down Expand Up @@ -119,137 +166,168 @@ bool mu2e::CaloDataVerifier::filter(art::Event& event){
}
}
}
return fragments;
}

size_t nCaloEvents(0);
size_t nCaloHits(0);
void mu2e::CaloDataVerifier::processCaloData(mu2e::DTCEventFragment& eventFragment, std::unique_ptr<std::vector<mu2e::CalorimeterDataDecoder>> const& caloDecoderColl){

TLOG(TLVL_DEBUG) << "Iterating through " << fragments.size() << " fragments\n";
for (const auto& frag : fragments) {
mu2e::DTCEventFragment eventFragment(frag);
DTCLib::DTC_Event dtcevent = eventFragment.getData();
//DTCLib::DTC_EventHeader* eventHeader = dtcevent.GetHeader();
std::vector<DTCLib::DTC_SubEvent> subevents = dtcevent.GetSubEvents();
TLOG(TLVL_DEBUG) << "Found " << subevents.size() << " total subevents\n";

DTCLib::DTC_Event dtcevent = eventFragment.getData();
//DTCLib::DTC_EventHeader* eventHeader = dtcevent.GetHeader();
std::vector<DTCLib::DTC_SubEvent> subevents = dtcevent.GetSubEvents();
TLOG(TLVL_DEBUG) << "Found " << subevents.size() << " total subevents\n";

auto caloSubEvents = eventFragment.getSubsystemData(subsystem_);
TLOG(TLVL_DEBUG) << "Iterating through " << caloSubEvents.size() << " calorimeter subevents\n";
for (const auto& subevent : caloSubEvents) {

// Retrieve the calo DTC header
const DTCLib::DTC_SubEventHeader* caloEvent_header = subevent.GetHeader();
TLOG(TLVL_DEBUG) << "Calo subevent header:\n" << caloEvent_header->toJson();
uint64_t dtcID = caloEvent_header->source_dtc_id;

mu2e::CalorimeterDataDecoder caloDecoder(subevent);
if (produceCaloDecoders_) {
caloDecoderColl->emplace_back(caloDecoder);
}
nCaloEvents++;

// Iterate over the data blocks (ROCs)
std::vector<DTCLib::DTC_DataBlock> dataBlocks = subevent.GetDataBlocks();
uint nROCs = dataBlocks.size();
TLOG(TLVL_DEBUG) << "Iterating through " << nROCs << " data blocks (ROCs)\n";
for (uint iroc = 0; iroc < nROCs; iroc++){
// print the data block header
DTCLib::DTC_DataHeaderPacket* dataHeader = dataBlocks[iroc].GetHeader().get();
TLOG(TLVL_DEBUG) << dataHeader->toJSON() << std::endl;

if (data_type_ == 0){ // STANDARD HITS

auto caloHits = caloDecoder.GetCalorimeterHitData(iroc);
uint nHits = caloHits->size();
TLOG(TLVL_INFO) << "There are " << nHits << " hits in DTC " << dtcID << " ROC " << iroc << " / " << nROCs << std::endl;
for (uint ihit = 0; ihit<nHits; ihit++){
mu2e::CalorimeterDataDecoder::CalorimeterHitDataPacket hit = caloHits->at(ihit).first;
std::vector<uint16_t> hit_waveform = caloHits->at(ihit).second;
if (hit_waveform.size() == 0){
TLOG(TLVL_WARNING) << "[CaloDataVerifier::filter] found empty waveform! DTC " << dtcID << " ROC " << iroc << " hit " << ihit
<< " BoardID " << hit.BoardID << " ChannelNumber " << hit.ChannelNumber;
}
nCaloHits++;
auto caloSubEvents = eventFragment.getSubsystemData(subsystem_);
TLOG(TLVL_DEBUG) << "Iterating through " << caloSubEvents.size() << " calorimeter subevents\n";
for (const auto& subevent : caloSubEvents) {

checkAndUpdateDTCEWT(subevent);
uint64_t dtcID = subevent.GetDTCID();

mu2e::CalorimeterDataDecoder caloDecoder(subevent);
if (produceCaloDecoders_) {
caloDecoderColl->emplace_back(subevent); //FIXME: double construction of this calo decoder
}
nCaloEvents++;
// Iterate over the data blocks (ROCs)
std::vector<DTCLib::DTC_DataBlock> dataBlocks = subevent.GetDataBlocks();
uint nROCs = dataBlocks.size();
TLOG(TLVL_DEBUG) << "Iterating through " << nROCs << " data blocks (ROCs)\n";
for (uint iroc = 0; iroc < nROCs; iroc++){

checkAndUpdateROCEWT(dataBlocks[iroc]);

if (data_type_ == 0){ // STANDARD HITS

auto caloHits = caloDecoder.GetCalorimeterHitData(iroc);
uint nHits = caloHits->size();
TLOG(TLVL_INFO) << "There are " << nHits << " hits in DTC " << dtcID << " ROC " << iroc << " / " << nROCs << std::endl;
for (uint ihit = 0; ihit<nHits; ihit++){
mu2e::CalorimeterDataDecoder::CalorimeterHitDataPacket hit = caloHits->at(ihit).first;
std::vector<uint16_t> hit_waveform = caloHits->at(ihit).second;
if (hit_waveform.size() == 0){
TLOG(TLVL_WARNING) << "[CaloDataVerifier::filter] found empty waveform! DTC " << dtcID << " ROC " << iroc << " hit " << ihit
<< " BoardID " << hit.BoardID << " ChannelNumber " << hit.ChannelNumber;
}

} else if (data_type_ == 1){ // DEBUG HITS

auto caloHits = caloDecoder.GetCalorimeterHitTestData(iroc);
uint nHits = caloHits->size();
TLOG(TLVL_INFO) << "There are " << nHits << " hits in DTC " << dtcID << " ROC " << iroc << " / " << nROCs << std::endl;
for (uint ihit = 0; ihit<nHits; ihit++){
mu2e::CalorimeterDataDecoder::CalorimeterHitTestDataPacket hit = caloHits->at(ihit).first;
std::vector<uint16_t> hit_waveform = caloHits->at(ihit).second;

if (hit_waveform.size() == 0){
TLOG(TLVL_WARNING) << "[CaloDataVerifier::filter] found empty waveform! DTC " << dtcID << " ROC " << iroc << " hit " << ihit
<< " BoardID " << hit.BoardID << " ChannelID " << hit.ChannelID;
}

nCaloHits++;
nCaloHits++;
}

TLOG(TLVL_DEBUG)
<< "Hit " << ihit << " :" << std::endl
<< "\tBeginMarker: " << std::hex << hit.BeginMarker << std::dec << std::endl
<< "\tBoardID: " << hit.BoardID << std::endl
<< "\tChannelID: " << hit.ChannelID << std::endl
<< "\tInPayloadEventWindowTag: " << hit.InPayloadEventWindowTag << std::endl
<< "\tLastSampleMarker: " << std::hex << hit.LastSampleMarker << std::dec << std::endl
<< "\tErrorFlags: " << hit.ErrorFlags << std::endl
<< "\tTime: " << hit.Time << std::endl
<< "\tIndexOfMaxDigitizerSample: " << hit.IndexOfMaxDigitizerSample << std::endl
<< "\tNumberOfSamples: " << hit.NumberOfSamples << std::endl;

if (metricMan != nullptr){
TLOG(TLVL_DEBUG) << "[CaloDataVerifier::filter] sending hit metrics to Grafana..." << std::endl;
metricMan->sendMetric("BoardID", hit.BoardID, "Board ID number",
metrics_reporting_level_, artdaq::MetricMode::LastPoint);
metricMan->sendMetric("ChannelID", hit.ChannelID, "Channel ID number",
metrics_reporting_level_, artdaq::MetricMode::LastPoint);
metricMan->sendMetric("NumberOfSamples", hit.NumberOfSamples, "Number of samples",
metrics_reporting_level_, artdaq::MetricMode::LastPoint);
}

} else if (data_type_ == 1){ // DEBUG HITS
auto caloHits = caloDecoder.GetCalorimeterHitTestData(iroc);
uint nHits = caloHits->size();
TLOG(TLVL_INFO) << "There are " << nHits << " hits in DTC " << dtcID << " ROC " << iroc << " / " << nROCs << std::endl;
for (uint ihit = 0; ihit<nHits; ihit++){
mu2e::CalorimeterDataDecoder::CalorimeterHitTestDataPacket hit = caloHits->at(ihit).first;
std::vector<uint16_t> hit_waveform = caloHits->at(ihit).second;
if (hit_waveform.size() == 0){
TLOG(TLVL_WARNING) << "[CaloDataVerifier::filter] found empty waveform! DTC " << dtcID << " ROC " << iroc << " hit " << ihit
<< " BoardID " << hit.BoardID << " ChannelID " << hit.ChannelID;
}

nCaloHits++;

TLOG(TLVL_DEBUG)
<< "Hit " << ihit << " :" << std::endl
<< "\tBeginMarker: " << std::hex << hit.BeginMarker << std::dec << std::endl
<< "\tBoardID: " << hit.BoardID << std::endl
<< "\tChannelID: " << hit.ChannelID << std::endl
<< "\tInPayloadEventWindowTag: " << hit.InPayloadEventWindowTag << std::endl
<< "\tLastSampleMarker: " << std::hex << hit.LastSampleMarker << std::dec << std::endl
<< "\tErrorFlags: " << hit.ErrorFlags << std::endl
<< "\tTime: " << hit.Time << std::endl
<< "\tIndexOfMaxDigitizerSample: " << hit.IndexOfMaxDigitizerSample << std::endl
<< "\tNumberOfSamples: " << hit.NumberOfSamples << std::endl
<< "\twaveform size: " << hit_waveform.size() << std::endl;

std::stringstream ss_wf;
for (auto sample : hit_waveform) ss_wf << sample << " ";
TLOG(TLVL_DEBUG) << "Waveform:\n" << ss_wf.str();

if (metricMan != nullptr){
metricMan->sendMetric("nHits", int(nHits), "Hits",
TLOG(TLVL_DEBUG) << "[CaloDataVerifier::filter] sending hit metrics to Grafana..." << std::endl;
metricMan->sendMetric("BoardID", hit.BoardID, "Board ID number",
metrics_reporting_level_, artdaq::MetricMode::LastPoint);
metricMan->sendMetric("ChannelID", hit.ChannelID, "Channel ID number",
metrics_reporting_level_, artdaq::MetricMode::LastPoint);
metricMan->sendMetric("NumberOfSamples", hit.NumberOfSamples, "Number of samples",
metrics_reporting_level_, artdaq::MetricMode::LastPoint);
}
}
}

if (metricMan != nullptr){
metricMan->sendMetric("nSubEvents", caloSubEvents.size(), "Subevents",
metrics_reporting_level_, artdaq::MetricMode::LastPoint);
if (metricMan != nullptr){
metricMan->sendMetric("nHits", int(nHits), "Hits",
metrics_reporting_level_, artdaq::MetricMode::LastPoint);
}
} else if (data_type_ == 2){ // COUNTERS
auto caloHits = caloDecoder.GetCalorimeterCountersData(iroc);
uint nHits = caloHits->size();
TLOG(TLVL_INFO) << "There are " << nHits << " hits in DTC " << dtcID << " ROC " << iroc << " / " << nROCs << std::endl;
for (uint ihit = 0; ihit<nHits; ihit++){
mu2e::CalorimeterDataDecoder::CalorimeterCountersDataPacket hit = caloHits->at(ihit).first;
std::vector<uint32_t> hit_counters = caloHits->at(ihit).second;
if (hit_counters.size() == 0){
TLOG(TLVL_WARNING) << "[CaloDataVerifier::filter] found empty counters! DTC " << dtcID << " ROC " << iroc << " hit " << ihit;
}
nCaloHits++;

TLOG(TLVL_DEBUG)
<< "Hit " << ihit << " :" << std::endl
<< "\numberOfCounters: " << hit.numberOfCounters << std::endl
<< "\tcounters size: " << hit_counters.size() << std::endl;

std::stringstream ss_wf;
for (auto sample : hit_counters) ss_wf << sample << " ";
TLOG(TLVL_DEBUG) << "Counters:\n" << ss_wf.str();

if (metricMan != nullptr){
TLOG(TLVL_DEBUG) << "[CaloDataVerifier::filter] sending hit metrics to Grafana..." << std::endl;
metricMan->sendMetric("NumberOfCounters", hit.numberOfCounters, "Number of counters",
metrics_reporting_level_, artdaq::MetricMode::LastPoint);
}
}
if (metricMan != nullptr){
metricMan->sendMetric("nHits", int(nHits), "Hits",
metrics_reporting_level_, artdaq::MetricMode::LastPoint);
}
}
}

TLOG(TLVL_DEBUG) << "[CaloDataVerifier::filter] found " << nCaloEvents << " calo subevents" << std::endl;
TLOG(TLVL_DEBUG) << "[CaloDataVerifier::filter] found " << nCaloHits << " calo hits" << std::endl;

if (nCaloEvents == 0) {
TLOG(TLVL_WARNING) << "[CaloDataVerifier::filter] found no calo subevents!" << std::endl;
}

TLOG(TLVL_INFO) << "mu2e::CaloDataVerifier::filter exiting eventNumber="
<< (int)(event.event()) << " / timestamp=" << (int)eventNumber << std::endl;

if (metricMan != nullptr){
TLOG(TLVL_DEBUG) << "Sending nFragments metric!\n";
metricMan->sendMetric("nFragments", fragments.size(), "Fragments",
metrics_reporting_level_, artdaq::MetricMode::LastPoint);
metricMan->sendMetric("nSubEvents", caloSubEvents.size(), "Subevents",
metrics_reporting_level_, artdaq::MetricMode::LastPoint);
}

}

if (produceCaloDecoders_) {
event.put(std::move(caloDecoderColl));
}

bool mu2e::CaloDataVerifier::checkAndUpdateDTCEWT(const DTCLib::DTC_SubEvent& subevent){
uint64_t dtcID = subevent.GetDTCID();
long int dtcEWT = subevent.GetEventWindowTag().GetEventWindowTag(true);
TLOG(TLVL_DEBUG) << "DTC: " << dtcID << " - Current EWT: " << dtcEWT << " - Previous EWT: " << lastDTCEventWindow[dtcID];
if (lastDTCEventWindow.find(dtcEWT) != lastDTCEventWindow.end() && dtcEWT != lastDTCEventWindow[dtcID] + 1) {
TLOG(TLVL_ERROR) << "Error in the event window (DTC)!\n"
<< "current: " << dtcEWT
<< " previous: " << lastDTCEventWindow[dtcID]
<< "\nCurrent DTC HEADER: " << subevent.GetHeader()->toJson();
lastDTCEventWindow[dtcID] = dtcEWT;
return false;
}
lastDTCEventWindow[dtcID] = dtcEWT;
return true;
}


bool mu2e::CaloDataVerifier::endRun( art::Run& ) {
bool mu2e::CaloDataVerifier::checkAndUpdateROCEWT(const DTCLib::DTC_DataBlock& dataBlock){

// print the data block header
DTCLib::DTC_DataHeaderPacket* rocHeader = dataBlock.GetHeader().get();
uint64_t dtcID = rocHeader->GetID();
uint64_t rocID = rocHeader->GetLinkID();
long int rocEWT = rocHeader->GetEventWindowTag().GetEventWindowTag(true);
TLOG(TLVL_DEBUG) << "DTC: " << dtcID << " - ROC: " << rocID << " - Current EWT: " << rocEWT << " - Previous EWT: " << lastROCEventWindow[dtcID][rocID];
if (lastROCEventWindow.find(rocEWT) != lastROCEventWindow.end() && rocEWT != lastROCEventWindow[dtcID][rocID] + 1) {
TLOG(TLVL_ERROR) << "Error in the event window (ROC)!\n"
<< "current: " << rocEWT
<< " previous: " << lastROCEventWindow[dtcID][rocID]
<< "\nCurrent ROC HEADER: " << rocHeader->toJSON();
lastROCEventWindow[dtcID][rocID] = rocEWT;
return false;
}
lastROCEventWindow[dtcID][rocID] = rocEWT;
return true;
}

Expand Down
Loading