gt: 		File file = new File("forecastingLog.txt");
context: package es.tekniker.eefrmwrk.prediction;
  
  import java.io.BufferedWriter;
  import java.io.File;
  import java.io.FileInputStream;
  import java.io.FileNotFoundException;
  import java.io.FileOutputStream;
  import java.io.FileWriter;
  import java.io.IOException;
  import java.io.ObjectInputStream;
  import java.io.ObjectOutputStream;
  import java.text.SimpleDateFormat;
  import java.util.ArrayList;
  import java.util.List;
  
  import weka.classifiers.evaluation.NumericPrediction;
  import weka.classifiers.timeseries.WekaForecaster;
  import weka.classifiers.timeseries.core.TSLagMaker;
  import weka.classifiers.timeseries.core.TSLagMaker.Periodicity;
  import weka.classifiers.timeseries.eval.TSEvaluation;
  import weka.core.Instance;
  import weka.core.Instances;
  
  /**
   * @author ebikandi
   * */
  public class Forecaster extends SupervisedClassifierCreator {
  
  	private WekaForecaster forecaster = null;
  	private List<List<NumericPrediction>> forecasting = null;
  	//private Instances instanceSet = null;
  
  	// Instances realData;
  
  	/**
  	 * Constructor
  	 * */
  	public Forecaster() {
  		forecaster = new WekaForecaster();
  
  	}
  
  	/**
  	 * Returns the WekaForecaster that is currently loaded.
  	 * 
  	 * @return WekaForecaster The WekaForecaster that is currently loaded.
  	 * */
  	public WekaForecaster getForecaster() {
  		return forecaster;
  	}
  
  	/**
  	 * Returns the prediction that is currently loaded.
  	 * 
  	 * @return List<List<NumericPrediction>> The prediction that is currently loaded.
  	 * */
  	public List<List<NumericPrediction>> getPrediction(){
  		return forecasting;
  	}
  	
  	/**
  	 * Saves the forecaster that is currently loaded in a .model in order to re-use it.
  	 * 
  	 * @param String
  	 *            The filename to use when creating the file (without the .model
  	 *            extension)
  	 * */
  	public void saveForecastingModel(String modelname, Instances structure)throws FileNotFoundException, IOException {
  		File sFile = new File(modelname + ".model");
  		ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(sFile));
  		oos.writeObject(forecaster);
  		oos.writeObject(new Instances(structure, 0));
  		oos.close();
  	}
  
  	/**
  	 * Loads a stored forecaster form a .model file.
  	 * 
  	 * @param String The name of the .model file (without the .model extension)
  	 * @throws Exception 
  	 * */
  	public void loadForecasterFromModel(String modelname) throws Exception {
  		ObjectInputStream ois = new ObjectInputStream(new FileInputStream( modelname + ".model"));
  		forecaster.reset();
  		forecaster = (WekaForecaster) ois.readObject();
  		ois.close();
  	}
  
  	/**
  	 * Builds the forecaster to prepare for the execution.
  	 * @param Instances The instances to use. Also they will be stored to remember the data-structure for future use.
  	 * @param List<String> The names of the variables to forecast.
  	 * @param String The Name of the algorithm to use.
  	 * @param Long The time-lapse between the intervals.
  	 * @param int The number of steps to set the confidence interval
  	 *@throws Exception 
  	 * */
  //For now, we will not fix the periodicity
  //	public void buildForecaster(Instances instances, List<String> varNames, String algorithm, Long periodicity) throws Exception {
  public void buildForecaster(Instances instances, List<String> varNames, String algorithm) throws Exception {
  		if (varNames.size() > 0) {
  			System.out.println("Building the forecast");
  //			instanceSet = new Instances(instances);
  			// Set the attributes we want to make the forecasting
  			String varString = "";
  			for (String f : varNames) {
  				varString += f + ",";
  			}
  
  			varString = varString.substring(0, varString.length() - 1);
  			forecaster.setFieldsToForecast(varString);
  
  			forecaster.setBaseForecaster(createClassifier(algorithm));
  			
  			forecaster.getTSLagMaker().setTimeStampField("date"); // date  timestamp
  //			forecaster.getTSLagMaker().setAdjustForVariance(true);
  
  //FIXME dynamic periodicity, depending on the input data
  //			// Set the periodicity 
  //			if (periodicity == 86400000L)
  //				forecaster.getTSLagMaker().setPeriodicity(Periodicity.DAILY); 
  //			else
  //				forecaster.getTSLagMaker().setPeriodicity(Periodicity.HOURLY); //Default option
  			// Assign the model
  //			forecaster.setConfidenceLevel((double)0.99);
  //			forecaster.setCalculateConfIntervalsForForecasts(steps);
  			forecaster.buildForecaster(instances, System.out);
  		}
  	}
  
  	/**
  	 * Runs the forecaster. It has to be built previously with buildForecaster().
  	 * @param The instance-set to prime the forecaster
  	 * @param int The number of time-steps to predict beyond the last data.
  	 *@throws Exception 
  	 * */
  	public void runForecaster(Instances instanceSet,int steps) throws Exception { 
  	
  		forecaster.primeForecaster(instanceSet);
  		forecasting = forecaster.forecast(steps, System.out);
  //		this.printPrediction(false, false);
  	}
  
  	/**
  	 * Evaluates the forecaster that is currently built loaded.
  	 * @param The instance-set to prime the forecaster
  	 * @param int The number of time-steps to predict beyond the last data.
  	 * @return String The summary of the evaluation.
  	 *@throws Exception 
  	 * */
  	public String evaluateForecaster(Instances instanceSet, int steps) throws Exception { 
  		TSEvaluation eval = new TSEvaluation(instanceSet, 0.3);
  		// Set the evaluation horizon
  		if (forecaster.getTSLagMaker().getPeriodicity() == Periodicity.DAILY)
  			eval.setHorizon(7);// One week
  		else
  			eval.setHorizon(6); 
  		eval.setHorizon(steps);
  		eval.setEvaluateOnTestData(true);
  		eval.setEvaluateOnTrainingData(false);
  		eval.evaluateForecaster(forecaster, System.out);
  		System.out.println(eval.toSummaryString());
  		return eval.toSummaryString();
  	}
  
  	/**
  	 * Prints the last forecasting that has been done.
  	 * @param String The name of the algorithm that it has been used.
  	 * @param Boolean To save the forecasting in a log. (True to store)
  	 * @param Boolean To append (true) the forecasting to the content of the file, or erase (false) it.
  	 * @throws Exception
  	 * */
  	public void printPrediction(boolean save2Log, boolean append) throws Exception {
  		if (forecasting != null) {
  			int i, j;
  			double lastDate, firstDate, delta;
  			SimpleDateFormat sdf = new SimpleDateFormat(
  					"yyyy-MM-dd HH:mm:ss.SSS");
  			StringBuilder logContent = new StringBuilder(
  					"********************************\n********	" + forecaster.getAlgorithmName()
  							+ "\n********************************\n\n");
  			TSLagMaker tslMaker = forecaster.getTSLagMaker();
  			lastDate = tslMaker.getCurrentTimeStampValue();
  			delta = tslMaker.getDeltaTime();
  			firstDate = lastDate - (delta * forecasting.size());
  			for (i = 0; i < forecasting.size(); i++) { // Number of steps
  				logContent.append(sdf.format(firstDate + (delta * (i + 1)))
  						+ ": ");
  				for (j = 0; j < forecasting.get(i).size(); j++) { // Number of attributes (variables)
  					logContent.append(forecasting.get(i).get(j).predicted()
  							+ " ");
  				}
  				logContent.append("\n");
  			}
  			System.out.println(logContent);
  			if (save2Log)
  				saveLoging(logContent.toString(), append);
  
  		}
  	}
  
  	/**Saves a string into a log file.
  	 * @param String The string to write into the file.
  	 * @param Boolean Boolean To append (true) the forcasting to the content of the file, or erase (false) it.
  	 * */
  	public void saveLoging(String logContent, boolean append)
  			throws IOException {
  