#pragma once #include "stdafx.h" #include "CGBCalculate.h" #include "OTSFieldData.h" #include "GBImgPropCal.h" #include "OTSHelper.h" #include "OTSImageProcess.h" #include "CGBLevel.h" #include namespace OTSGBCalculate { using namespace OTSDATA; using namespace OTSIMGPROC; CGBCalculate::CGBCalculate(CReportMgr* rptMgrPtr) { m_rptMgrPtr = rptMgrPtr; } CGBCalculate::~CGBCalculate() { } // class methods // public CGridDatasList CGBCalculate::GetGBInclusion(CALCULATE_TABLE_TYPE tableType) { CGBFieldList listCGBField; CGridDatasList listGridData; listGridData.clear(); CGridDatasList multGridList; multGridList.clear(); // depart compound source name CPropParamPtr currentProp = m_rptMgrPtr->GetPropertyParamForGrid(); std::vector listDataSource = currentProp->GetDataSourceList(); int nSelectedDataSourceIndex = currentProp->GetDataSourceId(); CString sDataSourceNames = listDataSource[nSelectedDataSourceIndex]; std::vector listSelectedDataSource = COTSHelper::SplitString(sDataSourceNames, _T("+")); for (auto strDataSourceName : listSelectedDataSource) { listCGBField.clear(); CGridDataPtr pGridData = CGridDataPtr(new CGridData()); // data source id std::vector listDataSource; listDataSource.clear(); listDataSource = currentProp->GetDataSourceList(); pGridData->SetDataSourceList(listDataSource); int nDataSourceId = currentProp->GetDataSourceId(); pGridData->SetDataSourceId(nDataSourceId); CSmplMsrResultFileMgrPtr rstFileMgrPrt = m_rptMgrPtr->GetASmplMsrResultMgrByFileName(strDataSourceName); CSmplMsrResultFilePtr pSmplMsrResultFile = rstFileMgrPrt->GetSmplMsrResultFile(); if (tableType == CALCULATE_TABLE_TYPE::DIN) { CGBFieldDataPtr DINFld(new CGBFieldData()); DINFld->CaculateLevelDIN(pSmplMsrResultFile->GetAllParticles()); listGridData = this->GetGridDataListForOneDataSourceDIN(DINFld);//express these result data by grid } else { GB_METHODE_TYPE t; switch(tableType) { case CALCULATE_TABLE_TYPE::GB_Method1: t = GB_METHODE_TYPE::METHODE_1; break; case CALCULATE_TABLE_TYPE::GB_Method2: t= GB_METHODE_TYPE::METHODE_2; break; case CALCULATE_TABLE_TYPE::ASTM: t = GB_METHODE_TYPE::ASTM; break; default: t = GB_METHODE_TYPE::METHODE_1; break; } CGBFieldList listRawGBFields = CalGBFields(rstFileMgrPrt,t); CategoryGBInclutions(listRawGBFields, tableType); listCGBField = listRawGBFields; CGBGradeData gradeData = CGBGradeData(listCGBField); listGridData = this->GetGridDataListForOneDataSource(&gradeData, tableType);//express these result data by grid } multGridList.insert (multGridList.end (), listGridData.begin(), listGridData.end()); } return multGridList; } void CGBCalculate::CategoryGBInclutions(CGBFieldList listCGBField, CALCULATE_TABLE_TYPE ty) { for (CGBFieldDataPtr GBFld : listCGBField) { switch (ty) { case CALCULATE_TABLE_TYPE::GB_Method1: GBFld->CategoryByMethod1(); break; case CALCULATE_TABLE_TYPE::GB_Method2: GBFld->CategoryByMethod2(); break; case CALCULATE_TABLE_TYPE::ASTM: GBFld->CategoryByASTM(); break; default: break; } } } CGBFieldList CGBCalculate::GetTopGradeGBFieldsByIncCategory(CGBFieldList listGBFields, GBIncCategory incCategory) { CGBFieldList fields; CGBGradeData gradeData = CGBGradeData(listGBFields); GBGradeCell* categoryRow; switch (incCategory) { case GBIncCategory::AT: categoryRow = gradeData.ALevel; break; case GBIncCategory::AW: categoryRow = gradeData.ALevel_w; break; case GBIncCategory::AS: categoryRow = gradeData.ALevel_s; break; case GBIncCategory::BT: categoryRow = gradeData.BLevel; break; case GBIncCategory::BW: categoryRow = gradeData.BLevel_w; break; case GBIncCategory::BS: categoryRow = gradeData.BLevel_s; break; case GBIncCategory::CT: categoryRow = gradeData.CLevel; break; case GBIncCategory::CW: categoryRow = gradeData.CLevel_w; break; case GBIncCategory::CS: categoryRow = gradeData.CLevel_s; break; case GBIncCategory::DT: categoryRow = gradeData.DLevel; break; case GBIncCategory::DW: categoryRow = gradeData.DLevel_w; break; case GBIncCategory::DS: categoryRow = gradeData.DLevel_s; break; case GBIncCategory::DSulfideT: categoryRow = gradeData.DSulfideLevel; break; case GBIncCategory::DSulfideW: categoryRow = gradeData.DSulfideLevel_w; break; case GBIncCategory::DSulfideS: categoryRow = gradeData.DSulfideLevel_s; break; default: categoryRow = gradeData.DSulfideLevel_s; break; } for (int i = 10; i > 0; i--)//by invert searching ,the first none zero cell is the toppest grade of this category. { if (categoryRow[i].nFldNum > 0) { fields = categoryRow[i].GBFlds; break; } } return fields; } CGBFieldList CGBCalculate::GetAllGBFields(CALCULATE_TABLE_TYPE tableType) { CPropParamPtr currentProp = m_rptMgrPtr->GetPropertyParamForGrid(); std::vector listDataSource = currentProp->GetDataSourceList(); int nSelectedDataSourceIndex = currentProp->GetDataSourceId(); CString sDataSourceNames = listDataSource[nSelectedDataSourceIndex]; std::vector listSelectedDataSource = COTSHelper::SplitString(sDataSourceNames, _T("+")); CGBFieldList fields; if (listSelectedDataSource.size() > 1) return fields; CSmplMsrResultFileMgrPtr rstFileMgrPrt = m_rptMgrPtr->GetASmplMsrResultMgrByFileName(listSelectedDataSource[0]); GB_METHODE_TYPE t; switch (tableType) { case CALCULATE_TABLE_TYPE::GB_Method1: t = GB_METHODE_TYPE::METHODE_1; break; case CALCULATE_TABLE_TYPE::GB_Method2: t = GB_METHODE_TYPE::METHODE_2; break; case CALCULATE_TABLE_TYPE::ASTM: t = GB_METHODE_TYPE::ASTM; break; default: t = GB_METHODE_TYPE::METHODE_1; break; } CGBFieldList listGBFields = CalGBFields(rstFileMgrPrt,t); CategoryGBInclutions(listGBFields, tableType); return listGBFields; } CGridDatasList CGBCalculate::GetGridDataListForOneDataSource(CGBGradeData* gradeData, CALCULATE_TABLE_TYPE tableType) { CGridDatasList listGridData; CGridDataPtr AGrid; CGridDataPtr BGrid; CGridDataPtr CGrid; CGridDataPtr DGrid; CGridDataPtr DSulfideGrid; CGridDataPtr DSGrid; CGridDataPtr GBFieldGrid; switch (tableType) { case CALCULATE_TABLE_TYPE::GB_Method1: AGrid = GetGridLevel("A", gradeData->ALevel, gradeData->ALevel_w, gradeData->ALevel_s); BGrid = GetGridLevel("B", gradeData->BLevel, gradeData->BLevel_w, gradeData->BLevel_s); CGrid = GetGridLevel("C", gradeData->CLevel, gradeData->CLevel_w, gradeData->CLevel_s); DGrid = GetGridLevel("D", gradeData->DLevel, gradeData->DLevel_w, gradeData->DLevel_s); DSGrid = GetGridDSLevel(gradeData); listGridData.push_back(AGrid); listGridData.push_back(BGrid); listGridData.push_back(CGrid); listGridData.push_back(DGrid); listGridData.push_back(DSGrid); return listGridData; break; case CALCULATE_TABLE_TYPE::GB_Method2: AGrid = GetGridLevel("A", gradeData->ALevel, gradeData->ALevel_w, gradeData->ALevel_s); BGrid = GetGridLevel("B", gradeData->BLevel, gradeData->BLevel_w, gradeData->BLevel_s); CGrid = GetGridLevel("C", gradeData->CLevel, gradeData->CLevel_w, gradeData->CLevel_s); DGrid = GetGridLevel("D", gradeData->DLevel, gradeData->DLevel_w, gradeData->DLevel_s); DSulfideGrid = GetGridLevel("DSulfide", gradeData->DSulfideLevel, gradeData->DSulfideLevel_w, gradeData->DSulfideLevel_s); DSGrid = GetGridDSLevel(gradeData); listGridData.push_back(AGrid); listGridData.push_back(BGrid); listGridData.push_back(CGrid); listGridData.push_back(DGrid); listGridData.push_back(DSulfideGrid); listGridData.push_back(DSGrid); return listGridData; break; case CALCULATE_TABLE_TYPE::ASTM: AGrid = GetGridLevel("A", gradeData->ALevel, gradeData->ALevel_w, gradeData->ALevel_s); BGrid = GetGridLevel("B", gradeData->BLevel, gradeData->BLevel_w, gradeData->BLevel_s); CGrid = GetGridLevel("C", gradeData->CLevel, gradeData->CLevel_w, gradeData->CLevel_s); DGrid = GetGridLevel("D", gradeData->DLevel, gradeData->DLevel_w, gradeData->DLevel_s); DSGrid = GetGridDSLevel(gradeData); listGridData.push_back(AGrid); listGridData.push_back(BGrid); listGridData.push_back(CGrid); listGridData.push_back(DGrid); listGridData.push_back(DSGrid); return listGridData; break; default: return listGridData; break; } } CGridDatasList CGBCalculate::GetGridDataListForOneDataSourceDIN(CGBFieldDataPtr DINFld) { CGridDatasList listGridData; COTSParticleList cotsparticlelistA; set cotsparticlelistB; COTSParticleList cotsparticlelistC; COTSParticleList cotsparticlelistD; cotsparticlelistA = DINFld->listAThinParticles; cotsparticlelistB = DINFld->listBThinParticles; cotsparticlelistC = DINFld->listCThinParticles; cotsparticlelistD = DINFld->listDThinParticles; CGridDataPtr AGrid; AGrid = GetGridDIN(cotsparticlelistA, cotsparticlelistB, cotsparticlelistC, cotsparticlelistD); listGridData.push_back(AGrid); return listGridData; } //get grid with level ABCD CGridDataPtr CGBCalculate::GetGridLevel(CString GridType, GBGradeCell a_nLevel[], GBGradeCell a_nLevel_w[], GBGradeCell a_nLevel_s[]) { CGridDataPtr pGridData = CGridDataPtr(new CGridData()); std::vector listDataSource; listDataSource.clear(); listDataSource = m_rptMgrPtr->GetPropertyParamForGrid()->GetDataSourceList(); pGridData->SetDataSourceList(listDataSource); int nDataSourceId = m_rptMgrPtr->GetPropertyParamForGrid()->GetDataSourceId(); pGridData->SetDataSourceId(nDataSourceId); //amounts CGridColumnsList listCol; listCol.clear(); int columnNum = 11 + 1 + 1;//表格总列数 12个级别再加上前面的“分类”列和“宽度/um”列 CGridColumnPtr pColumn; for (int i=0;i< columnNum;i++) { CString strName; CGridRowsList listRows; CGridRowPtr pRow; CString strWidthName1, strWidthName2, strWidthName3; switch( i) { case 0: pColumn = CGridColumnPtr(new CGridColumn()); //strName = MultiLang::GetInstance ().GetCStringByKey (GBStr1); strName = "Class"; pColumn->SetName(strName); pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::STRING); pRow->SetStringValue("Thin"); //MultiLang::GetInstance().GetCStringByKey(GBStr2) listRows.push_back(pRow); pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::STRING); pRow->SetStringValue("Thick"); //MultiLang::GetInstance().GetCStringByKey(GBStr3) listRows.push_back(pRow); pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::STRING); pRow->SetStringValue("OverSize"); //MultiLang::GetInstance().GetCStringByKey(GBStr4) listRows.push_back(pRow); pColumn->SetGridRowsList(listRows); listCol.push_back(pColumn); break; case 1: pColumn = CGridColumnPtr(new CGridColumn()); strName = "Width/um"; //MultiLang::GetInstance().GetCStringByKey(GBStr5); pColumn->SetName(strName); if (GridType == "A") { strWidthName1 = "2.0~4.0"; strWidthName2 = "4.0~12.0"; strWidthName3 = ">12.0"; } if (GridType == "B") { strWidthName1 = "2.0~9.0"; strWidthName2 = "9.0~15.0"; strWidthName3 = ">15.0"; } if (GridType == "C") { strWidthName1 = "2.0~5.0"; strWidthName2 = "5.0~12.0"; strWidthName3 = ">12.0"; } if (GridType == "D") { strWidthName1 = "2.0~8.0"; strWidthName2 = "8.0~13.0"; strWidthName3 = ">13.0"; } if (GridType == "DSulfide") { strWidthName1 = "2.0~8.0"; strWidthName2 = "8.0~13.0"; strWidthName3 = ">13.0"; } pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::STRING); pRow->SetStringValue(strWidthName1); listRows.push_back(pRow); pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::STRING); pRow->SetStringValue(strWidthName2); listRows.push_back(pRow); pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::STRING); pRow->SetStringValue(strWidthName3); listRows.push_back(pRow); pColumn->SetGridRowsList(listRows); listCol.push_back(pColumn); break; default: pColumn = CGridColumnPtr(new CGridColumn()); CString name; name.Format(_T("%.1f"), (i - 2) / 2.0);//i=2 输出0 i=3 输出0.5 i=4 输出1 以此类推 pColumn->SetName(name); CGridRowsList listRows; pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::INT); pRow->SetIntValue(a_nLevel[i - 2].nFldNum); listRows.push_back(pRow); pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::INT); pRow->SetIntValue(a_nLevel_w[i - 2].nFldNum); listRows.push_back(pRow); pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::INT); pRow->SetIntValue(a_nLevel_s[i - 2].nFldNum); listRows.push_back(pRow); pColumn->SetGridRowsList(listRows); listCol.push_back(pColumn); break; } } pGridData->SetGridColumnList(listCol); return pGridData; } CGridDataPtr CGBCalculate::GetGridDSLevel(CGBGradeData* gradeData) { CGridDataPtr pGridData = CGridDataPtr(new CGridData()); std::vector listDataSource; listDataSource.clear(); listDataSource = m_rptMgrPtr->GetPropertyParamForGrid()->GetDataSourceList(); pGridData->SetDataSourceList(listDataSource); int nDataSourceId = m_rptMgrPtr->GetPropertyParamForGrid()->GetDataSourceId(); pGridData->SetDataSourceId(nDataSourceId); //amounts CGridColumnsList listCol; listCol.clear(); int columnNum = 6; CGridColumnPtr pColumn; for (int i = 0; i < columnNum; i++) { CString strName; CGridRowsList listRows[6]; CGridRowPtr pRow; CString strWidthName1, strWidthName2, strWidthName3; switch (i) { case 0: pColumn = CGridColumnPtr(new CGridColumn()); strName = "No."; pColumn->SetName(strName); pColumn->SetGridRowsList(listRows[0]); listCol.push_back(pColumn); break; case 1: pColumn = CGridColumnPtr(new CGridColumn()); strName = "Area/um2"; pColumn->SetName(strName); pColumn->SetGridRowsList(listRows[1]); listCol.push_back(pColumn); break; case 2: pColumn = CGridColumnPtr(new CGridColumn()); strName = "MaxFeret/um"; pColumn->SetName(strName); pColumn->SetGridRowsList(listRows[2]); listCol.push_back(pColumn); break; case 3: pColumn = CGridColumnPtr(new CGridColumn()); strName = "X/um"; pColumn->SetName(strName); pColumn->SetGridRowsList(listRows[3]); listCol.push_back(pColumn); break; case 4: pColumn = CGridColumnPtr(new CGridColumn()); strName = "Y/um"; pColumn->SetName(strName); pColumn->SetGridRowsList(listRows[4]); listCol.push_back(pColumn); break; case 5: pColumn = CGridColumnPtr(new CGridColumn()); strName = "Grade"; pColumn->SetName(strName); pColumn->SetGridRowsList(listRows[5]); listCol.push_back(pColumn); break; } } for (auto part : gradeData->allDSParts) { DisplayDSPartRow(part, listCol); } pGridData->SetGridColumnList(listCol); return pGridData; } //get grid with level ABCD CGridDataPtr CGBCalculate::GetGridDIN(COTSParticleList cotsparticlelistA, set cotsparticlelistB, COTSParticleList cotsparticlelistC, COTSParticleList cotsparticlelistD) { CGridDataPtr pGridData = CGridDataPtr(new CGridData()); std::vector listDataSource; listDataSource.clear(); listDataSource = m_rptMgrPtr->GetPropertyParamForGrid()->GetDataSourceList(); pGridData->SetDataSourceList(listDataSource); int nDataSourceId = m_rptMgrPtr->GetPropertyParamForGrid()->GetDataSourceId(); pGridData->SetDataSourceId(nDataSourceId); //amounts CGridColumnsList listCol; listCol.clear(); int columnNum = 12;//表格总列数 11个级别再加上前面的“分类”列 CGridColumnPtr pColumn; int levA[9] = { 0,0,0,0,0,0,0,0,0 }; int levB[9] = { 0,0,0,0,0,0,0,0,0 }; int levC[9] = { 0,0,0,0,0,0,0,0,0 }; int levD[9] = { 0,0,0,0,0,0,0,0,0 }; double fg[9] = { 0.05,0.1,0.2,0.5,1,2,5,10,20 }; //指数 double ka = 0, kb = 0, kc = 0, kd = 0; //统计不同大小颗粒出现次数 for (auto pParticle : cotsparticlelistA) { double area = pParticle->GetActualArea(); for (int i = 0; i < 8; i++) { if (area >= fg[i] && area < fg[i + 1]) { levA[i] += 1; ka = ka + fg[i]; } } if (area >= fg[8]) { levA[8] += 1; ka = ka + fg[8]; } } for (auto pParticle : cotsparticlelistB) { double area = pParticle->GetActualArea(); for (int i = 0; i < 8; i++) { if (area >= fg[i] && area < fg[i + 1]) { levB[i] += 1; kb = kb + fg[i]; } } if (area >= fg[8]) { levB[8] += 1; kb = kb + fg[8]; } } for (auto pParticle : cotsparticlelistC) { double area = pParticle->GetActualArea(); for (int i = 0; i < 8; i++) { if (area >= fg[i] && area < fg[i + 1]) { levC[i] += 1; kc = kc + fg[i]; } } if (area >= fg[8]) { levC[8] += 1; kc = kc + fg[8]; } } for (auto pParticle : cotsparticlelistD) { double area = pParticle->GetActualArea(); for (int i = 0; i < 8; i++) { if (area >= fg[i] && area < fg[i + 1]) { levD[i] += 1; kd = kd + fg[i]; } } if (area >= fg[8]) { levD[8] += 1; kd = kd + fg[8]; } } double to = kb + kc + kd; for (int i = 0; i < columnNum; i++) { CString strName; CGridRowsList listRows; CGridRowPtr pRow; CString strWidthName1, strWidthName2, strWidthName3, strWidthName4; switch (i) { case 0: pColumn = CGridColumnPtr(new CGridColumn()); strName = "Class"; pColumn->SetName(strName); pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::STRING); pRow->SetStringValue("SS"); listRows.push_back(pRow); pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::STRING); pRow->SetStringValue("OA"); listRows.push_back(pRow); pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::STRING); pRow->SetStringValue("OS"); listRows.push_back(pRow); pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::STRING); pRow->SetStringValue("OG"); listRows.push_back(pRow); pColumn->SetGridRowsList(listRows); listCol.push_back(pColumn); break; case 10: pColumn = CGridColumnPtr(new CGridColumn()); strName = "S"; pColumn->SetName(strName); strWidthName1.Format(_T("%lf"), ka); strWidthName2 = ""; strWidthName3 = ""; strWidthName4 = ""; pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::FLOAT); pRow->SetDoubleValue(ka); listRows.push_back(pRow); pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::FLOAT); pRow->SetDoubleValue(0); listRows.push_back(pRow); pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::FLOAT); pRow->SetDoubleValue(0); listRows.push_back(pRow); pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::FLOAT); pRow->SetDoubleValue(0); listRows.push_back(pRow); pColumn->SetGridRowsList(listRows); listCol.push_back(pColumn); break; case 11: pColumn = CGridColumnPtr(new CGridColumn()); strName = "O"; pColumn->SetName(strName); strWidthName1.Format(_T("%lf"), to); strWidthName2 = ""; strWidthName3 = ""; strWidthName4 = ""; pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::FLOAT); pRow->SetDoubleValue(0); listRows.push_back(pRow); pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::FLOAT); pRow->SetDoubleValue(kb); listRows.push_back(pRow); pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::FLOAT); pRow->SetDoubleValue(kc); listRows.push_back(pRow); pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::FLOAT); pRow->SetDoubleValue(kd); listRows.push_back(pRow); pColumn->SetGridRowsList(listRows); listCol.push_back(pColumn); break; default: pColumn = CGridColumnPtr(new CGridColumn()); strName.Format("%d", i - 1); pColumn->SetName(strName); CGridRowsList listRows; pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::INT); pRow->SetIntValue(levA[i - 1]); listRows.push_back(pRow); pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::INT); pRow->SetIntValue(levB[i - 1]); listRows.push_back(pRow); pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::INT); pRow->SetIntValue(levC[i - 1]); listRows.push_back(pRow); pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::INT); pRow->SetIntValue(levD[i - 1]); listRows.push_back(pRow); pColumn->SetGridRowsList(listRows); listCol.push_back(pColumn); break; } } pGridData->SetGridColumnList(listCol); return pGridData; } void CGBCalculate::SetFrameLevelNo(GB_GRADE_TYPE a_level, int a_nLevel[]) { a_nLevel[(int)a_level] += 1; } // calculate GB fields CGBFieldList CGBCalculate::CalGBFields(CSmplMsrResultFileMgrPtr pSmplMgr, GB_METHODE_TYPE calType) { CGBFieldList m_listGBFields; m_listGBFields.clear(); ASSERT(pSmplMgr); CSmplMsrResultFilePtr pSmplMsrResultFile = pSmplMgr->GetSmplMsrResultFile(); ASSERT(pSmplMsrResultFile); COTSSamplePtr pOTSSample = pSmplMsrResultFile->GetSample(); ASSERT(pOTSSample); CSEMDataMsrPtr pEMDataMsrPtr = pOTSSample->GetSEMDataMsr(); ASSERT(pEMDataMsrPtr); // get field width int nOTSFieldWidth = pEMDataMsrPtr->GetScanFieldSize(); int nOTSFieldHeight = pEMDataMsrPtr->GetScanFieldHeight(); if (nOTSFieldWidth == 0 || nOTSFieldHeight==0) { LogErrorTrace(__FILE__, __LINE__, _T("CalGBFields: field width is zero .")); return m_listGBFields; } // scan parameters CMsrParamsPtr pMsrParam = pOTSSample->GetMsrParams(); //CMsrParamsPtr pMsrParam = pOTSSample->get COTSImageScanParamPtr pImgScanParam = pMsrParam->GetImageScanParam(); CSize sizePixelImage = pImgScanParam->GetImageResolution(); //use OTSField width cal the OTSField height //get OTSfilds list COTSFieldDataList allOTSFields; allOTSFields = pSmplMsrResultFile->GetFieldData(); // convert ots fields to gb fields if (!OTSFieldToGBField( allOTSFields, &m_listGBFields, sizePixelImage, nOTSFieldWidth, nOTSFieldHeight)) { LogErrorTrace(__FILE__, __LINE__, _T("CalGBFields: call OTSFieldToGBField failed.")); return m_listGBFields; } for (auto fld : m_listGBFields) { fld->SetCalcuType(calType); } return m_listGBFields; } // Turn OTSField to GBField BOOL CGBCalculate::OTSFieldToGBField(COTSFieldDataList allOTSFields, CGBFieldList* m_listGBFields,CSize sizePixelImage,int nOTSFieldWidth,int nOTSFieldHeight) { if (allOTSFields.empty()) { LogTrace(__FILE__, __LINE__, _T("CalGBFields: listOTSFields is empty .")); return TRUE; } // get topleft point and bottomright point of the measurement convered area CPoint pointTopleft, pointBottomright; pointTopleft = pointBottomright = allOTSFields[0]->GetPosition(); //判断有效区域 for (unsigned int i = 0; i< allOTSFields.size(); i++) { //get current OTSField Position,the position is in the center of the field CPoint poiOTSFieldPosition = allOTSFields[i]->GetPosition(); pointTopleft.x = min(poiOTSFieldPosition.x, pointTopleft.x); pointTopleft.y = max(poiOTSFieldPosition.y, pointTopleft.y); pointBottomright.x = max(poiOTSFieldPosition.x, pointBottomright.x); pointBottomright.y = min(poiOTSFieldPosition.y, pointBottomright.y); } pointTopleft.x -= nOTSFieldWidth / 2; pointTopleft.y += nOTSFieldHeight / 2; pointBottomright.x+= nOTSFieldWidth / 2; pointBottomright.y-= nOTSFieldHeight / 2; double totalWidth = pointBottomright.x - pointTopleft.x; double totalHeight = pointTopleft.y - pointBottomright.y; int nPossibleGBFieldRowNum = totalHeight /GB_FIELD_WIDTH+0.5;//可能有的国标field行数 int nPossibleGBFieldColNum = totalWidth / GB_FIELD_WIDTH+0.5;//列数 //get possible OTSFields m_listGBFields->clear(); CPoint pointGBFieldPosition; for (int i = 0; i < nPossibleGBFieldRowNum; i++) { for (int j = 0; j < nPossibleGBFieldColNum; j++) { // cal GB field rectangle CPoint poiCurGBFieldTopLeft, poiCurGBFieldBottomRight; poiCurGBFieldTopLeft = pointTopleft; //获得左上角的坐标 poiCurGBFieldTopLeft.x += j * GB_FIELD_WIDTH; poiCurGBFieldTopLeft.y -= i * GB_FIELD_WIDTH; //获得右下角的坐标 poiCurGBFieldBottomRight.x = poiCurGBFieldTopLeft.x + GB_FIELD_WIDTH; poiCurGBFieldBottomRight.y = poiCurGBFieldTopLeft.y - GB_FIELD_WIDTH; COTSRect rectGBField(poiCurGBFieldTopLeft, poiCurGBFieldBottomRight); CGBFieldDataPtr pGBFieldData; pGBFieldData = GetOneGBField(rectGBField, allOTSFields, sizePixelImage, nOTSFieldWidth, nOTSFieldHeight); if (!pGBFieldData) { continue; } CPoint poiNewPosition=rectGBField.GetCenterPoint(); pGBFieldData->SetPosition(poiNewPosition); // add the GBField into the GBFields list m_listGBFields->push_back(pGBFieldData); } } // ok, return TRUE return TRUE; } // Custom collation rules BOOL comp(const COTSFieldDataPtr &a, const COTSFieldDataPtr &b) { if (a->GetPosition().y <= b->GetPosition().y) { if (a->GetPosition().y == b->GetPosition().y) { if (a->GetPosition().x < b->GetPosition().x) { return TRUE; } } else { return TRUE; } } return FALSE; } // get the GB field within a rectangle CGBFieldDataPtr CGBCalculate::GetOneGBField(COTSRect a_rectGBField, COTSFieldDataList& allOTSFields, CSize a_sizePixelImage, int nOTSFieldWidth, int nOTSFieldHeight) { // GB Field handle CGBFieldDataPtr pGBFieldData = nullptr; // get OTS fields within the rectangle COTSFieldDataList myOTSFields; myOTSFields.clear(); COTSFieldDataList::iterator itr = allOTSFields.begin(); while (itr != allOTSFields.end()) { // get an OTS field CPoint poiOTSField = (*itr)->GetPosition(); COTSRect fldRec = COTSRect(poiOTSField.x - nOTSFieldWidth / 2, poiOTSField.y + nOTSFieldHeight / 2, poiOTSField.x + nOTSFieldWidth / 2, poiOTSField.y - nOTSFieldHeight / 2); if (a_rectGBField.IntersectOtherRect( fldRec)) { (*itr)->SetRect(fldRec); myOTSFields.push_back(*itr); itr++; continue; } itr++; } pGBFieldData = NormalizeParticlesAndIdentifyChemicalType(a_rectGBField, myOTSFields, a_sizePixelImage, nOTSFieldWidth, nOTSFieldHeight); pGBFieldData->myReleventOTSFlds = myOTSFields; return pGBFieldData; } // normalize particles for the GBFields CGBFieldDataPtr CGBCalculate::NormalizeParticlesAndIdentifyChemicalType(COTSRect a_rectGBField, COTSFieldDataList myOTSFields, CSize a_sizePixelImage, int nFieldWidth,int nFieldHeight) { // inits CGBFieldDataPtr pGBFieldData(new CGBFieldData); pGBFieldData->SetMyRect(a_rectGBField); COTSParticleList listNormalizedParticles; CPoint pointGBFieldRectTopLeft = a_rectGBField.GetTopLeft(); COTSRect GBRect = a_rectGBField; int nBeforeCalNo = 0; int nAfterCalNo = 0; for (auto OTSField : myOTSFields) { for (auto part : OTSField->GetParticleList()) { CPoint fieldPos = OTSField->GetPosition(); CPoint fieldTopLeft = OTSField->GetRect().GetTopLeft(); double fwidth = nFieldWidth; double pixelsize = fwidth / a_sizePixelImage.cx; CPoint xrayPosInFieldByPixel= part->GetXRayPos(); CPoint partPos = CPoint(fieldTopLeft.x + xrayPosInFieldByPixel.x * pixelsize, fieldTopLeft.y - xrayPosInFieldByPixel.y * pixelsize); if (GBRect.PointInRect(partPos)) { CRect rectInSinglefld = part->GetParticleRect(); CPoint OTSLeftTop = CPoint(fieldTopLeft.x + rectInSinglefld.left * pixelsize, fieldTopLeft.y - rectInSinglefld.top * pixelsize); CPoint OTSRightBottom = CPoint(fieldTopLeft.x + rectInSinglefld.right * pixelsize, fieldTopLeft.y - rectInSinglefld.bottom * pixelsize); COTSRect recInOTSCord = COTSRect(OTSLeftTop, OTSRightBottom); part->SetOTSRect(recInOTSCord); pGBFieldData->IdentifyPartChemicalType(part); listNormalizedParticles.push_back(part); } } } // put new particle in the GB Field pGBFieldData->SetParticleList(listNormalizedParticles); return pGBFieldData; } void CGBCalculate::SetPixSize(double p) { PixSize = p; } void CGBCalculate::DisplayDSPartRow(COTSParticlePtr part, CGridColumnsList listCol) { int columnNum = 6; CGridColumnPtr pColumn; for (int i = 0; i < columnNum; i++) { CString strName; CGridRowsList listRows; CGridRowPtr pRow; CString strWidthName1, strWidthName2, strWidthName3; CString idstr; int fldid; int partId; switch (i) { case 0: pColumn = listCol.at(0); pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::STRING); fldid = part->GetFieldId(); partId = part->GetParticleId(); idstr.Format("%d_%d", fldid, partId); pRow->SetStringValue(idstr); pColumn->AddGridRow(pRow); break; case 1: pColumn = listCol.at(1); pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::INT); pRow->SetIntValue(part->GetActualArea()); pColumn->AddGridRow(pRow); break; case 2: pColumn = listCol.at(2); pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::FLOAT); pRow->SetDoubleValue(part->GetFeretDiameter()); pColumn->AddGridRow(pRow); break; case 3: pColumn = listCol.at(3); pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::FLOAT); pRow->SetDoubleValue(part->GetAbsolutPos().x); pColumn->AddGridRow(pRow); break; case 4: pColumn = listCol.at(4); pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::FLOAT); pRow->SetDoubleValue(part->GetAbsolutPos().y); pColumn->AddGridRow(pRow); break; case 5: pColumn = listCol.at(5); pRow = CGridRowPtr(new CGridRow()); pRow->SetDataType(REPORT_GRID_DATA_TYPE::STRING); pRow->SetStringValue(OTSGBCalculate::GetDSGrade(part->GetFeretDiameter())); pColumn->AddGridRow(pRow); break; } } } }