Executor.java [src/java/m/sensitivity/model] Revision: default Date:
package m.sensitivity.model;
import com.ezylang.evalex.Expression;
import com.ezylang.evalex.data.EvaluationValue;
import java.io.BufferedReader;
import java.io.File;
import java.io.PrintWriter;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import m.sensitivity.model.methods.SensitivityAnalyzer;
/**
*
* @author nathan
*/
public class Executor {
private final Path trace;
private final List<String> parameters;
private final List<String> positiveBestMetrics;
private final List<String> zeroBestMetrics;
private final List<Map<String, Object>> customMetrics;
private final Map<String, List<Double>> parameterMap = new LinkedHashMap<>();
private final Map<String, List<Double>> metricMap = new HashMap<>();
private boolean init = false;
public Executor(File trace, String[] parameters,
String[] positiveBestMetrics, String[] zeroBestMetrics,
List<Map<String, Object>> customMetrics) {
this.trace = trace.toPath();
this.parameters = new ArrayList<>(Arrays.asList(parameters));
this.positiveBestMetrics = new ArrayList<>(Arrays.asList(positiveBestMetrics));
this.zeroBestMetrics = new ArrayList<>(Arrays.asList(zeroBestMetrics));
this.customMetrics = customMetrics;
for (Map<String, Object> map : this.customMetrics) {
String name = String.valueOf(map.get("name"));
boolean positiveBest = (Boolean) map.get("positiveBest");
if (positiveBest) {
this.positiveBestMetrics.add(name);
} else {
this.zeroBestMetrics.add(name);
}
}
}
public void execute(SensitivityAnalyzer sa, Path outputDirectory) {
if (!init) {
readTrace();
init = true;
}
for (String metric : positiveBestMetrics) {
execute(sa, metric, true, outputDirectory);
}
for (String metric : zeroBestMetrics) {
execute(sa, metric, false, outputDirectory);
}
}
private void readTrace() {
try (BufferedReader reader = Files.newBufferedReader(trace)) {
String header = reader.readLine();
String[] split = header.split(",");
Map<String, Integer> indexMap = new HashMap<>();
for (int i = 0; i < split.length; ++i) {
indexMap.put(split[i], i);
}
Set<String> params = new HashSet<>();
Set<String> metrics = new HashSet<>();
for (String p : parameters) {
if (indexMap.containsKey(p)) {
params.add(p);
parameterMap.put(p, new ArrayList<>());
}
}
for (String m : positiveBestMetrics) {
if (indexMap.containsKey(m)) {
metrics.add(m);
metricMap.put(m, new ArrayList<>());
}
}
for (String m : zeroBestMetrics) {
if (indexMap.containsKey(m)) {
metrics.add(m);
metricMap.put(m, new ArrayList<>());
}
}
String line;
while ((line = reader.readLine()) != null) {
split = line.split(",");
for (String p : params) {
int i = indexMap.get(p);
parameterMap.get(p).add(Double.valueOf(split[i]));
}
for (String m : metrics) {
if (indexMap.containsKey(m)) {
int i = indexMap.get(m);
metricMap.get(m).add(Double.valueOf(split[i]));
}
}
if (!customMetrics.isEmpty()) {
Map<String, Double> values = new HashMap<>();
for (Map.Entry<String, Integer> entry : indexMap.entrySet()) {
values.put(entry.getKey(), Double.valueOf(split[entry.getValue()]));
}
for (Map<String, Object> customMetric : customMetrics) {
String name = String.valueOf(customMetric.get("name"));
String value = String.valueOf(customMetric.get("value"));
Expression exp = new Expression(value);
EvaluationValue result = exp.withValues(values).evaluate();
if (metricMap.containsKey(name)) {
metricMap.get(name).add(result.getNumberValue().doubleValue());
} else {
List<Double> list = new ArrayList<>();
list.add(result.getNumberValue().doubleValue());
metricMap.put(name, list);
}
}
}
}
} catch (Exception ex) {
throw new RuntimeException("Error reading values: " + trace, ex);
}
}
private void execute(SensitivityAnalyzer sa, String metric, boolean isPositiveBest, Path outputDirectory) {
if (metricMap.containsKey(metric)) {
Map<String, Double> sensitivityMap = sa.compute(parameterMap, metricMap.get(metric), isPositiveBest);
sensitivityMap = sortMapByValueReversed(sensitivityMap);
Path outputFilePath = outputDirectory.resolve("output_" + sa.getName() + "_" + metric + ".csv");
writeOutput(outputFilePath, sensitivityMap);
}
}
private static Map<String, Double> sortMapByValueReversed(Map<String, Double> map) {
List<Map.Entry<String, Double>> list = new ArrayList<>(map.entrySet());
list.sort((o1, o2) -> {
// reverse order so the highest value is first
return Double.compare(o2.getValue(), o1.getValue());
});
Map<String, Double> result = new LinkedHashMap<>();
for (Map.Entry<String, Double> entry : list) {
result.put(entry.getKey(), entry.getValue());
}
return result;
}
private static void writeOutput(Path outputFilePath, Map<String, Double> sensitivityMap) {
try (PrintWriter writer = new PrintWriter(Files.newBufferedWriter(outputFilePath))) {
writer.println("parameter,sensitivity");
for (Map.Entry<String, Double> entry : sensitivityMap.entrySet()) {
writer.println(entry.getKey() + "," + entry.getValue());
}
} catch (Exception ex) {
throw new RuntimeException("Failed to write output: " + outputFilePath, ex);
}
}
}