| package org.eclipse.stem.util.analysis; |
| |
| /******************************************************************************* |
| * 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 |
| *******************************************************************************/ |
| |
| import java.io.File; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Map.Entry; |
| import java.util.Set; |
| |
| import org.eclipse.emf.common.util.EList; |
| import org.eclipse.jface.operation.IRunnableContext; |
| import org.eclipse.stem.analysis.ErrorFunction; |
| import org.eclipse.stem.analysis.ErrorResult; |
| import org.eclipse.stem.analysis.LogInitializationException; |
| import org.eclipse.stem.analysis.impl.ReferenceScenarioDataMapImpl; |
| import org.eclipse.stem.analysis.impl.ReferenceScenarioDataMapImpl.ReferenceScenarioDataInstance; |
| import org.eclipse.stem.analysis.util.CSVscenarioLoader; |
| import org.eclipse.stem.core.scenario.Scenario; |
| import org.eclipse.stem.util.analysis.views.AnalysisControl; |
| import org.eclipse.stem.util.analysis.views.EstimatorControl; |
| import org.eclipse.stem.util.analysis.views.Messages; |
| import org.eclipse.swt.widgets.TaskBar; |
| |
| /** |
| * Analyzes a {@link Scenario} and compares scenarios |
| */ |
| public class ScenarioAnalysisSuite { |
| /** |
| * For testing |
| */ |
| public static final String REFERENCE_ROOT_DIRECTORY = AggregateDataWriter.ANALYSISFOLDER; |
| |
| /** |
| * Where we start looking for recorded scenario files |
| */ |
| public static String REFERENCE_TESTING_DIRECTORY = REFERENCE_ROOT_DIRECTORY; |
| |
| /** |
| * Set to an actual folder below (if found) |
| */ |
| public static String REFERENCE_TESTING_AGGREGATE_FILE = REFERENCE_ROOT_DIRECTORY+File.separator+AggregateDataWriter.AGGREGATE_FOLDERNAME+File.separator+"aggregate.csv"; |
| |
| private static String DEFAULT_AGGREGATE_FILENAME = "aggregate"; |
| |
| private static String COMPARISON_FILE_NAME = "RMSComparisonResults"; |
| |
| /** |
| * Message if directory not found |
| */ |
| public static final String NOT_FOUND_MSG = Messages.getString("COMMON.NOTFOUND"); |
| |
| /** |
| * Message if data not valid |
| */ |
| public static final String INVALID_DATA_MSG = Messages.getString("COMMON.NOTDATA"); |
| |
| /** |
| * Message if done |
| */ |
| public static final String DONE_MSG = Messages.getString("COMMON.DONE"); |
| |
| /** |
| * Message if Ready |
| */ |
| public static final String READY_MSG = Messages.getString("COMMON.READY"); |
| |
| /** |
| * Message if Working |
| */ |
| public static final String WORKING_MSG = Messages.getString("COMMON.WORKING"); |
| |
| |
| /** |
| * Contains all reference scenario data |
| */ |
| ReferenceScenarioDataMapImpl referenceScenarioDataMap = null; |
| |
| /** |
| * Contains all reference scenario data (for comparison) |
| */ |
| ReferenceScenarioDataMapImpl comparisonScenarioDataMap = null; |
| |
| /** |
| * the Estimator instance |
| */ |
| ScenarioParameterEstimator estimator = null; |
| |
| AnalysisControl control = null; |
| |
| |
| /** |
| * @param ctrl |
| * |
| */ |
| public ScenarioAnalysisSuite(AnalysisControl ctrl) { |
| control = ctrl; |
| // Nothing |
| } |
| |
| /** |
| * Aggregate data |
| * |
| * @param folder Scenario folder |
| * @param runnableContext Runnable context |
| * @param alpha the Immunity Loss Rate. This is needed to compute the incidence |
| * @return String[] filename where filename[0] = aggregate data file and filename[1] = incidence data file |
| * @throws LogInitializationException Thrown if problem reading data |
| */ |
| |
| public String aggregateData(String folder, IRunnableContext runnableContext, double alpha) throws LogInitializationException{ |
| CSVscenarioLoader loader = new CSVscenarioLoader(folder); |
| int maxResolution = loader.getMaxResolution(); |
| ReferenceScenarioDataMapImpl map = loader.parseAllFiles(maxResolution); |
| String aggregateFileName = getAggregateFileName(folder); |
| ReferenceScenarioDataInstance aggregatedData = map.aggregateScenarioData(runnableContext); |
| AggregateDataWriter writer = new AggregateDataWriter(folder, aggregateFileName); |
| |
| return writer.logDataInstance(aggregatedData, alpha); |
| } |
| |
| |
| /** |
| * Aggregate data but filter the locations that get aggregate to match the locations |
| * in the referenceFolder |
| * @param referenceFolder |
| * @param folder Scenario folder |
| * @param runnableContext Runnable context |
| * @param alpha the Immunity Loss Rate. This is needed to compute the incidence |
| * @return String[] filename where filename[0] = aggregate data file and filename[1] = incidence data file |
| * @throws LogInitializationException Thrown if problem reading data |
| */ |
| |
| public String aggregateByFilter(String referenceFolder, String folder, IRunnableContext runnableContext, double alpha) throws LogInitializationException{ |
| CSVscenarioLoader refLoader = new CSVscenarioLoader(referenceFolder); |
| int maxRes = refLoader.getMaxResolution(); |
| Set<String> locationsToAggregate = refLoader.getLocations(maxRes); |
| CSVscenarioLoader loader = new CSVscenarioLoader(folder); |
| int maxResolution = loader.getMaxResolution(); |
| ReferenceScenarioDataMapImpl map = loader.parseAllFiles(locationsToAggregate, maxResolution); |
| String aggregateFileName = getAggregateFileName(folder); |
| ReferenceScenarioDataInstance aggregatedData = map.aggregateScenarioData(runnableContext); |
| AggregateDataWriter writer = new AggregateDataWriter(folder, aggregateFileName); |
| |
| return writer.logDataInstance(aggregatedData, alpha); |
| } |
| |
| /** |
| * Estimates the model parameters for scenario data located in the referenceDirectory |
| * @param dataMap Data |
| * @param parameterEstimatorMethod Which method do we use to estimate |
| * @param runnableContext Context used for long running tasks |
| * @return a set of fitted model parameters |
| */ |
| public ModelParameters estimateParameters(ReferenceScenarioDataMapImpl dataMap, ParameterEstimatorMethod parameterEstimatorMethod, IRunnableContext runnableContext) { |
| this.referenceScenarioDataMap = dataMap; |
| estimator = new ScenarioParameterEstimator(this.referenceScenarioDataMap, parameterEstimatorMethod); |
| |
| ModelParameters bestEstimate = new ModelParameters(); |
| |
| // The user can set this |
| boolean sumAllLocations = false; |
| Map<String,Object> controlParametersMap = control.getControlParametersMap(); |
| if(controlParametersMap != null) { |
| sumAllLocations = ((Boolean) controlParametersMap.get(EstimatorControl.SUM_LOCATIONS_KEY)).booleanValue(); |
| } |
| |
| if(sumAllLocations) { |
| bestEstimate = estimator.averageThenEstimateParameters(controlParametersMap, runnableContext); |
| } else { |
| Map<String,ModelParameters> fittedParameters = estimator.estimateParameters(controlParametersMap, runnableContext); |
| bestEstimate.average(fittedParameters); |
| } |
| |
| |
| return bestEstimate; |
| } |
| |
| /** |
| * The aggregate file is named after the data directory under csv |
| * @param dir |
| * @return |
| */ |
| private static String getAggregateFileName(String dir) { |
| int start = dir.lastIndexOf(File.separatorChar); |
| |
| String filename = DEFAULT_AGGREGATE_FILENAME; |
| if(start >=0) { |
| filename = dir.substring(start+1,dir.length()); |
| } |
| filename = filename +".csv"; |
| return filename; |
| } |
| |
| /** |
| * Root Mean Square Difference Comparison |
| * Compares data from two scenarios: the referenceDirectory and the comparisonDirectory |
| * The comparison directory will recursively traverse directories to search for log files. |
| * When found, a comparison is done and the results is written to the comparison directory |
| * including the parameters used for the simulation |
| * |
| * @param referenceDirectory |
| * @param comparisonDirectory |
| * @param runnableContext Context for long running task |
| * @return ErrorResult |
| * @throws LogInitializationException |
| */ |
| |
| public ErrorResult compare(String referenceDirectory, String comparisonDirectory, IRunnableContext runnableContext, ErrorFunction errorfunc) throws LogInitializationException { |
| CSVscenarioLoader referenceLoader = new CSVscenarioLoader(referenceDirectory); |
| // We will write the result to a file in the comparison directory folder |
| String resultFile = COMPARISON_FILE_NAME; |
| |
| CSVAnalysisWriter resultWriter = new CSVAnalysisWriter(resultFile); |
| Map<Map<String, String>, ErrorResult> result = new HashMap<Map<String, String>, ErrorResult>(); |
| compareRecursive(referenceLoader, comparisonDirectory, result, runnableContext, errorfunc); |
| resultWriter.logData(result); |
| resultWriter.flushLoggerData(); |
| resultWriter.closeLoggerData(); |
| // Find the smallest RMS difference and return its double list |
| double smallestError = Double.MAX_VALUE; |
| ErrorResult returnError=null; |
| for(Entry<Map<String, String>,ErrorResult> entry : result.entrySet()) { |
| ErrorResult res = entry.getValue(); |
| // Compute average |
| double error = 0.0; |
| if(res !=null) { |
| error = res.getError(); |
| } |
| if(error < smallestError) {smallestError = error;returnError = res;} |
| } |
| return returnError; |
| } |
| |
| /** |
| * Root Mean Square Difference Comparison |
| * Compares data from two scenarios: the referenceDirectory and the comparisonDirectory |
| * The comparison directory will recursively traverse directories to search for log files. |
| * When found, a comparison is done and the results is written to the comparison directory |
| * including the parameters used for the simulation |
| * |
| * @param referenceLoader |
| * @param comparisonDirectory |
| * @param result |
| * @param runnableContext Context for long running task |
| * @throws LogInitializationException |
| */ |
| public void compareRecursive(CSVscenarioLoader referenceLoader, String comparisonDirectory, Map<Map<String, String>, ErrorResult> result, IRunnableContext runnableContext, ErrorFunction errorfunc) throws LogInitializationException { |
| try { |
| CSVscenarioLoader comparisonLoader = new CSVscenarioLoader(comparisonDirectory); |
| // A valid scenario folder was found. Do the comparison |
| ErrorResult res = _compare(referenceLoader, comparisonLoader, runnableContext, errorfunc); |
| Map<String, String>runParms = comparisonLoader.getRunParameters(); |
| result.put(runParms, res); |
| } catch(LogInitializationException sie) { |
| // The folder did not contain valid log files. Recurse down subdirectories |
| // looking for log files |
| File f = new File(comparisonDirectory); |
| String [] dirs = f.list(); |
| if(dirs != null) |
| for(String dir : dirs) compareRecursive(referenceLoader, comparisonDirectory+File.separator+dir, result, runnableContext, errorfunc); |
| } |
| } |
| |
| |
| /** |
| * Root Mean Square Difference Comparison |
| * Compares data from two scenarios: the referenceDirectory and the comparisonDirectory |
| * @param refLoader |
| * @param compLoader |
| * @param runnableContext Context for long running {@link TaskBar} |
| * @param ErrorFunc Error function |
| * @return the mean square diff |
| * @throws LogInitializationException |
| */ |
| private ErrorResult _compare(CSVscenarioLoader refLoader, CSVscenarioLoader compLoader, IRunnableContext runnableContext, ErrorFunction errorfunc) throws LogInitializationException { |
| int maxRef = refLoader.getMaxResolution(); |
| int maxComp = compLoader.getMaxResolution(); |
| // Find the highest resolution common two both locations and |
| // use it for comparison. |
| int actualRes = (maxRef > maxComp)?maxComp:maxRef; |
| |
| this.referenceScenarioDataMap = refLoader.parseAllFiles(actualRes); |
| |
| this.comparisonScenarioDataMap = compLoader.parseAllFiles(actualRes); |
| |
| ErrorCalculator msd = new ErrorCalculator(referenceScenarioDataMap, comparisonScenarioDataMap, errorfunc); |
| |
| ErrorResult result = msd.solve(runnableContext); |
| return result; |
| } |
| |
| /** |
| * |
| * @param directory |
| * @return true is a data directory exists |
| */ |
| public boolean validate(String directory) { |
| return CSVscenarioLoader.validate(directory); |
| } |
| |
| /** |
| * Root Mean Square Difference Comparison |
| * Compares data from two scenarios: the referenceDirectory and the comparisonDirectory |
| * @param referenceDirectory |
| * @param comparisonDirectory |
| * @param runnableContext Context for long running tasks |
| * @return the mean square diff |
| * @throws LogInitializationException Thrown if problems encountered reading data |
| */ |
| |
| public List<PhaseSpaceCoordinate[]> getLyapunovTrajectory(String referenceDirectory, String comparisonDirectory, IRunnableContext runnableContext) throws LogInitializationException { |
| |
| // for reference and for single scenario analysis |
| CSVscenarioLoader refLoader = new CSVscenarioLoader(referenceDirectory); |
| int maxRef = refLoader.getMaxResolution(); |
| if(maxRef <=-1) return null; |
| // for testing comparison functions |
| CSVscenarioLoader compLoader = new CSVscenarioLoader(comparisonDirectory); |
| int maxComp = compLoader.getMaxResolution(); |
| int actualRes = (maxRef > maxComp)?maxComp:maxRef; |
| if(actualRes<=-1) return null; |
| this.referenceScenarioDataMap = refLoader.parseAllFiles(actualRes); |
| this.comparisonScenarioDataMap = compLoader.parseAllFiles(actualRes); |
| |
| LyapunovAnalysis lyap = new LyapunovAnalysis(referenceScenarioDataMap, comparisonScenarioDataMap, runnableContext); |
| |
| List<PhaseSpaceCoordinate[]> retVal = lyap.getLyapunovTrajectory(runnableContext); |
| return retVal; |
| } |
| |
| /** |
| * |
| * @param trajectoryList |
| * @return the deviation as List(double[]) |
| */ |
| public static List<EList<Double>> getCumulativePhaseSpaceDeviation(List<PhaseSpaceCoordinate[]> trajectoryList) { |
| List<EList<Double>> deviation = LyapunovAnalysis.getCumulativePhaseSpaceDeviation(trajectoryList); |
| return deviation; |
| |
| } |
| |
| /** |
| * |
| * @return the current estimator |
| */ |
| public ParameterEstimator getEstimator() { |
| return estimator.getEstimator(); |
| } |
| |
| |
| |
| } |