Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
4 changes: 3 additions & 1 deletion sbnobj/Common/PMT/Data/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
cet_make_library(
SOURCE
PMTBeamSignal.cxx
PMTconfiguration.cxx
V1730Configuration.cxx
V1730channelConfiguration.cxx
LIBRARIES
lardataobj::RawData
messagefacility::MF_MessageLogger
lardataobj::RawData
)

art_dictionary(DICTIONARY_LIBRARIES sbnobj::Common_PMT_Data)
Expand Down
128 changes: 128 additions & 0 deletions sbnobj/Common/PMT/Data/PMTBeamSignal.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
/**
* @file sbnobj/Common/PMT/Data/PMTBeamSignal.cxx
* @brief Holds the event-by-event RWM or EW times
* @author Anna Heggestuen (aheggest@colostate.edu), adapted from M. Vincenzi in https://github.com/SBNSoftware/icaruscode/pull/751
Comment thread
aheggest marked this conversation as resolved.
Outdated
* @date May 19, 2025
* @see sbnobj/Common/PMT/Data/PMTBeamSignal.h
*/

//library header
#include "sbnobj/Common/PMT/Data/PMTBeamSignal.hh"

// framework libraries
#include "messagefacility/MessageLogger/MessageLogger.h"

// C/C++ standard libraries
#include <iostream>
Comment thread
aheggest marked this conversation as resolved.
Outdated

// -----------------------------------------------------------------------------
void sbn::timing::SelectFirstOpHitByTime(const recob::OpHit* const hit,
std::map<int, double> &startmap,
std::map<int, double> &risemap)
Comment thread
aheggest marked this conversation as resolved.
{
const int ch = hit->OpChannel();
double ts = hit->StartTime();
double tr = hit->RiseTime();
// select the first ophit (by time) in each channel
if (startmap.find(ch) != startmap.end())
{
if (ts < startmap[ch])
{
startmap[ch] = ts;
risemap[ch] = ts + tr;
}
}
else
{
startmap[ch] = ts;
risemap[ch] = ts + tr;
}
}
// -----------------------------------------------------------------------------
int sbn::timing::getSideByChannel(const int channel)
{
/*
Channels are numbered from east to west, from North (cryo side) to South (beam side)
We look in the opposide direction wrt to the beam direction South->North:
- Left is the east wall of each cryostat;
- Right is the west side of each cryostat;
- [ 0:89 ] and [180:269] are on the left,
the return value of the function is 0;
- [ 90-179 ] and [ 270:359 ] are on the right,
the return value of the function is 1;
*/

int side = channel / 90; // always round down
return side % 2;
}

// -----------------------------------------------------------------------------
double sbn::timing::getFlashBunchTime(std::map<int, double> startmap,
std::map<int, double> risemap,
std::vector<sbn::timing::PMTBeamSignal> RWMTimes)
Comment thread
aheggest marked this conversation as resolved.
Outdated
{
// if no RWM info available, all pmt_start_time_rwm are invalid
// return icarus::timing::NoTime as well for the flash
if (RWMTimes.empty())
return sbn::timing::NoTime;

std::vector<int> channels;
std::vector<double> hit_rise_time_rwm;
for (auto it = startmap.begin(); it != startmap.end(); it++){
int ch = it->first;
channels.push_back(ch);
auto rwm = RWMTimes.at(ch);
if (!rwm.isValid()){
mf::LogTrace("PMTBeamSignal getFlashBunchTime") << "No RWM signal for channel " << ch << " "
<< "(Crate " << rwm.crate << ", Board " << rwm.digitizerLabel
<< ", SpecialChannel " << rwm.specialChannel << ")\n";
}
float rwm_trigger = rwm.startTime; // rwm time w.r.t. trigger time [us]
hit_rise_time_rwm.push_back(risemap[ch] - rwm_trigger);
}

double tfirst_left = std::numeric_limits<double>::max();
double tfirst_right = std::numeric_limits<double>::max();

int nleft = 0;
int nright = 0;
for(std::size_t i = 0; i < hit_rise_time_rwm.size(); i++){
int ch = channels[i];
int side = sbn::timing::getSideByChannel(ch);
//int side = (ch / 90) % 2 ; //move this to a function as Matteo did to keep doc clear
double t = hit_rise_time_rwm[i]; // rise time w.r.t. rwm

// if any RWM copy is missing (therefore missing for an entire PMT crate),
// it might not be possible to use the first hits (they might not have a RMW time)
// so return icarus::timing::NoTime as in other bad cases
if (!RWMTimes[i].isValid())
return sbn::timing::NoTime;

// count hits separetely on the two walls
if (side == 0)
{
nleft++;
if (t < tfirst_left)
tfirst_left = t;
}
else if (side == 1)
{
nright++;
if (t < tfirst_right)
tfirst_right = t;
}
} //end loop over m_hit_rise_time_rwm vector

// if there are no hits in one of the walls... very rare?
if (nleft < 1 || nright < 1)
{
mf::LogWarning("PMTBeamSignal getFlashBunchTime") << "Flash doesn't have hits on both walls!"
<< "Left: " << nleft << " t " << tfirst_left << " "
<< "Right: " << nright << " t " << tfirst_right;
// return what we have...
return (tfirst_left < tfirst_right) ? tfirst_left : tfirst_right;
}

return (tfirst_left + tfirst_right) / 2.;

}
85 changes: 85 additions & 0 deletions sbnobj/Common/PMT/Data/PMTBeamSignal.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/**
* @file sbnobj/Common/PMT/Data/PMTBeamSignal.hh (moved from icaruscode/IcarusObj/PMTBeamSignal.h)
* @brief Holds the event-by-event RWM or EW times
* @author Matteo Vicenzi (mvicenzi@bnl.gov)
* @date March 14 2024, updated May 2025
*/

#ifndef SBNOBJ_COMMON_PMT_DATA_PMTBEAMSIGNAL_HH
#define SBNOBJ_COMMON_PMT_DATA_PMTBEAMSIGNAL_HH

// LArSoft libraries
#include "lardataobj/RecoBase/OpHit.h"

// C/C++ standard libraries
#include <limits>
#include <string>
#include <vector>
#include <map>
#include <cstddef>
#include <iostream> //remove after testing
Comment thread
aheggest marked this conversation as resolved.
Outdated

namespace sbn::timing
{

/// Special value to denote no special channel information.
static constexpr auto NoChannel = std::numeric_limits<unsigned int>::max();
/// Special value to denote no time channel information.
static constexpr double NoTime = std::numeric_limits<double>::max();
// Special value to denote no sample information.
static constexpr std::size_t NoSample = 0;

void SelectFirstOpHitByTime(const recob::OpHit* const hit,
std::map<int, double> &startmap,
std::map<int, double> &risemap);

int getSideByChannel(const int channel);

/**
* @brief Beam time as seen by a PMT readout board.
*
* This could either be an early warning (EW) or a resistive wall monitor (RWM) time.
* These signals are delivered via fibers and digitized in special PMT channels.
*
* Both the time in @ref DetectorClocksElectronicsTime "electronics time scale"
* and time time relative to the hardware trigger are included.
*
* The information in this object may be missing: its validity should
* always be checked in advance with `isValid()`.
*/

struct PMTBeamSignal
{

/// Special channel this time was extracted from.
/// These are defined in `CAEN_V1730_setup_icarus.fcl`.
unsigned int specialChannel = NoChannel;

/// Board on which the special channel is on (e.g: WW-TOP-A).
/// Should match the same format as `icarusDB::PMTChannelInfo_t::digitizerLabel`.
std::string digitizerLabel = "";

/// Crate this time applies to (e.g.: WW-TOP).
/// Corresponds to the first part of `digitizerLabel`.
std::string crate = "";

/// Sample within the waveform where the reference signal is found.
std::size_t sample = NoSample;

/// Start time in electronics time [us].
double startTimeAbs = NoTime;

/// Start time relative to trigger time [us].
double startTime = NoTime;

/// Returns whether the time is valid.
bool isValid() const { return (sample != NoSample); }
};

double getFlashBunchTime(std::map<int, double> startmap,
std::map<int, double> risemap,
std::vector<PMTBeamSignal> RWMTimes);

} // namespace sbn::timing

#endif // SBNOBJ_COMMON_PMT_DATA_PMTBEAMSIGNAL_HH
1 change: 1 addition & 0 deletions sbnobj/Common/PMT/Data/classes.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

// SBN libraries
#include "sbnobj/Common/PMT/Data/PMTconfiguration.h"
#include "sbnobj/Common/PMT/Data/PMTBeamSignal.hh"

// framework libraries
#include "canvas/Persistency/Common/Ptr.h"
Expand Down
5 changes: 4 additions & 1 deletion sbnobj/Common/PMT/Data/classes_def.xml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,10 @@
<class name="art::Ptr<sbn::PMTconfiguration>"/>
<class name="art::Wrapper<sbn::PMTconfiguration>"/>


<!-- PMTBeamSignal classes -->
<class name ="art::Wrapper<vector<sbn::timing::PMTBeamSignal> >"/>
<class name ="sbn::timing::PMTBeamSignal"/>
<class name ="vector<sbn::timing::PMTBeamSignal>"/>
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
<!-- copy&paste templates for: -->
<!-- PROD -->
Expand Down