diff --git a/.gitignore b/.gitignore
index 73d9179fa..14cd4d345 100644
--- a/.gitignore
+++ b/.gitignore
@@ -26,3 +26,4 @@ spark-warehouse
/**/*.log
/**/.factorypath
/**/.scalafmt.conf
+/.java-version
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
new file mode 100644
index 000000000..aff151f94
--- /dev/null
+++ b/CODE_OF_CONDUCT.md
@@ -0,0 +1,43 @@
+# Contributor Code of Conduct
+
+Openness, transparency and our community-driven participatory approach guide us in our day-to-day interactions and decision-making. Our open source projects are no exception. Trust, respect, collaboration and transparency are core values we believe should live and breathe within our projects. Our community welcomes participants from around the world with different experiences, unique perspectives, and great ideas to share.
+
+## Our Pledge
+
+In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.
+
+## Our Standards
+
+Examples of behavior that contributes to creating a positive environment include:
+
+- Using welcoming and inclusive language
+- Being respectful of differing viewpoints and experiences
+- Gracefully accepting constructive criticism
+- Attempting collaboration before conflict
+- Focusing on what is best for the community
+- Showing empathy towards other community members
+
+Examples of unacceptable behavior by participants include:
+
+- Violence, threats of violence, or inciting others to commit self-harm
+- The use of sexualized language or imagery and unwelcome sexual attention or advances
+- Trolling, intentionally spreading misinformation, insulting/derogatory comments, and personal or political attacks
+- Public or private harassment
+- Publishing others' private information, such as a physical or electronic address, without explicit permission
+- Abuse of the reporting process to intentionally harass or exclude others
+- Advocating for, or encouraging, any of the above behavior
+- Other conduct which could reasonably be considered inappropriate in a professional setting
+
+## Our Responsibilities
+
+Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
+
+Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
+
+## Scope
+
+This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org/), [version 1.4](https://www.contributor-covenant.org/version/1/4/code-of-conduct.html).
\ No newline at end of file
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 000000000..13a359c86
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,10 @@
+# Contributing to D-Net Hadoop
+
+:+1::tada: First off, thanks for taking the time to contribute! :tada::+1:
+
+This project and everyone participating in it is governed by our [Code of Conduct](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. Please report unacceptable behavior to [dnet-team@isti.cnr.it](mailto:dnet-team@isti.cnr.it).
+
+The following is a set of guidelines for contributing to this project and its packages. These are mostly guidelines, not rules, which applies to this project as a while, including all its sub-modules.
+Use your best judgment, and feel free to propose changes to this document in a pull request.
+
+All contributions are welcome, all contributions will be considered to be contributed under the [project license](LICENSE.md).
diff --git a/LICENSE b/LICENSE.md
similarity index 100%
rename from LICENSE
rename to LICENSE.md
diff --git a/README.md b/README.md
index 0a0bd82ab..b6575814d 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,133 @@
# dnet-hadoop
-Dnet-hadoop is the project that defined all the OOZIE workflows for the OpenAIRE Graph construction, processing, provisioning.
\ No newline at end of file
+
+Dnet-hadoop is the project that defined all the [OOZIE workflows](https://oozie.apache.org/) for the OpenAIRE Graph construction, processing, provisioning.
+
+This project adheres to the Contributor Covenant [code of conduct](CODE_OF_CONDUCT.md).
+By participating, you are expected to uphold this code. Please report unacceptable behavior to [dnet-team@isti.cnr.it](mailto:dnet-team@isti.cnr.it).
+
+This project is licensed under the [AGPL v3 or later version](#LICENSE.md).
+
+How to build, package and run oozie workflows
+====================
+
+Oozie-installer is a utility allowing building, uploading and running oozie workflows. In practice, it creates a `*.tar.gz`
+package that contains resources that define a workflow and some helper scripts.
+
+This module is automatically executed when running:
+
+`mvn package -Poozie-package -Dworkflow.source.dir=classpath/to/parent/directory/of/oozie_app`
+
+on module having set:
+
+```
+
+ eu.dnetlib.dhp
+ dhp-workflows
+
+```
+
+in `pom.xml` file. `oozie-package` profile initializes oozie workflow packaging, `workflow.source.dir` property points to
+a workflow (notice: this is not a relative path but a classpath to directory usually holding `oozie_app` subdirectory).
+
+The outcome of this packaging is `oozie-package.tar.gz` file containing inside all the resources required to run Oozie workflow:
+
+- jar packages
+- workflow definitions
+- job properties
+- maintenance scripts
+
+Required properties
+====================
+
+In order to include proper workflow within package, `workflow.source.dir` property has to be set. It could be provided
+by setting `-Dworkflow.source.dir=some/job/dir` maven parameter.
+
+In oder to define full set of cluster environment properties one should create `~/.dhp/application.properties` file with
+the following properties:
+
+- `dhp.hadoop.frontend.user.name` - your user name on hadoop cluster and frontend machine
+- `dhp.hadoop.frontend.host.name` - frontend host name
+- `dhp.hadoop.frontend.temp.dir` - frontend directory for temporary files
+- `dhp.hadoop.frontend.port.ssh` - frontend machine ssh port
+- `oozieServiceLoc` - oozie service location required by run_workflow.sh script executing oozie job
+- `nameNode` - name node address
+- `jobTracker` - job tracker address
+- `oozie.execution.log.file.location` - location of file that will be created when executing oozie job, it contains output
+produced by `run_workflow.sh` script (needed to obtain oozie job id)
+- `maven.executable` - mvn command location, requires parameterization due to a different setup of CI cluster
+- `sparkDriverMemory` - amount of memory assigned to spark jobs driver
+- `sparkExecutorMemory` - amount of memory assigned to spark jobs executors
+- `sparkExecutorCores` - number of cores assigned to spark jobs executors
+
+All values will be overriden with the ones from `job.properties` and eventually `job-override.properties` stored in module's
+main folder.
+
+When overriding properties from `job.properties`, `job-override.properties` file can be created in main module directory
+(the one containing `pom.xml` file) and define all new properties which will override existing properties.
+One can provide those properties one by one as command line `-D` arguments.
+
+Properties overriding order is the following:
+
+1. `pom.xml` defined properties (located in the project root dir)
+2. `~/.dhp/application.properties` defined properties
+3. `${workflow.source.dir}/job.properties`
+4. `job-override.properties` (located in the project root dir)
+5. `maven -Dparam=value`
+
+where the maven `-Dparam` property is overriding all the other ones.
+
+Workflow definition requirements
+====================
+
+`workflow.source.dir` property should point to the following directory structure:
+
+ [${workflow.source.dir}]
+ |
+ |-job.properties (optional)
+ |
+ \-[oozie_app]
+ |
+ \-workflow.xml
+
+This property can be set using maven `-D` switch.
+
+`[oozie_app]` is the default directory name however it can be set to any value as soon as `oozieAppDir` property is
+provided with directory name as value.
+
+Sub-workflows are supported as well and sub-workflow directories should be nested within `[oozie_app]` directory.
+
+Creating oozie installer step-by-step
+=====================================
+
+Automated oozie-installer steps are the following:
+
+1. creating jar packages: `*.jar` and `*tests.jar` along with copying all dependencies in `target/dependencies`
+2. reading properties from maven, `~/.dhp/application.properties`, `job.properties`, `job-override.properties`
+3. invoking priming mechanism linking resources from import.txt file (currently resolving subworkflow resources)
+4. assembling shell scripts for preparing Hadoop filesystem, uploading Oozie application and starting workflow
+5. copying whole `${workflow.source.dir}` content to `target/${oozie.package.file.name}`
+6. generating updated `job.properties` file in `target/${oozie.package.file.name}` based on maven,
+`~/.dhp/application.properties`, `job.properties` and `job-override.properties`
+7. creating `lib` directory (or multiple directories for sub-workflows for each nested directory) and copying jar packages
+created at step (1) to each one of them
+8. bundling whole `${oozie.package.file.name}` directory into single tar.gz package
+
+Uploading oozie package and running workflow on cluster
+=======================================================
+
+In order to simplify deployment and execution process two dedicated profiles were introduced:
+
+- `deploy`
+- `run`
+
+to be used along with `oozie-package` profile e.g. by providing `-Poozie-package,deploy,run` maven parameters.
+
+The `deploy` profile supplements packaging process with:
+1) uploading oozie-package via scp to `/home/${user.name}/oozie-packages` directory on `${dhp.hadoop.frontend.host.name}` machine
+2) extracting uploaded package
+3) uploading oozie content to hadoop cluster HDFS location defined in `oozie.wf.application.path` property (generated dynamically by maven build process, based on `${dhp.hadoop.frontend.user.name}` and `workflow.source.dir` properties)
+
+The `run` profile introduces:
+1) executing oozie application uploaded to HDFS cluster using `deploy` command. Triggers `run_workflow.sh` script providing runtime properties defined in `job.properties` file.
+
+Notice: ssh access to frontend machine has to be configured on system level and it is preferable to set key-based authentication in order to simplify remote operations.
\ No newline at end of file
diff --git a/dhp-common/pom.xml b/dhp-common/pom.xml
index 6df11f4ea..6198bd81e 100644
--- a/dhp-common/pom.xml
+++ b/dhp-common/pom.xml
@@ -52,6 +52,8 @@
+ true
+ ${scala.binary.version}
${scala.version}
@@ -60,6 +62,11 @@
+
+ eu.dnetlib.dhp
+ dhp-pace-core
+ ${project.version}
+
org.apache.hadoop
@@ -76,11 +83,11 @@
org.apache.spark
- spark-core_2.11
+ spark-core_${scala.binary.version}
org.apache.spark
- spark-sql_2.11
+ spark-sql_${scala.binary.version}
@@ -142,11 +149,6 @@
okhttp
-
- eu.dnetlib
- dnet-pace-core
-
-
org.apache.httpcomponents
httpclient
@@ -159,7 +161,7 @@
eu.dnetlib.dhp
- dhp-schemas
+ ${dhp-schemas.artifact}
diff --git a/dhp-common/src/main/java/eu/dnetlib/dhp/common/Constants.java b/dhp-common/src/main/java/eu/dnetlib/dhp/common/Constants.java
index 4f2c6341e..0477d6399 100644
--- a/dhp-common/src/main/java/eu/dnetlib/dhp/common/Constants.java
+++ b/dhp-common/src/main/java/eu/dnetlib/dhp/common/Constants.java
@@ -51,6 +51,7 @@ public class Constants {
public static final String RETRY_DELAY = "retryDelay";
public static final String CONNECT_TIMEOUT = "connectTimeOut";
public static final String READ_TIMEOUT = "readTimeOut";
+ public static final String REQUEST_METHOD = "requestMethod";
public static final String FROM_DATE_OVERRIDE = "fromDateOverride";
public static final String UNTIL_DATE_OVERRIDE = "untilDateOverride";
diff --git a/dhp-common/src/main/java/eu/dnetlib/dhp/common/api/context/CategorySummary.java b/dhp-common/src/main/java/eu/dnetlib/dhp/common/api/context/CategorySummary.java
new file mode 100644
index 000000000..fff28dbdf
--- /dev/null
+++ b/dhp-common/src/main/java/eu/dnetlib/dhp/common/api/context/CategorySummary.java
@@ -0,0 +1,39 @@
+
+package eu.dnetlib.dhp.common.api.context;
+
+public class CategorySummary {
+
+ private String id;
+
+ private String label;
+
+ private boolean hasConcept;
+
+ public String getId() {
+ return id;
+ }
+
+ public String getLabel() {
+ return label;
+ }
+
+ public boolean isHasConcept() {
+ return hasConcept;
+ }
+
+ public CategorySummary setId(final String id) {
+ this.id = id;
+ return this;
+ }
+
+ public CategorySummary setLabel(final String label) {
+ this.label = label;
+ return this;
+ }
+
+ public CategorySummary setHasConcept(final boolean hasConcept) {
+ this.hasConcept = hasConcept;
+ return this;
+ }
+
+}
diff --git a/dhp-common/src/main/java/eu/dnetlib/dhp/common/api/context/CategorySummaryList.java b/dhp-common/src/main/java/eu/dnetlib/dhp/common/api/context/CategorySummaryList.java
new file mode 100644
index 000000000..7213a945a
--- /dev/null
+++ b/dhp-common/src/main/java/eu/dnetlib/dhp/common/api/context/CategorySummaryList.java
@@ -0,0 +1,7 @@
+
+package eu.dnetlib.dhp.common.api.context;
+
+import java.util.ArrayList;
+
+public class CategorySummaryList extends ArrayList {
+}
diff --git a/dhp-common/src/main/java/eu/dnetlib/dhp/common/api/context/ConceptSummary.java b/dhp-common/src/main/java/eu/dnetlib/dhp/common/api/context/ConceptSummary.java
new file mode 100644
index 000000000..a576f9a1e
--- /dev/null
+++ b/dhp-common/src/main/java/eu/dnetlib/dhp/common/api/context/ConceptSummary.java
@@ -0,0 +1,52 @@
+
+package eu.dnetlib.dhp.common.api.context;
+
+import java.util.List;
+
+public class ConceptSummary {
+
+ private String id;
+
+ private String label;
+
+ public boolean hasSubConcept;
+
+ private List concepts;
+
+ public String getId() {
+ return id;
+ }
+
+ public String getLabel() {
+ return label;
+ }
+
+ public List getConcepts() {
+ return concepts;
+ }
+
+ public ConceptSummary setId(final String id) {
+ this.id = id;
+ return this;
+ }
+
+ public ConceptSummary setLabel(final String label) {
+ this.label = label;
+ return this;
+ }
+
+ public boolean isHasSubConcept() {
+ return hasSubConcept;
+ }
+
+ public ConceptSummary setHasSubConcept(final boolean hasSubConcept) {
+ this.hasSubConcept = hasSubConcept;
+ return this;
+ }
+
+ public ConceptSummary setConcept(final List concepts) {
+ this.concepts = concepts;
+ return this;
+ }
+
+}
diff --git a/dhp-common/src/main/java/eu/dnetlib/dhp/common/api/context/ConceptSummaryList.java b/dhp-common/src/main/java/eu/dnetlib/dhp/common/api/context/ConceptSummaryList.java
new file mode 100644
index 000000000..45ccd2810
--- /dev/null
+++ b/dhp-common/src/main/java/eu/dnetlib/dhp/common/api/context/ConceptSummaryList.java
@@ -0,0 +1,7 @@
+
+package eu.dnetlib.dhp.common.api.context;
+
+import java.util.ArrayList;
+
+public class ConceptSummaryList extends ArrayList {
+}
diff --git a/dhp-common/src/main/java/eu/dnetlib/dhp/common/api/context/ContextSummary.java b/dhp-common/src/main/java/eu/dnetlib/dhp/common/api/context/ContextSummary.java
new file mode 100644
index 000000000..46a0d0d5a
--- /dev/null
+++ b/dhp-common/src/main/java/eu/dnetlib/dhp/common/api/context/ContextSummary.java
@@ -0,0 +1,50 @@
+
+package eu.dnetlib.dhp.common.api.context;
+
+public class ContextSummary {
+
+ private String id;
+
+ private String label;
+
+ private String type;
+
+ private String status;
+
+ public String getId() {
+ return id;
+ }
+
+ public String getLabel() {
+ return label;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public String getStatus() {
+ return status;
+ }
+
+ public ContextSummary setId(final String id) {
+ this.id = id;
+ return this;
+ }
+
+ public ContextSummary setLabel(final String label) {
+ this.label = label;
+ return this;
+ }
+
+ public ContextSummary setType(final String type) {
+ this.type = type;
+ return this;
+ }
+
+ public ContextSummary setStatus(final String status) {
+ this.status = status;
+ return this;
+ }
+
+}
diff --git a/dhp-common/src/main/java/eu/dnetlib/dhp/common/api/context/ContextSummaryList.java b/dhp-common/src/main/java/eu/dnetlib/dhp/common/api/context/ContextSummaryList.java
new file mode 100644
index 000000000..618600007
--- /dev/null
+++ b/dhp-common/src/main/java/eu/dnetlib/dhp/common/api/context/ContextSummaryList.java
@@ -0,0 +1,7 @@
+
+package eu.dnetlib.dhp.common.api.context;
+
+import java.util.ArrayList;
+
+public class ContextSummaryList extends ArrayList {
+}
diff --git a/dhp-common/src/main/java/eu/dnetlib/dhp/common/collection/HttpClientParams.java b/dhp-common/src/main/java/eu/dnetlib/dhp/common/collection/HttpClientParams.java
index 6fcec00dd..d26d9c0e9 100644
--- a/dhp-common/src/main/java/eu/dnetlib/dhp/common/collection/HttpClientParams.java
+++ b/dhp-common/src/main/java/eu/dnetlib/dhp/common/collection/HttpClientParams.java
@@ -1,6 +1,9 @@
package eu.dnetlib.dhp.common.collection;
+import java.util.HashMap;
+import java.util.Map;
+
/**
* Bundles the http connection parameters driving the client behaviour.
*/
@@ -13,6 +16,8 @@ public class HttpClientParams {
public static int _connectTimeOut = 10; // seconds
public static int _readTimeOut = 30; // seconds
+ public static String _requestMethod = "GET";
+
/**
* Maximum number of allowed retires before failing
*/
@@ -38,17 +43,30 @@ public class HttpClientParams {
*/
private int readTimeOut;
+ /**
+ * Custom http headers
+ */
+ private Map headers;
+
+ /**
+ * Request method (i.e., GET, POST etc)
+ */
+ private String requestMethod;
+
public HttpClientParams() {
- this(_maxNumberOfRetry, _requestDelay, _retryDelay, _connectTimeOut, _readTimeOut);
+ this(_maxNumberOfRetry, _requestDelay, _retryDelay, _connectTimeOut, _readTimeOut, new HashMap<>(),
+ _requestMethod);
}
public HttpClientParams(int maxNumberOfRetry, int requestDelay, int retryDelay, int connectTimeOut,
- int readTimeOut) {
+ int readTimeOut, Map headers, String requestMethod) {
this.maxNumberOfRetry = maxNumberOfRetry;
this.requestDelay = requestDelay;
this.retryDelay = retryDelay;
this.connectTimeOut = connectTimeOut;
this.readTimeOut = readTimeOut;
+ this.headers = headers;
+ this.requestMethod = requestMethod;
}
public int getMaxNumberOfRetry() {
@@ -91,4 +109,19 @@ public class HttpClientParams {
this.readTimeOut = readTimeOut;
}
+ public Map getHeaders() {
+ return headers;
+ }
+
+ public void setHeaders(Map headers) {
+ this.headers = headers;
+ }
+
+ public String getRequestMethod() {
+ return requestMethod;
+ }
+
+ public void setRequestMethod(String requestMethod) {
+ this.requestMethod = requestMethod;
+ }
}
diff --git a/dhp-common/src/main/java/eu/dnetlib/dhp/common/collection/HttpConnector2.java b/dhp-common/src/main/java/eu/dnetlib/dhp/common/collection/HttpConnector2.java
index dd46ab1f4..342d73cdc 100644
--- a/dhp-common/src/main/java/eu/dnetlib/dhp/common/collection/HttpConnector2.java
+++ b/dhp-common/src/main/java/eu/dnetlib/dhp/common/collection/HttpConnector2.java
@@ -8,10 +8,13 @@ import java.io.InputStream;
import java.net.*;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.TimeUnit;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.math.NumberUtils;
+import org.apache.commons.lang3.time.DateUtils;
import org.apache.http.HttpHeaders;
+import org.joda.time.Instant;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -94,24 +97,32 @@ public class HttpConnector2 {
throw new CollectorException(msg);
}
- log.info("Request attempt {} [{}]", retryNumber, requestUrl);
-
InputStream input = null;
+ long start = System.currentTimeMillis();
try {
if (getClientParams().getRequestDelay() > 0) {
backoffAndSleep(getClientParams().getRequestDelay());
}
+
+ log.info("Request attempt {} [{}]", retryNumber, requestUrl);
+
final HttpURLConnection urlConn = (HttpURLConnection) new URL(requestUrl).openConnection();
urlConn.setInstanceFollowRedirects(false);
urlConn.setReadTimeout(getClientParams().getReadTimeOut() * 1000);
urlConn.setConnectTimeout(getClientParams().getConnectTimeOut() * 1000);
urlConn.addRequestProperty(HttpHeaders.USER_AGENT, userAgent);
+ urlConn.setRequestMethod(getClientParams().getRequestMethod());
- if (log.isDebugEnabled()) {
- logHeaderFields(urlConn);
+ // if provided, add custom headers
+ if (!getClientParams().getHeaders().isEmpty()) {
+ for (Map.Entry headerEntry : getClientParams().getHeaders().entrySet()) {
+ urlConn.addRequestProperty(headerEntry.getKey(), headerEntry.getValue());
+ }
}
+ logHeaderFields(urlConn);
+
int retryAfter = obtainRetryAfter(urlConn.getHeaderFields());
String rateLimit = urlConn.getHeaderField(Constants.HTTPHEADER_IETF_DRAFT_RATELIMIT_LIMIT);
String rateRemaining = urlConn.getHeaderField(Constants.HTTPHEADER_IETF_DRAFT_RATELIMIT_REMAINING);
@@ -125,9 +136,7 @@ public class HttpConnector2 {
}
if (is2xx(urlConn.getResponseCode())) {
- input = urlConn.getInputStream();
- responseType = urlConn.getContentType();
- return input;
+ return getInputStream(urlConn, start);
}
if (is3xx(urlConn.getResponseCode())) {
// REDIRECTS
@@ -137,6 +146,7 @@ public class HttpConnector2 {
.put(
REPORT_PREFIX + urlConn.getResponseCode(),
String.format("Moved to: %s", newUrl));
+ logRequestTime(start);
urlConn.disconnect();
if (retryAfter > 0) {
backoffAndSleep(retryAfter);
@@ -152,26 +162,50 @@ public class HttpConnector2 {
if (retryAfter > 0) {
log
.warn(
- "{} - waiting and repeating request after suggested retry-after {} sec.",
- requestUrl, retryAfter);
+ "waiting and repeating request after suggested retry-after {} sec for URL {}",
+ retryAfter, requestUrl);
backoffAndSleep(retryAfter * 1000);
} else {
log
.warn(
- "{} - waiting and repeating request after default delay of {} sec.",
- requestUrl, getClientParams().getRetryDelay());
- backoffAndSleep(retryNumber * getClientParams().getRetryDelay() * 1000);
+ "waiting and repeating request after default delay of {} sec for URL {}",
+ getClientParams().getRetryDelay(), requestUrl);
+ backoffAndSleep(retryNumber * getClientParams().getRetryDelay());
}
report.put(REPORT_PREFIX + urlConn.getResponseCode(), requestUrl);
+
+ logRequestTime(start);
+
urlConn.disconnect();
+
return attemptDownload(requestUrl, retryNumber + 1, report);
+ case 422: // UNPROCESSABLE ENTITY
+ report.put(REPORT_PREFIX + urlConn.getResponseCode(), requestUrl);
+ log.warn("waiting and repeating request after 10 sec for URL {}", requestUrl);
+ backoffAndSleep(10000);
+ urlConn.disconnect();
+ logRequestTime(start);
+ try {
+ return getInputStream(urlConn, start);
+ } catch (IOException e) {
+ log
+ .error(
+ "server returned 422 and got IOException accessing the response body from URL {}",
+ requestUrl);
+ log.error("IOException:", e);
+ return attemptDownload(requestUrl, retryNumber + 1, report);
+ }
default:
+ log.error("gor error {} from URL: {}", urlConn.getResponseCode(), urlConn.getURL());
+ log.error("response message: {}", urlConn.getResponseMessage());
report
.put(
REPORT_PREFIX + urlConn.getResponseCode(),
String
.format(
"%s Error: %s", requestUrl, urlConn.getResponseMessage()));
+ logRequestTime(start);
+ urlConn.disconnect();
throw new CollectorException(urlConn.getResponseCode() + " error " + report);
}
}
@@ -192,13 +226,27 @@ public class HttpConnector2 {
}
}
+ private InputStream getInputStream(HttpURLConnection urlConn, long start) throws IOException {
+ InputStream input = urlConn.getInputStream();
+ responseType = urlConn.getContentType();
+ logRequestTime(start);
+ return input;
+ }
+
+ private static void logRequestTime(long start) {
+ log
+ .info(
+ "request time elapsed: {}sec",
+ TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis() - start));
+ }
+
private void logHeaderFields(final HttpURLConnection urlConn) throws IOException {
- log.debug("StatusCode: {}", urlConn.getResponseMessage());
+ log.info("Response: {} - {}", urlConn.getResponseCode(), urlConn.getResponseMessage());
for (Map.Entry> e : urlConn.getHeaderFields().entrySet()) {
if (e.getKey() != null) {
for (String v : e.getValue()) {
- log.debug(" key: {} - value: {}", e.getKey(), v);
+ log.info(" key: {} - value: {}", e.getKey(), v);
}
}
}
@@ -218,7 +266,7 @@ public class HttpConnector2 {
for (String key : headerMap.keySet()) {
if ((key != null) && key.equalsIgnoreCase(HttpHeaders.RETRY_AFTER) && (!headerMap.get(key).isEmpty())
&& NumberUtils.isCreatable(headerMap.get(key).get(0))) {
- return Integer.parseInt(headerMap.get(key).get(0)) + 10;
+ return Integer.parseInt(headerMap.get(key).get(0));
}
}
return -1;
diff --git a/dhp-common/src/main/java/eu/dnetlib/dhp/common/vocabulary/Vocabulary.java b/dhp-common/src/main/java/eu/dnetlib/dhp/common/vocabulary/Vocabulary.java
index 2ab23bda6..94e7f5221 100644
--- a/dhp-common/src/main/java/eu/dnetlib/dhp/common/vocabulary/Vocabulary.java
+++ b/dhp-common/src/main/java/eu/dnetlib/dhp/common/vocabulary/Vocabulary.java
@@ -63,7 +63,10 @@ public class Vocabulary implements Serializable {
}
public VocabularyTerm getTermBySynonym(final String syn) {
- return getTerm(synonyms.get(syn.toLowerCase()));
+ return Optional
+ .ofNullable(syn)
+ .map(s -> getTerm(synonyms.get(s.toLowerCase())))
+ .orElse(null);
}
public Qualifier getTermAsQualifier(final String termId) {
diff --git a/dhp-common/src/main/java/eu/dnetlib/dhp/common/vocabulary/VocabularyGroup.java b/dhp-common/src/main/java/eu/dnetlib/dhp/common/vocabulary/VocabularyGroup.java
index fc7175270..64b6f91af 100644
--- a/dhp-common/src/main/java/eu/dnetlib/dhp/common/vocabulary/VocabularyGroup.java
+++ b/dhp-common/src/main/java/eu/dnetlib/dhp/common/vocabulary/VocabularyGroup.java
@@ -135,6 +135,24 @@ public class VocabularyGroup implements Serializable {
return vocs.get(vocId.toLowerCase()).getSynonymAsQualifier(syn);
}
+ public Qualifier lookupTermBySynonym(final String vocId, final String syn) {
+ return find(vocId)
+ .map(
+ vocabulary -> Optional
+ .ofNullable(vocabulary.getTerm(syn))
+ .map(
+ term -> OafMapperUtils
+ .qualifier(term.getId(), term.getName(), vocabulary.getId(), vocabulary.getName()))
+ .orElse(
+ Optional
+ .ofNullable(vocabulary.getTermBySynonym(syn))
+ .map(
+ term -> OafMapperUtils
+ .qualifier(term.getId(), term.getName(), vocabulary.getId(), vocabulary.getName()))
+ .orElse(null)))
+ .orElse(null);
+ }
+
/**
* getSynonymAsQualifierCaseSensitive
*
diff --git a/dhp-common/src/main/java/eu/dnetlib/dhp/oa/merge/AuthorMerger.java b/dhp-common/src/main/java/eu/dnetlib/dhp/oa/merge/AuthorMerger.java
index aea046203..0461c9353 100644
--- a/dhp-common/src/main/java/eu/dnetlib/dhp/oa/merge/AuthorMerger.java
+++ b/dhp-common/src/main/java/eu/dnetlib/dhp/oa/merge/AuthorMerger.java
@@ -119,6 +119,131 @@ public class AuthorMerger {
});
}
+ public static String normalizeFullName(final String fullname) {
+ return nfd(fullname)
+ .toLowerCase()
+ // do not compact the regexes in a single expression, would cause StackOverflowError
+ // in case
+ // of large input strings
+ .replaceAll("(\\W)+", " ")
+ .replaceAll("(\\p{InCombiningDiacriticalMarks})+", " ")
+ .replaceAll("(\\p{Punct})+", " ")
+ .replaceAll("(\\d)+", " ")
+ .replaceAll("(\\n)+", " ")
+
+ .trim();
+ }
+
+ private static String authorFieldToBeCompared(Author author) {
+ if (StringUtils.isNotBlank(author.getSurname())) {
+ return author.getSurname();
+
+ }
+ if (StringUtils.isNotBlank(author.getFullname())) {
+ return author.getFullname();
+ }
+ return null;
+ }
+
+ /**
+ * This method tries to figure out when two author are the same in the contest
+ * of ORCID enrichment
+ *
+ * @param left Author in the OAF entity
+ * @param right Author ORCID
+ * @return based on a heuristic on the names of the authors if they are the same.
+ */
+ public static boolean checkORCIDSimilarity(final Author left, final Author right) {
+ final Person pl = parse(left);
+ final Person pr = parse(right);
+
+ // If one of them didn't have a surname we verify if they have the fullName not empty
+ // and verify if the normalized version is equal
+ if (!(pl.getSurname() != null && pl.getSurname().stream().anyMatch(StringUtils::isNotBlank) &&
+ pr.getSurname() != null && pr.getSurname().stream().anyMatch(StringUtils::isNotBlank))) {
+
+ if (pl.getFullname() != null && !pl.getFullname().isEmpty() && pr.getFullname() != null
+ && !pr.getFullname().isEmpty()) {
+ return pl
+ .getFullname()
+ .stream()
+ .anyMatch(
+ fl -> pr.getFullname().stream().anyMatch(fr -> normalize(fl).equalsIgnoreCase(normalize(fr))));
+ } else {
+ return false;
+ }
+ }
+ // The Authors have one surname in common
+ if (pl.getSurname().stream().anyMatch(sl -> pr.getSurname().stream().anyMatch(sr -> sr.equalsIgnoreCase(sl)))) {
+
+ // If one of them has only a surname and is the same we can say that they are the same author
+ if ((pl.getName() == null || pl.getName().stream().allMatch(StringUtils::isBlank)) ||
+ (pr.getName() == null || pr.getName().stream().allMatch(StringUtils::isBlank)))
+ return true;
+ // The authors have the same initials of Name in common
+ if (pl
+ .getName()
+ .stream()
+ .anyMatch(
+ nl -> pr
+ .getName()
+ .stream()
+ .anyMatch(nr -> nr.equalsIgnoreCase(nl))))
+ return true;
+ }
+
+ // Sometimes we noticed that publication have author wrote in inverse order Surname, Name
+ // We verify if we have an exact match between name and surname
+ if (pl.getSurname().stream().anyMatch(sl -> pr.getName().stream().anyMatch(nr -> nr.equalsIgnoreCase(sl))) &&
+ pl.getName().stream().anyMatch(nl -> pr.getSurname().stream().anyMatch(sr -> sr.equalsIgnoreCase(nl))))
+ return true;
+ else
+ return false;
+ }
+ //
+
+ /**
+ * Method to enrich ORCID information in one list of authors based on another list
+ *
+ * @param baseAuthor the Author List in the OAF Entity
+ * @param orcidAuthor The list of ORCID Author intersected
+ * @return The Author List of the OAF Entity enriched with the orcid Author
+ */
+ public static List enrichOrcid(List baseAuthor, List orcidAuthor) {
+
+ if (baseAuthor == null || baseAuthor.isEmpty())
+ return orcidAuthor;
+
+ if (orcidAuthor == null || orcidAuthor.isEmpty())
+ return baseAuthor;
+
+ if (baseAuthor.size() == 1 && orcidAuthor.size() > 10)
+ return baseAuthor;
+
+ final List oAuthor = new ArrayList<>();
+ oAuthor.addAll(orcidAuthor);
+
+ baseAuthor.forEach(ba -> {
+ Optional aMatch = oAuthor.stream().filter(oa -> checkORCIDSimilarity(ba, oa)).findFirst();
+ if (aMatch.isPresent()) {
+ final Author sameAuthor = aMatch.get();
+ addPid(ba, sameAuthor.getPid());
+ oAuthor.remove(sameAuthor);
+ }
+ });
+ return baseAuthor;
+ }
+
+ private static void addPid(final Author a, final List pids) {
+
+ if (a.getPid() == null) {
+ a.setPid(new ArrayList<>());
+ }
+
+ a.getPid().addAll(pids);
+
+ }
+
public static String pidToComparableString(StructuredProperty pid) {
final String classid = pid.getQualifier().getClassid() != null ? pid.getQualifier().getClassid().toLowerCase()
: "";
@@ -171,7 +296,7 @@ public class AuthorMerger {
}
}
- private static String normalize(final String s) {
+ public static String normalize(final String s) {
String[] normalized = nfd(s)
.toLowerCase()
// do not compact the regexes in a single expression, would cause StackOverflowError
diff --git a/dhp-common/src/main/java/eu/dnetlib/dhp/oa/merge/DispatchEntitiesSparkJob.java b/dhp-common/src/main/java/eu/dnetlib/dhp/oa/merge/DispatchEntitiesSparkJob.java
deleted file mode 100644
index 3f65d754f..000000000
--- a/dhp-common/src/main/java/eu/dnetlib/dhp/oa/merge/DispatchEntitiesSparkJob.java
+++ /dev/null
@@ -1,97 +0,0 @@
-
-package eu.dnetlib.dhp.oa.merge;
-
-import static eu.dnetlib.dhp.common.SparkSessionSupport.runWithSparkSession;
-
-import java.util.Objects;
-import java.util.Optional;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.spark.SparkConf;
-import org.apache.spark.api.java.function.FilterFunction;
-import org.apache.spark.api.java.function.MapFunction;
-import org.apache.spark.sql.Encoders;
-import org.apache.spark.sql.SaveMode;
-import org.apache.spark.sql.SparkSession;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.fasterxml.jackson.databind.ObjectMapper;
-
-import eu.dnetlib.dhp.application.ArgumentApplicationParser;
-import eu.dnetlib.dhp.common.HdfsSupport;
-import eu.dnetlib.dhp.schema.oaf.Oaf;
-import eu.dnetlib.dhp.schema.oaf.OafEntity;
-
-public class DispatchEntitiesSparkJob {
-
- private static final Logger log = LoggerFactory.getLogger(DispatchEntitiesSparkJob.class);
-
- private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
-
- public static void main(String[] args) throws Exception {
-
- String jsonConfiguration = IOUtils
- .toString(
- Objects
- .requireNonNull(
- DispatchEntitiesSparkJob.class
- .getResourceAsStream(
- "/eu/dnetlib/dhp/oa/merge/dispatch_entities_parameters.json")));
- final ArgumentApplicationParser parser = new ArgumentApplicationParser(jsonConfiguration);
- parser.parseArgument(args);
-
- Boolean isSparkSessionManaged = Optional
- .ofNullable(parser.get("isSparkSessionManaged"))
- .map(Boolean::valueOf)
- .orElse(Boolean.TRUE);
- log.info("isSparkSessionManaged: {}", isSparkSessionManaged);
-
- String inputPath = parser.get("inputPath");
- log.info("inputPath: {}", inputPath);
-
- String outputPath = parser.get("outputPath");
- log.info("outputPath: {}", outputPath);
-
- String graphTableClassName = parser.get("graphTableClassName");
- log.info("graphTableClassName: {}", graphTableClassName);
-
- @SuppressWarnings("unchecked")
- Class extends OafEntity> entityClazz = (Class extends OafEntity>) Class.forName(graphTableClassName);
-
- SparkConf conf = new SparkConf();
- runWithSparkSession(
- conf,
- isSparkSessionManaged,
- spark -> {
- HdfsSupport.remove(outputPath, spark.sparkContext().hadoopConfiguration());
- dispatchEntities(spark, inputPath, entityClazz, outputPath);
- });
- }
-
- private static void dispatchEntities(
- SparkSession spark,
- String inputPath,
- Class clazz,
- String outputPath) {
-
- spark
- .read()
- .textFile(inputPath)
- .filter((FilterFunction) s -> isEntityType(s, clazz))
- .map((MapFunction) s -> StringUtils.substringAfter(s, "|"), Encoders.STRING())
- .map(
- (MapFunction) value -> OBJECT_MAPPER.readValue(value, clazz),
- Encoders.bean(clazz))
- .write()
- .mode(SaveMode.Overwrite)
- .option("compression", "gzip")
- .json(outputPath);
- }
-
- private static boolean isEntityType(final String s, final Class clazz) {
- return StringUtils.substringBefore(s, "|").equals(clazz.getName());
- }
-
-}
diff --git a/dhp-common/src/main/java/eu/dnetlib/dhp/oa/merge/GroupEntitiesSparkJob.java b/dhp-common/src/main/java/eu/dnetlib/dhp/oa/merge/GroupEntitiesSparkJob.java
index e652bd5b6..0225a5063 100644
--- a/dhp-common/src/main/java/eu/dnetlib/dhp/oa/merge/GroupEntitiesSparkJob.java
+++ b/dhp-common/src/main/java/eu/dnetlib/dhp/oa/merge/GroupEntitiesSparkJob.java
@@ -2,50 +2,49 @@
package eu.dnetlib.dhp.oa.merge;
import static eu.dnetlib.dhp.common.SparkSessionSupport.runWithSparkSession;
-import static eu.dnetlib.dhp.utils.DHPUtils.toSeq;
+import static org.apache.spark.sql.functions.col;
+import static org.apache.spark.sql.functions.when;
-import java.io.IOException;
-import java.util.List;
-import java.util.Objects;
+import java.util.Map;
import java.util.Optional;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ForkJoinPool;
import java.util.stream.Collectors;
import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang3.StringUtils;
import org.apache.spark.SparkConf;
-import org.apache.spark.api.java.JavaSparkContext;
-import org.apache.spark.api.java.function.FilterFunction;
import org.apache.spark.api.java.function.MapFunction;
+import org.apache.spark.api.java.function.ReduceFunction;
import org.apache.spark.sql.*;
-import org.apache.spark.sql.expressions.Aggregator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.fasterxml.jackson.databind.DeserializationFeature;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.jayway.jsonpath.Configuration;
-import com.jayway.jsonpath.DocumentContext;
-import com.jayway.jsonpath.JsonPath;
-import com.jayway.jsonpath.Option;
-
import eu.dnetlib.dhp.application.ArgumentApplicationParser;
import eu.dnetlib.dhp.common.HdfsSupport;
+import eu.dnetlib.dhp.common.vocabulary.VocabularyGroup;
+import eu.dnetlib.dhp.schema.common.EntityType;
import eu.dnetlib.dhp.schema.common.ModelSupport;
-import eu.dnetlib.dhp.schema.oaf.*;
+import eu.dnetlib.dhp.schema.oaf.OafEntity;
+import eu.dnetlib.dhp.schema.oaf.utils.GraphCleaningFunctions;
import eu.dnetlib.dhp.schema.oaf.utils.OafMapperUtils;
+import eu.dnetlib.dhp.utils.ISLookupClientFactory;
+import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpException;
+import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;
import scala.Tuple2;
/**
* Groups the graph content by entity identifier to ensure ID uniqueness
*/
public class GroupEntitiesSparkJob {
-
private static final Logger log = LoggerFactory.getLogger(GroupEntitiesSparkJob.class);
- private static final String ID_JPATH = "$.id";
+ private static final Encoder OAFENTITY_KRYO_ENC = Encoders.kryo(OafEntity.class);
- private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper()
- .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+ private ArgumentApplicationParser parser;
+
+ public GroupEntitiesSparkJob(ArgumentApplicationParser parser) {
+ this.parser = parser;
+ }
public static void main(String[] args) throws Exception {
@@ -63,141 +62,133 @@ public class GroupEntitiesSparkJob {
.orElse(Boolean.TRUE);
log.info("isSparkSessionManaged: {}", isSparkSessionManaged);
+ final String isLookupUrl = parser.get("isLookupUrl");
+ log.info("isLookupUrl: {}", isLookupUrl);
+
+ final ISLookUpService isLookupService = ISLookupClientFactory.getLookUpService(isLookupUrl);
+
+ new GroupEntitiesSparkJob(parser).run(isSparkSessionManaged, isLookupService);
+ }
+
+ public void run(Boolean isSparkSessionManaged, ISLookUpService isLookUpService)
+ throws ISLookUpException {
+
String graphInputPath = parser.get("graphInputPath");
log.info("graphInputPath: {}", graphInputPath);
+ String checkpointPath = parser.get("checkpointPath");
+ log.info("checkpointPath: {}", checkpointPath);
+
String outputPath = parser.get("outputPath");
log.info("outputPath: {}", outputPath);
+ boolean filterInvisible = Boolean.parseBoolean(parser.get("filterInvisible"));
+ log.info("filterInvisible: {}", filterInvisible);
+
SparkConf conf = new SparkConf();
conf.set("spark.serializer", "org.apache.spark.serializer.KryoSerializer");
conf.registerKryoClasses(ModelSupport.getOafModelClasses());
+ final VocabularyGroup vocs = VocabularyGroup.loadVocsFromIS(isLookUpService);
+
runWithSparkSession(
conf,
isSparkSessionManaged,
spark -> {
- HdfsSupport.remove(outputPath, spark.sparkContext().hadoopConfiguration());
- groupEntities(spark, graphInputPath, outputPath);
+ HdfsSupport.remove(checkpointPath, spark.sparkContext().hadoopConfiguration());
+ groupEntities(spark, graphInputPath, checkpointPath, outputPath, filterInvisible, vocs);
});
}
private static void groupEntities(
SparkSession spark,
String inputPath,
- String outputPath) {
+ String checkpointPath,
+ String outputPath,
+ boolean filterInvisible, VocabularyGroup vocs) {
- final TypedColumn aggregator = new GroupingAggregator().toColumn();
- final JavaSparkContext sc = JavaSparkContext.fromSparkContext(spark.sparkContext());
- spark
- .read()
- .textFile(toSeq(listEntityPaths(inputPath, sc)))
- .map((MapFunction) GroupEntitiesSparkJob::parseOaf, Encoders.kryo(OafEntity.class))
- .filter((FilterFunction) e -> StringUtils.isNotBlank(ModelSupport.idFn().apply(e)))
- .groupByKey((MapFunction) oaf -> ModelSupport.idFn().apply(oaf), Encoders.STRING())
- .agg(aggregator)
+ Dataset allEntities = spark.emptyDataset(OAFENTITY_KRYO_ENC);
+
+ for (Map.Entry e : ModelSupport.entityTypes.entrySet()) {
+ String entity = e.getKey().name();
+ Class extends OafEntity> entityClass = e.getValue();
+ String entityInputPath = inputPath + "/" + entity;
+
+ if (!HdfsSupport.exists(entityInputPath, spark.sparkContext().hadoopConfiguration())) {
+ continue;
+ }
+
+ allEntities = allEntities
+ .union(
+ ((Dataset) spark
+ .read()
+ .schema(Encoders.bean(entityClass).schema())
+ .json(entityInputPath)
+ .filter("length(id) > 0")
+ .as(Encoders.bean(entityClass)))
+ .map((MapFunction) r -> r, OAFENTITY_KRYO_ENC));
+ }
+
+ Dataset> groupedEntities = allEntities
.map(
- (MapFunction, String>) t -> t._2().getClass().getName() +
- "|" + OBJECT_MAPPER.writeValueAsString(t._2()),
- Encoders.STRING())
+ (MapFunction) entity -> GraphCleaningFunctions
+ .applyCoarVocabularies(entity, vocs),
+ OAFENTITY_KRYO_ENC)
+ .groupByKey((MapFunction) OafEntity::getId, Encoders.STRING())
+ .reduceGroups((ReduceFunction) OafMapperUtils::mergeEntities)
+ .map(
+ (MapFunction, Tuple2>) t -> new Tuple2<>(
+ t._2().getClass().getName(), t._2()),
+ Encoders.tuple(Encoders.STRING(), OAFENTITY_KRYO_ENC));
+
+ // pivot on "_1" (classname of the entity)
+ // created columns containing only entities of the same class
+ for (Map.Entry e : ModelSupport.entityTypes.entrySet()) {
+ String entity = e.getKey().name();
+ Class extends OafEntity> entityClass = e.getValue();
+
+ groupedEntities = groupedEntities
+ .withColumn(
+ entity,
+ when(col("_1").equalTo(entityClass.getName()), col("_2")));
+ }
+
+ groupedEntities
+ .drop("_1", "_2")
.write()
- .option("compression", "gzip")
.mode(SaveMode.Overwrite)
- .text(outputPath);
- }
+ .option("compression", "gzip")
+ .save(checkpointPath);
- public static class GroupingAggregator extends Aggregator {
+ ForkJoinPool parPool = new ForkJoinPool(ModelSupport.entityTypes.size());
- @Override
- public OafEntity zero() {
- return null;
- }
-
- @Override
- public OafEntity reduce(OafEntity b, OafEntity a) {
- return mergeAndGet(b, a);
- }
-
- private OafEntity mergeAndGet(OafEntity b, OafEntity a) {
- if (Objects.nonNull(a) && Objects.nonNull(b)) {
- return OafMapperUtils.mergeEntities(b, a);
- }
- return Objects.isNull(a) ? b : a;
- }
-
- @Override
- public OafEntity merge(OafEntity b, OafEntity a) {
- return mergeAndGet(b, a);
- }
-
- @Override
- public OafEntity finish(OafEntity j) {
- return j;
- }
-
- @Override
- public Encoder bufferEncoder() {
- return Encoders.kryo(OafEntity.class);
- }
-
- @Override
- public Encoder outputEncoder() {
- return Encoders.kryo(OafEntity.class);
- }
-
- }
-
- private static OafEntity parseOaf(String s) {
-
- DocumentContext dc = JsonPath
- .parse(s, Configuration.defaultConfiguration().addOptions(Option.SUPPRESS_EXCEPTIONS));
- final String id = dc.read(ID_JPATH);
- if (StringUtils.isNotBlank(id)) {
-
- String prefix = StringUtils.substringBefore(id, "|");
- switch (prefix) {
- case "10":
- return parse(s, Datasource.class);
- case "20":
- return parse(s, Organization.class);
- case "40":
- return parse(s, Project.class);
- case "50":
- String resultType = dc.read("$.resulttype.classid");
- switch (resultType) {
- case "publication":
- return parse(s, Publication.class);
- case "dataset":
- return parse(s, eu.dnetlib.dhp.schema.oaf.Dataset.class);
- case "software":
- return parse(s, Software.class);
- case "other":
- return parse(s, OtherResearchProduct.class);
- default:
- throw new IllegalArgumentException(String.format("invalid resultType: '%s'", resultType));
- }
- default:
- throw new IllegalArgumentException(String.format("invalid id prefix: '%s'", prefix));
- }
- } else {
- throw new IllegalArgumentException(String.format("invalid oaf: '%s'", s));
- }
- }
-
- private static OafEntity parse(String s, Class clazz) {
- try {
- return OBJECT_MAPPER.readValue(s, clazz);
- } catch (IOException e) {
- throw new IllegalArgumentException(e);
- }
- }
-
- private static List listEntityPaths(String inputPath, JavaSparkContext sc) {
- return HdfsSupport
- .listFiles(inputPath, sc.hadoopConfiguration())
+ ModelSupport.entityTypes
+ .entrySet()
.stream()
- .filter(f -> !f.toLowerCase().contains("relation"))
- .collect(Collectors.toList());
- }
+ .map(e -> parPool.submit(() -> {
+ String entity = e.getKey().name();
+ Class extends OafEntity> entityClass = e.getValue();
+ spark
+ .read()
+ .load(checkpointPath)
+ .select(col(entity).as("value"))
+ .filter("value IS NOT NULL")
+ .as(OAFENTITY_KRYO_ENC)
+ .map((MapFunction) r -> r, (Encoder) Encoders.bean(entityClass))
+ .filter(filterInvisible ? "dataInfo.invisible != TRUE" : "TRUE")
+ .write()
+ .mode(SaveMode.Overwrite)
+ .option("compression", "gzip")
+ .json(outputPath + "/" + entity);
+ }))
+ .collect(Collectors.toList())
+ .forEach(t -> {
+ try {
+ t.get();
+ } catch (InterruptedException | ExecutionException e) {
+ throw new RuntimeException(e);
+ }
+ });
+ }
}
diff --git a/dhp-common/src/main/java/eu/dnetlib/dhp/oozie/RunSQLSparkJob.java b/dhp-common/src/main/java/eu/dnetlib/dhp/oozie/RunSQLSparkJob.java
new file mode 100644
index 000000000..027bf0735
--- /dev/null
+++ b/dhp-common/src/main/java/eu/dnetlib/dhp/oozie/RunSQLSparkJob.java
@@ -0,0 +1,77 @@
+
+package eu.dnetlib.dhp.oozie;
+
+import static eu.dnetlib.dhp.common.SparkSessionSupport.runWithSparkHiveSession;
+
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+
+import org.apache.commons.lang3.time.DurationFormatUtils;
+import org.apache.commons.text.StringSubstitutor;
+import org.apache.spark.SparkConf;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.io.Resources;
+
+import eu.dnetlib.dhp.application.ArgumentApplicationParser;
+
+public class RunSQLSparkJob {
+ private static final Logger log = LoggerFactory.getLogger(RunSQLSparkJob.class);
+
+ private final ArgumentApplicationParser parser;
+
+ public RunSQLSparkJob(ArgumentApplicationParser parser) {
+ this.parser = parser;
+ }
+
+ public static void main(String[] args) throws Exception {
+
+ Map params = new HashMap<>();
+ for (int i = 0; i < args.length - 1; i++) {
+ if (args[i].startsWith("--")) {
+ params.put(args[i].substring(2), args[++i]);
+ }
+ }
+
+ /*
+ * String jsonConfiguration = IOUtils .toString( Objects .requireNonNull( RunSQLSparkJob.class
+ * .getResourceAsStream( "/eu/dnetlib/dhp/oozie/run_sql_parameters.json"))); final ArgumentApplicationParser
+ * parser = new ArgumentApplicationParser(jsonConfiguration); parser.parseArgument(args);
+ */
+
+ Boolean isSparkSessionManaged = Optional
+ .ofNullable(params.get("isSparkSessionManaged"))
+ .map(Boolean::valueOf)
+ .orElse(Boolean.TRUE);
+ log.info("isSparkSessionManaged: {}", isSparkSessionManaged);
+
+ URL url = com.google.common.io.Resources.getResource(params.get("sql"));
+ String raw_sql = Resources.toString(url, StandardCharsets.UTF_8);
+
+ String sql = StringSubstitutor.replace(raw_sql, params);
+ log.info("sql: {}", sql);
+
+ SparkConf conf = new SparkConf();
+ conf.set("hive.metastore.uris", params.get("hiveMetastoreUris"));
+
+ runWithSparkHiveSession(
+ conf,
+ isSparkSessionManaged,
+ spark -> {
+ for (String statement : sql.split(";\\s*/\\*\\s*EOS\\s*\\*/\\s*")) {
+ log.info("executing: {}", statement);
+ long startTime = System.currentTimeMillis();
+ spark.sql(statement).show();
+ log
+ .info(
+ "executed in {}",
+ DurationFormatUtils.formatDuration(System.currentTimeMillis() - startTime, "HH:mm:ss.S"));
+ }
+ });
+ }
+
+}
diff --git a/dhp-common/src/main/java/eu/dnetlib/dhp/schema/oaf/utils/FundRefCleaningRule.java b/dhp-common/src/main/java/eu/dnetlib/dhp/schema/oaf/utils/FundRefCleaningRule.java
index 7f6303825..a267b8b88 100644
--- a/dhp-common/src/main/java/eu/dnetlib/dhp/schema/oaf/utils/FundRefCleaningRule.java
+++ b/dhp-common/src/main/java/eu/dnetlib/dhp/schema/oaf/utils/FundRefCleaningRule.java
@@ -6,14 +6,16 @@ import java.util.regex.Pattern;
public class FundRefCleaningRule {
- public static String clean(final String fundrefId) {
+ public static final Pattern PATTERN = Pattern.compile("\\d+");
- String s = fundrefId
+ public static String clean(final String fundRefId) {
+
+ String s = fundRefId
.toLowerCase()
.replaceAll("\\s", "");
- Matcher m = Pattern.compile("\\d+").matcher(s);
- if (m.matches()) {
+ Matcher m = PATTERN.matcher(s);
+ if (m.find()) {
return m.group();
} else {
return "";
diff --git a/dhp-common/src/main/java/eu/dnetlib/dhp/schema/oaf/utils/GraphCleaningFunctions.java b/dhp-common/src/main/java/eu/dnetlib/dhp/schema/oaf/utils/GraphCleaningFunctions.java
index a47b63edb..0124e96fc 100644
--- a/dhp-common/src/main/java/eu/dnetlib/dhp/schema/oaf/utils/GraphCleaningFunctions.java
+++ b/dhp-common/src/main/java/eu/dnetlib/dhp/schema/oaf/utils/GraphCleaningFunctions.java
@@ -1,8 +1,12 @@
package eu.dnetlib.dhp.schema.oaf.utils;
+import static eu.dnetlib.dhp.schema.common.ModelConstants.*;
+import static eu.dnetlib.dhp.schema.common.ModelConstants.OPENAIRE_META_RESOURCE_TYPE;
import static eu.dnetlib.dhp.schema.oaf.utils.OafMapperUtils.getProvenance;
+import java.net.MalformedURLException;
+import java.net.URL;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
@@ -13,16 +17,13 @@ import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.commons.lang3.StringUtils;
-import org.apache.spark.api.java.function.MapFunction;
-import org.apache.spark.sql.Encoders;
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.sisyphsu.dateparser.DateParserUtils;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import eu.dnetlib.dhp.common.vocabulary.VocabularyGroup;
+import eu.dnetlib.dhp.common.vocabulary.VocabularyTerm;
import eu.dnetlib.dhp.schema.common.ModelConstants;
import eu.dnetlib.dhp.schema.common.ModelSupport;
import eu.dnetlib.dhp.schema.oaf.*;
@@ -30,6 +31,10 @@ import me.xuender.unidecode.Unidecode;
public class GraphCleaningFunctions extends CleaningFunctions {
+ public static final String DNET_PUBLISHERS = "dnet:publishers";
+
+ public static final String DNET_LICENSES = "dnet:licenses";
+
public static final String ORCID_CLEANING_REGEX = ".*([0-9]{4}).*[-–—−=].*([0-9]{4}).*[-–—−=].*([0-9]{4}).*[-–—−=].*([0-9x]{4})";
public static final int ORCID_LEN = 19;
public static final String CLEANING_REGEX = "(?:\\n|\\r|\\t)";
@@ -39,6 +44,68 @@ public class GraphCleaningFunctions extends CleaningFunctions {
public static final String TITLE_FILTER_REGEX = String.format("(%s)|\\W|\\d", TITLE_TEST);
public static final int TITLE_FILTER_RESIDUAL_LENGTH = 5;
+ private static final String NAME_CLEANING_REGEX = "[\\r\\n\\t\\s]+";
+
+ private static final Set INVALID_AUTHOR_NAMES = new HashSet<>();
+
+ private static final Set INVALID_URLS = new HashSet<>();
+
+ private static final Set INVALID_URL_HOSTS = new HashSet<>();
+
+ private static final HashSet PEER_REVIEWED_TYPES = new HashSet<>();
+
+ static {
+ PEER_REVIEWED_TYPES.add("Article");
+ PEER_REVIEWED_TYPES.add("Part of book or chapter of book");
+ PEER_REVIEWED_TYPES.add("Book");
+ PEER_REVIEWED_TYPES.add("Doctoral thesis");
+ PEER_REVIEWED_TYPES.add("Master thesis");
+ PEER_REVIEWED_TYPES.add("Data Paper");
+ PEER_REVIEWED_TYPES.add("Thesis");
+ PEER_REVIEWED_TYPES.add("Bachelor thesis");
+ PEER_REVIEWED_TYPES.add("Conference object");
+
+ INVALID_AUTHOR_NAMES.add("(:null)");
+ INVALID_AUTHOR_NAMES.add("(:unap)");
+ INVALID_AUTHOR_NAMES.add("(:tba)");
+ INVALID_AUTHOR_NAMES.add("(:unas)");
+ INVALID_AUTHOR_NAMES.add("(:unav)");
+ INVALID_AUTHOR_NAMES.add("(:unkn)");
+ INVALID_AUTHOR_NAMES.add("(:unkn) unknown");
+ INVALID_AUTHOR_NAMES.add(":none");
+ INVALID_AUTHOR_NAMES.add(":null");
+ INVALID_AUTHOR_NAMES.add(":unas");
+ INVALID_AUTHOR_NAMES.add(":unav");
+ INVALID_AUTHOR_NAMES.add(":unkn");
+ INVALID_AUTHOR_NAMES.add("[autor desconocido]");
+ INVALID_AUTHOR_NAMES.add("[s. n.]");
+ INVALID_AUTHOR_NAMES.add("[s.n]");
+ INVALID_AUTHOR_NAMES.add("[unknown]");
+ INVALID_AUTHOR_NAMES.add("anonymous");
+ INVALID_AUTHOR_NAMES.add("n.n.");
+ INVALID_AUTHOR_NAMES.add("nn");
+ INVALID_AUTHOR_NAMES.add("no name supplied");
+ INVALID_AUTHOR_NAMES.add("none");
+ INVALID_AUTHOR_NAMES.add("none available");
+ INVALID_AUTHOR_NAMES.add("not available not available");
+ INVALID_AUTHOR_NAMES.add("null &na;");
+ INVALID_AUTHOR_NAMES.add("null anonymous");
+ INVALID_AUTHOR_NAMES.add("unbekannt");
+ INVALID_AUTHOR_NAMES.add("unknown");
+
+ INVALID_URL_HOSTS.add("creativecommons.org");
+ INVALID_URL_HOSTS.add("www.academia.edu");
+ INVALID_URL_HOSTS.add("academia.edu");
+ INVALID_URL_HOSTS.add("researchgate.net");
+ INVALID_URL_HOSTS.add("www.researchgate.net");
+
+ INVALID_URLS.add("http://repo.scoap3.org/api");
+ INVALID_URLS.add("http://ora.ox.ac.uk/objects/uuid:");
+ INVALID_URLS.add("http://ntur.lib.ntu.edu.tw/news/agent_contract.pdf");
+ INVALID_URLS.add("https://media.springer.com/full/springer-instructions-for-authors-assets/pdf/SN_BPF_EN.pdf");
+ INVALID_URLS.add("http://www.tobaccoinduceddiseases.org/dl/61aad426c96519bea4040a374c6a6110/");
+ INVALID_URLS.add("https://www.bilboard.nl/verenigingsbladen/bestuurskundige-berichten");
+ }
public static T cleanContext(T value, String contextId, String verifyParam) {
if (ModelSupport.isSubClass(value, Result.class)) {
@@ -228,7 +295,7 @@ public class GraphCleaningFunctions extends CleaningFunctions {
}
public static boolean filter(T value) {
- if (Boolean.TRUE
+ if (!(value instanceof Relation) && (Boolean.TRUE
.equals(
Optional
.ofNullable(value)
@@ -239,15 +306,16 @@ public class GraphCleaningFunctions extends CleaningFunctions {
d -> Optional
.ofNullable(d.getInvisible())
.orElse(true))
- .orElse(true))
- .orElse(true))) {
+ .orElse(false))
+ .orElse(true)))) {
return true;
}
if (value instanceof Datasource) {
// nothing to evaluate here
} else if (value instanceof Project) {
- // nothing to evaluate here
+ final Project p = (Project) value;
+ return Objects.nonNull(p.getCode()) && StringUtils.isNotBlank(p.getCode().getValue());
} else if (value instanceof Organization) {
// nothing to evaluate here
} else if (value instanceof Relation) {
@@ -275,6 +343,12 @@ public class GraphCleaningFunctions extends CleaningFunctions {
public static T cleanup(T value, VocabularyGroup vocs) {
+ if (Objects.isNull(value.getDataInfo())) {
+ final DataInfo d = new DataInfo();
+ d.setDeletedbyinference(false);
+ value.setDataInfo(d);
+ }
+
if (value instanceof OafEntity) {
OafEntity e = (OafEntity) value;
@@ -294,6 +368,17 @@ public class GraphCleaningFunctions extends CleaningFunctions {
} else if (value instanceof Result) {
Result r = (Result) value;
+ if (Objects.isNull(r.getContext())) {
+ r.setContext(new ArrayList<>());
+ }
+
+ if (Objects.nonNull(r.getFulltext())
+ && (ModelConstants.SOFTWARE_RESULTTYPE_CLASSID.equals(r.getResulttype().getClassid()) ||
+ ModelConstants.DATASET_RESULTTYPE_CLASSID.equals(r.getResulttype().getClassid()))) {
+ r.setFulltext(null);
+
+ }
+
if (Objects.nonNull(r.getDateofacceptance())) {
Optional date = cleanDateField(r.getDateofacceptance());
if (date.isPresent()) {
@@ -318,8 +403,26 @@ public class GraphCleaningFunctions extends CleaningFunctions {
.filter(sp -> StringUtils.isNotBlank(sp.getValue()))
.collect(Collectors.toList()));
}
- if (Objects.nonNull(r.getPublisher()) && StringUtils.isBlank(r.getPublisher().getValue())) {
- r.setPublisher(null);
+ if (Objects.nonNull(r.getPublisher())) {
+ if (StringUtils.isBlank(r.getPublisher().getValue())) {
+ r.setPublisher(null);
+ } else {
+ r
+ .getPublisher()
+ .setValue(
+ r
+ .getPublisher()
+ .getValue()
+ .replaceAll(NAME_CLEANING_REGEX, " "));
+
+ if (vocs.vocabularyExists(DNET_PUBLISHERS)) {
+ vocs
+ .find(DNET_PUBLISHERS)
+ .map(voc -> voc.getTermBySynonym(r.getPublisher().getValue()))
+ .map(VocabularyTerm::getName)
+ .ifPresent(publisher -> r.getPublisher().setValue(publisher));
+ }
+ }
}
if (Objects.isNull(r.getLanguage()) || StringUtils.isBlank(r.getLanguage().getClassid())) {
r
@@ -478,6 +581,43 @@ public class GraphCleaningFunctions extends CleaningFunctions {
if (Objects.isNull(i.getRefereed()) || StringUtils.isBlank(i.getRefereed().getClassid())) {
i.setRefereed(qualifier("0000", "Unknown", ModelConstants.DNET_REVIEW_LEVELS));
}
+
+ if (Objects.nonNull(i.getLicense()) && Objects.nonNull(i.getLicense().getValue())) {
+ vocs
+ .find(DNET_LICENSES)
+ .map(voc -> voc.getTermBySynonym(i.getLicense().getValue()))
+ .map(VocabularyTerm::getId)
+ .ifPresent(license -> i.getLicense().setValue(license));
+ }
+
+ // from the script from Dimitris
+ if ("0000".equals(i.getRefereed().getClassid())) {
+ final boolean isFromCrossref = Optional
+ .ofNullable(i.getCollectedfrom())
+ .map(KeyValue::getKey)
+ .map(id -> id.equals(ModelConstants.CROSSREF_ID))
+ .orElse(false);
+ final boolean hasDoi = Optional
+ .ofNullable(i.getPid())
+ .map(
+ pid -> pid
+ .stream()
+ .anyMatch(
+ p -> PidType.doi.toString().equals(p.getQualifier().getClassid())))
+ .orElse(false);
+ final boolean isPeerReviewedType = PEER_REVIEWED_TYPES
+ .contains(i.getInstancetype().getClassname());
+ final boolean noOtherLitType = r
+ .getInstance()
+ .stream()
+ .noneMatch(ii -> "Other literature type".equals(ii.getInstancetype().getClassname()));
+ if (isFromCrossref && hasDoi && isPeerReviewedType && noOtherLitType) {
+ i.setRefereed(qualifier("0001", "peerReviewed", ModelConstants.DNET_REVIEW_LEVELS));
+ } else {
+ i.setRefereed(qualifier("0002", "nonPeerReviewed", ModelConstants.DNET_REVIEW_LEVELS));
+ }
+ }
+
if (Objects.nonNull(i.getDateofacceptance())) {
Optional date = cleanDateField(i.getDateofacceptance());
if (date.isPresent()) {
@@ -486,6 +626,20 @@ public class GraphCleaningFunctions extends CleaningFunctions {
i.setDateofacceptance(null);
}
}
+ if (StringUtils.isNotBlank(i.getFulltext()) &&
+ (ModelConstants.SOFTWARE_RESULTTYPE_CLASSID.equals(r.getResulttype().getClassid()) ||
+ ModelConstants.DATASET_RESULTTYPE_CLASSID.equals(r.getResulttype().getClassid()))) {
+ i.setFulltext(null);
+ }
+ if (Objects.nonNull(i.getUrl())) {
+ i
+ .setUrl(
+ i
+ .getUrl()
+ .stream()
+ .filter(GraphCleaningFunctions::urlFilter)
+ .collect(Collectors.toList()));
+ }
}
}
if (Objects.isNull(r.getBestaccessright())
@@ -508,8 +662,8 @@ public class GraphCleaningFunctions extends CleaningFunctions {
.getAuthor()
.stream()
.filter(Objects::nonNull)
- .filter(a -> StringUtils.isNotBlank(a.getFullname()))
- .filter(a -> StringUtils.isNotBlank(a.getFullname().replaceAll("[\\W]", "")))
+ .filter(GraphCleaningFunctions::isValidAuthorName)
+ .map(GraphCleaningFunctions::cleanupAuthor)
.collect(Collectors.toList()));
boolean nullRank = r
@@ -535,6 +689,9 @@ public class GraphCleaningFunctions extends CleaningFunctions {
.filter(Objects::nonNull)
.filter(p -> Objects.nonNull(p.getQualifier()))
.filter(p -> StringUtils.isNotBlank(p.getValue()))
+ .filter(
+ p -> StringUtils
+ .contains(StringUtils.lowerCase(p.getQualifier().getClassid()), ORCID))
.map(p -> {
// hack to distinguish orcid from orcid_pending
String pidProvenance = getProvenance(p.getDataInfo());
@@ -544,7 +701,8 @@ public class GraphCleaningFunctions extends CleaningFunctions {
.toLowerCase()
.contains(ModelConstants.ORCID)) {
if (pidProvenance
- .equals(ModelConstants.SYSIMPORT_CROSSWALK_ENTITYREGISTRY)) {
+ .equals(ModelConstants.SYSIMPORT_CROSSWALK_ENTITYREGISTRY) ||
+ pidProvenance.equals("ORCID_ENRICHMENT")) {
p.getQualifier().setClassid(ModelConstants.ORCID);
} else {
p.getQualifier().setClassid(ModelConstants.ORCID_PENDING);
@@ -604,6 +762,35 @@ public class GraphCleaningFunctions extends CleaningFunctions {
return value;
}
+ private static Author cleanupAuthor(Author author) {
+ if (StringUtils.isNotBlank(author.getFullname())) {
+ author
+ .setFullname(
+ author
+ .getFullname()
+ .replaceAll(NAME_CLEANING_REGEX, " ")
+ .replace("\"", "\\\""));
+ }
+ if (StringUtils.isNotBlank(author.getName())) {
+ author
+ .setName(
+ author
+ .getName()
+ .replaceAll(NAME_CLEANING_REGEX, " ")
+ .replace("\"", "\\\""));
+ }
+ if (StringUtils.isNotBlank(author.getSurname())) {
+ author
+ .setSurname(
+ author
+ .getSurname()
+ .replaceAll(NAME_CLEANING_REGEX, " ")
+ .replace("\"", "\\\""));
+ }
+
+ return author;
+ }
+
private static Optional cleanDateField(Field dateofacceptance) {
return Optional
.ofNullable(dateofacceptance)
@@ -637,12 +824,30 @@ public class GraphCleaningFunctions extends CleaningFunctions {
// HELPERS
private static boolean isValidAuthorName(Author a) {
- return !Stream
- .of(a.getFullname(), a.getName(), a.getSurname())
- .filter(s -> s != null && !s.isEmpty())
- .collect(Collectors.joining(""))
- .toLowerCase()
- .matches(INVALID_AUTHOR_REGEX);
+ return StringUtils.isNotBlank(a.getFullname()) &&
+ StringUtils.isNotBlank(a.getFullname().replaceAll("[\\W]", "")) &&
+ !INVALID_AUTHOR_NAMES.contains(StringUtils.lowerCase(a.getFullname()).trim()) &&
+ !Stream
+ .of(a.getFullname(), a.getName(), a.getSurname())
+ .filter(StringUtils::isNotBlank)
+ .collect(Collectors.joining(""))
+ .toLowerCase()
+ .matches(INVALID_AUTHOR_REGEX);
+ }
+
+ private static boolean urlFilter(String u) {
+ try {
+ final URL url = new URL(u);
+ if (StringUtils.isBlank(url.getPath()) || "/".equals(url.getPath())) {
+ return false;
+ }
+ if (INVALID_URL_HOSTS.contains(url.getHost())) {
+ return false;
+ }
+ return !INVALID_URLS.contains(url.toString());
+ } catch (MalformedURLException ex) {
+ return false;
+ }
}
private static List processPidCleaning(List pids) {
@@ -692,4 +897,105 @@ public class GraphCleaningFunctions extends CleaningFunctions {
return s;
}
+ public static OafEntity applyCoarVocabularies(OafEntity entity, VocabularyGroup vocs) {
+
+ if (entity instanceof Result) {
+ final Result result = (Result) entity;
+
+ Optional
+ .ofNullable(result.getInstance())
+ .ifPresent(
+ instances -> instances
+ .forEach(
+ instance -> {
+ if (Objects.isNull(instance.getInstanceTypeMapping())) {
+ List mapping = Lists.newArrayList();
+ mapping
+ .add(
+ OafMapperUtils
+ .instanceTypeMapping(
+ instance.getInstancetype().getClassname(),
+ OPENAIRE_COAR_RESOURCE_TYPES_3_1));
+ instance.setInstanceTypeMapping(mapping);
+ }
+ Optional optionalItm = instance
+ .getInstanceTypeMapping()
+ .stream()
+ .filter(GraphCleaningFunctions::originalResourceType)
+ .findFirst();
+ if (optionalItm.isPresent()) {
+ InstanceTypeMapping coarItm = optionalItm.get();
+ Optional
+ .ofNullable(
+ vocs
+ .lookupTermBySynonym(
+ OPENAIRE_COAR_RESOURCE_TYPES_3_1, coarItm.getOriginalType()))
+ .ifPresent(type -> {
+ coarItm.setTypeCode(type.getClassid());
+ coarItm.setTypeLabel(type.getClassname());
+ });
+ final List mappings = Lists.newArrayList();
+ if (vocs.vocabularyExists(OPENAIRE_USER_RESOURCE_TYPES)) {
+ Optional
+ .ofNullable(
+ vocs
+ .lookupTermBySynonym(
+ OPENAIRE_USER_RESOURCE_TYPES, coarItm.getTypeCode()))
+ .ifPresent(
+ type -> mappings
+ .add(
+ OafMapperUtils
+ .instanceTypeMapping(coarItm.getTypeCode(), type)));
+ }
+ if (!mappings.isEmpty()) {
+ instance.getInstanceTypeMapping().addAll(mappings);
+ }
+ }
+ }));
+ result.setMetaResourceType(getMetaResourceType(result.getInstance(), vocs));
+ }
+
+ return entity;
+ }
+
+ private static boolean originalResourceType(InstanceTypeMapping itm) {
+ return StringUtils.isNotBlank(itm.getOriginalType()) &&
+ OPENAIRE_COAR_RESOURCE_TYPES_3_1.equals(itm.getVocabularyName()) &&
+ StringUtils.isBlank(itm.getTypeCode()) &&
+ StringUtils.isBlank(itm.getTypeLabel());
+ }
+
+ private static Qualifier getMetaResourceType(final List instances, final VocabularyGroup vocs) {
+ return Optional
+ .ofNullable(instances)
+ .map(ii -> {
+ if (vocs.vocabularyExists(OPENAIRE_META_RESOURCE_TYPE)) {
+ Optional itm = ii
+ .stream()
+ .filter(Objects::nonNull)
+ .flatMap(
+ i -> Optional
+ .ofNullable(i.getInstanceTypeMapping())
+ .map(Collection::stream)
+ .orElse(Stream.empty()))
+ .filter(t -> OPENAIRE_COAR_RESOURCE_TYPES_3_1.equals(t.getVocabularyName()))
+ .findFirst();
+
+ if (!itm.isPresent() || Objects.isNull(itm.get().getTypeCode())) {
+ return null;
+ } else {
+ final String typeCode = itm.get().getTypeCode();
+ return Optional
+ .ofNullable(vocs.lookupTermBySynonym(OPENAIRE_META_RESOURCE_TYPE, typeCode))
+ .orElseThrow(
+ () -> new IllegalStateException("unable to find a synonym for '" + typeCode + "' in " +
+ OPENAIRE_META_RESOURCE_TYPE));
+ }
+ } else {
+ throw new IllegalStateException("vocabulary '" + OPENAIRE_META_RESOURCE_TYPE + "' not available");
+ }
+ })
+ .orElse(null);
+ }
+
}
diff --git a/dhp-common/src/main/java/eu/dnetlib/dhp/schema/oaf/utils/GridCleaningRule.java b/dhp-common/src/main/java/eu/dnetlib/dhp/schema/oaf/utils/GridCleaningRule.java
index ff45d6a0d..37ab91dd5 100644
--- a/dhp-common/src/main/java/eu/dnetlib/dhp/schema/oaf/utils/GridCleaningRule.java
+++ b/dhp-common/src/main/java/eu/dnetlib/dhp/schema/oaf/utils/GridCleaningRule.java
@@ -6,13 +6,19 @@ import java.util.regex.Pattern;
public class GridCleaningRule {
+ public static final Pattern PATTERN = Pattern.compile("(?\\d{4,6}\\.[0-9a-z]{1,2})");
+
public static String clean(String grid) {
String s = grid
.replaceAll("\\s", "")
.toLowerCase();
- Matcher m = Pattern.compile("\\d{4,6}\\.[0-9a-z]{1,2}").matcher(s);
- return m.matches() ? "grid." + m.group() : "";
+ Matcher m = PATTERN.matcher(s);
+ if (m.find()) {
+ return "grid." + m.group("grid");
+ }
+
+ return "";
}
}
diff --git a/dhp-common/src/main/java/eu/dnetlib/dhp/schema/oaf/utils/ISNICleaningRule.java b/dhp-common/src/main/java/eu/dnetlib/dhp/schema/oaf/utils/ISNICleaningRule.java
index 5bc49c453..bcd8279cc 100644
--- a/dhp-common/src/main/java/eu/dnetlib/dhp/schema/oaf/utils/ISNICleaningRule.java
+++ b/dhp-common/src/main/java/eu/dnetlib/dhp/schema/oaf/utils/ISNICleaningRule.java
@@ -7,10 +7,12 @@ import java.util.regex.Pattern;
// https://www.wikidata.org/wiki/Property:P213
public class ISNICleaningRule {
+ public static final Pattern PATTERN = Pattern.compile("([0]{4}) ?([0-9]{4}) ?([0-9]{4}) ?([0-9]{3}[0-9X])");
+
public static String clean(final String isni) {
- Matcher m = Pattern.compile("([0]{4}) ?([0-9]{4}) ?([0-9]{4}) ?([0-9]{3}[0-9X])").matcher(isni);
- if (m.matches()) {
+ Matcher m = PATTERN.matcher(isni);
+ if (m.find()) {
return String.join("", m.group(1), m.group(2), m.group(3), m.group(4));
} else {
return "";
diff --git a/dhp-common/src/main/java/eu/dnetlib/dhp/schema/oaf/utils/OafMapperUtils.java b/dhp-common/src/main/java/eu/dnetlib/dhp/schema/oaf/utils/OafMapperUtils.java
index c58096d35..4cecd0895 100644
--- a/dhp-common/src/main/java/eu/dnetlib/dhp/schema/oaf/utils/OafMapperUtils.java
+++ b/dhp-common/src/main/java/eu/dnetlib/dhp/schema/oaf/utils/OafMapperUtils.java
@@ -14,7 +14,6 @@ import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import eu.dnetlib.dhp.schema.common.AccessRightComparator;
-import eu.dnetlib.dhp.schema.common.ModelConstants;
import eu.dnetlib.dhp.schema.common.ModelSupport;
import eu.dnetlib.dhp.schema.oaf.*;
@@ -141,6 +140,28 @@ public class OafMapperUtils {
.collect(Collectors.toList());
}
+ public static InstanceTypeMapping instanceTypeMapping(String originalType, String code, String label,
+ String vocabularyName) {
+ final InstanceTypeMapping m = new InstanceTypeMapping();
+ m.setVocabularyName(vocabularyName);
+ m.setOriginalType(originalType);
+ m.setTypeCode(code);
+ m.setTypeLabel(label);
+ return m;
+ }
+
+ public static InstanceTypeMapping instanceTypeMapping(String originalType, Qualifier term) {
+ return instanceTypeMapping(originalType, term.getClassid(), term.getClassname(), term.getSchemeid());
+ }
+
+ public static InstanceTypeMapping instanceTypeMapping(String originalType) {
+ return instanceTypeMapping(originalType, null, null, null);
+ }
+
+ public static InstanceTypeMapping instanceTypeMapping(String originalType, String vocabularyName) {
+ return instanceTypeMapping(originalType, null, null, vocabularyName);
+ }
+
public static Qualifier unknown(final String schemeid, final String schemename) {
return qualifier(UNKNOWN, "Unknown", schemeid, schemename);
}
diff --git a/dhp-common/src/main/java/eu/dnetlib/dhp/schema/oaf/utils/PICCleaningRule.java b/dhp-common/src/main/java/eu/dnetlib/dhp/schema/oaf/utils/PICCleaningRule.java
index 83b9a1f9f..a2213ed9f 100644
--- a/dhp-common/src/main/java/eu/dnetlib/dhp/schema/oaf/utils/PICCleaningRule.java
+++ b/dhp-common/src/main/java/eu/dnetlib/dhp/schema/oaf/utils/PICCleaningRule.java
@@ -6,10 +6,12 @@ import java.util.regex.Pattern;
public class PICCleaningRule {
+ public static final Pattern PATTERN = Pattern.compile("\\d{9}");
+
public static String clean(final String pic) {
- Matcher m = Pattern.compile("\\d{9}").matcher(pic);
- if (m.matches()) {
+ Matcher m = PATTERN.matcher(pic);
+ if (m.find()) {
return m.group();
} else {
return "";
diff --git a/dhp-common/src/main/java/eu/dnetlib/dhp/schema/oaf/utils/PmcCleaningRule.java b/dhp-common/src/main/java/eu/dnetlib/dhp/schema/oaf/utils/PmcCleaningRule.java
index 4e1205805..903041d43 100644
--- a/dhp-common/src/main/java/eu/dnetlib/dhp/schema/oaf/utils/PmcCleaningRule.java
+++ b/dhp-common/src/main/java/eu/dnetlib/dhp/schema/oaf/utils/PmcCleaningRule.java
@@ -1,13 +1,24 @@
package eu.dnetlib.dhp.schema.oaf.utils;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
public class PmcCleaningRule {
+ public static final Pattern PATTERN = Pattern.compile("PMC\\d{1,8}");
+
public static String clean(String pmc) {
String s = pmc
.replaceAll("\\s", "")
.toUpperCase();
- return s.matches("^PMC\\d{1,8}$") ? s : "";
+
+ final Matcher m = PATTERN.matcher(s);
+
+ if (m.find()) {
+ return m.group();
+ }
+ return "";
}
}
diff --git a/dhp-common/src/main/java/eu/dnetlib/dhp/schema/oaf/utils/PmidCleaningRule.java b/dhp-common/src/main/java/eu/dnetlib/dhp/schema/oaf/utils/PmidCleaningRule.java
index 65833a594..c0c451b88 100644
--- a/dhp-common/src/main/java/eu/dnetlib/dhp/schema/oaf/utils/PmidCleaningRule.java
+++ b/dhp-common/src/main/java/eu/dnetlib/dhp/schema/oaf/utils/PmidCleaningRule.java
@@ -1,16 +1,25 @@
package eu.dnetlib.dhp.schema.oaf.utils;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
// https://researchguides.stevens.edu/c.php?g=442331&p=6577176
public class PmidCleaningRule {
+ public static final Pattern PATTERN = Pattern.compile("0*(\\d{1,8})");
+
public static String clean(String pmid) {
String s = pmid
.toLowerCase()
- .replaceAll("\\s", "")
- .trim()
- .replaceAll("^0+", "");
- return s.matches("^\\d{1,8}$") ? s : "";
+ .replaceAll("\\s", "");
+
+ final Matcher m = PATTERN.matcher(s);
+
+ if (m.find()) {
+ return m.group(1);
+ }
+ return "";
}
}
diff --git a/dhp-common/src/main/java/eu/dnetlib/dhp/schema/oaf/utils/RorCleaningRule.java b/dhp-common/src/main/java/eu/dnetlib/dhp/schema/oaf/utils/RorCleaningRule.java
index f40cdb00c..f6685f19d 100644
--- a/dhp-common/src/main/java/eu/dnetlib/dhp/schema/oaf/utils/RorCleaningRule.java
+++ b/dhp-common/src/main/java/eu/dnetlib/dhp/schema/oaf/utils/RorCleaningRule.java
@@ -7,12 +7,21 @@ import java.util.regex.Pattern;
// https://ror.readme.io/docs/ror-identifier-pattern
public class RorCleaningRule {
+ public static final String ROR_PREFIX = "https://ror.org/";
+
+ private static final Pattern PATTERN = Pattern.compile("(?0[a-hj-km-np-tv-z|0-9]{6}[0-9]{2})");
+
public static String clean(String ror) {
String s = ror
.replaceAll("\\s", "")
.toLowerCase();
- Matcher m = Pattern.compile("0[a-hj-km-np-tv-z|0-9]{6}[0-9]{2}").matcher(s);
- return m.matches() ? "https://ror.org/" + m.group() : "";
+
+ Matcher m = PATTERN.matcher(s);
+
+ if (m.find()) {
+ return ROR_PREFIX + m.group("ror");
+ }
+ return "";
}
}
diff --git a/dhp-common/src/main/resources/eu/dnetlib/dhp/oa/merge/group_graph_entities_parameters.json b/dhp-common/src/main/resources/eu/dnetlib/dhp/oa/merge/group_graph_entities_parameters.json
index e65acb3c4..512878457 100644
--- a/dhp-common/src/main/resources/eu/dnetlib/dhp/oa/merge/group_graph_entities_parameters.json
+++ b/dhp-common/src/main/resources/eu/dnetlib/dhp/oa/merge/group_graph_entities_parameters.json
@@ -8,13 +8,31 @@
{
"paramName": "gin",
"paramLongName": "graphInputPath",
- "paramDescription": "the graph root path",
+ "paramDescription": "the input graph root path",
+ "paramRequired": true
+ },
+ {
+ "paramName": "cp",
+ "paramLongName": "checkpointPath",
+ "paramDescription": "checkpoint directory",
"paramRequired": true
},
{
"paramName": "out",
"paramLongName": "outputPath",
- "paramDescription": "the output merged graph root path",
+ "paramDescription": "the output graph root path",
+ "paramRequired": true
+ },
+ {
+ "paramName": "fi",
+ "paramLongName": "filterInvisible",
+ "paramDescription": "if true filters out invisible entities",
+ "paramRequired": true
+ },
+ {
+ "paramName": "isu",
+ "paramLongName": "isLookupUrl",
+ "paramDescription": "url to the ISLookup Service",
"paramRequired": true
}
]
\ No newline at end of file
diff --git a/dhp-common/src/main/resources/eu/dnetlib/dhp/oozie/run_sql_parameters.json b/dhp-common/src/main/resources/eu/dnetlib/dhp/oozie/run_sql_parameters.json
new file mode 100644
index 000000000..355f38e2f
--- /dev/null
+++ b/dhp-common/src/main/resources/eu/dnetlib/dhp/oozie/run_sql_parameters.json
@@ -0,0 +1,20 @@
+[
+ {
+ "paramName": "issm",
+ "paramLongName": "isSparkSessionManaged",
+ "paramDescription": "when true will stop SparkSession after job execution",
+ "paramRequired": false
+ },
+ {
+ "paramName": "hmu",
+ "paramLongName": "hiveMetastoreUris",
+ "paramDescription": "the hive metastore uris",
+ "paramRequired": true
+ },
+ {
+ "paramName": "sql",
+ "paramLongName": "sql",
+ "paramDescription": "sql script to execute",
+ "paramRequired": true
+ }
+]
\ No newline at end of file
diff --git a/dhp-common/src/test/java/eu/dnetlib/dhp/common/MdStoreClientTest.java b/dhp-common/src/test/java/eu/dnetlib/dhp/common/MdStoreClientTest.java
index f38d04979..f87f6e313 100644
--- a/dhp-common/src/test/java/eu/dnetlib/dhp/common/MdStoreClientTest.java
+++ b/dhp-common/src/test/java/eu/dnetlib/dhp/common/MdStoreClientTest.java
@@ -15,7 +15,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
public class MdStoreClientTest {
- @Test
+ // @Test
public void testMongoCollection() throws IOException {
final MdstoreClient client = new MdstoreClient("mongodb://localhost:27017", "mdstore");
diff --git a/dhp-common/src/test/java/eu/dnetlib/dhp/schema/oaf/utils/GridCleaningRuleTest.java b/dhp-common/src/test/java/eu/dnetlib/dhp/schema/oaf/utils/GridCleaningRuleTest.java
new file mode 100644
index 000000000..1b9163d46
--- /dev/null
+++ b/dhp-common/src/test/java/eu/dnetlib/dhp/schema/oaf/utils/GridCleaningRuleTest.java
@@ -0,0 +1,18 @@
+
+package eu.dnetlib.dhp.schema.oaf.utils;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+
+class GridCleaningRuleTest {
+
+ @Test
+ void testCleaning() {
+ assertEquals("grid.493784.5", GridCleaningRule.clean("grid.493784.5"));
+ assertEquals("grid.493784.5x", GridCleaningRule.clean("grid.493784.5x"));
+ assertEquals("grid.493784.5x", GridCleaningRule.clean("493784.5x"));
+ assertEquals("", GridCleaningRule.clean("493x784.5x"));
+ }
+
+}
diff --git a/dhp-common/src/test/java/eu/dnetlib/dhp/schema/oaf/utils/ISNICleaningRuleTest.java b/dhp-common/src/test/java/eu/dnetlib/dhp/schema/oaf/utils/ISNICleaningRuleTest.java
new file mode 100644
index 000000000..e51d1e05c
--- /dev/null
+++ b/dhp-common/src/test/java/eu/dnetlib/dhp/schema/oaf/utils/ISNICleaningRuleTest.java
@@ -0,0 +1,19 @@
+
+package eu.dnetlib.dhp.schema.oaf.utils;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+
+class ISNICleaningRuleTest {
+
+ @Test
+ void testCleaning() {
+ assertEquals("0000000463436020", ISNICleaningRule.clean("0000 0004 6343 6020"));
+ assertEquals("0000000463436020", ISNICleaningRule.clean("0000000463436020"));
+ assertEquals("", ISNICleaningRule.clean("Q30256598"));
+ assertEquals("0000000493403529", ISNICleaningRule.clean("ISNI:0000000493403529"));
+ assertEquals("000000008614884X", ISNICleaningRule.clean("0000 0000 8614 884X"));
+ }
+
+}
diff --git a/dhp-common/src/test/java/eu/dnetlib/dhp/schema/oaf/utils/PICCleaningRuleTest.java b/dhp-common/src/test/java/eu/dnetlib/dhp/schema/oaf/utils/PICCleaningRuleTest.java
new file mode 100644
index 000000000..3736033c3
--- /dev/null
+++ b/dhp-common/src/test/java/eu/dnetlib/dhp/schema/oaf/utils/PICCleaningRuleTest.java
@@ -0,0 +1,19 @@
+
+package eu.dnetlib.dhp.schema.oaf.utils;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+
+class PICCleaningRuleTest {
+
+ @Test
+ void testCleaning() {
+ assertEquals("887624982", PICCleaningRule.clean("887624982"));
+ assertEquals("", PICCleaningRule.clean("887 624982"));
+ assertEquals("887624982", PICCleaningRule.clean(" 887624982 "));
+ assertEquals("887624982", PICCleaningRule.clean(" 887624982x "));
+ assertEquals("887624982", PICCleaningRule.clean(" 88762498200 "));
+ }
+
+}
diff --git a/dhp-common/src/test/java/eu/dnetlib/dhp/schema/oaf/utils/PmcCleaningRuleTest.java b/dhp-common/src/test/java/eu/dnetlib/dhp/schema/oaf/utils/PmcCleaningRuleTest.java
new file mode 100644
index 000000000..e53ebae89
--- /dev/null
+++ b/dhp-common/src/test/java/eu/dnetlib/dhp/schema/oaf/utils/PmcCleaningRuleTest.java
@@ -0,0 +1,19 @@
+
+package eu.dnetlib.dhp.schema.oaf.utils;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+
+class PmcCleaningRuleTest {
+
+ @Test
+ void testCleaning() {
+ assertEquals("PMC1234", PmcCleaningRule.clean("PMC1234"));
+ assertEquals("PMC1234", PmcCleaningRule.clean(" PMC1234"));
+ assertEquals("PMC12345678", PmcCleaningRule.clean("PMC12345678"));
+ assertEquals("PMC12345678", PmcCleaningRule.clean("PMC123456789"));
+ assertEquals("PMC12345678", PmcCleaningRule.clean("PMC 12345678"));
+ }
+
+}
diff --git a/dhp-common/src/test/java/eu/dnetlib/dhp/schema/oaf/utils/PmidCleaningRuleTest.java b/dhp-common/src/test/java/eu/dnetlib/dhp/schema/oaf/utils/PmidCleaningRuleTest.java
new file mode 100644
index 000000000..295eac85f
--- /dev/null
+++ b/dhp-common/src/test/java/eu/dnetlib/dhp/schema/oaf/utils/PmidCleaningRuleTest.java
@@ -0,0 +1,24 @@
+
+package eu.dnetlib.dhp.schema.oaf.utils;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+
+class PmidCleaningRuleTest {
+
+ @Test
+ void testCleaning() {
+ // leading zeros are removed
+ assertEquals("1234", PmidCleaningRule.clean("01234"));
+ // tolerant to spaces in the middle
+ assertEquals("1234567", PmidCleaningRule.clean("0123 4567"));
+ // stop parsing at first not numerical char
+ assertEquals("123", PmidCleaningRule.clean("0123x4567"));
+ // invalid id leading to empty result
+ assertEquals("", PmidCleaningRule.clean("abc"));
+ // valid id with zeroes in the number
+ assertEquals("20794075", PmidCleaningRule.clean("20794075"));
+ }
+
+}
diff --git a/dhp-common/src/test/java/eu/dnetlib/dhp/schema/oaf/utils/RorCleaningRuleTest.java b/dhp-common/src/test/java/eu/dnetlib/dhp/schema/oaf/utils/RorCleaningRuleTest.java
new file mode 100644
index 000000000..5d5c03959
--- /dev/null
+++ b/dhp-common/src/test/java/eu/dnetlib/dhp/schema/oaf/utils/RorCleaningRuleTest.java
@@ -0,0 +1,17 @@
+
+package eu.dnetlib.dhp.schema.oaf.utils;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.Test;
+
+class RorCleaningRuleTest {
+
+ @Test
+ void testCleaning() {
+ assertEquals("https://ror.org/05rpz9w55", RorCleaningRule.clean("https://ror.org/05rpz9w55"));
+ assertEquals("https://ror.org/05rpz9w55", RorCleaningRule.clean("05rpz9w55"));
+ assertEquals("", RorCleaningRule.clean("05rpz9w_55"));
+ }
+
+}
diff --git a/dhp-common/src/test/java/eu/dnetlib/oa/merge/AuthorMergerTest.java b/dhp-common/src/test/java/eu/dnetlib/oa/merge/AuthorMergerTest.java
new file mode 100644
index 000000000..c0a8d6927
--- /dev/null
+++ b/dhp-common/src/test/java/eu/dnetlib/oa/merge/AuthorMergerTest.java
@@ -0,0 +1,114 @@
+
+package eu.dnetlib.oa.merge;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.util.List;
+import java.util.Objects;
+
+import org.junit.jupiter.api.Test;
+import org.junit.platform.commons.util.StringUtils;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import eu.dnetlib.dhp.oa.merge.AuthorMerger;
+import eu.dnetlib.dhp.schema.oaf.Author;
+
+public class AuthorMergerTest {
+
+ @Test
+ public void testEnrcichAuthor() throws Exception {
+ final ObjectMapper mapper = new ObjectMapper();
+
+ BufferedReader pr = new BufferedReader(new InputStreamReader(
+ Objects
+ .requireNonNull(
+ AuthorMergerTest.class
+ .getResourceAsStream("/eu/dnetlib/dhp/oa/merge/authors_publication_sample.json"))));
+ BufferedReader or = new BufferedReader(new InputStreamReader(
+ Objects
+ .requireNonNull(
+ AuthorMergerTest.class.getResourceAsStream("/eu/dnetlib/dhp/oa/merge/authors_orcid_sample.json"))));
+
+ TypeReference> aclass = new TypeReference>() {
+ };
+ String pubLine;
+
+ int i = 0;
+ while ((pubLine = pr.readLine()) != null) {
+ final String pubId = pubLine;
+ final String MatchPidOrcid = or.readLine();
+ final String pubOrcid = or.readLine();
+
+ final String data = pr.readLine();
+
+ if (StringUtils.isNotBlank(data)) {
+ List publicationAuthors = mapper.readValue(data, aclass);
+ List orcidAuthors = mapper.readValue(or.readLine(), aclass);
+ System.out.printf("OAF ID = %s \n", pubId);
+ System.out.printf("ORCID Intersected ID = %s \n", pubOrcid);
+ System.out.printf("OAF Author Size = %d \n", publicationAuthors.size());
+ System.out.printf("Oricd Author Size = %d \n", orcidAuthors.size());
+ System.out.printf("Oricd Matched PID = %s \n", MatchPidOrcid);
+
+ long originalAuthorWithPiD = publicationAuthors
+ .stream()
+ .filter(
+ a -> a.getPid() != null && a
+ .getPid()
+ .stream()
+ .anyMatch(
+ p -> p.getQualifier() != null
+ && p.getQualifier().getClassid().toLowerCase().contains("orcid")))
+ .count();
+ long start = System.currentTimeMillis();
+
+// final List enrichedList = AuthorMerger.enrichOrcid(publicationAuthors, orcidAuthors);
+ final List enrichedList = AuthorMerger.enrichOrcid(publicationAuthors, orcidAuthors);
+
+ long enrichedAuthorWithPid = enrichedList
+ .stream()
+ .filter(
+ a -> a.getPid() != null && a
+ .getPid()
+ .stream()
+ .anyMatch(
+ p -> p.getQualifier() != null
+ && p.getQualifier().getClassid().toLowerCase().contains("orcid")))
+ .count();
+
+ long totalTime = (System.currentTimeMillis() - start) / 1000;
+ System.out
+ .printf(
+ "Enriched authors in %d seconds from %d pid to %d pid \n", totalTime, originalAuthorWithPiD,
+ enrichedAuthorWithPid);
+
+ System.out.println("=================");
+ }
+ }
+ }
+
+ @Test
+ public void checkSimilarityTest() {
+ final Author left = new Author();
+ left.setName("Anand");
+ left.setSurname("Rachna");
+ left.setFullname("Anand, Rachna");
+
+ System.out.println(AuthorMerger.normalizeFullName(left.getFullname()));
+
+ final Author right = new Author();
+ right.setName("Rachna");
+ right.setSurname("Anand");
+ right.setFullname("Rachna, Anand");
+// System.out.println(AuthorMerger.normalize(right.getFullname()));
+ boolean same = AuthorMerger.checkORCIDSimilarity(left, right);
+
+ assertTrue(same);
+
+ }
+
+}
diff --git a/dhp-common/src/test/resources/eu/dnetlib/dhp/oa/merge/authors_orcid_sample.json b/dhp-common/src/test/resources/eu/dnetlib/dhp/oa/merge/authors_orcid_sample.json
new file mode 100644
index 000000000..ec521b3b7
--- /dev/null
+++ b/dhp-common/src/test/resources/eu/dnetlib/dhp/oa/merge/authors_orcid_sample.json
@@ -0,0 +1,3 @@
+WrappedArray(arXiv1507.08202)
+50|arXiv_dedup_::34e03f2336b8b28286550425e65634ea
+[{"fullname":"Liron Barak","name":"Liron","surname":"Barak","rank":null,"pid":[{"value":"0000-0002-3436-2726","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Giuseppe Avolio","name":"Giuseppe","surname":"Avolio","rank":null,"pid":[{"value":"0000-0003-2664-3437","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Tobias Golling","name":"Tobias","surname":"Golling","rank":null,"pid":[{"value":"0000-0001-8535-6687","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Ivan Sykora","name":"Ivan","surname":"Sykora","rank":null,"pid":[{"value":"0000-0003-3447-5621","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Joao Carvalho","name":"Joao","surname":"Carvalho","rank":null,"pid":[{"value":"0000-0002-3015-7821","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Jonathan David Long","name":"Jonathan David","surname":"Long","rank":null,"pid":[{"value":"0000-0002-2115-9382","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Heather Russell","name":"Heather","surname":"Russell","rank":null,"pid":[{"value":"0000-0003-4181-0678","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Alison Lister","name":"Alison","surname":"Lister","rank":null,"pid":[{"value":"0000-0002-1552-3651","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Malte Backhaus","name":"Malte","surname":"Backhaus","rank":null,"pid":[{"value":"0000-0002-5888-2304","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Xin Wu","name":"Xin","surname":"Wu","rank":null,"pid":[{"value":"0000-0001-7655-389X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Luke Lambourne","name":"Luke","surname":"Lambourne","rank":null,"pid":[{"value":"0000-0002-7001-7575","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Kazunori Hanagaki","name":"Kazunori","surname":"Hanagaki","rank":null,"pid":[{"value":"0000-0003-0676-0441","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Krzysztof Sliwa","name":"Krzysztof","surname":"Sliwa","rank":null,"pid":[{"value":"0000-0002-1201-4771","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Jiri Chudoba","name":"Jiri","surname":"Chudoba","rank":null,"pid":[{"value":"0000-0002-6425-2579","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Jörn Große-Knetter","name":"Jörn","surname":"Große-Knetter","rank":null,"pid":[{"value":"0000-0003-3085-7067","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Katharine Leney","name":"Katharine","surname":"Leney","rank":null,"pid":[{"value":"0000-0002-1525-2695","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Michel Lefebvre","name":"Michel","surname":"Lefebvre","rank":null,"pid":[{"value":"0000-0002-5560-0586","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Ahmed Bassalat","name":"Ahmed","surname":"Bassalat","rank":null,"pid":[{"value":"0000-0002-0129-1423","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Borut Kersevan","name":"Borut","surname":"Kersevan","rank":null,"pid":[{"value":"0000-0002-4529-452X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Calum Macdonald","name":"Calum","surname":"Macdonald","rank":null,"pid":[{"value":"0000-0001-7857-9188","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Davide Costanzo","name":"Davide","surname":"Costanzo","rank":null,"pid":[{"value":"0000-0003-4920-6264","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Wladyslaw Dabrowski","name":"Wladyslaw","surname":"Dabrowski","rank":null,"pid":[{"value":"0000-0001-9061-9568","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Jean-François Grivaz","name":"Jean-François","surname":"Grivaz","rank":null,"pid":[{"value":"0000-0003-4793-7995","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Elisabetta Pianori","name":"Elisabetta","surname":"Pianori","rank":null,"pid":[{"value":"0000-0001-9233-5892","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Christoph Falk Anders","name":"Christoph Falk","surname":"Anders","rank":null,"pid":[{"value":"0000-0001-6632-6327","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Vasiliki Kouskoura","name":"Vasiliki","surname":"Kouskoura","rank":null,"pid":[{"value":"0000-0002-8987-3208","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Ruth Pöttgen","name":"Ruth","surname":"Pöttgen","rank":null,"pid":[{"value":"0000-0002-3304-0987","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Sergey Burdin","name":"Sergey","surname":"Burdin","rank":null,"pid":[{"value":"0000-0003-4831-4132","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Farid Ould-Saada","name":"Farid","surname":"Ould-Saada","rank":null,"pid":[{"value":"0000-0002-9404-835X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Peter Onyisi","name":"Peter","surname":"Onyisi","rank":null,"pid":[{"value":"0000-0003-4201-7997","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Javier Llorente Merino","name":"Javier","surname":"Llorente Merino","rank":null,"pid":[{"value":"0000-0003-0027-7969","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Michel Vetterli","name":"Michel","surname":"Vetterli","rank":null,"pid":[{"value":"0000-0002-7223-2965","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Nicolas Morange","name":"Nicolas","surname":"Morange","rank":null,"pid":[{"value":"0000-0003-0047-7215","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Gianluca Introzzi","name":"Gianluca","surname":"Introzzi","rank":null,"pid":[{"value":"0000-0002-1314-2580","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Roger Moore","name":"Roger","surname":"Moore","rank":null,"pid":[{"value":"0000-0003-4160-4700","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Pierre-Antoine Delsart","name":"Pierre-Antoine","surname":"Delsart","rank":null,"pid":[{"value":"0000-0002-9556-2924","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Victor Solovyev","name":"Victor","surname":"Solovyev","rank":null,"pid":[{"value":"0000-0002-9402-6329","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Jiangyong jia","name":"Jiangyong","surname":"jia","rank":null,"pid":[{"value":"0000-0002-5725-3397","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Kyle Cranmer","name":"Kyle","surname":"Cranmer","rank":null,"pid":[{"value":"0000-0002-5769-7094","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Frederik Ruehr","name":"Frederik","surname":"Ruehr","rank":null,"pid":[{"value":"0000-0003-4452-620X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Peter van Gemmeren","name":"Peter","surname":"van Gemmeren","rank":null,"pid":[{"value":"0000-0002-7227-4006","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Jacob Kempster","name":"Jacob","surname":"Kempster","rank":null,"pid":[{"value":"0000-0003-4168-3373","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Oleg Brandt","name":"Oleg","surname":"Brandt","rank":null,"pid":[{"value":"0000-0001-5219-1417","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Antonio Policicchio","name":"Antonio","surname":"Policicchio","rank":null,"pid":[{"value":"0000-0002-1290-220X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Fabrice Hubaut","name":"Fabrice","surname":"Hubaut","rank":null,"pid":[{"value":"0000-0002-0113-2465","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Christopher Gorham Lester","name":"Christopher Gorham","surname":"Lester","rank":null,"pid":[{"value":"0000-0001-5770-4883","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Royer Edson Ticse Torres","name":"Royer Edson","surname":"Ticse Torres","rank":null,"pid":[{"value":"0000-0001-8178-5257","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Maria Josefina Alconada Verzini","name":"Maria Josefina","surname":"Alconada Verzini","rank":null,"pid":[{"value":"0000-0003-2212-7830","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"PHILLIP URQUIJO","name":"PHILLIP","surname":"URQUIJO","rank":null,"pid":[{"value":"0000-0002-0887-7953","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Annick Lleres","name":"Annick","surname":"Lleres","rank":null,"pid":[{"value":"0000-0003-1769-8524","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Andrei Snesarev","name":"Andrei","surname":"Snesarev","rank":null,"pid":[{"value":"0000-0002-9067-8362","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Marcin Wolter","name":"Marcin","surname":"Wolter","rank":null,"pid":[{"value":"0000-0001-9184-2921","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Garabed Halladjian","name":"Garabed","surname":"Halladjian","rank":null,"pid":[{"value":"0000-0001-7162-0301","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Anthony Morley","name":"Anthony","surname":"Morley","rank":null,"pid":[{"value":"0000-0003-0373-1346","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Francesco Nuti","name":"Francesco","surname":"Nuti","rank":null,"pid":[{"value":"0000-0003-3491-7637","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Mar Capeans","name":"Mar","surname":"Capeans","rank":null,"pid":[{"value":"0000-0001-7727-9175","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Jose Enrique Garcia Navarro","name":"Jose Enrique","surname":"Garcia Navarro","rank":null,"pid":[{"value":"0000-0002-0279-0523","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Aidan Robson","name":"Aidan","surname":"Robson","rank":null,"pid":[{"value":"0000-0002-1659-8284","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Eduardo Ros","name":"Eduardo","surname":"Ros","rank":null,"pid":[{"value":"0000-0003-2812-9554","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Kevin Varvell","name":"Kevin","surname":"Varvell","rank":null,"pid":[{"value":"0000-0003-1017-1295","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Ina Carli","name":"Ina","surname":"Carli","rank":null,"pid":[{"value":"0000-0002-0411-1141","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Ivo van Vulpen","name":"Ivo","surname":"van Vulpen","rank":null,"pid":[{"value":"0000-0001-7074-5655","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Liaoshan Shi","name":"Liaoshan","surname":"Shi","rank":null,"pid":[{"value":"0000-0001-9532-5075","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Pavel Starovoitov","name":"Pavel","surname":"Starovoitov","rank":null,"pid":[{"value":"0000-0003-1990-0992","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Lorenzo Feligioni","name":"Lorenzo","surname":"Feligioni","rank":null,"pid":[{"value":"0000-0002-1403-0951","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Christoph Wasicki","name":"Christoph","surname":"Wasicki","rank":null,"pid":[{"value":"0000-0001-8041-741X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Nuno Castro","name":"Nuno","surname":"Castro","rank":null,"pid":[{"value":"0000-0001-8491-4376","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Mikhail Levchenko","name":"Mikhail","surname":"Levchenko","rank":null,"pid":[{"value":"0000-0002-5495-0656","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Marek Palka","name":"Marek","surname":"Palka","rank":null,"pid":[{"value":"0000-0002-7185-3540","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Philip Allport","name":"Philip","surname":"Allport","rank":null,"pid":[{"value":"0000-0001-7303-2570","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Tomas Jakoubek","name":"Tomas","surname":"Jakoubek","rank":null,"pid":[{"value":"0000-0001-7038-0369","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Elizabeth Brost","name":"Elizabeth","surname":"Brost","rank":null,"pid":[{"value":"0000-0002-6800-9808","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Maciej Trzebinski","name":"Maciej","surname":"Trzebinski","rank":null,"pid":[{"value":"0000-0002-5151-7101","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Nikola Makovec","name":"Nikola","surname":"Makovec","rank":null,"pid":[{"value":"0000-0001-5124-904X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Bernhard Meirose","name":"Bernhard","surname":"Meirose","rank":null,"pid":[{"value":"0000-0003-0032-7022","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Andrea Dell’Acqua","name":"Andrea","surname":"Dell’Acqua","rank":null,"pid":[{"value":"0000-0003-2453-7745","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Carlos Escobar Ibáñez","name":"Carlos","surname":"Escobar Ibáñez","rank":null,"pid":[{"value":"0000-0003-4442-4537","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Hideyuki Oide","name":"Hideyuki","surname":"Oide","rank":null,"pid":[{"value":"0000-0002-2173-3233","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Valentina Maria Martina Cairo","name":"Valentina Maria Martina","surname":"Cairo","rank":null,"pid":[{"value":"0000-0002-0758-7575","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Johannes Erdmann","name":"Johannes","surname":"Erdmann","rank":null,"pid":[{"value":"0000-0002-8073-2740","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Frederic Deliot","name":"Frederic","surname":"Deliot","rank":null,"pid":[{"value":"0000-0003-0777-6031","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Fabian Hügging","name":"Fabian","surname":"Hügging","rank":null,"pid":[{"value":"0000-0002-7472-3151","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Antoine Marzin","name":"Antoine","surname":"Marzin","rank":null,"pid":[{"value":"0000-0003-4364-4351","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Sebastien Prince","name":"Sebastien","surname":"Prince","rank":null,"pid":[{"value":"0000-0001-9947-3892","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Melissa Ridel","name":"Melissa","surname":"Ridel","rank":null,"pid":[{"value":"0000-0002-2601-7420","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Christian Weiser","name":"Christian","surname":"Weiser","rank":null,"pid":[{"value":"0000-0002-6456-6834","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Farida Fassi","name":"Farida","surname":"Fassi","rank":null,"pid":[{"value":"0000-0002-6423-7213","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Manuella Vincter","name":"Manuella","surname":"Vincter","rank":null,"pid":[{"value":"0000-0002-5338-8972","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Julien Caudron","name":"Julien","surname":"Caudron","rank":null,"pid":[{"value":"0000-0002-3530-6531","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Giada Mancini","name":"Giada","surname":"Mancini","rank":null,"pid":[{"value":"0000-0001-6158-2751","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Vasiliki A. Mitsou","name":"Vasiliki A.","surname":"Mitsou","rank":null,"pid":[{"value":"0000-0002-1533-8886","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"David Wardrope","name":"David","surname":"Wardrope","rank":null,"pid":[{"value":"0000-0002-8208-2964","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Loïc Valéry","name":"Loïc","surname":"Valéry","rank":null,"pid":[{"value":"0000-0002-5510-1111","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Krisztian Peters","name":"Krisztian","surname":"Peters","rank":null,"pid":[{"value":"0000-0002-7654-1677","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Andrea Knue","name":"Andrea","surname":"Knue","rank":null,"pid":[{"value":"0000-0002-1559-9285","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Stathes Paganis","name":"Stathes","surname":"Paganis","rank":null,"pid":[{"value":"0000-0002-1950-8993","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Steffen Stärz","name":"Steffen","surname":"Stärz","rank":null,"pid":[{"value":"0000-0002-2908-3909","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Emma Torro Pastor","name":"Emma","surname":"Torro Pastor","rank":null,"pid":[{"value":"0000-0002-5507-7924","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Andrey Kiryunin","name":"Andrey","surname":"Kiryunin","rank":null,"pid":[{"value":"0000-0001-7490-6890","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Daniela Marcella Rebuzzi","name":"Daniela Marcella","surname":"Rebuzzi","rank":null,"pid":[{"value":"0000-0003-4461-3880","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Frederick Luehring","name":"Frederick","surname":"Luehring","rank":null,"pid":[{"value":"0000-0001-8721-6901","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"alessandro cerri","name":"alessandro","surname":"cerri","rank":null,"pid":[{"value":"0000-0002-1904-6661","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Remi Lafaye","name":"Remi","surname":"Lafaye","rank":null,"pid":[{"value":"0000-0001-7848-6088","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Torsten Akesson","name":"Torsten","surname":"Akesson","rank":null,"pid":[{"value":"0000-0003-4141-5408","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Hongbo Zhu","name":"Hongbo","surname":"Zhu","rank":null,"pid":[{"value":"0000-0001-8066-7048","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Paul Laycock","name":"Paul","surname":"Laycock","rank":null,"pid":[{"value":"0000-0002-8572-5339","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Paolo Giromini","name":"Paolo","surname":"Giromini","rank":null,"pid":[{"value":"0000-0003-0276-287X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Leszek Adamczyk","name":"Leszek","surname":"Adamczyk","rank":null,"pid":[{"value":"0000-0002-5859-2075","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Stephen Lloyd","name":"Stephen","surname":"Lloyd","rank":null,"pid":[{"value":"0000-0002-5073-2264","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Aaron Angerami","name":"Aaron","surname":"Angerami","rank":null,"pid":[{"value":"0000-0001-7834-8750","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Susumu Oda","name":"Susumu","surname":"Oda","rank":null,"pid":[{"value":"0000-0001-5836-768X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Nathalie Besson","name":"Nathalie","surname":"Besson","rank":null,"pid":[{"value":"0000-0001-9248-6252","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"MARCELLO FANTI","name":"MARCELLO","surname":"FANTI","rank":null,"pid":[{"value":"0000-0002-8773-145X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Peter Kodyš","name":"Peter","surname":"Kodyš","rank":null,"pid":[{"value":"0000-0002-8644-2349","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Teng Jian Khoo","name":"Teng Jian","surname":"Khoo","rank":null,"pid":[{"value":"0000-0002-5954-3101","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Javier Montejo Berlingen","name":"Javier","surname":"Montejo Berlingen","rank":null,"pid":[{"value":"0000-0001-9213-904X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Sandro Palestini","name":"Sandro","surname":"Palestini","rank":null,"pid":[{"value":"0000-0002-4110-096X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Mark Oreglia","name":"Mark","surname":"Oreglia","rank":null,"pid":[{"value":"0000-0001-6203-2209","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Krzysztof Korcyl","name":"Krzysztof","surname":"Korcyl","rank":null,"pid":[{"value":"0000-0001-8085-4505","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Sebastian Schmitt","name":"Sebastian","surname":"Schmitt","rank":null,"pid":[{"value":"0000-0002-7935-0470","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Irinel Caprini","name":"Irinel","surname":"Caprini","rank":null,"pid":[{"value":"0000-0003-3343-3200","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Anthony Doyle","name":"Anthony","surname":"Doyle","rank":null,"pid":[{"value":"0000-0001-6322-6195","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Markus Elsing","name":"Markus","surname":"Elsing","rank":null,"pid":[{"value":"0000-0002-1213-0545","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Christian Schmitt","name":"Christian","surname":"Schmitt","rank":null,"pid":[{"value":"0000-0003-1471-690X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Konstantinos Nikolopoulos","name":"Konstantinos","surname":"Nikolopoulos","rank":null,"pid":[{"value":"0000-0002-3048-489X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Janet Dietrich","name":"Janet","surname":"Dietrich","rank":null,"pid":[{"value":"0000-0001-7061-1585","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Yuri Kulchitsky","name":"Yuri","surname":"Kulchitsky","rank":null,"pid":[{"value":"0000-0002-3036-5575","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Sinead Farrington","name":"Sinead","surname":"Farrington","rank":null,"pid":[{"value":"0000-0001-5350-9271","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Stefano Terzo","name":"Stefano","surname":"Terzo","rank":null,"pid":[{"value":"0000-0003-3388-3906","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"stefania xella","name":"stefania","surname":"xella","rank":null,"pid":[{"value":"0000-0002-0988-1655","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Jonathan Butterworth","name":"Jonathan","surname":"Butterworth","rank":null,"pid":[{"value":"0000-0002-5905-5394","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Gideon Bella","name":"Gideon","surname":"Bella","rank":null,"pid":[{"value":"0000-0002-4009-0990","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Marcello Bindi","name":"Marcello","surname":"Bindi","rank":null,"pid":[{"value":"0000-0001-6172-545X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Heather Gray","name":"Heather","surname":"Gray","rank":null,"pid":[{"value":"0000-0002-5293-4716","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Marcel Vos","name":"Marcel","surname":"Vos","rank":null,"pid":[{"value":"0000-0001-8474-5357","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Ljiljana Morvaj","name":"Ljiljana","surname":"Morvaj","rank":null,"pid":[{"value":"0000-0003-2061-2904","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Didier Ferrere","name":"Didier","surname":"Ferrere","rank":null,"pid":[{"value":"0000-0002-5687-9240","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Mauro Villa","name":"Mauro","surname":"Villa","rank":null,"pid":[{"value":"0000-0002-9181-8048","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Deepak Kar","name":"Deepak","surname":"Kar","rank":null,"pid":[{"value":"0000-0002-4238-9822","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Frank Berghaus","name":"Frank","surname":"Berghaus","rank":null,"pid":[{"value":"0000-0003-1887-3910","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Bruce Yabsley","name":"Bruce","surname":"Yabsley","rank":null,"pid":[{"value":"0000-0002-2680-0474","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Frank Winklmeier","name":"Frank","surname":"Winklmeier","rank":null,"pid":[{"value":"0000-0001-8290-3200","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Zoya Karpova","name":"Zoya","surname":"Karpova","rank":null,"pid":[{"value":"0000-0003-0254-4629","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Jason Nielsen","name":"Jason","surname":"Nielsen","rank":null,"pid":[{"value":"0000-0002-9175-4419","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Claire Gwenlan","name":"Claire","surname":"Gwenlan","rank":null,"pid":[{"value":"0000-0002-3518-0617","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Stephanie Majewski","name":"Stephanie","surname":"Majewski","rank":null,"pid":[{"value":"0000-0002-6871-3395","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"James Mueller","name":"James","surname":"Mueller","rank":null,"pid":[{"value":"0000-0001-5099-4718","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Mario Giordani","name":"Mario","surname":"Giordani","rank":null,"pid":[{"value":"0000-0002-0792-6039","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Laura Fabbri","name":"Laura","surname":"Fabbri","rank":null,"pid":[{"value":"0000-0002-4002-8353","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Michael Begel","name":"Michael","surname":"Begel","rank":null,"pid":[{"value":"0000-0002-1634-4399","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Laurent Schoeffel","name":"Laurent","surname":"Schoeffel","rank":null,"pid":[{"value":"0000-0002-8081-2353","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Bobby Acharya","name":"Bobby","surname":"Acharya","rank":null,"pid":[{"value":"0000-0002-8588-9157","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Jan Kretzschmar","name":"Jan","surname":"Kretzschmar","rank":null,"pid":[{"value":"0000-0002-8515-1355","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Thi Ngoc Loan Truong","name":"Thi Ngoc Loan","surname":"Truong","rank":null,"pid":[{"value":"0000-0001-8249-7150","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Yury Smirnov","name":"Yury","surname":"Smirnov","rank":null,"pid":[{"value":"0000-0002-2891-0781","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Andreas Warburton","name":"Andreas","surname":"Warburton","rank":null,"pid":[{"value":"0000-0002-2298-7315","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Osamu Jinnouchi","name":"Osamu","surname":"Jinnouchi","rank":null,"pid":[{"value":"0000-0001-5073-0974","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Nicola Orlando","name":"Nicola","surname":"Orlando","rank":null,"pid":[{"value":"0000-0003-0616-245X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Magda Anna Chelstowska","name":"Magda Anna","surname":"Chelstowska","rank":null,"pid":[{"value":"0000-0003-1030-2099","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Armin Nairz","name":"Armin","surname":"Nairz","rank":null,"pid":[{"value":"0000-0003-3561-0880","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Chris Malena Delitzsch","name":"Chris Malena","surname":"Delitzsch","rank":null,"pid":[{"value":"0000-0001-7021-3333","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Kendall Reeves","name":"Kendall","surname":"Reeves","rank":null,"pid":[{"value":"0000-0003-3504-4882","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Minghui Liu","name":"Minghui","surname":"Liu","rank":null,"pid":[{"value":"0000-0003-0056-7296","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Clara Troncon","name":"Clara","surname":"Troncon","rank":null,"pid":[{"value":"0000-0002-7997-8524","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Chris Hays","name":"Chris","surname":"Hays","rank":null,"pid":[{"value":"0000-0003-2371-9723","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Driss Benchekroun","name":"Driss","surname":"Benchekroun","rank":null,"pid":[{"value":"0000-0001-5196-8327","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Tamar Djobava","name":"Tamar","surname":"Djobava","rank":null,"pid":[{"value":"0000-0002-9414-8350","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Joany Manjarrés Ramos","name":"Joany","surname":"Manjarrés Ramos","rank":null,"pid":[{"value":"0000-0003-3896-5222","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Craig Wiglesworth","name":"Craig","surname":"Wiglesworth","rank":null,"pid":[{"value":"0000-0001-6219-8946","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Lawrence Lee","name":"Lawrence","surname":"Lee","rank":null,"pid":[{"value":"0000-0002-5590-335X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Elisabetta Barberio","name":"Elisabetta","surname":"Barberio","rank":null,"pid":[{"value":"0000-0002-3111-0910","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Robert McPherson","name":"Robert","surname":"McPherson","rank":null,"pid":[{"value":"0000-0001-9211-7019","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Paul Jackson","name":"Paul","surname":"Jackson","rank":null,"pid":[{"value":"0000-0002-0847-402X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Peter Henrik Hansen","name":"Peter Henrik","surname":"Hansen","rank":null,"pid":[{"value":"0000-0002-6764-4789","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Cristobal Padilla","name":"Cristobal","surname":"Padilla","rank":null,"pid":[{"value":"0000-0001-7951-0166","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Nora Pettersson","name":"Nora","surname":"Pettersson","rank":null,"pid":[{"value":"0000-0001-7451-3544","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Paul Glaysher","name":"Paul","surname":"Glaysher","rank":null,"pid":[{"value":"0000-0002-5437-971X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Patrick Czodrowski","name":"Patrick","surname":"Czodrowski","rank":null,"pid":[{"value":"0000-0003-0723-1437","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"María Moreno Llácer","name":"María","surname":"Moreno Llácer","rank":null,"pid":[{"value":"0000-0003-1113-3645","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Soumya Mohapatra","name":"Soumya","surname":"Mohapatra","rank":null,"pid":[{"value":"0000-0003-3006-6337","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Andrea Gaudiello","name":"Andrea","surname":"Gaudiello","rank":null,"pid":[{"value":"0000-0001-7721-8217","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Maximiliano Sioli","name":"Maximiliano","surname":"Sioli","rank":null,"pid":[{"value":"0000-0002-0912-9121","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Christian Schroeder","name":"Christian","surname":"Schroeder","rank":null,"pid":[{"value":"0000-0001-6449-0668","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Guillaume Unal","name":"Guillaume","surname":"Unal","rank":null,"pid":[{"value":"0000-0001-8130-7423","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Christian Gutschow","name":"Christian","surname":"Gutschow","rank":null,"pid":[{"value":"0000-0003-0857-794X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Spyridon Argyropoulos","name":"Spyridon","surname":"Argyropoulos","rank":null,"pid":[{"value":"0000-0001-7748-1429","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Vadim Bednyakov","name":"Vadim","surname":"Bednyakov","rank":null,"pid":[{"value":"0000-0003-4864-8909","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Caterina Doglioni","name":"Caterina","surname":"Doglioni","rank":null,"pid":[{"value":"0000-0002-1509-0390","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Andrew Haas","name":"Andrew","surname":"Haas","rank":null,"pid":[{"value":"0000-0002-4832-0455","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Masahiro Morii","name":"Masahiro","surname":"Morii","rank":null,"pid":[{"value":"0000-0001-9324-057X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Andrea Coccaro","name":"Andrea","surname":"Coccaro","rank":null,"pid":[{"value":"0000-0003-2368-4559","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Edward Moyse","name":"Edward","surname":"Moyse","rank":null,"pid":[{"value":"0000-0003-4449-6178","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Takuya Nobe","name":"Takuya","surname":"Nobe","rank":null,"pid":[{"value":"0000-0002-5809-325X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Jahred Adelman","name":"Jahred","surname":"Adelman","rank":null,"pid":[{"value":"0000-0002-1041-3496","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Antonio Ereditato","name":"Antonio","surname":"Ereditato","rank":null,"pid":[{"value":"0000-0002-5423-8079","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Stefan Schmitt","name":"Stefan","surname":"Schmitt","rank":null,"pid":[{"value":"0000-0001-8387-1853","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"David DeMarco","name":"David","surname":"DeMarco","rank":null,"pid":[{"value":"0000-0002-8921-8828","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Alessandro La Rosa","name":"Alessandro","surname":"La Rosa","rank":null,"pid":[{"value":"0000-0001-6291-2142","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Liza Mijovic","name":"Liza","surname":"Mijovic","rank":null,"pid":[{"value":"0000-0003-0162-2891","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Stephane Willocq","name":"Stephane","surname":"Willocq","rank":null,"pid":[{"value":"0000-0002-4120-1453","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"George Iakovidis","name":"George","surname":"Iakovidis","rank":null,"pid":[{"value":"0000-0002-0330-5921","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Madar Romain","name":"Madar","surname":"Romain","rank":null,"pid":[{"value":"0000-0002-6875-6408","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"giuseppe iacobucci","name":"giuseppe","surname":"iacobucci","rank":null,"pid":[{"value":"0000-0001-9965-5442","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Allen Mincer","name":"Allen","surname":"Mincer","rank":null,"pid":[{"value":"0000-0002-6307-1418","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"TROCME Benjamin","name":"TROCME","surname":"Benjamin","rank":null,"pid":[{"value":"0000-0001-9500-2487","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Liang Li","name":"Liang","surname":"Li","rank":null,"pid":[{"value":"0000-0001-6411-6107","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"William Murray","name":"William","surname":"Murray","rank":null,"pid":[{"value":"0000-0003-1710-6306","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Chaowaroj Wanotayaroj","name":"Chaowaroj","surname":"Wanotayaroj","rank":null,"pid":[{"value":"0000-0002-8178-5705","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Luc Goossens","name":"Luc","surname":"Goossens","rank":null,"pid":[{"value":"0000-0002-2536-4498","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Kerstin Jon-And","name":"Kerstin","surname":"Jon-And","rank":null,"pid":[{"value":"0000-0001-8201-7700","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Arwa Bannoura","name":"Arwa","surname":"Bannoura","rank":null,"pid":[{"value":"0000-0002-7166-8118","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Filipe Veloso","name":"Filipe","surname":"Veloso","rank":null,"pid":[{"value":"0000-0002-5956-4244","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Maximilian Swiatlowski","name":"Maximilian","surname":"Swiatlowski","rank":null,"pid":[{"value":"0000-0001-7287-0468","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Marija Vranjes Milosavljevic","name":"Marija","surname":"Vranjes Milosavljevic","rank":null,"pid":[{"value":"0000-0003-4477-9733","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Riccardo Maria Bianchi","name":"Riccardo Maria","surname":"Bianchi","rank":null,"pid":[{"value":"0000-0001-7345-7798","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Elias Coniavitis","name":"Elias","surname":"Coniavitis","rank":null,"pid":[{"value":"0000-0002-2148-8012","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Ondrej Penc","name":"Ondrej","surname":"Penc","rank":null,"pid":[{"value":"0000-0002-5433-3981","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Julie Kirk","name":"Julie","surname":"Kirk","rank":null,"pid":[{"value":"0000-0001-8096-7577","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Hongtao Yang","name":"Hongtao","surname":"Yang","rank":null,"pid":[{"value":"0000-0003-3554-7113","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Ewelina Maria Lobodzinska","name":"Ewelina Maria","surname":"Lobodzinska","rank":null,"pid":[{"value":"0000-0001-9012-3431","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Christos Leonidopoulos","name":"Christos","surname":"Leonidopoulos","rank":null,"pid":[{"value":"0000-0002-7241-2114","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Silvia Biondi","name":"Silvia","surname":"Biondi","rank":null,"pid":[{"value":"0000-0002-1492-6715","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Stephane JEZEQUEL","name":"Stephane","surname":"JEZEQUEL","rank":null,"pid":[{"value":"0000-0001-7369-6975","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Zhiqing Zhang","name":"Zhiqing","surname":"Zhang","rank":null,"pid":[{"value":"0000-0002-7853-9079","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Kathleen Whalen","name":"Kathleen","surname":"Whalen","rank":null,"pid":[{"value":"0000-0002-9383-8763","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Sophie HENROT","name":"Sophie","surname":"HENROT","rank":null,"pid":[{"value":"0000-0003-1218-2991","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Louise Heelan","name":"Louise","surname":"Heelan","rank":null,"pid":[{"value":"0000-0002-4879-0131","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Dominik Derendarz","name":"Dominik","surname":"Derendarz","rank":null,"pid":[{"value":"0000-0001-5660-3095","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Ning Zhou","name":"Ning","surname":"Zhou","rank":null,"pid":[{"value":"0000-0002-1775-2511","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Mihai Caprini","name":"Mihai","surname":"Caprini","rank":null,"pid":[{"value":"0000-0002-6806-6730","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Lee Sawyer","name":"Lee","surname":"Sawyer","rank":null,"pid":[{"value":"0000-0001-8295-0605","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Lydia Roos","name":"Lydia","surname":"Roos","rank":null,"pid":[{"value":"0000-0001-7151-9983","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Stanislav Nemecek","name":"Stanislav","surname":"Nemecek","rank":null,"pid":[{"value":"0000-0001-8978-7150","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Matthias Danninger","name":"Matthias","surname":"Danninger","rank":null,"pid":[{"value":"0000-0002-7807-7484","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Lailin Xu","name":"Lailin","surname":"Xu","rank":null,"pid":[{"value":"0000-0001-8997-3199","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Angel Campoverde","name":"Angel","surname":"Campoverde","rank":null,"pid":[{"value":"0000-0003-1968-1216","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Carl Gwilliam","name":"Carl","surname":"Gwilliam","rank":null,"pid":[{"value":"0000-0002-9401-5304","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Fabrizio Salvatore","name":"Fabrizio","surname":"Salvatore","rank":null,"pid":[{"value":"0000-0002-3709-1554","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Werner Wiedenmann","name":"Werner","surname":"Wiedenmann","rank":null,"pid":[{"value":"0000-0003-3605-3633","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Adriaan König","name":"Adriaan","surname":"König","rank":null,"pid":[{"value":"0000-0001-6702-6473","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Romain Kukla","name":"Romain","surname":"Kukla","rank":null,"pid":[{"value":"0000-0002-1140-2465","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Sarah Heim","name":"Sarah","surname":"Heim","rank":null,"pid":[{"value":"0000-0002-2639-6571","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Stamatios Gkaitatzis","name":"Stamatios","surname":"Gkaitatzis","rank":null,"pid":[{"value":"0000-0001-9420-7499","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Alison Elliot","name":"Alison","surname":"Elliot","rank":null,"pid":[{"value":"0000-0003-0921-0314","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Marc Escalier","name":"Marc","surname":"Escalier","rank":null,"pid":[{"value":"0000-0003-4270-2775","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Philipp Stolte","name":"Philipp","surname":"Stolte","rank":null,"pid":[{"value":"0000-0002-8828-3564","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Peter Loch","name":"Peter","surname":"Loch","rank":null,"pid":[{"value":"0000-0002-2005-671X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Tamara Vazquez Schroeder","name":"Tamara","surname":"Vazquez Schroeder","rank":null,"pid":[{"value":"0000-0002-9780-099X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"lily asquith","name":"lily","surname":"asquith","rank":null,"pid":[{"value":"0000-0001-8035-7162","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Javier Sanchez","name":"Javier","surname":"Sanchez","rank":null,"pid":[{"value":"0000-0001-9913-310X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Tomas Davidek","name":"Tomas","surname":"Davidek","rank":null,"pid":[{"value":"0000-0002-3770-8307","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Lidia Dell'Asta","name":"Lidia","surname":"Dell'Asta","rank":null,"pid":[{"value":"0000-0002-9601-4225","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Francisco Alonso","name":"Francisco","surname":"Alonso","rank":null,"pid":[{"value":"0000-0001-9431-8156","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"J. Katharina Behr","name":"J. Katharina","surname":"Behr","rank":null,"pid":[{"value":"0000-0002-5501-4640","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"MARIO MARTINEZ","name":"MARIO","surname":"MARTINEZ","rank":null,"pid":[{"value":"0000-0002-3135-945X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Konstantinos Bachas","name":"Konstantinos","surname":"Bachas","rank":null,"pid":[{"value":"0000-0002-9047-6517","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Arnaud Lucotte","name":"Arnaud","surname":"Lucotte","rank":null,"pid":[{"value":"0000-0002-5992-0640","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"scott snyder","name":"scott","surname":"snyder","rank":null,"pid":[{"value":"0000-0001-8610-8423","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Edson Carquin","name":"Edson","surname":"Carquin","rank":null,"pid":[{"value":"0000-0002-7863-1166","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Kristin Lohwasser","name":"Kristin","surname":"Lohwasser","rank":null,"pid":[{"value":"0000-0003-1833-9160","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Jens Weingarten","name":"Jens","surname":"Weingarten","rank":null,"pid":[{"value":"0000-0003-2165-871X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Victor Maleev","name":"Victor","surname":"Maleev","rank":null,"pid":[{"value":"0000-0003-1028-8602","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Francesca Ungaro","name":"Francesca","surname":"Ungaro","rank":null,"pid":[{"value":"0000-0003-2005-595X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Koji Terashi","name":"Koji","surname":"Terashi","rank":null,"pid":[{"value":"0000-0001-6520-8070","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Kohei Yorita","name":"Kohei","surname":"Yorita","rank":null,"pid":[{"value":"0000-0003-1988-8401","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Roland Jansky","name":"Roland","surname":"Jansky","rank":null,"pid":[{"value":"0000-0003-0456-4658","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Sandro De Cecco","name":"Sandro","surname":"De Cecco","rank":null,"pid":[{"value":"0000-0003-4907-8610","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Wade Fisher","name":"Wade","surname":"Fisher","rank":null,"pid":[{"value":"0000-0003-3043-3045","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Jaroslav Guenther","name":"Jaroslav","surname":"Guenther","rank":null,"pid":[{"value":"0000-0003-3189-3959","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Tatsuya Masubuchi","name":"Tatsuya","surname":"Masubuchi","rank":null,"pid":[{"value":"0000-0001-9984-8009","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Janusz Chwastowski","name":"Janusz","surname":"Chwastowski","rank":null,"pid":[{"value":"0000-0002-6190-8376","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Ian Watson","name":"Ian","surname":"Watson","rank":null,"pid":[{"value":"0000-0003-2141-3413","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Patrick Rieck","name":"Patrick","surname":"Rieck","rank":null,"pid":[{"value":"0000-0003-0290-0566","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Mario Lassnig","name":"Mario","surname":"Lassnig","rank":null,"pid":[{"value":"0000-0002-9541-0592","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Jana Schaarschmidt","name":"Jana","surname":"Schaarschmidt","rank":null,"pid":[{"value":"0000-0002-0433-6439","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Joseph Reichert","name":"Joseph","surname":"Reichert","rank":null,"pid":[{"value":"0000-0003-2110-8021","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Bjarne Stugu","name":"Bjarne","surname":"Stugu","rank":null,"pid":[{"value":"0000-0002-1728-9272","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Paolo Gauzzi","name":"Paolo","surname":"Gauzzi","rank":null,"pid":[{"value":"0000-0003-4841-5822","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Sergei Smirnov","name":"Sergei","surname":"Smirnov","rank":null,"pid":[{"value":"0000-0002-6778-073X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Xiangyang Ju","name":"Xiangyang","surname":"Ju","rank":null,"pid":[{"value":"0000-0002-9745-1638","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Fernando Barreiro","name":"Fernando","surname":"Barreiro","rank":null,"pid":[{"value":"0000-0002-3021-0258","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Markus Cristinziani","name":"Markus","surname":"Cristinziani","rank":null,"pid":[{"value":"0000-0003-3893-9171","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Antonio Amorim","name":"Antonio","surname":"Amorim","rank":null,"pid":[{"value":"0000-0003-0638-2321","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Sune Jakobsen","name":"Sune","surname":"Jakobsen","rank":null,"pid":[{"value":"0000-0002-6564-040X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Alejandro Alonso","name":"Alejandro","surname":"Alonso","rank":null,"pid":[{"value":"0000-0003-1259-0573","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Makoto Shimojima","name":"Makoto","surname":"Shimojima","rank":null,"pid":[{"value":"0000-0002-8738-1664","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Francesco Guescini","name":"Francesco","surname":"Guescini","rank":null,"pid":[{"value":"0000-0001-5351-2673","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Christina Potter","name":"Christina","surname":"Potter","rank":null,"pid":[{"value":"0000-0002-9815-5208","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Evelina Bouhova-Thacker","name":"Evelina","surname":"Bouhova-Thacker","rank":null,"pid":[{"value":"0000-0002-5103-1558","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Eduard Simioni","name":"Eduard","surname":"Simioni","rank":null,"pid":[{"value":"0000-0002-8929-6236","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Paolo Camarri","name":"Paolo","surname":"Camarri","rank":null,"pid":[{"value":"0000-0002-5732-5645","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"William Leight","name":"William","surname":"Leight","rank":null,"pid":[{"value":"0000-0002-2968-7841","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Luis Roberto Flores Castillo","name":"Luis Roberto","surname":"Flores Castillo","rank":null,"pid":[{"value":"0000-0003-1551-5974","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Alessandro null","name":"Alessandro","surname":null,"rank":null,"pid":[{"value":"0000-0002-8224-6105","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Roman Lysak","name":"Roman","surname":"Lysak","rank":null,"pid":[{"value":"0000-0003-2990-1673","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Matteo Franchini","name":"Matteo","surname":"Franchini","rank":null,"pid":[{"value":"0000-0002-4554-252X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Martin Nagel","name":"Martin","surname":"Nagel","rank":null,"pid":[{"value":"0000-0002-2588-6691","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Harald Fox","name":"Harald","surname":"Fox","rank":null,"pid":[{"value":"0000-0003-3089-6090","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Klaus Moenig","name":"Klaus","surname":"Moenig","rank":null,"pid":[{"value":"0000-0002-3169-7117","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Sergey Karpov","name":"Sergey","surname":"Karpov","rank":null,"pid":[{"value":"0000-0002-2230-5353","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Remi Zaidan","name":"Remi","surname":"Zaidan","rank":null,"pid":[{"value":"0000-0002-3710-4554","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Kilian Rosbach","name":"Kilian","surname":"Rosbach","rank":null,"pid":[{"value":"0000-0002-4241-2949","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Pawel Klimek","name":"Pawel","surname":"Klimek","rank":null,"pid":[{"value":"0000-0003-1661-6873","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Nikolaos Konstantinidis","name":"Nikolaos","surname":"Konstantinidis","rank":null,"pid":[{"value":"0000-0002-4140-6360","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Alberto Mengarelli","name":"Alberto","surname":"Mengarelli","rank":null,"pid":[{"value":"0000-0002-1884-854X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Robert Kowalewski","name":"Robert","surname":"Kowalewski","rank":null,"pid":[{"value":"0000-0002-7314-0990","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Miguel Arratia","name":"Miguel","surname":"Arratia","rank":null,"pid":[{"value":"0000-0001-6877-3315","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Paola Giannetti","name":"Paola","surname":"Giannetti","rank":null,"pid":[{"value":"0000-0002-3721-9490","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Joern Lange","name":"Joern","surname":"Lange","rank":null,"pid":[{"value":"0000-0003-1307-1441","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Pavel Řezníček","name":"Pavel","surname":"Řezníček","rank":null,"pid":[{"value":"0000-0003-4017-9829","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Vojtech Pleskot","name":"Vojtech","surname":"Pleskot","rank":null,"pid":[{"value":"0000-0001-5435-497X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Federico Sforza","name":"Federico","surname":"Sforza","rank":null,"pid":[{"value":"0000-0002-4065-7352","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Danijela Bogavac","name":"Danijela","surname":"Bogavac","rank":null,"pid":[{"value":"0000-0003-2138-9062","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Nenad Vranjes","name":"Nenad","surname":"Vranjes","rank":null,"pid":[{"value":"0000-0001-5415-5225","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Peter Watkins","name":"Peter","surname":"Watkins","rank":null,"pid":[{"value":"0000-0002-1290-6833","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Yohei Yamaguchi","name":"Yohei","surname":"Yamaguchi","rank":null,"pid":[{"value":"0000-0002-3725-4800","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Matthias Saimpert","name":"Matthias","surname":"Saimpert","rank":null,"pid":[{"value":"0000-0002-3765-1320","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Alexander Grohsjean","name":"Alexander","surname":"Grohsjean","rank":null,"pid":[{"value":"0000-0003-0748-8494","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Tibor Zenis","name":"Tibor","surname":"Zenis","rank":null,"pid":[{"value":"0000-0001-8265-6916","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Stefano Camarda","name":"Stefano","surname":"Camarda","rank":null,"pid":[{"value":"0000-0003-0479-7689","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Carlos Lacasta","name":"Carlos","surname":"Lacasta","rank":null,"pid":[{"value":"0000-0002-2623-6252","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Oliver Ricken","name":"Oliver","surname":"Ricken","rank":null,"pid":[{"value":"0000-0001-5107-7276","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Claude Leroy","name":"Claude","surname":"Leroy","rank":null,"pid":[{"value":"0000-0003-3105-7045","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Murrough Landon","name":"Murrough","surname":"Landon","rank":null,"pid":[{"value":"0000-0001-6828-9769","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Martin White","name":"Martin","surname":"White","rank":null,"pid":[{"value":"0000-0001-5474-4580","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Dimitrii Krasnopevtsev","name":"Dimitrii","surname":"Krasnopevtsev","rank":null,"pid":[{"value":"0000-0002-6356-372X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Susana Cabrera Urbán","name":"Susana","surname":"Cabrera Urbán","rank":null,"pid":[{"value":"0000-0001-7640-7913","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Hans-Christian Schultz-Coulon","name":"Hans-Christian","surname":"Schultz-Coulon","rank":null,"pid":[{"value":"0000-0002-0860-7240","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Stephen Jiggins","name":"Stephen","surname":"Jiggins","rank":null,"pid":[{"value":"0000-0003-2906-1977","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Andre Sopczak","name":"Andre","surname":"Sopczak","rank":null,"pid":[{"value":"0000-0001-6981-0544","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Cristinel Diaconu","name":"Cristinel","surname":"Diaconu","rank":null,"pid":[{"value":"0000-0002-6193-5091","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Hector de la Torre Perez","name":"Hector","surname":"de la Torre Perez","rank":null,"pid":[{"value":"0000-0002-4516-5269","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Costa Mezquita","name":"Costa","surname":"Mezquita","rank":null,"pid":[{"value":"0000-0002-2064-2954","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Sahal Yacoob","name":"Sahal","surname":"Yacoob","rank":null,"pid":[{"value":"0000-0001-6977-3456","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Jian Liu","name":"Jian","surname":"Liu","rank":null,"pid":[{"value":"0000-0002-8397-7620","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Oxana Smirnova","name":"Oxana","surname":"Smirnova","rank":null,"pid":[{"value":"0000-0003-2517-531X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Thomas Koffas","name":"Thomas","surname":"Koffas","rank":null,"pid":[{"value":"0000-0001-9612-4988","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Stephen Burke","name":"Stephen","surname":"Burke","rank":null,"pid":[{"value":"0000-0002-1962-8493","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Elizaveta Shabalina","name":"Elizaveta","surname":"Shabalina","rank":null,"pid":[{"value":"0000-0003-4849-556X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Nicolas Ellis","name":"Nicolas","surname":"Ellis","rank":null,"pid":[{"value":"0000-0002-1920-4930","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Robert Astalos","name":"Robert","surname":"Astalos","rank":null,"pid":[{"value":"0000-0001-5095-605X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Valerio Dao","name":"Valerio","surname":"Dao","rank":null,"pid":[{"value":"0000-0003-1645-8393","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Javier Alberto Murillo Quijada","name":"Javier Alberto","surname":"Murillo Quijada","rank":null,"pid":[{"value":"0000-0003-4933-2092","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Alan Litke","name":"Alan","surname":"Litke","rank":null,"pid":[{"value":"0000-0003-3973-3642","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Hans Peter Beck","name":"Hans Peter","surname":"Beck","rank":null,"pid":[{"value":"0000-0001-7212-1096","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Flavia De Almeida Dias","name":"Flavia","surname":"De Almeida Dias","rank":null,"pid":[{"value":"0000-0001-6882-5402","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Mykhailo Lisovyi","name":"Mykhailo","surname":"Lisovyi","rank":null,"pid":[{"value":"0000-0002-3014-5855","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Frank Ellinghaus","name":"Frank","surname":"Ellinghaus","rank":null,"pid":[{"value":"0000-0003-3596-5331","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Alexey Ezhilov","name":"Alexey","surname":"Ezhilov","rank":null,"pid":[{"value":"0000-0002-7520-293X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Anna Sfyrla","name":"Anna","surname":"Sfyrla","rank":null,"pid":[{"value":"0000-0002-3003-9905","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Marc-André Pleier","name":"Marc-André","surname":"Pleier","rank":null,"pid":[{"value":"0000-0002-9461-3494","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Aliaksei Hrynevich","name":"Aliaksei","surname":"Hrynevich","rank":null,"pid":[{"value":"0000-0002-5411-114X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Lucia Masetti","name":"Lucia","surname":"Masetti","rank":null,"pid":[{"value":"0000-0002-0038-5372","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Petr Balek","name":"Petr","surname":"Balek","rank":null,"pid":[{"value":"0000-0002-0942-1966","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Marco Sessa","name":"Marco","surname":"Sessa","rank":null,"pid":[{"value":"0000-0002-1402-7525","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Ilija Vukotic","name":"Ilija","surname":"Vukotic","rank":null,"pid":[{"value":"0000-0003-0472-3516","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Tova Holmes","name":"Tova","surname":"Holmes","rank":null,"pid":[{"value":"0000-0002-3959-5174","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Hermann Kolanoski","name":"Hermann","surname":"Kolanoski","rank":null,"pid":[{"value":"0000-0003-0435-2524","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Sigve Haug","name":"Sigve","surname":"Haug","rank":null,"pid":[{"value":"0000-0003-0442-3361","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Bruno Galhardo","name":"Bruno","surname":"Galhardo","rank":null,"pid":[{"value":"0000-0003-0641-301X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Nello Bruscino","name":"Nello","surname":"Bruscino","rank":null,"pid":[{"value":"0000-0002-6168-689X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Jonas Strandberg","name":"Jonas","surname":"Strandberg","rank":null,"pid":[{"value":"0000-0002-8913-0981","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Riccardo Vari","name":"Riccardo","surname":"Vari","rank":null,"pid":[{"value":"0000-0002-2814-1337","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Emmanuel Sauvan","name":"Emmanuel","surname":"Sauvan","rank":null,"pid":[{"value":"0000-0003-1921-2647","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Hartmut Sadrozinski","name":"Hartmut","surname":"Sadrozinski","rank":null,"pid":[{"value":"0000-0003-0019-5410","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Juerg Beringer","name":"Juerg","surname":"Beringer","rank":null,"pid":[{"value":"0000-0002-9975-1781","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"laurent chevalier","name":"laurent","surname":"chevalier","rank":null,"pid":[{"value":"0000-0003-3762-7264","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Dominik Duda","name":"Dominik","surname":"Duda","rank":null,"pid":[{"value":"0000-0002-5916-3467","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Takanori Kono","name":"Takanori","surname":"Kono","rank":null,"pid":[{"value":"0000-0003-1553-2950","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Igor Gorelov","name":"Igor","surname":"Gorelov","rank":null,"pid":[{"value":"0000-0001-5570-0133","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Noam Tal Hod","name":"Noam","surname":"Tal Hod","rank":null,"pid":[{"value":"0000-0001-5241-0544","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Umberto De Sanctis","name":"Umberto","surname":"De Sanctis","rank":null,"pid":[{"value":"0000-0003-4704-525X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Andrii Tykhonov","name":"Andrii","surname":"Tykhonov","rank":null,"pid":[{"value":"0000-0003-2908-7915","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Francois Corriveau","name":"Francois","surname":"Corriveau","rank":null,"pid":[{"value":"0000-0002-4970-7600","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Michaela Queitsch-Maitland","name":"Michaela","surname":"Queitsch-Maitland","rank":null,"pid":[{"value":"0000-0003-4643-515X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Iacopo Vivarelli","name":"Iacopo","surname":"Vivarelli","rank":null,"pid":[{"value":"0000-0003-0097-123X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"sotirios vlachos","name":"sotirios","surname":"vlachos","rank":null,"pid":[{"value":"0000-0002-1879-3745","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Archil Durglishvili","name":"Archil","surname":"Durglishvili","rank":null,"pid":[{"value":"0000-0003-4157-592X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Vladimir Cindro","name":"Vladimir","surname":"Cindro","rank":null,"pid":[{"value":"0000-0002-2037-7185","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Tim Adye","name":"Tim","surname":"Adye","rank":null,"pid":[{"value":"0000-0003-0627-5059","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Ruggero Turra","name":"Ruggero","surname":"Turra","rank":null,"pid":[{"value":"0000-0001-8740-796X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Susana Amor Santos","name":"Susana","surname":"Amor Santos","rank":null,"pid":[{"value":"0000-0001-7566-6067","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Thorsten Wengler","name":"Thorsten","surname":"Wengler","rank":null,"pid":[{"value":"0000-0002-4375-5265","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Sergio Grancagnolo","name":"Sergio","surname":"Grancagnolo","rank":null,"pid":[{"value":"0000-0001-8490-8304","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Koji Sato","name":"Koji","surname":"Sato","rank":null,"pid":[{"value":"0000-0001-8988-4065","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Marjorie Shapiro","name":"Marjorie","surname":"Shapiro","rank":null,"pid":[{"value":"0000-0001-8540-9654","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Paul Thompson","name":"Paul","surname":"Thompson","rank":null,"pid":[{"value":"0000-0002-6239-7715","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Daniele Zanzi","name":"Daniele","surname":"Zanzi","rank":null,"pid":[{"value":"0000-0002-1222-7937","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Adrian Irles","name":"Adrian","surname":"Irles","rank":null,"pid":[{"value":"0000-0001-5668-151X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Walter Hopkins","name":"Walter","surname":"Hopkins","rank":null,"pid":[{"value":"0000-0001-7814-8740","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Aurelio Juste","name":"Aurelio","surname":"Juste","rank":null,"pid":[{"value":"0000-0002-1558-3291","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Yoram Rozen","name":"Yoram","surname":"Rozen","rank":null,"pid":[{"value":"0000-0001-6969-0634","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Mateusz Dyndal","name":"Mateusz","surname":"Dyndal","rank":null,"pid":[{"value":"0000-0001-9632-6352","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Monika Wielers","name":"Monika","surname":"Wielers","rank":null,"pid":[{"value":"0000-0001-9232-4827","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Anna Kaczmarska","name":"Anna","surname":"Kaczmarska","rank":null,"pid":[{"value":"0000-0002-8880-4120","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Evgeny Khramov","name":"Evgeny","surname":"Khramov","rank":null,"pid":[{"value":"0000-0001-7400-6454","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Vincent Alexander Croft","name":"Vincent Alexander","surname":"Croft","rank":null,"pid":[{"value":"0000-0002-8731-4525","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Yuji Yamazaki","name":"Yuji","surname":"Yamazaki","rank":null,"pid":[{"value":"0000-0003-3710-6995","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Sau Lan Wu","name":"Sau Lan","surname":"Wu","rank":null,"pid":[{"value":"0000-0001-5866-1504","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Kevin Kröninger","name":"Kevin","surname":"Kröninger","rank":null,"pid":[{"value":"0000-0001-9873-0228","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Calin Alexa","name":"Calin","surname":"Alexa","rank":null,"pid":[{"value":"0000-0003-0922-7669","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Frank Filthaut","name":"Frank","surname":"Filthaut","rank":null,"pid":[{"value":"0000-0003-3338-2247","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Alaettin Serhan Mete","name":"Alaettin Serhan","surname":"Mete","rank":null,"pid":[{"value":"0000-0002-5508-530X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Michael Duehrssen-Debling","name":"Michael","surname":"Duehrssen-Debling","rank":null,"pid":[{"value":"0000-0002-5833-7058","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Torre Wenaus","name":"Torre","surname":"Wenaus","rank":null,"pid":[{"value":"0000-0002-8678-893X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Michele LIVAN","name":"Michele","surname":"LIVAN","rank":null,"pid":[{"value":"0000-0002-5877-0062","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Jose Guillermo Panduro Vazquez","name":"Jose Guillermo","surname":"Panduro Vazquez","rank":null,"pid":[{"value":"0000-0003-2605-8940","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Pascal Pralavorio","name":"Pascal","surname":"Pralavorio","rank":null,"pid":[{"value":"0000-0002-2452-6715","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Yuto Minami","name":"Yuto","surname":"Minami","rank":null,"pid":[{"value":"0000-0003-2176-8089","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Stephen Hillier","name":"Stephen","surname":"Hillier","rank":null,"pid":[{"value":"0000-0002-7599-6469","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Simon Viel","name":"Simon","surname":"Viel","rank":null,"pid":[{"value":"0000-0001-9554-4059","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Andreas Kugel","name":"Andreas","surname":"Kugel","rank":null,"pid":[{"value":"0000-0002-8493-6660","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Lene Kristian Bryngemark","name":"Lene Kristian","surname":"Bryngemark","rank":null,"pid":[{"value":"0000-0002-8420-3408","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Guenter Duckeck","name":"Guenter","surname":"Duckeck","rank":null,"pid":[{"value":"0000-0002-7756-7801","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Alexey Anisenkov","name":"Alexey","surname":"Anisenkov","rank":null,"pid":[{"value":"0000-0002-7201-5936","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Javier Jiménez Peña","name":"Javier","surname":"Jiménez Peña","rank":null,"pid":[{"value":"0000-0002-8705-628X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Sascha null","name":"Sascha","surname":null,"rank":null,"pid":[{"value":"0000-0003-2941-2829","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Evelyn Thomson","name":"Evelyn","surname":"Thomson","rank":null,"pid":[{"value":"0000-0001-6031-2768","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Andrea Formica","name":"Andrea","surname":"Formica","rank":null,"pid":[{"value":"0000-0001-8308-2643","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Mattias Ellert","name":"Mattias","surname":"Ellert","rank":null,"pid":[{"value":"0000-0001-5265-3175","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Richard Keeler","name":"Richard","surname":"Keeler","rank":null,"pid":[{"value":"0000-0002-0510-4189","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Karolos Potamianos","name":"Karolos","surname":"Potamianos","rank":null,"pid":[{"value":"0000-0001-7839-9785","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Muhammad Alhroob","name":"Muhammad","surname":"Alhroob","rank":null,"pid":[{"value":"0000-0001-7569-7111","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Marie-Helene Genest","name":"Marie-Helene","surname":"Genest","rank":null,"pid":[{"value":"0000-0002-4098-2024","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"melissa franklin","name":"melissa","surname":"franklin","rank":null,"pid":[{"value":"0000-0002-6595-883X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"John Baines","name":"John","surname":"Baines","rank":null,"pid":[{"value":"0000-0003-0770-2702","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Jean-Baptiste de Vivie","name":"Jean-Baptiste","surname":"de Vivie","rank":null,"pid":[{"value":"0000-0001-9163-2211","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Kristian Gregersen","name":"Kristian","surname":"Gregersen","rank":null,"pid":[{"value":"0000-0003-0295-1670","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Elisabeth Schopf","name":"Elisabeth","surname":"Schopf","rank":null,"pid":[{"value":"0000-0002-9340-2214","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Tristan Beau","name":"Tristan","surname":"Beau","rank":null,"pid":[{"value":"0000-0002-2022-2140","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Ask Emil Løvschall-Jensen","name":"Ask Emil","surname":"Løvschall-Jensen","rank":null,"pid":[{"value":"0000-0003-1834-4904","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Karel Smolek","name":"Karel","surname":"Smolek","rank":null,"pid":[{"value":"0000-0002-5996-7000","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Wendy Taylor","name":"Wendy","surname":"Taylor","rank":null,"pid":[{"value":"0000-0002-6596-9125","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"James Robinson","name":"James","surname":"Robinson","rank":null,"pid":[{"value":"0000-0002-2856-9413","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Arno Straessner","name":"Arno","surname":"Straessner","rank":null,"pid":[{"value":"0000-0003-2460-6659","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Bruno Lenzi","name":"Bruno","surname":"Lenzi","rank":null,"pid":[{"value":"0000-0002-1024-4004","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Thomas G McCarthy","name":"Thomas G","surname":"McCarthy","rank":null,"pid":[{"value":"0000-0002-1182-3526","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Maria Curatolo","name":"Maria","surname":"Curatolo","rank":null,"pid":[{"value":"0000-0003-0978-4879","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Zuzana Rurikova","name":"Zuzana","surname":"Rurikova","rank":null,"pid":[{"value":"0000-0003-3051-9607","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Norman Gee","name":"Norman","surname":"Gee","rank":null,"pid":[{"value":"0000-0002-8833-3154","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Craig Buttar","name":"Craig","surname":"Buttar","rank":null,"pid":[{"value":"0000-0003-0188-6491","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Sophie Trincaz-Duvoid","name":"Sophie","surname":"Trincaz-Duvoid","rank":null,"pid":[{"value":"0000-0001-5913-0828","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Danilo Enoque Ferreira de Lima","name":"Danilo Enoque","surname":"Ferreira de Lima","rank":null,"pid":[{"value":"0000-0002-6606-3595","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Nektarios Benekos","name":"Nektarios","surname":"Benekos","rank":null,"pid":[{"value":"0000-0001-7831-8762","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Evgenii Baldin","name":"Evgenii","surname":"Baldin","rank":null,"pid":[{"value":"0000-0002-9854-975X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Craig Sawyer","name":"Craig","surname":"Sawyer","rank":null,"pid":[{"value":"0000-0002-2027-1428","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"George Redlinger","name":"George","surname":"Redlinger","rank":null,"pid":[{"value":"0000-0002-6437-9991","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Philip Sommer","name":"Philip","surname":"Sommer","rank":null,"pid":[{"value":"0000-0003-1703-7304","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Simone Monzani","name":"Simone","surname":"Monzani","rank":null,"pid":[{"value":"0000-0002-0479-2207","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Eirik Gramstad","name":"Eirik","surname":"Gramstad","rank":null,"pid":[{"value":"0000-0001-5792-5352","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Anna Lipniacka","name":"Anna","surname":"Lipniacka","rank":null,"pid":[{"value":"0000-0002-8759-8564","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Oana Vickey Boeriu","name":"Oana","surname":"Vickey Boeriu","rank":null,"pid":[{"value":"0000-0002-6497-6809","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Fridolin Dittus","name":"Fridolin","surname":"Dittus","rank":null,"pid":[{"value":"0000-0002-1760-8237","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Antonio Salvucci","name":"Antonio","surname":"Salvucci","rank":null,"pid":[{"value":"0000-0003-4876-2613","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Carlo Dallapiccola","name":"Carlo","surname":"Dallapiccola","rank":null,"pid":[{"value":"0000-0002-1391-2477","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Konstantinos Ntekas","name":"Konstantinos","surname":"Ntekas","rank":null,"pid":[{"value":"0000-0001-9252-6509","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Juan Antonio Aguilar Saavedra","name":"Juan Antonio","surname":"Aguilar Saavedra","rank":null,"pid":[{"value":"0000-0002-5475-8920","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Martine Bosman","name":"Martine","surname":"Bosman","rank":null,"pid":[{"value":"0000-0002-7290-643X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Trevor Vickey","name":"Trevor","surname":"Vickey","rank":null,"pid":[{"value":"0000-0002-1596-2611","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Christian Ohm","name":"Christian","surname":"Ohm","rank":null,"pid":[{"value":"0000-0002-8015-7512","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"William Davey","name":"William","surname":"Davey","rank":null,"pid":[{"value":"0000-0002-8140-8619","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Wolfgang Walkowiak","name":"Wolfgang","surname":"Walkowiak","rank":null,"pid":[{"value":"0000-0002-0385-3784","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Austin Basye","name":"Austin","surname":"Basye","rank":null,"pid":[{"value":"0000-0002-7519-1310","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Kuhan Wang","name":"Kuhan","surname":"Wang","rank":null,"pid":[{"value":"0000-0002-6151-0034","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Cristiano Alpigiani","name":"Cristiano","surname":"Alpigiani","rank":null,"pid":[{"value":"0000-0002-7641-5814","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"James Monk","name":"James","surname":"Monk","rank":null,"pid":[{"value":"0000-0001-8471-9247","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Christopher Pollard","name":"Christopher","surname":"Pollard","rank":null,"pid":[{"value":"0000-0002-3690-3960","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Jozsef Toth","name":"Jozsef","surname":"Toth","rank":null,"pid":[{"value":"0000-0001-9128-6080","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Vitaliano Chiarella","name":"Vitaliano","surname":"Chiarella","rank":null,"pid":[{"value":"0000-0002-4210-2924","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Jos Vermeulen","name":"Jos","surname":"Vermeulen","rank":null,"pid":[{"value":"0000-0003-4378-5736","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Yann Coadou","name":"Yann","surname":"Coadou","rank":null,"pid":[{"value":"0000-0001-8195-7004","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Christine Kourkoumelis","name":"Christine","surname":"Kourkoumelis","rank":null,"pid":[{"value":"0000-0003-0083-274X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Karishma Sekhon","name":"Karishma","surname":"Sekhon","rank":null,"pid":[{"value":"0000-0001-7677-8394","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Kun Liu","name":"Kun","surname":"Liu","rank":null,"pid":[{"value":"0000-0001-5807-0501","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Matt LeBlanc","name":"Matt","surname":"LeBlanc","rank":null,"pid":[{"value":"0000-0001-5977-6418","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Ewan Hill","name":"Ewan","surname":"Hill","rank":null,"pid":[{"value":"0000-0002-1725-7414","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Diane Cinca","name":"Diane","surname":"Cinca","rank":null,"pid":[{"value":"0000-0003-0944-8998","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Benedict Tobias Winter","name":"Benedict Tobias","surname":"Winter","rank":null,"pid":[{"value":"0000-0001-9606-7688","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Steven Schramm","name":"Steven","surname":"Schramm","rank":null,"pid":[{"value":"0000-0001-9031-6751","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Yusheng Wu","name":"Yusheng","surname":"Wu","rank":null,"pid":[{"value":"0000-0002-1528-4865","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Orel Gueta","name":"Orel","surname":"Gueta","rank":null,"pid":[{"value":"0000-0002-9440-2398","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Federico Meloni","name":"Federico","surname":"Meloni","rank":null,"pid":[{"value":"0000-0001-7075-2214","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Sylvain Tisserant","name":"Sylvain","surname":"Tisserant","rank":null,"pid":[{"value":"0000-0002-0294-6727","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Dimitrios Iliadis","name":"Dimitrios","surname":"Iliadis","rank":null,"pid":[{"value":"0000-0001-6303-2761","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Sebastien Binet","name":"Sebastien","surname":"Binet","rank":null,"pid":[{"value":"0000-0003-4913-6104","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Marcella Bona","name":"Marcella","surname":"Bona","rank":null,"pid":[{"value":"0000-0002-9660-580X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Ki Lie","name":"Ki","surname":"Lie","rank":null,"pid":[{"value":"0000-0002-5779-5989","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"David Sankey","name":"David","surname":"Sankey","rank":null,"pid":[{"value":"0000-0003-0955-4213","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Michele Faucci Giannelli","name":"Michele","surname":"Faucci Giannelli","rank":null,"pid":[{"value":"0000-0003-3731-820X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Georges Azuelos","name":"Georges","surname":"Azuelos","rank":null,"pid":[{"value":"0000-0003-4241-022X","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"David Britton","name":"David","surname":"Britton","rank":null,"pid":[{"value":"0000-0001-9998-4342","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Henri Bachacou","name":"Henri","surname":"Bachacou","rank":null,"pid":[{"value":"0000-0002-2256-4515","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Stefania Stucci","name":"Stefania","surname":"Stucci","rank":null,"pid":[{"value":"0000-0002-1639-4484","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Peter Berta","name":"Peter","surname":"Berta","rank":null,"pid":[{"value":"0000-0003-0780-0345","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"SERKANT ALİ ÇETİN","name":"SERKANT ALİ","surname":"ÇETİN","rank":null,"pid":[{"value":"0000-0001-5050-8441","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Alexey Zhemchugov","name":"Alexey","surname":"Zhemchugov","rank":null,"pid":[{"value":"0000-0002-3360-4965","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Yasushi Nagasaka","name":"Yasushi","surname":"Nagasaka","rank":null,"pid":[{"value":"0000-0002-3669-9525","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"James Walder","name":"James","surname":"Walder","rank":null,"pid":[{"value":"0000-0002-9039-8758","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Marina Rotaru","name":"Marina","surname":"Rotaru","rank":null,"pid":[{"value":"0000-0003-4088-6275","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Chunhui Chen","name":"Chunhui","surname":"Chen","rank":null,"pid":[{"value":"0000-0003-1589-9955","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Valentina Tudorache","name":"Valentina","surname":"Tudorache","rank":null,"pid":[{"value":"0000-0001-5384-3843","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Amanda Cooper-Sarkar","name":"Amanda","surname":"Cooper-Sarkar","rank":null,"pid":[{"value":"0000-0002-7107-5902","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Paul Dervan","name":"Paul","surname":"Dervan","rank":null,"pid":[{"value":"0000-0003-3929-8046","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Laura Gonella","name":"Laura","surname":"Gonella","rank":null,"pid":[{"value":"0000-0002-4919-0808","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Georges Aad","name":"Georges","surname":"Aad","rank":null,"pid":[{"value":"0000-0002-6665-4934","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Hok-Chuen Cheng","name":"Hok-Chuen","surname":"Cheng","rank":null,"pid":[{"value":"0000-0002-8912-4389","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Michal Svatos","name":"Michal","surname":"Svatos","rank":null,"pid":[{"value":"0000-0002-7199-3383","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Jens Janssen","name":"Jens","surname":"Janssen","rank":null,"pid":[{"value":"0000-0002-2391-3078","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Jana Faltova","name":"Jana","surname":"Faltova","rank":null,"pid":[{"value":"0000-0003-4278-7182","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Trisha Farooque","name":"Trisha","surname":"Farooque","rank":null,"pid":[{"value":"0000-0003-1363-9324","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"andrea gabrielli","name":"andrea","surname":"gabrielli","rank":null,"pid":[{"value":"0000-0003-0768-9325","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Santiago Gonzalez de la Hoz","name":"Santiago","surname":"Gonzalez de la Hoz","rank":null,"pid":[{"value":"0000-0001-5304-5390","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"José Ocariz","name":"José","surname":"Ocariz","rank":null,"pid":[{"value":"0000-0003-2262-0780","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null},{"fullname":"Michele Weber","name":"Michele","surname":"Weber","rank":null,"pid":[{"value":"0000-0002-2770-9031","qualifier":{"classid":"ORCID","classname":"ORCID","schemeid":"ORCID","schemename":"ORCID"},"dataInfo":null}],"affiliation":null}]
diff --git a/dhp-common/src/test/resources/eu/dnetlib/dhp/oa/merge/authors_publication_sample.json b/dhp-common/src/test/resources/eu/dnetlib/dhp/oa/merge/authors_publication_sample.json
new file mode 100644
index 000000000..eac239b93
--- /dev/null
+++ b/dhp-common/src/test/resources/eu/dnetlib/dhp/oa/merge/authors_publication_sample.json
@@ -0,0 +1,2 @@
+50|arXiv_dedup_::34e03f2336b8b28286550425e65634ea
+[{"fullname":"Aad, G.","name":"G.","surname":"Aad","rank":1,"pid":[],"affiliation":null},{"fullname":"Ayoub, M.K.","name":"M. K.","surname":"Ayoub","rank":2,"pid":[],"affiliation":null},{"fullname":"Bassalat, A.","name":"A.","surname":"Bassalat","rank":3,"pid":[],"affiliation":null},{"fullname":"Becot, C.","name":"C.","surname":"Becot","rank":4,"pid":[],"affiliation":null},{"fullname":"Binet, S.","name":"S.","surname":"Binet","rank":5,"pid":[],"affiliation":null},{"fullname":"Bourdarios, C.","name":"C.","surname":"Bourdarios","rank":6,"pid":[],"affiliation":null},{"fullname":"Regie, J.B. de Vivie de","name":"J. B. Vivie","surname":"Regie","rank":7,"pid":[],"affiliation":null},{"fullname":"Delgove, D.","name":"D.","surname":"Delgove","rank":8,"pid":[],"affiliation":null},{"fullname":"Duflot, L.","name":"L.","surname":"Duflot","rank":9,"pid":[],"affiliation":null},{"fullname":"Escalier, M.","name":"M.","surname":"Escalier","rank":10,"pid":[],"affiliation":null},{"fullname":"Fayard, L.","name":"L.","surname":"Fayard","rank":11,"pid":[],"affiliation":null},{"fullname":"Fournier, D.","name":"D.","surname":"Fournier","rank":12,"pid":[],"affiliation":null},{"fullname":"Gkougkousis, E.L.","name":"E. L.","surname":"Gkougkousis","rank":13,"pid":[],"affiliation":null},{"fullname":"Grivaz, J.-F.","name":"J. -F","surname":"Grivaz","rank":14,"pid":[],"affiliation":null},{"fullname":"Guillemin, T.","name":"T.","surname":"Guillemin","rank":15,"pid":[],"affiliation":null},{"fullname":"Hariri, F.","name":"F.","surname":"Hariri","rank":16,"pid":[],"affiliation":null},{"fullname":"Henrot-Versillé, S.","name":"S.","surname":"Henrot-Versillé","rank":17,"pid":[],"affiliation":null},{"fullname":"Hrivnac, J.","name":"J.","surname":"Hrivnac","rank":18,"pid":[],"affiliation":null},{"fullname":"Iconomidou-Fayard, L.","name":"L.","surname":"Iconomidou-Fayard","rank":19,"pid":[],"affiliation":null},{"fullname":"Kado, M.","name":"M.","surname":"Kado","rank":20,"pid":[],"affiliation":null},{"fullname":"Lounis, A.","name":"A.","surname":"Lounis","rank":21,"pid":[],"affiliation":null},{"fullname":"Makovec, N.","name":"N.","surname":"Makovec","rank":22,"pid":[],"affiliation":null},{"fullname":"Morange, N.","name":"N.","surname":"Morange","rank":23,"pid":[],"affiliation":null},{"fullname":"Nellist, C.","name":"C.","surname":"Nellist","rank":24,"pid":[],"affiliation":null},{"fullname":"Poggioli, L.","name":"L.","surname":"Poggioli","rank":25,"pid":[],"affiliation":null},{"fullname":"Puzo, P.","name":"P.","surname":"Puzo","rank":26,"pid":[],"affiliation":null},{"fullname":"Renaud, A.","name":"A.","surname":"Renaud","rank":27,"pid":[],"affiliation":null},{"fullname":"Rousseau, D.","name":"D.","surname":"Rousseau","rank":28,"pid":[],"affiliation":null},{"fullname":"Rybkin, G.","name":"G.","surname":"Rybkin","rank":29,"pid":[],"affiliation":null},{"fullname":"Schaffer, A.C.","name":"A. C.","surname":"Schaffer","rank":30,"pid":[],"affiliation":null},{"fullname":"Scifo, E.","name":"E.","surname":"Scifo","rank":31,"pid":[],"affiliation":null},{"fullname":"Serin, L.","name":"L.","surname":"Serin","rank":32,"pid":[],"affiliation":null},{"fullname":"Simion, S.","name":"S.","surname":"Simion","rank":33,"pid":[],"affiliation":null},{"fullname":"Tanaka, R.","name":"R.","surname":"Tanaka","rank":34,"pid":[],"affiliation":null},{"fullname":"Tran, H.L.","name":"H. L.","surname":"Tran","rank":35,"pid":[],"affiliation":null},{"fullname":"Zerwas, D.","name":"D.","surname":"Zerwas","rank":36,"pid":[],"affiliation":null},{"fullname":"Zhang, Zhongkai","name":"Zhongkai","surname":"Zhang","rank":37,"pid":[],"affiliation":null},{"fullname":"Zhao, Y.","name":"Y.","surname":"Zhao","rank":38,"pid":[],"affiliation":null},{"fullname":"Rahal, G.","name":"G.","surname":"Rahal","rank":39,"pid":[],"affiliation":null},{"fullname":"Barnovska, Z.","name":"Z.","surname":"Barnovska","rank":40,"pid":[],"affiliation":null},{"fullname":"Berger, N.","name":"N.","surname":"Berger","rank":41,"pid":[],"affiliation":null},{"fullname":"Delmastro, M.","name":"M.","surname":"Delmastro","rank":42,"pid":[],"affiliation":null},{"fullname":"Ciaccio, L. Di","name":"L. Di","surname":"Ciaccio","rank":43,"pid":[],"affiliation":null},{"fullname":"Elles, S.","name":"S.","surname":"Elles","rank":44,"pid":[],"affiliation":null},{"fullname":"Hryn’ova, T.","name":"T.","surname":"Hryn’ova","rank":45,"pid":[],"affiliation":null},{"fullname":"Jézéquel, S.","name":"S.","surname":"Jézéquel","rank":46,"pid":[],"affiliation":null},{"fullname":"Koletsou, I.","name":"I.","surname":"Koletsou","rank":47,"pid":[],"affiliation":null},{"fullname":"Lafaye, R.","name":"R.","surname":"Lafaye","rank":48,"pid":[],"affiliation":null},{"fullname":"Leveque, J.","name":"J.","surname":"Leveque","rank":49,"pid":[],"affiliation":null},{"fullname":"Massol, N.","name":"N.","surname":"Massol","rank":50,"pid":[],"affiliation":null},{"fullname":"Sauvage, G.","name":"G.","surname":"Sauvage","rank":51,"pid":[],"affiliation":null},{"fullname":"Sauvan, E.","name":"E.","surname":"Sauvan","rank":52,"pid":[],"affiliation":null},{"fullname":"Simard, O.","name":"O.","surname":"Simard","rank":53,"pid":[],"affiliation":null},{"fullname":"Todorov, T.","name":"T.","surname":"Todorov","rank":54,"pid":[],"affiliation":null},{"fullname":"Wingerter-Seez, I.","name":"I.","surname":"Wingerter-Seez","rank":55,"pid":[],"affiliation":null},{"fullname":"Albrand, S.","name":"S.","surname":"Albrand","rank":56,"pid":[],"affiliation":null},{"fullname":"Brown, J.","name":"J.","surname":"Brown","rank":57,"pid":[],"affiliation":null},{"fullname":"Collot, J.","name":"J.","surname":"Collot","rank":58,"pid":[],"affiliation":null},{"fullname":"Crépé-Renaudin, S.","name":"S.","surname":"Crépé-Renaudin","rank":59,"pid":[],"affiliation":null},{"fullname":"Delsart, P.A.","name":"P. A.","surname":"Delsart","rank":60,"pid":[],"affiliation":null},{"fullname":"Gabaldon, C.","name":"C.","surname":"Gabaldon","rank":61,"pid":[],"affiliation":null},{"fullname":"Genest, M.H.","name":"M. H.","surname":"Genest","rank":62,"pid":[],"affiliation":null},{"fullname":"Hostachy, J.Y.","name":"J. Y.","surname":"Hostachy","rank":63,"pid":[],"affiliation":null},{"fullname":"Ledroit-Guillon, F.","name":"F.","surname":"Ledroit-Guillon","rank":64,"pid":[],"affiliation":null},{"fullname":"Lleres, A.","name":"A.","surname":"Lleres","rank":65,"pid":[],"affiliation":null},{"fullname":"Lucotte, A.","name":"A.","surname":"Lucotte","rank":66,"pid":[],"affiliation":null},{"fullname":"Malek, F.","name":"F.","surname":"Malek","rank":67,"pid":[],"affiliation":null},{"fullname":"Monini, C.","name":"C.","surname":"Monini","rank":68,"pid":[],"affiliation":null},{"fullname":"Stark, J.","name":"J.","surname":"Stark","rank":69,"pid":[],"affiliation":null},{"fullname":"Trocmé, B.","name":"B.","surname":"Trocmé","rank":70,"pid":[],"affiliation":null},{"fullname":"Wu, M.","name":"M.","surname":"Wu","rank":71,"pid":[],"affiliation":null},{"fullname":"Alio, L.","name":"L.","surname":"Alio","rank":72,"pid":[],"affiliation":null},{"fullname":"Barbero, M.","name":"M.","surname":"Barbero","rank":73,"pid":[],"affiliation":null},{"fullname":"Coadou, Y.","name":"Y.","surname":"Coadou","rank":74,"pid":[],"affiliation":null},{"fullname":"Diaconu, C.","name":"C.","surname":"Diaconu","rank":75,"pid":[],"affiliation":null},{"fullname":"Diglio, Sara","name":"Sara","surname":"Diglio","rank":76,"pid":[],"affiliation":null},{"fullname":"Djama, F.","name":"F.","surname":"Djama","rank":77,"pid":[],"affiliation":null},{"fullname":"Duccu, O.","name":"O.","surname":"Duccu","rank":78,"pid":[],"affiliation":null},{"fullname":"Feligioni, L.","name":"L.","surname":"Feligioni","rank":79,"pid":[],"affiliation":null},{"fullname":"Gao, J.","name":"J.","surname":"Gao","rank":80,"pid":[],"affiliation":null},{"fullname":"Hallewell, G.D.","name":"G. D.","surname":"Hallewell","rank":81,"pid":[],"affiliation":null},{"fullname":"Hubaut, F.","name":"F.","surname":"Hubaut","rank":82,"pid":[],"affiliation":null},{"fullname":"Kahn, S.J.","name":"S. J.","surname":"Kahn","rank":83,"pid":[],"affiliation":null},{"fullname":"Knoops, E. B. F. G.","name":"E. B. F. G.","surname":"Knoops","rank":84,"pid":[],"affiliation":null},{"fullname":"Guirriec, E. Le","name":"E. Le","surname":"Guirriec","rank":85,"pid":[],"affiliation":null},{"fullname":"Liu, J.","name":"J.","surname":"Liu","rank":86,"pid":[],"affiliation":null},{"fullname":"Liu, K.","name":"K.","surname":"Liu","rank":87,"pid":[],"affiliation":null},{"fullname":"Madaffari, D.","name":"D.","surname":"Madaffari","rank":88,"pid":[],"affiliation":null},{"fullname":"Mochizuki, K.","name":"K.","surname":"Mochizuki","rank":89,"pid":[],"affiliation":null},{"fullname":"Monnier, E.","name":"E.","surname":"Monnier","rank":90,"pid":[],"affiliation":null},{"fullname":"Muanza, S.","name":"S.","surname":"Muanza","rank":91,"pid":[],"affiliation":null},{"fullname":"Nagai, Y.","name":"Y.","surname":"Nagai","rank":92,"pid":[],"affiliation":null},{"fullname":"Nagy, E.","name":"E.","surname":"Nagy","rank":93,"pid":[],"affiliation":null},{"fullname":"Pralavorio, P.","name":"P.","surname":"Pralavorio","rank":94,"pid":[],"affiliation":null},{"fullname":"Rozanov, A.","name":"A.","surname":"Rozanov","rank":95,"pid":[],"affiliation":null},{"fullname":"Serre, T.","name":"T.","surname":"Serre","rank":96,"pid":[],"affiliation":null},{"fullname":"Talby, M.","name":"M.","surname":"Talby","rank":97,"pid":[],"affiliation":null},{"fullname":"Torres, R.E. Ticse","name":"R. E. Ticse","surname":"Torres","rank":98,"pid":[],"affiliation":null},{"fullname":"Tiouchichine, E.","name":"E.","surname":"Tiouchichine","rank":99,"pid":[],"affiliation":null},{"fullname":"Tisserant, S.","name":"S.","surname":"Tisserant","rank":100,"pid":[],"affiliation":null},{"fullname":"Toth, J.","name":"J.","surname":"Toth","rank":101,"pid":[],"affiliation":null},{"fullname":"Touchard, F.","name":"F.","surname":"Touchard","rank":102,"pid":[],"affiliation":null},{"fullname":"Vacavant, L.","name":"L.","surname":"Vacavant","rank":103,"pid":[],"affiliation":null},{"fullname":"Boumediene, D.","name":"D.","surname":"Boumediene","rank":104,"pid":[],"affiliation":null},{"fullname":"Busato, Emmanuel","name":"Emmanuel","surname":"Busato","rank":105,"pid":[],"affiliation":null},{"fullname":"Calvet, D.","name":"D.","surname":"Calvet","rank":106,"pid":[],"affiliation":null},{"fullname":"Calvet, S.","name":"S.","surname":"Calvet","rank":107,"pid":[],"affiliation":null},{"fullname":"Donini, J.","name":"J.","surname":"Donini","rank":108,"pid":[],"affiliation":null},{"fullname":"Dubreuil, E.","name":"E.","surname":"Dubreuil","rank":109,"pid":[],"affiliation":null},{"fullname":"Gilles, G.","name":"G.","surname":"Gilles","rank":110,"pid":[],"affiliation":null},{"fullname":"Gris, Ph.","name":"Ph","surname":"Gris","rank":111,"pid":[],"affiliation":null},{"fullname":"Liao, H.","name":"H.","surname":"Liao","rank":112,"pid":[],"affiliation":null},{"fullname":"Madar, R.","name":"R.","surname":"Madar","rank":113,"pid":[],"affiliation":null},{"fullname":"Pallin, D.","name":"D.","surname":"Pallin","rank":114,"pid":[],"affiliation":null},{"fullname":"Saez, S.M. Romano","name":"S. M. Romano","surname":"Saez","rank":115,"pid":[],"affiliation":null},{"fullname":"Santoni, C.","name":"C.","surname":"Santoni","rank":116,"pid":[],"affiliation":null},{"fullname":"Simon, D.","name":"D.","surname":"Simon","rank":117,"pid":[],"affiliation":null},{"fullname":"Theveneaux-Pelzer, Timothée","name":"Timothée","surname":"Theveneaux-Pelzer","rank":118,"pid":[],"affiliation":null},{"fullname":"Vazeille, F.","name":"F.","surname":"Vazeille","rank":119,"pid":[],"affiliation":null},{"fullname":"Yatsenko, E.","name":"E.","surname":"Yatsenko","rank":120,"pid":[],"affiliation":null}]
\ No newline at end of file
diff --git a/dhp-pace-core/pom.xml b/dhp-pace-core/pom.xml
new file mode 100644
index 000000000..fd7f44fc9
--- /dev/null
+++ b/dhp-pace-core/pom.xml
@@ -0,0 +1,110 @@
+
+
+
+ 4.0.0
+
+
+ eu.dnetlib.dhp
+ dhp
+ 1.2.5-SNAPSHOT
+ ../pom.xml
+
+
+ eu.dnetlib.dhp
+ dhp-pace-core
+ 1.2.5-SNAPSHOT
+ jar
+
+
+
+
+ net.alchim31.maven
+ scala-maven-plugin
+ ${net.alchim31.maven.version}
+
+
+ scala-compile-first
+ initialize
+
+ add-source
+ compile
+
+
+
+ scala-test-compile
+ process-test-resources
+
+ testCompile
+
+
+
+
+ true
+ ${scala.binary.version}
+ ${scala.version}
+
+
+
+
+
+
+
+
+ edu.cmu
+ secondstring
+
+
+ com.google.guava
+ guava
+
+
+ com.google.code.gson
+ gson
+
+
+ org.apache.commons
+ commons-lang3
+
+
+ commons-io
+ commons-io
+
+
+ org.antlr
+ stringtemplate
+
+
+ commons-logging
+ commons-logging
+
+
+ org.reflections
+ reflections
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+
+
+ org.apache.commons
+ commons-math3
+
+
+ com.jayway.jsonpath
+ json-path
+
+
+ com.ibm.icu
+ icu4j
+
+
+ org.apache.spark
+ spark-core_${scala.binary.version}
+
+
+ org.apache.spark
+ spark-sql_${scala.binary.version}
+
+
+
+
diff --git a/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/AbstractClusteringFunction.java b/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/AbstractClusteringFunction.java
new file mode 100644
index 000000000..e971ec5bb
--- /dev/null
+++ b/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/AbstractClusteringFunction.java
@@ -0,0 +1,59 @@
+
+package eu.dnetlib.pace.clustering;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.apache.commons.lang3.StringUtils;
+
+import eu.dnetlib.pace.common.AbstractPaceFunctions;
+import eu.dnetlib.pace.config.Config;
+
+public abstract class AbstractClusteringFunction extends AbstractPaceFunctions implements ClusteringFunction {
+
+ protected Map params;
+
+ public AbstractClusteringFunction(final Map params) {
+ this.params = params;
+ }
+
+ protected abstract Collection doApply(Config conf, String s);
+
+ @Override
+ public Collection apply(Config conf, List fields) {
+ return fields
+ .stream()
+ .filter(f -> !f.isEmpty())
+ .map(s -> normalize(s))
+ .map(s -> filterAllStopWords(s))
+ .map(s -> doApply(conf, s))
+ .map(c -> filterBlacklisted(c, ngramBlacklist))
+ .flatMap(c -> c.stream())
+ .filter(StringUtils::isNotBlank)
+ .collect(Collectors.toCollection(HashSet::new));
+ }
+
+ public Map getParams() {
+ return params;
+ }
+
+ protected Integer param(String name) {
+ Object val = params.get(name);
+ if (val == null)
+ return null;
+ if (val instanceof Number) {
+ return ((Number) val).intValue();
+ }
+ return Integer.parseInt(val.toString());
+ }
+
+ protected int paramOrDefault(String name, int i) {
+ Integer res = param(name);
+ if (res == null)
+ res = i;
+ return res;
+ }
+}
diff --git a/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/Acronyms.java b/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/Acronyms.java
new file mode 100644
index 000000000..b5db27106
--- /dev/null
+++ b/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/Acronyms.java
@@ -0,0 +1,51 @@
+
+package eu.dnetlib.pace.clustering;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import com.google.common.collect.Sets;
+
+import eu.dnetlib.pace.config.Config;
+
+@ClusteringClass("acronyms")
+public class Acronyms extends AbstractClusteringFunction {
+
+ public Acronyms(Map params) {
+ super(params);
+ }
+
+ @Override
+ protected Collection doApply(Config conf, String s) {
+ return extractAcronyms(s, param("max"), param("minLen"), param("maxLen"));
+ }
+
+ private Set extractAcronyms(final String s, int maxAcronyms, int minLen, int maxLen) {
+
+ final Set acronyms = Sets.newLinkedHashSet();
+
+ for (int i = 0; i < maxAcronyms; i++) {
+
+ final StringTokenizer st = new StringTokenizer(s);
+ final StringBuilder sb = new StringBuilder();
+
+ while (st.hasMoreTokens()) {
+ final String token = st.nextToken();
+ if (sb.length() > maxLen) {
+ break;
+ }
+ if (token.length() > 1 && i < token.length()) {
+ sb.append(token.charAt(i));
+ }
+ }
+ String acronym = sb.toString();
+ if (acronym.length() > minLen) {
+ acronyms.add(acronym);
+ }
+ }
+ return acronyms;
+ }
+
+}
diff --git a/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/ClusteringClass.java b/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/ClusteringClass.java
new file mode 100644
index 000000000..3bb845b15
--- /dev/null
+++ b/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/ClusteringClass.java
@@ -0,0 +1,14 @@
+
+package eu.dnetlib.pace.clustering;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface ClusteringClass {
+
+ public String value();
+}
diff --git a/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/ClusteringFunction.java b/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/ClusteringFunction.java
new file mode 100644
index 000000000..269de867d
--- /dev/null
+++ b/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/ClusteringFunction.java
@@ -0,0 +1,16 @@
+
+package eu.dnetlib.pace.clustering;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import eu.dnetlib.pace.config.Config;
+
+public interface ClusteringFunction {
+
+ public Collection apply(Config config, List fields);
+
+ public Map getParams();
+
+}
diff --git a/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/ImmutableFieldValue.java b/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/ImmutableFieldValue.java
new file mode 100644
index 000000000..cbfcde266
--- /dev/null
+++ b/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/ImmutableFieldValue.java
@@ -0,0 +1,28 @@
+
+package eu.dnetlib.pace.clustering;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import com.google.common.collect.Lists;
+
+import eu.dnetlib.pace.config.Config;
+
+@ClusteringClass("immutablefieldvalue")
+public class ImmutableFieldValue extends AbstractClusteringFunction {
+
+ public ImmutableFieldValue(final Map params) {
+ super(params);
+ }
+
+ @Override
+ protected Collection doApply(final Config conf, final String s) {
+ final List res = Lists.newArrayList();
+
+ res.add(s);
+
+ return res;
+ }
+
+}
diff --git a/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/JSONListClustering.java b/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/JSONListClustering.java
new file mode 100644
index 000000000..e00092bd0
--- /dev/null
+++ b/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/JSONListClustering.java
@@ -0,0 +1,69 @@
+
+package eu.dnetlib.pace.clustering;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.apache.commons.lang3.StringUtils;
+
+import com.jayway.jsonpath.Configuration;
+import com.jayway.jsonpath.DocumentContext;
+import com.jayway.jsonpath.JsonPath;
+import com.jayway.jsonpath.Option;
+
+import eu.dnetlib.pace.common.AbstractPaceFunctions;
+import eu.dnetlib.pace.config.Config;
+import eu.dnetlib.pace.util.MapDocumentUtil;
+
+@ClusteringClass("jsonlistclustering")
+public class JSONListClustering extends AbstractPaceFunctions implements ClusteringFunction {
+
+ private Map params;
+
+ public JSONListClustering(Map params) {
+ this.params = params;
+ }
+
+ @Override
+ public Map getParams() {
+ return params;
+ }
+
+ @Override
+ public Collection apply(Config conf, List fields) {
+ return fields
+ .stream()
+ .filter(f -> !f.isEmpty())
+ .map(s -> doApply(conf, s))
+ .filter(StringUtils::isNotBlank)
+ .collect(Collectors.toCollection(HashSet::new));
+ }
+
+ private String doApply(Config conf, String json) {
+ StringBuilder st = new StringBuilder(); // to build the string used for comparisons basing on the jpath into
+ // parameters
+ final DocumentContext documentContext = JsonPath
+ .using(Configuration.defaultConfiguration().addOptions(Option.SUPPRESS_EXCEPTIONS))
+ .parse(json);
+
+ // for each path in the param list
+ for (String key : params.keySet().stream().filter(k -> k.contains("jpath")).collect(Collectors.toList())) {
+ String path = params.get(key).toString();
+ String value = MapDocumentUtil.getJPathString(path, documentContext);
+ if (value == null || value.isEmpty())
+ value = "";
+ st.append(value);
+ st.append(" ");
+ }
+
+ st.setLength(st.length() - 1);
+
+ if (StringUtils.isBlank(st)) {
+ return "1";
+ }
+ return st.toString();
+ }
+}
diff --git a/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/KeywordsClustering.java b/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/KeywordsClustering.java
new file mode 100644
index 000000000..fdd8d1fb1
--- /dev/null
+++ b/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/KeywordsClustering.java
@@ -0,0 +1,54 @@
+
+package eu.dnetlib.pace.clustering;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+import org.apache.commons.lang3.StringUtils;
+
+import eu.dnetlib.pace.config.Config;
+
+@ClusteringClass("keywordsclustering")
+public class KeywordsClustering extends AbstractClusteringFunction {
+
+ public KeywordsClustering(Map params) {
+ super(params);
+ }
+
+ @Override
+ protected Collection doApply(final Config conf, String s) {
+
+ // takes city codes and keywords codes without duplicates
+ Set keywords = getKeywords(s, conf.translationMap(), paramOrDefault("windowSize", 4));
+ Set cities = getCities(s, paramOrDefault("windowSize", 4));
+
+ // list of combination to return as result
+ final Collection combinations = new LinkedHashSet();
+
+ for (String keyword : keywordsToCodes(keywords, conf.translationMap())) {
+ for (String city : citiesToCodes(cities)) {
+ combinations.add(keyword + "-" + city);
+ if (combinations.size() >= paramOrDefault("max", 2)) {
+ return combinations;
+ }
+ }
+ }
+
+ return combinations;
+ }
+
+ @Override
+ public Collection apply(final Config conf, List fields) {
+ return fields
+ .stream()
+ .filter(f -> !f.isEmpty())
+ .map(KeywordsClustering::cleanup)
+ .map(KeywordsClustering::normalize)
+ .map(s -> filterAllStopWords(s))
+ .map(s -> doApply(conf, s))
+ .map(c -> filterBlacklisted(c, ngramBlacklist))
+ .flatMap(c -> c.stream())
+ .filter(StringUtils::isNotBlank)
+ .collect(Collectors.toCollection(HashSet::new));
+ }
+}
diff --git a/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/LastNameFirstInitial.java b/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/LastNameFirstInitial.java
new file mode 100644
index 000000000..9692f5762
--- /dev/null
+++ b/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/LastNameFirstInitial.java
@@ -0,0 +1,78 @@
+
+package eu.dnetlib.pace.clustering;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+import org.apache.commons.lang3.StringUtils;
+
+import com.google.common.collect.Lists;
+
+import eu.dnetlib.pace.config.Config;
+import eu.dnetlib.pace.model.Person;
+
+@ClusteringClass("lnfi")
+public class LastNameFirstInitial extends AbstractClusteringFunction {
+
+ private boolean DEFAULT_AGGRESSIVE = true;
+
+ public LastNameFirstInitial(final Map params) {
+ super(params);
+ }
+
+ @Override
+ public Collection apply(Config conf, List fields) {
+ return fields
+ .stream()
+ .filter(f -> !f.isEmpty())
+ .map(LastNameFirstInitial::normalize)
+ .map(s -> doApply(conf, s))
+ .map(c -> filterBlacklisted(c, ngramBlacklist))
+ .flatMap(c -> c.stream())
+ .filter(StringUtils::isNotBlank)
+ .collect(Collectors.toCollection(HashSet::new));
+ }
+
+ public static String normalize(final String s) {
+ return fixAliases(transliterate(nfd(unicodeNormalization(s))))
+ // do not compact the regexes in a single expression, would cause StackOverflowError in case of large input
+ // strings
+ .replaceAll("[^ \\w]+", "")
+ .replaceAll("(\\p{InCombiningDiacriticalMarks})+", "")
+ .replaceAll("(\\p{Punct})+", " ")
+ .replaceAll("(\\d)+", " ")
+ .replaceAll("(\\n)+", " ")
+ .trim();
+ }
+
+ @Override
+ protected Collection doApply(final Config conf, final String s) {
+
+ final List res = Lists.newArrayList();
+
+ final boolean aggressive = (Boolean) (getParams().containsKey("aggressive") ? getParams().get("aggressive")
+ : DEFAULT_AGGRESSIVE);
+
+ Person p = new Person(s, aggressive);
+
+ if (p.isAccurate()) {
+ String lastName = p.getNormalisedSurname().toLowerCase();
+ String firstInitial = p.getNormalisedFirstName().toLowerCase().substring(0, 1);
+
+ res.add(firstInitial.concat(lastName));
+ } else { // is not accurate, meaning it has no defined name and surname
+ List fullname = Arrays.asList(p.getNormalisedFullname().split(" "));
+ if (fullname.size() == 1) {
+ res.add(p.getNormalisedFullname().toLowerCase());
+ } else if (fullname.size() == 2) {
+ res.add(fullname.get(0).substring(0, 1).concat(fullname.get(1)).toLowerCase());
+ res.add(fullname.get(1).substring(0, 1).concat(fullname.get(0)).toLowerCase());
+ } else {
+ res.add(fullname.get(0).substring(0, 1).concat(fullname.get(fullname.size() - 1)).toLowerCase());
+ res.add(fullname.get(fullname.size() - 1).substring(0, 1).concat(fullname.get(0)).toLowerCase());
+ }
+ }
+
+ return res;
+ }
+}
diff --git a/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/LowercaseClustering.java b/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/LowercaseClustering.java
new file mode 100644
index 000000000..807f41dd5
--- /dev/null
+++ b/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/LowercaseClustering.java
@@ -0,0 +1,38 @@
+
+package eu.dnetlib.pace.clustering;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.lang3.StringUtils;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+
+import eu.dnetlib.pace.config.Config;
+
+@ClusteringClass("lowercase")
+public class LowercaseClustering extends AbstractClusteringFunction {
+
+ public LowercaseClustering(final Map params) {
+ super(params);
+ }
+
+ @Override
+ public Collection apply(Config conf, List fields) {
+ Collection c = Sets.newLinkedHashSet();
+ for (String f : fields) {
+ c.addAll(doApply(conf, f));
+ }
+ return c;
+ }
+
+ @Override
+ protected Collection doApply(final Config conf, final String s) {
+ if (StringUtils.isBlank(s)) {
+ return Lists.newArrayList();
+ }
+ return Lists.newArrayList(s.toLowerCase().trim());
+ }
+}
diff --git a/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/NGramUtils.java b/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/NGramUtils.java
new file mode 100644
index 000000000..6ee80b86e
--- /dev/null
+++ b/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/NGramUtils.java
@@ -0,0 +1,24 @@
+
+package eu.dnetlib.pace.clustering;
+
+import java.util.Set;
+
+import org.apache.commons.lang3.StringUtils;
+
+import eu.dnetlib.pace.common.AbstractPaceFunctions;
+
+public class NGramUtils extends AbstractPaceFunctions {
+ static private final NGramUtils NGRAMUTILS = new NGramUtils();
+
+ private static final int SIZE = 100;
+
+ private static final Set stopwords = AbstractPaceFunctions
+ .loadFromClasspath("/eu/dnetlib/pace/config/stopwords_en.txt");
+
+ public static String cleanupForOrdering(String s) {
+ return (NGRAMUTILS.filterStopWords(NGRAMUTILS.normalize(s), stopwords) + StringUtils.repeat(" ", SIZE))
+ .substring(0, SIZE)
+ .replaceAll(" ", "");
+ }
+
+}
diff --git a/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/NgramPairs.java b/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/NgramPairs.java
new file mode 100644
index 000000000..bcc9667a8
--- /dev/null
+++ b/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/NgramPairs.java
@@ -0,0 +1,41 @@
+
+package eu.dnetlib.pace.clustering;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import com.google.common.collect.Lists;
+
+import eu.dnetlib.pace.config.Config;
+
+@ClusteringClass("ngrampairs")
+public class NgramPairs extends Ngrams {
+
+ public NgramPairs(Map params) {
+ super(params, false);
+ }
+
+ public NgramPairs(Map params, boolean sorted) {
+ super(params, sorted);
+ }
+
+ @Override
+ protected Collection doApply(Config conf, String s) {
+ return ngramPairs(Lists.newArrayList(getNgrams(s, param("ngramLen"), param("max") * 2, 1, 2)), param("max"));
+ }
+
+ protected Collection ngramPairs(final List ngrams, int maxNgrams) {
+ Collection res = Lists.newArrayList();
+ int j = 0;
+ for (int i = 0; i < ngrams.size() && res.size() < maxNgrams; i++) {
+ if (++j >= ngrams.size()) {
+ break;
+ }
+ res.add(ngrams.get(i) + ngrams.get(j));
+ // System.out.println("-- " + concatNgrams);
+ }
+ return res;
+ }
+
+}
diff --git a/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/Ngrams.java b/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/Ngrams.java
new file mode 100644
index 000000000..7b862c729
--- /dev/null
+++ b/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/Ngrams.java
@@ -0,0 +1,52 @@
+
+package eu.dnetlib.pace.clustering;
+
+import java.util.*;
+
+import eu.dnetlib.pace.config.Config;
+
+@ClusteringClass("ngrams")
+public class Ngrams extends AbstractClusteringFunction {
+
+ private final boolean sorted;
+
+ public Ngrams(Map params) {
+ this(params, false);
+ }
+
+ public Ngrams(Map params, boolean sorted) {
+ super(params);
+ this.sorted = sorted;
+ }
+
+ @Override
+ protected Collection doApply(Config conf, String s) {
+ return getNgrams(s, param("ngramLen"), param("max"), param("maxPerToken"), param("minNgramLen"));
+ }
+
+ protected Collection getNgrams(String s, int ngramLen, int max, int maxPerToken, int minNgramLen) {
+
+ final Collection ngrams = sorted ? new TreeSet<>() : new LinkedHashSet();
+ final StringTokenizer st = new StringTokenizer(s);
+
+ while (st.hasMoreTokens()) {
+ final String token = st.nextToken();
+ if (!token.isEmpty()) {
+ for (int i = 0; i < maxPerToken && ngramLen + i <= token.length(); i++) {
+ String ngram = token.substring(i, Math.min(ngramLen + i, token.length())).trim();
+
+ if (ngram.length() >= minNgramLen) {
+ ngrams.add(ngram);
+
+ if (ngrams.size() >= max) {
+ return ngrams;
+ }
+ }
+ }
+ }
+ }
+ // System.out.println(ngrams + " n: " + ngrams.size());
+ return ngrams;
+ }
+
+}
diff --git a/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/NumAuthorsTitleSuffixPrefixChain.java b/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/NumAuthorsTitleSuffixPrefixChain.java
new file mode 100644
index 000000000..f1d1e17b9
--- /dev/null
+++ b/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/NumAuthorsTitleSuffixPrefixChain.java
@@ -0,0 +1,113 @@
+
+package eu.dnetlib.pace.clustering;
+
+import java.util.*;
+import java.util.stream.Collectors;
+import java.util.stream.StreamSupport;
+
+import com.google.common.base.Splitter;
+import com.google.common.collect.Sets;
+
+import eu.dnetlib.pace.config.Config;
+
+@ClusteringClass("numAuthorsTitleSuffixPrefixChain")
+public class NumAuthorsTitleSuffixPrefixChain extends AbstractClusteringFunction {
+
+ public NumAuthorsTitleSuffixPrefixChain(Map params) {
+ super(params);
+ }
+
+ @Override
+ public Collection apply(Config conf, List fields) {
+
+ try {
+ int num_authors = Math.min(Integer.parseInt(fields.get(0)), 21); // SIZE threshold is 20, +1
+
+ if (num_authors > 0) {
+ return super.apply(conf, fields.subList(1, fields.size()))
+ .stream()
+ .map(s -> num_authors + "-" + s)
+ .collect(Collectors.toList());
+ }
+ } catch (NumberFormatException e) {
+ // missing or null authors array
+ }
+
+ return Collections.emptyList();
+ }
+
+ @Override
+ protected Collection doApply(Config conf, String s) {
+ return suffixPrefixChain(cleanup(s), param("mod"));
+ }
+
+ private Collection suffixPrefixChain(String s, int mod) {
+ // create the list of words from the string (remove short words)
+ List wordsList = Arrays
+ .stream(s.split(" "))
+ .filter(si -> si.length() > 3)
+ .collect(Collectors.toList());
+
+ final int words = wordsList.size();
+ final int letters = s.length();
+
+ // create the prefix: number of words + number of letters/mod
+ String prefix = words / mod + "-";
+
+ return doSuffixPrefixChain(wordsList, prefix);
+
+ }
+
+ private Collection doSuffixPrefixChain(List wordsList, String prefix) {
+
+ Set set = Sets.newLinkedHashSet();
+ switch (wordsList.size()) {
+ case 0:
+ break;
+ case 1:
+ set.add(wordsList.get(0));
+ break;
+ case 2:
+ set
+ .add(
+ prefix +
+ suffix(wordsList.get(0), 3) +
+ prefix(wordsList.get(1), 3));
+
+ set
+ .add(
+ prefix +
+ prefix(wordsList.get(0), 3) +
+ suffix(wordsList.get(1), 3));
+
+ break;
+ default:
+ set
+ .add(
+ prefix +
+ suffix(wordsList.get(0), 3) +
+ prefix(wordsList.get(1), 3) +
+ suffix(wordsList.get(2), 3));
+
+ set
+ .add(
+ prefix +
+ prefix(wordsList.get(0), 3) +
+ suffix(wordsList.get(1), 3) +
+ prefix(wordsList.get(2), 3));
+ break;
+ }
+
+ return set;
+
+ }
+
+ private String suffix(String s, int len) {
+ return s.substring(s.length() - len);
+ }
+
+ private String prefix(String s, int len) {
+ return s.substring(0, len);
+ }
+
+}
diff --git a/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/PersonClustering.java b/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/PersonClustering.java
new file mode 100644
index 000000000..91b51bebb
--- /dev/null
+++ b/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/PersonClustering.java
@@ -0,0 +1,84 @@
+
+package eu.dnetlib.pace.clustering;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.lang3.StringUtils;
+
+import com.google.common.collect.Sets;
+
+import eu.dnetlib.pace.common.AbstractPaceFunctions;
+import eu.dnetlib.pace.config.Config;
+import eu.dnetlib.pace.model.Person;
+
+@ClusteringClass("personClustering")
+public class PersonClustering extends AbstractPaceFunctions implements ClusteringFunction {
+
+ private Map params;
+
+ private static final int MAX_TOKENS = 5;
+
+ public PersonClustering(final Map params) {
+ this.params = params;
+ }
+
+ @Override
+ public Collection apply(final Config conf, final List fields) {
+ final Set hashes = Sets.newHashSet();
+
+ for (final String f : fields) {
+
+ final Person person = new Person(f, false);
+
+ if (StringUtils.isNotBlank(person.getNormalisedFirstName())
+ && StringUtils.isNotBlank(person.getNormalisedSurname())) {
+ hashes.add(firstLC(person.getNormalisedFirstName()) + person.getNormalisedSurname().toLowerCase());
+ } else {
+ for (final String token1 : tokens(f, MAX_TOKENS)) {
+ for (final String token2 : tokens(f, MAX_TOKENS)) {
+ if (!token1.equals(token2)) {
+ hashes.add(firstLC(token1) + token2);
+ }
+ }
+ }
+ }
+ }
+
+ return hashes;
+ }
+
+// @Override
+// public Collection apply(final List fields) {
+// final Set hashes = Sets.newHashSet();
+//
+// for (final Field f : fields) {
+//
+// final GTAuthor gta = GTAuthor.fromOafJson(f.stringValue());
+//
+// final Author a = gta.getAuthor();
+//
+// if (StringUtils.isNotBlank(a.getFirstname()) && StringUtils.isNotBlank(a.getSecondnames())) {
+// hashes.add(firstLC(a.getFirstname()) + a.getSecondnames().toLowerCase());
+// } else {
+// for (final String token1 : tokens(f.stringValue(), MAX_TOKENS)) {
+// for (final String token2 : tokens(f.stringValue(), MAX_TOKENS)) {
+// if (!token1.equals(token2)) {
+// hashes.add(firstLC(token1) + token2);
+// }
+// }
+// }
+// }
+// }
+//
+// return hashes;
+// }
+
+ @Override
+ public Map getParams() {
+ return params;
+ }
+
+}
diff --git a/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/PersonHash.java b/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/PersonHash.java
new file mode 100644
index 000000000..09a112c37
--- /dev/null
+++ b/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/PersonHash.java
@@ -0,0 +1,34 @@
+
+package eu.dnetlib.pace.clustering;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import com.google.common.collect.Lists;
+
+import eu.dnetlib.pace.config.Config;
+import eu.dnetlib.pace.model.Person;
+
+@ClusteringClass("personHash")
+public class PersonHash extends AbstractClusteringFunction {
+
+ private boolean DEFAULT_AGGRESSIVE = false;
+
+ public PersonHash(final Map params) {
+ super(params);
+ }
+
+ @Override
+ protected Collection doApply(final Config conf, final String s) {
+ final List res = Lists.newArrayList();
+
+ final boolean aggressive = (Boolean) (getParams().containsKey("aggressive") ? getParams().get("aggressive")
+ : DEFAULT_AGGRESSIVE);
+
+ res.add(new Person(s, aggressive).hash());
+
+ return res;
+ }
+
+}
diff --git a/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/RandomClusteringFunction.java b/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/RandomClusteringFunction.java
new file mode 100644
index 000000000..3733dfc74
--- /dev/null
+++ b/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/RandomClusteringFunction.java
@@ -0,0 +1,20 @@
+
+package eu.dnetlib.pace.clustering;
+
+import java.util.Collection;
+import java.util.Map;
+
+import eu.dnetlib.pace.config.Config;
+
+public class RandomClusteringFunction extends AbstractClusteringFunction {
+
+ public RandomClusteringFunction(Map params) {
+ super(params);
+ }
+
+ @Override
+ protected Collection doApply(final Config conf, String s) {
+ return null;
+ }
+
+}
diff --git a/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/SortedNgramPairs.java b/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/SortedNgramPairs.java
new file mode 100644
index 000000000..ca1b4189b
--- /dev/null
+++ b/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/SortedNgramPairs.java
@@ -0,0 +1,34 @@
+
+package eu.dnetlib.pace.clustering;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import com.google.common.base.Joiner;
+import com.google.common.base.Splitter;
+import com.google.common.collect.Lists;
+
+import eu.dnetlib.pace.config.Config;
+
+@ClusteringClass("sortedngrampairs")
+public class SortedNgramPairs extends NgramPairs {
+
+ public SortedNgramPairs(Map params) {
+ super(params, false);
+ }
+
+ @Override
+ protected Collection doApply(Config conf, String s) {
+
+ final List tokens = Lists.newArrayList(Splitter.on(" ").omitEmptyStrings().trimResults().split(s));
+
+ Collections.sort(tokens);
+
+ return ngramPairs(
+ Lists.newArrayList(getNgrams(Joiner.on(" ").join(tokens), param("ngramLen"), param("max") * 2, 1, 2)),
+ param("max"));
+ }
+
+}
diff --git a/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/SpaceTrimmingFieldValue.java b/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/SpaceTrimmingFieldValue.java
new file mode 100644
index 000000000..048380f7e
--- /dev/null
+++ b/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/SpaceTrimmingFieldValue.java
@@ -0,0 +1,34 @@
+
+package eu.dnetlib.pace.clustering;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.commons.lang3.StringUtils;
+
+import com.google.common.collect.Lists;
+
+import eu.dnetlib.pace.config.Config;
+
+@ClusteringClass("spacetrimmingfieldvalue")
+public class SpaceTrimmingFieldValue extends AbstractClusteringFunction {
+
+ public SpaceTrimmingFieldValue(final Map params) {
+ super(params);
+ }
+
+ @Override
+ protected Collection doApply(final Config conf, final String s) {
+ final List res = Lists.newArrayList();
+
+ res
+ .add(
+ StringUtils.isBlank(s) ? RandomStringUtils.random(param("randomLength"))
+ : s.toLowerCase().replaceAll("\\s+", ""));
+
+ return res;
+ }
+
+}
diff --git a/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/SuffixPrefix.java b/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/SuffixPrefix.java
new file mode 100644
index 000000000..b6921e9f1
--- /dev/null
+++ b/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/SuffixPrefix.java
@@ -0,0 +1,42 @@
+
+package eu.dnetlib.pace.clustering;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+
+import com.google.common.collect.Sets;
+
+import eu.dnetlib.pace.config.Config;
+
+@ClusteringClass("suffixprefix")
+public class SuffixPrefix extends AbstractClusteringFunction {
+
+ public SuffixPrefix(Map params) {
+ super(params);
+ }
+
+ @Override
+ protected Collection doApply(Config conf, String s) {
+ return suffixPrefix(s, param("len"), param("max"));
+ }
+
+ private Collection suffixPrefix(String s, int len, int max) {
+ final Set bigrams = Sets.newLinkedHashSet();
+ int i = 0;
+ while (++i < s.length() && bigrams.size() < max) {
+ int j = s.indexOf(" ", i);
+
+ int offset = j + len + 1 < s.length() ? j + len + 1 : s.length();
+
+ if (j - len > 0) {
+ String bigram = s.substring(j - len, offset).replaceAll(" ", "").trim();
+ if (bigram.length() >= 4) {
+ bigrams.add(bigram);
+ }
+ }
+ }
+ return bigrams;
+ }
+
+}
diff --git a/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/UrlClustering.java b/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/UrlClustering.java
new file mode 100644
index 000000000..34f41085b
--- /dev/null
+++ b/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/UrlClustering.java
@@ -0,0 +1,52 @@
+
+package eu.dnetlib.pace.clustering;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import eu.dnetlib.pace.common.AbstractPaceFunctions;
+import eu.dnetlib.pace.config.Config;
+
+@ClusteringClass("urlclustering")
+public class UrlClustering extends AbstractPaceFunctions implements ClusteringFunction {
+
+ protected Map params;
+
+ public UrlClustering(final Map params) {
+ this.params = params;
+ }
+
+ @Override
+ public Map getParams() {
+ return params;
+ }
+
+ @Override
+ public Collection apply(final Config conf, List fields) {
+ try {
+ return fields
+ .stream()
+ .filter(f -> !f.isEmpty())
+ .map(this::asUrl)
+ .map(URL::getHost)
+ .collect(Collectors.toCollection(HashSet::new));
+ } catch (IllegalStateException e) {
+ return new HashSet<>();
+ }
+ }
+
+ private URL asUrl(String value) {
+ try {
+ return new URL(value);
+ } catch (MalformedURLException e) {
+ // should not happen as checked by pace typing
+ throw new IllegalStateException("invalid URL: " + value);
+ }
+ }
+
+}
diff --git a/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/WordsStatsSuffixPrefixChain.java b/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/WordsStatsSuffixPrefixChain.java
new file mode 100644
index 000000000..22351cf8f
--- /dev/null
+++ b/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/WordsStatsSuffixPrefixChain.java
@@ -0,0 +1,91 @@
+
+package eu.dnetlib.pace.clustering;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+import com.google.common.collect.Sets;
+
+import eu.dnetlib.pace.config.Config;
+
+@ClusteringClass("wordsStatsSuffixPrefixChain")
+public class WordsStatsSuffixPrefixChain extends AbstractClusteringFunction {
+
+ public WordsStatsSuffixPrefixChain(Map params) {
+ super(params);
+ }
+
+ @Override
+ protected Collection doApply(Config conf, String s) {
+ return suffixPrefixChain(s, param("mod"));
+ }
+
+ private Collection suffixPrefixChain(String s, int mod) {
+
+ // create the list of words from the string (remove short words)
+ List wordsList = Arrays
+ .stream(s.split(" "))
+ .filter(si -> si.length() > 3)
+ .collect(Collectors.toList());
+
+ final int words = wordsList.size();
+ final int letters = s.length();
+
+ // create the prefix: number of words + number of letters/mod
+ String prefix = words + "-" + letters / mod + "-";
+
+ return doSuffixPrefixChain(wordsList, prefix);
+
+ }
+
+ private Collection doSuffixPrefixChain(List wordsList, String prefix) {
+
+ Set set = Sets.newLinkedHashSet();
+ switch (wordsList.size()) {
+ case 0:
+ case 1:
+ break;
+ case 2:
+ set
+ .add(
+ prefix +
+ suffix(wordsList.get(0), 3) +
+ prefix(wordsList.get(1), 3));
+
+ set
+ .add(
+ prefix +
+ prefix(wordsList.get(0), 3) +
+ suffix(wordsList.get(1), 3));
+
+ break;
+ default:
+ set
+ .add(
+ prefix +
+ suffix(wordsList.get(0), 3) +
+ prefix(wordsList.get(1), 3) +
+ suffix(wordsList.get(2), 3));
+
+ set
+ .add(
+ prefix +
+ prefix(wordsList.get(0), 3) +
+ suffix(wordsList.get(1), 3) +
+ prefix(wordsList.get(2), 3));
+ break;
+ }
+
+ return set;
+
+ }
+
+ private String suffix(String s, int len) {
+ return s.substring(s.length() - len);
+ }
+
+ private String prefix(String s, int len) {
+ return s.substring(0, len);
+ }
+
+}
diff --git a/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/WordsSuffixPrefix.java b/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/WordsSuffixPrefix.java
new file mode 100644
index 000000000..f9fef376b
--- /dev/null
+++ b/dhp-pace-core/src/main/java/eu/dnetlib/pace/clustering/WordsSuffixPrefix.java
@@ -0,0 +1,59 @@
+
+package eu.dnetlib.pace.clustering;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+
+import com.google.common.collect.Sets;
+
+import eu.dnetlib.pace.config.Config;
+
+@ClusteringClass("wordssuffixprefix")
+public class WordsSuffixPrefix extends AbstractClusteringFunction {
+
+ public WordsSuffixPrefix(Map params) {
+ super(params);
+ }
+
+ @Override
+ protected Collection doApply(Config conf, String s) {
+ return suffixPrefix(s, param("len"), param("max"));
+ }
+
+ private Collection suffixPrefix(String s, int len, int max) {
+
+ final int words = s.split(" ").length;
+
+ // adjust the token length according to the number of words
+ switch (words) {
+ case 1:
+ return Sets.newLinkedHashSet();
+ case 2:
+ return doSuffixPrefix(s, len + 2, max, words);
+ case 3:
+ return doSuffixPrefix(s, len + 1, max, words);
+ default:
+ return doSuffixPrefix(s, len, max, words);
+ }
+ }
+
+ private Collection doSuffixPrefix(String s, int len, int max, int words) {
+ final Set bigrams = Sets.newLinkedHashSet();
+ int i = 0;
+ while (++i < s.length() && bigrams.size() < max) {
+ int j = s.indexOf(" ", i);
+
+ int offset = j + len + 1 < s.length() ? j + len + 1 : s.length();
+
+ if (j - len > 0) {
+ String bigram = s.substring(j - len, offset).replaceAll(" ", "").trim();
+ if (bigram.length() >= 4) {
+ bigrams.add(words + bigram);
+ }
+ }
+ }
+ return bigrams;
+ }
+
+}
diff --git a/dhp-pace-core/src/main/java/eu/dnetlib/pace/common/AbstractPaceFunctions.java b/dhp-pace-core/src/main/java/eu/dnetlib/pace/common/AbstractPaceFunctions.java
new file mode 100644
index 000000000..ba7639ada
--- /dev/null
+++ b/dhp-pace-core/src/main/java/eu/dnetlib/pace/common/AbstractPaceFunctions.java
@@ -0,0 +1,359 @@
+
+package eu.dnetlib.pace.common;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.nio.charset.StandardCharsets;
+import java.text.Normalizer;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+
+import com.google.common.base.Joiner;
+import com.google.common.base.Splitter;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Sets;
+import com.ibm.icu.text.Transliterator;
+
+import eu.dnetlib.pace.clustering.NGramUtils;
+
+/**
+ * Set of common functions for the framework
+ *
+ * @author claudio
+ */
+public class AbstractPaceFunctions {
+
+ // city map to be used when translating the city names into codes
+ private static Map cityMap = AbstractPaceFunctions
+ .loadMapFromClasspath("/eu/dnetlib/pace/config/city_map.csv");
+
+ // list of stopwords in different languages
+ protected static Set stopwords_gr = loadFromClasspath("/eu/dnetlib/pace/config/stopwords_gr.txt");
+ protected static Set stopwords_en = loadFromClasspath("/eu/dnetlib/pace/config/stopwords_en.txt");
+ protected static Set stopwords_de = loadFromClasspath("/eu/dnetlib/pace/config/stopwords_de.txt");
+ protected static Set stopwords_es = loadFromClasspath("/eu/dnetlib/pace/config/stopwords_es.txt");
+ protected static Set stopwords_fr = loadFromClasspath("/eu/dnetlib/pace/config/stopwords_fr.txt");
+ protected static Set stopwords_it = loadFromClasspath("/eu/dnetlib/pace/config/stopwords_it.txt");
+ protected static Set stopwords_pt = loadFromClasspath("/eu/dnetlib/pace/config/stopwords_pt.txt");
+
+ // transliterator
+ protected static Transliterator transliterator = Transliterator.getInstance("Any-Eng");
+
+ // blacklist of ngrams: to avoid generic keys
+ protected static Set ngramBlacklist = loadFromClasspath("/eu/dnetlib/pace/config/ngram_blacklist.txt");
+
+ // html regex for normalization
+ public static final Pattern HTML_REGEX = Pattern.compile("<[^>]*>");
+
+ private static final String alpha = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ";
+ private static final String aliases_from = "⁰¹²³⁴⁵⁶⁷⁸⁹⁺⁻⁼⁽⁾ⁿ₀₁₂₃₄₅₆₇₈₉₊₋₌₍₎àáâäæãåāèéêëēėęəîïíīįìôöòóœøōõûüùúūßśšłžźżçćčñń";
+ private static final String aliases_to = "0123456789+-=()n0123456789+-=()aaaaaaaaeeeeeeeeiiiiiioooooooouuuuussslzzzcccnn";
+
+ // doi prefix for normalization
+ public static final Pattern DOI_PREFIX = Pattern.compile("(https?:\\/\\/dx\\.doi\\.org\\/)|(doi:)");
+
+ private static Pattern numberPattern = Pattern.compile("-?\\d+(\\.\\d+)?");
+
+ private static Pattern hexUnicodePattern = Pattern.compile("\\\\u(\\p{XDigit}{4})");
+
+ private static Pattern romanNumberPattern = Pattern
+ .compile("^M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$");
+
+ protected static String concat(final List l) {
+ return Joiner.on(" ").skipNulls().join(l);
+ }
+
+ public static String cleanup(final String s) {
+ final String s1 = HTML_REGEX.matcher(s).replaceAll("");
+ final String s2 = unicodeNormalization(s1.toLowerCase());
+ final String s3 = nfd(s2);
+ final String s4 = fixXML(s3);
+ final String s5 = s4.replaceAll("([0-9]+)", " $1 ");
+ final String s6 = transliterate(s5);
+ final String s7 = fixAliases(s6);
+ final String s8 = s7.replaceAll("[^\\p{ASCII}]", "");
+ final String s9 = s8.replaceAll("[\\p{Punct}]", " ");
+ final String s10 = s9.replaceAll("\\n", " ");
+ final String s11 = s10.replaceAll("(?m)\\s+", " ");
+ final String s12 = s11.trim();
+ return s12;
+ }
+
+ protected static String fixXML(final String a) {
+
+ return a
+ .replaceAll("–", " ")
+ .replaceAll("&", " ")
+ .replaceAll(""", " ")
+ .replaceAll("−", " ");
+ }
+
+ protected static boolean checkNumbers(final String a, final String b) {
+ final String numbersA = getNumbers(a);
+ final String numbersB = getNumbers(b);
+ final String romansA = getRomans(a);
+ final String romansB = getRomans(b);
+ return !numbersA.equals(numbersB) || !romansA.equals(romansB);
+ }
+
+ protected static String getRomans(final String s) {
+ final StringBuilder sb = new StringBuilder();
+ for (final String t : s.split(" ")) {
+ sb.append(isRoman(t) ? t : "");
+ }
+ return sb.toString();
+ }
+
+ protected static boolean isRoman(final String s) {
+ Matcher m = romanNumberPattern.matcher(s);
+ return m.matches() && m.hitEnd();
+ }
+
+ protected static String getNumbers(final String s) {
+ final StringBuilder sb = new StringBuilder();
+ for (final String t : s.split(" ")) {
+ sb.append(isNumber(t) ? t : "");
+ }
+ return sb.toString();
+ }
+
+ public static boolean isNumber(String strNum) {
+ if (strNum == null) {
+ return false;
+ }
+ return numberPattern.matcher(strNum).matches();
+ }
+
+ protected static String fixAliases(final String s) {
+ final StringBuilder sb = new StringBuilder();
+
+ s.chars().forEach(ch -> {
+ final int i = StringUtils.indexOf(aliases_from, ch);
+ sb.append(i >= 0 ? aliases_to.charAt(i) : (char) ch);
+ });
+
+ return sb.toString();
+ }
+
+ protected static String transliterate(final String s) {
+ try {
+ return transliterator.transliterate(s);
+ } catch (Exception e) {
+ return s;
+ }
+ }
+
+ protected static String removeSymbols(final String s) {
+ final StringBuilder sb = new StringBuilder();
+
+ s.chars().forEach(ch -> {
+ sb.append(StringUtils.contains(alpha, ch) ? (char) ch : ' ');
+ });
+
+ return sb.toString().replaceAll("\\s+", " ");
+ }
+
+ protected static boolean notNull(final String s) {
+ return s != null;
+ }
+
+ public static String normalize(final String s) {
+ return fixAliases(transliterate(nfd(unicodeNormalization(s))))
+ .toLowerCase()
+ // do not compact the regexes in a single expression, would cause StackOverflowError in case of large input
+ // strings
+ .replaceAll("[^ \\w]+", "")
+ .replaceAll("(\\p{InCombiningDiacriticalMarks})+", "")
+ .replaceAll("(\\p{Punct})+", " ")
+ .replaceAll("(\\d)+", " ")
+ .replaceAll("(\\n)+", " ")
+ .trim();
+ }
+
+ public static String nfd(final String s) {
+ return Normalizer.normalize(s, Normalizer.Form.NFD);
+ }
+
+ public static String utf8(final String s) {
+ byte[] bytes = s.getBytes(StandardCharsets.UTF_8);
+ return new String(bytes, StandardCharsets.UTF_8);
+ }
+
+ public static String unicodeNormalization(final String s) {
+
+ Matcher m = hexUnicodePattern.matcher(s);
+ StringBuffer buf = new StringBuffer(s.length());
+ while (m.find()) {
+ String ch = String.valueOf((char) Integer.parseInt(m.group(1), 16));
+ m.appendReplacement(buf, Matcher.quoteReplacement(ch));
+ }
+ m.appendTail(buf);
+ return buf.toString();
+ }
+
+ protected static String filterStopWords(final String s, final Set stopwords) {
+ final StringTokenizer st = new StringTokenizer(s);
+ final StringBuilder sb = new StringBuilder();
+ while (st.hasMoreTokens()) {
+ final String token = st.nextToken();
+ if (!stopwords.contains(token)) {
+ sb.append(token);
+ sb.append(" ");
+ }
+ }
+ return sb.toString().trim();
+ }
+
+ public static String filterAllStopWords(String s) {
+
+ s = filterStopWords(s, stopwords_en);
+ s = filterStopWords(s, stopwords_de);
+ s = filterStopWords(s, stopwords_it);
+ s = filterStopWords(s, stopwords_fr);
+ s = filterStopWords(s, stopwords_pt);
+ s = filterStopWords(s, stopwords_es);
+ s = filterStopWords(s, stopwords_gr);
+
+ return s;
+ }
+
+ protected static Collection filterBlacklisted(final Collection set,
+ final Set ngramBlacklist) {
+ final Set newset = Sets.newLinkedHashSet();
+ for (final String s : set) {
+ if (!ngramBlacklist.contains(s)) {
+ newset.add(s);
+ }
+ }
+ return newset;
+ }
+
+ public static Set loadFromClasspath(final String classpath) {
+
+ Transliterator transliterator = Transliterator.getInstance("Any-Eng");
+
+ final Set h = Sets.newHashSet();
+ try {
+ for (final String s : IOUtils
+ .readLines(NGramUtils.class.getResourceAsStream(classpath), StandardCharsets.UTF_8)) {
+ h.add(fixAliases(transliterator.transliterate(s))); // transliteration of the stopwords
+ }
+ } catch (final Throwable e) {
+ return Sets.newHashSet();
+ }
+ return h;
+ }
+
+ public static Map loadMapFromClasspath(final String classpath) {
+
+ Transliterator transliterator = Transliterator.getInstance("Any-Eng");
+
+ final Map m = new HashMap<>();
+ try {
+ for (final String s : IOUtils
+ .readLines(AbstractPaceFunctions.class.getResourceAsStream(classpath), StandardCharsets.UTF_8)) {
+ // string is like this: code;word1;word2;word3
+ String[] line = s.split(";");
+ String value = line[0];
+ for (int i = 1; i < line.length; i++) {
+ m.put(fixAliases(transliterator.transliterate(line[i].toLowerCase())), value);
+ }
+ }
+ } catch (final Throwable e) {
+ return new HashMap<>();
+ }
+ return m;
+ }
+
+ public static String removeKeywords(String s, Set keywords) {
+
+ s = " " + s + " ";
+ for (String k : keywords) {
+ s = s.replaceAll(k.toLowerCase(), "");
+ }
+
+ return s.trim();
+ }
+
+ public static double commonElementsPercentage(Set s1, Set s2) {
+
+ double longer = Math.max(s1.size(), s2.size());
+ return (double) s1.stream().filter(s2::contains).count() / longer;
+ }
+
+ // convert the set of keywords to codes
+ public static Set toCodes(Set keywords, Map translationMap) {
+ return keywords.stream().map(s -> translationMap.get(s)).collect(Collectors.toSet());
+ }
+
+ public static Set keywordsToCodes(Set keywords, Map translationMap) {
+ return toCodes(keywords, translationMap);
+ }
+
+ public static Set citiesToCodes(Set keywords) {
+ return toCodes(keywords, cityMap);
+ }
+
+ protected static String firstLC(final String s) {
+ return StringUtils.substring(s, 0, 1).toLowerCase();
+ }
+
+ protected static Iterable tokens(final String s, final int maxTokens) {
+ return Iterables.limit(Splitter.on(" ").omitEmptyStrings().trimResults().split(s), maxTokens);
+ }
+
+ public static String normalizePid(String pid) {
+ return DOI_PREFIX.matcher(pid.toLowerCase()).replaceAll("");
+ }
+
+ // get the list of keywords into the input string
+ public static Set getKeywords(String s1, Map translationMap, int windowSize) {
+
+ String s = s1;
+
+ List tokens = Arrays.asList(s.toLowerCase().split(" "));
+
+ Set codes = new HashSet<>();
+
+ if (tokens.size() < windowSize)
+ windowSize = tokens.size();
+
+ int length = windowSize;
+
+ while (length != 0) {
+
+ for (int i = 0; i <= tokens.size() - length; i++) {
+ String candidate = concat(tokens.subList(i, i + length));
+ if (translationMap.containsKey(candidate)) {
+ codes.add(candidate);
+ s = s.replace(candidate, "").trim();
+ }
+ }
+
+ tokens = Arrays.asList(s.split(" "));
+ length -= 1;
+ }
+
+ return codes;
+ }
+
+ public static Set getCities(String s1, int windowSize) {
+ return getKeywords(s1, cityMap, windowSize);
+ }
+
+ public static String readFromClasspath(final String filename, final Class clazz) {
+ final StringWriter sw = new StringWriter();
+ try {
+ IOUtils.copy(clazz.getResourceAsStream(filename), sw, StandardCharsets.UTF_8);
+ return sw.toString();
+ } catch (final IOException e) {
+ throw new RuntimeException("cannot load resource from classpath: " + filename);
+ }
+ }
+
+}
diff --git a/dhp-pace-core/src/main/java/eu/dnetlib/pace/config/Config.java b/dhp-pace-core/src/main/java/eu/dnetlib/pace/config/Config.java
new file mode 100644
index 000000000..4d823d129
--- /dev/null
+++ b/dhp-pace-core/src/main/java/eu/dnetlib/pace/config/Config.java
@@ -0,0 +1,53 @@
+
+package eu.dnetlib.pace.config;
+
+import java.util.List;
+import java.util.Map;
+import java.util.function.Predicate;
+
+import eu.dnetlib.pace.model.ClusteringDef;
+import eu.dnetlib.pace.model.FieldDef;
+import eu.dnetlib.pace.tree.support.TreeNodeDef;
+
+/**
+ * Interface for PACE configuration bean.
+ *
+ * @author claudio
+ */
+public interface Config {
+
+ /**
+ * Field configuration definitions.
+ *
+ * @return the list of definitions
+ */
+ public List model();
+
+ /**
+ * Decision Tree definition
+ *
+ * @return the map representing the decision tree
+ */
+ public Map decisionTree();
+
+ /**
+ * Clusterings.
+ *
+ * @return the list
+ */
+ public List clusterings();
+
+ /**
+ * Blacklists.
+ *
+ * @return the map
+ */
+ public Map> blacklists();
+
+ /**
+ * Translation map.
+ *
+ * @return the map
+ * */
+ public Map translationMap();
+}
diff --git a/dhp-pace-core/src/main/java/eu/dnetlib/pace/config/DedupConfig.java b/dhp-pace-core/src/main/java/eu/dnetlib/pace/config/DedupConfig.java
new file mode 100644
index 000000000..ac0ef08e4
--- /dev/null
+++ b/dhp-pace-core/src/main/java/eu/dnetlib/pace/config/DedupConfig.java
@@ -0,0 +1,178 @@
+
+package eu.dnetlib.pace.config;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.nio.charset.StandardCharsets;
+import java.util.AbstractMap;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.function.Predicate;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+import java.util.stream.Collectors;
+
+import org.antlr.stringtemplate.StringTemplate;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.collect.Maps;
+
+import eu.dnetlib.pace.model.ClusteringDef;
+import eu.dnetlib.pace.model.FieldDef;
+import eu.dnetlib.pace.tree.support.TreeNodeDef;
+import eu.dnetlib.pace.util.PaceException;
+
+public class DedupConfig implements Config, Serializable {
+ private static String CONFIG_TEMPLATE = "dedupConfig.st";
+
+ private PaceConfig pace;
+
+ private WfConfig wf;
+
+ @JsonIgnore
+ private Map> blacklists;
+
+ private static Map defaults = Maps.newHashMap();
+
+ static {
+ defaults.put("dedupRun", "001");
+ defaults.put("entityType", "result");
+ defaults.put("subEntityType", "resulttype");
+ defaults.put("subEntityValue", "publication");
+ defaults.put("orderField", "title");
+ defaults.put("queueMaxSize", "2000");
+ defaults.put("groupMaxSize", "10");
+ defaults.put("slidingWindowSize", "200");
+ defaults.put("rootBuilder", "result");
+ defaults.put("includeChildren", "true");
+ defaults.put("maxIterations", "20");
+ defaults.put("idPath", "$.id");
+ }
+
+ public DedupConfig() {
+ }
+
+ public static DedupConfig load(final String json) {
+
+ final DedupConfig config;
+ try {
+ config = new ObjectMapper().readValue(json, DedupConfig.class);
+ config.getPace().initModel();
+ config.getPace().initTranslationMap();
+
+ config.blacklists = config
+ .getPace()
+ .getBlacklists()
+ .entrySet()
+ .stream()
+ .map(
+ e -> new AbstractMap.SimpleEntry>(e.getKey(),
+ e
+ .getValue()
+ .stream()
+ .filter(s -> !StringUtils.isBlank(s))
+ .map(Pattern::compile)
+ .collect(Collectors.toList())))
+ .collect(
+ Collectors
+ .toMap(
+ e -> e.getKey(),
+ e -> (Predicate & Serializable) s -> e
+ .getValue()
+ .stream()
+ .filter(p -> p.matcher(s).matches())
+ .findFirst()
+ .isPresent()))
+
+ ;
+
+ return config;
+ } catch (IOException | PatternSyntaxException e) {
+ throw new PaceException("Error in parsing configuration json", e);
+ }
+
+ }
+
+ public static DedupConfig loadDefault() throws IOException {
+ return loadDefault(new HashMap());
+ }
+
+ public static DedupConfig loadDefault(final Map params) throws IOException {
+
+ final StringTemplate template = new StringTemplate(new DedupConfig().readFromClasspath(CONFIG_TEMPLATE));
+
+ for (final Entry e : defaults.entrySet()) {
+ template.setAttribute(e.getKey(), e.getValue());
+ }
+ for (final Entry e : params.entrySet()) {
+ if (template.getAttribute(e.getKey()) != null) {
+ template.getAttributes().computeIfPresent(e.getKey(), (o, o2) -> e.getValue());
+ } else {
+ template.setAttribute(e.getKey(), e.getValue());
+ }
+ }
+
+ final String json = template.toString();
+ return load(json);
+ }
+
+ private String readFromClasspath(final String resource) throws IOException {
+ return IOUtils.toString(getClass().getResource(resource), StandardCharsets.UTF_8);
+ }
+
+ public PaceConfig getPace() {
+ return pace;
+ }
+
+ public void setPace(final PaceConfig pace) {
+ this.pace = pace;
+ }
+
+ public WfConfig getWf() {
+ return wf;
+ }
+
+ public void setWf(final WfConfig wf) {
+ this.wf = wf;
+ }
+
+ @Override
+ public String toString() {
+ try {
+ return new ObjectMapper().writeValueAsString(this);
+ } catch (IOException e) {
+ throw new PaceException("unable to serialise configuration", e);
+ }
+ }
+
+ @Override
+ public Map decisionTree() {
+ return getPace().getDecisionTree();
+ }
+
+ @Override
+ public List model() {
+ return getPace().getModel();
+ }
+
+ @Override
+ public List clusterings() {
+ return getPace().getClustering();
+ }
+
+ @Override
+ public Map> blacklists() {
+ return blacklists;
+ }
+
+ @Override
+ public Map translationMap() {
+ return getPace().translationMap();
+ }
+
+}
diff --git a/dhp-pace-core/src/main/java/eu/dnetlib/pace/config/PaceConfig.java b/dhp-pace-core/src/main/java/eu/dnetlib/pace/config/PaceConfig.java
new file mode 100644
index 000000000..f1bc49f4a
--- /dev/null
+++ b/dhp-pace-core/src/main/java/eu/dnetlib/pace/config/PaceConfig.java
@@ -0,0 +1,108 @@
+
+package eu.dnetlib.pace.config;
+
+import java.io.Serializable;
+import java.util.List;
+import java.util.Map;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.google.common.collect.Maps;
+import com.ibm.icu.text.Transliterator;
+
+import eu.dnetlib.pace.common.AbstractPaceFunctions;
+import eu.dnetlib.pace.model.ClusteringDef;
+import eu.dnetlib.pace.model.FieldDef;
+import eu.dnetlib.pace.tree.support.TreeNodeDef;
+import eu.dnetlib.pace.util.PaceResolver;
+
+public class PaceConfig extends AbstractPaceFunctions implements Serializable {
+
+ private List model;
+
+ private List clustering;
+ private Map decisionTree;
+
+ private Map> blacklists;
+ private Map> synonyms;
+
+ @JsonIgnore
+ private Map translationMap;
+
+ public Map getModelMap() {
+ return modelMap;
+ }
+
+ @JsonIgnore
+ private Map modelMap;
+
+ @JsonIgnore
+ public static PaceResolver resolver = new PaceResolver();
+
+ public PaceConfig() {
+ }
+
+ public void initModel() {
+ modelMap = Maps.newHashMap();
+ for (FieldDef fd : getModel()) {
+ modelMap.put(fd.getName(), fd);
+ }
+ }
+
+ public void initTranslationMap() {
+ translationMap = Maps.newHashMap();
+
+ Transliterator transliterator = Transliterator.getInstance("Any-Eng");
+ for (String key : synonyms.keySet()) {
+ for (String term : synonyms.get(key)) {
+ translationMap
+ .put(
+ fixAliases(transliterator.transliterate(term.toLowerCase())),
+ key);
+ }
+ }
+ }
+
+ public Map translationMap() {
+ return translationMap;
+ }
+
+ public List getModel() {
+ return model;
+ }
+
+ public void setModel(final List model) {
+ this.model = model;
+ }
+
+ public List getClustering() {
+ return clustering;
+ }
+
+ public void setClustering(final List clustering) {
+ this.clustering = clustering;
+ }
+
+ public Map getDecisionTree() {
+ return decisionTree;
+ }
+
+ public void setDecisionTree(Map decisionTree) {
+ this.decisionTree = decisionTree;
+ }
+
+ public Map