//----------------------------------------------------------------------------------
//! Main routine.
//----------------------------------------------------------------------------------
void SegmentationEvaluationMetric::_process()
{
	ML_TRACE_IN("SegmentationEvaluationMetric::_process ()");

	_numTruePositive = 0;
	_numTrueNegative = 0;
	_numFalsePositive = 0;
	_numFalseNegative = 0;
	double sensitivity = 0.0;
	double specificity = 0.0;
	unsigned int numVoxels = 0; 
	double prevalence = 0.0;
	double levelOfTest = 0.0;
	double dsc = 0.0;
	double cFactor = 0.0;
	
		


	// process all pages
    MLErrorCode err = processAllPages(-1);
  
	if (err==ML_RESULT_OK) {
		
		// sensitivity
		if ( (_numTruePositive + _numFalseNegative) > 0) {
			sensitivity = _numTruePositive / (double)(_numTruePositive+_numFalseNegative);
		}

		// specificity
		if ( (_numTrueNegative + _numFalsePositive) > 0) {
			specificity = _numTrueNegative / (double) (_numTrueNegative+_numFalsePositive);
		}

		// total number of voxels
		numVoxels = _numTruePositive + _numFalsePositive + _numFalseNegative + _numTrueNegative;
		
		// prevalence
		if (numVoxels > 0) {
			prevalence = (_numTruePositive + _numFalseNegative) / (double)numVoxels;
		}

		// level of test
		if (numVoxels > 0) {
			levelOfTest = (_numTruePositive + _numFalsePositive) / (double)numVoxels;
		}
		
		// Dice similarity coefficient
		if ( 2*_numTruePositive + _numFalsePositive + _numFalseNegative > 0) {
			dsc = 2.0 * _numTruePositive / (double)(2.0*_numTruePositive + _numFalsePositive + _numFalseNegative);
		}
		
		// C-Factor
		double p = sensitivity;
		double q = specificity;
		double d = (2.0 * p * (1 - q)) / (p + (1-q)) + (2 * (1-p) * q) / ((1-p) + p);
		
		if ( (p >= q) && (p > 1-q) ) {
			cFactor = d;
		}
		else if ( (p < q) && (p > 1-q) ) {
			cFactor = -d;
		}
		else if ( (p <= 1-q) ) {
			// undefined
		}
    }
    else {
        // Set error status.
		std::cerr << MLGetErrorCodeDescription(err);
    }

	// set output
	_truePositiveFld->setIntValue(_numTruePositive);
	_trueNegativeFld->setIntValue(_numTrueNegative);
	_falsePositiveFld->setIntValue(_numFalsePositive);
	_falseNegativeFld->setIntValue(_numFalseNegative);
	_sensitivityFld->setDoubleValue(sensitivity);
	_specificityFld->setDoubleValue(specificity);
	_prevalenceFld->setDoubleValue(prevalence);
	_levelOfTestFld->setDoubleValue(levelOfTest);
	_diceSimilarityCoefficientFld->setDoubleValue(dsc);
	_cFactorFld->setDoubleValue(cFactor);
}
//----------------------------------------------------------------------------------
//! Handle field changes of the field \c field.
//----------------------------------------------------------------------------------
void CalcCodedSegmentation::handleNotification (Field *field)
{
	ML_TRACE_IN("CalcCodedSegmentation::handleNotification()")
	
    if (field == _fld_Add)
	{
		replaceValues->clear();
		replaceValues_MaxIndex = 0;		
		replaceValues->resize(MAX_SIZE,0);		
		addImage();		
		renewObjectValues();		
		int error = processAllPages(0);
		if (error!=0) std::cout << "processAllPages Error (add) = " << MLGetErrorCodeDescription(error) << std::endl;
    } 
	else if (field == _fld_Reset)
	{
		//std::cout << "_fld_Reset" << std::endl;
		calcOutImageProps(0);		
		reset();		
		clearOutputImage();	
		getOutImg(0)->setOutOfDate();
		
		int error = processAllPages(0);
		if (error!=0) std::cout << "processAllPages Error (reset) = " << MLGetErrorCodeDescription(error) << std::endl; //Das mit dem invalidieren per setOutOfDate geht nicht
		
		_fld_ObjectValues->setStringValue("");
		_fld_ImageValues->setStringValue("");