11 #include "art/Framework/Core/EDProducer.h"
12 #include "art/Framework/Core/ModuleMacros.h"
13 #include "art/Framework/Principal/Event.h"
14 #include "art/Framework/Principal/Handle.h"
15 #include "art/Framework/Principal/Run.h"
16 #include "art/Framework/Principal/SubRun.h"
17 #include "canvas/Utilities/InputTag.h"
18 #include "fhiclcpp/types/Atom.h"
19 #include "messagefacility/MessageLogger/MessageLogger.h"
22 #include "artdaq-core/Data/Fragment.hh"
23 #include "sbndaq-artdaq-core/Overlays/ICARUS/ICARUSTriggerV2Fragment.hh"
27 #include "ifdh_art/IFBeamService/IFBeam_service.h"
47 fhicl::Atom<double> TimePadding {
49 Comment{
"extension to the time window considered when collecting spills [seconds]" },
54 Name{
"raw_data_label" },
55 Comment{
"art data product instance name for trigger information (product label is 'daq')" }
59 Name{
"DeviceUsedForTiming" },
60 Comment{
"name in the IFBeam database of the device used to extract spill times" }
63 fhicl::Atom<std::string>
URL {
65 Comment{
"IFBeam database access URL" }
79 Name{
"MultiWireBundle" },
84 Name{
"MWR_TimeWindow" },
104 void produce(art::Event&
e)
override;
106 void endSubRun(art::SubRun& sr)
override;
119 std::unique_ptr<ifbeam_ns::BeamFolder>
bfp;
120 std::unique_ptr<ifbeam_ns::BeamFolder>
bfp_mwr;
157 art::EventID
const& eventID,
159 MWRdata_t const& MWRdata,
bool isFirstEventInRun,
160 std::vector< sbn::BNBSpillInfo >& beamInfos
172 (art::EventID
const& eventID,
double time,
MWRdata_t const& MWRdata, std::vector<int>
const& matched_MWR)
const;
177 : EDProducer{params},
178 fTimePad(params().TimePadding()),
179 raw_data_label(params().RawDataLabel()),
180 fDeviceUsedForTiming(params().DeviceUsedForTiming()),
181 bfp( ifbeam_handle->getBeamFolder(params().Bundle(), params().URL(), params().TimeWindow())),
182 bfp_mwr( ifbeam_handle->getBeamFolder(params().MultiWireBundle(), params().URL(), params().MWR_TimeWindow()))
187 throw art::Exception(art::errors::Configuration)
188 <<
"Parameter `TimePadding` must be non-negative (" << fTimePad <<
" was specified).\n";
197 bfp->set_epsilon(0.02);
198 bfp_mwr->set_epsilon(0.5);
201 bfp_mwr->setValidWindow(3605);
202 produces< std::vector< sbn::BNBSpillInfo >, art::InSubRun >();
216 if (e.event() == 1)
return;
227 MWRdata_t const MWRdata = extractSpillTimes(triggerInfo);
230 int const spill_count = matchMultiWireData(e.id(), triggerInfo, MWRdata, e.event() == 1, fOutbeamInfos);
248 auto const & raw_data = e.getProduct< std::vector<artdaq::Fragment> >({ raw_data_label,
"ICARUSTriggerV2" });
252 for(
auto raw_datum : raw_data){
254 uint64_t artdaq_ts = raw_datum.timestamp();
255 icarus::ICARUSTriggerV2Fragment frag(raw_datum);
256 std::string data = frag.GetDataString();
257 char *buffer =
const_cast<char*
>(data.c_str());
258 icarus::ICARUSTriggerInfo datastream_info = icarus::parse_ICARUSTriggerV2String(buffer);
259 triggerInfo.gate_type = datastream_info.gate_type;
260 triggerInfo.number_of_gates_since_previous_event = frag.getDeltaGatesBNB();
262 triggerInfo.t_current_event =
static_cast<double>(artdaq_ts)/(1000000000.0);
263 if(triggerInfo.gate_type == 1)
264 triggerInfo.t_previous_event = (
static_cast<double>(frag.getLastTimestampBNB()))/(1e9);
266 triggerInfo.t_previous_event = (
static_cast<double>(frag.getLastTimestampOther()))/(1000000000.0);
270 mf::LogDebug(
"BNBRetriever") << std::setprecision(19) <<
"Previous : " << triggerInfo.t_previous_event <<
", Current : " << triggerInfo.t_current_event << std::endl;
280 try{
auto cur_vec_temp = bfp->GetNamedVector((triggerInfo.
t_previous_event)-fTimePad,
"E:THCURR");}
catch (WebAPIException &we) {}
281 try{
auto packed_M876BB_temp = bfp_mwr->GetNamedVector((triggerInfo.
t_current_event)+fTimePad,
"E:M875BB{4440:888}.RAW");}
catch (WebAPIException &we) {}
288 std::vector< std::vector< std::vector< int > > > unpacked_MWR;
289 std::vector< std::vector< double> > MWR_times;
290 unpacked_MWR.resize(3);
292 std::string packed_data_str;
297 std::vector<std::string> vars = bfp_mwr->GetDeviceList();
298 mf::LogDebug(
"BNBRetriever") <<
" Number of MWR Device Blocks Found : " << vars.size() << std::endl;
313 mf::LogDebug(
"BNBRetriever") <<
" t_steps " << t_steps << std::endl;
315 for(
int t = 0; t < t_steps; t++){
316 for (std::string
const& var : vars) {
320 mf::LogDebug(
"BNBRetriever") <<
" NO MWR DEVICES?!" << std::endl;
324 if(var.find(
"M875BB") != std::string::npos ) dev = 0;
325 else if(var.find(
"M876BB") != std::string::npos ) dev = 1;
326 else if(var.find(
"MMBTBB") != std::string::npos ) dev = 2;
328 mf::LogDebug(
"BNBRetriever") <<
" NOT matched to a MWR DEVICES?!" << var << std::endl;
336 std::vector<double> packed_MWR = bfp_mwr->GetNamedVector((triggerInfo.
t_previous_event)-20.-fTimePad+
double(0.5*t),var,&time_for_mwr);
341 packed_data_str.clear();
343 packed_data_str.append(
",");
344 packed_data_str.append(var);
345 packed_data_str.append(
",,");
351 for(
int j = 0; j < int(packed_MWR.size()); j++){
353 if(j <
int(packed_MWR.size())-1)
354 packed_data_str.append(
",");
358 std::vector<double> MWR_times_temp;
362 std::vector< std::vector< int > > unpacked_MWR_temp = mwrdata.unpackMWR(packed_data_str,MWR_times_temp,MWRtoroidDelay);
368 if(std::find(MWR_times[dev].
begin(), MWR_times[
dev].end(), MWR_times_temp[
s]) == MWR_times[dev].
end()){
369 unpacked_MWR[
dev].push_back(unpacked_MWR_temp[
s]);
370 MWR_times[
dev].push_back(MWR_times_temp[s]);
374 catch (WebAPIException &we) {
382 mf::LogDebug(
"BNBRetriever") <<
" Number of MWR[0] times : " << MWR_times[0].size() << std::endl;
383 mf::LogDebug(
"BNBRetriever") <<
" Number of MWR[0]s : " << unpacked_MWR[0].size() << std::endl;
384 mf::LogDebug(
"BNBRetriever") <<
" Number of MWR[1] times : " << MWR_times[1].size() << std::endl;
385 mf::LogDebug(
"BNBRetriever") <<
" Number of MWR[1]s : " << unpacked_MWR[1].size() << std::endl;
386 mf::LogDebug(
"BNBRetriever") <<
" Number of MWR[2] times : " << MWR_times[2].size() << std::endl;
387 mf::LogDebug(
"BNBRetriever") <<
" Number of MWR[2]s : " << unpacked_MWR[2].size() << std::endl;
389 return { std::move(MWR_times), std::move(unpacked_MWR) };
394 art::EventID
const& eventID,
396 MWRdata_t const& MWRdata,
bool isFirstEventInRun,
397 std::vector< sbn::BNBSpillInfo >& beamInfos
400 auto const& [ MWR_times, unpacked_MWR ] = MWRdata;
405 std::vector<double> times_temps = bfp->GetTimeList(fDeviceUsedForTiming);
410 std::vector<int> matched_MWR;
411 matched_MWR.resize(3);
420 if(isFirstEventInRun){
423 int spills_after_our_target = 0;
426 for (
size_t i = 0; i < times_temps.size(); i++) {
428 spills_after_our_target++;
433 times_temps.erase(times_temps.end()-spills_after_our_target,times_temps.end());
441 for (
size_t i = 0; i < times_temps.size(); i++) {
445 if(!isFirstEventInRun){
456 for(
int dev = 0;
dev < int(MWR_times.size());
dev++){
459 double Tdiff = 1000000000.;
460 matched_MWR[
dev] = 0;
462 for(
int mwrt = 0; mwrt < int(MWR_times[
dev].
size()); mwrt++){
465 if(fabs((MWR_times[
dev][mwrt] - times_temps[i])) >= Tdiff){
continue;}
467 bool best_match =
true;
470 for (
size_t j = 0; j < times_temps.size(); j++) {
471 if( j == i)
continue;
476 if(fabs((MWR_times[
dev][mwrt] - times_temps[j])) <
477 fabs((MWR_times[
dev][mwrt] - times_temps[i]))){
485 if(best_match ==
true){
486 matched_MWR[
dev] = mwrt;
487 Tdiff = fabs((MWR_times[
dev][mwrt] - times_temps[i]));
494 sbn::BNBSpillInfo spillInfo = makeBNBSpillInfo(eventID, times_temps[i], MWRdata, matched_MWR);
496 beamInfos.push_back(std::move(spillInfo));
509 (art::EventID
const& eventID,
double time,
MWRdata_t const& MWRdata, std::vector<int>
const& matched_MWR)
const
512 auto const& [ MWR_times, unpacked_MWR ] = MWRdata;
531 double TOR860_time = 0;
537 try{bfp->GetNamedData(time,
"E:TOR860@",&TOR860,&TOR860_time);}
catch (WebAPIException &we) {mf::LogDebug(
"BNBRetriever")<<
"At time : " << time <<
" " <<
"got exception: " << we.what() <<
"\n";}
538 try{bfp->GetNamedData(time,
"E:TOR875",&TOR875);}
catch (WebAPIException &we) {mf::LogDebug(
"BNBRetriever")<<
"At time : " << time <<
" " <<
"got exception: " << we.what() <<
"\n";}
539 try{bfp->GetNamedData(time,
"E:LM875A",&LM875A);}
catch (WebAPIException &we) {mf::LogDebug(
"BNBRetriever")<<
"At time : " << time <<
" " <<
"got exception: " << we.what() <<
"\n";}
540 try{bfp->GetNamedData(time,
"E:LM875B",&LM875B);}
catch (WebAPIException &we) {mf::LogDebug(
"BNBRetriever")<<
"At time : " << time <<
" " <<
"got exception: " << we.what() <<
"\n";}
541 try{bfp->GetNamedData(time,
"E:LM875C",&LM875C);}
catch (WebAPIException &we) {mf::LogDebug(
"BNBRetriever")<<
"At time : " << time <<
" " <<
"got exception: " << we.what() <<
"\n";}
542 try{bfp->GetNamedData(time,
"E:HP875",&HP875);}
catch (WebAPIException &we) {mf::LogDebug(
"BNBRetriever")<<
"At time : " << time <<
" " <<
"got exception: " << we.what() <<
"\n";}
543 try{bfp->GetNamedData(time,
"E:VP875",&VP875);}
catch (WebAPIException &we) {mf::LogDebug(
"BNBRetriever")<<
"At time : " << time <<
" " <<
"got exception: " << we.what() <<
"\n";}
544 try{bfp->GetNamedData(time,
"E:HPTG1",&HPTG1);}
catch (WebAPIException &we) {mf::LogDebug(
"BNBRetriever")<<
"At time : " << time <<
" " <<
"got exception: " << we.what() <<
"\n";}
545 try{bfp->GetNamedData(time,
"E:VPTG1",&VPTG1);}
catch (WebAPIException &we) {mf::LogDebug(
"BNBRetriever")<<
"At time : " << time <<
" " <<
"got exception: " << we.what() <<
"\n";}
546 try{bfp->GetNamedData(time,
"E:HPTG2",&HPTG2);}
catch (WebAPIException &we) {mf::LogDebug(
"BNBRetriever")<<
"At time : " << time <<
" " <<
"got exception: " << we.what() <<
"\n";}
547 try{bfp->GetNamedData(time,
"E:VPTG2",&VPTG2);}
catch (WebAPIException &we) {mf::LogDebug(
"BNBRetriever")<<
"At time : " << time <<
" " <<
"got exception: " << we.what() <<
"\n";}
548 try{bfp->GetNamedData(time,
"E:BTJT2",&BTJT2);}
catch (WebAPIException &we) {mf::LogDebug(
"BNBRetriever")<<
"At time : " << time <<
" " <<
"got exception: " << we.what() <<
"\n";}
549 try{bfp->GetNamedData(time,
"E:THCURR",&THCURR);}
catch (WebAPIException &we) {mf::LogDebug(
"BNBRetriever")<<
"At time : " << time <<
" " <<
"got exception: " << we.what() <<
"\n";}
552 unsigned long int time_closest_int = (int) TOR860_time;
553 double time_closest_ns = (TOR860_time - time_closest_int)*1e9;
557 beamInfo.
TOR860 = TOR860*1e12;
558 beamInfo.
TOR875 = TOR875*1e12;
562 beamInfo.
HP875 = HP875;
563 beamInfo.
VP875 = VP875;
564 beamInfo.
HPTG1 = HPTG1;
565 beamInfo.
VPTG1 = VPTG1;
566 beamInfo.
HPTG2 = HPTG2;
567 beamInfo.
VPTG2 = VPTG2;
568 beamInfo.
BTJT2 = BTJT2;
573 for(
auto const& MWRdata: unpacked_MWR){
574 std::ignore = MWRdata;
575 assert(!MWRdata.empty());
578 if(unpacked_MWR[0].
empty()){
583 beamInfo.
M875BB = unpacked_MWR[0][matched_MWR[0]];
587 if(unpacked_MWR[1].
empty()){
592 beamInfo.
M876BB = unpacked_MWR[1][matched_MWR[1]];
596 if(unpacked_MWR[2].
empty()){
601 beamInfo.
MMBTBB = unpacked_MWR[2][matched_MWR[2]];
608 beamInfo.
event = eventID.event();
626 mf::LogDebug(
"BNBRetriever")<<
"Total number of DAQ Spills : " << TotalBeamSpills << std::endl;
627 mf::LogDebug(
"BNBRetriever")<<
"Total number of Selected Spills : " << fOutbeamInfos.size() << std::endl;
629 auto p = std::make_unique< std::vector< sbn::BNBSpillInfo > >();
630 std::swap(*
p, fOutbeamInfos);
632 sr.put(std::move(
p), art::subRunFragment());
unsigned int number_of_gates_since_previous_event
float M876BB_spill_time_diff
the time difference between M876BB and the matched spill
std::vector< int > M876BB
Multiwire station after Mag 875...?
void produce(art::Event &e) override
std::string fDeviceUsedForTiming
float LM875C
Loss Monitor after the RWM, unit R/s.
float VPTG2
Horizontal Position Monitor at Target Station 2, closest to target, units mm.
std::string raw_data_label
int gate_type
Source of the spill: 1: BNB, 2: NuMI.
float VPTG1
Horizontal Position Monitor at Target Station 1, units mm.
unsigned long int spill_time_ns
The IFDB Beam Spill Time, unit nsec.
fhicl::Atom< std::string > Bundle
MWRdata_t extractSpillTimes(TriggerInfo_t const &triggerInfo) const
Determines spill times and extracts data based on multiwire devices.
BNBRetriever(Parameters const ¶ms)
std::size_t size(FixedBins< T, C > const &) noexcept
TriggerInfo_t extractTriggerInfo(art::Event const &e) const
Returns the information of the trigger in the current event.
float MMBTBB_spill_time_diff
the time difference between MMBTBB and the matched spill
fhicl::Atom< double > TimePadding fhicl::Atom< std::string > RawDataLabel
float TOR875
Toroid after Mag 875, units e12 Protons.
unsigned int TotalBeamSpills
float LM875A
Loss Monitor before the RWM, unit R/s.
std::unique_ptr< ifbeam_ns::BeamFolder > bfp
auto counter(T begin, T end)
Returns an object to iterate values from begin to end in a range-for loop.
std::vector< sbn::BNBSpillInfo > fOutbeamInfos
float BTJT2
Temperature of air exiting target, units Deg C.
fhicl::Atom< std::string > URL
void beginSubRun(art::SubRun &sr) override
std::vector< int > MMBTBB
Multiwire station at the target station,.
auto end(FixedBins< T, C > const &) noexcept
fhicl::Atom< std::string > DeviceUsedForTiming
std::unique_ptr< ifbeam_ns::BeamFolder > bfp_mwr
BEGIN_PROLOG vertical distance to the surface Name
Test of util::counter and support utilities.
art::EDProducer::Table< Config > Parameters
float HP875
Horizontal Position Monitor after Mag 875, units mm.
int matchMultiWireData(art::EventID const &eventID, TriggerInfo_t const &triggerInfo, MWRdata_t const &MWRdata, bool isFirstEventInRun, std::vector< sbn::BNBSpillInfo > &beamInfos) const
Matches spill times with multiwire chamber data from the database.
auto begin(FixedBins< T, C > const &) noexcept
std::vector< std::vector< double > > MWR_times
float HPTG2
Horizontal Position Monitor at Target Station 2, closest to target, units mm.
float THCURR
Current applied to Horn, units kiloAmperes.
fhicl::Atom< double > MWR_TimeWindow
unsigned long int spill_time_s
The IFDB Beam Spill Time, unit sec.
std::string to_string(WindowPattern const &pattern)
then echo File list $list not found else cat $list while read file do echo $file sed s
sbn::BNBSpillInfo makeBNBSpillInfo(art::EventID const &eventID, double time, MWRdata_t const &MWRdata, std::vector< int > const &matched_MWR) const
Assembles and returns a spill information record.
float VP875
Verticle Position Monitor after Mag 875, units mm.
void endSubRun(art::SubRun &sr) override
float TOR860
Toroid before Mag 875, units e12 Protons.
BNBRetriever & operator=(BNBRetriever const &)=delete
std::vector< int > M875BB
Multiwire station before Mag 875...?
float LM875B
Loss Monitor after the RWM, unit R/s.
std::vector< std::vector< std::vector< int > > > unpacked_MWR
fhicl::Atom< double > TimeWindow
bool empty(FixedBins< T, C > const &) noexcept
static constexpr double MWRtoroidDelay
the same time point is measured t by MWR and _t + MWRtoroidDelay`_ by the toroid [ms] ...
art::ServiceHandle< ifbeam_ns::IFBeam > ifbeam_handle
float M875BB_spill_time_diff
the time difference between M875BB and the matched spill
float HPTG1
Horizontal Position Monitor at Target Station 1, units mm.
fhicl::Atom< std::string > MultiWireBundle