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:
parent
a2a01e568b
commit
66e1065394
|
@ -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);
|
||||||
|
|
|
@ -24,59 +24,44 @@ 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)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Cut2D::~Cut2D() {}
|
Cut2D::~Cut2D() {}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Even-odd point in polygon algorithm (see Wikipedia)
|
Even-odd point in polygon algorithm (see Wikipedia)
|
||||||
Walk around the sides of the polygon and check intersection with each of the sides.
|
Walk around the sides of the polygon and check intersection with each of the sides.
|
||||||
Cast a ray from the point to infinity in any direction and check the number of intersections.
|
Cast a ray from the point to infinity in any direction and check the number of intersections.
|
||||||
If odd number of intersections, point is inside. Even, point is outside.
|
If odd number of intersections, point is inside. Even, point is outside.
|
||||||
Edge cases of point is a vertex or on a side considered.
|
Edge cases of point is a vertex or on a side considered.
|
||||||
*/
|
*/
|
||||||
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 */
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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]))
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user