diff --git a/experiment_data/sample_data/ABS.xlsx b/experiment_data/sample_data/ABS.xlsx new file mode 100644 index 0000000..0469b4e Binary files /dev/null and b/experiment_data/sample_data/ABS.xlsx differ diff --git a/src/DSCAnalysisTool.pro b/src/DSCAnalysisTool.pro index b0496a3..27dd395 100644 --- a/src/DSCAnalysisTool.pro +++ b/src/DSCAnalysisTool.pro @@ -9,7 +9,7 @@ CONFIG+=precompile_header PRECOMPILED_HEADER=stable.h # -VERSION = 1.0.8 +VERSION = 1.1.0 # 设置目标文件名,包含版本号 TARGET = DSCAnalysisTool_$${VERSION} @@ -120,13 +120,13 @@ FORMS += \ ui/specificheatcomparisonmethodform.ui INCLUDEPATH += serialport \ -ui \ -logger \ -thirdparty/easylogging \ -thirdparty/qcustomplot \ -data \ -. \ -thirdparty/eigen-3.4.0\Eigen + ui \ + logger \ + thirdparty/easylogging \ + thirdparty/qcustomplot \ + data \ + . \ + thirdparty/eigen-3.4.0\Eigen # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin diff --git a/src/data/pointcalculate.cpp b/src/data/pointcalculate.cpp index b8778b7..37e147f 100644 --- a/src/data/pointcalculate.cpp +++ b/src/data/pointcalculate.cpp @@ -619,16 +619,22 @@ QVector PointCalculate::getNearbyPointGroupByX(const float targetX) if (diff < minDiff) { minDiff = diff; - targetPointVtr = QVector(tmpPointVtr.end() - conCount, tmpPointVtr.end()); + if(tmpPointVtr.size() > conCount){ + targetPointVtr = QVector(tmpPointVtr.end() - conCount, tmpPointVtr.end()); + }else{ + targetPointVtr = tmpPointVtr; + } } } - return targetPointVtr; } // 计算两点之间的斜率 double PointCalculate::calculateSlope(double x1, double y1, double x2, double y2) { + if(x1 == x2){ + return 0.0; + } return (y2 - y1) / (x2 - x1); } @@ -659,6 +665,9 @@ QMap PointCalculate::calculateTangentLine( for (double xInflection : inflectionPointsX) { int i = std::distance(x.begin(), std::find(x.begin(), x.end(), xInflection)); double slope = calculateSlope(x[i - 1], y[i - 1], x[i + 1], y[i + 1]); + if(slope == 0.0){ + continue; + } double yInflection = y[i]; double intercept = yInflection - slope * xInflection; tangentLines[xInflection] = {slope, intercept}; @@ -1137,3 +1146,8 @@ std::pair PointCalculate::calculateMedianOIT(){ return std::make_pair(true, sortedData[n/2]); } } + + +double PointCalculate::calculateDistance(const QPointF& p1, const QPointF& p2) { + return std::sqrt(std::pow(p2.x() - p1.x(), 2) + std::pow(p2.y() - p1.y(), 2)); +} diff --git a/src/data/pointcalculate.h b/src/data/pointcalculate.h index af10cef..9262ab7 100644 --- a/src/data/pointcalculate.h +++ b/src/data/pointcalculate.h @@ -85,6 +85,7 @@ QPointF getIntersection(const Line& line1, const Line& line2); double calculateSlope(double x1, double y1, double x2, double y2) ; QVector findInflectionPoints(const QVector& x, const QVector& y) ; QMap calculateTangentLine(const QVector& x, const QVector& y) ; +double calculateDistance(const QPointF& p1, const QPointF& p2); //private void updateStartEndPoint(); @@ -104,6 +105,7 @@ QVector getPeakPointGroup(); std::vector movingAverage(const std::vector& data, int windowSize); QVector movingAveragePoint(const QVector& data, int windowSize); + extern QVector _dataVtr; extern QPointF _peakPoint; extern QPointF _leftSelectedPoint,_rightSelectedPoint; diff --git a/src/mainwindow.h b/src/mainwindow.h index 24e2693..e3d7ab7 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -127,6 +127,8 @@ private: void smoothness(const int level); QVector smoothnessDetail(const int level,const QVector&); void smoothnessExperimentData(const int level); + + private: bool _manuallyStopTheExperimentFlag; Ui::MainWindow *ui; diff --git a/src/ui/centralwidget.cpp b/src/ui/centralwidget.cpp index bb15207..d484406 100644 --- a/src/ui/centralwidget.cpp +++ b/src/ui/centralwidget.cpp @@ -617,7 +617,7 @@ void CentralWidget::slotSelectionChangedByUser() void CentralWidget::uiLoadXlsxFileData() { -#if 0 +#if 1 // Set axis. _customPlot->yAxis->setVisible(true); _customPlot->yAxis->setLabel(AxisDSC); @@ -632,6 +632,8 @@ void CentralWidget::uiLoadXlsxFileData() _customPlot->yAxis2->setVisible(true); _customPlot->yAxis2->setLabel(AxisTemperature); } + + _customPlot->replot(); #endif #if 1 @@ -759,12 +761,19 @@ void CentralWidget::uiLoadXlsxFileData() void CentralWidget::glassTransitionHandle(const double x1,const double x2,const QString objectName) { + QVector tickPositions = _customPlot->xAxis->tickVector(); + double step = tickPositions.at(1) - tickPositions.at(0); + logde<<"glassTransitionHandle step:"< point1Vtr = PointCalculate::getNearbyPointGroupByX(point1.x()); QVector point2Vtr = PointCalculate::getNearbyPointGroupByX(point2.x()); @@ -777,16 +786,15 @@ void CentralWidget::glassTransitionHandle(const double x1,const double x2,const PointCalculate::Line line1 = calculateLinearRegression(xVtr,yVtr); #if 1 - ///line1 - // QVector xVtr,yVtr; + //line1 xVtr.clear(); yVtr.clear(); xVtr.push_back(point1.x()); yVtr.push_back(point1.y()); - xVtr.push_back(point1.x() + 10); - double y1 = line1.slope * (point1.x() + 10) + line1.intercept; + xVtr.push_back(point1.x() + extendedLineStep); + double y1 = line1.slope * (point1.x() + extendedLineStep) + line1.intercept; yVtr.push_back(y1); QCPGraph *lineGraph1 = _customPlot->addGraph(); @@ -797,9 +805,9 @@ void CentralWidget::glassTransitionHandle(const double x1,const double x2,const QPen pen; pen.setColor(Qt::darkGreen); lineGraph1->setPen(pen); - #endif + //line2 xVtr.clear(); yVtr.clear(); for(QPointF &p:point2Vtr){ @@ -809,8 +817,7 @@ void CentralWidget::glassTransitionHandle(const double x1,const double x2,const PointCalculate::Line line2 = calculateLinearRegression(xVtr,yVtr); -#if 1 - ///line2 +#if 0 QVector xVtr2,yVtr2; xVtr2.push_back(point2.x()); yVtr2.push_back(point2.y()); @@ -846,18 +853,7 @@ void CentralWidget::glassTransitionHandle(const double x1,const double x2,const PointCalculate::Line targetLine; double maxSlopeAbs = 0.0; // 初始化最大斜率绝对值为0 -#if 0 - for (auto it = tangentLines.begin(); it != tangentLines.end(); ++it) { - if (std::fabs(it.value().slope) > maxSlopeAbs) { - maxSlopeAbs = std::fabs(it.value().slope); // 更新最大斜率绝对值 - - targetX = it.key(); - targetLine = it.value(); - } - } -#endif - - // new method + // for (auto it = tangentLines.begin(); it != tangentLines.end(); ++it) { if (std::fabs(it.value().slope) > maxSlopeAbs) { maxSlopeAbs = std::fabs(it.value().slope); // 更新最大斜率绝对值 @@ -881,26 +877,17 @@ void CentralWidget::glassTransitionHandle(const double x1,const double x2,const prePoint = pointVtr[index - 1]; lastPoint = pointVtr[index + 1]; - targetLine.slope = PointCalculate::calculateSlope(lastPoint.x(),lastPoint.y(),prePoint.x(),prePoint.y()); targetLine.intercept = currentPoint.y() - targetLine.slope * currentPoint.x(); // -#if 1 + QPointF intersection1 = PointCalculate::getIntersection(targetLine,line1); QPointF intersection2 = PointCalculate::getIntersection(targetLine,line2); - // graph 3 + // line 3 xVtr.clear(); yVtr.clear(); -#if 0 - xVtr.push_back(point1.x()); - yVtr.push_back(point1.y()); - - xVtr.push_back(point1.x()); - yVtr.push_back(point1.y()); -#endif - #if 1 xVtr.push_back(intersection1.x()); yVtr.push_back(intersection1.y()); @@ -914,12 +901,50 @@ void CentralWidget::glassTransitionHandle(const double x1,const double x2,const lineGraph3->setPen(pen); ItemManager::addTemporaryQCPGraph(lineGraph3,objectName); + + _customPlot->replot(); + + // draw line 2 + QVector xVtr2,yVtr2; + xVtr2.push_back(point2.x()); + yVtr2.push_back(point2.y()); + +#if 0 + xVtr2.push_back(point2.x() - 10); + double y2 = line2.slope * (point2.x() - 10) + line2.intercept; + yVtr2.push_back(y2); #endif + double minDistance = PointCalculate::calculateDistance(point2,intersection2); + // 计算延长线另一个端点,使线长度超过minDistance. + double halfOfExtendedLineStep = extendedLineStep /2; + double distance = 0.0; + int power = 0; + QPointF line2Endpoint; + while(distance < minDistance){ + power++; + + line2Endpoint.setX(point2.x() - halfOfExtendedLineStep * power); + line2Endpoint.setY(line2.slope * (point2.x() - halfOfExtendedLineStep * power) + + line2.intercept); + + distance = PointCalculate::calculateDistance( + point2,line2Endpoint); + } + + xVtr2.push_back(line2Endpoint.x()); + yVtr2.push_back(line2Endpoint.y()); + + QCPGraph *lineGraph2 = _customPlot->addGraph(); + lineGraph2->setData(xVtr2, yVtr2); + lineGraph2->setPen(pen); + + ItemManager::addTemporaryQCPGraph(lineGraph2,objectName); + _customPlot->replot(); // point value - double averageY = (point1.y() + point2.y()) / 2; + double averageY = (intersection1.y() + intersection2.y()) / 2; QPointF averagePoint = PointCalculate::getClosestPointByY(point1.x(),point2.x(),averageY); @@ -1137,6 +1162,9 @@ void CentralWidget::fillGraph(const double x1, const double x2,const QString obj yVtr.push_back(x2Ed.dsc); if(_axisMode == AxisMode::DoubleY){ + x1Ed = PointCalculate::getClosestDataByTime(x1); + x2Ed = PointCalculate::getClosestDataByTime(x2); + xVtr.clear(); xVtr.push_back(x1Ed.runTime); @@ -1343,22 +1371,31 @@ void CentralWidget::calculateAnalysisResult( { logde<<"calculateAnalysisResult..."; + logde<<"x1,x2:"<parent(), "warnning", "曲线选择错误."); + return; + } - if(Global::isZero(ed.dsc)){ - QMessageBox::warning((QWidget*)this->parent(), "warnning", "曲线选择错误."); - return; - } + selectPoint = QPointF(ed.sampleTemp,ed.dsc); + str = PointCalculate::textFormatNumbericalLabel(selectPoint); + }else{ + Global::ExperimentData ed = PointCalculate::getClosestDataByTime(x1); - QPointF selectPoint(ed.sampleTemp,ed.dsc); - QString str = PointCalculate::textFormatNumbericalLabel(selectPoint); - if(_axisMode == AxisMode::DoubleY){ - selectPoint.setX(ed.runTime); + if(Global::isZero(ed.dsc)){ + QMessageBox::warning((QWidget*)this->parent(), "warnning", "曲线选择错误."); + return; + } + selectPoint = QPointF(ed.runTime,ed.dsc); str = PointCalculate::textFormatNumbericalLabelWithTime(selectPoint); } @@ -1405,7 +1442,9 @@ void CentralWidget::calculateAnalysisResult( } case AnalysisMode::PeakSynthesisAnalysis: { + fillGraph(x1,x2,objectName); + return; PointCalculate::setRegionPointX(x1,x2); @@ -1501,7 +1540,6 @@ void CentralWidget::calculateAnalysisResult( { glassTransitionHandle(x1,x2,objectName); - // break; } case AnalysisMode::OnsetTemperaturePoint:{ @@ -1644,6 +1682,7 @@ void CentralWidget::setAxisMode(AxisMode mode) if(_axisMode != mode){ _axisMode = mode; +#if 0 // Set axis. _customPlot->yAxis->setVisible(true); _customPlot->yAxis->setLabel(AxisDSC); @@ -1660,11 +1699,109 @@ void CentralWidget::setAxisMode(AxisMode mode) } _customPlot->replot(); +#endif uiLoadXlsxFileData(); } } +void CentralWidget::peakSynthesisDoubleAxisY(const double, const double,const QString objectName) +{ + +} + +void CentralWidget::peakSynthesisSingleAxisY(const double x1, const double x2,const QString objectName) +{ + fillGraph(x1,x2,objectName); + + PointCalculate::setRegionPointX(x1,x2); + + //enthalpy + double sampleWeight = 1.0f; + if(Global::_curveFileDataVtr.empty()){ + sampleWeight = Global::converStrToDouble(Global::_experimentInfo.sampleWeight); + }else{ + for(Global::CurveFileData& cfd:Global::_curveFileDataVtr){ + for(Global::PhaseTotalInfo& pti:cfd.phaseTotalVtr){ + +#if 0 + if(_currentCurve && _currentCurve == pti.curve){ + sampleWeight = cfd.ei.sampleWeight.toDouble(); + } +#endif + if(_currentCurve){ + if(_currentCurve == pti.curve){ + sampleWeight = cfd.ei.sampleWeight.toDouble(); + }else{ + } + }else{ + // logde<<"current curve nullptr."; + } + } + } + } + + if(sampleWeight <= 0){ + logde<<"sample weight set value 1,"< startEndPointPair = + PointCalculate::calculateStartAndEndPoint(); + + logde<<"start,end:"<