Skip to content

Conversation

@brucehoward-physics
Copy link
Contributor

Putting together PR for a couple of spill info updates to try to get things into the CAFs and in a way that we can also start to do beam quality cuts. Some questions notes:

See some info in doc-33224 slides 5-13

  1. IMPORTANT (!!) -- I'm not sure if I should be making this PR against develop or v09_72_00_05 e.g. There seem to be a lot of commits present in the latter but not in develop as my changes are only the last few commits...

  2. Think some additional similar changes may be needed in BNB module(s) but probably would be a PR from their side — including Joseph and Jacob L in the conversation here.

  3. What else do we need for validation? (See some info at doc-33224)

  4. Do we want these parts (info.spill_time_s+(info.spill_time_ns/1.0e9)) to instead do something with more precision?

  5. We probably want to talk to NOvA to remember how they handle the POT sums within CAFAna and with spill quality cuts, but this PR is more about getting the info available for use rather than the internal workings. But it's possible that the way of saving them would preclude certain usage patterns.

Tagging some reviewers that I think make sense given this touches trigger info, spill accounting, CAFs, etc.

…he spill quality for the spill that goes with a given event, and code supporting that.
…wants to use this spill. The other checks not just for the first event but the first event OF A GIVEN STREAM for the numi case.
@brucehoward-physics
Copy link
Contributor Author

One other thing to check is that we probably want some way to directly check in the CAFs nspill from ifbeam vs nspill from TDAQ reporting to cut instances of disagreement if indeed that's what we want to do --- need to see if that's available or needs to be added.

@brucehoward-physics brucehoward-physics changed the base branch from develop to release_v09_72_00_03 November 1, 2023 20:44
@brucehoward-physics
Copy link
Contributor Author

Per @PetrilloAtWork request to make things less confusing (even if we still have to figure out about the differences between this and develop) I've changed the base branch to be release_v09_72_00_03 which looking at my area's git log seemed to be what the tag I was working from pointed to.

Copy link
Member

@PetrilloAtWork PetrilloAtWork left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks ok, comments left mostly for C++ improval plus an error that I would prefer to be fatal.
Becomes approval if you think it's ok as is.
Ok, it's already approval because I messed up. But it's ok.

if ( fBNBInfoEventMap.find(info.event)==fBNBInfoEventMap.end() ) {
fBNBInfoEventMap[info.event] = info;
}
else if ( (info.spill_time_s+(info.spill_time_ns/1.0e9)) >
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you put this into a function, like:

namespace {
  template <typename SpillInfo>
  double spillInfoToTimestamp(SpillInfo const& info) {
    return static_cast<double>(info.spill_time_s)
      + static_cast<double>(info.spill_time_ns)*1e-9;
  }
}

Even better would be to add a timestamp() member function to caf::SRBNBSpillInfo and sister.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea! Is the namespace { } enclosure here just a generic template of such a function or do you prefer it live in a specific namespace? Otherwise, I was thinking to just put it in caf namespace in the code.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The unnamed namespace has a specific meaning, in that its content is not visible outside the translation unit C++ source file where it is defined. For example, if I wrote a header file cheater.h like:

template <typename SpillInfo>
double spillInfoToTimestamp(SpillInfo const& info);

and I included it in another source file:

#include "cheater.h"

double const timeStamp = spillInfoToTimestamp(SpillInfo{});

this would fail linking because spillInfoToTimestamp would not be found anywhere.

[example faults: (1) for a template this should not be done in such way anyway (pretend it's not a template) and (2) the header where SpillInfo is declared needs to be included somewhere]

Comment on lines 788 to 794
if ( fBNBInfoEventMap.find(info.event)==fBNBInfoEventMap.end() ) {
fBNBInfoEventMap[info.event] = info;
}
else if ( (info.spill_time_s+(info.spill_time_ns/1.0e9)) >
(fBNBInfoEventMap[info.event].spill_time_s+(fBNBInfoEventMap[info.event].spill_time_ns/1.0e9)) ) {
fBNBInfoEventMap[info.event] = info;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor point: optimisation to reduce lookups in the map:

Suggested change
if ( fBNBInfoEventMap.find(info.event)==fBNBInfoEventMap.end() ) {
fBNBInfoEventMap[info.event] = info;
}
else if ( (info.spill_time_s+(info.spill_time_ns/1.0e9)) >
(fBNBInfoEventMap[info.event].spill_time_s+(fBNBInfoEventMap[info.event].spill_time_ns/1.0e9)) ) {
fBNBInfoEventMap[info.event] = info;
}
auto const iInfo = fBNBInfoEventMap.find(info.event);
if ( iInfo==fBNBInfoEventMap.end() ) {
fBNBInfoEventMap[info.event] = info;
}
else if ( (info.spill_time_s+(info.spill_time_ns/1.0e9)) >
(iInfo->spill_time_s+(iInfo->spill_time_ns/1.0e9)) ) {
*iInfo = info;
}

Another approach is a bit more convoluted:

Suggested change
if ( fBNBInfoEventMap.find(info.event)==fBNBInfoEventMap.end() ) {
fBNBInfoEventMap[info.event] = info;
}
else if ( (info.spill_time_s+(info.spill_time_ns/1.0e9)) >
(fBNBInfoEventMap[info.event].spill_time_s+(fBNBInfoEventMap[info.event].spill_time_ns/1.0e9)) ) {
fBNBInfoEventMap[info.event] = info;
}
auto& storedInfo = fBNBInfoEventMap[info.event];
if (storedInfo.event == UINT_MAX) { // no info
storedInfo = info;
}
else if ( (info.spill_time_s+info.spill_time_ns/1.0e9) >
(storedInfo.spill_time_s+storedInfo.spill_time_ns/1.0e9)) ) {
storedInfo = info;
}

which relies on the fact that a default-constructed SpillInfo object has an event number UINT_MAX; or, merging with the other suggestion:

Suggested change
if ( fBNBInfoEventMap.find(info.event)==fBNBInfoEventMap.end() ) {
fBNBInfoEventMap[info.event] = info;
}
else if ( (info.spill_time_s+(info.spill_time_ns/1.0e9)) >
(fBNBInfoEventMap[info.event].spill_time_s+(fBNBInfoEventMap[info.event].spill_time_ns/1.0e9)) ) {
fBNBInfoEventMap[info.event] = info;
}
auto& storedInfo = fBNBInfoEventMap[info.event]; // creates if needed
if ((storedInfo.event == UINT_MAX) // no info
|| spillInfoToTimestamp(info) > spillInfoToTimestamp(storedInfo) // newer
{
storedInfo = std::move(info);
}

std::cout << "Found > 0 BNBInfo size and NuMIInfo size, which seems strange. Will not fill event-specific spill quality info for this event..." << std::endl;
}
else if ( fHasBNBInfo ) {
if ( fBNBInfoEventMap.find(evt.id().event()) == fBNBInfoEventMap.end() )
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or, more intelligible:

Suggested change
if ( fBNBInfoEventMap.find(evt.id().event()) == fBNBInfoEventMap.end() )
unsigned int const eventNo = evt.id().event();
if ( fBNBInfoEventMap.count(eventNo) == 0 )

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wait shouldn't count > 0 if fHasBNBInfo ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That count "counts" the number of entries in the map for eventNo: there may be some information (in which case presumably fHasBNBInfo is true), but the one for eventNo might be missing, in which case that count(eventNo) returns 0.
I would call that situation a problem, but technically it is possible.

else rec.hdr.spillbnbinfo = makeSRBNBInfo(fBNBInfoEventMap.at(evt.id().event()));
}
else if ( fHasNuMIInfo ) {
if ( fNuMIInfoEventMap.find(evt.id().event()) == fNuMIInfoEventMap.end() )
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto.

@brucehoward-physics
Copy link
Contributor Author

@PetrilloAtWork does what I just pushed address your idea with the count() correctly or not quite?

Tried to address other points as well, let me know if something misses the mark. Thanks for the suggestions! (Will be running a test to see that I get the same POT values or something else as with my previous test.)

auto const & raw_data = (*raw_data_ptr);

// NOTE: Really we should skip the first event of each trigger type, so let's make this look at that too...
if ( raw_data.size()==0 ) return;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't believe I missed one of my favourite pet peeves!

Suggested change
if ( raw_data.size()==0 ) return;
if ( raw_data.empty() ) return;

@PetrilloAtWork PetrilloAtWork self-requested a review November 17, 2023 00:31
Copy link
Member

@PetrilloAtWork PetrilloAtWork left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I confirm the approval.

@miquelnebot
Copy link
Contributor

@brucehoward-physics @PetrilloAtWork Is this still needed for the " current ICARUS production" or as been discussed can go into develop and into the soon coming new production release?

@PetrilloAtWork
Copy link
Member

@brucehoward-physics @PetrilloAtWork Is this still needed for the " current ICARUS production" or as been discussed can go into develop and into the soon coming new production release?

I hereby summon @SFBayLaser since I definitely don't have knowledge current enough to answer.

@brucehoward-physics
Copy link
Contributor Author

I'm seeing something slightly strange in my last test so probably best to not merge just yet... I'll try to figure out what's going on (or re-do the test?)...

@brucehoward-physics
Copy link
Contributor Author

brucehoward-physics commented Dec 7, 2023

I don't know what happened with my initial attempted retest where things didn't seem to add up but I am getting the same output POT I got the first time, so I'm back to thinking this is okay... I even added the fix for @PetrilloAtWork 's preference to use empty()

@brucehoward-physics
Copy link
Contributor Author

brucehoward-physics commented Feb 21, 2025

@kjplows I see this got assigned to me. I had to go back and try to remember, but I think this PR can just be closed (🤔)

See e.g. #407

but maybe someone else here remembers if there was a reason to keep this version around?

@kjplows
Copy link
Contributor

kjplows commented Mar 26, 2025

Hi @brucehoward-physics , since I haven't heard anyone object and #407 got merged, I am closing this PR now. Many thanks!

@kjplows kjplows closed this Mar 26, 2025
@github-project-automation github-project-automation bot moved this from Needs revisiting to Done in SBN software development Mar 26, 2025
@kjplows kjplows moved this from Done to 2025 PRs in SBN software development Jan 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

Status: 2025 PRs

Development

Successfully merging this pull request may close these issues.

6 participants