#include using namespace RAT; ChannelFlagsProc::ChannelFlagsProc() : Processor("ChannelFlagsProc"){ fRunRangeSync16 = 0; fRunRangeSync24 = 0; fFindSyncMode = 0; } void ChannelFlagsProc::SetI(const std::string& param, const int value){ if(param == "run_sync16"){ fRunRangeSync16 = value; } else if(param == "run_sync24"){ fRunRangeSync24 = value; } else if(param == "find_syncs"){ fFindSyncMode = value; if(fFindSyncMode != 0 && fFindSyncMode != 1){ throw ParamInvalid(param, "Value must be either 0 or 1."); } } else{ throw ParamUnknown(param); } } void ChannelFlagsProc::BeginOfRun(DS::Run&){ DBLinkPtr fMissedCountBurst = DB::Get()->GetLink("MISSED_COUNT_BURST"); fTimeCut = fMissedCountBurst->GetD("time_cut"); fNChannelsBurst = fMissedCountBurst->GetI("nchannels"); fCountSync16 = 0; fCountSync24 = 0; fSync16Occured = 0; fSync24Occured = 0; fEventCounter = 0; fResync = 0; fMissedCountBurstCount = 0; fTimeZero = 0; fMissedCountCut.resize(9728, 0); fBurstChannelCount.resize(9728, 0); fCGTSync24.resize(9728, 0); fCMOSSync16.resize(9728, 0); fCGTSync24PreviousRuns.resize(9728, 0); fCMOSSync16PreviousRuns.resize(9728, 0); fCountAllSync16.resize(9728, -1); fCountAllSync24.resize(9728, -1); } Processor::Result ChannelFlagsProc::DSEvent(DS::Run&, DS::Entry& ds){ for(size_t iEV = 0; iEV < ds.GetEVCount(); iEV++){ Event(ds, ds.GetEV(iEV)); } return OK; } Processor::Result ChannelFlagsProc::Event(DS::Entry&, DS::EV& ev){ int gtid = ev.GetGTID(); ULong64_t clock50 = ev.GetClockCount50(); // Event is an orphan if(ev.GetTrigType() == 0){ return OK; } // Run was resynced, don't look at sync errors until a GTID of 2**16 if(gtid == 1 && fEventCounter == 0){ fResync = 1; } // Count the Sync 16s and Sync 24s // GTID is 24 bit word, so SYNC24s only come at GTID == 0 // or at a resync if((gtid == 0) || (fResync && fEventCounter == 0)){ fCountSync24++; fSync24Occured = 1; } if((gtid % (1<<16) == 0) || (fResync && fEventCounter == 0)){ fCountSync16++; fSync16Occured = 1; } fEventCounter++; // Just find whether there was a sync in the run // don't worry about the channel flags if(fFindSyncMode) return OK; // Loop over all uncalibrated PMTs and check the channel flags DS::UncalPMTs& uncalPMTs = ev.GetUncalPMTs(); for(size_t iPMT = 0; iPMT < uncalPMTs.GetAllCount(); iPMT++){ DS::PMTUncal& pmtUncal = uncalPMTs.GetAllPMT(iPMT); int flags = pmtUncal.GetChanFlags(); int lcn = pmtUncal.GetID(); // Missed count flag. This keeps track of the number of missed count flags // set for each channel during the run. if(flags & (1<<2)){ double dt = (clock50 - fTimeZero)*20; // Start a time window to check for a burst of missed counts if(fTimeZero == 0){ fTimeZero = clock50; fGTIDZero = gtid; } // In the time window count the channels that have dropped hits else if(dt < fTimeCut && dt > 0){ if(fBurstChannelCount[lcn] == 0){ fMissedCountBurstCount++; } fBurstChannelCount[lcn] += 1; } else{ // We had a burst of missed counts, so we don't flag the channels, // instead we will cut a chunk of time with data-cleaning if(fMissedCountBurstCount > fNChannelsBurst){ fBurstGTID.push_back(fGTIDZero); } // We did not have a burst, so flag the channels else{ for(int l = 0; l < 9728; l++){ fMissedCountCut[l] += fBurstChannelCount[l]; } } fTimeZero = 0.0; fMissedCountBurstCount = 0; fGTIDZero = 0; std::fill(fBurstChannelCount.begin(), fBurstChannelCount.end(), 0); } } // CMOS Sync 16 Flag. If this flag is set before the first sync 16, it is not // an issue for the current run. If it gets set at the first sync 16, then its // an issue for both the current and any previous runs (since the last sync). // If it gets set at the second sync 16 or aftwards, its only an issue for // the current run. If we have not had a sync yet in the current run, than the // channel was already flagged in the previous run(s), when the last sync happened. if(flags & (1<<5)){ // Don't count each channel's error for every hit (only count once between syncs) if(fCountAllSync16[lcn] != fCountSync16){ if(fCountSync16 == 0 && !fResync){ // Flag is already high before a SYNC, but we didnt necessarily // catch these in the previous run if that channel wasn't hit in that run fCMOSSync16PreviousRuns[lcn]++; } else if(fCountSync16 == 1 && !fResync){ // These have defintely not been caught yet, // so we need to flag them for the previous run fCMOSSync16PreviousRuns[lcn]++; fCMOSSync16[lcn]++; } else if(fCountSync16 > 1){ fCMOSSync16[lcn]++; } fCountAllSync16[lcn] = fCountSync16; } } // CGT sync 24 flag. See the comments above regarding Sync 16. if(flags & (1<<1)){ // Don't count each channel's error for every hit (only count once between syncs) if(fCountAllSync24[lcn] != fCountSync24){ if(fCountSync24 == 0 && !fResync){ // Flag is already high before a SYNC, but we didnt necessarily // catch these in the previous run if that channel wasn't hit in that run fCGTSync24PreviousRuns[lcn]++; } else if(fCountSync24 == 1 && !fResync){ // These have defintely not been caught yet, // so we need to flag them for the previous run fCGTSync24[lcn]++; fCGTSync24PreviousRuns[lcn]++; } else if(fCountSync24 > 1){ fCGTSync24[lcn]++; } fCountAllSync24[lcn] = fCountSync24; } } } return OK; } void ChannelFlagsProc::EndOfRun(DS::Run& run){ if(fFindSyncMode == 1){ // To be used nearline, not pushed to ratdb RAT::DBTable MCTable("FIND_SYNCS"); MCTable.SetIndex(""); MCTable.SetI("version", 2); MCTable.SetPassNumber(-1); MCTable.SetI("resync", fResync); MCTable.SetI("count_sync16", fCountSync16); MCTable.SetI("count_sync24", fCountSync24); MCTable.SaveAs("FindSyncs.ratdb"); } if(fFindSyncMode == 0){ // Save table for current run for any channel with missed counts RAT::DBTable MCTable("MISSED_COUNTS"); MCTable.SetIndex(""); MCTable.SetI("version", 1); MCTable.SetRunRange(run.GetRunID(),run.GetRunID()); MCTable.SetPassNumber(-1); MCTable.SetIArray("missed_counts", fMissedCountCut); MCTable.SaveAs("MissedCounts.ratdb"); RAT::DBTable MCBurstTable("MISSED_BURST"); MCBurstTable.SetIndex(""); MCBurstTable.SetI("version", 1); MCBurstTable.SetRunRange(run.GetRunID(),run.GetRunID()); MCBurstTable.SetPassNumber(-1); MCBurstTable.SetIArray("missed_counts_burst_gtid", fBurstGTID); MCBurstTable.SaveAs("MissedCountsBurst.ratdb"); // If a sync 16 happend in the run // Create a sync 16 table valid for this run // and a sync 16 table valid for previous runs, since the last sync 16 if(fSync16Occured){ RAT::DBTable SYNC16Table("CMOS_SYNC16"); SYNC16Table.SetIndex(""); SYNC16Table.SetI("version", 1); SYNC16Table.SetRunRange(run.GetRunID(), run.GetRunID()); SYNC16Table.SetPassNumber(-1); SYNC16Table.SetIArray("cmos_sync16", fCMOSSync16); SYNC16Table.SaveAs("CMOSSync16.ratdb"); RAT::DBTable SYNC16PRTable("CMOS_SYNC16_PREVIOUS_RUNS"); SYNC16PRTable.SetIndex(""); SYNC16PRTable.SetI("version", 1); SYNC16PRTable.SetRunRange(fRunRangeSync16, run.GetRunID()-1); SYNC16PRTable.SetPassNumber(-1); SYNC16PRTable.SetIArray("cmos_sync16", fCMOSSync16PreviousRuns); SYNC16PRTable.SaveAs("CMOSSync16PreviousRuns.ratdb"); } // If a sync 24 happend in the run // Create a sync 24 table valid for this run // and a sync 24 table valid for previous runs, since the last sync 24 if(fSync24Occured){ RAT::DBTable SYNC24Table("CGT_SYNC24"); SYNC24Table.SetIndex(""); SYNC24Table.SetI("version", 1); SYNC24Table.SetRunRange(run.GetRunID(), run.GetRunID()); SYNC24Table.SetPassNumber(-1); SYNC24Table.SetIArray("cgt_sync24", fCGTSync24); SYNC24Table.SaveAs("CGTSync24.ratdb"); RAT::DBTable SYNC24PRTable("CGT_SYNC24_PREVIOUS_RUNS"); SYNC24PRTable.SetIndex(""); SYNC24PRTable.SetI("version", 1); SYNC24PRTable.SetRunRange(fRunRangeSync24, run.GetRunID()-1); SYNC24PRTable.SetPassNumber(-1); SYNC24PRTable.SetIArray("cgt_sync24", fCGTSync24PreviousRuns); SYNC24PRTable.SaveAs("CGTSync24PreviousRuns.ratdb"); } } }