|  | @@ -21,6 +21,7 @@ namespace OTSClassifyEngine
 | 
	
		
			
				|  |  |  	const CString STR_N = _T("N");
 | 
	
		
			
				|  |  |  	const CString STR_CR = _T("Cr");
 | 
	
		
			
				|  |  |  	const double SIC_MOLAR_CUTOFF = 85.0;
 | 
	
		
			
				|  |  | +	const double NBC_MOLAR_CUTOFF = 30.0;
 | 
	
		
			
				|  |  |  	const double FEO_MOLAR_CUTOFF = 85.0;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	// key element
 | 
	
	
		
			
				|  | @@ -29,7 +30,7 @@ namespace OTSClassifyEngine
 | 
	
		
			
				|  |  |  	const double INC_KEY_ELEMENT_TOTAL_100 = 5.0;	// total molar value
 | 
	
		
			
				|  |  |  	const CString INC_KEY_ELEMENT_NAMES[INC_KEY_ELEMENT_MAX] =
 | 
	
		
			
				|  |  |  	{
 | 
	
		
			
				|  |  | -		_T("S"),_T("N"),_T("O"),_T("C")
 | 
	
		
			
				|  |  | +		_T("S"),_T("N"),_T("O")
 | 
	
		
			
				|  |  |  	};
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	// sub element
 | 
	
	
		
			
				|  | @@ -191,13 +192,7 @@ namespace OTSClassifyEngine
 | 
	
		
			
				|  |  |  			// 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."));
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  		
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -289,6 +284,7 @@ namespace OTSClassifyEngine
 | 
	
		
			
				|  |  |  		double dSumKeyElements = 0;
 | 
	
		
			
				|  |  |  		double dSumSubElements = 0;
 | 
	
		
			
				|  |  |  		double dCarbonMolar = 0;
 | 
	
		
			
				|  |  | +		double dNbMolar = 0;
 | 
	
		
			
				|  |  |  		double dOMolar = 0;
 | 
	
		
			
				|  |  |  		double dSiMolar = 0;
 | 
	
		
			
				|  |  |  		double dFeMolar = 0;
 | 
	
	
		
			
				|  | @@ -320,10 +316,7 @@ namespace OTSClassifyEngine
 | 
	
		
			
				|  |  |  				{
 | 
	
		
			
				|  |  |  					dOMolar = pElChem->GetMolarPercentage();
 | 
	
		
			
				|  |  |  				}
 | 
	
		
			
				|  |  | -				else if (pElChem->GetName().CompareNoCase(STR_C) == 0)
 | 
	
		
			
				|  |  | -				{
 | 
	
		
			
				|  |  | -					dCarbonMolar = pElChem->GetMolarPercentage();
 | 
	
		
			
				|  |  | -				}
 | 
	
		
			
				|  |  | +				
 | 
	
		
			
				|  |  |  			}
 | 
	
		
			
				|  |  |  			// sub element?, include Fe
 | 
	
		
			
				|  |  |  			else if (IsSubElement(pElChem))
 | 
	
	
		
			
				|  | @@ -350,6 +343,10 @@ namespace OTSClassifyEngine
 | 
	
		
			
				|  |  |  				{
 | 
	
		
			
				|  |  |  					dSiMolar = pElChem->GetMolarPercentage();
 | 
	
		
			
				|  |  |  				}
 | 
	
		
			
				|  |  | +				else if (pElChem->GetName().CompareNoCase(STR_Nb) == 0)
 | 
	
		
			
				|  |  | +				{
 | 
	
		
			
				|  |  | +					dNbMolar = pElChem->GetMolarPercentage();
 | 
	
		
			
				|  |  | +				}
 | 
	
		
			
				|  |  |  					
 | 
	
		
			
				|  |  |  				
 | 
	
		
			
				|  |  |  			}
 | 
	
	
		
			
				|  | @@ -357,7 +354,10 @@ namespace OTSClassifyEngine
 | 
	
		
			
				|  |  |  			{
 | 
	
		
			
				|  |  |  				dFeMolar = pElChem->GetMolarPercentage();
 | 
	
		
			
				|  |  |  			}
 | 
	
		
			
				|  |  | -			
 | 
	
		
			
				|  |  | +			else if (pElChem->GetName().CompareNoCase(STR_C) == 0)
 | 
	
		
			
				|  |  | +			{
 | 
	
		
			
				|  |  | +				dCarbonMolar = pElChem->GetMolarPercentage();
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  |  			
 | 
	
		
			
				|  |  |  			
 | 
	
		
			
				|  |  |  		}
 | 
	
	
		
			
				|  | @@ -369,13 +369,21 @@ namespace OTSClassifyEngine
 | 
	
		
			
				|  |  |  		{
 | 
	
		
			
				|  |  |  			// calculate molar % of C + Si
 | 
	
		
			
				|  |  |  			double dMolarC_Si = Cal100NorValue(dCarbonMolar + dSiMolar, a_dMolarSumNoFe + dCarbonMolar);
 | 
	
		
			
				|  |  | -			if (dMolarC_Si > SIC_MOLAR_CUTOFF)
 | 
	
		
			
				|  |  | +			if (dMolarC_Si > SIC_MOLAR_CUTOFF && dSiMolar> INC_SUB_ELEMENT_CUT_OFF)
 | 
	
		
			
				|  |  |  			{
 | 
	
		
			
				|  |  |  				// this is a SiC, not a inclusion, return FALSE
 | 
	
		
			
				|  |  |  				a_nIncId =OTS_PARTCLE_TYPE::ISNOT_INCLUTION;
 | 
	
		
			
				|  |  |  				notIncId = NOT_INCLUTION_ID::SiC;
 | 
	
		
			
				|  |  |  				return TRUE;
 | 
	
		
			
				|  |  |  			}
 | 
	
		
			
				|  |  | +			double dMolarC_Nb = Cal100NorValue(dCarbonMolar + dNbMolar, a_dMolarSumNoFe + dCarbonMolar);
 | 
	
		
			
				|  |  | +			if (dMolarC_Nb > NBC_MOLAR_CUTOFF && dNbMolar > INC_SUB_ELEMENT_CUT_OFF)
 | 
	
		
			
				|  |  | +			{
 | 
	
		
			
				|  |  | +				// this is a SiC, not a inclusion, return FALSE
 | 
	
		
			
				|  |  | +				a_nIncId = OTS_PARTCLE_TYPE::ISNOT_INCLUTION;
 | 
	
		
			
				|  |  | +				notIncId = NOT_INCLUTION_ID::NbC;
 | 
	
		
			
				|  |  | +				return TRUE;
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  |  		//=========================================
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -480,22 +488,7 @@ namespace OTSClassifyEngine
 | 
	
		
			
				|  |  |  			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;
 | 
	
	
		
			
				|  | @@ -1269,152 +1262,7 @@ namespace OTSClassifyEngine
 | 
	
		
			
				|  |  |  		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;
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | +	
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	// nominate element chemistries list 
 | 
	
		
			
				|  |  |  	BOOL COTSClassifyEng::NomiNateElChemsList( CElementChemistriesList& a_listElChemsInc, 
 | 
	
	
		
			
				|  | @@ -1423,7 +1271,7 @@ namespace OTSClassifyEngine
 | 
	
		
			
				|  |  |  		// return FALSE if nothing in the input list
 | 
	
		
			
				|  |  |  		if (a_listElChemsInc.empty())
 | 
	
		
			
				|  |  |  		{
 | 
	
		
			
				|  |  | -			LogErrorTrace(__FILE__, __LINE__, _T("COTSClassifyEng::NomiNateElChemsList: invalid inclusion x-ray data."));
 | 
	
		
			
				|  |  | +			//LogErrorTrace(__FILE__, __LINE__, _T("COTSClassifyEng::NomiNateElChemsList: invalid inclusion x-ray data."));
 | 
	
		
			
				|  |  |  			return FALSE;
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  |  
 |