From 4293dc3fbcf495457e0dfac51e0c993fbbf76c1e Mon Sep 17 00:00:00 2001 From: Richard Palmer Date: Mon, 28 Jun 2021 22:15:02 +0100 Subject: [PATCH 1/5] Adding Echo Calculator to return fields in output --- .../api/calculator/CalculatorFactory.java | 6 +++++ .../MeasurementConfiguration.java | 24 +++++++++++++++++++ .../api/configuration/schema/Field.java | 10 ++++++++ .../gwdg/metadataqa/api/json/JsonBranch.java | 15 ++++++++++++ 4 files changed, 55 insertions(+) diff --git a/src/main/java/de/gwdg/metadataqa/api/calculator/CalculatorFactory.java b/src/main/java/de/gwdg/metadataqa/api/calculator/CalculatorFactory.java index 01a9ac65..ca9c0d21 100644 --- a/src/main/java/de/gwdg/metadataqa/api/calculator/CalculatorFactory.java +++ b/src/main/java/de/gwdg/metadataqa/api/calculator/CalculatorFactory.java @@ -44,6 +44,7 @@ private void configure() { addLanguageMeasurement(); addMultilingualSaturationMeasurement(); addUniquenessMeasurement(); + addEcho(); } private void addExtractor() { @@ -51,6 +52,11 @@ private void addExtractor() { calculators.add(new FieldExtractor(schema)); } + private void addEcho() { + if (configuration.isEchoEnabled()) + calculators.add(new EchoField(schema)); + } + private void addCompleteness() { if (configuration.isCompletenessMeasurementEnabled()) { CompletenessCalculator completenessCalculator = new CompletenessCalculator(schema); diff --git a/src/main/java/de/gwdg/metadataqa/api/configuration/MeasurementConfiguration.java b/src/main/java/de/gwdg/metadataqa/api/configuration/MeasurementConfiguration.java index 7f86846c..5460479b 100644 --- a/src/main/java/de/gwdg/metadataqa/api/configuration/MeasurementConfiguration.java +++ b/src/main/java/de/gwdg/metadataqa/api/configuration/MeasurementConfiguration.java @@ -11,6 +11,11 @@ public class MeasurementConfiguration { */ private boolean fieldExtractorEnabled = false; + /** + * Flag whether or not field echo is enabled (default: false). + */ + private boolean fieldEchoEnabled = false; + /** * Flag whether or not run the field existence measurement * (default: true). @@ -122,11 +127,13 @@ public MeasurementConfiguration() {} * Flag whether or not run the problem catalog */ public MeasurementConfiguration(final boolean runFieldExistence, + final boolean runFieldEcho, final boolean runFieldCardinality, final boolean runCompleteness, final boolean runTfIdf, final boolean runProblemCatalog) { this.fieldExistenceMeasurementEnabled = runFieldExistence; + this.fieldEchoEnabled = runFieldEcho; this.fieldCardinalityMeasurementEnabled = runFieldCardinality; this.completenessMeasurementEnabled = runCompleteness; this.tfIdfMeasurementEnabled = runTfIdf; @@ -154,6 +161,23 @@ public boolean isFieldExtractorEnabled() { return fieldExtractorEnabled; } + public MeasurementConfiguration enableEcho() { + return enableEcho(true); + } + + public MeasurementConfiguration disableEcho() { + return enableEcho(false); + } + + public MeasurementConfiguration enableEcho(boolean flag) { + this.echoEnabled = flag; + return this; + } + + public boolean isEchoEnabled() { + return echoEnabled; + } + /** * Returns whether or not to run the field existence measurement. * @return diff --git a/src/main/java/de/gwdg/metadataqa/api/configuration/schema/Field.java b/src/main/java/de/gwdg/metadataqa/api/configuration/schema/Field.java index f4016993..5a53bff4 100644 --- a/src/main/java/de/gwdg/metadataqa/api/configuration/schema/Field.java +++ b/src/main/java/de/gwdg/metadataqa/api/configuration/schema/Field.java @@ -7,6 +7,7 @@ public class Field { private String path; private List categories; private boolean extractable; + private boolean echo; private List rules; private String indexField; @@ -42,6 +43,15 @@ public void setExtractable(boolean extractable) { this.extractable = extractable; } + public boolean isEcho() { + return echo; + } + + public void setEcho(boolean echo) { + this.echo= echo; + } + + public List getRules() { return rules; } diff --git a/src/main/java/de/gwdg/metadataqa/api/json/JsonBranch.java b/src/main/java/de/gwdg/metadataqa/api/json/JsonBranch.java index 6b18d0c2..9eed5a19 100644 --- a/src/main/java/de/gwdg/metadataqa/api/json/JsonBranch.java +++ b/src/main/java/de/gwdg/metadataqa/api/json/JsonBranch.java @@ -28,6 +28,7 @@ public class JsonBranch implements Cloneable, Serializable { private boolean collection = false; private boolean isActive = true; private boolean isExtractable = false; + private boolean isEcho = false; private boolean isMandatory = false; private List rules; private Schema schema; @@ -205,6 +206,20 @@ public JsonBranch setExtractable(boolean extractable) { return this; } + public boolean isEcho() { + return isEcho; + } + + public JsonBranch setEcho() { + isEcho = true; + return this; + } + + public JsonBranch setEcho(boolean echo) { + isEcho = echo; + return this; + } + public List getRules() { return rules; } From c381d5b5fd2be4f3f1f1d15031af9e34f93914d6 Mon Sep 17 00:00:00 2001 From: Richard Palmer Date: Tue, 29 Jun 2021 21:04:09 +0100 Subject: [PATCH 2/5] Correct fieldname --- .../api/configuration/MeasurementConfiguration.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/de/gwdg/metadataqa/api/configuration/MeasurementConfiguration.java b/src/main/java/de/gwdg/metadataqa/api/configuration/MeasurementConfiguration.java index 5460479b..808c4560 100644 --- a/src/main/java/de/gwdg/metadataqa/api/configuration/MeasurementConfiguration.java +++ b/src/main/java/de/gwdg/metadataqa/api/configuration/MeasurementConfiguration.java @@ -170,12 +170,12 @@ public MeasurementConfiguration disableEcho() { } public MeasurementConfiguration enableEcho(boolean flag) { - this.echoEnabled = flag; + this.fieldEchoEnabled = flag; return this; } public boolean isEchoEnabled() { - return echoEnabled; + return fieldEchoEnabled; } /** From 237c6b5ad131d8a613fbe9ba2e2b942a13ff9a41 Mon Sep 17 00:00:00 2001 From: Richard Palmer Date: Tue, 29 Jun 2021 21:04:27 +0100 Subject: [PATCH 3/5] Update schemas to support EchoCalculator --- .../metadataqa/api/schema/BaseSchema.java | 19 +++++++++++++++++ .../metadataqa/api/schema/MarcJsonSchema.java | 16 ++++++++++++++ .../de/gwdg/metadataqa/api/schema/Schema.java | 21 +++++++++++++++++++ .../metadataqa/api/schema/edm/EdmSchema.java | 16 ++++++++++++++ .../metadataqa/api/util/SchemaFactory.java | 3 +++ 5 files changed, 75 insertions(+) diff --git a/src/main/java/de/gwdg/metadataqa/api/schema/BaseSchema.java b/src/main/java/de/gwdg/metadataqa/api/schema/BaseSchema.java index b0818b1e..0708e8b0 100644 --- a/src/main/java/de/gwdg/metadataqa/api/schema/BaseSchema.java +++ b/src/main/java/de/gwdg/metadataqa/api/schema/BaseSchema.java @@ -19,6 +19,7 @@ public class BaseSchema implements Schema, CsvAwareSchema, Serializable { private final Map collectionPaths = new LinkedHashMap<>(); private final Map directChildren = new LinkedHashMap<>(); private Map extractableFields = new LinkedHashMap<>(); + private Map echoFields = new LinkedHashMap<>(); private List categories = null; private List ruleCheckers; private List indexFields; @@ -42,6 +43,9 @@ public BaseSchema addField(JsonBranch branch) { if (branch.isExtractable()) extractableFields.put(branch.getLabel(), branch.getJsonPath()); + if (branch.isEcho()) + echoFields.put(branch.getLabel(), branch.getJsonPath()); + return this; } @@ -123,6 +127,21 @@ public void addExtractableField(String label, String jsonPath) { extractableFields.put(label, jsonPath); } + @Override + public Map getEchoFields() { + return echoFields; + } + + @Override + public void setEchoFields(Map echoFields) { + this.echoFields = echoFields; + } + + @Override + public void addEchoField(String label, String jsonPath) { + echoFields.put(label, jsonPath); + } + @Override public List getCategories() { if (categories == null) { diff --git a/src/main/java/de/gwdg/metadataqa/api/schema/MarcJsonSchema.java b/src/main/java/de/gwdg/metadataqa/api/schema/MarcJsonSchema.java index 3911cd5c..b73d1499 100644 --- a/src/main/java/de/gwdg/metadataqa/api/schema/MarcJsonSchema.java +++ b/src/main/java/de/gwdg/metadataqa/api/schema/MarcJsonSchema.java @@ -23,6 +23,7 @@ public class MarcJsonSchema implements Schema, ProblemCatalogSchema, Serializabl private static final Map DIRECT_CHILDREN = new LinkedHashMap<>(); public static final String NOT_SUPPORTED_YET = "Not supported yet."; private static Map extractableFields = new LinkedHashMap<>(); + private static Map echoFields = new LinkedHashMap<>(); private static List categories = null; private static List ruleCheckers = null; @@ -438,6 +439,21 @@ public void addExtractableField(String label, String jsonPath) { extractableFields.put(label, jsonPath); } + @Override + public Map getEchoFields() { + return echoFields; + } + + @Override + public void setEchoFields(Map echoFields) { + this.echoFields = echoFields; + } + + @Override + public void addEchoField(String label, String jsonPath) { + echoFields.put(label, jsonPath); + } + private static void addPath(JsonBranch branch) { PATHS.put(branch.getLabel(), branch); diff --git a/src/main/java/de/gwdg/metadataqa/api/schema/Schema.java b/src/main/java/de/gwdg/metadataqa/api/schema/Schema.java index bb162cea..386a215c 100644 --- a/src/main/java/de/gwdg/metadataqa/api/schema/Schema.java +++ b/src/main/java/de/gwdg/metadataqa/api/schema/Schema.java @@ -95,6 +95,27 @@ public interface Schema extends Serializable { */ void addExtractableField(String label, String jsonPath); + /** + * Get fields for which the values should be echoed from the records. + * @return The map of echoed fields. The key is the label of a field, + * the value is a JSON path expression. + */ + Map getEchoFields(); + + /** + * Set the echo fields. + * @see #getEchoFields + * @param echoFields The extractable fields. + */ + void setEchoFields(Map echoFields); + + /** + * Add a single field to the map of echo fields. + * @param label The label of the field. + * @param jsonPath JSON path expression. + */ + void addEchoField(String label, String jsonPath); + List getCategories(); List getRuleCheckers(); diff --git a/src/main/java/de/gwdg/metadataqa/api/schema/edm/EdmSchema.java b/src/main/java/de/gwdg/metadataqa/api/schema/edm/EdmSchema.java index f0ebf7e8..7388be05 100644 --- a/src/main/java/de/gwdg/metadataqa/api/schema/edm/EdmSchema.java +++ b/src/main/java/de/gwdg/metadataqa/api/schema/edm/EdmSchema.java @@ -34,6 +34,7 @@ public abstract class EdmSchema implements Schema, ProblemCatalogSchema { protected List ruleCheckers; protected Map extractableFields = new LinkedHashMap<>(); + protected Map echoFields = new LinkedHashMap<>(); protected void addPath(JsonBranch branch) { paths.put(branch.getLabel(), branch); @@ -128,4 +129,19 @@ public void setExtractableFields(Map extractableFields) { public void addExtractableField(String label, String jsonPath) { extractableFields.put(label, jsonPath); } + + @Override + public Map getEchoFields() { + return echoFields; + } + + @Override + public void setEchoFields(Map echoFields) { + this.echoFields = echoFields; + } + + @Override + public void addEchoField(String label, String jsonPath) { + echoFields.put(label, jsonPath); + } } diff --git a/src/main/java/de/gwdg/metadataqa/api/util/SchemaFactory.java b/src/main/java/de/gwdg/metadataqa/api/util/SchemaFactory.java index 46a487fb..a5510b37 100644 --- a/src/main/java/de/gwdg/metadataqa/api/util/SchemaFactory.java +++ b/src/main/java/de/gwdg/metadataqa/api/util/SchemaFactory.java @@ -51,6 +51,9 @@ public static Schema fromConfig(SchemaConfiguration config) { if (field.isExtractable()) branch.setExtractable(); + if (field.isEcho()) + branch.setEcho(); + if (field.getRules() != null) branch.setRule(field.getRules()); From 276cd5fb82ff010de395a8555aec0093802848ce Mon Sep 17 00:00:00 2001 From: Richard Palmer Date: Wed, 30 Jun 2021 21:06:06 +0100 Subject: [PATCH 4/5] Add in the EchoField Calculator --- .../metadataqa/api/calculator/EchoField.java | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 src/main/java/de/gwdg/metadataqa/api/calculator/EchoField.java diff --git a/src/main/java/de/gwdg/metadataqa/api/calculator/EchoField.java b/src/main/java/de/gwdg/metadataqa/api/calculator/EchoField.java new file mode 100644 index 00000000..dd11428b --- /dev/null +++ b/src/main/java/de/gwdg/metadataqa/api/calculator/EchoField.java @@ -0,0 +1,71 @@ +package de.gwdg.metadataqa.api.calculator; + +import com.jayway.jsonpath.InvalidJsonException; +import de.gwdg.metadataqa.api.interfaces.Calculator; +import de.gwdg.metadataqa.api.interfaces.MetricResult; +import de.gwdg.metadataqa.api.model.pathcache.PathCache; +import de.gwdg.metadataqa.api.model.XmlFieldInstance; +import de.gwdg.metadataqa.api.schema.Schema; +import de.gwdg.metadataqa.api.counter.FieldCounter; +import de.gwdg.metadataqa.api.problemcatalog.FieldCounterBasedResult; +import de.gwdg.metadataqa.api.json.JsonBranch; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Logger; + +/** + * + * @author Péter Király + */ +public class EchoField implements Calculator, Serializable { + + private static final Logger LOGGER = Logger.getLogger(EchoField.class.getCanonicalName()); + + public static final String CALCULATOR_NAME = "echoField"; + + protected Schema schema; + + public EchoField(Schema schema) { + this.schema = schema; + } + + @Override + public String getCalculatorName() { + return CALCULATOR_NAME; + } + + @Override + public List measure(PathCache cache) + throws InvalidJsonException { + // FieldCounter resultMap; + FieldCounter resultMap = new FieldCounter<>(); + + if (schema != null) { + String path; + for (String fieldName : schema.getEchoFields().keySet()) { + path = schema.getEchoFields().get(fieldName); + List values = cache.get(path); + String value = null; + if (values == null || values.isEmpty() || values.get(0) == null || values.get(0).getValue() == null) { + // logger.warning("Null value in field: " + fieldName + " (" + path + ")"); + value = null; + } else { + value = values.get(0).getValue(); + } + resultMap.put(fieldName, value); + } + } + return List.of(new FieldCounterBasedResult<>(getCalculatorName(), resultMap).withNoCompression()); + } + + @Override + public List getHeader() { + List headers = new ArrayList<>(); + for (String fieldName : schema.getEchoFields().keySet()) { + headers.add("echo:" + fieldName); + } + return headers; + } +} From eb7144ffbbff73ccecf80320e955e2e22d475621 Mon Sep 17 00:00:00 2001 From: Richard Palmer Date: Wed, 30 Jun 2021 22:02:25 +0100 Subject: [PATCH 5/5] Update tests for echo calculator --- .../api/calculator/CalculatorFacadeTest.java | 14 +++++++------- .../api/schema/GoogleDatasetSchema.java | 15 +++++++++++++++ .../gwdg/metadataqa/api/xml/OaiPmhXPathTest.java | 2 +- 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/test/java/de/gwdg/metadataqa/api/calculator/CalculatorFacadeTest.java b/src/test/java/de/gwdg/metadataqa/api/calculator/CalculatorFacadeTest.java index ce15a1f3..7ef5225d 100644 --- a/src/test/java/de/gwdg/metadataqa/api/calculator/CalculatorFacadeTest.java +++ b/src/test/java/de/gwdg/metadataqa/api/calculator/CalculatorFacadeTest.java @@ -55,7 +55,7 @@ public void tearDown() { @Test public void testNoAbbreviate() throws URISyntaxException, IOException { - MeasurementConfiguration configuration = new MeasurementConfiguration(true, true, true, false, true); + MeasurementConfiguration configuration = new MeasurementConfiguration(true, false, true, true, false, true); CalculatorFacade calculatorFacade = new CalculatorFacade(configuration); calculatorFacade.setSchema(new EdmOaiPmhJsonSchema()); calculatorFacade.configure(); @@ -65,7 +65,7 @@ public void testNoAbbreviate() throws URISyntaxException, IOException { @Test public void testNoAbbreviate_map() throws URISyntaxException, IOException { - MeasurementConfiguration configuration = new MeasurementConfiguration(true, true, true, false, true); + MeasurementConfiguration configuration = new MeasurementConfiguration(true, false, true, true, false, true); CalculatorFacade calculatorFacade = new CalculatorFacade(configuration); calculatorFacade.setSchema(new EdmOaiPmhJsonSchema()); calculatorFacade.configure(); @@ -79,7 +79,7 @@ public void testNoAbbreviate_map() throws URISyntaxException, IOException { @Test public void testNoAbbreviate_list() throws URISyntaxException, IOException { - CalculatorFacade calculatorFacade = new CalculatorFacade(new MeasurementConfiguration(true, true, true, false, true)); + CalculatorFacade calculatorFacade = new CalculatorFacade(new MeasurementConfiguration(true, false, true, true, false, true)); calculatorFacade.setSchema(new EdmOaiPmhJsonSchema()); calculatorFacade.configure(); @@ -93,7 +93,7 @@ public void testNoAbbreviate_list() throws URISyntaxException, IOException { @Test public void testNoAbbreviate_list2() throws URISyntaxException, IOException { - CalculatorFacade calculatorFacade = new CalculatorFacade(new MeasurementConfiguration(true, true, true, false, true)); + CalculatorFacade calculatorFacade = new CalculatorFacade(new MeasurementConfiguration(true, false, true, true, false, true)); calculatorFacade.setSchema(new EdmOaiPmhJsonSchema()); calculatorFacade.configure(); @@ -140,7 +140,7 @@ public void testNoAbbreviate_list2() throws URISyntaxException, IOException { @Test public void testNoAbbreviate_listOfObject() throws URISyntaxException, IOException { - CalculatorFacade calculatorFacade = new CalculatorFacade(new MeasurementConfiguration(true, true, true, false, true)); + CalculatorFacade calculatorFacade = new CalculatorFacade(new MeasurementConfiguration(true, false, true, true, false, true)); calculatorFacade.setSchema(new EdmOaiPmhJsonSchema()); calculatorFacade.configure(); @@ -154,7 +154,7 @@ public void testNoAbbreviate_listOfObject() throws URISyntaxException, IOExcepti @Test public void testWithAbbreviate() throws URISyntaxException, IOException { - CalculatorFacade calculatorFacade = new CalculatorFacade(new MeasurementConfiguration(true, true, true, false, true)); + CalculatorFacade calculatorFacade = new CalculatorFacade(new MeasurementConfiguration(true, false, true, true, false, true)); calculatorFacade.setSchema(new EdmOaiPmhJsonSchema()); calculatorFacade.configure(); String expected = "0.184,1.0,0.181818,0.388889,0.272727,0.5,0.357143,0.75,0.363636,0.4,1,1,1,0,0,0,0,0,1,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,1,0,0,1,1,0,0,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1,1,0,0,0,0,0,1,1,0,0,0,0,5,0,0,0,0,0,0,0,1,0,0,1,0,0,1,1,0,0,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,12,0,0,0.0,0.0,0.0"; @@ -325,7 +325,7 @@ private CalculatorFacade createCalculatorFacadeForCsv() { new CsvReader() .setHeader(((CsvAwareSchema) schema).getHeader())); - MeasurementConfiguration measurementConfiguration = new MeasurementConfiguration(true, true, true, false, true); + MeasurementConfiguration measurementConfiguration = new MeasurementConfiguration(true, false, true, true, false, true); assertTrue((measurementConfiguration.isFieldExistenceMeasurementEnabled())); CalculatorFacade calculatorFacade = new CalculatorFacade(measurementConfiguration); diff --git a/src/test/java/de/gwdg/metadataqa/api/schema/GoogleDatasetSchema.java b/src/test/java/de/gwdg/metadataqa/api/schema/GoogleDatasetSchema.java index f391805b..49ecd173 100644 --- a/src/test/java/de/gwdg/metadataqa/api/schema/GoogleDatasetSchema.java +++ b/src/test/java/de/gwdg/metadataqa/api/schema/GoogleDatasetSchema.java @@ -97,6 +97,21 @@ public void addExtractableField(String label, String jsonPath) { extractableFields.put(label, jsonPath); } + @Override + public Map getEchoFields() { + return echoFields; + } + + @Override + public void setEchoFields(Map echoFields) { + this.echoFields = echoFields; + } + + @Override + public void addEchoField(String label, String jsonPath) { + echoFields.put(label, jsonPath); + } + @Override public List getCategories() { if (categories == null) diff --git a/src/test/java/de/gwdg/metadataqa/api/xml/OaiPmhXPathTest.java b/src/test/java/de/gwdg/metadataqa/api/xml/OaiPmhXPathTest.java index 6a2a6706..f629d0e1 100644 --- a/src/test/java/de/gwdg/metadataqa/api/xml/OaiPmhXPathTest.java +++ b/src/test/java/de/gwdg/metadataqa/api/xml/OaiPmhXPathTest.java @@ -159,7 +159,7 @@ public void testTops() { @Test public void testCalculator() throws IOException, URISyntaxException { CalculatorFacade calculatorFacade = new CalculatorFacade( - new MeasurementConfiguration(true, true, true, false, true)); + new MeasurementConfiguration(true, false, true, true, false, true)); calculatorFacade.setSchema(new EdmOaiPmhXmlSchema()); calculatorFacade.configure(); String expected = "0.208,1.0,0.181818,0.388889,0.272727,0.5,0.357143,0.75,0.363636,0.4,1,1,1,0,0,0,0,0,1,1,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,1,0,0,1,1,0,0,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,0,0,0,1,0,1,1,1,1,0,0,0,0,0,1,1,0,0,0,0,5,0,0,0,0,0,0,0,1,0,0,1,0,0,1,1,0,0,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,2,0,0,0,59,0,0,0,39,0,39,0.0,0.0,0.0";