AnalysisSystemForRadionucli.../DataStore.cpp
2024-06-04 15:25:02 +08:00

637 lines
24 KiB
C++
Raw Permalink 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 "DataStore.h"
#include <QDateTime>
#include <QFile>
#include <QTextStream>
#include <QCoreApplication>
#include <QDebug>
#include <vector>
#include <QtMath>
#include <QSettings>
#include <QDir>
#include "GammaAnalyAlgLib.h"
#include "GammaAnalyALG.h"
#include "analyseflow.h"
#define double_to_no_precision(x) x,0,'f'
#define double_to_six_precision(x) x,15,'f',6
#define DBL_MAX 1.7976931348623158e+308
//#define OPERATOR_Manager QLatin1String("管理员")
//#define OPERATOR_Analyst QLatin1String("分析员")
//#define OPERATOR_SeniorAnalyst QLatin1String("高级分析员")
#define Role_Manager QString("Administrator")
#define Role_SuperAnalyst QString("SeniorAnalyst")
#define Role_Analyst QString("Analyst")
#define SAMPLEID QLatin1String("ANLYSAMPLEID")
#define OPERATOR_AUTO QLatin1String("Auto")
#define DECLARESAMPLEID QLatin1String("SMAPLEID")
#define ANLYID QLatin1String("ANLYID")
#define Status_U QLatin1String("U")
#define Status_R QLatin1String("R")
#define Status_F QLatin1String("F")
DataStore* DataStore::m_dataStore = 0;
DataStore::DataStore() : m_phd(0), m_nCount(0), m_nSChan(0), m_dStep(0.25), m_bRewriteAll(false)
{
// 加载默认用户核素库
m_userlib_G = AlgFunc::UserNuclide("G");
m_userlib_P = AlgFunc::UserNuclide("P");
}
DataStore *DataStore::GetDataStore()
{
if(m_dataStore == 0)
{
m_dataStore = new DataStore();
}
return m_dataStore;
}
DataStore::~DataStore()
{
}
bool DataStore::AnalyseData(QString strPath, ThrCallBack callFuc)
{
AnalyseFlow fow(this, strPath, callFuc);
// printf("1######\n");
}
void DataStore::SetQuery(const QSqlQuery &query, bool bRemote)
{
m_bFromDB = bRemote;
m_query = query;
m_mapNucLineG = GetNuclideLines(m_userlib_G);
m_mapNucLineP = GetNuclideLines(m_userlib_P);
}
void DataStore::SetPHD(PHDFile* phd)
{
m_phd = phd;
m_nCount = 0;
m_vCount.clear();
m_userlib.clear();
if(m_phd)
{
m_nCount = phd->Spec.num_g_channel;
m_nSChan = phd->Spec.begin_channel;
// 确保绘制曲线时所有谱都是从1道开始
int i = 0;
if(m_nSChan == 0) i = 1;
for(; i<m_nCount; ++i)
{
m_vCount.push_back(phd->Spec.counts[i]);
}
if(m_nSChan == 0) m_vCount.push_back(0);
// 加载默认用户核素库
if(phd->header.system_type.toUpper() == "G")
{
if(m_userlib_G.isEmpty()) m_userlib_G = AlgFunc::UserNuclide("G");
m_userlib = m_userlib_G;
}
else {
if(m_userlib_P.isEmpty()) m_userlib_P = AlgFunc::UserNuclide("P");
m_userlib = m_userlib_P;
}
}
}
int DataStore::GetChannelByEnergy(double energy, int startIndex)
{
// 注索引从0开始道从1开始道 = 索引 + 1
if(startIndex < 0) startIndex = 0;
int channel = startIndex + 1; // 将 channel 设为 startIndex 处的道数
for(int i=channel; i<m_phd->vEnergy.size(); ++i) // 从 startIndex 的下一个索引开始
{
if(m_phd->vEnergy[i] >= energy)
{
if(m_phd->vEnergy[i] - energy > energy - m_phd->vEnergy[i-1]) channel = i; // 道在索引(i-1)处
else channel = i+1; // 道在索引(i)处
break;
}
}
return channel;
}
double DataStore::GetEnergyByFloatChan(double x)
{
// 算法描述:取指定点附近的两点,根据 y=ax+b 方程求指定点处的能量
double y = 0.0;
int channel = x;
int index = channel > 0 ? channel-1 : channel; // 确保索引大于等于0
if(m_phd->vEnergy.size() == m_nCount && index < m_nCount) // 确保索引有效
{
int index2 = (index < m_nCount-1 ? index + 1 : index - 1);
double y1 = m_phd->vEnergy[index];
double y2 = m_phd->vEnergy[index2];
y = y1 + (y2 - y1) / (index2 - index) * (x - index);
}
return y;
}
int DataStore::FindNearPeak(const vector<PeakInfo> &vPeak, int channel, bool *bFind)
{
bool t_bFind = false;
int i=0, peakNum = vPeak.size();
for(; i<peakNum; ++i)
{
const PeakInfo &peak = vPeak[i];
if(channel >= peak.left && channel <= peak.right) // 如果 channel 在峰的左右边界内
{
if(peak.multiIndex > 0 && channel > peak.peakCentroid) // 如果是重峰,且 channel 在重峰的第一个峰的中心道右侧
{
int j = i;
double temp = channel - peak.peakCentroid;
while(++j < peakNum && vPeak[j].multiIndex == peak.multiIndex)
{
if(qAbs(vPeak[j].peakCentroid - channel) < temp) // 找出重峰中峰中心道离 channel 最近的峰
{
temp = qAbs(vPeak[j].peakCentroid - channel);
i = j;
}
}
}
// channel 在索引(i)对应的峰内
t_bFind = true;
break;
}
else if(peak.left > channel) // channel 不在任何峰内,找离它最近的峰
{
if(i>0 && channel-vPeak[i-1].peakCentroid < peak.peakCentroid-channel) i -= 1;
break;
}
}
if(i >= peakNum) i -= 1;
if(bFind) *bFind = t_bFind;
return i;
}
double DataStore::GetSignificance(int channel)
{
double signif = 0.0;
bool bFind;
int peakIndex = FindNearPeak(m_phd->vPeak, channel, &bFind);
if(bFind)
{
signif = m_phd->vPeak[peakIndex].significance;
}
return signif;
}
double DataStore::GetSignificance(double energy)
{
return GetSignificance(GetChannelByEnergy(energy));
}
/*ChartData DataStore::Energy_Count(double start, double end)
{
ChartData cData;
if(start < end)
{
int startIndex = GetChannelByEnergy(start);
int endIndex = GetChannelByEnergy(end, startIndex);
cData = Energy_Count(startIndex, endIndex);
}
return cData;
}*/
QString RightFill(QString str, int fieldWidth = 0, QChar fillChar = ' ')
{
int fillNum = fieldWidth - str.length();
while(fillNum > 0)
{
str.append(fillChar);
--fillNum;
}
return str;
}
QString DataStore::MakeUpSpectrum(PHDFile *phd)
{
QString spectrum = "";
spectrum += "BEGIN IMS2.0" + STRING_END;
spectrum += QString("MSG_TYPE %1%2").arg(phd->msgInfo.msg_type, STRING_END);
spectrum += QString("MSG_ID %1 %2%3").arg(phd->msgInfo.msg_id, phd->msgInfo.msg_src_code, STRING_END);
if(phd->msgInfo.verify_srid)
{
spectrum += "REF_ID" + STRING_END;
spectrum += QString("%1 %2 %3 %4%5").arg(phd->msgInfo.ref_id_str, phd->msgInfo.ref_src_code, phd->msgInfo.seq_num, phd->msgInfo.tot_num, STRING_END);
spectrum += QString("PROD_ID %1 %2%3").arg(phd->msgInfo.product_id, phd->msgInfo.delivery_id, STRING_END);
}
spectrum += QString("DATA_TYPE %1%2").arg(phd->msgInfo.data_type, STRING_END);
QStringList data_types;
data_types.push_back("SAMPLEPHD");
data_types.push_back("SPHDF");
data_types.push_back("SPHDP");
data_types.push_back("GASBKPHD");
data_types.push_back("BLANKPHD");
data_types.push_back("DETBKPHD");
data_types.push_back("QCPHD");
data_types.push_back("CALIBPHD");
if(!data_types.contains(phd->msgInfo.data_type)) return spectrum;
// #Header
spectrum += QString("#Header %1%2").arg(phd->header.designator, STRING_END);
spectrum += QString("%1 %2 %3 %4 %5%6").arg(RightFill(phd->header.site_code, 5),
RightFill(phd->header.detector_code, 9),
RightFill(phd->header.system_type, 1),
RightFill(phd->header.sample_geometry, 17),
RightFill(phd->header.spectrum_quantity, 4), STRING_END);
spectrum += phd->header.sample_ref_id + STRING_END;
spectrum += QString("%1 %2 %3%4").arg(RightFill(phd->header.measurement_id, 31),
RightFill(phd->header.detector_bk_measurement_id, 31),
phd->header.gas_bk_measurement_id, STRING_END);
spectrum += QString("%1 %2%3").arg(phd->header.transmit_date, phd->header.transmit_time, STRING_END);
// #Comment
if(!phd->oriTotalCmt.isEmpty())
{
QString comment = phd->oriTotalCmt.replace("\r\n", "\n");
comment.replace("\n", STRING_END);
spectrum += "#Comment" + STRING_END;
spectrum += comment + STRING_END;
}
// #Collection
spectrum += "#Collection" + STRING_END;
spectrum += QString("%1 %2 %3 %4 %5%6").arg(phd->collect.collection_start_date, phd->collect.collection_start_time,
phd->collect.collection_stop_date, phd->collect.collection_stop_time,
QString::number(phd->collect.air_volume), STRING_END);
// #Acquisition
spectrum += "#Acquisition" + STRING_END;
spectrum += QString("%1 %2 %3 %4").arg(phd->acq.acquisition_start_date)
.arg(phd->acq.acquisition_start_time)
.arg(RightFill(QString::number(phd->acq.acquisition_real_time, 'f', 2), 14))
.arg(RightFill(QString::number(phd->acq.acquisition_live_time, 'f', 2), 14)) + STRING_END;
// #Processing
if(phd->process.sample_volume_of_Xe > 0)
{
spectrum += "#Processing" + STRING_END;
spectrum += QString("%1 %2%3 %4 %5%6 %7%8").arg(RightFill(QString::number(phd->process.sample_volume_of_Xe), 8),
RightFill(QString::number(phd->process.uncertainty_1), 8), STRING_END,
RightFill(QString::number(phd->process.Xe_collection_yield), 8),
RightFill(QString::number(phd->process.uncertainty_2), 8), STRING_END,
phd->process.archive_bottle_id, STRING_END);
}
// #Sample
if(phd->sampleBlock.dimension_1 > 0)
{
spectrum += "#Sample" + STRING_END;
spectrum += QString("%1 %2").arg(phd->sampleBlock.dimension_1).arg(phd->sampleBlock.dimension_2) + STRING_END;
}
// Certificate
if(!phd->certificate.g_energy.isEmpty())
{
spectrum += "#Certificate" + STRING_END;
spectrum += phd->certificate.total_source_activity + phd->certificate.assay_date
+ phd->certificate.assay_time + phd->certificate.units_activity + STRING_END;
int fieldWidth = 12;
for(int i=0; i<phd->certificate.g_energy.size(); ++i)
{
spectrum += QString("%1 %2 %3 %4 %5 %6 %7 %8 %9")
.arg(phd->certificate.nuclide_name[i], fieldWidth)
.arg(phd->certificate.half_life_time[i], fieldWidth)
.arg(phd->certificate.time_unit[i], fieldWidth)
.arg(phd->certificate.activity_nuclide_time_assay[i], fieldWidth)
.arg(phd->certificate.uncertainty[i], fieldWidth)
.arg(phd->certificate.g_energy[i], fieldWidth)
.arg(phd->certificate.g_intensity[i], fieldWidth)
.arg(phd->certificate.electron_decay_mode[i], fieldWidth)
.arg(phd->certificate.maximum_energy[i], fieldWidth)
.arg(phd->certificate.intensity_b_particle[i], fieldWidth) + STRING_END;
}
}
// #Calibration
if(!phd->calibration.date_calibration.isEmpty())
{
spectrum += "#Calibration" + STRING_END;
spectrum += QString("%1 %2%3").arg(phd->calibration.date_calibration).arg(phd->calibration.time_calibration).arg(STRING_END);
}
// #g_Energy
spectrum += "#g_Energy" + STRING_END;
const G_EnergyBlock &g_ener = phd->usedEnerKD;
for(int i=0; i<g_ener.g_energy.length(); ++i)
{
spectrum += QString("%1 %2 %3")
.arg(RightFill(QString::number(g_ener.g_energy[i], 'f', 9), 16))
.arg(RightFill(QString::number(g_ener.centroid_channel[i], 'f', 9), 16))
.arg(RightFill(QString::number(qIsNaN(g_ener.uncertainty[i]) ? 0.5 : g_ener.uncertainty[i], 'f', 9), 16)).append(STRING_END);
}
// #g_Resolution
spectrum += "#g_Resolution" + STRING_END;
const G_ResolutionBlock &g_reso = phd->usedResoKD;
for(int i=0; i<g_reso.FWHM.length(); ++i)
{
spectrum += QString("%1 %2 %3")
.arg(RightFill(QString::number(g_reso.g_energy[i], 'f', 9), 16))
.arg(RightFill(QString::number(g_reso.FWHM[i], 'f', 9), 16))
.arg(RightFill(QString::number(qIsNaN(g_reso.uncertainty[i]) ? 0.5 : g_reso.uncertainty[i], 'f', 9), 16)).append(STRING_END);
}
// #g_Efficiency
spectrum += "#g_Efficiency" + STRING_END;
const G_EfficiencyBlock &g_effi = phd->usedEffiKD;
for(int i=0; i<g_effi.efficiency.length(); ++i)
{
spectrum += QString("%1 %2 %3")
.arg(RightFill(QString::number(g_effi.g_energy[i], 'f', 9), 16))
.arg(RightFill(QString::number(g_effi.efficiency[i], 'f', 9), 16))
.arg(RightFill(QString::number(qIsNaN(g_effi.uncertainty[i]) ? 0.5 : g_effi.uncertainty[i], 'f', 9), 16)).append(STRING_END);
}
// #TotalEff
if(phd->usedTotEKD.g_energy.size() > 0)
{
spectrum += "#TotalEff" + STRING_END;
const TotaleffBlock &g_totE = phd->usedTotEKD;
for(int i=0; i<g_totE.record_count; ++i)
{
spectrum += QString("%1 %2 %3")
.arg(RightFill(QString::number(g_totE.g_energy[i], 'f', 9), 16))
.arg(RightFill(QString::number(g_totE.total_efficiency[i], 'f', 9), 16))
.arg(RightFill(QString::number(qIsNaN(g_totE.uncertainty[i]) ? 0.5 : g_totE.uncertainty[i], 'f', 9), 16));
}
}
// #g_Spectrum
spectrum += "#g_Spectrum" + STRING_END;
spectrum += QString("%1 %2").arg(RightFill(QString::number(phd->Spec.num_g_channel), 5),
RightFill(QString::number(phd->Spec.g_energy_span), 4)) + STRING_END;
int i=0, j=phd->Spec.begin_channel, len = phd->Spec.counts.length();
for(; i<len-4; i+=5,j+=5)
{
spectrum += QString("%1 %2 %3 %4 %5 %6").arg(RightFill(QString::number(j), 5))
.arg(RightFill(QString::number(phd->Spec.counts[i]), 10))
.arg(RightFill(QString::number(phd->Spec.counts[i+1]), 10))
.arg(RightFill(QString::number(phd->Spec.counts[i+2]), 10))
.arg(RightFill(QString::number(phd->Spec.counts[i+3]), 10))
.arg(RightFill(QString::number(phd->Spec.counts[i+4]), 10)).append(STRING_END);
}
if(i < len)
{
spectrum += QString("%1 %2").arg(RightFill(QString::number(j), 5))
.arg(RightFill(QString::number(phd->Spec.counts[i]), 10));
for(i = i+1; i < phd->Spec.num_g_channel; ++i)
{
spectrum += QString(" %1").arg(RightFill(QString::number(phd->Spec.counts[i]), 10));
}
spectrum += STRING_END;
}
spectrum += "STOP" + STRING_END;
return spectrum;
}
int DataStore::SettingChanged(PHDFile *phd)
{
SpecSetup &newSets = phd->setting;
SpecSetup &oldSets = phd->usedSetting;
if(newSets.ECutAnalysis_Low != oldSets.ECutAnalysis_Low
|| newSets.ECutAnalysis_High != oldSets.ECutAnalysis_High
|| newSets.EnergyTolerance != oldSets.EnergyTolerance
|| newSets.PSS_low != oldSets.PSS_low
|| newSets.BaseImprovePSS != oldSets.BaseImprovePSS
|| newSets.k_back != oldSets.k_back
|| newSets.k_alpha != oldSets.k_alpha
|| newSets.k_beta != oldSets.k_beta
|| newSets.RiskLevelK != oldSets.RiskLevelK
|| newSets.refTime_act != oldSets.refTime_act
|| newSets.refTime_conc != oldSets.refTime_conc)
{
return 1;
}
stdvec &old_ener = phd->usedEnerPara.p;
stdvec &new_ener = phd->mapEnerPara[phd->newEner].p;
if(old_ener.size() != new_ener.size()) return 1;
for(int i=0; i<old_ener.size(); ++i)
{
if(abs(old_ener[i] - new_ener[i]) > 1E-6) return 1;
}
stdvec &old_reso = phd->usedResoPara.p;
stdvec &new_reso = phd->mapResoPara[phd->newReso].p;
if(old_reso.size() != new_reso.size()) return 1;
for(int i=0; i<old_reso.size(); ++i)
{
if(abs(old_reso[i] - new_reso[i]) > 1E-6) return 1;
}
stdvec &old_effi = phd->usedEffiPara.p;
stdvec &new_effi = phd->mapEffiPara[phd->newEffi].p;
if(old_effi.size() != new_effi.size()) return -1;
for(int i=0; i<old_effi.size(); ++i)
{
if(abs(old_effi[i] - new_effi[i]) > 1E-6) return -1;
}
return 0;
}
QVector<QString> DataStore::DetailedInfo()
{
// Sample_Id, Station_Code, Detector_Code, System_Type, Data_Type, Spectral_Qualifier,
// SRID, Sample_Status, Collect_Start, Sampling_Time, Quantity, Flow_Rate,
// Acq_Start, Acq_Real, Acq_Live, Decay_Time, Auto_Cat, Category
QVector<QString> detailInfo(18, "");
detailInfo[0] = m_phd->id_sample; // Sample_Id
detailInfo[1] = m_phd->header.site_code; // Station_Code
detailInfo[2] = m_phd->header.detector_code; // Detector_Code
detailInfo[3] = m_phd->header.system_type; // System_Type
detailInfo[4] = m_phd->msgInfo.data_type; // Data_Type
detailInfo[5] = m_phd->header.spectrum_quantity; // Spectral_Qualifier
detailInfo[6] = m_phd->header.sample_ref_id; // SRID
detailInfo[7] = m_phd->status; // Sample_Status
QDateTime collect_stop_dt = QDateTime::fromString(m_phd->collect.collection_stop_date + " " + m_phd->collect.collection_stop_time, QString(DATATIME_FORMAT));
detailInfo[8] = m_phd->collect.collection_start_date + " " + m_phd->collect.collection_start_time;
double timeSpan = QDateTime::fromString(detailInfo[8], QString(DATATIME_FORMAT)).secsTo(collect_stop_dt) / 3600.0;
detailInfo[9] = QString::number(timeSpan, 'f', 2); // Sampling_Time
detailInfo[10] = QString("%1").arg(m_phd->collect.air_volume, 0, 'f', 2);
if(timeSpan != 0) detailInfo[11] = QString("%1").arg(m_phd->collect.air_volume / timeSpan, 0, 'f', 2);
detailInfo[12] = m_phd->acq.acquisition_start_date + " " + m_phd->acq.acquisition_start_time;
detailInfo[13] = QString("%1").arg(m_phd->acq.acquisition_real_time, 0, 'f', 2);
detailInfo[14] = QString("%1").arg(m_phd->acq.acquisition_live_time, 0, 'f', 2);
qint64 timespan = collect_stop_dt.secsTo(QDateTime::fromString(detailInfo[12], QString(DATATIME_FORMAT)));
detailInfo[15] = QString::number(timespan / 3600.0, 'f', 2);
detailInfo[17] = m_phd->category;
return detailInfo;
}
QMap<QString, NuclideLines> DataStore::GetNuclideLines(const QStringList nuclideList)
{
QMap<QString, NuclideLines> mapLines;
if(nuclideList.size() < 1) return mapLines;
QString table_lines = m_bFromDB ? T_NUL_LINE_REMOTE : T_NUL_LINE_LOCAL;
QString table_lib = m_bFromDB ? T_NUL_LIB_REMOTE : T_NUL_LIB_LOCAL;
foreach (QString name, nuclideList)
{
NuclideLines nlines;
QString sql = QString("select fullname, energy, energy_uncert, yield, yield_uncert, key_flag from %1 where name = '%2' Order by energy").arg(table_lines).arg(name);
if(m_query.exec(sql))
{
int j=0;
while(m_query.next())
{
nlines.fullNames.push_back(m_query.value(0).toString());
nlines.vEnergy.push_back(m_query.value(1).toDouble());
nlines.vUncertE.push_back(m_query.value(2).toDouble());
nlines.vYield.push_back(m_query.value(3).toDouble() / 100);
nlines.vUncertY.push_back(m_query.value(4).toDouble());
if(m_query.value(5).toInt() > 0)
{
nlines.key_flag = j;
nlines.maxYeildIdx = j;
}
++j;
}
}
mapLines[name] = nlines;
}
QString names = nuclideList.join("','");
names.insert(0, "'");
names.insert(names.length(), "'");
QString sql = QString("select name, halflife from %1 where name in (%2)").arg(table_lib).arg(names);
if(m_query.exec(sql))
{
while (m_query.next())
{
mapLines[m_query.value(0).toString()].halflife = m_query.value(1).toDouble() * 86400; // 将天转换成秒
}
}
return mapLines;
}
QMap<QString, NuclideLines> DataStore::GetNuclideLines()
{
QMap<QString, NuclideLines> t_map;
if(m_phd)
{
t_map = (m_phd->header.system_type == "P" ? m_mapNucLineP : m_mapNucLineG);
}
return t_map;
}
QString Str_DateTime(QString date, QString time)
{
if(date.size() != 10 || time.size() < 8) return QString();
else return date + " " + time.left(8);
}
QString DataStore::BaseCtrlToString(const BaseControls &baseCtrl)
{
QString strRet = "";
strRet += "#AnalyseRange" + LINE_END;
strRet += QString("%1 %2").arg(baseCtrl.rg_low).arg(baseCtrl.rg_high) + LINE_END;
int numPerLine = 5;
size_t i, nCP = baseCtrl.XCtrl.size(), nGroupCP = nCP / numPerLine * numPerLine;
strRet += "#XCtrl" + LINE_END;
const stdvec &cx = baseCtrl.XCtrl;
for(i=0; i<nGroupCP; i+=numPerLine)
{
strRet += QString("%1%2%3%4%5").arg(double_to_six_precision(cx[i]))
.arg(double_to_six_precision(cx[i+1])).arg(double_to_six_precision(cx[i+2]))
.arg(double_to_six_precision(cx[i+3])).arg(double_to_six_precision(cx[i+4])) + LINE_END;
}
if(i < nCP)
{
for(; i<nCP; ++i) strRet += QString("%1").arg(double_to_six_precision(cx[i]));
strRet += LINE_END;
}
strRet += "#YCtrl" + LINE_END;
const stdvec &cy = baseCtrl.YCtrl;
for(i=0; i<nGroupCP; i+=numPerLine)
{
strRet += QString("%1%2%3%4%5").arg(double_to_six_precision(cy[i]))
.arg(double_to_six_precision(cy[i+1])).arg(double_to_six_precision(cy[i+2]))
.arg(double_to_six_precision(cy[i+3])).arg(double_to_six_precision(cy[i+4])) + LINE_END;
}
if(i < nCP)
{
for(; i<nCP; ++i) strRet += QString("%1").arg(double_to_six_precision(cy[i]));
strRet += LINE_END;
}
strRet += "#YSlope" + LINE_END;
const stdvec &cdy = baseCtrl.YSlope;
for(i=0; i<nGroupCP; i+=numPerLine)
{
strRet += QString("%1%2%3%4%5").arg(double_to_six_precision(cdy[i]))
.arg(double_to_six_precision(cdy[i+1])).arg(double_to_six_precision(cdy[i+2]))
.arg(double_to_six_precision(cdy[i+3])).arg(double_to_six_precision(cdy[i+4])) + LINE_END;
}
if(i < nCP)
{
for(; i<nCP; ++i) strRet += QString("%1").arg(double_to_six_precision(cdy[i]));
strRet += LINE_END;
}
size_t nBL = baseCtrl.Baseline.size(), nGroupBL = nBL / numPerLine * numPerLine;
strRet += "#Baseline" + LINE_END;
strRet += QString::number(nBL) + LINE_END;
const stdvec &bl = baseCtrl.Baseline;
for(i=0; i<nGroupBL; i+=numPerLine)
{
strRet += QString("%1%2%3%4%5").arg(double_to_six_precision(bl[i]))
.arg(double_to_six_precision(bl[i+1])).arg(double_to_six_precision(bl[i+2]))
.arg(double_to_six_precision(bl[i+3])).arg(double_to_six_precision(bl[i+4])) + LINE_END;
}
if(i < nBL)
{
for(; i<nBL; ++i) strRet += QString("%1").arg(double_to_six_precision(bl[i]));
strRet += LINE_END;
}
strRet += "#StepCounts" + LINE_END;
strRet += QString::number(nBL) + LINE_END;
const stdvec &sc = baseCtrl.StepCounts;
for(i=0; i<nGroupBL; i+=numPerLine)
{
strRet += QString("%1%2%3%4%5").arg(double_to_six_precision(sc[i]))
.arg(double_to_six_precision(sc[i+1])).arg(double_to_six_precision(sc[i+2]))
.arg(double_to_six_precision(sc[i+3])).arg(double_to_six_precision(sc[i+4])) + LINE_END;
}
if(i < nBL)
{
for(; i<nBL; ++i) strRet += QString("%1").arg(double_to_six_precision(sc[i]));
strRet += LINE_END;
}
strRet += LINE_END;
return strRet;
}