#include "stdafx.h" #include "TrioCal.h" #include "OTSFileSys.h" #include "OTSHelper.h" #include "PropParam.h" #include "SmplMsrResultFileMgr.h" #include //计算三元相图 namespace OTSMODEL { TrioCal::TrioCal(CReportProjFileMgr * rptMgrPtr) { m_rptMgrPtr = rptMgrPtr; } TrioCal::~TrioCal() { } // 主要功能为解决多数据源问题 CGridDatasList TrioCal::CompParticleTrioInfo() { // use the dll resource AFX_MANAGE_STATE(AfxGetStaticModuleState()); //定义返回的Grid数据结构 CGridDatasList listGridData; listGridData.clear(); // depart compound source name std::vector listWorkIndex; std::vector listPos; //std::vector listDataSourceOut = m_rptMgrPtr->GetFullDataSource(a_pGridIn, listWorkIndex, listPos); int dataSourceId;//用户在propertygrid(sourcegrid)界面上选择的样品下拉列表ID号,如果是有需要对比的复合样品源,会在第0项出现。 CPropParamPtr prop = m_rptMgrPtr->GetCurrentPropParam(); dataSourceId = prop->GetDataSourceId(); std::vector listDataSource = m_rptMgrPtr->GetCurrentPropParam()->GetDataSourceList(); int nSelectedDataSourceIndex = prop->GetDataSourceId(); CString sDataSourceNames = listDataSource[nSelectedDataSourceIndex]; std::vector listSelectedDataSource = COTSHelper::SplitString(sDataSourceNames, _T("+")); int nIndex = 0; for (auto strDataSourceName : listSelectedDataSource) { CGridDataPtr pGridData = CGridDataPtr(new CGridData()); // data source id std::vector listDataSource; listDataSource.clear(); listDataSource = prop->GetDataSourceList(); pGridData->SetDataSourceList(listDataSource); int nDataSourceId = prop->GetDataSourceId(); pGridData->SetDataSourceId(nDataSourceId); COTSParticleList listParticleAll = m_rptMgrPtr->GetAnalysisParticleList(strDataSourceName);//找到这个样品中所有的有效颗粒 CPosXraysList listXray= m_rptMgrPtr->GetAnalysisXrayList(strDataSourceName);//找到所有颗粒对应的Xray map particleInfoMap; for (auto p : listParticleAll) { //using fieldid combined analysisid to vector key int xrayId = p->GetAnalysisId(); int fieldId = p->GetFieldId(); if (xrayId < 0 || fieldId < 0) { continue; } CString fieldidwithxrayid = ""; fieldidwithxrayid.Format(_T("%d%d"), fieldId, xrayId); int i_fieldidwithxrayid = atoi(fieldidwithxrayid); auto itr = std::find_if(listXray.begin(), listXray.end(), [xrayId, fieldId](CPosXrayPtr x) { return (x->GetIndex() == xrayId && x->GetScanFieldId() == fieldId); }); if (itr != listXray.end()) { CPosXrayPtr posXray = *itr;//迭代器是指针,所以要解引用 particleInfoMap.insert(pair(i_fieldidwithxrayid, posXray)); } } //TrioTemplate trioTem; TrioTemplateMulti trioTemMulti; if (prop->GetCalChartType() == CALCULATE_CHART_TYPE::TRIO_CHART) { CTriTempItemList lsCTriTempItemList = m_rptMgrPtr->GetRptParamFilePtr()->GetTriTempFile()->GetTriTempItemList(); trioTemMulti.elementA = lsCTriTempItemList[prop->GetTrioChartType()]->GetTopName(); trioTemMulti.elementB = lsCTriTempItemList[prop->GetTrioChartType()]->GetLeftName(); trioTemMulti.elementC = lsCTriTempItemList[prop->GetTrioChartType()]->GetRightName(); for (int i = 0; i < lsCTriTempItemList[prop->GetTrioChartType()]->GetTriTempItemElementList().size(); i++) { if (lsCTriTempItemList[prop->GetTrioChartType()]->GetTriTempItemElementList()[i]->GetItemTypeName() == "Top") { trioTemMulti.velementA.push_back(lsCTriTempItemList[prop->GetTrioChartType()]->GetTriTempItemElementList()[i]->GetElementName()); trioTemMulti.vAnum.push_back(lsCTriTempItemList[prop->GetTrioChartType()]->GetTriTempItemElementList()[i]->GetElementNumber()); } if (lsCTriTempItemList[prop->GetTrioChartType()]->GetTriTempItemElementList()[i]->GetItemTypeName() == "Left") { trioTemMulti.velementB.push_back(lsCTriTempItemList[prop->GetTrioChartType()]->GetTriTempItemElementList()[i]->GetElementName()); trioTemMulti.vBnum.push_back(lsCTriTempItemList[prop->GetTrioChartType()]->GetTriTempItemElementList()[i]->GetElementNumber()); } if (lsCTriTempItemList[prop->GetTrioChartType()]->GetTriTempItemElementList()[i]->GetItemTypeName() == "Right") { trioTemMulti.velementC.push_back(lsCTriTempItemList[prop->GetTrioChartType()]->GetTriTempItemElementList()[i]->GetElementName()); trioTemMulti.vCnum.push_back(lsCTriTempItemList[prop->GetTrioChartType()]->GetTriTempItemElementList()[i]->GetElementNumber()); } } } //get pixel size CSmplMsrResultFileMgrPtr pSmplMsrResultFileMgr = m_rptMgrPtr->GetASmplMsrResultMgrByFileName(strDataSourceName); ASSERT(pSmplMsrResultFileMgr); if (!pSmplMsrResultFileMgr) { LogErrorTrace(__FILE__, __LINE__, _T("CompParticleTrioInfo: can't get sample result file manager.")); return listGridData; } CSmplMsrResultFilePtr pSmplMsrResultFile = pSmplMsrResultFileMgr->GetSmplMsrResultFile(); ASSERT(pSmplMsrResultFile); if (!pSmplMsrResultFile) { LogErrorTrace(__FILE__, __LINE__, _T("CompParticleTrioInfo: can't get sample result file.")); return listGridData; } COTSSamplePtr pSample = pSmplMsrResultFile->GetSample(); ASSERT(pSample); if (!pSample) { LogErrorTrace(__FILE__, __LINE__, _T("CompParticleTrioInfo: can't get sample.")); return listGridData; } double dPixelSize = pSample->CalculatePixelSize(); if (!GetTrioInfoFromParticleList(listParticleAll, dPixelSize, prop->GetSizeCalMethodType(), particleInfoMap, trioTemMulti,pGridData)) { LogErrorTrace(__FILE__, __LINE__, _T("CompParticleTrioInfo: can't get general information.")); return listGridData; } listGridData.push_back(pGridData); nIndex++; } return listGridData; } BOOL TrioCal::GetTrioInfoFromParticleList(COTSParticleList a_listParticle, double a_dPixelSize, SIZE_CAL_METHOD_TYPE a_nMethod, map particleInfoMap, TrioTemplateMulti t1, CGridDataPtr a_pGridData) { ASSERT(a_pGridData); if (!a_pGridData) { LogErrorTrace(__FILE__, __LINE__, _T("GetGenInfoFromParticleList: invalid grid data pointer.")); return FALSE; } //devide all the particles into groups,according to the particle type,use map to keep it,Id is the key,the particle list is the value. COTSParticleList listPartReport; map mapSameSTDItemPartList; map::iterator partListIter; //get the same type particle together for (auto pParticle : a_listParticle) { int nType = pParticle->GetType(); //only consider the type value bigger than NOT_IDENTIFIED if (nType >= (int)(int)OTS_PARTCLE_TYPE::NOT_IDENTIFIED_SIC) { partListIter = mapSameSTDItemPartList.find(nType); if (partListIter == mapSameSTDItemPartList.end()) { COTSParticleList listParticle; listParticle.push_back(pParticle); mapSameSTDItemPartList.insert(pair(nType, listParticle)); } else { partListIter->second.push_back(pParticle); } } } for (partListIter = mapSameSTDItemPartList.begin(); partListIter != mapSameSTDItemPartList.end(); partListIter++) { listPartReport.insert(listPartReport.end(), partListIter->second.begin(), partListIter->second.end()); } int nColumnNum = ((int)(REPORT_PARTICLE_TRIO_INFO_GRID_CLUMN::MAX) - (int)(REPORT_PARTICLE_TRIO_INFO_GRID_CLUMN::MIN) + 1); CGridColumnsList listGridColumn; for (int i = 0; i < nColumnNum; i++) { CGridColumnPtr pColumn = CGridColumnPtr(new CGridColumn()); CGridRowsList listGridRows; listGridRows.clear(); int nType = 0; int nPos = 0; switch (i) { case (int)REPORT_PARTICLE_TRIO_INFO_GRID_CLUMN::SIZE: pColumn->SetName("sizeLevel"); listGridRows.clear(); for (auto pParticle : listPartReport) { CGridRowPtr pGridRow = CGridRowPtr(new CGridRow()); pGridRow->SetDataType(REPORT_GRID_DATA_TYPE::STRING); double dSize = m_rptMgrPtr->GetValueAsMethod(pParticle, a_nMethod, a_dPixelSize); CPartSizeFilePtr pPartSize = m_rptMgrPtr->GetCurrentPropParam()->GetWorkingSizeFile (); CPartSizeItemList listPartSize = pPartSize->GetPartSizeList(); if (!listPartSize.empty()) { for (auto partsizeItem : listPartSize) { CDoubleRangePtr levelPtr = partsizeItem->GetSizeLevel(); double dStart = levelPtr->GetStart(); double theEnd = levelPtr->GetEnd(); double dEnd = theEnd; if (dSize >= dStart && dSize < dEnd) { CString str, str1; if ((dStart - (int)dStart) == 0) { //小数位为零 str.Format(_T("%.0f"), dStart); } else { str.Format(_T("%0.1lf"), dStart); } if (dEnd == 1000000) { str1 = "Max"; } else { if ((dEnd - (int)dEnd) == 0) { //小数位为零 str1.Format(_T("%.0f"), dEnd); } else { str1.Format(_T("%0.1lf"), dEnd); } } CString level = str + _T(" ~ ") + str1;//“0-5” 或 “5-10”等 pGridRow->SetStringValue(level); } } } listGridRows.push_back(pGridRow); } break; case (int)REPORT_PARTICLE_TRIO_INFO_GRID_CLUMN::Location: pColumn->SetName("particleLocation"); listGridRows.clear(); for (auto pParticle : listPartReport) { CGridRowPtr pGridRow = CGridRowPtr(new CGridRow()); pGridRow->SetDataType(REPORT_GRID_DATA_TYPE::STRING); //using field id combined xray id to vector key int xrayId = pParticle->GetAnalysisId(); int fieldId = pParticle->GetFieldId(); CString fieldidwithxrayid = ""; fieldidwithxrayid.Format(_T("%d%d"), fieldId, xrayId); int i_fieldidwithxrayid = atoi(fieldidwithxrayid); auto itr = particleInfoMap.find(i_fieldidwithxrayid); if (itr != particleInfoMap.end()) { CString loc; loc = GetTrioMoleRatio(*itr, t1); pGridRow->SetStringValue(loc); } else { CString loc; loc = _T("0,0,0"); pGridRow->SetStringValue(loc); } listGridRows.push_back(pGridRow); } break; } pColumn->SetGridRowsList(listGridRows); listGridColumn.push_back(pColumn); } a_pGridData->SetGridColumnList(listGridColumn); return TRUE; } CString TrioCal::GetTrioMoleRatio(pair p, TrioTemplateMulti t1) { CElementChemistriesList chemistriesList = p.second->GetElementQuantifyData(); CString strRet;//由三条边上的位置组成,如三角形的三个顶点分别为a b c,则strRet为:aTob,bToc,cToa double aPercent=0, bPercent=0, cPercent=0; double d_ASum = 0; double d_BSum = 0; double d_CSum = 0; auto aElements = t1.velementA; auto bElements = t1.velementB; auto cElements = t1.velementC; auto aNums = t1.vAnum; auto bNums = t1.vBnum; auto cNums = t1.vCnum; auto partElements = p.second->GetElementQuantifyData(); for (int i = 0; i < aElements.size(); i++) { for (int k = 0; k < partElements.size (); k++) { if (aElements[i].MakeUpper() == partElements[k]->GetName().MakeUpper()) { //找到有包含的元素了,并乘以该元素对应的比例 d_ASum = d_ASum + (partElements[k]->GetPercentage() / CElement::GetAtomWeight(partElements[k]->GetName())) * aNums[i]; } } } for (int i = 0; i < bElements.size(); i++) { for (int k = 0; k < partElements.size(); k++) { if (bElements[i] == partElements[k]->GetName()) { //找到有包含的元素了,并乘以该元素对应的比例 d_BSum = d_BSum + (partElements[k]->GetPercentage() / CElement::GetAtomWeight(partElements[k]->GetName())) * bNums[i]; } } } for (int i = 0; i < cElements.size(); i++) { for (int k = 0; k < partElements.size(); k++) { if (cElements[i] == partElements[k]->GetName()) { //找到有包含的元素了,并乘以该元素对应的比例 d_CSum = d_CSum + (partElements[k]->GetPercentage() / CElement::GetAtomWeight(partElements[k]->GetName())) * cNums[i]; } } } double allNums = d_ASum + d_BSum + d_CSum; if ((allNums) == 0) { return "0,0,0"; } else { if (d_ASum != 0) { aPercent = d_ASum / allNums; } if (d_BSum != 0) { bPercent = d_BSum / allNums; } if (d_CSum != 0) { cPercent = d_CSum / allNums; } CString ls_str; if (aPercent == 0 || aPercent == 1) { ls_str.Format(_T("%.0f"), aPercent); } else { ls_str.Format(_T("%.4f"), aPercent); } strRet = strRet + ls_str + ","; if (bPercent == 0 || bPercent == 1) { ls_str.Format(_T("%.0f"), bPercent); } else { ls_str.Format(_T("%.4f"), bPercent); } strRet = strRet + ls_str + ","; if (cPercent == 0 || cPercent == 1) { ls_str.Format(_T("%.0f"), cPercent); } else { ls_str.Format(_T("%.4f"), cPercent); } strRet = strRet + ls_str; return strRet; } //四元相图计算扩展 /*strRet = strRet + ls_str + ","; if (atod == 0 || atod == 1) { ls_str.Format(_T("%.0f"), atod); } else { ls_str.Format(_T("%.4f"), atod); } strRet = strRet + ls_str + ","; if (dtob == 0 || dtob == 1) { ls_str.Format(_T("%.0f"), dtob); } else { ls_str.Format(_T("%.4f"), dtob); } strRet = strRet + ls_str;*/ return strRet; } //传入,两个项顶点的元素List及对应的比例,再传入颗粒所有包含元素列表,通过综合运算,返回两个顶点中包含颗粒的元素的摩尔比之合,再弄成摩尔比 double TrioCal::GetMoleRatio(vector oneitem, vector voneitemNum, vector twoitem, vector vtwoitemNum, vector thirdItem, vector thirdItemNum, CElementChemistriesList particleitem) { double d_oneSum = 0; double d_twoSum = 0; for (int i = 0; i < oneitem.size(); i++) { for (int k = 0; k < particleitem.size(); k++) { if (oneitem[i] == particleitem[k]->GetName()) { //找到有包含的元素了,并乘以该元素对应的比例 //d_oneSum = d_oneSum + particleitem[k]->GetPercentage() * voneitemNum[i]; d_oneSum = d_oneSum + (particleitem[k]->GetPercentage()/ CElement::GetAtomWeight(particleitem[k]->GetName())) * voneitemNum[i]; } } } //CElement::GetAtomWeight(""); for (int i = 0; i < twoitem.size(); i++) { for (int k = 0; k < particleitem.size(); k++) { if (twoitem[i] == particleitem[k]->GetName()) { //找到有包含的元素了,并乘以该元素对应的比例 //d_twoSum = d_twoSum + particleitem[k]->GetPercentage() * vtwoitemNum[i]; d_twoSum = d_twoSum + (particleitem[k]->GetPercentage() / CElement::GetAtomWeight(particleitem[k]->GetName())) * vtwoitemNum[i]; } } } if ((d_oneSum + d_twoSum) == 0) //if(d_oneSum == 0 || d_twoSum == 0)//如果有任何对比为0情况就返回0?,那么顶点又无法返回了 { return 0; } else { return 1 - d_oneSum / (d_oneSum + d_twoSum); } } }