12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279 |
- #pragma once
- #include "stdafx.h"
- #include "OTSClassifyEng.h"
- #include "OTSHelper.h"
- namespace OTSClassifyEngine
- {
- using namespace OTSClassifyEngine;
- COTSClassifyEng::COTSClassifyEng(CInclutionSTDDataPtr a_pPartSTDData) // constructor
- {
- ASSERT(a_pPartSTDData);
- // get all sulfides STD items
- pPartSTDData = a_pPartSTDData;
- if (!GetClassifySTDItem(a_pPartSTDData, INC_CLASSIFY_TYPE::SUL, listSulfideSTD))
- {
- // something is wrong
- LogErrorTrace(__FILE__, __LINE__, _T("COTSClassifyEng::SulClassify: failed to call GetClassifySTDItem method."));
- }
- // get all oxides STD items
-
- if (!GetClassifySTDItem(a_pPartSTDData, INC_CLASSIFY_TYPE::OXIDE, listOxideSTD))
- {
- // something wrong
- LogErrorTrace(__FILE__, __LINE__, _T("COTSClassifyEng::OxideClassify: failed to call GetClassifySTDItem method."));
- }
- // get all nitride STD items
-
- if (!GetClassifySTDItem(a_pPartSTDData, INC_CLASSIFY_TYPE::NITR, listNitrideSTD))
- {
- // something wrong
- LogErrorTrace(__FILE__, __LINE__, _T("COTSClassifyEng::NitrideClassify: failed to call GetClassifySTDItem method."));
- }
- // get all nitride STD items
-
- if (!GetClassifySTDItem(a_pPartSTDData, INC_CLASSIFY_TYPE::CARBON, listCarbonSTD))
- {
- // something wrong
- LogErrorTrace(__FILE__, __LINE__, _T("CClassifyEng::NitrideClassify: failed to call GetClassifySTDItem method."));
- }
- // get user STD items
-
- //if (!GetClassifySTDItem(a_pPartSTDData, INC_CLASSIFY_TYPE::USER, listUserSTD))
- //{
- // // something wrong
- // LogErrorTrace(__FILE__, __LINE__, _T("COTSClassifyEng::OxideClassify: failed to call GetClassifySTDItem method."));
- //
- //}
- }
- COTSClassifyEng::~COTSClassifyEng() // detractor
- {
- }
- //Dispose ClassifyXray
- BOOL COTSClassifyEng::ClassifyXray( STEEL_TECHNOLOGY steelTech, CElementChemistriesList& a_listElementChemistries, int& a_nIncId, int& a_GrpId)
- {
-
-
- // the element chemistries list is an inclusion
- CElementChemistriesList listElChemsInc;
- CElementChemistriesList listElChemsIncNoFe;
-
- double dMolarSum = 0.0f;
- double dMolarSumNoFe = 0.0f;
- OTS_PARTICLE_TYPE incId;
- NOT_INCLUTION_ID notAIncId;// is not an inc but we can identify
- if (!IsAnValidIncXRay(a_listElementChemistries, listElChemsInc, listElChemsIncNoFe, dMolarSum, dMolarSumNoFe, incId, notAIncId))
- {
-
- LogErrorTrace(__FILE__, __LINE__, _T("COTSClassifyEng::failed to call IsAnValidIncXRay"));
-
- return FALSE;
- }
- if (incId == OTS_PARTCLE_TYPE::ISNOT_INCLUTION)// this is not an inclution particle,but we can identify.
- {
- a_nIncId =(int) notAIncId;
- a_GrpId = (int)OTS_PARTCLE_TYPE::ISNOT_INCLUTION;
- return TRUE;
- }
- if (incId == OTS_PARTCLE_TYPE::INVALID)// this is not an valid inclution particle.
- {
- a_nIncId = (int)OTS_PARTCLE_TYPE::INVALID;
- a_GrpId = (int)OTS_PARTCLE_TYPE::INVALID;
- return TRUE;
- }
-
- // system STD classification
- int nIncId = (int)OTS_PARTICLE_TYPE::NOT_IDENTIFIED;
- if (!SystemClassify( steelTech, listElChemsIncNoFe, dMolarSumNoFe, nIncId))
- {
- LogErrorTrace(__FILE__, __LINE__, _T("COTSClassifyEng::ClassifyXray: failed to call SystemClassify method."));
- a_nIncId = (int)OTS_PARTICLE_TYPE::NOT_IDENTIFIED;
- return FALSE;
- }
- // identified?
- if (nIncId > (int)OTS_PARTICLE_TYPE::IDENTIFIED)
- {// identified, return TRUE
- a_nIncId = nIncId;
- IDENTIFIED_INC_GRP_ID grpid;
- GroupClassify(a_listElementChemistries,nIncId, grpid);
- a_GrpId = (int)grpid;
- return TRUE;
- }
- // user STD classification
- /*if (!UserClassify(a_pPartSTDData, listElChemsInc, dMolarSum, nIncId))
- {
- LogErrorTrace(__FILE__, __LINE__, _T("COTSClassifyEng::ClassifyXray: failed to call UserClassify method."));
- a_nIncId = (int)OTS_PARTICLE_TYPE::NOT_IDENTIFIED;
- return FALSE;
- }*/
- // identified?
- if (nIncId > (int)OTS_PARTICLE_TYPE::IDENTIFIED)
- {
- // identified, return TRUE
- a_nIncId = nIncId;
- IDENTIFIED_INC_GRP_ID grpid;
- GroupClassify(a_listElementChemistries,nIncId, grpid);
- a_GrpId = (int)grpid;
- return TRUE;
- }
- // can't identify this inclusion
- a_nIncId = (int)OTS_PARTICLE_TYPE::NOT_IDENTIFIED;
- IDENTIFIED_INC_GRP_ID grpid;
- GroupClassify(a_listElementChemistries,nIncId, grpid);
- a_GrpId = (int)grpid;
- return TRUE;
- }
- // public
- // check if the x-ray is an inc x-ray,
- BOOL COTSClassifyEng::IsAnValidIncXRay(
- CElementChemistriesList& a_listElementChemistries,
- CElementChemistriesList& a_listElChemsInc,
- CElementChemistriesList& a_listElChemsIncNoFe,
- double& a_dMolarSum,
- double& a_dMolarSumNoFe,
- OTS_PARTICLE_TYPE& a_nIncId,
- NOT_INCLUTION_ID& notIncId)
- {
-
- // go through all elementS
- a_listElChemsInc.clear();
- a_listElChemsIncNoFe.clear();
- a_dMolarSum = 0;
- a_dMolarSumNoFe = 0;
- double dSumKeyElements = 0;
- double dSumSubElements = 0;
- double dCarbonMolar = 0;
- double dOMolar = 0;
- double dSiMolar = 0;
- double dFeMolar = 0;
- for (auto pElChem : a_listElementChemistries)
- {
- // create a new element chemistry
- CElementChemistryPtr pElChemNew = CElementChemistryPtr(new CElementChemistry(*pElChem.get()));
- // key element? S,O,N
- if (IsKeyElement(pElChem))
- {
- // this is a key element
- // get molar percentage of this element
- double dMolarPercentage = pElChem->GetMolarPercentage();
- // cal molar percentage sum (both lists)
- a_dMolarSum += dMolarPercentage;
- a_dMolarSumNoFe += dMolarPercentage;
- // cal key element molar percentage sum
- dSumKeyElements += dMolarPercentage;
- // add the element into the two lists
- a_listElChemsInc.push_back(pElChemNew);
- a_listElChemsIncNoFe.push_back(pElChemNew);
- if (pElChem->GetName().CompareNoCase(STR_O) == 0)
- {
- dOMolar = pElChem->GetMolarPercentage();
- }
- else if (pElChem->GetName().CompareNoCase(STR_C) == 0)
- {
- dCarbonMolar = pElChem->GetMolarPercentage();
- }
- }
- // sub element?, include Fe
- else if (IsSubElement(pElChem))
- {
- // this is a sub element
- // get molar percentage of this element
- double dMolarPercentage = pElChem->GetMolarPercentage();
- // cal molar percentage sum list
- a_dMolarSum += dMolarPercentage;
- // cal key element molar percentage sum
- dSumSubElements += dMolarPercentage;
- // add the element into the list
- a_listElChemsInc.push_back(pElChemNew);
-
-
- // cal molar percentage sum list (no Fe)
- a_dMolarSumNoFe += pElChem->GetMolarPercentage();
- // add the element into the list (no Fe)
- a_listElChemsIncNoFe.push_back(pElChemNew);
- // Si
- if (pElChem->GetName().CompareNoCase(STR_SI) == 0)
- {
- dSiMolar = pElChem->GetMolarPercentage();
- }
-
-
- }
- else if (pElChem->GetName().CompareNoCase(STR_FE) == 0)
- {
- dFeMolar = pElChem->GetMolarPercentage();
- }
-
-
-
- }
- // not a inc if this is a SiC
- //=========================================
- // any carbon?
- if (dCarbonMolar > MIN_DOUBLE_VALUE)
- {
- // calculate molar % of C + Si
- double dMolarC_Si = Cal100NorValue(dCarbonMolar + dSiMolar, a_dMolarSumNoFe + dCarbonMolar);
- if (dMolarC_Si > SIC_MOLAR_CUTOFF)
- {
- // this is a SiC, not a inclusion, return FALSE
- a_nIncId =OTS_PARTCLE_TYPE::ISNOT_INCLUTION;
- notIncId = NOT_INCLUTION_ID::SiC;
- return TRUE;
- }
- }
- //=========================================
- //FeO
- if (dOMolar > MIN_DOUBLE_VALUE)
- {
- // calculate molar % of Fe + O
- double dMolarFe_O = Cal100NorValue(dOMolar + dFeMolar, a_dMolarSum + dCarbonMolar);
- if (dMolarFe_O > FEO_MOLAR_CUTOFF)
- {
- if (a_listElementChemistries.size() == 2)//there is only Fe and O
- {
- if (std::find_if(a_listElementChemistries.begin(), a_listElementChemistries.end(), [](CElementChemistryPtr i) {return ((i->GetName().CompareNoCase(STR_CR) != 0) && (i->GetName().CompareNoCase(STR_O) != 0)); }) != a_listElementChemistries.end())
- {
- //this is a FeO, not a inclusion, return FALSE
- a_nIncId = OTS_PARTCLE_TYPE::ISNOT_INCLUTION;
- notIncId = NOT_INCLUTION_ID::FeO;
- return TRUE;
- }
- }
- }
- }
- // both key molar percentage sum and sub molar percentage sum have to be over certain values
- double dSumKeyElementsMolar = Cal100NorValue(dSumKeyElements, a_dMolarSumNoFe);
- double dSumSubElementsMolar = Cal100NorValue(dSumSubElements, a_dMolarSumNoFe);
- if (a_dMolarSumNoFe < MIN_ELEMENT_SUM)
- {
- a_nIncId = OTS_PARTICLE_TYPE::INVALID;
- return TRUE;
- }
- if (dSumKeyElementsMolar > INC_KEY_ELEMENT_TOTAL_100 && dSumSubElementsMolar > INC_SUB_ELEMENT_TOTAL_100)
- {
- a_nIncId = OTS_PARTCLE_TYPE::NOT_IDENTIFIED;
- return TRUE;
- }
- else
- {
- a_nIncId = OTS_PARTICLE_TYPE::INVALID;
- return TRUE;
- }
- }
- // system classification
- BOOL COTSClassifyEng::SystemClassify(
- STEEL_TECHNOLOGY steelTech,
- CElementChemistriesList& a_listElChemsIncNoFe,
- double a_dMolarSumNoFe,
- int& a_nIncId)
- {
-
- // try sulfide classification
- int nIncId = (int)OTS_PARTICLE_TYPE::INVALID;
- if (!SulClassify(steelTech, a_listElChemsIncNoFe, a_dMolarSumNoFe, nIncId))
- {
- // something wrong
- LogErrorTrace(__FILE__, __LINE__, _T("COTSClassifyEng::ClassifyXray: failed to call SulClassify method."));
- a_nIncId = (int)OTS_PARTICLE_TYPE::NOT_IDENTIFIED;
- return FALSE;
- }
- // inclusion identified?
- if (nIncId != (int)OTS_PARTICLE_TYPE::INVALID)
- {
- // yes, this is a sulfide
- a_nIncId = nIncId;
-
- return TRUE;
- }
- // nitride classification
- if (!NitrideClassify(a_listElChemsIncNoFe, a_dMolarSumNoFe, nIncId))
- {
- // something wrong
- LogErrorTrace(__FILE__, __LINE__, _T("COTSClassifyEng::ClassifyXray: failed to call NitrideClassify method."));
- a_nIncId = (int)OTS_PARTICLE_TYPE::NOT_IDENTIFIED;
- return FALSE;
- }
- // inclusion identified?
- if (nIncId != (int)OTS_PARTICLE_TYPE::INVALID)
- {
- // yes, this is a nitride
- a_nIncId = nIncId;
- return TRUE;
- }
- // oxide classification
- if (!OxideClassify(a_listElChemsIncNoFe, a_dMolarSumNoFe, nIncId))
- {
- // something wrong
- LogErrorTrace(__FILE__, __LINE__, _T("COTSClassifyEng::ClassifyXray: failed to call OxideClassify method."));
- a_nIncId = (int)OTS_PARTICLE_TYPE::NOT_IDENTIFIED;
- return FALSE;
- }
- // inclusion identified?
- if (nIncId != (int)OTS_PARTICLE_TYPE::INVALID)
- {
- // yes, this is a oxide
- a_nIncId = nIncId;
- return TRUE;
- }
- // CarbonClassify classification
- if (!CarbonClassify(a_listElChemsIncNoFe, a_dMolarSumNoFe, nIncId))
- {
- // something wrong
- LogErrorTrace(__FILE__, __LINE__, _T("COTSClassifyEng::ClassifyXray: failed to call CarbonClassify method."));
- a_nIncId = (int)OTS_PARTICLE_TYPE::NOT_IDENTIFIED;
- return FALSE;
- }
- // inclusion identified?
- if (nIncId != (int)OTS_PARTICLE_TYPE::INVALID)
- {
- // yes, this is a oxide
- a_nIncId = nIncId;
- return TRUE;
- }
- // can't identify this inclusion
- a_nIncId = (int)OTS_PARTICLE_TYPE::NOT_IDENTIFIED;
- return TRUE;
- }
- BOOL COTSClassifyEng::GroupClassify(CElementChemistriesList& a_listElChemsIncNoFe,int incId, IDENTIFIED_INC_GRP_ID& a_GrpId)
- {
-
- double dOWeight = 0;
- double dSWeight = 0;
- double dNWeight = 0;
- /*double weightsum=0;
- for (auto ele : a_listElChemsIncNoFe)
- {
- weightsum += ele->GetPercentage();
- }*/
- auto stdItm =pPartSTDData->GetSTDItemById( incId);
- if (incId == (int)OTS_PARTICLE_TYPE::NOT_IDENTIFIED)
- {
- a_GrpId = IDENTIFIED_INC_GRP_ID::Others;
- return true;
- }
- auto stdName = stdItm->GetName();
- // sulfide classification
- for (long i = 0; i < INC_SUL_SUB_ELEMENT_MAX; i++)
- {
- if (stdName.CompareNoCase(INC_SULFILSES_NAMES[i]) == 0 )
- {
- a_GrpId = IDENTIFIED_INC_GRP_ID::SULFIDE;
- return true;
- }
- }
- if (stdName.CompareNoCase(SULFIDE_STR) == 0 )
- {
- a_GrpId = IDENTIFIED_INC_GRP_ID::SULFIDE;
- return true;
- }
- //oxide classification
- for (long i = 0; i < INC_OXIDE_SUB_ELEMENT_MAX; i++)
- {
- if (stdName.CompareNoCase(INC_OXIDE_NAMES[i]) == 0)
- {
- a_GrpId = IDENTIFIED_INC_GRP_ID::OXIDE;
- return true;
- }
- }
- if (stdName.CompareNoCase(SPINEL_STR) == 0)
- {
- a_GrpId = IDENTIFIED_INC_GRP_ID::OXIDE;
- return true;
- }
- if (stdName.CompareNoCase(ALUMINATE12CaO_7Al2O3_STR) == 0)
- {
- a_GrpId = IDENTIFIED_INC_GRP_ID::OXIDE;
- return true;
- }
- if (stdName.CompareNoCase(ALUMINATE3CaO_Al2O3_STR) == 0)
- {
- a_GrpId = IDENTIFIED_INC_GRP_ID::OXIDE;
- return true;
- }
- if (stdName.CompareNoCase(ALUMINATE_STR) == 0)
- {
- a_GrpId = IDENTIFIED_INC_GRP_ID::OXIDE;
- return true;
- }
- if (stdName.CompareNoCase(Ca_ALUMINATE_STR) == 0)
- {
- a_GrpId = IDENTIFIED_INC_GRP_ID::OXIDE;
- return true;
- }
- for (long i = 0; i < INC_NITR_SUB_ELEMENT_MAX; i++)
- {
- if (stdName.CompareNoCase(INC_NITR_NAMES[i]) == 0)
- {
- a_GrpId = IDENTIFIED_INC_GRP_ID::CARBONNITRIDE_NITRIDE;
- return true;
- }
- }
- for (auto pElChem : a_listElChemsIncNoFe)
- {
-
- if (pElChem->GetName().CompareNoCase(STR_O) == 0)
- {
-
- dOWeight = pElChem->GetPercentage();
-
- }
- else if (pElChem->GetName().CompareNoCase(STR_SUL) == 0)
- {
- dSWeight = pElChem->GetPercentage();
-
- }
- else if (pElChem->GetName().CompareNoCase(STR_N) == 0)
- {
- dNWeight = pElChem->GetPercentage();
- }
- }
-
-
- if (dOWeight >= MIN_ELEMENT_SUM && dSWeight< MIN_ELEMENT_SUM )
- {
-
- a_GrpId = IDENTIFIED_INC_GRP_ID::OXIDE;
-
- }
- else if ( dSWeight >= MIN_ELEMENT_SUM && dOWeight < MIN_ELEMENT_SUM)
- {
- a_GrpId = IDENTIFIED_INC_GRP_ID::SULFIDE;
- }
- else if (dOWeight >= MIN_ELEMENT_SUM && dSWeight >= MIN_ELEMENT_SUM )
- {
- a_GrpId = IDENTIFIED_INC_GRP_ID::SULFIDE_OXIDE;
- }
- else if ( dNWeight >= MIN_ELEMENT_SUM)
- {
- a_GrpId = IDENTIFIED_INC_GRP_ID::CARBONNITRIDE_NITRIDE;
- }
- else
- {
- a_GrpId = IDENTIFIED_INC_GRP_ID::Others;
- }
-
- return TRUE;
-
-
- }
- BOOL COTSClassifyEng::GetGroupNameAndColorById(int grpId,std::string& grpName,std::string& grpColor)
- {
- if (grpId == (int)OTS_PARTICLE_TYPE::INVALID)
- {
- grpName = "Invalid";
- grpColor = "#000000";
- }
- if (grpId == (int)OTS_PARTICLE_TYPE::NOT_IDENTIFIED)
- {
- grpName = "Not Identified";
- grpColor = "#000000";
- }
- if (grpId == (int)OTS_PARTICLE_TYPE::ISNOT_INCLUTION)
- {
- grpName = "NOT_INCLUTION";
- grpColor = "#483D8B";
- }
- switch (grpId)
- {
- case (int)IDENTIFIED_INC_GRP_ID::OXIDE:
- grpName = "Oxide";
- grpColor = "#FF69B4";
- break;
- case (int)IDENTIFIED_INC_GRP_ID::SULFIDE:
- grpName = "Sulfide";
- grpColor = "#FF00FF";
- break;
- case (int)IDENTIFIED_INC_GRP_ID::SULFIDE_OXIDE:
- grpName = "Sulfide_Oxide";
- grpColor = "#0000FF";
- break;
- case (int)IDENTIFIED_INC_GRP_ID::CARBONNITRIDE_NITRIDE:
- grpName = "CarbonNitride/Nitride";
- grpColor = "#00FF7F";
- break;
- case (int)IDENTIFIED_INC_GRP_ID::Others:
- grpName = "Other";
- grpColor = "#B0C4DE";
- break;
- default:
- break;
- }
- return true;
-
-
- }
- // sulfides classification
- BOOL COTSClassifyEng::SulClassify(
- STEEL_TECHNOLOGY steelTech,
- CElementChemistriesList& a_listElChemsIncNoFe,
- double a_dMolarSumNoFe,
- int& a_nIncId)
- {
-
-
- // check if element chemistries list contain any sulfur
- CElementChemistryPtr pSulElChem = GetNamedElementChemistry(a_listElChemsIncNoFe, STR_SUL);
- if (!pSulElChem)
- {
- // contains no sulfur, this is not a sulfide
- return TRUE;
- }
- // calculate sulfur 100 percentage molar
- double dSulMolar100 = Cal100NorValue(pSulElChem->GetMolarPercentage(), a_dMolarSumNoFe);
- // check if sulfur amount enough
- if (dSulMolar100 < MIN_SUL_MOLAR)
- {
- // no enough sulfur, this is not a sulfide
- return TRUE;
- }
- // this is a sulfide
- // any sulfides STD items
- if (listSulfideSTD.empty())
- {
- // no sulfides std items. can't identify sulfide
- // can't identify this inclusion
- a_nIncId = (int)OTS_PARTICLE_TYPE::NOT_IDENTIFIED;
- return TRUE;
- }
- // mapping Mn first
- BOOL bMnMapped = FALSE;
- {
- CElementChemistryPtr pElChemMn = GetNamedElementChemistry(a_listElChemsIncNoFe, INC_SUL_SUB_ELEMENT_NAMES[0]);
- double dMappingRatio = INC_SULFILSES_MAPPING_RATIO[0];
- if (pElChemMn)
- {
- // there Mn in the element list, map S & Mn
- if (!ElementsMapping(a_dMolarSumNoFe, dMappingRatio, pElChemMn, pSulElChem, bMnMapped))
- {
- // something is wrong
- LogErrorTrace(__FILE__, __LINE__, _T("COTSClassifyEng::SulClassify: failed to call ElementsMapping method."));
- return FALSE;
- }
- }
- }
- // need to re-calculate sulfur 100% molar value if Mn mapped
- if(bMnMapped)
- {
- dSulMolar100 = Cal100NorValue(pSulElChem->GetMolarPercentage(), a_dMolarSumNoFe);
- }
- // process mapping if sulfur amount enough
- CElementChemistriesList listChemistriesToAnalysis;
- CString strProMappingSulName = _T("");
- BOOL bProMapped = FALSE;
- if (dSulMolar100 > MIN_SUL_MOLAR)
- {
- // still have enough sulfur, mapping Ca, Mg or Ce, La
- double dMappingRadio;
- switch ( steelTech)
- {
- // Ca process
- case STEEL_TECHNOLOGY::CaProcessMode:
- {
- //remove the Mg element first
- CElementChemistryPtr pElChemMg = GetNamedElementChemistry(a_listElChemsIncNoFe, INC_SUL_SUB_ELEMENT_NAMES[2]);
-
- if (pElChemMg)
- {
- for (auto el : a_listElChemsIncNoFe)
- {
- if (!el->GetName().CompareNoCase(INC_SUL_SUB_ELEMENT_NAMES[2]))
- {
- listChemistriesToAnalysis.push_back(el);
- }
-
- }
-
- }
- else
- {
- listChemistriesToAnalysis = a_listElChemsIncNoFe;
- }
- // try to get Ca element chemistry
- CElementChemistryPtr pElChemCa = GetNamedElementChemistry(a_listElChemsIncNoFe, INC_SUL_SUB_ELEMENT_NAMES[1]);
- if (pElChemCa)
- {
- // there Ca in the element list, map Ca & S
- dMappingRadio = INC_SULFILSES_MAPPING_RATIO[1];
- if (!ElementsMapping(a_dMolarSumNoFe, dMappingRadio, pElChemCa, pSulElChem, bProMapped))
- {
- // something is wrong
- LogErrorTrace(__FILE__, __LINE__, _T("COTSClassifyEng::SulClassify: failed to call ElementsMapping method."));
- return FALSE;
- }
- // mapping successful?
- if (bProMapped)
- {
- strProMappingSulName = INC_SULFILSES_NAMES[1];
- }
- }
- }
- break;
- // Mg process
- case STEEL_TECHNOLOGY::MgProcessMode:
- {
- //remove the Ca element first
- CElementChemistryPtr pElChemCa = GetNamedElementChemistry(a_listElChemsIncNoFe, INC_SUL_SUB_ELEMENT_NAMES[1]);
-
- if (pElChemCa)
- {
- for (auto el : a_listElChemsIncNoFe)
- {
- if (!el->GetName().CompareNoCase(INC_SUL_SUB_ELEMENT_NAMES[1]))
- {
- listChemistriesToAnalysis.push_back(el);
- }
- }
- }
- else
- {
- listChemistriesToAnalysis = a_listElChemsIncNoFe;
- }
- // try to get Mg element chemistry
- CElementChemistryPtr pElChemMg = GetNamedElementChemistry(a_listElChemsIncNoFe, INC_SUL_SUB_ELEMENT_NAMES[2]);
- if (pElChemMg)
- {
- // there Mg in the element list, map Mg & S
- dMappingRadio = INC_SULFILSES_MAPPING_RATIO[2];
- if (!ElementsMapping(a_dMolarSumNoFe, dMappingRadio, pElChemMg, pSulElChem, bProMapped))
- {
- // something is wrong
- LogErrorTrace(__FILE__, __LINE__, _T("COTSClassifyEng::SulClassify: failed to call ElementsMapping method."));
- return FALSE;
- }
- // mapping successful?
- if (bProMapped)
- {
- strProMappingSulName = INC_SULFILSES_NAMES[2];
- }
- }
- }
- break;
- // real earth elements process
- case STEEL_TECHNOLOGY::RareEarthMode:
- {
- listChemistriesToAnalysis = a_listElChemsIncNoFe;
- // try to get Ce element chemistry
- CElementChemistryPtr pElChemCe = GetNamedElementChemistry(a_listElChemsIncNoFe, INC_SUL_SUB_ELEMENT_NAMES[3]);
- BOOL bCeMapped = FALSE;
- if (pElChemCe)
- {
- // there Ce in the element list, map S with Ce
- dMappingRadio = INC_SULFILSES_MAPPING_RATIO[3];
- if (!ElementsMapping(a_dMolarSumNoFe, dMappingRadio, pElChemCe, pSulElChem, bCeMapped))
- {
- // something is wrong
- LogErrorTrace(__FILE__, __LINE__, _T("COTSClassifyEng::SulClassify: failed to call ElementsMapping method."));
- return FALSE;
- }
- }
- // try to get La element chemistry
- CElementChemistryPtr pElChemLa = GetNamedElementChemistry(a_listElChemsIncNoFe, INC_SUL_SUB_ELEMENT_NAMES[4]);
- BOOL bLaMapped = FALSE;
- if (pElChemLa)
- {
- // there La in the element list, map S with La
- dMappingRadio = INC_SULFILSES_MAPPING_RATIO[4];
- if (!ElementsMapping(a_dMolarSumNoFe, dMappingRadio, pElChemLa, pSulElChem, bLaMapped))
- {
- // something is wrong
- LogErrorTrace(__FILE__, __LINE__, _T("COTSClassifyEng::SulClassify: failed to call ElementsMapping method."));
- return FALSE;
- }
- }
- // mapped both
- if (bCeMapped && bLaMapped)
- {
- strProMappingSulName = INC_SULFILSES_NAMES[3] + STR_CONNECT + INC_SULFILSES_NAMES[4];
- bProMapped = TRUE;
- }
- else if (bCeMapped)
- {
- strProMappingSulName = INC_SULFILSES_NAMES[3];
- bProMapped = TRUE;
- }
- else if (bLaMapped)
- {
- strProMappingSulName = INC_SULFILSES_NAMES[4];
- bProMapped = TRUE;
- }
- }
- break;
- default:
- listChemistriesToAnalysis = a_listElChemsIncNoFe;
- break;
- }
- }
- else
- {
- listChemistriesToAnalysis = a_listElChemsIncNoFe;
- }
- // set sulfide base name
- CString strSulfideBaseName = _T("");
- if (bMnMapped && bProMapped)
- {
- // both Mn and process mapped
- strSulfideBaseName = INC_SULFILSES_NAMES[0] + strProMappingSulName;
- }
- else if (bMnMapped)
- {
- // Mn mapped only
- strSulfideBaseName = INC_SULFILSES_NAMES[0];
- }
- else if (bProMapped)
- {
- // process mapped only
- strSulfideBaseName = strProMappingSulName;
- }
- else
- {
- // mapped nothing
- // force sulfide base name as "Sulfide" if sulfur 100% molar value over cutting off value
- if (dSulMolar100 > SULFIDE_MOLAR_CUTOFF)
- {
- strSulfideBaseName = SULFIDE_STR;
- }
- else
- {
- // no enough sulfur, consider that it is not a sulfide
- return TRUE;
- }
- }
- // check if the rest element chemistries map an oxide
- int nIncId = (int)OTS_PARTICLE_TYPE::INVALID;
- if (!OxideClassify(listChemistriesToAnalysis, a_dMolarSumNoFe, nIncId))
- {
- // something wrong
- LogErrorTrace(__FILE__, __LINE__, _T("COTSClassifyEng::SulClassify: failed to call OxideClassify method."));
- return FALSE;
- }
- // mapped?
- if (nIncId >= (int)OTS_PARTICLE_TYPE::IDENTIFIED)
- {
- // this is an oxide sulfide
- // confirm the oxide sulfide id
- // get the STD item of the mapped oxide
- CSTDItemPtr pOxideSTDItem = pPartSTDData->GetSTDItemById(nIncId);
- if (pOxideSTDItem)
- {
- // get mapped oxide name
- CString strOxideName = pOxideSTDItem->GetName();
- // oxide sulfide name: oxide + "-" + sulfide base string
- CString strOxide_SulName = strOxideName + STR_CONNECT + strSulfideBaseName;
- // try to find the STD item
- CSTDItemPtr pOxideSulSTDItem = GetSTDItemByName(listSulfideSTD, strOxide_SulName);
- if (pOxideSulSTDItem)
- {
- // found the STD item
- a_nIncId = pOxideSulSTDItem->GetSTDId();
- return TRUE;
- }
- // rename the oxide sulfide name as "Oxide" + "-" + sulfide base string
- strOxide_SulName = OXIDE_STR + STR_CONNECT + strSulfideBaseName;
- // try to find the STD item
- pOxideSulSTDItem = GetSTDItemByName(listSulfideSTD, strOxide_SulName);
- if (pOxideSulSTDItem)
- {
- // found the STD item
- a_nIncId = pOxideSulSTDItem->GetSTDId();
- return TRUE;
- }
- // rename the oxide sulfide name as strOxideName + "-" + "Sulfide"
- strOxide_SulName = strOxideName + STR_CONNECT + SULFIDE_STR;
- // try to find the STD item
- pOxideSulSTDItem = GetSTDItemByName(listSulfideSTD, strOxide_SulName);
- if (pOxideSulSTDItem)
- {
- // found the STD item
- a_nIncId = pOxideSulSTDItem->GetSTDId();
- return TRUE;
- }
- // rename the oxide sulfide name as "Oxide" + "-" + "Sulfide"
- strOxide_SulName = OXIDE_STR + STR_CONNECT + SULFIDE_STR;
- // try to find the STD item
- pOxideSulSTDItem = GetSTDItemByName(listSulfideSTD, strOxide_SulName);
- if (pOxideSulSTDItem)
- {
- // found the STD item
- a_nIncId = pOxideSulSTDItem->GetSTDId();
- return TRUE;
- }
- // rename the oxide sulfide name as "Sulfide"
- strOxide_SulName = SULFIDE_STR;
- // try to find the STD item
- pOxideSulSTDItem = GetSTDItemByName(listSulfideSTD, strOxide_SulName);
- if (pOxideSulSTDItem)
- {
- // found the STD item
- a_nIncId = pOxideSulSTDItem->GetSTDId();
- return TRUE;
- }
- }
- // can't identify this inclusion
- a_nIncId = (int)OTS_PARTICLE_TYPE::NOT_IDENTIFIED;
- return TRUE;
- }
- // this is a general sulfide
- // confirm the sulfide id
- // try to find the STD item
- CSTDItemPtr pSulSTDItem = GetSTDItemByName(listSulfideSTD, strSulfideBaseName);
- if (pSulSTDItem)
- {
- // found the STD item
- a_nIncId = pSulSTDItem->GetSTDId();
- return TRUE;
- }
- // rename the sulfides name as "Sulfide" if it is not
- if (strSulfideBaseName.CompareNoCase(SULFIDE_STR) != 0)
- {
- strSulfideBaseName = SULFIDE_STR;
- pSulSTDItem = GetSTDItemByName(listSulfideSTD, strSulfideBaseName);
- if (pSulSTDItem)
- {
- // found the STD item
- a_nIncId = pSulSTDItem->GetSTDId();
- return TRUE;
- }
- }
- // can't identify this inclusion
- a_nIncId = (int)OTS_PARTICLE_TYPE::NOT_IDENTIFIED;
- return TRUE;
- }
- // oxides classification
- BOOL COTSClassifyEng::OxideClassify(
- CElementChemistriesList& a_listElChemsIncNoFe,
- double a_dMolarSumNoFe,
- int& a_nIncId)
- {
-
- // check if element chemistries list contain any oxygen
- CElementChemistryPtr pOElChem = GetNamedElementChemistry(a_listElChemsIncNoFe, STR_OXIDE);
- if (!pOElChem)
- {
- // contains no oxygen, this is not an oxide
- return TRUE;
- }
- // check if oxygen amount enough
- double dOMolar100 = Cal100NorValue(pOElChem->GetMolarPercentage(), a_dMolarSumNoFe);
- if (dOMolar100 < MIN_OXIDE_MOLAR)
- {
- // no enough oxygen, this is not an oxide
- return TRUE;
- }
- // this is an oxide
- // any oxide STD items
- if (listOxideSTD.empty())
- {
- // no oxide STD items, can't identify oxide
- // can't identify this inclusion
- a_nIncId = (int)OTS_PARTICLE_TYPE::NOT_IDENTIFIED;
- return TRUE;
- }
- // build oxide sub elements list
- // =========================================
- // get all possible oxide sub element chemistries
- CElementChemistriesList listTempOxideSubElChems;
- double dTempOxideSubElMolarSum = 0;
- for (int i = 0; i < INC_OXIDE_SUB_ELEMENT_MAX; ++i)
- {
- // try to get the oxide sub element
- CElementChemistryPtr pSubElChem = GetNamedElementChemistry(a_listElChemsIncNoFe, INC_OXIDE_SUB_ELEMENT_NAMES[i]);
- // found it?
- if (pSubElChem)
- {
- // got one
- // get the %molar value of the sub element chemistries
- double dSubElMolar = pSubElChem->GetMolarPercentage();
- // add the sub element chemistries into the oxides element chemistries list
- listTempOxideSubElChems.push_back(pSubElChem);
- dTempOxideSubElMolarSum += dSubElMolar;
- }
- }
- // clear oxide sub element chemistries list
- CElementChemistriesList listOxideSubElChems;
- double dOxideSubElMolarSum = 0;
- for (auto pElChem : listTempOxideSubElChems)
- {
- // get the %molar value of the sub element chemistries
- double dSubElMolar = pElChem->GetMolarPercentage();
- // the %molar value of the sub element chemistries of the sub element chemistries list
- double dSubElMolarMolar100 = Cal100NorValue(dSubElMolar, dTempOxideSubElMolarSum);
- // remove the sub element chemistries less than the cut off (2%)
- if (dSubElMolarMolar100 > MIN_OXIDE_SUB_MOLAR_CUTOFF)
- {
- // keep it
- listOxideSubElChems.push_back(pElChem);
- dOxideSubElMolarSum += dSubElMolar;
- }
- }
- // =========================================
- // check oxide elements list
- CString strOxideName = _T("");
- CString aluminateStr=_T("");
- if (listOxideSubElChems.empty())
- {
- // no oxide sub elements
- // consider this is not a oxide (may be it just is a dust)
- return TRUE;
- }
- // is a simple oxide?
- else if(IsASimpleOxide(listOxideSubElChems, dOxideSubElMolarSum, strOxideName))
- {
- // this is a simple oxide
- // named already during checking
- }
-
- // is it a REOxide (La-Ce-Oxide)?
- else if (IsAREOxide(listOxideSubElChems, dOxideSubElMolarSum))
- {
- // REOxcide
- strOxideName = REOXIDE_STR;
- }
- // should be a complex oxide
- // is it a REAlOxide?
- else if (IsAnREAlOxide(listOxideSubElChems, dOxideSubElMolarSum))
- {
- // REOxcide
- strOxideName = REALOXIDE_STR;
- }
- // is it a Spinel?
- else if (IsASpinel(listOxideSubElChems, dOxideSubElMolarSum))
- {
- // Spinel
- strOxideName = SPINEL_STR;
- }
- // is it a Silicate?
- else if (IsASilicate(listOxideSubElChems, dOxideSubElMolarSum))
- {
- // Silicate
- strOxideName = SILICATE_STR;
- }
- // is it an Aluminate?
-
- else if (IsAnCa_Aluminate(listOxideSubElChems, dOxideSubElMolarSum, aluminateStr))
- {
- // Aluminate
- strOxideName = aluminateStr;
- }
- // fit none of them, simply name it as an oxide
- else
- {
- strOxideName = OXIDE_STR;
- }
- // confirm the oxide id
- // try to find the STD
- auto pSTDItem = GetSTDItemByName(listOxideSTD, strOxideName);
- if (pSTDItem)
- {
- // found the STD item
- a_nIncId = pSTDItem->GetSTDId();
- return TRUE;
- }
- // rename the oxide as "Oxide" if it is not
- if (strOxideName.CompareNoCase(OXIDE_STR) != 0)
- {
- strOxideName = OXIDE_STR;
- auto pSTDItem = GetSTDItemByName(listOxideSTD, strOxideName);
- if (pSTDItem)
- {
- // found the STD item
- a_nIncId = pSTDItem->GetSTDId();
- return TRUE;
- }
- }
- // can't identify this inclusion
- a_nIncId = (int)OTS_PARTICLE_TYPE::NOT_IDENTIFIED;
- return TRUE;
- }
- // nitrides classification
- BOOL COTSClassifyEng::NitrideClassify(
- CElementChemistriesList& a_listElChemsIncNoFe,
- double a_dMolarSumNoFe,
- int& a_nIncId)
- {
-
- // check if element chemistries list contain any nitrogen
- CElementChemistryPtr pNitrElChem = GetNamedElementChemistry(a_listElChemsIncNoFe, STR_NITR);
- if (!pNitrElChem)
- {
- // contains no nitrogen, this is not a nitride
- return TRUE;
- }
- // check if nitrogen amount enough
- double dNitrMolar100 = Cal100NorValue(pNitrElChem->GetMolarPercentage(), a_dMolarSumNoFe);
- if (dNitrMolar100 < MIN_NITR_MOLAR)
- {
- // have no enough nitrogen, this is not a nitride
- return TRUE;
- }
- // this is a nitride
- // any nitride STD items
- if (listNitrideSTD.empty())
- {
- // no nitrides std items.
- // can't identify this inclusion
- a_nIncId = (int)OTS_PARTICLE_TYPE::NOT_IDENTIFIED;
- return TRUE;
- }
- // mapping nitride sub elements
- CString strNitrideName = _T("");
- BOOL bMapped = FALSE;
- for (int i = 0; i < INC_NITR_SUB_ELEMENT_MAX; ++i)
- {
- CElementChemistryPtr pNitrSubElChem = GetNamedElementChemistry(a_listElChemsIncNoFe, INC_NITR_SUB_ELEMENT_NAMES[i]);
- if (pNitrSubElChem)
- {
- // this is a nitride sub element chemistry
- // get %molar value of this sub element chemistry
- double dNitr_Sub_Molar = Cal100NorValue(pNitrSubElChem->GetMolarPercentage(), a_dMolarSumNoFe);
- // make sure the sub element molar value is over mapping min value
- if (dNitr_Sub_Molar > MIN_NITR_SUB_MOLAR)
- {
- // mapping this sub element chemistry
- double dMappingRadio = INC_NITR_MAPPING_RATIO[i];
- if (!ElementsMapping(a_dMolarSumNoFe, dMappingRadio, pNitrSubElChem, pNitrElChem, bMapped))
- {
- // something is wrong
- LogErrorTrace(__FILE__, __LINE__, _T("COTSClassifyEng::NitrideClassify: failed to call ElementsMapping method."));
- return FALSE;
- }
- // mapping succeed?
- if(bMapped)
- {
- // is mapped Ti?
- if (i == 0)
- {
- // the first mapped nitride is "TiN"
- // try to map Nb
- BOOL bNbMapped = FALSE;
- // get molar % of the rest nitrogen
- dNitrMolar100 = Cal100NorValue(pNitrElChem->GetMolarPercentage(), a_dMolarSumNoFe);
- // make sure nitrogen amount is enough
- if (dNitrMolar100 > MIN_NITR_MOLAR)
- {
- // get element "Nb"
- CElementChemistryPtr pElChemNb = GetNamedElementChemistry(a_listElChemsIncNoFe, STR_Nb);
- // is there Nb in the list
- if (pElChemNb)
- {
- // get %molar value of Nb
- double dNb_Molar = Cal100NorValue(pElChemNb->GetMolarPercentage(), a_dMolarSumNoFe);
-
- // make sure Nb molar value is over mapping min value
- double dNbMappingRadio = INC_NITR_MAPPING_RATIO[2];
- if (dNb_Molar > MIN_NITR_SUB_MOLAR)
- {
- if (!ElementsMapping(a_dMolarSumNoFe, dNbMappingRadio, pElChemNb, pNitrElChem, bNbMapped))
- {
- // something is wrong
- LogErrorTrace(__FILE__, __LINE__, _T("COTSClassifyEng::NitrideClassify: failed to call ElementsMapping method."));
- return FALSE;
- }
- }
- }
- }
- // mapped "Nb"
- if (bNbMapped)
- {
- // nitride name is "TiN-NbN"
- strNitrideName = INC_NITR_NAMES[0] + STR_CONNECT + INC_NITR_NAMES[2];
- }
- else
- {
- // nitride name is "TiN"
- strNitrideName = INC_NITR_NAMES[0];
- }
- }
- else
- {
- // get the nitride name
- strNitrideName = INC_NITR_NAMES[i];
- }
- // completed mapping, get out the loop
- break;
- }
- }
- }
- }
- // not mapped?
- if (!bMapped)
- {
- // force to name it as "Nitride" if N 100% molar value over cutting off value
- if (dNitrMolar100 > NITRIDE_MOLAR_CUTOFF)
- {
- strNitrideName = NITRIDE_STR;
- }
- else
- {
- // no enough nitride, consider that it is not a nitride
- return TRUE;
- }
- }
- // check if the rest element chemistries map an oxide
- int nIncId = (int)OTS_PARTICLE_TYPE::INVALID;
- if (!OxideClassify( a_listElChemsIncNoFe, a_dMolarSumNoFe, nIncId))
- {
- // something wrong
- LogErrorTrace(__FILE__, __LINE__, _T("COTSClassifyEng::NitrideClassify: failed to call OxideClassify method."));
- return FALSE;
- }
- // mapped?
- if (nIncId >= (int)OTS_PARTICLE_TYPE::IDENTIFIED)
- {
- // this is an oxide nitride
- // confirm the oxide nitride id
- // get the STD item of the mapped oxide
- CSTDItemPtr pOxideSTDItem = pPartSTDData->GetSTDItemById(nIncId);
- if (pOxideSTDItem)
- {
- // get mapped oxide name
- CString strOxideName = pOxideSTDItem->GetName();
- // oxide nitride name: oxide + "-" + nitride base string
- CString strOxide_NitrName = strOxideName + STR_CONNECT + strNitrideName;
- // try to find the STD item
- CSTDItemPtr pOxideNitrSTDItem = GetSTDItemByName(listNitrideSTD, strOxide_NitrName);
- if (pOxideNitrSTDItem)
- {
- // found the STD item
- a_nIncId = pOxideNitrSTDItem->GetSTDId();
- return TRUE;
- }
- // can't find the STD item
- // rename the oxide nitride name as "Oxide" + "-" + nitride base string
- strOxide_NitrName = OXIDE_STR + STR_CONNECT + strOxide_NitrName;
- // try to find the STD item
- pOxideNitrSTDItem = GetSTDItemByName(listNitrideSTD, strOxide_NitrName);
- if (pOxideNitrSTDItem)
- {
- // found the STD item
- a_nIncId = pOxideNitrSTDItem->GetSTDId();
- return TRUE;
- }
- // rename the oxide nitride name as strOxideName + "-" + "Nitride"
- strOxide_NitrName = strOxideName + STR_CONNECT + NITRIDE_STR;
- // try to find the STD item
- pOxideNitrSTDItem = GetSTDItemByName(listNitrideSTD, strOxide_NitrName);
- if (pOxideNitrSTDItem)
- {
- // found the STD item
- a_nIncId = pOxideNitrSTDItem->GetSTDId();
- return TRUE;
- }
- // rename the oxide nitride name as "Oxide" + "-" + "Nitride"
- strOxide_NitrName = OXIDE_STR + STR_CONNECT + NITRIDE_STR;
- // try to find the STD item
- pOxideNitrSTDItem = GetSTDItemByName(listNitrideSTD, strOxide_NitrName);
- if (pOxideNitrSTDItem)
- {
- // found the STD item
- a_nIncId = pOxideNitrSTDItem->GetSTDId();
- return TRUE;
- }
- // rename the oxide nitride name as "Nitride"
- strOxide_NitrName = NITRIDE_STR;
- // try to find the STD item
- pOxideNitrSTDItem = GetSTDItemByName(listNitrideSTD, strOxide_NitrName);
- if (pOxideNitrSTDItem)
- {
- // found the STD item
- a_nIncId = pOxideSTDItem->GetSTDId();
- return TRUE;
- }
- }
- // can't identify this inclusion
- a_nIncId = (int)OTS_PARTICLE_TYPE::NOT_IDENTIFIED;
- return TRUE;
- }
- // confirm the nitride id
- // try to find the STD
- auto pSTDItem = GetSTDItemByName(listNitrideSTD, strNitrideName);
- if (pSTDItem)
- {
- // found the STD item
- a_nIncId = pSTDItem->GetSTDId();
- return TRUE;
- }
- // rename the nitride as "Nitride" if it is not
- if (strNitrideName.CompareNoCase(NITRIDE_STR) != 0)
- {
- strNitrideName = NITRIDE_STR;
- auto pSTDItem = GetSTDItemByName(listNitrideSTD, strNitrideName);
- if (pSTDItem)
- {
- // found the STD item
- a_nIncId = pSTDItem->GetSTDId();
- return TRUE;
- }
- }
- // can't identify this inclusion
- a_nIncId = (int)OTS_PARTICLE_TYPE::NOT_IDENTIFIED;
- return TRUE;
- }
- // nitrides classification
- BOOL COTSClassifyEng::CarbonClassify(
- CElementChemistriesList& a_listElChemsIncNoFe,
- double a_dMolarSumNoFe,
- int& a_nIncId)
- {
-
- // check if element chemistries list contain any nitrogen
- CElementChemistryPtr pCarElChem = GetNamedElementChemistry(a_listElChemsIncNoFe, STR_CAR);
- if (!pCarElChem)
- {
- // contains no nitrogen, this is not a nitride
- return TRUE;
- }
- // check if nitrogen amount enough
- double dCarMolar100 = Cal100NorValue(pCarElChem->GetMolarPercentage(), a_dMolarSumNoFe);
- if (dCarMolar100 < MIN_CAR_MOLAR)
- {
- // have no enough nitrogen, this is not a nitride
- return TRUE;
- }
- // this is a carbon
- // any carbon STD items
- if (listCarbonSTD.empty())
- {
- // no nitrides std items.
- // can't identify this inclusion
- a_nIncId = (int)OTS_PARTICLE_TYPE::NOT_IDENTIFIED;
- return TRUE;
- }
- // mapping carbon sub elements
- CString strCarbonName = _T("");
- BOOL bMapped = FALSE;
- for (int i = 0; i < INC_CAR_SUB_ELEMENT_MAX; ++i)
- {
- CElementChemistryPtr pCarSubElChem = GetNamedElementChemistry(a_listElChemsIncNoFe, INC_CAR_SUB_ELEMENT_NAMES[i]);
- if (pCarSubElChem)
- {
- // this is a nitride sub element chemistry
- // get %molar value of this sub element chemistry
- double dCar_Sub_Molar = Cal100NorValue(pCarSubElChem->GetMolarPercentage(), a_dMolarSumNoFe);
- // make sure the sub element molar value is over mapping min value
- if (dCar_Sub_Molar > MIN_CAR_SUB_MOLAR)
- {
- // try to map Nb
- BOOL bNbMapped = FALSE;
- // get molar % of the rest nitrogen
- dCarMolar100 = Cal100NorValue(pCarElChem->GetMolarPercentage(), a_dMolarSumNoFe);
- // make sure nitrogen amount is enough
- if (dCarMolar100 > MIN_CAR_MOLAR)
- {
- // get element "Nb"
- CElementChemistryPtr pElChemNb = GetNamedElementChemistry(a_listElChemsIncNoFe, STR_Nb);
- // is there Nb in the list
- if (pElChemNb)
- {
- // get %molar value of Nb
- double dNb_Molar = Cal100NorValue(pElChemNb->GetMolarPercentage(), a_dMolarSumNoFe);
- // make sure Nb molar value is over mapping min value
- double dNbMappingRatio = INC_NITR_MAPPING_RATIO[2];
- if (dNb_Molar > MIN_CAR_SUB_MOLAR)
- {
- if (!ElementsMapping(a_dMolarSumNoFe, dNbMappingRatio, pElChemNb, pCarElChem, bNbMapped))
- {
- // something is wrong
- LogErrorTrace(__FILE__, __LINE__, _T("CClassifyEng::NitrideClassify: failed to call ElementsMapping method."));
- return FALSE;
- }
- }
- }
- }
- // mapped "Nb"
- if (bNbMapped)
- {
- // carbon name is "NbC"
- strCarbonName = INC_CAR_NAMES[0];
- }
- // completed mapping, get out the loop
- break;
- }
- }
- }
- // mapped?
- if (a_nIncId >= (int)OTS_PARTICLE_TYPE::IDENTIFIED)
- {
- // this is an oxide nitride
- // confirm the oxide nitride id
- CSTDItemPtr pCarSTDItem = GetSTDItemByName(listCarbonSTD, strCarbonName);
- // get the STD item of the mapped oxide
- if (pCarSTDItem)
- {
- // found the STD item
- a_nIncId = pCarSTDItem->GetSTDId();
- return TRUE;
- }
- // can't identify this inclusion
- a_nIncId = (int)OTS_PARTICLE_TYPE::NOT_IDENTIFIED;
- return TRUE;
- }
- // confirm the carben id
- // try to find the STD
- auto pSTDItem = GetSTDItemByName(listCarbonSTD, strCarbonName);
- if (pSTDItem)
- {
- // found the STD item
- a_nIncId = pSTDItem->GetSTDId();
- return TRUE;
- }
- // rename the Carbon as "Carbon" if it is not
- if (strCarbonName.CompareNoCase(CARBON_STR) != 0)
- {
- strCarbonName = NITRIDE_STR;
- auto pSTDItem = GetSTDItemByName(listCarbonSTD, strCarbonName);
- if (pSTDItem)
- {
- // found the STD item
- a_nIncId = pSTDItem->GetSTDId();
- return TRUE;
- }
- }
- // can't identify this inclusion
- a_nIncId = (int)OTS_PARTICLE_TYPE::NOT_IDENTIFIED;
- return TRUE;
- }
- //// user STD items classification
- //BOOL COTSClassifyEng::UserClassify(
- // CElementChemistriesList& a_listEltChemsInc,
- // double dSum,
- // int& a_nIncId)
- //{
- //
- //
- // // try to identify the oxide
- // for (auto pUserSTD : listUserSTD)
- // {
- // // matching STD?
- // if (MatchingSTD(a_listEltChemsInc, pUserSTD, dSum))
- // {
- // // found matching STD
- // a_nIncId = pUserSTD->GetSTDId();
- // return TRUE;
- // }
- // }
- // // can't identify this inclusion
- // a_nIncId = (int)OTS_PARTICLE_TYPE::NOT_IDENTIFIED;
- // return TRUE;
- //}
- // nominate element chemistries list
- BOOL COTSClassifyEng::NomiNateElChemsList( CElementChemistriesList& a_listElChemsInc,
- CElementChemistriesList& a_listNomiElChemsInc)
- {
- // return FALSE if nothing in the input list
- if (a_listElChemsInc.empty())
- {
- LogErrorTrace(__FILE__, __LINE__, _T("COTSClassifyEng::NomiNateElChemsList: invalid inclusion x-ray data."));
- return FALSE;
- }
- // initialize outputs
- a_listNomiElChemsInc.clear();
- // go thought all element chemistry objects of the input lit
- double dWeightPerSum = 0;
- for (auto pElChem : a_listElChemsInc)
- {
- // create a new element chemistry
- CElementChemistryPtr pElChemNew = CElementChemistryPtr(new CElementChemistry(*pElChem.get()));
- // key element?
- if (IsKeyElement(pElChem))
- {
- // this is a key element
- // cal weight percentage sum
- dWeightPerSum += pElChem->GetPercentage();
- // add the element into the output list
- a_listNomiElChemsInc.push_back(pElChemNew);
- }
- // sub element?
- else if (IsSubElement(pElChem))
- {
- // this is a sub element
- // Fe?
- if (pElChem->GetName().CompareNoCase("Fe") != 0)
- {
- // cal weight percentage sum
- dWeightPerSum += pElChem->GetPercentage();
- // add the element into the output list
- a_listNomiElChemsInc.push_back(pElChemNew);
- }
- }
- }
- // return FALSE if nothing in the input list or sum less than cut off value
- if (a_listNomiElChemsInc.empty() || dWeightPerSum < INC_SUB_ELEMENT_CUT_OFF)
- {
- // something wrong
- LogErrorTrace(__FILE__, __LINE__, _T("COTSClassifyEng::NomiNateElChemsList: invalid inclusion x-ray data."));
- return FALSE;
- }
- // go thought all element chemistry objects of the output lit
- for (auto pElChem : a_listNomiElChemsInc)
- {
- // reset weight % value
- // get weight % value
- double dWeightPer = pElChem->GetPercentage();
- // calculate new weight % value
- double dWeightPerNew = Cal100NorValue(dWeightPer, dWeightPerSum);
- // reset
- pElChem->SetPercentage(dWeightPerNew);
- }
- // ok, return TRUE
- return TRUE;
- }
- // protected
- // check if this is a key element
- BOOL COTSClassifyEng::IsKeyElement(CElementChemistryPtr a_pElChem)
- {
- // safety check
- ASSERT(a_pElChem);
- if (!a_pElChem)
- {
- // something wrong
- LogErrorTrace(__FILE__, __LINE__, _T("COTSClassifyEng::IsKeyElement: invalid CElementChemistryPtr."));
- return FALSE;
- }
- // go thought all key element
- for (long i = 0; i < INC_KEY_ELEMENT_MAX; ++i)
- {
- // compare
- if ((a_pElChem->GetName().CompareNoCase(INC_KEY_ELEMENT_NAMES[i]) == 0) && (a_pElChem->GetPercentage() >= INC_KEY_ELEMENT_CUT_OFF))
- {
- // this is a key element, return TRUE
- return TRUE;
- }
- }
- // this is not a key element, return FALSE
- return FALSE;
- }
- // check if this is a sub element
- BOOL COTSClassifyEng::IsSubElement(CElementChemistryPtr a_pElChem)
- {
- // safety check
- ASSERT(a_pElChem);
- if (!a_pElChem)
- {
- // something wrong
- LogErrorTrace(__FILE__, __LINE__, _T("COTSClassifyEng::IsSubElement: invalid CElementChemistryPtr."));
- return FALSE;
- }
- // go thought all sub element
- for (long i = 0; i < INC_SUB_ELEMENT_MAX; ++i)
- {
- // compare
- if ((a_pElChem->GetName().CompareNoCase(INC_SUB_ELEMENT_NAMES[i]) == 0) && (a_pElChem->GetPercentage() >= INC_SUB_ELEMENT_CUT_OFF))
- {
- // this is a key element, return TRUE
- return TRUE;
- }
- }
- // this is not a key element, return FALSE
- return FALSE;
- }
- // get named element chemistry
- CElementChemistryPtr COTSClassifyEng::GetNamedElementChemistry(CElementChemistriesList & a_listChemistriesElements, const CString a_strElementName)
- {
- CElementChemistryPtr pElChem = nullptr;
- CString strName = a_strElementName;
- auto itr = std::find_if(a_listChemistriesElements.begin(), a_listChemistriesElements.end(), [strName](CElementChemistryPtr& poElementChemistry) { return poElementChemistry->GetName().CompareNoCase(strName) == 0; });
- if (itr != a_listChemistriesElements.end())
- {
- pElChem = *itr;
- }
- return pElChem;
- }
- bool SortBySTDID(const std::shared_ptr< CSTDItem> &v1, const std::shared_ptr< CSTDItem> &v2)
- {
- return v1->GetSTDId() < v2->GetSTDId();
- }
- // get classify STD items
- BOOL COTSClassifyEng::GetClassifySTDItem(CInclutionSTDDataPtr a_pPartSTDDataPtr, INC_CLASSIFY_TYPE a_nClassifyType, CSTDItemsList& a_listSTDItems)
- {
-
- // cal STD item id value range
- OTS_STD_ITEM_VALUE nSTDIdRangeMin = OTS_STD_ITEM_VALUE::INVALID;
- OTS_STD_ITEM_VALUE nSTDIdRangeMax = OTS_STD_ITEM_VALUE::INVALID;
- switch (a_nClassifyType)
- {
- case INC_CLASSIFY_TYPE::SIMPLE_OXIDE:
- {
- nSTDIdRangeMin = OTS_STD_ITEM_VALUE::SYS_SIMPLE_OXIDE_MIN;
- nSTDIdRangeMax = OTS_STD_ITEM_VALUE::SYS_SIMPLE_OXIDE_MAX;
- }
- break;
- case INC_CLASSIFY_TYPE::COMPLEX_OXIDE:
- {
- nSTDIdRangeMin = OTS_STD_ITEM_VALUE::SYS_COMPLEX_OXIDE_MIN;
- nSTDIdRangeMax = OTS_STD_ITEM_VALUE::SYS_COMPLEX_OXIDE_MAX;
- }
- break;
- case INC_CLASSIFY_TYPE::OXIDE:
- {
- nSTDIdRangeMin = OTS_STD_ITEM_VALUE::SYS_OXIDE_MIN;
- nSTDIdRangeMax = OTS_STD_ITEM_VALUE::SYS_OXIDE_MAX;
- }
- break;
- case INC_CLASSIFY_TYPE::SUL:
- {
- nSTDIdRangeMin = OTS_STD_ITEM_VALUE::SYS_SUL_MIN;
- nSTDIdRangeMax = OTS_STD_ITEM_VALUE::SYS_SUL_MAX;
- }
- break;
- case INC_CLASSIFY_TYPE::NITR:
- {
- nSTDIdRangeMin = OTS_STD_ITEM_VALUE::SYS_NITRIDE_MIN;
- nSTDIdRangeMax = OTS_STD_ITEM_VALUE::SYS_NITRIDE_MAX;
- }
- break;
- case INC_CLASSIFY_TYPE::CARBON:
- {
- nSTDIdRangeMin = OTS_STD_ITEM_VALUE::SYS_CARBON_MIN;
- nSTDIdRangeMax = OTS_STD_ITEM_VALUE::SYS_CARBON_MAX;
- }
- break;
- case INC_CLASSIFY_TYPE::USER:
- {
- nSTDIdRangeMin = OTS_STD_ITEM_VALUE::USER_MIN;
- nSTDIdRangeMax = OTS_STD_ITEM_VALUE::USER_MAX;
- }
- break;
- default:
- {
- // wrong classify type value, return FALSE
- return FALSE;
- }
- break;
- }
- // go through all STD items
- a_listSTDItems.clear();
- for (auto pSTDItem : a_pPartSTDDataPtr->GetSTDItemsList())
- {
- // is matching STD item?
- if (pSTDItem->GetSTDId() >= (int)nSTDIdRangeMin && pSTDItem->GetSTDId() <= (int)nSTDIdRangeMax)
- {
- // get matching STD item
- a_listSTDItems.push_back(pSTDItem);
- }
- }
- // sort std item by std id
- sort(a_listSTDItems.begin(), a_listSTDItems.end(), SortBySTDID);
- // ok, return TRUE
- return TRUE;
- }
- // get STD item by name
- CSTDItemPtr COTSClassifyEng::GetSTDItemByName(CSTDItemsList& a_listSTDItems, CString a_strName)
- {
- CSTDItemPtr pSTDItem = nullptr;
- auto itr = std::find_if(a_listSTDItems.begin(), a_listSTDItems.end(), [a_strName](CSTDItemPtr& pSTD) { return pSTD->GetName().CompareNoCase(a_strName) == 0; });
- if (itr != a_listSTDItems.end())
- {
- // found the STD item
- pSTDItem = *itr;
- }
- return pSTDItem;
- }
- // get STD item name by id
- CString COTSClassifyEng::GetSTDItemNameById(CSTDItemsList& a_listSTDItems, int a_nItemId)
- {
- CString strName = _T("");
- CSTDItemPtr pSTDItem = nullptr;
- auto itr = std::find_if(a_listSTDItems.begin(), a_listSTDItems.end(), [a_nItemId](CSTDItemPtr& pSTD) { return pSTD->GetSTDId() == a_nItemId; });
- if (itr != a_listSTDItems.end())
- {
- // found the STD item
- pSTDItem = *itr;
- strName = pSTDItem->GetName();
- }
- return strName;
- }
- // elements mapping
- BOOL COTSClassifyEng::ElementsMapping(double a_dMolarSumNoFe,
- double a_dMappingRatio,
- CElementChemistryPtr a_pFirstElChem,
- CElementChemistryPtr a_pSecondElChem,
- BOOL& a_bMapped)
- {
- // safety check
- ASSERT(a_pFirstElChem);
- if (!a_pFirstElChem)
- {
- // something wrong
- LogErrorTrace(__FILE__, __LINE__, _T("COTSClassifyEng::ElementsMapping: invalid a_pFirstElChem."));
- return FALSE;
- }
- ASSERT(a_pSecondElChem);
- if (!a_pSecondElChem)
- {
- // something wrong
- LogErrorTrace(__FILE__, __LINE__, _T("COTSClassifyEng::ElementsMapping: invalid a_pSecondElChem."));
- return FALSE;
- }
- if (a_dMolarSumNoFe < MIN_ELEMENT_SUM)
- {
- // something wrong
- LogErrorTrace(__FILE__, __LINE__, _T("COTSClassifyEng::ElementsMapping: invalid molar sum value."));
- return FALSE;
- }
- if (a_dMappingRatio < MIN_DOUBLE_VALUE)
- {
- // something wrong
- LogErrorTrace(__FILE__, __LINE__, _T("COTSClassifyEng::ElementsMapping: invalid mapping radio value."));
- return FALSE;
- }
- // set mapped flag to FALSE as default
- a_bMapped = FALSE;
- // get first mapping element molar value
- double dFirstMolar = a_pFirstElChem->GetMolarPercentage();
- // make sure molar value of the first mapping element chemistry is enough
- double dFirstMolar100 = Cal100NorValue(dFirstMolar, a_dMolarSumNoFe);
- if (dFirstMolar100 > ELEMENT_MAPPING_100MOLAR)
- {
- // get second mapping element chemistry molar value
- double dSecondElMolar = a_pSecondElChem->GetMolarPercentage();
- // make sure second mapping element chemistry value is enough
- double dSecondElMolar100 = Cal100NorValue(dSecondElMolar, a_dMolarSumNoFe);
- if (dSecondElMolar100 > ELEMENT_MAPPING_100MOLAR)
- {
- // set mapped flag to true
- a_bMapped = TRUE;
- // reset mapping element chemistry molar values
- // is there any first element left?
- if (dFirstMolar - dSecondElMolar * a_dMappingRatio > 0)
- {
- // no more second element chemistry left;
- a_pSecondElChem->SetPercentage(0.0);
- // still there are some first element left
- // calculate left first element molar value
- dFirstMolar = dFirstMolar - (dSecondElMolar * a_dMappingRatio);
- dFirstMolar100 = Cal100NorValue(dFirstMolar100, a_dMolarSumNoFe);
- // is there enough first element left?
- if (dFirstMolar100 > ELEMENT_MAPPING_100MOLAR)
- {
- // still have enough first element left
- a_pFirstElChem->SetMolarPercentage(dFirstMolar);
- }
- else
- {
- // no enough enough first element left, set to 0.0
- a_pFirstElChem->SetPercentage(0.0);
- }
- }
- else
- {
- // no more first element chemistry left
- a_pFirstElChem->SetPercentage(0.0);
- // still there are some second element left
- // calculate left second element molar value
- dSecondElMolar = dSecondElMolar - dFirstMolar / a_dMappingRatio;
- dSecondElMolar100 = Cal100NorValue(dSecondElMolar, a_dMolarSumNoFe);
- // is there enough second element left?
- if (dSecondElMolar100 > ELEMENT_MAPPING_100MOLAR)
- {
- // still have enough second element left
- a_pSecondElChem->SetMolarPercentage(dSecondElMolar);
- }
- else
- {
- // no enough enough second element left, set to 0.0
- a_pSecondElChem->SetPercentage(0.0);
- }
- }
- }
- }
- // ok, return TRUE
- return TRUE;
- }
- // check if is a REOxide
- BOOL COTSClassifyEng::IsASimpleOxide(CElementChemistriesList& a_listElChems, double a_dMolarSum, CString& a_strSimOxName)
- {
- // go through oxide sub element chemistries
- for (auto pOxideSubElChems : a_listElChems)
- {
- // calculate the %molar value of the sub element chemistry in the list
- double dSubElMolar100 = Cal100NorValue(pOxideSubElChems->GetMolarPercentage(), a_dMolarSum);
- // over simple oxide cut_off
- if (dSubElMolar100 > SIMPLE_OXIDE_MOLAR_CUTOFF)
- {
- // this is a simple oxide, name it
- for (int i = 0; i < INC_OXIDE_SUB_ELEMENT_MAX; ++i)
- {
- if (pOxideSubElChems->GetName().CompareNoCase(INC_OXIDE_SUB_ELEMENT_NAMES[i]) == 0)
- {
- // found it
- // assign simple oxide name
- a_strSimOxName = INC_OXIDE_NAMES[i];
- // return TRUE
- return TRUE;
- }
- }
- }
- }
- // not a simple oxide, return FALSE
- return FALSE;
- }
- // check if is a REOxide (deal with La-Ce-Oxide)
- BOOL COTSClassifyEng::IsAREOxide(CElementChemistriesList& a_listElChems, double a_dMolarSum)
- {
- // calculate real element molar %
- double dREElementMolarSum = 0;
- for (int i = 0; i < REOXIDE_KEY_ELEMENT_MAX; ++i)
- {
- CElementChemistryPtr pREElement = GetNamedElementChemistry(a_listElChems, REOXIDE_KEY_ELEMENT_NAMES[i]);
- if (pREElement)
- {
- // got a real element
- // calculate the %molar value of the real element chemistry in the list
- double dSubElMolar100 = Cal100NorValue(pREElement->GetMolarPercentage(), a_dMolarSum);
- // calculate real element molar %
- dREElementMolarSum += dSubElMolar100;
- }
- }
- // is real element molar % over REAlOxide elements molar % cut_off
- if (dREElementMolarSum > REALOXIDE_ELEMELTS_MOLAR_CUTOFF)
- {
- // this is a REAlOxide, return TRUE
- return TRUE;
- }
- // not a REOxide, return FALSE
- return FALSE;
- }
- // check if is a REAlOxide
- BOOL COTSClassifyEng::IsAnREAlOxide(CElementChemistriesList& a_listElChems, double a_dMolarSum)
- {
- // calculate real element molar %
- double dREElementMolarSum = 0;
- for (int i = 0; i < REOXIDE_KEY_ELEMENT_MAX; ++i)
- {
- CElementChemistryPtr pREElement = GetNamedElementChemistry(a_listElChems, REOXIDE_KEY_ELEMENT_NAMES[i]);
- if (pREElement)
- {
- // got a real element
- // calculate the %molar value of the real element chemistry in the list
- double dSubElMolar100 = Cal100NorValue(pREElement->GetMolarPercentage(), a_dMolarSum);
- // calculate real element molar %
- dREElementMolarSum += dSubElMolar100;
- }
- }
- // is real element molar % over REAlOxide element molar % min cut_off
- if (dREElementMolarSum < REALOXIDE_ELEMENT_MOLAR_LOW_CUTOFF)
- {
- // no, this is not a REALOxide, return FALSE
- return FALSE;
- }
- // calculate Al/Si elements molar %
- double dAl_Si_ElementMolarSum = 0;
- for (int i = 0; i < REALOXIDE_SUB_ELEMENT_MAX; ++i)
- {
- CElementChemistryPtr pAlSiElement = GetNamedElementChemistry(a_listElChems, REALOXIDE_SUB_ELEMENT_NAMES[i]);
- if (pAlSiElement)
- {
- // got a Al or Si element
- // calculate the %molar value of the Al and Si element chemistry in the list
- double dAl_SiElMolar100 = Cal100NorValue(pAlSiElement->GetMolarPercentage(), a_dMolarSum);
- // calculate Al/Si elements molar %
- dAl_Si_ElementMolarSum += dAl_SiElMolar100;
- }
- }
- // is Al/Si elements molar % over REAlOxide element molar % min cut_off
- if (dAl_Si_ElementMolarSum < REALOXIDE_ELEMENT_MOLAR_LOW_CUTOFF)
- {
- // no, this is not a REALOxide, return FALSE
- return FALSE;
- }
- // is real element molar % + Al/Si elements molar % over the cut off
- if (dREElementMolarSum + dAl_Si_ElementMolarSum > SIMPLE_OXIDE_MOLAR_CUTOFF)
- {
- // this is a REAlOxide, return TRUE
- return TRUE;
- }
- // not a REAlOxide, return FALSE
- return FALSE;
- }
- // check if is a Spinel
- BOOL COTSClassifyEng::IsASpinel(CElementChemistriesList& a_listElChems, double a_dMolarSum)
- {
- // we deal with Mg, Al Spinel only
- // get the first key element of Spinel
- CElementChemistryPtr pFirstElChem = GetNamedElementChemistry(a_listElChems, SPINEL_KEY_ELEMENT_NAMES[0]);
- if (!pFirstElChem)
- {
- // not a Spinel, return FALSE
- return FALSE;
- }
- // get the second key element of Spinel
- CElementChemistryPtr pSecondElChem = GetNamedElementChemistry(a_listElChems, SPINEL_KEY_ELEMENT_NAMES[1]);
- if (!pSecondElChem)
- {
- // not a Spinel, return FALSE
- return FALSE;
- }
- // check ratio between the two elements
- double dFirstElMolar = pFirstElChem->GetMolarPercentage();
- double dSecondElMolar = pSecondElChem->GetMolarPercentage();
- if (dFirstElMolar < MIN_DOUBLE_VALUE)
- {
- // something wrong
- // not a Spinel, return FALSE
- return FALSE;
- }
- double dRatio = dSecondElMolar / dFirstElMolar;
- if (dRatio < SPINEL_ELEMENT_RATIO_MIN || dRatio > SPINEL_ELEMENT_RATIO_MAX)
- {
- // not a Spinel, return FALSE
- return FALSE;
- }
- // molar % amount check
- double dFirstElMolar100 = Cal100NorValue(dFirstElMolar, a_dMolarSum);
- double dSecondElMolar100 = Cal100NorValue(dSecondElMolar, a_dMolarSum);
- if (dFirstElMolar100 + dSecondElMolar100 > SPINEL_KEY_ELEMENT_MOLAR_TOTAL)
- {
- // this is a Spinel
- return TRUE;
- }
-
- // not a Spinel, return FALSE
- return FALSE;
- }
- // check if is a Silicate
- BOOL COTSClassifyEng::IsASilicate(CElementChemistriesList& a_listElChems, double a_dMolarSum)
- {
- // get key element of Silicate
- CElementChemistryPtr pKeyElChem = GetNamedElementChemistry(a_listElChems, SILICATE_KEY_ELEMENT_NAME);
- if (!pKeyElChem)
- {
- // not a Silicate, return FALSE
- return FALSE;
- }
- // molar % amount check
- double dKeyElMolar100 = Cal100NorValue(pKeyElChem->GetMolarPercentage(), a_dMolarSum);
- if (dKeyElMolar100 > SILICATE_KEY_ELEMENT_MOLAR_TOTAL_MIN && dKeyElMolar100 < SILICATE_KEY_ELEMENT_MOLAR_TOTAL_MAX)
- {
- // this is a Silicate, return TRUE
- return TRUE;
- }
- // not a Silicate, return FALSE
- return FALSE;
- }
- // check if is a Aluminate
- BOOL COTSClassifyEng::IsAnCa_Aluminate(CElementChemistriesList& a_listElChems, double a_dMolarSum,CString& strName)
- {
- // get key element of Aluminate
- CElementChemistryPtr pKeyElChem = GetNamedElementChemistry(a_listElChems, ALUMINATE_KEY_ELEMENT_NAME[0]);
- if (!pKeyElChem)
- {
- // not an Aluminate, return FALSE
- return FALSE;
- }
-
- // molar % amount check
- double dKeyElMolar100 = Cal100NorValue(pKeyElChem->GetMolarPercentage(), a_dMolarSum);
- if (dKeyElMolar100 > ALUMINAT_KEY_ELEMENT_MOLAR_TOTAL_MIN && dKeyElMolar100 < ALUMINAT_KEY_ELEMENT_MOLAR_TOTAL_MAX)
- {
- CElementChemistryPtr pKeyElChem2 = GetNamedElementChemistry(a_listElChems, ALUMINATE_KEY_ELEMENT_NAME[1]);
- if (!pKeyElChem2|| pKeyElChem2->GetPercentage()< MIN_ELEMENT_SUM)
- {
- strName = ALUMINATE_STR;
- return TRUE;
- }
- double dFirstElMolar = pKeyElChem->GetMolarPercentage();//Al
- double dSecondElMolar = pKeyElChem2->GetMolarPercentage();//Ca
- double dRatio = dFirstElMolar/dSecondElMolar ;// Al/Ca
- if (dRatio < 1.3 || dRatio > 0.9)//12CaO-7Al2O3 14/12
- {
- // not a Spinel, return FALSE
- strName = ALUMINATE12CaO_7Al2O3_STR;
- return TRUE;
- }
- if (dRatio < 0.9 || dRatio > 0.4)//3CaO-Al2O3 2/3
- {
- // not a Spinel, return FALSE
- strName = ALUMINATE3CaO_Al2O3_STR;
- return TRUE;
- }
- else
- {
- strName = Ca_ALUMINATE_STR;
- }
-
- // this is a Aluminate, return TRUE
- return TRUE;
- }
- // not a Aluminate, return FALSE
- return FALSE;
- }
- // check if the element chemistries list matching the STD
- BOOL COTSClassifyEng::MatchingSTD(CElementChemistriesList& a_listElChems, CSTDItemPtr a_pSTDItem, double a_dMolarSum)
- {
- // safety check
- ASSERT(a_pSTDItem);
- if (!a_pSTDItem)
- {
- // something wrong
- LogErrorTrace(__FILE__, __LINE__, _T("COTSClassifyEng::MatchingSTD: invalid CSTDItemPtr."));
- return FALSE;
- }
- if (a_dMolarSum < MIN_ELEMENT_SUM)
- {
- // something wrong
- LogErrorTrace(__FILE__, __LINE__, _T("COTSClassifyEng::MatchingSTD: invalid molar sum value."));
- return FALSE;
- }
- // find out how many elements need for the STD
- CElementRangeList& listElementRange = a_pSTDItem->GetElementRangeList();
- int nElNoMin = 0;
- for (auto pElmentRange : listElementRange)
- {
- int nStart = pElmentRange->GetRange()->GetStart();
- if (nStart > 0)
- {
- // this element has to have
- ++nElNoMin;
- }
- }
- int nElNoMax = (int)listElementRange.size();
- // a_listChemistriesElements size has to be between nElNoMin and nElNoMax
- int nElementSize = (int)a_listElChems.size();
- //if (nElementSize < nElNoMin || nElementSize > nElNoMax)
- if (nElementSize < nElNoMin)
- {
- // a_listChemistriesElements size not match
- return FALSE;
- }
- // all element chemistries have to be in listElementRange and in the range
- for (auto pElChems : a_listElChems)
- {
- CString strElement = pElChems->GetName();
- auto itr = std::find_if(listElementRange.begin(), listElementRange.end(), [strElement](CElementRangePtr& poElemenRange) { return poElemenRange->GetElement()->GetName().CompareNoCase(strElement) == 0; });
- if (itr == listElementRange.end())
- {
- // not in the element range list, not match then
- return FALSE;
- }
- // molar value has to be in the range
- double dMolar = pElChems->GetMolarPercentage();
- dMolar = Cal100NorValue(dMolar, a_dMolarSum);
- if (dMolar < (double)(*itr)->GetRange()->GetStart() || dMolar >(double)(*itr)->GetRange()->GetEnd())
- {
- // molar value has to be in the range, not match then
- return FALSE;
- }
- }
- // the two are matching each other, return TRUE
- return TRUE;
- }
- // calculate 100% normalize value (molar)
- double COTSClassifyEng::Cal100NorValue(double a_dValue, double a_dSumValue)
- {
- double d100NorCalue = MIN_DOUBLE_VALUE;
- // sum has a cut off
- if (a_dSumValue < MIN_ELEMENT_SUM)
- {
- return d100NorCalue;
- }
- d100NorCalue = a_dValue / a_dSumValue * 100;
- return d100NorCalue;
- }
- }
|