Files
TowerOptoSifAndSpectral/othersoft/calibration_console/Source_Files/calibration.cpp
2022-10-12 14:15:14 +08:00

272 lines
8.0 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "Header_Files/calibration.h"
CalibrationAlgorithm::CalibrationAlgorithm()
{
}
CalibrationAlgorithm::~CalibrationAlgorithm()
{
}
void CalibrationAlgorithm::readAndResample_StandardLightFile(QString filePath, int integratingSphereDetectorValue, DeviceAttribute deviceAttribute, DeviceInfo deviceInfo)
{
QFile file(filePath);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
{
std::cout << "文件不存在!" << std::endl;
return;
}
//读取标准灯数据
int lineCount = 0;
while (!file.atEnd())
{
QByteArray tmp = file.readLine();
lineCount++;
}
double * StandardLightWavelength_tmp = new double[lineCount - 1];
double * StandardLightData_tmp = new double[lineCount - 1];
file.seek(0);
for (size_t i = 0; i < lineCount; i++)
{
QByteArray line = file.readLine();
QString str(line);
//cout << str.section('\t', 1).trimmed().toStdString() << endl;
if (i == 0)
{
QString first = str.section('\t', 0, 0);
m_dStandardLightDataBase = first.toDouble();
}
else
{
QString first = str.section('\t', 0, 0);
QString second = str.section('\t', 1, 1);
StandardLightWavelength_tmp[i - 1] = first.toDouble();
StandardLightData_tmp[i - 1] = second.toDouble();
//if (i== lineCount-1)//查看最后一行数据是否正确
//{
// double xx = first.toDouble();
// double yy = second.toDouble();
// std::cout << "xx" << xx <<std::endl;
// std::cout << "yy" << yy << std::endl;
//}
}
}
//截取标准灯数据的有效段
int startPos, endPos;
int buffer = 3;//需要考虑标准灯原始文件的行数
//QString biaozhundengfanwei = QString::number(StandardLightWavelength_tmp[0]) + "--" + QString::number(StandardLightWavelength_tmp[lineCount - 2]);
if (deviceAttribute.fWaveLengthInNM[0] < StandardLightWavelength_tmp[0])//标准灯文件范围未包含光谱仪最小波长
{
startPos = 0;
}
else
{
for (size_t i = 0; i < lineCount - 1; i++)
{
if (deviceAttribute.fWaveLengthInNM[0] < StandardLightWavelength_tmp[i])
{
startPos = i - buffer;
break;
}
}
}
if (deviceAttribute.fWaveLengthInNM[deviceAttribute.iPixels - 1] > StandardLightWavelength_tmp[lineCount - 2])//标准灯文件范围未包含光谱仪最大波长
{
endPos = lineCount - 2;
}
else
{
for (size_t i = 0; i < lineCount - 1; i++)
{
if (deviceAttribute.fWaveLengthInNM[deviceAttribute.iPixels - 1] < StandardLightWavelength_tmp[i])
{
endPos = i + buffer;//??
break;
}
}
}
m_dStandardLightWavelength = new double[endPos - startPos];
m_dStandardLightData = new double[endPos - startPos];
for (size_t i = 0; i < endPos - startPos; i++)
{
m_dStandardLightWavelength[i] = StandardLightWavelength_tmp[i + startPos];
m_dStandardLightData[i] = StandardLightData_tmp[i + startPos];
}
//将截断标准灯数据输出到csv
QFileInfo fileInfo(filePath);
QString standardLightFileFolder = fileInfo.path();
QString standardLightFileName = fileInfo.fileName();
QDateTime curDateTime = QDateTime::currentDateTime();
QString currentTime = curDateTime.toString("yyyy_MM_dd_hh_mm_ss");
QString tmp = standardLightFileFolder + "/" + currentTime + "_" + QString::fromStdString(deviceInfo.strSN) +"_"+ standardLightFileName + "_truncation.csv";
std::ofstream outfile1(tmp.toStdString().c_str());
for (size_t i = 0; i < endPos - startPos; i++)
{
if (i == 0)
{
outfile1 << m_dStandardLightDataBase << std::endl;
}
outfile1 << m_dStandardLightWavelength[i] << "," << m_dStandardLightData[i] << std::endl;
}
outfile1.close();
//重采样标准灯数据
Eigen::VectorXd vx = Eigen::VectorXd::Map(m_dStandardLightWavelength, endPos - startPos/*x_vec.size()*/);
Eigen::VectorXd vy = Eigen::VectorXd::Map(m_dStandardLightData, endPos - startPos/*y_vec.size()*/);
using namespace ZZ_MATH::SplineFit;
SplineInterpolation m_sfLine(vx, vy);
m_dStandardLightWavelengthResampled = new double[deviceAttribute.iPixels];
m_dStandardLightDataResampled = new double[deviceAttribute.iPixels];
double dTemp,scaleFactor;
if(integratingSphereDetectorValue <= 0)
scaleFactor=1;
else
scaleFactor=integratingSphereDetectorValue/m_dStandardLightDataBase;
for (size_t i = 0; i < deviceAttribute.iPixels; i++)
{
if (deviceAttribute.fWaveLengthInNM[i] < StandardLightWavelength_tmp[0])//此波长 < 标准灯文件最小波长
{
dTemp = m_sfLine(StandardLightWavelength_tmp[0]);//???????????????
}
else if (StandardLightWavelength_tmp[lineCount - 2] < deviceAttribute.fWaveLengthInNM[i])//标准灯文件最大波长 < 此波长
{
dTemp = m_sfLine(StandardLightWavelength_tmp[lineCount - 2]);//???????????????
}
else
{
dTemp = m_sfLine(deviceAttribute.fWaveLengthInNM[i]);//?????
}
//double dTemp2 = m_sfLine(deviceAttribute.fWaveLengthInNM[i]);//外插结果,没有使用
m_dStandardLightWavelengthResampled[i] = deviceAttribute.fWaveLengthInNM[i];
m_dStandardLightDataResampled[i] = dTemp * scaleFactor;
}
//将重采样的标准灯数据输出到csv
QString outputName = standardLightFileFolder + "/" + currentTime + "_" + QString::fromStdString(deviceInfo.strSN) + "_" + standardLightFileName + "_resample.csv";
std::ofstream outfile2(outputName.toStdString().c_str());
for (size_t i = 0; i < deviceAttribute.iPixels; i++)
{
if (i == 0)
{
outfile2 << m_dStandardLightDataBase << std::endl;
}
outfile2 << deviceAttribute.fWaveLengthInNM[i] << "," << m_dStandardLightDataResampled[i] << std::endl;
}
outfile2.close();
}
void CalibrationAlgorithm::produceCalfile(QString calFilePath, DeviceAttribute deviceAttribute, DataFrame integratingSphereData, DataFrame darkData)
{
using namespace ZZ_MISCDEF;//ZZ_U32
int errorCode;
size_t writeCounter;
double* m_gain = new double[deviceAttribute.iPixels];//double*
double* m_offset = new double[deviceAttribute.iPixels];//double*
for (size_t i = 0; i < deviceAttribute.iPixels; i++)
{
if (integratingSphereData.lData[i] - darkData.lData[i] == 0)//如果分母为零
{
m_gain[i] = 0;
}
else
{
m_gain[i] = m_dStandardLightDataResampled[i] / (integratingSphereData.lData[i] - darkData.lData[i]);
}
m_offset[i] = 0;
}
//写入到二进制文件
FILE * calFileHandle = fopen(calFilePath.toStdString().c_str(), "wb");
writeCounter = fwrite(&integratingSphereData.usExposureTimeInMS,sizeof(ZZ_U32), 1, calFileHandle);//曝光时间
writeCounter = fwrite(&integratingSphereData.fTemperature, sizeof(float), 1, calFileHandle);//温度
writeCounter = fwrite(&deviceAttribute.iPixels, sizeof(int), 1, calFileHandle);//波长数
writeCounter = fwrite(&deviceAttribute.fWaveLengthInNM, sizeof(float), deviceAttribute.iPixels, calFileHandle);//波长
writeCounter = fwrite(m_gain, sizeof(double), deviceAttribute.iPixels, calFileHandle);//gain
writeCounter = fwrite(m_offset, sizeof(double), deviceAttribute.iPixels, calFileHandle);//offset
fclose(calFileHandle);
//写入到CSV文件
QString calFile_csv = calFilePath.split(".")[0] + ".csv";
std::ofstream outfile(calFile_csv.toStdString().c_str());
for (int i = 0; i < deviceAttribute.iPixels; i++)
{
if (i==0)
{
outfile << integratingSphereData.usExposureTimeInMS << std::endl;
}
outfile << deviceAttribute.fWaveLengthInNM[i] << "," << m_gain[i] << std::endl;
}
outfile.close();
//输出定标文件时,直接写结构体
using namespace ZZ_MISCDEF::ZZ_DATAFILE;//tagCalibrationFrame
tagCalibrationFrame calibrationFrame;
calibrationFrame.uiExposureTimeInMS = integratingSphereData.usExposureTimeInMS;
calibrationFrame.fTemperature = integratingSphereData.fTemperature;
calibrationFrame.iPixels = deviceAttribute.iPixels;
for (size_t i = 0; i < deviceAttribute.iPixels; i++)
{
calibrationFrame.fWaveLength[i] = deviceAttribute.fWaveLengthInNM[i];
calibrationFrame.dCal_Gain[i] = m_gain[i];
}
QStringList tmp = calFilePath.split('.');
QString calFilePath2 = tmp[0] + "_structure." + tmp[1];
FILE * calFileHandle2 = fopen(calFilePath2.toStdString().c_str(), "wb");
writeCounter = fwrite(&calibrationFrame,sizeof(tagCalibrationFrame), 1, calFileHandle2);
fclose(calFileHandle2);
delete[] m_gain;
delete[] m_offset;
}