// load a volume for computation
void emotionRoiProcessing::loadVolume(studyParams &vdb, volume<float> &v, int index)
{
	char processedFile[200], prefix[BUFF_SIZE], tempVolume[BUFF_SIZE];
	if (0)
	{
		// gets the motion corrected and gaussian file
		vdb.getMCGVolumeName(processedFile, index);
		read_volume(v, string(processedFile));
	}
	else
	{
		// making the activation volume for viewing
		vdb.getFinalVolumeFormat(prefix);
		vdb.setActivationFile(index);
		estimateActivation(index, index, vdb.slidingWindowSize, prefix, vdb.maskFile, vdb.activationFile);

		// gets the motion corrected and gaussian file and calculates the mean with the last n volumes (n = sliding window size)
		sprintf(tempVolume, "%s%s", vdb.outputDir, "temp.nii");
		vdb.getMCGVolumeFormat(prefix);
		estimateActivation(index, index, vdb.slidingWindowSize, prefix, tempVolume);
		read_volume(v, string(tempVolume));
		if (fileExists(tempVolume))
			remove(tempVolume);
	}

}
// plug in test function
DLLExport testSVM(studyParams &vdb, int index, float &classnum, float &projection, void * &userData)
{
   char prefix[BUFF_SIZE];
   SVMProcessing *svmProcessingVar = (SVMProcessing *) userData;

   vdb.getFinalVolumeFormat(prefix);

   fprintf(stderr, "Generating activation file.\n");
   vdb.setActivationFile(index);

   estimateActivation(index, index, vdb.slidingWindowSize, prefix, vdb.maskFile, vdb.activationFile);
   
   fprintf(stderr, "Classifying.\n");
   svmProcessingVar->test(index, vdb.activationFile, classnum, projection);
   
   return 1;
}
void FunctionalConnectivity::processVolume(studyParams &vdb, int index, float &classnum, float &projection)
{
    char volumeFile[BUFF_SIZE];
   
    // calculate correlations
    vdb.getVolume(volumeFile, index, volumeType);
    connectivityCalculator.calculateCorrelations(volumeFile);

    // calculate zNorm ROI means for graphic display. This values are meant for FRONT END display. We do a incremental zcore calculation to avoid problems in graphic display causedby differente bold values levels in different rois.
    for (int t=0; t < connectivityCalculator.numRegions; t++)
    {
       double value = connectivityCalculator.means[t];
       outputMeanReport << connectivityCalculator.means[t] << " ";
       zNormRegionMeans[t].addValue(value);
       zNormRegionMeanValues[t] = zNormRegionMeans[t].zValue(value);
    }
	outputMeanReport << "\n";
   
    // calculate mean correlation
    double correlationMean=0;
    for (int t=0; t < connectivityCalculator.numPairs; t++)
        correlationMean += connectivityCalculator.correlations[t];
   
    // remember here we have only one pair of rois to form a correlation. Other calculations with more than one pair are possible. You have the power to define it in your way.
    correlationMean /= connectivityCalculator.numPairs;
   
   // saving the results in a file, for debug purposes
	outputCorrelationReport << correlationMean << "\n";
    outputMeanReport.flush();
	outputCorrelationReport.flush();

    // calculate weigted mean
    correlationWeightedMean.addValue(correlationMean);

    // calculates the incremental correlation stats
    correlationStats.addValue(correlationMean);

    if (true)
    {
       // Calculate a dynamic range to be used in coupling task
       minCorrelationBaseline = correlationWeightedMean.mean - correlationMultiplyer * correlationStats.deviation;
       maxCorrelationBaseline = correlationWeightedMean.mean + correlationMultiplyer * correlationStats.deviation;
    
       // get Classe
       classnum = vdb.getClass(index);
    
       // get projection (percentage)
       fprintf(stderr, "condition = %s\n", vdb.getCondition(index));
       bool randomLike = (strcmp(vdb.getCondition(index), stabilizationCondition) == 0) || vdb.randomRun;
       
       if (vdb.interval.isBaselineCondition(index))
       {
          fprintf(stderr, "Baseline condition.\n");
          projection = 0;
       }
       else if (randomLike) // stabilization mode. the participant is encouraged to maintain state.
       {
           fprintf(stderr, "Stabilization task.\n");
           fprintf(stderr, "Mean = %f mean 2 = %f\n", correlationMean, correlationWeightedMean.mean);
           projection = 1-abs(correlationMean-correlationWeightedMean.mean);
       }
       else // coupling task. the participant is encouraged to coupling anterior temporal lobe and subgenual areas. Here we use a dynamic range for transform the correlation in a percentage.
       {
           fprintf(stderr, "Coupling task.\n");
           fprintf(stderr, "Mean = %f min = %f max = %f \n", correlationMean, minCorrelationBaseline, maxCorrelationBaseline);
           projection = (correlationMean-minCorrelationBaseline)  / (maxCorrelationBaseline-minCorrelationBaseline);

       }
	   outputFeedbackReport << index << " - " << projection << "\n";
    }
   
    // enforcing value limits 0 and 1
    if (projection > 1) projection = 1;
    else if (projection < 0) projection = 0;
    fprintf(stderr, "Projection value = %f \n", projection);
}
// calculates the feedback value
int emotionRoiProcessing::processVolume(studyParams &vdb, int index, float &classnum, float &feedbackValue)
{
   int idxInterval = vdb.interval.returnInterval(index);
   double positivePSC, negativePSC;

   volume<float> v;


   loadVolume(vdb, v, index);
   // if in baseline condition, calculates the mean volume, one by one
   classnum = vdb.getClass(index);
   feedbackValue = 0;

   double intervalSize = (double)(vdb.interval.intervals[idxInterval].end - vdb.interval.intervals[idxInterval].start + 1);

   if (vdb.interval.isBaselineCondition(index))
   {
      if (vdb.interval.intervals[idxInterval].start == index) meanbaseline = v;
      else meanbaseline += v;
      // in the end of condition, divides the sum by the size of the current block
      if (vdb.interval.intervals[idxInterval].end == index) 
      {
         meanbaseline /= intervalSize;
         meanCalculation.calculateMeans(meanbaseline);
         
         // calculates the mean roi value of the mean volume. We just need this value
         positiveBaseline = meanCalculation.roiMean(positiveIndex);
		 negativeBaseline = meanCalculation.roiMean(negativeIndex);
	  }
   }
   else // task condition. Taking the mean of the volume and calculating the PSC
   {
      meanCalculation.calculateMeans(v);
	  positivePSC = PSC(meanCalculation.roiMean(positiveIndex), positiveBaseline);
	  negativePSC = PSC(meanCalculation.roiMean(negativeIndex), negativeBaseline);

	  // negative emotion Feedback
	  if (classnum == 1)
	  {
		  feedbackValue = negativePSC / negativeTargetValue;
		  if (vdb.interval.intervals[idxInterval].start == index) negativePSCMean = negativePSC / intervalSize;
		  else  negativePSCMean += negativePSC / intervalSize;

		  if (vdb.interval.intervals[idxInterval].end == index)
		  {
			  if (negativePSCMean >= negativeTargetValue)
				  negativeBlocksAboveTarget++;
		  }

		  if (negativePSC > 0)
			  negativeActivationLevel.addValue(negativePSC, 1);

		  double valueLevel = negativeActivationLevel.mean * (1 + levelMultiplyer);
		  if (valueLevel > 0) negativeTargetValue = valueLevel;
	  }
	  else if (classnum == 3)
	  {
		  feedbackValue = positivePSC / positiveTargetValue;
		  if (vdb.interval.intervals[idxInterval].start == index) positivePSCMean = positivePSC / intervalSize;
		  else  positivePSCMean += positivePSC / intervalSize;

		  if (vdb.interval.intervals[idxInterval].end == index)
		  {
			  if (positivePSCMean >= positiveTargetValue)
				  positiveBlocksAboveTarget++;
		  }

		  if (positivePSC > 0)
			  positiveActivationLevel.addValue(positivePSC, 1);

		  double valueLevel = positiveActivationLevel.mean * (1 + levelMultiplyer);
		  if (valueLevel > 0) positiveTargetValue = valueLevel;
	  }
      fprintf(stderr, "Feedback value = %f\n", feedbackValue);
   }
   return 0;
}