2025-05-07T17:33:02

This commit is contained in:
yuntang 2025-05-07 17:33:03 +08:00
parent 225ff71859
commit 62bf7d4d9f
10 changed files with 176 additions and 80 deletions

Binary file not shown.

Binary file not shown.

View File

@ -259,17 +259,19 @@ float PointCalculate::calculateArea() {
float startTemp = _leftSelectedPoint.x();
float value1 = Global::_enthalpyCoefficientVtr.at(0);
float value2 = Global::_enthalpyCoefficientVtr.at(0);
float value3 = Global::_enthalpyCoefficientVtr.at(0);
float c = Global::_enthalpyCoefficientVtr.at(0);
float b = Global::_enthalpyCoefficientVtr.at(1);
float a = Global::_enthalpyCoefficientVtr.at(2);
coefficient = value1 * startTemp * startTemp +
value2 * startTemp +
value3;
coefficient = a * startTemp * startTemp +
b * startTemp +
c;
logde<<"coefficient:"<<coefficient;
}
float area = integral * coefficient ;
float area = integral * coefficient * Global::DefaultParamter;
return area;
}
@ -661,3 +663,29 @@ double PointCalculate::obtainTimeValueBasedOnTemperatureValue(const double sampl
return targetValue;
}
QPointF PointCalculate::onsetTemperaturePoint(const double x1, const double x2)
{
const double threshold = 0.1;
QPointF targetPoint;
QVector<QPointF> pointVtr = getPointVtrInXRange(x1,x2);
for(int i = 3;i < pointVtr.size();i++){
QPointF prePoint1 = pointVtr.at(i - 1);
QPointF prePoint2 = pointVtr.at(i - 2);
QPointF prePoint3 = pointVtr.at(i - 3);
QPointF currentPoint = pointVtr.at(i);
if(std::abs(prePoint1.y() - currentPoint.y()) > threshold){
targetPoint = pointVtr.at(i - 3);
}
if(std::abs(prePoint2.y() - currentPoint.y()) > threshold){
targetPoint = pointVtr.at(i - 3);
}
if(std::abs(prePoint3.y() - currentPoint.y()) > threshold){
targetPoint = pointVtr.at(i - 3);
}
}
return targetPoint;
}

View File

@ -50,6 +50,8 @@ double calculateSlope(double x1, double y1, double x2, double y2) ;
QVector<double> findInflectionPoints(const QVector<double>& x, const QVector<double>& y) ;
QMap<double, Line> calculateTangentLine(const QVector<double>& x, const QVector<double>& y) ;
QPointF onsetTemperaturePoint(const double x1,const double x2);
//private
void updateStartEndPoint();
QPair<QPointF,QPointF> calculateMaxDiffPointLeft();

View File

@ -18,8 +18,21 @@ const QString AnalysisStateFolder = ExperimentDirPath + "/analysis_state";
const QString CurveOfTimeTypeObjectName("curve_time");
// json string.
const QString AtomsphereData("atomsphereData");
const QString SampleData("sampleData");
const QString Atmosphere("atmosphere");
const QString HeatingRate("heatingRate");
const QString SampleName("sampleName");
const QString TemperatureStr("temperature");
const QString RateStr("rate");
//
const double DefaultParamter = 1.0;
//
enum Mode{
Analysis,
ConnectedToDev,

View File

@ -166,6 +166,8 @@ void CentralWidget::setAnalysisMode(const CentralWidget::AnalysisMode mode)
case AnalysisMode::StopPoint:
case AnalysisMode::PeakSynthesisAnalysis:
case AnalysisMode::GlassTransition:
case AnalysisMode::OnsetTemperaturePoint:
case AnalysisMode::EndsetTemperaturePoint:
_customPlot->setInteractions(QCP::iSelectPlottables);
setEventHandlerEnable(true);
break;
@ -288,6 +290,7 @@ void CentralWidget::slotRecvAnalysisFileName(const QString &filePath)
_currentCurve = new QCPCurve(_customPlot->xAxis, _customPlot->yAxis);
_currentCurve->setData(tVtr, xVtr, yVtr);
_currentCurve->setSelectable(QCP::stWhole); // 设置曲线可选
_currentCurve->setLineStyle(QCPCurve::lsLine); // 线性连接
pti.curve = _currentCurve;
}
@ -398,6 +401,22 @@ void CentralWidget::slotAnalysisSettingApply()
//
break;
}
case AnalysisMode::OnsetTemperaturePoint:{
double x1 = _line1->point1->coords().x();
double x2 = _line2->point1->coords().x();
QPointF point = PointCalculate::onsetTemperaturePoint(x1,x2);
QString str = QString::number(point.y(),'f',3);
drawText(point,str);
break;
}
case AnalysisMode::EndsetTemperaturePoint:{
break;
}
default:
break;
}

View File

@ -58,14 +58,34 @@ void CoefficientSelectionForm::on_pushButtonConfirm_clicked()
Global::_enthalpyCoefficientEnableFlag = false;
}else{
QVector<double> xVtr,yVtr;
QJsonDocument jsonDoc = QJsonDocument::fromJson(_jsonStr.toUtf8());
QJsonArray jsonArray = jsonDoc.array();
QJsonDocument doc = QJsonDocument::fromJson(_jsonStr.toUtf8());
if (doc.isNull()) {
logde << "Failed to parse JSON data";
return;
}
if (!doc.isObject()) {
logde << "JSON data is not an object";
return ;
}
QJsonObject majorObj = doc.object();
{
QJsonObject subObj = majorObj[Global::AtomsphereData].toObject();
double temperature = subObj[Global::Atmosphere].toDouble();
double heatingRate = subObj[Global::HeatingRate].toDouble();
logde<<"temperatur:"<<temperature;
logde<<"heatingRate:"<<heatingRate;
}
QJsonArray jsonArray = majorObj[Global::SampleData].toArray();
QVector<double> xVtr,yVtr;
for (const QJsonValue &value : jsonArray) {
QJsonObject jsonObj = value.toObject();
xVtr<<jsonObj["temperature"].toDouble();
yVtr<<jsonObj["rate"].toDouble();
xVtr<<jsonObj[Global::TemperatureStr].toDouble();
yVtr<<jsonObj[Global::RateStr].toDouble();
}
double coeff[3] = {0};
@ -78,9 +98,8 @@ void CoefficientSelectionForm::on_pushButtonConfirm_clicked()
<< coeff[2] << std::endl;
#endif
logde<<"y:"<<coeff[0]<<","
<<coeff[1]<<","
logde<<"y:"<<coeff[0]<<"x2,"
<<coeff[1]<<"x,"
<<coeff[2];
Global::_enthalpyCoefficientEnableFlag = true;
@ -108,72 +127,67 @@ void CoefficientSelectionForm::on_pushButtonExit_clicked()
hide();
}
void CoefficientSelectionForm::quadraticLeastSquaresFit(double x[], double y[], int n, double coeff[]) {
if (n < 3) {
throw std::runtime_error("At least 3 data points are required for quadratic fit.");
throw std::invalid_argument("At least 3 data points are required for quadratic fitting");
}
// 计算各次幂的和
double sum_x = 0.0, sum_x2 = 0.0, sum_x3 = 0.0, sum_x4 = 0.0;
double sum_y = 0.0, sum_xy = 0.0, sum_x2y = 0.0;
double sum_x = 0, sum_x2 = 0, sum_x3 = 0, sum_x4 = 0;
double sum_y = 0, sum_xy = 0, sum_x2y = 0;
// 计算各项累加和
for (int i = 0; i < n; ++i) {
sum_x += x[i];
sum_x2 += x[i] * x[i];
sum_x3 += x[i] * x[i] * x[i];
sum_x4 += x[i] * x[i] * x[i] * x[i];
sum_y += y[i];
sum_xy += x[i] * y[i];
sum_x2y += x[i] * x[i] * y[i];
double xi = x[i];
double xi2 = xi * xi;
double xi3 = xi2 * xi;
double xi4 = xi3 * xi;
double yi = y[i];
sum_x += xi;
sum_x2 += xi2;
sum_x3 += xi3;
sum_x4 += xi4;
sum_y += yi;
sum_xy += xi * yi;
sum_x2y += xi2 * yi;
}
// 构建法方程矩阵 A 和向量 b
double A[3][3] = {
{sum_x2, sum_x, n},
{sum_x3, sum_x2, sum_x},
{sum_x4, sum_x3, sum_x2}
// 构建正规方程组的增广矩阵
double matrix[3][4] = {
{sum_x4, sum_x3, sum_x2, sum_x2y}, // 对应方程: a*Σx⁴ + b*Σx³ + c*Σx² = Σx²y
{sum_x3, sum_x2, sum_x, sum_xy}, // 对应方程: a*Σx³ + b*Σx² + c*Σx = Σxy
{sum_x2, sum_x, static_cast<double>(n), sum_y} // 对应方程: a*Σx² + b*Σx + c*n = Σy
};
double b[3] = {sum_x2y, sum_xy, sum_y};
// 使用高斯消元法线性方程组
// 高斯消元法解方程组
for (int i = 0; i < 3; ++i) {
// 寻找主元行
int max_row = i;
double max_val = std::fabs(A[i][i]);
for (int j = i + 1; j < 3; ++j) {
if (std::fabs(A[j][i]) > max_val) {
max_val = std::fabs(A[j][i]);
max_row = j;
// 部分主元选择
int maxRow = i;
for (int k = i + 1; k < 3; ++k) {
if (std::abs(matrix[k][i]) > std::abs(matrix[maxRow][i])) {
maxRow = k;
}
}
// 交换行
if (max_row != i) {
for (int k = 0; k < 3; ++k) {
std::swap(A[i][k], A[max_row][k]);
}
std::swap(b[i], b[max_row]);
for (int k = i; k < 4; ++k) {
std::swap(matrix[i][k], matrix[maxRow][k]);
}
// 消元
for (int j = i + 1; j < 3; ++j) {
double factor = A[j][i] / A[i][i];
for (int k = i; k < 3; ++k) {
A[j][k] -= factor * A[i][k];
for (int k = i + 1; k < 3; ++k) {
double factor = matrix[k][i] / matrix[i][i];
for (int j = i; j < 4; ++j) {
matrix[k][j] -= factor * matrix[i][j];
}
b[j] -= factor * b[i];
}
}
// 回代求解
coeff[2] = b[2] / A[2][2];
for (int i = 1; i >= 0; --i) {
double sum = 0.0;
for (int j = i + 1; j < 3; ++j) {
sum += A[i][j] * coeff[j];
}
coeff[i] = (b[i] - sum) / A[i][i];
}
coeff[2] = matrix[2][3] / matrix[2][2]; // c
coeff[1] = (matrix[1][3] - matrix[1][2] * coeff[2]) / matrix[1][1]; // b
coeff[0] = (matrix[0][3] - matrix[0][2] * coeff[2] - matrix[0][1] * coeff[1]) / matrix[0][0]; // a
}
void CoefficientSelectionForm::on_pushButtonSelectFile_clicked()
{
@ -198,6 +212,8 @@ void CoefficientSelectionForm::on_pushButtonSelectFile_clicked()
//
ui->labelFilePath->setText(filePath);
ui->labelFilePath->setToolTip(filePath);
ui->textEditFileContent->setText(_jsonStr);
}

View File

@ -8,6 +8,7 @@
#include "enthalpydatacorrectionform.h"
#include "ui_enthalpydatacorrectionform.h"
#include "global.h"
EnthalpyDataCorrectionForm::EnthalpyDataCorrectionForm(QWidget *parent) :
QWidget(parent),
@ -30,131 +31,134 @@ EnthalpyDataCorrectionForm::~EnthalpyDataCorrectionForm()
void EnthalpyDataCorrectionForm::on_pushButtonSave_clicked()
{
_atmosphere = ui->lineEditAtomsphere->text().toDouble();
_heatingRate = ui->lineEditHeatingRate->text().toDouble();
if(ui->checkBoxC6H12->isChecked()){
double temperature = ui->labelTempC6H12->text().toDouble();
double theory = ui->lineEditTheoryC6H12->text().toDouble();
double measure = ui->lineEditMeasC6H12->text().toDouble();
_theoryDataVtr.push_back({temperature,theory/measure});
_theoryDataVtr.push_back({"C6H12",temperature,theory/measure});
}
if(ui->checkBoxHg->isChecked()){
double temperature = ui->labelTempHg->text().toDouble();
double theory = ui->lineEditTheoryHg->text().toDouble();
double measure = ui->lineEditMeasHg->text().toDouble();
_theoryDataVtr.push_back({temperature,theory/measure});
_theoryDataVtr.push_back({"Hg",temperature,theory/measure});
}
if(ui->checkBoxC6H5COOH->isChecked()){
double temperature = ui->labelTempC6H5COOH->text().toDouble();
double theory = ui->lineEditTheoryC6H5COOH->text().toDouble();
double measure = ui->lineEditMeasC6H5COOH->text().toDouble();
_theoryDataVtr.push_back({temperature,theory/measure});
_theoryDataVtr.push_back({"C6H5COOH",temperature,theory/measure});
}
if(ui->checkBoxIn->isChecked()){
double temperature = ui->labelTempIn->text().toDouble();
double theory = ui->lineEditTheoryIn->text().toDouble();
double measure = ui->lineEditMeasIn->text().toDouble();
_theoryDataVtr.push_back({temperature,theory/measure});
_theoryDataVtr.push_back({"In",temperature,theory/measure});
}
if(ui->checkBoxSn->isChecked()){
double temperature = ui->labelTempSn->text().toDouble();
double theory = ui->lineEditTheorySn->text().toDouble();
double measure = ui->lineEditMeasSn->text().toDouble();
_theoryDataVtr.push_back({temperature,theory/measure});
_theoryDataVtr.push_back({"Sn",temperature,theory/measure});
}
if(ui->checkBoxBi->isChecked()){
double temperature = ui->labelTempBi->text().toDouble();
double theory = ui->lineEditTheoryBi->text().toDouble();
double measure = ui->lineEditMeasBi->text().toDouble();
_theoryDataVtr.push_back({temperature,theory/measure});
_theoryDataVtr.push_back({"Bi",temperature,theory/measure});
}
if(ui->checkBoxKC1O3->isChecked()){
double temperature = ui->labelTempKC1O3->text().toDouble();
double theory = ui->lineEditTheoryKC1O3->text().toDouble();
double measure = ui->lineEditMeasKC103->text().toDouble();
_theoryDataVtr.push_back({temperature,theory/measure});
_theoryDataVtr.push_back({"KC1O3",temperature,theory/measure});
}
if(ui->checkBoxPb->isChecked()){
double temperature = ui->labelTempPb->text().toDouble();
double theory = ui->lineEditTheoryPb->text().toDouble();
double measure = ui->lineEditMeasPb->text().toDouble();
_theoryDataVtr.push_back({temperature,theory/measure});
_theoryDataVtr.push_back({"Pb",temperature,theory/measure});
}
if(ui->checkBoxKNO3->isChecked()){
double temperature = ui->labelTempKNO3->text().toDouble();
double theory = ui->lineEditTheoryKNO3->text().toDouble();
double measure = ui->lineEditMeasKNO3->text().toDouble();
_theoryDataVtr.push_back({temperature,theory/measure});
_theoryDataVtr.push_back({"KNO3",temperature,theory/measure});
}
if(ui->checkBoxZn->isChecked()){
double temperature = ui->labelTempZn->text().toDouble();
double theory = ui->lineEditTheoryZn->text().toDouble();
double measure = ui->lineEditMeasZn->text().toDouble();
_theoryDataVtr.push_back({temperature,theory/measure});
_theoryDataVtr.push_back({"Zn",temperature,theory/measure});
}
if(ui->checkBoxAg2SO4->isChecked()){
double temperature = ui->labelTempAg2SO4->text().toDouble();
double theory = ui->lineEditTheoryAg2SO4->text().toDouble();
double measure = ui->lineEditMeasAg2SO4->text().toDouble();
_theoryDataVtr.push_back({temperature,theory/measure});
_theoryDataVtr.push_back({"Ag2SO4",temperature,theory/measure});
}
if(ui->checkBoxCsCl->isChecked()){
double temperature = ui->labelTempCsC1->text().toDouble();
double theory = ui->lineEditTheoryCsC1->text().toDouble();
double measure = ui->lineEditMeasCsCl->text().toDouble();
_theoryDataVtr.push_back({temperature,theory/measure});
_theoryDataVtr.push_back({"CsCl",temperature,theory/measure});
}
if(ui->checkBoxSiO2->isChecked()){
double temperature = ui->labelTempSiO2->text().toDouble();
double theory = ui->lineEditTheorySiO2->text().toDouble();
double measure = ui->lineEditMeasSiO2->text().toDouble();
_theoryDataVtr.push_back({temperature,theory/measure});
_theoryDataVtr.push_back({"SiO2",temperature,theory/measure});
}
if(ui->checkBoxK2SO4->isChecked()){
double temperature = ui->labelTempK2SO4->text().toDouble();
double theory = ui->lineEditTheoryK2SO4->text().toDouble();
double measure = ui->lineEditMeasK2SO4->text().toDouble();
_theoryDataVtr.push_back({temperature,theory/measure});
_theoryDataVtr.push_back({"K2SO4",temperature,theory/measure});
}
if(ui->checkBoxK2CrO4->isChecked()){
double temperature = ui->labelTempK2CrO4->text().toDouble();
double theory = ui->lineEditTheoryK2CrO4->text().toDouble();
double measure = ui->lineEditMeasK2CrO4->text().toDouble();
_theoryDataVtr.push_back({temperature,theory/measure});
_theoryDataVtr.push_back({"K2CrO4",temperature,theory/measure});
}
if(ui->checkBoxBaCO3->isChecked()){
double temperature = ui->labelTempBaCO3->text().toDouble();
double theory = ui->lineEditTheoryBaCO3->text().toDouble();
double measure = ui->lineEditMeasBaCO3->text().toDouble();
_theoryDataVtr.push_back({temperature,theory/measure});
_theoryDataVtr.push_back({"BaCO3",temperature,theory/measure});
}
if(ui->checkBoxAg->isChecked()){
double temperature = ui->labelTempAg->text().toDouble();
double theory = ui->lineEditTheoryAg->text().toDouble();
double measure = ui->lineEditMeasAg->text().toDouble();
_theoryDataVtr.push_back({temperature,theory/measure});
_theoryDataVtr.push_back({"Ag",temperature,theory/measure});
}
if(ui->checkBoxCu->isChecked()){
double temperature = ui->labelTempCu->text().toDouble();
double theory = ui->lineEditTheoryCu->text().toDouble();
double measure = ui->lineEditMeasCu->text().toDouble();
_theoryDataVtr.push_back({temperature,theory/measure});
_theoryDataVtr.push_back({"Cu",temperature,theory/measure});
}
//
saveJson();
@ -168,16 +172,27 @@ void EnthalpyDataCorrectionForm::on_pushButtonExit_clicked()
void EnthalpyDataCorrectionForm::saveJson()
{
// 创建一个 QJsonArray 来存储数据
QJsonObject majorObj;
{
QJsonObject subObj;
subObj[Global::Atmosphere] = _atmosphere;
subObj[Global::HeatingRate] = _heatingRate;
majorObj[Global::AtomsphereData] = subObj;
}
QJsonArray jsonArray;
for (const TheoryData &data : _theoryDataVtr) {
QJsonObject jsonObj;
jsonObj["temperature"] = data.temperature;
jsonObj["rate"] = data.rate;
jsonObj[Global::TemperatureStr] = data.temperature;
jsonObj[Global::RateStr] = data.rate;
jsonArray.append(jsonObj);
}
// 创建一个 QJsonDocument 并设置根数组
QJsonDocument doc(jsonArray);
majorObj[Global::SampleData] = jsonArray;
QJsonDocument doc(majorObj);
// 打开保存文件对话框,让用户选择保存位置
QString fileName = QFileDialog::getSaveFileName(nullptr, "保存 JSON 文件",

View File

@ -22,7 +22,10 @@ private slots:
private:
void saveJson();
private:
double _atmosphere;
double _heatingRate;
struct TheoryData{
QString sampleName;
double temperature;
double rate;
};

View File

@ -656,7 +656,7 @@
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEditAtomsphereRate"/>
<widget class="QLineEdit" name="lineEditHeatingRate"/>
</item>
</layout>
</widget>