mirror of
https://github.com/gwm17/Specter.git
synced 2024-11-22 18:28:52 -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));
|
||||
|
||||
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("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("joe2D_cut", "myHisto2D");
|
||||
|
||||
m_imgui_layer = new ImGuiLayer();
|
||||
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*/
|
||||
Cut2D::Cut2D(const std::string& name, const std::string& xpar, const std::string& ypar, const std::vector<Point>& points) :
|
||||
Cut(name, xpar, ypar), m_points(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_xpoints(xpoints), m_ypoints(ypoints)
|
||||
{
|
||||
}
|
||||
|
||||
Cut2D::~Cut2D() {}
|
||||
|
||||
/*
|
||||
Even-odd point in polygon algorithm (see Wikipedia)
|
||||
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.
|
||||
If odd number of intersections, point is inside. Even, point is outside.
|
||||
Edge cases of point is a vertex or on a side considered.
|
||||
Even-odd point in polygon algorithm (see Wikipedia)
|
||||
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.
|
||||
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
|
||||
{
|
||||
bool result = false;
|
||||
size_t j = m_points.size() -1;
|
||||
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;
|
||||
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)
|
||||
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;
|
||||
}
|
||||
j=i;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//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
|
||||
{
|
||||
std::vector<ImVec2> draw_points;
|
||||
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);
|
||||
ImPlot::PlotLine(m_params.name.c_str(), m_xpoints.data(), m_ypoints.data(), m_xpoints.size());
|
||||
}
|
||||
|
||||
/* CutMap */
|
||||
|
|
|
@ -19,12 +19,6 @@ namespace Navigator {
|
|||
std::string y_par;
|
||||
};
|
||||
|
||||
struct NAV_API Point
|
||||
{
|
||||
double x = 0;
|
||||
double y = 0;
|
||||
};
|
||||
|
||||
class NAV_API Cut
|
||||
{
|
||||
public:
|
||||
|
@ -65,7 +59,7 @@ namespace Navigator {
|
|||
class NAV_API Cut2D : public Cut
|
||||
{
|
||||
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 bool IsInside(double x, double y = 0) const override;
|
||||
virtual void Draw() const override;
|
||||
|
@ -73,7 +67,8 @@ namespace Navigator {
|
|||
virtual bool Is2D() const override { return true; }
|
||||
|
||||
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};
|
||||
};
|
||||
|
||||
|
@ -90,10 +85,10 @@ namespace Navigator {
|
|||
std::lock_guard<std::mutex> guard(m_cutMutex);
|
||||
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);
|
||||
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);
|
||||
|
|
|
@ -36,8 +36,6 @@ namespace Navigator {
|
|||
ImGui::SliderInt2("Rows, Columns", m_tableSizes, 1, 3);
|
||||
m_totalSlots = m_tableSizes[0] * m_tableSizes[1];
|
||||
m_selectedGrams.resize(m_totalSlots);
|
||||
for (auto& gram : m_selectedGrams)
|
||||
gram = m_activeList[0].name;
|
||||
if (ImGui::BeginTable("Select Histograms", m_tableSizes[1]))
|
||||
{
|
||||
std::string label;
|
||||
|
@ -50,7 +48,7 @@ namespace Navigator {
|
|||
ImGui::TableNextColumn();
|
||||
this_gram = i * m_tableSizes[1] + j;
|
||||
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)
|
||||
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++)
|
||||
m_binCounts[i] = 0;
|
||||
m_maxBinContent = 0;
|
||||
|
||||
m_initFlag = true;
|
||||
}
|
||||
|
||||
void Histogram2D::FillData(double x, double y)
|
||||
|
@ -122,20 +124,22 @@ namespace Navigator {
|
|||
return;
|
||||
|
||||
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;
|
||||
|
||||
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!!
|
||||
void Histogram2D::Draw()
|
||||
{
|
||||
ImPlot::SetupAxes(m_params.x_par.c_str(), m_params.y_par.c_str(), 0, 0);
|
||||
ImPlot::PlotHeatmap(m_params.name.c_str(), &m_binCounts.data()[0], m_params.nbins_y, m_params.nbins_x, 0, m_maxBinContent, NULL,
|
||||
ImPlot::SetupAxes(m_params.x_par.c_str(), m_params.y_par.c_str());
|
||||
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));
|
||||
ImPlot::PopColormap();
|
||||
auto& cutmap = CutMap::GetInstance();
|
||||
for(auto& cut : m_params.cutsDrawnUpon)
|
||||
cutmap.DrawCut(cut);
|
||||
|
|
|
@ -33,6 +33,7 @@ namespace Navigator {
|
|||
ParameterMap& pmap = ParameterMap::GetInstance();
|
||||
for (auto& pair : m_map)
|
||||
{
|
||||
|
||||
xpar = pair.second->GetXParam();
|
||||
ypar = pair.second->GetYParam();
|
||||
|
||||
|
@ -53,7 +54,9 @@ namespace Navigator {
|
|||
auto iterx = pmap.find(xpar);
|
||||
auto itery = pmap.find(ypar);
|
||||
if (iterx == pmap.end() || itery == pmap.end() || !iterx->second->validFlag || !itery->second->validFlag)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
pair.second->FillData(iterx->second->value, itery->second->value);
|
||||
|
|
|
@ -36,6 +36,7 @@ namespace Navigator {
|
|||
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;
|
||||
|
||||
ImGui::StyleColorsDark();
|
||||
ImPlot::StyleColorsDark();
|
||||
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user