/**
 * 
 */
package org.eclipse.stem.util.analysis;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.stem.analysis.impl.ReferenceScenarioDataMapImpl.ReferenceScenarioDataInstance;


/*******************************************************************************
 * Copyright (c) 2007, 2008 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

/**
  * This class is designed to take a pair of time series each involving multiple epidemic waves. It uses one 
  * series as a reference an then phase shifts the peaks within the second data series so that the epidemics
  * are "synchronized". This is necessary in order to accurately fit model parameters of many locations without imposing a
  * transportation model. As the epidemic "moves", peaks occur at different times. Synchronizing allows us to estimate the epidemic
  * parameters without a transportation model. This class is used when the fitting is done by adding synchronized data over all locations.
  * This is not necessary if we can fit each location independantly, but is necessary when the amount of data is scarce (eg for real
  * epidemic incidence data).
 */
public class PhaseSynchronizer {
	
	ReferenceScenarioDataInstance reference;
	//ReferenceScenarioDataInstance data;
	
	/**
	 * this phase shift maximizes the correlation between the two vectors
	 */
	//int phaseShift;
	
	/**
	 * by default we will try to find max correlation for a shift of +/- 30 days
	 * if the vectors are shorter than this we reduce the window
	 */
	//int defaultShiftWindow = 30;
	
	/**
	 * This class is designed to take a pair of ReferenceScenarioDataInstance(s) each involving multiple epidemic waves. It uses one 
	 * series as a reference an then phase shifts the peaks within the second incidence data series so that the epidemics
	 * are "synchronized". This is necessary in order to accurately fit model parameters of many locations without imposing a
	 * transportation model. As the epidemic "moves", peaks occur at different times. Synchronizing allows us to estimate the epidemic
	 * parameters without a transportation model. This class is used when the fitting is done by adding synchronized data over all locations.
	 * This is not necessary if we can fit each location independently, but is necessary when the amount of data is scarce (eg for real
	 * epidemic incidence data).
	 * @param refInstance
	 * 
	 */
	public PhaseSynchronizer(ReferenceScenarioDataInstance refInstance) {
		reference = refInstance;
		this.getPeakPositions(reference, "Incidence");
	}
	
	/**
	 * Finds index of peaks, returns as list
	 * @param instance
	 * @param key 
	 * @parameter key (must be I, E, or incidence - they have peaks)
	 * @return list of peak positions
	 */
	public List<Integer> getPeakPositions(ReferenceScenarioDataInstance instance, String key) {
		List<Double> vector = instance.getData().get(key);
		List<Integer> peaks = new ArrayList<Integer>();
		for (int i = 0; i < vector.size(); i ++) {
			double value = vector.get(i).doubleValue();
			double next = 0.0;
			double last = 0.0;
			if (i<(vector.size()-1)) next = vector.get(i+1).doubleValue();
			if (i>0) last = vector.get(i-1).doubleValue();
			if((value > next)&&(value>last)) {
				peaks.add(Integer.valueOf(i));
				// DEBUG
				//Activator.logInformation("found peak at i="+i+", value="+value);
			}
		}
		return peaks;
	}
	
	/**
	 * Rotates the vector (List) by Shift - wrapping values from beginning to end or vice versa as necessary
	 * This should work for quasi periodic time series
	 * @param shift
	 * @param vector
	 * @return shifted vector
	 */
	public List<Double> getShiftedVector(int shift, List<Double> vector){
		List shifted = new ArrayList<Double>();
		int max = vector.size();
		for (int i = 0; i < max; i ++) {
			int j = i - shift;
			if (j >= max) {
				j = j - max;
			}
			if (j < 0) {
				j = max+j;
			}
			shifted.add(i,vector.get(j));
		}
		
		return shifted;
	}
 
}
