1
0
Fork 0
mirror of https://github.com/gwm17/Specter.git synced 2024-11-26 12:18:51 -05:00

Overhaul data id system. Now use a pairing function to map board-channel info to a unique id.

This commit is contained in:
Gordon McCann 2022-10-01 15:13:36 -04:00
parent a26ac08f34
commit c0b51c5ba9
11 changed files with 93 additions and 25 deletions

View File

@ -15,10 +15,12 @@ namespace Specter {
beamIntegrator("beamIntegrator") beamIntegrator("beamIntegrator")
{ {
SPEC_PROFILE_FUNCTION(); SPEC_PROFILE_FUNCTION();
//Bind some parameters
manager->BindParameter(delayFLTime); manager->BindParameter(delayFLTime);
manager->BindParameter(delayFRTime); manager->BindParameter(delayFRTime);
manager->BindParameter(delayBLTime); manager->BindParameter(delayBLTime);
manager->BindParameter(delayBRTime); manager->BindParameter(delayBRTime);
//Bind parameters with some default histograms. Saves us the effort of making them in the UI. //Bind parameters with some default histograms. Saves us the effort of making them in the UI.
manager->BindParameter(x1, 600, -300.0, 300.0); manager->BindParameter(x1, 600, -300.0, 300.0);
manager->BindParameter(x2, 600, -300.0, 300.0); manager->BindParameter(x2, 600, -300.0, 300.0);
@ -29,12 +31,24 @@ namespace Specter {
manager->BindParameter(cathode, 4096, 0.0, 4096); manager->BindParameter(cathode, 4096, 0.0, 4096);
manager->BindParameter(xavg_sabreCoinc, 600, -300.0, 300.0); manager->BindParameter(xavg_sabreCoinc, 600, -300.0, 300.0);
std::vector<std::string> sabre_list; //Example of injecting experiment specific info. I know that SABRE is only used in 16 channel digitizers,
for (int i = 0; i < 127; i++) //so I can make a simple incremental id for use with the UI so that the parameter names are human readable. We map this "simple" id
//to the more robust and universal Specter board/channel UUID using a std::unordered_map
//This is kind of a really simple example of injecting a channel map; more complicated and advanced versions could involve reading
//a text file to get detector ID information, detector channel number, etc.
std::vector<std::string> sabre_list; //list of names will allow us to create a summary histogram.
uint32_t uuid;
for (uint32_t board = 0; board < 7; board++)
{ {
sabre_list.push_back("sabre_" + std::to_string(i)); for (uint32_t channel = 0; channel < 16; channel++)
sabre.emplace_back(sabre_list[i]); {
manager->BindParameter(sabre[i]); //ImGui & spdlog come prepackaged with the fmt library, so make good use of it!
sabre_list.push_back(fmt::format("sabre_%d", board*16 + channel));
uuid = Utilities::GetBoardChannelUUID(board, channel);
sabre[uuid] = Parameter(sabre_list.back());
manager->BindParameter(sabre[uuid]);
}
} }
//If you want to make a histogram default available, you can add one like this. //If you want to make a histogram default available, you can add one like this.
@ -52,70 +66,78 @@ namespace Specter {
//Do some physics! //Do some physics!
void SPSAnalysisStage::AnalyzePhysicsEvent(const SpecEvent& event) void SPSAnalysisStage::AnalyzePhysicsEvent(const SpecEvent& event)
{ {
SPEC_PROFILE_FUNCTION(); SPEC_PROFILE_FUNCTION();
//You might want some flags for coincidence cases
//Use statics to avoid allocating extra memory each call (these pipeline functions are called a lot!)
static bool sabreFlag;
//Most analysis stages will start kinda like this. Take the raw event data and //Most analysis stages will start kinda like this. Take the raw event data and
//put it into NavParameters using the hit id. Switches are perfect for this. Can also //put it into Specter::Parameters using the hit id. Switches are perfect for this. Can also
//create mapping classes to use text-file-based id association (commonly called channel maps). //create mapping classes to use text-file-based id association (commonly called channel maps).
bool sabreFlag = false; sabreFlag = false;
for(auto& hit : event) for(auto& hit : event)
{ {
if (hit.id < 127) //Check the SABRE map first; use iterators from std::unordered_map.
//See std::unordered_map docs for more info if this sort of idiom is unfamiliar
auto iter = sabre.find(hit.id);
if (iter != sabre.end())
{ {
sabreFlag = true; sabreFlag = true;
if (hit.longEnergy > sabre[hit.id].GetValue()) if (hit.longEnergy > iter->second.GetValue())
sabre[hit.id].SetValue(hit.longEnergy); iter->second.SetValue(hit.longEnergy);
continue;
} }
switch (hit.id) switch (hit.id)
{ {
case 129: case s_scintLeftID:
{ {
if (hit.longEnergy > scintLeft.GetValue()) if (hit.longEnergy > scintLeft.GetValue())
scintLeft.SetValue(hit.longEnergy); scintLeft.SetValue(hit.longEnergy);
break; break;
} }
case 133: case s_beamIntID:
{ {
beamIntegrator.Increment(); beamIntegrator.Increment();
break; break;
} }
case 135: case s_cathodeID:
{ {
if (hit.longEnergy > cathode.GetValue()) if (hit.longEnergy > cathode.GetValue())
cathode.SetValue(hit.longEnergy); cathode.SetValue(hit.longEnergy);
break; break;
} }
case 136: case s_delayFrontLeftID:
{ {
if (!delayFLTime.IsValid()) if (!delayFLTime.IsValid())
delayFLTime.SetValue(hit.timestamp / 1.0e3); delayFLTime.SetValue(hit.timestamp / 1.0e3);
break; break;
} }
case 137: case s_delayFrontRightID:
{ {
if (!delayFRTime.IsValid()) if (!delayFRTime.IsValid())
delayFRTime.SetValue(hit.timestamp / 1.0e3); delayFRTime.SetValue(hit.timestamp / 1.0e3);
break; break;
} }
case 138: case s_delayBackLeftID:
{ {
if (!delayBLTime.IsValid()) if (!delayBLTime.IsValid())
delayBLTime.SetValue(hit.timestamp / 1.0e3); delayBLTime.SetValue(hit.timestamp / 1.0e3);
break; break;
} }
case 139: case s_delayBackRightID:
{ {
if (!delayBRTime.IsValid()) if (!delayBRTime.IsValid())
delayBRTime.SetValue(hit.timestamp / 1.0e3); delayBRTime.SetValue(hit.timestamp / 1.0e3);
break; break;
} }
case 141: case s_anodeFrontID:
{ {
if (hit.longEnergy > anodeFront.GetValue()) if (hit.longEnergy > anodeFront.GetValue())
anodeFront.SetValue(hit.longEnergy); anodeFront.SetValue(hit.longEnergy);
break; break;
} }
case 143: case s_anodeBackID:
{ {
if (hit.longEnergy > anodeBack.GetValue()) if (hit.longEnergy > anodeBack.GetValue())
anodeBack.SetValue(hit.longEnergy); anodeBack.SetValue(hit.longEnergy);

View File

@ -31,7 +31,9 @@ namespace Specter {
Parameter cathode; Parameter cathode;
Parameter xavg_sabreCoinc; Parameter xavg_sabreCoinc;
std::vector<Parameter> sabre; //For collections of parameters, prefer std::unordered_map or std::map over vector
//Better with use of UUIDs for board-channel pairs
std::unordered_map<uint32_t, Parameter> sabre;
//Create a few variables //Create a few variables
Variable x1_weight; Variable x1_weight;
@ -39,6 +41,19 @@ namespace Specter {
//Create a scaler //Create a scaler
Scaler beamIntegrator; Scaler beamIntegrator;
//Define some board-channel ID's that we'll use. The static keyword means that we only need to calculate them once,
//constexpr allows us to use them in a switch (and makes them compile time evaluated)
//Note that to make them static constexpr we use literals (i.e. hardcoded) in the arguments
static constexpr uint32_t s_scintLeftID = Utilities::GetBoardChannelUUID(8, 0);
static constexpr uint32_t s_beamIntID = Utilities::GetBoardChannelUUID(8, 5);
static constexpr uint32_t s_cathodeID = Utilities::GetBoardChannelUUID(8, 7);
static constexpr uint32_t s_delayFrontLeftID = Utilities::GetBoardChannelUUID(8, 8);
static constexpr uint32_t s_delayFrontRightID = Utilities::GetBoardChannelUUID(8, 9);
static constexpr uint32_t s_delayBackLeftID = Utilities::GetBoardChannelUUID(8, 10);
static constexpr uint32_t s_delayBackRightID = Utilities::GetBoardChannelUUID(8, 11);
static constexpr uint32_t s_anodeFrontID = Utilities::GetBoardChannelUUID(8, 13);
static constexpr uint32_t s_anodeBackID = Utilities::GetBoardChannelUUID(8, 15);
}; };
} }

View File

@ -103,6 +103,8 @@ target_sources(Specter PRIVATE
Specter/Physics/Daqromancy/DYFileSource.cpp Specter/Physics/Daqromancy/DYFileSource.cpp
Specter/Physics/Daqromancy/DYOnlineSource.h Specter/Physics/Daqromancy/DYOnlineSource.h
Specter/Physics/Daqromancy/DYOnlineSource.cpp Specter/Physics/Daqromancy/DYOnlineSource.cpp
Specter/Utils/Functions.h
Specter/Utils/Functions.cpp
) )
#ImPlot sources #ImPlot sources

View File

@ -34,5 +34,6 @@
#include "Specter/Events/Event.h" #include "Specter/Events/Event.h"
#include "Specter/Utils/TestServerLayer.h" #include "Specter/Utils/TestServerLayer.h"
#include "Specter/Utils/Instrumentor.h" #include "Specter/Utils/Instrumentor.h"
#include "Specter/Utils/Functions.h"
#endif #endif

View File

@ -82,7 +82,7 @@ namespace Specter {
m_datum.shortEnergy = m_currentHit.energyShort; m_datum.shortEnergy = m_currentHit.energyShort;
m_datum.calEnergy = m_currentHit.energyCalibrated; m_datum.calEnergy = m_currentHit.energyCalibrated;
m_datum.timestamp = m_currentHit.timestamp; m_datum.timestamp = m_currentHit.timestamp;
m_datum.id = m_currentHit.board * m_nchannels_per_board + m_currentHit.channel; m_datum.id = Utilities::GetBoardChannelUUID(m_currentHit.board, m_currentHit.channel);
return m_datum; return m_datum;
} }

View File

@ -147,7 +147,7 @@ namespace Specter {
m_datum.shortEnergy = m_hit.energyShort; m_datum.shortEnergy = m_hit.energyShort;
m_datum.calEnergy = m_hit.energyCalibrated; m_datum.calEnergy = m_hit.energyCalibrated;
m_datum.timestamp = m_hit.timestamp; m_datum.timestamp = m_hit.timestamp;
m_datum.id = m_hit.board * m_nchannels_per_board + m_hit.channel; m_datum.id = Utilities::GetBoardChannelUUID(m_hit.board, m_hit.channel);
} }
return m_datum; return m_datum;

View File

@ -108,7 +108,7 @@ namespace Specter {
m_datum.longEnergy = m_dyHit.energy; m_datum.longEnergy = m_dyHit.energy;
m_datum.shortEnergy = m_dyHit.energyShort; m_datum.shortEnergy = m_dyHit.energyShort;
m_datum.timestamp = m_dyHit.timestamp; m_datum.timestamp = m_dyHit.timestamp;
m_datum.id = m_dyHit.board * m_channelsPerBoard + m_dyHit.channel; m_datum.id = Utilities::GetBoardChannelUUID(m_dyHit.board, m_dyHit.channel);
} }
return m_datum; return m_datum;
} }

View File

@ -27,7 +27,7 @@ namespace Specter {
m_datum.longEnergy = m_dyHit.energy; m_datum.longEnergy = m_dyHit.energy;
m_datum.shortEnergy = m_dyHit.energyShort; m_datum.shortEnergy = m_dyHit.energyShort;
m_datum.timestamp = m_dyHit.timestamp; m_datum.timestamp = m_dyHit.timestamp;
m_datum.id = m_dyHit.board * m_channelsPerBoard + m_dyHit.channel; m_datum.id = Utilities::GetBoardChannelUUID(m_dyHit.board, m_dyHit.channel);
} }
else else
{ {

View File

@ -0,0 +1,8 @@
#include "Functions.h"
namespace Specter {
namespace Utilities {
}
}

View File

@ -0,0 +1,19 @@
#ifndef SPEC_FUNCTIONS_H
#define SPEC_FUNCTIONS_H
namespace Specter {
namespace Utilities
{
//Use Szudzik pairing function to convert board/channel number pair to a single universal unqiue identifier (UUID)
//Allows us to unqiuely id board-channel combo even with a set of boards that don't have the same number of channels
//It's constexpr, since for each board/channel pair the value should be evaluated at compile time (and allows us to use values in a switch)
//This is mostly syntactic sugar. When board and channel are constexpr (read: literals) it gives a constexpr value, otherwise behaves same as any other function
constexpr uint32_t GetBoardChannelUUID(uint32_t board, uint32_t channel)
{
return board >= channel ? (board * board + board + channel) : (channel * channel + board);
}
}
}
#endif

View File

@ -18,5 +18,6 @@
#include "Specter/Core/Logger.h" #include "Specter/Core/Logger.h"
#include "Specter/Utils/Instrumentor.h" #include "Specter/Utils/Instrumentor.h"
#include "Specter/Utils/Functions.h"
#endif #endif