diff --git a/include/G3PointAction.h b/include/G3PointAction.h index a3e0981..6aa0212 100644 --- a/include/G3PointAction.h +++ b/include/G3PointAction.h @@ -41,7 +41,7 @@ public: void fit(); void exportResults(); void plots(); - void showWolman(const Eigen::ArrayXf& d_sample); + void showWolman(const Eigen::ArrayXf& d_sample, const Eigen::Array3d &dq_final, const Eigen::Array3d &edq); bool wolman(); bool angles(); bool processNewStacks(std::vector>& newStacks, int pointCount); @@ -117,8 +117,6 @@ private: GrainsAsEllipsoids* m_grainsAsEllipsoids; - std::unique_ptr m_progress; - int m_currentNumberOfSteps; }; } diff --git a/include/G3PointPlots.h b/include/G3PointPlots.h index 04f479e..33e71a5 100644 --- a/include/G3PointPlots.h +++ b/include/G3PointPlots.h @@ -5,6 +5,9 @@ #include +// Eigen +#include + namespace Ui { class G3PointPlots; } @@ -24,7 +27,7 @@ public: void closeCurrentWidget(); template - bool exportToCSV(QString filename, SharedDataContainer container) const; + bool exportToCSV(QString filename, SharedDataContainer container, const Eigen::Array3d* dq_final=nullptr, const Eigen::Array3d* edq=nullptr) const; void onExportToCSV(); diff --git a/include/WolmanCustomPlot.h b/include/WolmanCustomPlot.h index d59c21c..05158b3 100644 --- a/include/WolmanCustomPlot.h +++ b/include/WolmanCustomPlot.h @@ -68,14 +68,22 @@ class WolmanCustomPlot : public QCustomPlot { Q_OBJECT public: - WolmanCustomPlot(const Eigen::ArrayXf& d_sample); + WolmanCustomPlot(const Eigen::ArrayXf& d_sample, const Eigen::Array3d& dq_final, const Eigen::Array3d& edq); QSharedPointer dataContainer(){return m_graph->data();} + Eigen::Array3d m_dq_final; + + Eigen::Array3d m_edq; + QCPGraph* m_graph; + void rescale(); + void emitCloseTab(){emit closeTab();} + void mouseDoubleClickEvent(QMouseEvent* event) override; + void mousePressEvent(QMouseEvent* event) override; signals: diff --git a/src/G3PointAction.cpp b/src/G3PointAction.cpp index 8e07196..2c091a2 100644 --- a/src/G3PointAction.cpp +++ b/src/G3PointAction.cpp @@ -1075,10 +1075,11 @@ void myPrint(QString name, T array) // Hyndman and Fan, 1996) R. J. Hyndman and Y. Fan, “Sample quantiles in statistical packages”, // The American Statistician, 50(4), pp. 361-365, 1996 template -typename T1::value_type quant(const T1 &x, T2 q) +typename T1::value_type quant(T1& x, const T2& q) { assert(q >= 0.0 && q <= 1.0); + std::sort(x.begin(), x.end()); const auto n = x.size(); const auto id = (n - 1) * q; const auto lo = floor(id); @@ -1101,12 +1102,12 @@ void G3PointAction::plots() angles(); } -void G3PointAction::showWolman(const Eigen::ArrayXf& d_sample) +void G3PointAction::showWolman(const Eigen::ArrayXf& d_sample, const Eigen::Array3d& dq_final, const Eigen::Array3d& edq) { // QCustomPlot if (!s_g3PointPlots) s_g3PointPlots = new G3PointPlots(m_cloud->getName()); - s_g3PointPlots->addToTabWidget(new WolmanCustomPlot(d_sample)); + s_g3PointPlots->addToTabWidget(new WolmanCustomPlot(d_sample, dq_final, edq)); s_g3PointPlots->show(); } @@ -1171,6 +1172,10 @@ bool G3PointAction::wolman() #endif for (int k = 0; k < n_iter; k++) { + if (k % 20 == 0) + { + std::cout << k << std::endl; + } float r0 = dist(urbg); float r1 = dist(urbg); // std::cout << r0 << ", " << r1 << "," << std::endl; @@ -1185,7 +1190,6 @@ bool G3PointAction::wolman() for (int iy = 0; iy < ny; iy++) { distances = ((x - x_grid(ix)).pow(2) + (y - y_grid(iy)).pow(2)).sqrt(); - dist(ix, iy) = distances.minCoeff(&minLoc); iWolman(ix, iy) = minLoc; } @@ -1245,7 +1249,7 @@ bool G3PointAction::wolman() quant(d_sample, 0.5), quant(d_sample, 0.9)}; - showWolman(d_sample); + showWolman(d_sample, dq_final, edq); return true; } @@ -2030,10 +2034,10 @@ bool G3PointAction::setCloud(ccPointCloud *cloud) // build stacks from g3point_index int nPointsInGrains = 0; - m_progress.reset(new QProgressBar()); - m_progress->setRange(0, m_cloud->size()); - m_progress->setWindowTitle("Processing g3point_label"); - m_progress->show(); + std::unique_ptr progress(new QProgressBar()); + progress->setRange(0, m_cloud->size()); + progress->setWindowTitle("Processing g3point_label"); + progress->show(); std::vector> newStacks(labelsSet.size()); @@ -2048,12 +2052,12 @@ bool G3PointAction::setCloud(ccPointCloud *cloud) } if (index % 20 == 0) { - m_progress->setValue(index); + progress->setValue(index); QApplication::processEvents(); } } - m_progress->hide(); + progress->hide(); QApplication::processEvents(); ccLog::Print("[G3PointAction::setCloud] g3point_label available, found " diff --git a/src/G3PointPlots.cpp b/src/G3PointPlots.cpp index dc1b88a..bd627d4 100644 --- a/src/G3PointPlots.cpp +++ b/src/G3PointPlots.cpp @@ -72,7 +72,7 @@ void G3PointPlots::closeCurrentWidget() } template -bool G3PointPlots::exportToCSV(QString filename, SharedDataContainer container) const +bool G3PointPlots::exportToCSV(QString filename, SharedDataContainer container, const Eigen::Array3d* dq_final, const Eigen::Array3d* edq) const { QFile file(filename); if (!file.open(QFile::WriteOnly | QFile::Text)) @@ -86,7 +86,18 @@ bool G3PointPlots::exportToCSV(QString filename, SharedDataContainer container) stream.setRealNumberNotation(QTextStream::FixedNotation); //header - stream << "angle [°], counts" << endl; + if (dq_final) // WolmanCustomPlot + { + stream << "# D10 [mm], D50 [mm], D90 [mm]" << endl; + stream << (*dq_final)(0) << (*dq_final)(0) << (*dq_final)(0) << endl; + stream << "# std(D10) [mm], std(D50) [mm], std(D90) [mm]" << endl; + stream << (*edq)(0) << (*edq)(0) << (*edq)(0) << endl; + stream << "diameter [m], pdf" << endl; + } + else // AnglesCustomPlot + { + stream << "angle [degree], counts" << endl; + } //data { @@ -132,13 +143,18 @@ void G3PointPlots::onExportToCSV() if (currentWidget->property("TypeOfCustomPlot").toString() == "AnglesCustomPlot") { + Eigen::Array3d dq_final; + Eigen::Array3d edq; exportToCSV(filename, static_cast(currentWidget)->dataContainer()); } else if (currentWidget->property("TypeOfCustomPlot").toString() == "WolmanCustomPlot") { + WolmanCustomPlot* wolmanCustomPlot = static_cast(currentWidget); exportToCSV(filename, - static_cast(currentWidget)->dataContainer()); + wolmanCustomPlot->dataContainer(), + &wolmanCustomPlot->m_dq_final, + &wolmanCustomPlot->m_edq); } } diff --git a/src/WolmanCustomPlot.cpp b/src/WolmanCustomPlot.cpp index a44cddf..49b18d4 100644 --- a/src/WolmanCustomPlot.cpp +++ b/src/WolmanCustomPlot.cpp @@ -1,7 +1,9 @@ #include "WolmanCustomPlot.h" #include "ui_WolmanCustomPlot.h" -WolmanCustomPlot::WolmanCustomPlot(const Eigen::ArrayXf &d_sample): +WolmanCustomPlot::WolmanCustomPlot(const Eigen::ArrayXf &d_sample, const Eigen::Array3d& dq_final, const Eigen::Array3d& edq): + m_dq_final(dq_final), + m_edq(edq), ui(new Ui::WolmanCustomPlot) { setProperty("TypeOfCustomPlot", "WolmanCustomPlot"); @@ -10,6 +12,8 @@ WolmanCustomPlot::WolmanCustomPlot(const Eigen::ArrayXf &d_sample): setWindowTitle("Wolman"); + QPen pen; + m_graph = this->addGraph(); QVector x_data(d_sample.size()); QVector y_data(d_sample.size()); @@ -25,6 +29,44 @@ WolmanCustomPlot::WolmanCustomPlot(const Eigen::ArrayXf &d_sample): this->xAxis->setScaleType(QCPAxis::stLogarithmic); this->xAxis->setLabel("Diameter [mm]"); this->yAxis->setLabel("CDF"); + + // add error bars + QCPGraph* errorBarsGraph = this->addGraph(); + errorBarsGraph->setData(QVector({dq_final[0], dq_final[1], dq_final[2]}), + QVector({0.1, 0.5, 0.9})); + errorBarsGraph->setLineStyle(QCPGraph::lsNone); + errorBarsGraph->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssCircle, 4)); + QCPErrorBars *errorBars = new QCPErrorBars(xAxis, yAxis); + errorBars->removeFromLegend(); + errorBars->setAntialiased(false); + errorBars->setDataPlottable(errorBarsGraph); + errorBars->setErrorType(QCPErrorBars::etKeyError); + // pen.setWidth(1); + errorBars->setPen(pen); + errorBars->setData(QVector({edq[0], edq[1], edq[2]})); + errorBars->setPen(QPen(QColorConstants::Red)); + errorBars->rescaleAxes(true); + + setInteractions(QCP::iRangeDrag | QCP::iRangeZoom); +} + +void WolmanCustomPlot::rescale() +{ + // set ranges appropriate to show data + if (m_graph) + { + m_graph->rescaleAxes(); + replot(); + } +} + +void WolmanCustomPlot::mouseDoubleClickEvent(QMouseEvent *event) +{ + if (event->button() == Qt::LeftButton) + { + rescale(); + } + QCustomPlot::mouseDoubleClickEvent(event); } void WolmanCustomPlot::mousePressEvent(QMouseEvent *event) diff --git a/ui/G3PointDialog.ui b/ui/G3PointDialog.ui index 5da4234..023de3b 100644 --- a/ui/G3PointDialog.ui +++ b/ui/G3PointDialog.ui @@ -6,8 +6,8 @@ 0 0 - 384 - 608 + 412 + 675 @@ -438,6 +438,35 @@ + + + + false + + + QFrame::Shape::NoFrame + + + 1 + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><meta charset="utf-8" /><style type="text/css"> +p, li { white-space: pre-wrap; } +hr { height: 1px; border-width: 0; } +li.unchecked::marker { content: "\2610"; } +li.checked::marker { content: "\2612"; } +</style></head><body style=" font-family:'Segoe UI'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:700;">Wolman</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Grid step = 1.1 * max(b_axis)</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:700;">Angles</span></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Dip is defined with respect to the z axis</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Azimut is defined in the xy plane</p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Mind the CloudCompare trihedron in the GUI</p></body></html> + + +