1
0
Fork 0
mirror of https://github.com/gwm17/Specter.git synced 2025-01-30 18:28:51 -05:00

Several big changes. Biggest change: Added in Summary spectra!! Fully integrated into system. Changed spectrum and cut type identification to avoid extra string comps. Cut checking now handled differently, hopefully more efficiently (needs profiling). Renamed Resources to Assets to avoid Xcode weirdness

This commit is contained in:
Gordon McCann 2022-03-31 15:23:45 -04:00
parent a27ebfe6e0
commit b46df04c00
20 changed files with 732 additions and 214 deletions

View File

@ -14,7 +14,7 @@
*/
MassMap::MassMap()
{
std::ifstream massfile("Resources/amdc2016_mass.txt");
std::ifstream massfile("Assets/amdc2016_mass.txt");
if (massfile.is_open())
{
std::string junk, A, element;

View File

@ -23,13 +23,14 @@ namespace Navigator {
Cut1D::Cut1D(const CutParams& params, double min, double max) :
Cut(params), m_minVal(min), m_maxVal(max)
{
m_params.type = CutType::Cut1D;
}
Cut1D::~Cut1D() {}
bool Cut1D::IsInside(double x, double y) const
void Cut1D::IsInside(double x, double y)
{
return x >= m_minVal && x <= m_maxVal;
m_isValid = x >= m_minVal && x <= m_maxVal;
}
//Only within an ImPlot/ImGui context!!!
@ -43,6 +44,7 @@ namespace Navigator {
Cut2D::Cut2D(const CutParams& params, const std::vector<double>& xpoints, const std::vector<double>& ypoints) :
Cut(params), m_xpoints(xpoints), m_ypoints(ypoints)
{
m_params.type = CutType::Cut2D;
}
Cut2D::~Cut2D() {}
@ -54,24 +56,31 @@ namespace Navigator {
If odd number of intersections, point is inside. Even, point is outside.
Edge cases of point is a vertex or on a side considered.
*/
bool Cut2D::IsInside(double x, double y) const
void Cut2D::IsInside(double x, double y)
{
bool result = false;
m_isValid = false;
double slope;
for(size_t i=0; i<(m_xpoints.size()-1); i++)
{
if(x == m_xpoints[i+1] && y == m_ypoints[i+1])
return true;
if (x == m_xpoints[i + 1] && y == m_ypoints[i + 1])
{
m_isValid = true;
return;
}
else if((m_ypoints[i+1] > y) != (m_ypoints[i] > y))
{
slope = (x - m_xpoints[i+1])*(m_ypoints[i] - m_ypoints[i+1]) - (m_xpoints[i] - m_xpoints[i+1])*(y - m_ypoints[i+1]);
if(slope == 0.0)
return true;
else if ((slope < 0.0) != (m_ypoints[i] < m_ypoints[i+1]))
result = !result;
if (slope == 0.0)
{
m_isValid = true;
return;
}
else if ((slope < 0.0) != (m_ypoints[i] < m_ypoints[i + 1]))
{
m_isValid = !m_isValid;
}
}
}
return result;
}
//Only in ImPlot/ImGui context!!!!

View File

@ -22,6 +22,13 @@
namespace Navigator {
enum class CutType
{
Cut1D,
Cut2D,
None
};
struct NAV_API CutParams
{
CutParams() {}
@ -30,6 +37,7 @@ namespace Navigator {
{
}
CutType type = CutType::None;
std::string name = "None";
std::string x_par = "None";
std::string y_par = "None";
@ -40,25 +48,27 @@ namespace Navigator {
public:
Cut(const CutParams& params) :
m_params(params)
m_params(params), m_isValid(false)
{
}
virtual ~Cut() {}
virtual bool IsInside(double x, double y=0.0) const = 0;
virtual void IsInside(double x, double y=0.0) = 0;
virtual void Draw() const = 0;
virtual bool Is1D() const = 0;
virtual bool Is2D() const = 0;
virtual std::vector<double> GetXValues() const = 0;
virtual std::vector<double> GetYValues() const = 0;
inline const bool IsValid() const { return m_isValid; }
inline void ResetValidity() { m_isValid = false; }
inline CutType GetType() const { return m_params.type; }
inline const std::string& GetName() const { return m_params.name; }
inline const std::string& GetXParameter() const { return m_params.x_par; }
inline const std::string& GetYParameter() const { return m_params.y_par; }
inline const CutParams& GetCutParams() const { return m_params; }
protected:
CutParams m_params;
bool m_isValid;
};
class NAV_API Cut1D : public Cut
@ -66,10 +76,8 @@ namespace Navigator {
public:
Cut1D(const CutParams& params, double min, double max);
virtual ~Cut1D();
virtual bool IsInside(double x, double y=0.0) const override;
virtual void IsInside(double x, double y=0.0) override;
virtual void Draw() const override;
virtual bool Is1D() const override { return true; }
virtual bool Is2D() const override { return false; }
virtual std::vector<double> GetXValues() const override { return std::vector<double>({ m_minVal, m_maxVal }); }
virtual std::vector<double> GetYValues() const override { return std::vector<double>(); }
@ -82,10 +90,8 @@ namespace Navigator {
public:
Cut2D(const CutParams& params, const std::vector<double>& xpoints, const std::vector<double>& ypoints);
virtual ~Cut2D();
virtual bool IsInside(double x, double y) const override;
virtual void IsInside(double x, double y) override;
virtual void Draw() const override;
virtual bool Is1D() const override { return false; }
virtual bool Is2D() const override { return true; }
virtual std::vector<double> GetXValues() const override { return m_xpoints; }
virtual std::vector<double> GetYValues() const override { return m_ypoints; }

View File

@ -13,7 +13,8 @@
namespace Navigator {
SpectrumDialog::SpectrumDialog()
SpectrumDialog::SpectrumDialog() :
m_openFlag(false), m_openCutFlag(false)
{
selectFlags = ImGuiSelectableFlags_DontClosePopups;
}
@ -24,67 +25,38 @@ namespace Navigator {
bool SpectrumDialog::ImGuiRenderSpectrumDialog(const std::vector<HistogramParameters>& histoList, const std::vector<CutParams>& cutList, const std::vector<std::string>& paramList)
{
static int dims = 1;
static std::string selectedCut = "";
bool result = false;
if (m_openFlag)
{
m_newParams = m_blank;
m_openFlag = false;
dims = 1;
m_newParams = m_blank;
m_subhistos.clear();
ImGui::OpenPopup(ICON_FA_CHART_BAR " New Spectrum Dialog");
}
if (ImGui::BeginPopupModal(ICON_FA_CHART_BAR " New Spectrum Dialog"))
{
ImGui::InputText("Spectrum Name", &m_newParams.name);
ImGui::SliderInt("Dimensions", &dims, 1, 2);
if (ImGui::BeginTable("SpecParamsTable", 4))
if (ImGui::BeginCombo("Spectrum Type", ConvertSpectrumTypeToString(m_newParams.type).c_str()))
{
ImGui::TableNextRow();
ImGui::TableNextColumn();
if (ImGui::BeginCombo("X Param.", m_newParams.x_par.c_str()))
{
for (auto& params : paramList)
{
if (ImGui::Selectable(params.c_str(), params == m_newParams.x_par, selectFlags))
m_newParams.x_par = params;
}
ImGui::EndCombo();
}
ImGui::TableNextColumn();
ImGui::InputInt("X Bins", &m_newParams.nbins_x);
ImGui::TableNextColumn();
ImGui::InputDouble("Min X", &m_newParams.min_x);
ImGui::TableNextColumn();
ImGui::InputDouble("Max X", &m_newParams.max_x);
if (dims == 2)
{
ImGui::TableNextRow();
ImGui::TableNextColumn();
if (ImGui::BeginCombo("Y Param.", m_newParams.y_par.c_str()))
{
for (auto& params : paramList)
{
if (ImGui::Selectable(params.c_str(), params == m_newParams.y_par, selectFlags))
m_newParams.y_par = params;
}
ImGui::EndCombo();
}
ImGui::TableNextColumn();
ImGui::InputInt("Y Bins", &m_newParams.nbins_y);
ImGui::TableNextColumn();
ImGui::InputDouble("Min Y", &m_newParams.min_y);
ImGui::TableNextColumn();
ImGui::InputDouble("Max Y", &m_newParams.max_y);
}
ImGui::EndTable();
if (ImGui::Selectable("Histogram1D", m_newParams.type == SpectrumType::Histo1D, selectFlags))
m_newParams.type = SpectrumType::Histo1D;
else if (ImGui::Selectable("Histogram2D", m_newParams.type == SpectrumType::Histo2D, selectFlags))
m_newParams.type = SpectrumType::Histo2D;
else if (ImGui::Selectable("Summary", m_newParams.type == SpectrumType::Summary, selectFlags))
m_newParams.type = SpectrumType::Summary;
ImGui::EndCombo();
}
switch (m_newParams.type)
{
case SpectrumType::Histo1D: RenderDialog1D(paramList); break;
case SpectrumType::Histo2D: RenderDialog2D(paramList); break;
case SpectrumType::Summary: RenderDialogSummary(paramList); break;
case SpectrumType::None: break;
}
if (ImGui::TreeNode("Applied Cuts"))
{
for (auto& name : m_newParams.cutsAppliedTo)
@ -96,33 +68,19 @@ namespace Navigator {
if (ImGui::Button("Apply Cuts"))
{
selectedCut = "";
ImGui::OpenPopup("Cut List");
}
if (ImGui::BeginPopup("Cut List"))
{
for (auto& cut : cutList)
{
if (ImGui::Selectable(cut.name.c_str(), cut.name == selectedCut, selectFlags))
selectedCut = cut.name;
}
ImGui::InputText("Selected Cut", &selectedCut);
if (ImGui::Button("Ok"))
{
m_newParams.cutsAppliedTo.push_back(selectedCut);
ImGui::CloseCurrentPopup();
}
ImGui::SameLine();
if (ImGui::Button("Cancel"))
{
ImGui::CloseCurrentPopup();
}
ImGui::EndPopup();
m_openCutFlag = true;
}
RenderCutDialog(cutList);
if (ImGui::Button("Ok"))
{
SpectrumManager::GetInstance().AddHistogram(m_newParams);
switch (m_newParams.type)
{
case SpectrumType::Histo1D: SpectrumManager::GetInstance().AddHistogram(m_newParams); break;
case SpectrumType::Histo2D: SpectrumManager::GetInstance().AddHistogram(m_newParams); break;
case SpectrumType::Summary: SpectrumManager::GetInstance().AddHistogramSummary(m_newParams, m_subhistos); break;
case SpectrumType::None: break;
}
ImGui::CloseCurrentPopup();
result = true;
}
@ -136,4 +94,161 @@ namespace Navigator {
}
return result;
}
void SpectrumDialog::RenderDialog1D(const std::vector<std::string>& paramList)
{
if (ImGui::BeginTable("SpecParamsTable", 4))
{
ImGui::TableNextRow();
ImGui::TableNextColumn();
if (ImGui::BeginCombo("X Param.", m_newParams.x_par.c_str()))
{
for (auto& params : paramList)
{
if (ImGui::Selectable(params.c_str(), params == m_newParams.x_par, selectFlags))
m_newParams.x_par = params;
}
ImGui::EndCombo();
}
ImGui::TableNextColumn();
ImGui::InputInt("X Bins", &m_newParams.nbins_x);
ImGui::TableNextColumn();
ImGui::InputDouble("Min X", &m_newParams.min_x);
ImGui::TableNextColumn();
ImGui::InputDouble("Max X", &m_newParams.max_x);
ImGui::EndTable();
}
}
void SpectrumDialog::RenderDialog2D(const std::vector<std::string>& paramList)
{
if (ImGui::BeginTable("SpecParamsTable", 4))
{
ImGui::TableNextRow();
ImGui::TableNextColumn();
if (ImGui::BeginCombo("X Param.", m_newParams.x_par.c_str()))
{
for (auto& params : paramList)
{
if (ImGui::Selectable(params.c_str(), params == m_newParams.x_par, selectFlags))
m_newParams.x_par = params;
}
ImGui::EndCombo();
}
ImGui::TableNextColumn();
ImGui::InputInt("X Bins", &m_newParams.nbins_x);
ImGui::TableNextColumn();
ImGui::InputDouble("Min X", &m_newParams.min_x);
ImGui::TableNextColumn();
ImGui::InputDouble("Max X", &m_newParams.max_x);
ImGui::TableNextRow();
ImGui::TableNextColumn();
if (ImGui::BeginCombo("Y Param.", m_newParams.y_par.c_str()))
{
for (auto& params : paramList)
{
if (ImGui::Selectable(params.c_str(), params == m_newParams.y_par, selectFlags))
m_newParams.y_par = params;
}
ImGui::EndCombo();
}
ImGui::TableNextColumn();
ImGui::InputInt("Y Bins", &m_newParams.nbins_y);
ImGui::TableNextColumn();
ImGui::InputDouble("Min Y", &m_newParams.min_y);
ImGui::TableNextColumn();
ImGui::InputDouble("Max Y", &m_newParams.max_y);
ImGui::EndTable();
}
}
void SpectrumDialog::RenderDialogSummary(const std::vector<std::string>& paramList)
{
static std::string selectedParam = "";
if (ImGui::BeginTable("SpecParamsTable", 3))
{
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::InputInt("X Bins", &m_newParams.nbins_x);
ImGui::TableNextColumn();
ImGui::InputDouble("Min X", &m_newParams.min_x);
ImGui::TableNextColumn();
ImGui::InputDouble("Max X", &m_newParams.max_x);
ImGui::EndTable();
}
if (ImGui::TreeNode("Selected Parameters"))
{
for (auto& name : m_subhistos)
{
ImGui::BulletText("%s", name.c_str());
}
ImGui::TreePop();
}
if (ImGui::Button("Add Parameter"))
{
selectedParam = "";
ImGui::OpenPopup("Param List");
}
if (ImGui::BeginPopup("Param List"))
{
if (ImGui::BeginCombo("Parameter", selectedParam.c_str()))
{
for (auto& param : paramList)
{
if (ImGui::Selectable(param.c_str(), param == selectedParam, selectFlags))
selectedParam = param;
}
ImGui::EndCombo();
}
if (ImGui::Button("Ok"))
{
m_subhistos.push_back(selectedParam);
ImGui::CloseCurrentPopup();
}
ImGui::SameLine();
if (ImGui::Button("Cancel"))
{
ImGui::CloseCurrentPopup();
}
ImGui::EndPopup();
}
}
void SpectrumDialog::RenderCutDialog(const std::vector<CutParams>& cutList)
{
static std::string selectedCut = "";
if (m_openCutFlag)
{
selectedCut = "";
m_openCutFlag = false;
ImGui::OpenPopup("Cut List");
}
if (ImGui::BeginPopup("Cut List"))
{
for (auto& cut : cutList)
{
if (ImGui::Selectable(cut.name.c_str(), cut.name == selectedCut, selectFlags))
selectedCut = cut.name;
}
ImGui::InputText("Selected Cut", &selectedCut);
if (ImGui::Button("Ok"))
{
m_newParams.cutsAppliedTo.push_back(selectedCut);
ImGui::CloseCurrentPopup();
}
ImGui::SameLine();
if (ImGui::Button("Cancel"))
{
ImGui::CloseCurrentPopup();
}
ImGui::EndPopup();
}
}
}

View File

@ -25,9 +25,16 @@ namespace Navigator {
inline void SetSpectrumDialog() { m_openFlag = true; }
private:
void RenderDialog1D(const std::vector<std::string>& paramList);
void RenderDialog2D(const std::vector<std::string>& paramList);
void RenderDialogSummary(const std::vector<std::string>& paramList);
void RenderCutDialog(const std::vector<CutParams>& cutList);
bool m_openFlag;
bool m_openCutFlag;
HistogramParameters m_newParams;
HistogramParameters m_blank;
std::vector<std::string> m_subhistos;
ImGuiSelectableFlags selectFlags;
};

View File

@ -26,7 +26,7 @@ namespace Navigator {
}
SpectrumPanel::SpectrumPanel() :
m_zoomedFlag(false), m_cutModeFlag(false), m_zoomedGram(), m_totalSlots(1), m_nRegions(0)
m_zoomedFlag(false), m_cutModeFlag(false), m_acceptCutFlag(false), m_zoomedGram(), m_totalSlots(1), m_nRegions(0)
{
m_tableSizes[0] = 1; m_tableSizes[1] = 1;
}
@ -37,22 +37,25 @@ namespace Navigator {
bool SpectrumPanel::OnImGuiRender(const std::vector<HistogramParameters>& histoList, const std::vector<CutParams>& cutList, const std::vector<std::string>& paramList)
{
static bool acceptCutFlag = false;
bool result = false;
m_result = false;
if (ImGui::Begin("Active View"))
{
if (histoList.size() > 0)
{
if (m_zoomedFlag && m_zoomedGram.name != "")
if (m_zoomedFlag && m_zoomedGram.type != SpectrumType::None)
{
RenderCutButton();
ImGui::SameLine();
if (m_zoomedGram.type == SpectrumType::Histo1D || m_zoomedGram.type == SpectrumType::Histo2D)
{
RenderCutButton();
ImGui::SameLine();
}
if(ImGui::Button("Clear"))
{
SpectrumManager::GetInstance().ClearHistogram(m_zoomedGram.name);
}
ImGui::SameLine();
RenderRemoveRegionButton();
if (m_zoomedGram.y_par != "None")
if (m_zoomedGram.type == SpectrumType::Histo2D || m_zoomedGram.type == SpectrumType::Summary)
{
float* scale = SpectrumManager::GetInstance().GetColorScaleRange(m_zoomedGram.name);
ImGui::DragFloatRange2("Min / Max", &(scale[0]), &(scale[1]), 0.01f);
@ -67,36 +70,11 @@ namespace Navigator {
m_zoomedFlag = false;
m_zoomedGram = HistogramParameters();
}
else if (m_cutModeFlag && m_newCutParams.y_par == "None")
else if (m_cutModeFlag)
{
if (m_newCutX.size() == 2)
{
acceptCutFlag = true;
}
else if (ImPlot::IsPlotHovered() && ImGui::IsMouseClicked(ImGuiMouseButton_Left))
{
m_newCutX.push_back(ImPlot::GetPlotMousePos().x);
}
ImPlot::PlotVLines(m_newCutParams.name.c_str(), m_newCutX.data(), int(m_newCutX.size()));
HandleCutMode();
}
else if(m_cutModeFlag)
{
if (m_newCutX.size() >= 2 && ImPlot::IsPlotHovered() && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left))
{
acceptCutFlag = true;
m_newCutX.push_back(m_newCutX[0]);
m_newCutY.push_back(m_newCutY[0]);
}
else if (ImPlot::IsPlotHovered() && ImGui::IsMouseClicked(ImGuiMouseButton_Left))
{
auto point = ImPlot::GetPlotMousePos();
m_newCutX.push_back(point.x);
m_newCutY.push_back(point.y);
}
ImPlot::PlotLine(m_newCutParams.name.c_str(), m_newCutX.data(), m_newCutY.data(), int(m_newCutX.size()));
}
if (ImPlot::IsPlotSelected()) {
auto select = ImPlot::GetPlotSelection();
if (ImGui::IsMouseClicked(ImPlot::GetInputMap().SelectCancel)) {
@ -118,45 +96,13 @@ namespace Navigator {
}
ImPlot::EndPlot();
}
if (acceptCutFlag)
{
acceptCutFlag = false;
m_cutModeFlag = false;
ImGui::OpenPopup("Accept Cut");
}
if (ImGui::BeginPopupModal("Accept Cut"))
{
ImGui::Text("Save this Cut?");
if (ImGui::Button("Yes"))
{
if (m_newCutParams.y_par == "None")
{
std::sort(m_newCutX.begin(), m_newCutX.end());
SpectrumManager::GetInstance().AddCut(m_newCutParams, m_newCutX[0], m_newCutX[1]);
}
else
{
SpectrumManager::GetInstance().AddCut(m_newCutParams, m_newCutX, m_newCutY);
}
SpectrumManager::GetInstance().AddCutToHistogramDraw(m_newCutParams.name, m_zoomedGram.name);
ImGui::CloseCurrentPopup();
result = true;
}
ImGui::SameLine();
if (ImGui::Button("No"))
{
ImGui::CloseCurrentPopup();
result = false;
}
ImGui::EndPopup();
}
RenderAcceptCutDialog();
}
else
{
ImGui::SliderInt2("Rows, Columns", m_tableSizes, 1, 3);
ImGui::SameLine();
if(ImGui::Button("Clear All"))
if (ImGui::Button("Clear All"))
{
SpectrumManager::GetInstance().ClearHistograms();
}
@ -220,9 +166,82 @@ namespace Navigator {
}
ImGui::End();
}
return result;
return m_result;
}
void SpectrumPanel::HandleCutMode()
{
switch (m_zoomedGram.type)
{
case SpectrumType::Histo1D:
{
if (m_newCutX.size() == 2)
{
m_acceptCutFlag = true;
}
else if (ImPlot::IsPlotHovered() && ImGui::IsMouseClicked(ImGuiMouseButton_Left))
{
m_newCutX.push_back(ImPlot::GetPlotMousePos().x);
}
ImPlot::PlotVLines(m_newCutParams.name.c_str(), m_newCutX.data(), int(m_newCutX.size()));
break;
}
case SpectrumType::Histo2D:
{
if (m_newCutX.size() >= 2 && ImPlot::IsPlotHovered() && ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left))
{
m_acceptCutFlag = true;
m_newCutX.push_back(m_newCutX[0]);
m_newCutY.push_back(m_newCutY[0]);
}
else if (ImPlot::IsPlotHovered() && ImGui::IsMouseClicked(ImGuiMouseButton_Left))
{
auto point = ImPlot::GetPlotMousePos();
m_newCutX.push_back(point.x);
m_newCutY.push_back(point.y);
}
ImPlot::PlotLine(m_newCutParams.name.c_str(), m_newCutX.data(), m_newCutY.data(), int(m_newCutX.size()));
break;
}
}
}
void SpectrumPanel::RenderAcceptCutDialog()
{
if (m_acceptCutFlag)
{
m_acceptCutFlag = false;
m_cutModeFlag = false;
ImGui::OpenPopup("Accept Cut");
}
if (ImGui::BeginPopupModal("Accept Cut"))
{
ImGui::Text("Save this Cut?");
if (ImGui::Button("Yes"))
{
if (m_newCutParams.y_par == "None")
{
std::sort(m_newCutX.begin(), m_newCutX.end());
SpectrumManager::GetInstance().AddCut(m_newCutParams, m_newCutX[0], m_newCutX[1]);
}
else
{
SpectrumManager::GetInstance().AddCut(m_newCutParams, m_newCutX, m_newCutY);
}
SpectrumManager::GetInstance().AddCutToHistogramDraw(m_newCutParams.name, m_zoomedGram.name);
ImGui::CloseCurrentPopup();
m_result = true;
}
ImGui::SameLine();
if (ImGui::Button("No"))
{
ImGui::CloseCurrentPopup();
m_result = false;
}
ImGui::EndPopup();
}
}
//Renders Cut button as well as dialog for creating cuts.
void SpectrumPanel::RenderCutButton()
{
@ -237,9 +256,25 @@ namespace Navigator {
{
m_newCutParams.x_par = m_zoomedGram.x_par;
m_newCutParams.y_par = m_zoomedGram.y_par;
switch (m_zoomedGram.type)
{
case SpectrumType::Histo1D:
{
m_newCutParams.type = CutType::Cut1D;
ImGui::BulletText("%s", ("X Parameter: " + m_newCutParams.x_par).c_str());
break;
}
case SpectrumType::Histo2D:
{
m_newCutParams.type = CutType::Cut2D;
ImGui::BulletText("%s", ("X Parameter: " + m_newCutParams.x_par).c_str());
ImGui::BulletText("%s", ("Y Parameter: " + m_newCutParams.y_par).c_str());
break;
}
case SpectrumType::None: m_newCutParams.type = CutType::None; break;
case SpectrumType::Summary: m_newCutParams.type = CutType::None; break;
}
ImGui::InputText("Cut Name", &m_newCutParams.name);
ImGui::BulletText("%s", ("X Parameter: " + m_newCutParams.x_par).c_str());
ImGui::BulletText("%s", ("Y Parameter: " + m_newCutParams.y_par).c_str());
if (ImGui::Button("Accept & Draw"))
{
m_cutModeFlag = true;

View File

@ -38,6 +38,8 @@ namespace Navigator {
inline const bool IsZoomed() { return m_zoomedFlag; }
private:
void HandleCutMode();
void RenderAcceptCutDialog();
void RenderCutButton();
void RenderRemoveRegionButton();
void RemoveSelectedRegion(const std::string& region);
@ -45,6 +47,8 @@ namespace Navigator {
std::vector<IntegrationRegion> m_integralRegions;
bool m_zoomedFlag;
bool m_cutModeFlag;
bool m_acceptCutFlag;
bool m_result;
HistogramParameters m_zoomedGram;
int m_tableSizes[2];
int m_totalSlots;

View File

@ -31,6 +31,18 @@
namespace Navigator {
std::string ConvertSpectrumTypeToString(SpectrumType type)
{
switch (type)
{
case SpectrumType::Histo1D: return "Histogram1D";
case SpectrumType::Histo2D: return "Histogram2D";
case SpectrumType::Summary: return "Summary";
case SpectrumType::None: return "None";
}
return "None";
}
/*
1D Histogram class
*/
@ -44,6 +56,7 @@ namespace Navigator {
void Histogram1D::InitBins()
{
m_params.type = SpectrumType::Histo1D;
if(m_params.nbins_x == 0 || (m_params.min_x >= m_params.max_x))
{
NAV_WARN("Attempting to create an illegal Histogram1D {0} with {1} bins and a range from {2} to {3}. Historgram not initialized.", m_params.name, m_params.nbins_x, m_params.min_x, m_params.max_x);
@ -135,6 +148,7 @@ namespace Navigator {
void Histogram2D::InitBins()
{
m_params.type = SpectrumType::Histo2D;
if(m_params.nbins_x <= 0 || m_params.nbins_y <= 0 || m_params.min_x >= m_params.max_x || m_params.min_y >= m_params.max_y)
{
NAV_WARN("Attempting to create illegal Histogram2D {0} with {1} x bins, {2} y bins, an x range of {3} to {4}, and a y range of {5} to {6}. Not initialized.", m_params.name, m_params.nbins_x, m_params.nbins_y,
@ -252,4 +266,143 @@ namespace Navigator {
return results;
}
/*
HistogramSummary class methods
-- 03/18/22 Adding in the basics, unsure of how to exactly approach design
-- Fill data to independent histogram? Steal data from other histograms?
-- Cuts?
-- Literally everything hahaha
*/
HistogramSummary::HistogramSummary(const HistogramParameters& params, const std::vector<std::string>& subhistos) :
Histogram(params), m_subhistos(subhistos), m_labels(nullptr)
{
m_colorScaleRange[0] = 0.0f;
m_colorScaleRange[1] = 0.0f;
InitBins();
}
HistogramSummary::~HistogramSummary()
{
if (m_labels)
delete[] m_labels;
}
void HistogramSummary::InitBins()
{
m_params.type = SpectrumType::Summary;
if (m_params.nbins_x <= 0 || m_params.min_x >= m_params.max_x)
{
NAV_WARN("Attempting to create illegal HistogramSummary {0} with {1} x bins and an x range of {2} to {3}. Not initialized.", m_params.name, m_params.nbins_x, m_params.min_x, m_params.max_x);
m_initFlag = false;
return;
}
m_labels = new const char* [m_subhistos.size() + 1];
for (size_t i = 0; i < m_subhistos.size(); i++)
m_labels[i] = m_subhistos[i].c_str();
m_labels[m_subhistos.size()] = "";
m_params.nbins_y = m_subhistos.size();
m_params.min_y = 0.0;
m_params.max_y = m_subhistos.size();
m_binWidthX = (m_params.max_x - m_params.min_x) / m_params.nbins_x;
m_nBinsTotal = m_params.nbins_x * m_params.nbins_y;
m_binCounts.resize(m_nBinsTotal);
for (int i = 0; i < m_nBinsTotal; i++)
m_binCounts[i] = 0;
m_initFlag = true;
}
void HistogramSummary::FillData(double x, double y)
{
if (x < m_params.min_x || x >= m_params.max_x || y <= m_params.min_y || y > m_params.max_y)
return;
int bin_x = int((x - m_params.min_x) / m_binWidthX);
int bin_y = int((m_params.max_y - y) / m_binWidthY);
int bin = bin_y * m_params.nbins_x + bin_x;
m_binCounts[bin] += 1.0;
}
void HistogramSummary::Draw()
{
ImPlot::SetupAxisTicks(ImAxis_Y1, m_params.min_y, m_params.max_y, m_params.nbins_y, m_labels, false);
ImPlot::PushColormap(ImPlotColormap_Viridis);
ImPlot::PlotHeatmap(m_params.name.c_str(), &m_binCounts.data()[0], m_params.nbins_y, m_params.nbins_x, m_colorScaleRange[0], m_colorScaleRange[1], NULL,
ImPlotPoint(m_params.min_x, m_params.min_y), ImPlotPoint(m_params.max_x, m_params.max_y));
ImPlot::PopColormap();
}
void HistogramSummary::ClearData()
{
for (int i = 0; i < m_nBinsTotal; i++)
m_binCounts[i] = 0;
}
StatResults HistogramSummary::AnalyzeRegion(double x_min, double x_max, double y_min, double y_max)
{
int xbin_min, xbin_max, ybin_min, ybin_max;
int curbin;
StatResults results;
//We clamp to the boundaries of the histogram
if (x_min <= m_params.min_x)
xbin_min = 0;
else
xbin_min = int((x_min - m_params.min_x) / (m_binWidthX));
if (x_max >= m_params.max_x)
xbin_max = m_params.nbins_x - 1;
else
xbin_max = int((x_max - m_params.min_x) / (m_binWidthX));
if (y_min <= m_params.min_y)
ybin_max = m_params.nbins_y - 1;
else
ybin_max = int((m_params.max_y - y_min) / m_binWidthY);
if (y_max >= m_params.max_y)
ybin_min = 0;
else
ybin_min = int((m_params.max_y - y_max) / m_binWidthY);
for (int y = ybin_min; y <= ybin_max; y++)
{
for (int x = xbin_min; x <= xbin_max; x++)
{
curbin = y * m_params.nbins_x + x;
results.integral += m_binCounts[curbin];
results.cent_x += m_binCounts[curbin] * (m_params.min_x + m_binWidthX * x);
results.cent_y += m_binCounts[curbin] * (m_params.max_y - m_binWidthY * y);
}
}
if (results.integral == 0)
return results;
results.cent_x /= results.integral;
results.cent_y /= results.integral;
for (int y = ybin_min; y <= ybin_max; y++)
{
for (int x = xbin_min; x <= xbin_max; x++)
{
curbin = y * m_params.nbins_x + x;
results.sigma_x += m_binCounts[curbin] * ((m_params.min_x + m_binWidthX * x) - results.cent_x) * ((m_params.min_x + m_binWidthX * x) - results.cent_x);
results.sigma_y += m_binCounts[curbin] * ((m_params.max_y - m_binWidthY * y) - results.cent_y) * ((m_params.max_y - m_binWidthY * y) - results.cent_y);
}
}
results.sigma_x = std::sqrt(results.sigma_x / (results.integral - 1));
results.sigma_y = std::sqrt(results.sigma_y / (results.integral - 1));
return results;
}
}

View File

@ -28,6 +28,17 @@
namespace Navigator {
enum class SpectrumType
{
Histo1D,
Histo2D,
Summary,
None
};
std::string ConvertSpectrumTypeToString(SpectrumType type);
struct NAV_API StatResults
{
double integral = 0.0;
@ -51,6 +62,7 @@ namespace Navigator {
{
}
SpectrumType type = SpectrumType::None;
std::string name = "None";
std::string x_par = "None";
std::string y_par = "None";
@ -81,11 +93,10 @@ namespace Navigator {
virtual void Draw() {}
virtual void ClearData() {}
virtual StatResults AnalyzeRegion(double x_min, double x_max, double y_min = 0.0, double y_max = 0.0) { return StatResults(); }
inline virtual bool Is1D() const { return false; }
inline virtual bool Is2D() const { return false; }
inline virtual float* GetColorScaleRange() { return nullptr; }
inline virtual std::vector<double> GetBinData() { return std::vector<double>(); }
inline HistogramParameters& GetParameters() { return m_params; }
inline SpectrumType GetType() { return m_params.type; }
inline const std::string& GetXParam() const { return m_params.x_par; };
inline const std::string& GetYParam() const { return m_params.y_par; };
inline const std::string& GetName() const { return m_params.name; }
@ -106,8 +117,6 @@ namespace Navigator {
virtual void Draw() override;
virtual void ClearData() override;
virtual StatResults AnalyzeRegion(double x_min, double x_max, double y_min = 0.0, double y_max = 0.0) override;
inline virtual bool Is1D() const override { return true; }
inline virtual bool Is2D() const override { return false; }
inline virtual std::vector<double> GetBinData() override { return m_binCounts; }
private:
@ -128,8 +137,6 @@ namespace Navigator {
virtual void Draw() override;
virtual void ClearData() override;
virtual StatResults AnalyzeRegion(double x_min, double x_max, double y_min = 0.0, double y_max = 0.0) override;
inline virtual bool Is1D() const override { return false; }
inline virtual bool Is2D() const override { return true; }
inline virtual std::vector<double> GetBinData() override { return m_binCounts; }
inline virtual float* GetColorScaleRange() override { return m_colorScaleRange; }
@ -145,6 +152,33 @@ namespace Navigator {
float m_colorScaleRange[2];
};
class NAV_API HistogramSummary : public Histogram
{
public:
HistogramSummary(const HistogramParameters& params, const std::vector<std::string>& subhistos);
~HistogramSummary();
inline const std::vector<std::string>& GetSubHistograms() const { return m_subhistos; }
virtual void FillData(double x, double y) override;
virtual void ClearData() override;
virtual void Draw() override;
inline virtual float* GetColorScaleRange() override { return m_colorScaleRange; }
virtual StatResults AnalyzeRegion(double x_min, double x_max, double y_min = 0.0, double y_max = 0.0) override;
inline virtual std::vector<double> GetBinData() override { return m_binCounts; }
private:
void InitBins();
std::vector<std::string> m_subhistos;
const char** m_labels;
std::vector<double> m_binCounts;
int m_nBinsTotal;
double m_binWidthX;
const double m_binWidthY = 1.0;
float m_colorScaleRange[2];
};
}
#endif

View File

@ -68,8 +68,8 @@ namespace Navigator {
//config.GlyphMinAdvanceX = 13.0f; // Use if you want to make the icon monospaced
config.PixelSnapH = true;
static const ImWchar icon_ranges[] = { ICON_MIN_FA, ICON_MAX_FA, 0 };
io.Fonts->AddFontFromFileTTF("Resources/fonts/Roboto-Regular.ttf", 16.0f, &latin_config, io.Fonts->GetGlyphRangesDefault());
io.Fonts->AddFontFromFileTTF("Resources/fonts/fa-solid-900.ttf", 16.0f, &config, icon_ranges);
io.Fonts->AddFontFromFileTTF("Assets/fonts/Roboto-Regular.ttf", 16.0f, &latin_config, io.Fonts->GetGlyphRangesDefault());
io.Fonts->AddFontFromFileTTF("Assets/fonts/fa-solid-900.ttf", 16.0f, &config, icon_ranges);
Application& app = Application::Get();
GLFWwindow* window = static_cast<GLFWwindow*>(app.GetWindow().GetNativeWindow());

View File

@ -35,6 +35,12 @@ namespace Navigator {
m_histoMap[params.name].reset(new Histogram2D(params));
}
void SpectrumManager::AddHistogramSummary(const HistogramParameters& params, const std::vector<std::string>& subhistos)
{
std::lock_guard<std::mutex> guard(m_managerMutex);
m_histoMap[params.name].reset(new HistogramSummary(params, subhistos));
}
void SpectrumManager::RemoveHistogram(const std::string& name)
{
std::lock_guard<std::mutex> guard(m_managerMutex);
@ -61,13 +67,17 @@ namespace Navigator {
void SpectrumManager::UpdateHistograms()
{
std::lock_guard<std::mutex> guard(m_managerMutex);
//Set state of all cuts for the event
CheckCuts();
bool cutFlag;
for (auto& pair : m_histoMap)
{
cutFlag = true;
for (auto& cutname : pair.second->GetParameters().cutsAppliedTo) //check the event against cuts
for (auto& cutname : pair.second->GetParameters().cutsAppliedTo) //check the associated cuts
{
if (!IsInsideCut(cutname))
if (!IsCutValid(cutname))
{
cutFlag = false;
break;
@ -76,20 +86,44 @@ namespace Navigator {
if (!cutFlag)
continue;
if (pair.second->Is1D())
switch (pair.second->GetType())
{
auto iterX = m_paramMap.find(pair.second->GetXParam());
if (iterX != m_paramMap.end() && iterX->second->validFlag)
pair.second->FillData(iterX->second->value);
}
else if (pair.second->Is2D())
{
auto iterX = m_paramMap.find(pair.second->GetXParam());
auto iterY = m_paramMap.find(pair.second->GetYParam());
if (iterX != m_paramMap.end() && iterY != m_paramMap.end() && iterX->second->validFlag && iterY->second->validFlag)
pair.second->FillData(iterX->second->value, iterY->second->value);
case SpectrumType::Histo1D:
{
auto iterX = m_paramMap.find(pair.second->GetXParam());
if (iterX != m_paramMap.end() && iterX->second->validFlag)
pair.second->FillData(iterX->second->value);
break;
}
case SpectrumType::Histo2D:
{
auto iterX = m_paramMap.find(pair.second->GetXParam());
auto iterY = m_paramMap.find(pair.second->GetYParam());
if (iterX != m_paramMap.end() && iterY != m_paramMap.end() && iterX->second->validFlag && iterY->second->validFlag)
pair.second->FillData(iterX->second->value, iterY->second->value);
break;
}
case SpectrumType::Summary:
{
const std::vector<std::string>& subhistos = std::static_pointer_cast<HistogramSummary>(pair.second)->GetSubHistograms();
for (size_t i = 0; i < subhistos.size(); i++)
{
auto iterX = m_paramMap.find(subhistos[i]);
if (iterX != m_paramMap.end() && iterX->second->validFlag)
pair.second->FillData(iterX->second->value, i + 0.5); //avoid floating point conversion issues
}
break;
}
case SpectrumType::None:
{
NAV_WARN("Found a spectrum with None type!");
break;
}
}
}
//Reset the state of all cuts in preparation for next event
ResetCutValidities();
}
void SpectrumManager::ClearHistograms()
@ -154,6 +188,18 @@ namespace Navigator {
return std::vector<double>();
}
std::vector<std::string> SpectrumManager::GetSubHistograms(const std::string& name)
{
std::lock_guard<std::mutex> guard(m_managerMutex);
auto iter = m_histoMap.find(name);
if (iter != m_histoMap.end() && iter->second->GetType() == SpectrumType::Summary)
{
auto gram = std::static_pointer_cast<HistogramSummary>(iter->second);
return gram->GetSubHistograms();
}
return std::vector<std::string>();
}
//Pass through for stats
StatResults SpectrumManager::AnalyzeHistogramRegion(const std::string& name, const ImPlotRect& region)
{
@ -349,29 +395,52 @@ namespace Navigator {
iter->second->Draw();
}
//Check if event passes a cut. Only used when filling histograms.
bool SpectrumManager::IsInsideCut(const std::string& name)
//Set the state of the cuts for the current event. Called by the
void SpectrumManager::CheckCuts()
{
bool result = false;
auto iter = m_cutMap.find(name);
if (iter != m_cutMap.end())
for (auto& iter : m_cutMap)
{
const std::string& xpar = iter->second->GetXParameter();
const std::string& ypar = iter->second->GetYParameter();
if (iter->second->Is1D())
const std::string& xpar = iter.second->GetXParameter();
const std::string& ypar = iter.second->GetYParameter();
switch (iter.second->GetType())
{
auto iterX = m_paramMap.find(xpar);
if (iterX != m_paramMap.end() && iterX->second->validFlag)
result = iter->second->IsInside(iterX->second->value);
}
else if (iter->second->Is2D())
{
auto iterX = m_paramMap.find(xpar);
auto iterY = m_paramMap.find(ypar);
if (iterX != m_paramMap.end() && iterX->second->validFlag && iterY != m_paramMap.end() && iterY->second->validFlag)
result = iter->second->IsInside(iterX->second->value, iterY->second->value);
case CutType::Cut1D:
{
auto iterX = m_paramMap.find(xpar);
if (iterX != m_paramMap.end() && iterX->second->validFlag)
iter.second->IsInside(iterX->second->value);
break;
}
case CutType::Cut2D:
{
auto iterX = m_paramMap.find(xpar);
auto iterY = m_paramMap.find(ypar);
if (iterX != m_paramMap.end() && iterX->second->validFlag && iterY != m_paramMap.end() && iterY->second->validFlag)
iter.second->IsInside(iterX->second->value, iterY->second->value);
break;
}
case CutType::None:
{
NAV_WARN("Found a cut with None type!");
break;
}
}
}
return result;
}
bool SpectrumManager::IsCutValid(const std::string& name)
{
auto iter = m_cutMap.find(name);
if (iter != m_cutMap.end())
return iter->second->IsValid();
return false;
}
void SpectrumManager::ResetCutValidities()
{
for (auto& iter : m_cutMap)
{
iter.second->ResetValidity();
}
}
}

View File

@ -39,6 +39,7 @@ namespace Navigator {
/*Histogram Functions*/
void AddHistogram(const HistogramParameters& params);
void AddHistogramSummary(const HistogramParameters& params, const std::vector<std::string>& subhistos);
void RemoveHistogram(const std::string& name);
void AddCutToHistogramDraw(const std::string& cutname, const std::string& histoname);
void AddCutToHistogramApplied(const std::string& cutname, const std::string& histoname);
@ -49,6 +50,7 @@ namespace Navigator {
const HistogramParameters& GetHistogramParams(const std::string& name);
float* GetColorScaleRange(const std::string& name);
std::vector<double> GetBinData(const std::string& name);
std::vector<std::string> GetSubHistograms(const std::string& name);
StatResults AnalyzeHistogramRegion(const std::string& name, const ImPlotRect& region);
std::vector<HistogramParameters> GetListOfHistograms();
/********************/
@ -86,7 +88,9 @@ namespace Navigator {
//Only used from within manager
void RemoveCutFromHistograms(const std::string& cutname);
void DrawCut(const std::string& name);
bool IsInsideCut(const std::string& name);
void CheckCuts();
bool IsCutValid(const std::string& name);
void ResetCutValidities();
static SpectrumManager* s_instance;

View File

@ -39,7 +39,7 @@ namespace Navigator {
output << "begin_cuts" << std::endl;
for (auto& cut : cutList)
{
if (cut.y_par == "None")
if (cut.type == CutType::Cut1D)
{
std::vector<double> xpoints = manager.GetCutXPoints(cut.name);
output << "\tbegin_cut1D" << std::endl;
@ -49,7 +49,7 @@ namespace Navigator {
output << "\t\tmaxValue: " << xpoints[1] << std::endl;
output << "\tend_cut1D" << std::endl;
}
else
else if (cut.type == CutType::Cut2D)
{
std::vector<double> xpoints = manager.GetCutXPoints(cut.name);
std::vector<double> ypoints = manager.GetCutYPoints(cut.name);
@ -77,7 +77,7 @@ namespace Navigator {
output << "begin_histograms" << std::endl;
for (auto& params : histoList)
{
if (params.y_par == "None")
if (params.type == SpectrumType::Histo1D)
{
output << "\tbegin_histogram1D" << std::endl;
output << "\t\tname: " << params.name << std::endl;
@ -99,7 +99,7 @@ namespace Navigator {
output << "\t\tend_cutsapplied" << std::endl;
output << "\tend_histogram1D" << std::endl;
}
else
else if (params.type == SpectrumType::Histo2D)
{
output << "\tbegin_histogram2D" << std::endl;
output << "\t\tname: " << params.name << std::endl;
@ -125,6 +125,34 @@ namespace Navigator {
output << "\t\tend_cutsapplied" << std::endl;
output << "\tend_histogram2D" << std::endl;
}
else if (params.type == SpectrumType::Summary)
{
output << "\tbegin_histogramSummary" << std::endl;
output << "\t\tname: " << params.name << std::endl;
output << "\t\tNxbins: " << params.nbins_x << std::endl;
output << "\t\tXMin: " << params.min_x << std::endl;
output << "\t\tXMax: " << params.max_x << std::endl;
output << "\t\tbegin_subhistos" << std::endl;
std::vector<std::string> subhistos = manager.GetSubHistograms(params.name);
for (auto& name : subhistos)
{
output << "\t\t\t" << name << std::endl;
}
output << "\t\tend_subhistos" << std::endl;
output << "\t\tbegin_cutsdrawn" << std::endl;
for (const auto& name : params.cutsDrawnUpon)
{
output << "\t\t\t" << name << std::endl;
}
output << "\t\tend_cutsdrawn" << std::endl;
output << "\t\tbegin_cutsapplied" << std::endl;
for (const auto& name : params.cutsAppliedTo)
{
output << "\t\t\t" << name << std::endl;
}
output << "\t\tend_cutsapplied" << std::endl;
output << "\tend_histogram1D" << std::endl;
}
}
output << "end_histograms" << std::endl;
@ -149,6 +177,7 @@ namespace Navigator {
CutParams cut_data, reset_cut;
std::vector<double> cut_xdata;
std::vector<double> cut_ydata;
std::vector<std::string> subhistos;
HistogramParameters hist_data, reset_hist;
while (input >> check)
@ -162,6 +191,7 @@ namespace Navigator {
cut_ydata.clear();
if (check == "begin_cut1D")
{
cut_data.type = CutType::Cut1D;
input >> check >> cut_data.name;
input >> check >> cut_data.x_par;
input >> check >> value_doub;
@ -173,6 +203,7 @@ namespace Navigator {
}
else if (check == "begin_cut2D")
{
cut_data.type = CutType::Cut2D;
input >> check >> cut_data.name;
input >> check >> cut_data.x_par;
input >> check >> cut_data.y_par;
@ -214,6 +245,7 @@ namespace Navigator {
hist_data = reset_hist;
if (check == "begin_histogram1D")
{
hist_data.type = SpectrumType::Histo1D;
input >> check >> hist_data.name;
input >> check >> hist_data.x_par;
input >> check >> hist_data.nbins_x;
@ -246,6 +278,7 @@ namespace Navigator {
}
else if (check == "begin_histogram2D")
{
hist_data.type = SpectrumType::Histo2D;
input >> check >> hist_data.name;
input >> check >> hist_data.x_par;
input >> check >> hist_data.y_par;
@ -280,6 +313,50 @@ namespace Navigator {
input >> check;
manager.AddHistogram(hist_data);
}
else if (check == "begin_histogramSummary")
{
subhistos.clear();
hist_data.type = SpectrumType::Summary;
input >> check >> hist_data.name;
input >> check >> hist_data.nbins_x;
input >> check >> hist_data.min_x;
input >> check >> hist_data.max_x;
while (input >> check)
{
if (check == "begin_subhistos")
continue;
else if (check == "end_subhistos")
break;
else
{
subhistos.push_back(check);
}
}
while (input >> check)
{
if (check == "begin_cutsdrawn")
continue;
else if (check == "end_cutsdrawn")
break;
else
{
hist_data.cutsDrawnUpon.push_back(check);
}
}
while (input >> check)
{
if (check == "begin_cutsapplied")
continue;
else if (check == "end_cutsapplied")
break;
else
{
hist_data.cutsAppliedTo.push_back(check);
}
}
input >> check;
manager.AddHistogramSummary(hist_data, subhistos);
}
else if (check == "end_histograms")
break;
else

View File

@ -161,10 +161,6 @@ project "NavProject"
systemversion "latest"
postbuildcommands {
(" {COPYDIR} Resources %{cfg.targetdir} ")
}
filter "system:macosx"
defines "NAV_APPLE"
sysincludedirs {
@ -191,8 +187,14 @@ project "NavProject"
linkoptions {
"-pthread"
}
postbuildcommands {
(" {COPYDIR} Assets %{cfg.targetdir} ")
}
filter "system:windows"
defines "NAV_WINDOWS"
postbuildcommands {
(" {COPYDIR} Assets %{cfg.targetdir}/Assets ")
}
filter "system:linux"
defines "NAV_LINUX"
links {
@ -206,6 +208,9 @@ project "NavProject"
linkoptions {
"-pthread"
}
postbuildcommands {
(" {COPYDIR} Assets %{cfg.targetdir} ")
}