mirror of
https://github.com/gwm17/Specter.git
synced 2024-11-22 18:28:52 -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:
parent
a26ac08f34
commit
c0b51c5ba9
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
8
Specter/src/Specter/Utils/Functions.cpp
Normal file
8
Specter/src/Specter/Utils/Functions.cpp
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
#include "Functions.h"
|
||||||
|
|
||||||
|
namespace Specter {
|
||||||
|
|
||||||
|
namespace Utilities {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
19
Specter/src/Specter/Utils/Functions.h
Normal file
19
Specter/src/Specter/Utils/Functions.h
Normal 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
|
|
@ -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
|
Loading…
Reference in New Issue
Block a user