From 98e0479f26ce0bc54016c4fba8e74e3223203b9a Mon Sep 17 00:00:00 2001 From: 20001LastOrder Date: Wed, 5 Jun 2019 11:38:23 -0400 Subject: plotting for metrics during generation --- .../realistic/metrics/calculator/app/Domain.xtend | 5 ++ .../realistic/metrics/calculator/app/Main.xtend | 4 +- .../app/PartialInterpretationMetric.xtend | 45 +++++++++++- .../metrics/calculator/distance/KSDistance.xtend | 47 +++++++++++++ .../realistic/metrics/calculator/graph/Graph.xtend | 20 ++++++ .../metrics/calculator/input/GraphReader.xtend | 81 ---------------------- .../input/PartialInterpretationReader.xtend | 7 -- .../metrics/calculator/io/CsvFileWriter.xtend | 37 ++++++++++ .../metrics/calculator/io/GraphReader.xtend | 81 ++++++++++++++++++++++ .../metrics/calculator/io/RepMetricsReader.xtend | 79 +++++++++++++++++++++ .../metrics/calculator/metrics/Metric.xtend | 1 + .../calculator/metrics/MetricSampleGroup.xtend | 9 +++ .../MultiplexParticipationCoefficientMetric.xtend | 59 ++++++++++------ .../calculator/metrics/NodeActivityMetric.xtend | 16 ++++- .../calculator/metrics/OutDegreeMetric.xtend | 15 +++- .../metrics/calculator/output/CsvFileWriter.xtend | 37 ---------- 16 files changed, 389 insertions(+), 154 deletions(-) create mode 100644 Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/app/Domain.xtend create mode 100644 Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/distance/KSDistance.xtend delete mode 100644 Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/input/GraphReader.xtend delete mode 100644 Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/input/PartialInterpretationReader.xtend create mode 100644 Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/io/CsvFileWriter.xtend create mode 100644 Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/io/GraphReader.xtend create mode 100644 Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/io/RepMetricsReader.xtend create mode 100644 Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/metrics/MetricSampleGroup.xtend delete mode 100644 Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/output/CsvFileWriter.xtend (limited to 'Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator') diff --git a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/app/Domain.xtend b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/app/Domain.xtend new file mode 100644 index 00000000..8351e96b --- /dev/null +++ b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/app/Domain.xtend @@ -0,0 +1,5 @@ +package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.app + +enum Domain{ + Yakinduum +} \ No newline at end of file diff --git a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/app/Main.xtend b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/app/Main.xtend index 15df0dde..cf871ead 100644 --- a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/app/Main.xtend +++ b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/app/Main.xtend @@ -1,8 +1,8 @@ package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.app import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.graph.EMFGraph -import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.input.GraphReader -import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.output.CsvFileWriter +import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.io.CsvFileWriter +import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.io.GraphReader import hu.bme.mit.inf.dslreasoner.domains.yakindu.sgraph.yakindumm.impl.YakindummPackageImpl import java.util.ArrayList diff --git a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/app/PartialInterpretationMetric.xtend b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/app/PartialInterpretationMetric.xtend index 0e505d30..cdd06027 100644 --- a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/app/PartialInterpretationMetric.xtend +++ b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/app/PartialInterpretationMetric.xtend @@ -1,11 +1,12 @@ package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.app +import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.distance.KSDistance import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.graph.PartialInterpretationGraph +import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.io.CsvFileWriter import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.Metric import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.MultiplexParticipationCoefficientMetric import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.NodeActivityMetric import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.OutDegreeMetric -import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.output.CsvFileWriter import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation import java.io.File import java.io.FileNotFoundException @@ -17,10 +18,28 @@ import org.eclipse.viatra.dse.api.Solution class PartialInterpretationMetric { var static state = 0; + var static KSDistance ks; def static void initPaths(){ new File("debug/metric/").mkdir(); new File("debug/metric/trajectories/").mkdir(); + ks = new KSDistance(Domain.Yakinduum); + } + + def static MetricDistanceGroup calculateMetricDistance(PartialInterpretation partial){ + val metrics = new ArrayList(); + metrics.add(new OutDegreeMetric()); + metrics.add(new NodeActivityMetric()); + metrics.add(new MultiplexParticipationCoefficientMetric()); + + val metricCalculator = new PartialInterpretationGraph(partial, metrics, null); + var metricSamples = metricCalculator.evaluateAllMetricsToSamples(); + + var mpc = ks.mpcDistance(metricSamples.mpcSamples); + var na = ks.naDistance(metricSamples.naSamples); + var outDegree = ks.outDegreeDistance(metricSamples.outDegreeSamples); + + return new MetricDistanceGroup(mpc, na, outDegree); } // calculate the metrics for a state @@ -78,4 +97,28 @@ class PartialInterpretationMetric { } } } +} + +class MetricDistanceGroup{ + var double mpcDistance; + var double naDistance; + var double outDegreeDistance; + + new(double mpcDistance, double naDistance, double outDegreeDistance){ + this.mpcDistance = mpcDistance; + this.naDistance = naDistance; + this.outDegreeDistance = outDegreeDistance; + } + + def double getMPCDistance(){ + return this.mpcDistance + } + + def double getNADistance(){ + return this.naDistance + } + + def double getOutDegreeDistance(){ + return this.outDegreeDistance + } } \ No newline at end of file diff --git a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/distance/KSDistance.xtend b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/distance/KSDistance.xtend new file mode 100644 index 00000000..1fb21529 --- /dev/null +++ b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/distance/KSDistance.xtend @@ -0,0 +1,47 @@ +package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.distance + +import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.app.Domain +import java.util.List +import org.apache.commons.math3.stat.inference.KolmogorovSmirnovTest +import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.io.RepMetricsReader + +class KSDistance { + var static ksTester = new KolmogorovSmirnovTest(); + var double[] mpcSamples; + var double[] naSamples; + var double[] outDegreeSamples; + + new(Domain d){ + var metrics = RepMetricsReader.read(d); + mpcSamples = metrics.mpcSamples; + naSamples = metrics.naSamples.stream.mapToDouble([it]).toArray(); + outDegreeSamples = metrics.outDegreeSamples.stream.mapToDouble([it]).toArray(); + } + + def double mpcDistance(List samples){ + // map list to array + var arr = samples.stream.mapToDouble([it]).toArray(); + + //if the size of array is smaller than 2, ks distance cannot be performed, simply return 1 + if(arr.size < 2) return 1; + return ksTester.kolmogorovSmirnovStatistic(mpcSamples, arr); + } + + def double naDistance(List samples){ + // map list to array + var arr = samples.stream.mapToDouble([it]).toArray(); + + //if the size of array is smaller than 2, ks distance cannot be performed, simply return 1 + if(arr.size < 2) return 1; + return ksTester.kolmogorovSmirnovStatistic(naSamples as double[], arr); + } + + def double outDegreeDistance(List samples){ + // map list to array + var arr = samples.stream.mapToDouble([it]).toArray(); + + //if the size of array is smaller than 2, ks distance cannot be performed, simply return 1 + if(arr.size < 2) return 1; + return ksTester.kolmogorovSmirnovStatistic(outDegreeSamples, arr); + } +} \ No newline at end of file diff --git a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/graph/Graph.xtend b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/graph/Graph.xtend index 6d65367f..cf4aedba 100644 --- a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/graph/Graph.xtend +++ b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/graph/Graph.xtend @@ -1,8 +1,12 @@ package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.graph import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.Metric +import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.MetricSampleGroup import java.util.ArrayList import java.util.List +import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.MultiplexParticipationCoefficientMetric +import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.NodeActivityMetric +import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.OutDegreeMetric abstract class Graph { @@ -33,6 +37,22 @@ abstract class Graph { return result; } + def MetricSampleGroup evaluateAllMetricsToSamples(){ + var sample = new MetricSampleGroup(); + + for(metric : this.metrics){ + if(metric instanceof MultiplexParticipationCoefficientMetric){ + sample.mpcSamples = metric.evaluateSamples(this.statistic); + }else if(metric instanceof NodeActivityMetric){ + sample.naSamples = metric.evaluateSamples(this.statistic); + }else if(metric instanceof OutDegreeMetric){ + sample.outDegreeSamples = metric.evaluateSamples(this.statistic); + } + } + + return sample; + } + def void setBasicInformation(ArrayList> result); def GraphStatistic getStatistic(); diff --git a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/input/GraphReader.xtend b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/input/GraphReader.xtend deleted file mode 100644 index 56bf95a3..00000000 --- a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/input/GraphReader.xtend +++ /dev/null @@ -1,81 +0,0 @@ -package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.input - -import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.graph.EMFGraph -import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.Metric -import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.MultiplexParticipationCoefficientMetric -import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.NodeActivityMetric -import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.OutDegreeMetric -import java.io.File -import java.io.FileNotFoundException -import java.util.ArrayList -import java.util.List -import org.eclipse.emf.common.util.URI -import org.eclipse.emf.ecore.EObject -import org.eclipse.emf.ecore.EPackage -import org.eclipse.emf.ecore.EReference -import org.eclipse.emf.ecore.resource.Resource -import org.eclipse.emf.ecore.resource.ResourceSet -import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl -import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl - -class GraphReader{ - val ResourceSet resSet = new ResourceSetImpl(); - val referenceTypes = new ArrayList(); - - new(EPackage metaModel) { - Resource.Factory.Registry.INSTANCE.extensionToFactoryMap.put("*",new XMIResourceFactoryImpl) - - //find all reference types in the meta model - metaModel.eAllContents.forEach[ - if(it instanceof EReference){ - referenceTypes.add(it.name); - } - ] - } - - def List readModels(String path){ - val dir = new File(path); - if(!dir.isDirectory){ - throw new Exception("expecting a directory"); - } - - val graphs = new ArrayList(); - - val metrics = new ArrayList(); - metrics.add(new OutDegreeMetric()); - metrics.add(new NodeActivityMetric()); - metrics.add(new MultiplexParticipationCoefficientMetric()); - - //check all files in the directory with xmi - for(String name : dir.list.filter[it| it.endsWith(".xmi")]){ - val file = new File(name); - val roots = readModel(EObject, path, file.name); - //add a list of metrics - val g = new EMFGraph(); - for(root : roots){ - g.init(root, metrics, name.replaceFirst(".xmi", ""), referenceTypes); - } - - graphs.add(g); - } - - return graphs; - } - - def List readModel(Class type, String path, String name) { - try { - val resource = resSet.getResource(getURI(path, name),true); - if(resource === null) throw new FileNotFoundException(getURI(path, name).toString) - else { - return resource.contents as List - } - } catch(Exception e) { - e.printStackTrace(); - throw new FileNotFoundException(getURI(path, name).toString + "reason: " + e.message) - } - } - - def static getURI(String path, String name) { - URI.createFileURI(path + "/" + name) - } -} \ No newline at end of file diff --git a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/input/PartialInterpretationReader.xtend b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/input/PartialInterpretationReader.xtend deleted file mode 100644 index dbaf36b2..00000000 --- a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/input/PartialInterpretationReader.xtend +++ /dev/null @@ -1,7 +0,0 @@ -package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.input - -import hu.bme.mit.inf.dslreasoner.viatrasolver.partialinterpretationlanguage.partialinterpretation.PartialInterpretation - -class PartialInterpretationReader { - -} \ No newline at end of file diff --git a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/io/CsvFileWriter.xtend b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/io/CsvFileWriter.xtend new file mode 100644 index 00000000..bed356e9 --- /dev/null +++ b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/io/CsvFileWriter.xtend @@ -0,0 +1,37 @@ +package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.io; + +import java.io.File +import java.io.FileNotFoundException +import java.io.PrintWriter +import java.util.ArrayList +import java.util.List + +class CsvFileWriter { + def static void write(ArrayList> datas, String uri) { + if(datas.size() <= 0) { + return; + } + + //println("Output csv for " + uri); + try { + val PrintWriter writer = new PrintWriter(new File(uri)); + val output = new StringBuilder; + for(List datarow : datas){ + for(var i = 0; i < datarow.size() - 1; i++){ + output.append(datarow.get(i) + ','); + } + + if(datarow.size > 1){ + output.append(datarow.get(datarow.size() - 1)); + output.append('\n'); + } + } + + writer.write(output.toString()); + writer.close(); + //println("Output csv finished"); + }catch(FileNotFoundException e) { + e.printStackTrace(); + } + } +} diff --git a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/io/GraphReader.xtend b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/io/GraphReader.xtend new file mode 100644 index 00000000..fc56e142 --- /dev/null +++ b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/io/GraphReader.xtend @@ -0,0 +1,81 @@ +package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.io; + +import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.graph.EMFGraph +import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.Metric +import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.MultiplexParticipationCoefficientMetric +import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.NodeActivityMetric +import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.OutDegreeMetric +import java.io.File +import java.io.FileNotFoundException +import java.util.ArrayList +import java.util.List +import org.eclipse.emf.common.util.URI +import org.eclipse.emf.ecore.EObject +import org.eclipse.emf.ecore.EPackage +import org.eclipse.emf.ecore.EReference +import org.eclipse.emf.ecore.resource.Resource +import org.eclipse.emf.ecore.resource.ResourceSet +import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl +import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl + +class GraphReader{ + val ResourceSet resSet = new ResourceSetImpl(); + val referenceTypes = new ArrayList(); + + new(EPackage metaModel) { + Resource.Factory.Registry.INSTANCE.extensionToFactoryMap.put("*",new XMIResourceFactoryImpl) + + //find all reference types in the meta model + metaModel.eAllContents.forEach[ + if(it instanceof EReference){ + referenceTypes.add(it.name); + } + ] + } + + def List readModels(String path){ + val dir = new File(path); + if(!dir.isDirectory){ + throw new Exception("expecting a directory"); + } + + val graphs = new ArrayList(); + + val metrics = new ArrayList(); + metrics.add(new OutDegreeMetric()); + metrics.add(new NodeActivityMetric()); + metrics.add(new MultiplexParticipationCoefficientMetric()); + + //check all files in the directory with xmi + for(String name : dir.list.filter[it| it.endsWith(".xmi")]){ + val file = new File(name); + val roots = readModel(EObject, path, file.name); + //add a list of metrics + val g = new EMFGraph(); + for(root : roots){ + g.init(root, metrics, name.replaceFirst(".xmi", ""), referenceTypes); + } + + graphs.add(g); + } + + return graphs; + } + + def List readModel(Class type, String path, String name) { + try { + val resource = resSet.getResource(getURI(path, name),true); + if(resource === null) throw new FileNotFoundException(getURI(path, name).toString) + else { + return resource.contents as List + } + } catch(Exception e) { + e.printStackTrace(); + throw new FileNotFoundException(getURI(path, name).toString + "reason: " + e.message) + } + } + + def static getURI(String path, String name) { + URI.createFileURI(path + "/" + name) + } +} \ No newline at end of file diff --git a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/io/RepMetricsReader.xtend b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/io/RepMetricsReader.xtend new file mode 100644 index 00000000..867ddd1a --- /dev/null +++ b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/io/RepMetricsReader.xtend @@ -0,0 +1,79 @@ +package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.io + +import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.app.Domain +import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.MultiplexParticipationCoefficientMetric +import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.NodeActivityMetric +import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.OutDegreeMetric +import java.io.File +import java.util.List +import java.util.Scanner +import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics.MetricSampleGroup + +/** + * Read the sample of the distribution of a metric provided the csv file of the metric + */ +class RepMetricsReader { + static def read(Domain d){ + var domainRepPath = CsvDataName.REP_PATH + d.name + '/'; + var rep = new MetricSampleGroup() + rep.mpcSamples = readFile(domainRepPath + CsvDataName.MPC_REP, MultiplexParticipationCoefficientMetric.valueName, + MultiplexParticipationCoefficientMetric.countName).map[Double.parseDouble(it)]; + rep.naSamples = readFile(domainRepPath+CsvDataName.NA_REP, NodeActivityMetric.valueName, NodeActivityMetric.countName + ).map[Double.parseDouble(it)]; + rep.outDegreeSamples = readFile(domainRepPath+CsvDataName.OUT_D_REP, OutDegreeMetric.valueName, OutDegreeMetric.countName + ).map[Double.parseDouble(it)]; + return rep; + } + + /** + * read metric data and parse it to samples + */ + private static def List readFile(String filename, String valueDataName, String countDataName){ + var s = new Scanner(new File(filename)); + val counts = newArrayList(); + val values = newArrayList(); + //read data from csv + while(s.hasNext()){ + var data = s.nextLine().split(','); + + if(data.size >= 1){ + if(data.get(0).equals(countDataName)){ + //add all data with parsing them as integers + counts.addAll(data.subList(1, data.size()).map[Integer.parseInt(it)]); + }else if(data.get(0).equals(valueDataName)){ + //add all data without parsing (there can be either double or string, to be parsed later) + values.addAll(data.subList(1, data.size())); + } + } + } + + return createSamples(counts, values); + } + + // create samples from values and counts + private static def List createSamples(List counts, List values){ + val samples = newArrayList(); + + if(counts.size() != values.size()){ + throw new RuntimeException("counts and values should have the same size!"); + } + + for(var i = 0; i < counts.size(); i++){ + for(var j = 0; j < counts.get(i); j++){ + samples.add(values.get(i)); + } + } + + return samples; + } + + +} + +class CsvDataName{ + public static val REP_PATH = 'data/'; + public static val MPC_REP = 'mpc_rep.csv'; + public static val NA_REP = 'na_rep.csv'; + public static val OUT_D_REP = 'out_d_rep.csv'; +} + diff --git a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/metrics/Metric.xtend b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/metrics/Metric.xtend index ea52009a..38ef72f2 100644 --- a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/metrics/Metric.xtend +++ b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/metrics/Metric.xtend @@ -4,4 +4,5 @@ import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.graph.GraphStatis abstract class Metric { abstract def String[][] evaluate(GraphStatistic g); + abstract def double[] evaluateSamples(GraphStatistic g); } \ No newline at end of file diff --git a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/metrics/MetricSampleGroup.xtend b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/metrics/MetricSampleGroup.xtend new file mode 100644 index 00000000..8cd3daee --- /dev/null +++ b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/metrics/MetricSampleGroup.xtend @@ -0,0 +1,9 @@ +package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics + +import java.util.List + +class MetricSampleGroup{ + public var List mpcSamples; + public var List naSamples; + public var List outDegreeSamples; +} \ No newline at end of file diff --git a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/metrics/MultiplexParticipationCoefficientMetric.xtend b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/metrics/MultiplexParticipationCoefficientMetric.xtend index 7bd48754..d9c88bb4 100644 --- a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/metrics/MultiplexParticipationCoefficientMetric.xtend +++ b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/metrics/MultiplexParticipationCoefficientMetric.xtend @@ -2,11 +2,13 @@ package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.graph.GraphStatistic import java.text.DecimalFormat +import java.util.ArrayList import java.util.HashMap +import org.eclipse.emf.ecore.EObject class MultiplexParticipationCoefficientMetric extends Metric { - static val countName = "MPCCount"; - static val valueName = "MPCValue"; + public static val countName = "MPCCount"; + public static val valueName = "MPCValue"; override evaluate(GraphStatistic g) { @@ -18,26 +20,7 @@ class MultiplexParticipationCoefficientMetric extends Metric { val map = new HashMap(); //calculate the metric distribution g.allNodes.forEach[n| - val edgeCounts = g.outDegree(n) + g.inDegree(n); - - var coef = 0.0; - - for(type : g.allTypes){ - val degree = g.dimentionalDegree(n, type) as double; - coef += Math.pow(degree / edgeCounts, 2); - } - coef = 1 - coef; - coef = coef * typeCounts / (typeCounts-1); - - //Consider the case that either typeCounts-1 or the edgeCounts could be 0 in some situation - //in this case the metric should be evaluated to 0 - if(typeCounts == 1){ - println("bad"); - } - - if(Double.isNaN(coef)){ - coef = 0; - } + var coef = calculateMPC(n, g, typeCounts); //format number to String val value = formatter.format(coef); @@ -62,4 +45,36 @@ class MultiplexParticipationCoefficientMetric extends Metric { return datas; } + + override evaluateSamples(GraphStatistic g){ + val samples = new ArrayList(); + val typeCounts = g.allTypes.size; + //calculate the metric distribution + g.allNodes.forEach[ + samples.add(calculateMPC(it, g, typeCounts)); + ] + + return samples; + } + + def double calculateMPC(EObject n, GraphStatistic g, int typeCounts){ + val edgeCounts = g.outDegree(n) + g.inDegree(n); + + var coef = 0.0; + + for(type : g.allTypes){ + val degree = g.dimentionalDegree(n, type) as double; + coef += Math.pow(degree / edgeCounts, 2); + } + coef = 1 - coef; + coef = coef * typeCounts / (typeCounts-1); + + //Consider the case that either typeCounts-1 or the edgeCounts could be 0 in some situation + //in this case the metric should be evaluated to 0 + if(Double.isNaN(coef)){ + coef = 0; + } + + return coef; + } } \ No newline at end of file diff --git a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/metrics/NodeActivityMetric.xtend b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/metrics/NodeActivityMetric.xtend index 297bdd14..fbf06c47 100644 --- a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/metrics/NodeActivityMetric.xtend +++ b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/metrics/NodeActivityMetric.xtend @@ -1,11 +1,12 @@ package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.graph.GraphStatistic +import java.util.ArrayList import java.util.HashMap class NodeActivityMetric extends Metric { - static val countName = "NACount"; - static val valueName = "NAValue"; + public static val countName = "NACount"; + public static val valueName = "NAValue"; override evaluate(GraphStatistic g) { val map = new HashMap(); @@ -34,4 +35,15 @@ class NodeActivityMetric extends Metric { return datas; } + + override evaluateSamples(GraphStatistic g){ + val samples = new ArrayList(); + + //calculate the metric distribution + g.allNodes.forEach[ + samples.add(g.numOfEdgeTypes(it) as double); + ] + + return samples; + } } \ No newline at end of file diff --git a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/metrics/OutDegreeMetric.xtend b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/metrics/OutDegreeMetric.xtend index 1ba6c8c7..55046b14 100644 --- a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/metrics/OutDegreeMetric.xtend +++ b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/metrics/OutDegreeMetric.xtend @@ -1,11 +1,12 @@ package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.metrics import ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.graph.GraphStatistic +import java.util.ArrayList import java.util.HashMap class OutDegreeMetric extends Metric { - static val countName = "OutDegreeCount"; - static val valueName = "OutDegreeValue"; + public static val countName = "OutDegreeCount"; + public static val valueName = "OutDegreeValue"; override evaluate(GraphStatistic g) { val map = new HashMap(); @@ -34,5 +35,15 @@ class OutDegreeMetric extends Metric { return datas; } + override evaluateSamples(GraphStatistic g){ + val samples = new ArrayList(); + + //calculate the metric distribution + g.allNodes.forEach[ + samples.add(g.outDegree(it) as double); + ] + + return samples; + } } \ No newline at end of file diff --git a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/output/CsvFileWriter.xtend b/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/output/CsvFileWriter.xtend deleted file mode 100644 index 1dd204a0..00000000 --- a/Metrics/Metrics-Calculation/ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator/src/ca/mcgill/ecse/dslreasoner/realistic/metrics/calculator/output/CsvFileWriter.xtend +++ /dev/null @@ -1,37 +0,0 @@ -package ca.mcgill.ecse.dslreasoner.realistic.metrics.calculator.output; - -import java.io.File -import java.io.FileNotFoundException -import java.io.PrintWriter -import java.util.ArrayList -import java.util.List - -class CsvFileWriter { - def static void write(ArrayList> datas, String uri) { - if(datas.size() <= 0) { - return; - } - - //println("Output csv for " + uri); - try { - val PrintWriter writer = new PrintWriter(new File(uri)); - val output = new StringBuilder; - for(List datarow : datas){ - for(var i = 0; i < datarow.size() - 1; i++){ - output.append(datarow.get(i) + ','); - } - - if(datarow.size > 1){ - output.append(datarow.get(datarow.size() - 1)); - output.append('\n'); - } - } - - writer.write(output.toString()); - writer.close(); - //println("Output csv finished"); - }catch(FileNotFoundException e) { - e.printStackTrace(); - } - } -} -- cgit v1.2.3-54-g00ecf