Skip to content
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
2 changes: 2 additions & 0 deletions fcl/reco/Stage0/Run2/partial/decodeTrigger_icarus.fcl
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "services_common_icarus.fcl"
#include "channelmapping_icarus.fcl"
#include "rootoutput_icarus.fcl"
#include "decoderdefs_icarus.fcl"

Expand All @@ -11,6 +12,7 @@ services: {

@table::icarus_geometry_services
DetectorClocksService: @local::icarus_detectorclocks
IICARUSChannelMap: @local::icarus_channelmappinggservice # from channelmapping_icarus.fcl
}


Expand Down
18 changes: 14 additions & 4 deletions icaruscode/Decode/ChannelMapping/ChannelMapDumper.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -168,12 +168,22 @@ void dumpPMTmapping(icarusDB::IICARUSChannelMapProvider const& mapping) {
<< " includes " << digitizerChannels.size()
<< " LArSoft channels between " << digitizerChannels.front().channelID
<< " and " << digitizerChannels.back().channelID
<< " [board channel index in brackets]:";
Pager pager{ 8 };
<< " [board channel info in brackets]:";
Pager pager{ 3 };
for(auto const & chInfo: digitizerChannels) {
if (pager.nextHasNewLine()) log << "\n ";
log << " " << std::setw(3) << chInfo.channelID
<< " [" << std::setw(3) << chInfo.digitizerChannelNo << "]";
log << " " << std::setw(3) << chInfo.channelID
<< " [" << chInfo.digitizerLabel << "@"
<< std::setfill('0') << std::setw(2) << chInfo.digitizerChannelNo;
if (chInfo.hasLVDSinfo()) {
log << ", LVDS:" << chInfo.LVDSconnector << "-"
<< std::setw(2) << chInfo.LVDSbit;
}
if (chInfo.hasAdderInfo()) {
log << ", adder:" << chInfo.adderConnector << "-"
<< std::setw(2) << chInfo.adderBit;
}
log << "]";
} // for channel

} // for fragment
Expand Down
92 changes: 66 additions & 26 deletions icaruscode/Decode/ChannelMapping/ChannelMapPostGres.cxx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* @file icaruscode/Decode/ChannelMapping/ChannelMapPostGres.cxx
* @brief Interface with ICARUS channel mapping PostGres database.
* @author T. Usher (factorised by Gianluca Petrillo, petrillo@slac.stanford.edu)
* @author T. Usher (factorised by G. Petrillo, petrillo@slac.stanford.edu)
* @see icaruscode/Decode/ChannelMapping/ChannelMapPostGres.h
*/

Expand Down Expand Up @@ -230,15 +230,15 @@ int icarusDB::ChannelMapPostGres::BuildTPCFragmentIDToReadoutIDMap
// Note that the fragment ID is stored in the database as a string which
// reads as a hex number, meaning we have to read back as a string and
// decode to get the numerical value
Expected const fragmentIDString
util::Expected const fragmentIDString
= getStringFromTuple(tuple, FragmentIDcolumn);
if (!fragmentIDString) {
throw myException() << "Error (code: " << fragmentIDString.code()
throw myException() << "Error (code: " << fragmentIDString.error()
<< " on row " << row
<< ") retrieving TPC fragment ID from channel mapping database\n";
}

unsigned int const fragmentID = std::stol(fragmentIDString, nullptr, 16);
unsigned int const fragmentID = std::stol(*fragmentIDString, nullptr, 16);
if (!(fragmentID & tpcIdentifier)) continue;

if (fragmentBoardMap.find(fragmentID) == fragmentBoardMap.end()) {
Expand All @@ -251,16 +251,17 @@ int icarusDB::ChannelMapPostGres::BuildTPCFragmentIDToReadoutIDMap
}

// build the flange name
Expected const chimneyNoString = getStringFromTuple(tuple, ChimneyNoColumn);
util::Expected const chimneyNoString
= getStringFromTuple(tuple, ChimneyNoColumn);
if (!chimneyNoString) {
throw myException() << "Error (code: " << chimneyNoString.code()
throw myException() << "Error (code: " << chimneyNoString.error()
<< " on row " << row
<< ") retrieving chimney number from channel mapping database\n";
}

Expected const TPCIDstring = getStringFromTuple(tuple, TPCIDcolumn);
util::Expected const TPCIDstring = getStringFromTuple(tuple, TPCIDcolumn);
if (!TPCIDstring) {
throw myException() << "Error (code: " << TPCIDstring.code()
throw myException() << "Error (code: " << TPCIDstring.error()
<< " on row " << row
<< ") retrieving TPC tag from channel mapping database\n";
}
Expand Down Expand Up @@ -358,14 +359,14 @@ int icarusDB::ChannelMapPostGres::BuildTPCReadoutBoardToChannelMap
}

// Recover the plane identifier
Expected const fragmentBuffer
util::Expected const fragmentBuffer
= getStringFromTuple(tuple, PlaneIdentifierColumn);
if (!fragmentBuffer) {
throw myException() << "Error (code: " << fragmentBuffer.code()
throw myException() << "Error (code: " << fragmentBuffer.error()
<< " on row " << row << ") reading plane type\n";
}
// Make sure lower case... (sigh...)
unsigned int const plane = TPCplaneIdentifierToPlane(fragmentBuffer);
unsigned int const plane = TPCplaneIdentifierToPlane(*fragmentBuffer);
if (plane >= 3) {
mf::LogError{ "ChannelMapSQLite" } << "YIKES!!! Plane is " << plane
<< " for channel " << channelID << " with type "
Expand Down Expand Up @@ -415,11 +416,13 @@ int icarusDB::ChannelMapPostGres::BuildPMTFragmentToDigitizerChannelMap
// input is C-strings; we force the other term of comparison to C++ strings
using namespace std::string_literals;
auto const [
ChannelIDcolumn, LaserChannelColumn, DigitizerColumn,
DigitizerChannelNoColumn, FragmentIDcolumn
LaserChannelColumn, DigitizerChannelColumn, ChannelIDcolumn,
FragmentIDcolumn, DigitizerLabelColumn, LVDSconnectorColumn,
AdderConnectorColumn
]= details::WDAPositionFinder{ getTuple(dataset, 0) }(
"channel_id"s, "light_fiber_label"s, "digitizer_label"s,
"digitizer_ch_number"s, "fragment_id"s
"light_fiber_label"s, "digitizer_ch_number"s, "channel_id"s,
"fragment_id"s, "digitizer_label"s, "FPGA_connector_DIO"s,
"adder_connector_DIO"s
);

// Ok, now we can start extracting the information
Expand All @@ -432,16 +435,18 @@ int icarusDB::ChannelMapPostGres::BuildPMTFragmentToDigitizerChannelMap

int error = 0;

// nice... and currently unused
Expected const digitizerLabel = getStringFromTuple(tuple, DigitizerColumn);
PMTChannelInfo_t chInfo;
auto const nFields = static_cast<std::size_t>(getNfields(tuple));

// digitizer label
util::Expected const digitizerLabel
= getStringFromTuple(tuple, DigitizerLabelColumn);
if (!digitizerLabel) {
throw myException() << "Error (code: " << digitizerLabel.code()
throw myException() << "Error (code: " << digitizerLabel.error()
<< " on row " << row
<< ") retrieving PMT digitizer from channel mapping database\n";
}


PMTChannelInfo_t chInfo;
chInfo.digitizerLabel = *digitizerLabel;

// fragment id
unsigned long const fragmentID
Expand All @@ -453,7 +458,7 @@ int icarusDB::ChannelMapPostGres::BuildPMTFragmentToDigitizerChannelMap

// digitizer channel number
chInfo.digitizerChannelNo
= getLongValue(tuple, DigitizerChannelNoColumn, &error);
= getLongValue(tuple, DigitizerChannelColumn, &error);
if (error) {
throw myException() << "Error (code: " << error << " on row " << row
<< ") reading PMT readout board channel number\n";
Expand All @@ -466,15 +471,50 @@ int icarusDB::ChannelMapPostGres::BuildPMTFragmentToDigitizerChannelMap
<< ") reading PMT channel ID\n";
}
// laser channel number
Expected laserChannelLabel = getStringFromTuple(tuple, LaserChannelColumn);
util::Expected laserChannelLabel
= getStringFromTuple(tuple, LaserChannelColumn);
if (!laserChannelLabel) {
throw myException() << "Error (code: " << laserChannelLabel.code()
throw myException() << "Error (code: " << laserChannelLabel.error()
<< " on row " << row
<< ") retrieving PMT laser channel from channel mapping database\n";
}
// will throw on error:
chInfo.laserChannelNo = std::stol(laserChannelLabel.value().substr(2));

// LVDS connector and bit
if (LVDSconnectorColumn < nFields) {
util::Expected LVDSconnectorLabel
= getStringFromTuple(tuple, LVDSconnectorColumn);
if (!LVDSconnectorLabel) {
throw myException() << "Error (code: " << LVDSconnectorLabel.error()
<< " on row " << row
<< ") retrieving LVDS connector from channel mapping database\n";
}
if (!LVDSconnectorLabel->empty() && (*LVDSconnectorLabel != "-")) {
auto const [ LVDSconnector, LVDSbit ]
= splitIntegers<2, unsigned short int>(*LVDSconnectorLabel, "-");
chInfo.LVDSconnector = LVDSconnector;
chInfo.LVDSbit = LVDSbit;
}
}

// adder connector and bit
if (AdderConnectorColumn < nFields) {
util::Expected adderConnectorLabel
= getStringFromTuple(tuple, AdderConnectorColumn);
if (!adderConnectorLabel) {
throw myException() << "Error (code: " << adderConnectorLabel.error()
<< " on row " << row
<< ") retrieving adder connector from channel mapping database\n";
}
if (!adderConnectorLabel->empty() && (*adderConnectorLabel != "-")) {
auto const [ adderConnector, adderBit ]
= splitIntegers<2, unsigned short int>(*adderConnectorLabel, "-");
chInfo.adderConnector = adderConnector;
chInfo.adderBit = adderBit;
}
}

// fill the map
fragmentToDigitizerChannelMap[fragmentID].push_back(std::move(chInfo));

Expand Down Expand Up @@ -705,8 +745,8 @@ bool icarusDB::ChannelMapPostGres::printDatasetError

// -----------------------------------------------------------------------------
template <std::size_t BufferSize /* = 32 */>
auto icarusDB::ChannelMapPostGres::getStringFromTuple
(details::WDATuple const& tuple, std::size_t column) -> Expected<std::string>
util::Expected<std::string> icarusDB::ChannelMapPostGres::getStringFromTuple
(details::WDATuple const& tuple, std::size_t column)
{
int error = 0;
std::string buffer(BufferSize, '\0');
Expand Down
32 changes: 3 additions & 29 deletions icaruscode/Decode/ChannelMapping/ChannelMapPostGres.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* @file icaruscode/Decode/ChannelMapping/ChannelMapPostGres.h
* @brief Interface with ICARUS channel mapping PostGres database.
* @author T. Usher (factorised by Gianluca Petrillo, petrillo@slac.stanford.edu)
* @author T. Usher (factorised by G. Petrillo, petrillo@slac.stanford.edu)
* @see icaruscode/Decode/ChannelMapping/ChannelMapPostGres.cxx
*/

Expand All @@ -12,6 +12,7 @@
// ICARUS libraries
#include "icaruscode/Decode/ChannelMapping/IChannelMapping.h"
#include "icaruscode/Decode/ChannelMapping/RunPeriods.h"
#include "icaruscode/Utilities/Expected.h"
#include "icarusalg/Utilities/mfLoggingClass.h"

// framework libraries
Expand Down Expand Up @@ -133,33 +134,6 @@ class icarusDB::ChannelMapPostGres
virtual int BuildSideCRTCalibrationMap(SideCRTChannelToCalibrationMap&) const override;

private:

/// Loosely based on C++-20 `std::expected`.
template <typename T, typename E = int>
class Expected {
std::variant<T, E> fValue;
public:
constexpr Expected(E e = E{}): fValue{ std::move(e) } {}
constexpr Expected(T t): fValue{ std::move(t) } {}

Expected<T, E>& operator= (E e) { fValue = std::move(e); return *this; }
Expected<T, E>& operator= (T t) { fValue = std::move(t); return *this; }
template <typename... Args>
T& emplace(Args&&... args)
{ return fValue.emplace(std::forward<Args>(args)...); }

bool has_value() const { return std::holds_alternative<T>(fValue); }

E code() const { return std::get<E>(fValue); }
T const& value() const { return std::get<T>(fValue); }

operator T const& () const { return value(); }
T const& operator*() const { return value(); }

explicit operator bool() const { return has_value(); }

}; // Expected


// --- BEGIN --- Configuration parameters ------------------------------------

Expand Down Expand Up @@ -225,7 +199,7 @@ class icarusDB::ChannelMapPostGres
/// Returns the string on the specified `column` of the `tuple`.
/// @return the requested string, or an error code from libwda on error
template <std::size_t BufferSize = 32>
static Expected<std::string> getStringFromTuple
static util::Expected<std::string> getStringFromTuple
(details::WDATuple const& tuple, std::size_t column);

/// Returns an exception object pre-approved with our signature.
Expand Down
49 changes: 42 additions & 7 deletions icaruscode/Decode/ChannelMapping/ChannelMapSQLite.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
// C++ standard libraries
#include <algorithm> // std::transform()
#include <string>
#include <string_view>
#include <memory>
#include <cctype> // std::tolower()

Expand Down Expand Up @@ -450,19 +451,23 @@ int icarusDB::ChannelMapSQLite::buildPMTFragmentToDigitizerChannelMap_callback
// input is C-strings; we force the other term of comparison to C++ strings
using namespace std::string_literals;
auto const [
LaserChannelColumn, DigitizerChannelColumn, ChannelIDcolumn,
FragmentIDcolumn
LaserChannelColumn, DigitizerChannelColumn, ChannelIDcolumn,
FragmentIDcolumn, DigitizerLabelColumn, LVDSconnectorColumn,
AdderConnectorColumn
] = icarus::ns::util::PositionFinder{ gsl::span{azColName, (unsigned) argc} }(
"light_fiber_label"s, "digitizer_ch_number"s, "channel_id"s,
"fragment_id"s
"light_fiber_label"s, "digitizer_ch_number"s, "channel_id"s,
"fragment_id"s, "digitizer_label"s, "FPGA_connector_DIO"s,
"adder_connector_DIO"s
);

auto& fragmentToDigitizerChannelMap
= *static_cast<PMTFragmentToDigitizerChannelMap*>(dataOut);

// Start extracting info
unsigned int const fragmentID = std::stol(argv[FragmentIDcolumn]);
unsigned int const digitizerChannelNo = std::stol(argv[DigitizerChannelColumn]);
std::string digitizerLabel = argv[DigitizerLabelColumn];
unsigned int const digitizerChannelNo
= std::stol(argv[DigitizerChannelColumn]);
unsigned int const channelID = std::stol(argv[ChannelIDcolumn]);

// Read the laser channel; format is `L-<number>`. <number> is int from [1-41]
Expand All @@ -476,10 +481,40 @@ int icarusDB::ChannelMapSQLite::buildPMTFragmentToDigitizerChannelMap_callback
<< "Failed to convert laser channel '" << laserChannelLabel
<< "' into a channel number for channel " << channelID << "!\n";
}

// connector bits; if the column is not present or if the value is empty or
// just "-", fall back to invalid values
auto const isValidConnectorBit = [argv,argc](std::size_t column)
{
if (column >= (std::size_t) argc) return false;
std::string_view const value = argv[column];
return !value.empty() && (value != "-");
};

// PMT discriminated signal connector and bit;
auto const [ LVDSconnector, LVDSbit ]
= isValidConnectorBit(LVDSconnectorColumn)
? splitIntegers<2, unsigned short int>(argv[LVDSconnectorColumn], "-")
: std::array
{ PMTChannelInfo_t::NoConnector, PMTChannelInfo_t::NoConnectorBit }
;

// adder discriminated signal connector and bit
// if the column is not present or if the value is empty or "-", fall back
auto const [ adderConnector, adderBit ]
= isValidConnectorBit(AdderConnectorColumn)
? splitIntegers<2, unsigned short int>(argv[AdderConnectorColumn], "-")
: std::array
{ PMTChannelInfo_t::NoConnector, PMTChannelInfo_t::NoConnectorBit }
;

// Fill the map
fragmentToDigitizerChannelMap[fragmentID].push_back
({ digitizerChannelNo, channelID, laserChannel });
fragmentToDigitizerChannelMap[fragmentID].push_back({ // C++20: name members
std::move(digitizerLabel), digitizerChannelNo,
channelID, laserChannel,
LVDSconnector, LVDSbit,
adderConnector, adderBit
});

return 0;
} // ...::ChannelMapSQLite::buildPMTFragmentToDigitizerChannelMap_callback()
Expand Down
Loading