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

Cuts now implemented, drawn and applied to histograms

This commit is contained in:
Gordon McCann 2022-01-17 16:42:12 -05:00
parent a2a01e568b
commit 66e1065394
7 changed files with 34 additions and 45 deletions

View File

@ -21,10 +21,13 @@ namespace Navigator {
PushLayer(new EditorLayer(&m_histMap)); PushLayer(new EditorLayer(&m_histMap));
m_histMap.AddHistogram("myHisto", "joseph", 100, 0, 10); m_histMap.AddHistogram("myHisto", "joseph", 100, 0, 10);
m_histMap.AddHistogram("myHisto2D", "joseph", "joseph", 100, 0, 10, 100, 0, 10);
CutMap::GetInstance().AddCut("joe_cut","joseph",0.0, 7.0); CutMap::GetInstance().AddCut("joe_cut","joseph",0.0, 7.0);
CutMap::GetInstance().AddCut("joe2D_cut", "joseph", "joseph", { 1.0, 3.0, 3.0, 1.0, 1.0}, { 1.0, 1.0, 3.0, 3.0, 1.0});
m_histMap.AddCutToHistogramDraw("joe_cut", "myHisto"); m_histMap.AddCutToHistogramDraw("joe_cut", "myHisto");
m_histMap.AddCutToHistogramDraw("joe2D_cut", "myHisto2D");
m_imgui_layer = new ImGuiLayer(); m_imgui_layer = new ImGuiLayer();
PushOverlay(m_imgui_layer); PushOverlay(m_imgui_layer);

View File

@ -24,8 +24,8 @@ namespace Navigator {
} }
/*2D Cuts -- Can only be made on 2D histogram, but applied to either 1D or 2D histograms*/ /*2D Cuts -- Can only be made on 2D histogram, but applied to either 1D or 2D histograms*/
Cut2D::Cut2D(const std::string& name, const std::string& xpar, const std::string& ypar, const std::vector<Point>& points) : Cut2D::Cut2D(const std::string& name, const std::string& xpar, const std::string& ypar, const std::vector<double>& xpoints, const std::vector<double>& ypoints) :
Cut(name, xpar, ypar), m_points(points) Cut(name, xpar, ypar), m_xpoints(xpoints), m_ypoints(ypoints)
{ {
} }
@ -41,42 +41,27 @@ namespace Navigator {
bool Cut2D::IsInside(double x, double y) const bool Cut2D::IsInside(double x, double y) const
{ {
bool result = false; bool result = false;
size_t j = m_points.size() -1;
double slope; double slope;
for(size_t i=0; i<m_points.size(); i++) for(size_t i=0; i<(m_xpoints.size()-1); i++)
{ {
if(x == m_points[i].x && y == m_points[i].y) if(x == m_xpoints[i+1] && y == m_ypoints[i+1])
return true; return true;
else if((m_points[i].y > y) != (m_points[j].y > y)) else if((m_ypoints[i+1] > y) != (m_ypoints[i] > y))
{ {
slope = (x - m_points[i].x)*(m_points[j].y - m_points[i].y) - (m_points[j].x - m_points[i].x)*(y - m_points[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) if(slope == 0.0)
return true; return true;
else if ((slope < 0.0) != (m_points[j].y < m_points[i].y)) else if ((slope < 0.0) != (m_ypoints[i] < m_ypoints[i+1]))
result = !result; result = !result;
} }
j=i;
} }
return result; return result;
} }
//Only in ImPlot/ImGui context!!!! //Only in ImPlot/ImGui context!!!!
/*
Again, more complicated. Want to draw the polygon that makes up the 2D-cut. To perform this,
first need to convert plot coordinates into global window coords (pixels). Then tell ImGui to add
a polyline to the draw list, make it red and closed. For this to work, this must be called within the
BeignPlot()/EndPlot() combo for which it was created (why histos own the draw commands).
*/
void Cut2D::Draw() const void Cut2D::Draw() const
{ {
std::vector<ImVec2> draw_points; ImPlot::PlotLine(m_params.name.c_str(), m_xpoints.data(), m_ypoints.data(), m_xpoints.size());
draw_points.reserve(m_points.size());
auto draw_list = ImGui::GetWindowDrawList();
for(auto& point : m_points)
draw_points.push_back(ImPlot::PlotToPixels(point.x, point.y));
draw_list->AddPolyline(draw_points.data(), static_cast<int>(draw_points.size()), ImGui::ColorConvertFloat4ToU32(colorVec), ImDrawFlags_Closed, 0.1);
} }
/* CutMap */ /* CutMap */

View File

@ -19,12 +19,6 @@ namespace Navigator {
std::string y_par; std::string y_par;
}; };
struct NAV_API Point
{
double x = 0;
double y = 0;
};
class NAV_API Cut class NAV_API Cut
{ {
public: public:
@ -65,7 +59,7 @@ namespace Navigator {
class NAV_API Cut2D : public Cut class NAV_API Cut2D : public Cut
{ {
public: public:
Cut2D(const std::string& name, const std::string& xpar, const std::string& ypar, const std::vector<Point>& points); Cut2D(const std::string& name, const std::string& xpar, const std::string& ypar, const std::vector<double>& xpoints, const std::vector<double>& ypoints);
virtual ~Cut2D(); virtual ~Cut2D();
virtual bool IsInside(double x, double y = 0) const override; virtual bool IsInside(double x, double y = 0) const override;
virtual void Draw() const override; virtual void Draw() const override;
@ -73,7 +67,8 @@ namespace Navigator {
virtual bool Is2D() const override { return true; } virtual bool Is2D() const override { return true; }
private: private:
std::vector<Point> m_points; std::vector<double> m_xpoints;
std::vector<double> m_ypoints;
const ImVec4 colorVec = {1.0, 0.0, 0.0, 0.5}; const ImVec4 colorVec = {1.0, 0.0, 0.0, 0.5};
}; };
@ -90,10 +85,10 @@ namespace Navigator {
std::lock_guard<std::mutex> guard(m_cutMutex); std::lock_guard<std::mutex> guard(m_cutMutex);
m_map[name].reset(new Cut1D(name, xpar, min, max)); m_map[name].reset(new Cut1D(name, xpar, min, max));
} }
inline void AddCut(const std::string& name, const std::string& xpar, const std::string& ypar, const std::vector<Point>& points) inline void AddCut(const std::string& name, const std::string& xpar, const std::string& ypar, const std::vector<double>& xpoints, const std::vector<double>& ypoints)
{ {
std::lock_guard<std::mutex> guard(m_cutMutex); std::lock_guard<std::mutex> guard(m_cutMutex);
m_map[name].reset(new Cut2D(name, xpar, ypar, points)); m_map[name].reset(new Cut2D(name, xpar, ypar, xpoints, ypoints));
} }
void DrawCut(const std::string& name); void DrawCut(const std::string& name);

View File

@ -36,8 +36,6 @@ namespace Navigator {
ImGui::SliderInt2("Rows, Columns", m_tableSizes, 1, 3); ImGui::SliderInt2("Rows, Columns", m_tableSizes, 1, 3);
m_totalSlots = m_tableSizes[0] * m_tableSizes[1]; m_totalSlots = m_tableSizes[0] * m_tableSizes[1];
m_selectedGrams.resize(m_totalSlots); m_selectedGrams.resize(m_totalSlots);
for (auto& gram : m_selectedGrams)
gram = m_activeList[0].name;
if (ImGui::BeginTable("Select Histograms", m_tableSizes[1])) if (ImGui::BeginTable("Select Histograms", m_tableSizes[1]))
{ {
std::string label; std::string label;
@ -50,7 +48,7 @@ namespace Navigator {
ImGui::TableNextColumn(); ImGui::TableNextColumn();
this_gram = i * m_tableSizes[1] + j; this_gram = i * m_tableSizes[1] + j;
label = "Histogram" + std::to_string(this_gram); label = "Histogram" + std::to_string(this_gram);
if (ImGui::BeginCombo(label.c_str(), m_activeList[0].name.c_str())) if (ImGui::BeginCombo(label.c_str(), m_selectedGrams[this_gram].c_str()))
{ {
for (auto& params : m_activeList) for (auto& params : m_activeList)
if (ImGui::Selectable(params.name.c_str(), params.name == m_selectedGrams[this_gram])) if (ImGui::Selectable(params.name.c_str(), params.name == m_selectedGrams[this_gram]))

View File

@ -114,6 +114,8 @@ namespace Navigator {
for(int i=0; i<m_nBinsTotal; i++) for(int i=0; i<m_nBinsTotal; i++)
m_binCounts[i] = 0; m_binCounts[i] = 0;
m_maxBinContent = 0; m_maxBinContent = 0;
m_initFlag = true;
} }
void Histogram2D::FillData(double x, double y) void Histogram2D::FillData(double x, double y)
@ -122,20 +124,22 @@ namespace Navigator {
return; return;
int bin_x = int((x - m_params.min_x)/m_binWidthX); int bin_x = int((x - m_params.min_x)/m_binWidthX);
int bin_y = int((y - m_params.min_y)/m_binWidthY); int bin_y = int((m_params.max_y - y)/m_binWidthY);
int bin = bin_y*m_params.nbins_x + bin_x; int bin = bin_y*m_params.nbins_x + bin_x;
m_binCounts[bin] += 1.0; m_binCounts[bin] += 1.0;
m_maxBinContent = m_binCounts[bin] > m_maxBinContent ? m_binCounts[bin] : m_maxBinContent; m_maxBinContent = m_binCounts[bin] > m_maxBinContent ? (m_binCounts[bin]*2) : m_maxBinContent;
} }
//Can only be used within an ImGui / ImPlot context!! //Can only be used within an ImGui / ImPlot context!!
void Histogram2D::Draw() void Histogram2D::Draw()
{ {
ImPlot::SetupAxes(m_params.x_par.c_str(), m_params.y_par.c_str(), 0, 0); ImPlot::SetupAxes(m_params.x_par.c_str(), m_params.y_par.c_str());
ImPlot::PlotHeatmap(m_params.name.c_str(), &m_binCounts.data()[0], m_params.nbins_y, m_params.nbins_x, 0, m_maxBinContent, NULL, ImPlot::PushColormap(ImPlotColormap_Viridis);
ImPlot::PlotHeatmap(m_params.name.c_str(), &m_binCounts.data()[0], m_params.nbins_y, m_params.nbins_x, 0.0, m_maxBinContent, NULL,
ImPlotPoint(m_params.min_x, m_params.min_y), ImPlotPoint(m_params.max_x, m_params.max_y)); ImPlotPoint(m_params.min_x, m_params.min_y), ImPlotPoint(m_params.max_x, m_params.max_y));
ImPlot::PopColormap();
auto& cutmap = CutMap::GetInstance(); auto& cutmap = CutMap::GetInstance();
for(auto& cut : m_params.cutsDrawnUpon) for(auto& cut : m_params.cutsDrawnUpon)
cutmap.DrawCut(cut); cutmap.DrawCut(cut);

View File

@ -33,6 +33,7 @@ namespace Navigator {
ParameterMap& pmap = ParameterMap::GetInstance(); ParameterMap& pmap = ParameterMap::GetInstance();
for (auto& pair : m_map) for (auto& pair : m_map)
{ {
xpar = pair.second->GetXParam(); xpar = pair.second->GetXParam();
ypar = pair.second->GetYParam(); ypar = pair.second->GetYParam();
@ -53,7 +54,9 @@ namespace Navigator {
auto iterx = pmap.find(xpar); auto iterx = pmap.find(xpar);
auto itery = pmap.find(ypar); auto itery = pmap.find(ypar);
if (iterx == pmap.end() || itery == pmap.end() || !iterx->second->validFlag || !itery->second->validFlag) if (iterx == pmap.end() || itery == pmap.end() || !iterx->second->validFlag || !itery->second->validFlag)
{
continue; continue;
}
else else
{ {
pair.second->FillData(iterx->second->value, itery->second->value); pair.second->FillData(iterx->second->value, itery->second->value);

View File

@ -36,6 +36,7 @@ namespace Navigator {
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;
ImGui::StyleColorsDark(); ImGui::StyleColorsDark();
ImPlot::StyleColorsDark();
ImGuiStyle& style = ImGui::GetStyle(); ImGuiStyle& style = ImGui::GetStyle();