EU-ADR

From BioAssist
Jump to: navigation, search

Description

The EU-ADR project aims to develop an innovative computerized system to detect adverse drug reactions (ADRs), supplementing spontaneous reporting systems. To achieve this objective, EU-ADR will exploit clinical data from electronic healthcare records (EHRs) of over 30 million patients from several European countries (The Netherlands, Denmark, United Kingdom, and Italy)[1].

This page describes the WebServices, which are developed in Erasmus MC. The list of all services can be downloaded here.

Modules

ATCCodes Historical Information

Given 
the 
ATC
 code,
 return
 historical 
information
 on 
the code
 (previous 
codes,
 deletions,
 insertions)
. This
 webservice
 uses
 a 
database 
with
 historical
 information 
on the 
ATC 
codes 
and 
will 
return 
a
 list 
of 
actions
 performed
 on 
the
 ATC 
code.
 


Storage Service

The goal of this WebService is to hide the implementation of the storage under the object-oriented interface. This allows storage to be implemented in different ways (e.g. the data can be stored in RDF storage or in plain SQL tables).

Input data

  • EU-ADR ontology is loaded into store as "concepts". Each concept has an ID (like http://www.nbic.nl/cwa/db/emc#138) and also have the associated list of IDs in other databases (like UMLS, ATC, ...)
  • The co-occurrences of concepts are mined from Drugbank and DailyMed data by Peregrine and are dumped into XML files. The co-occurrences are loaded from XML files as relations of concepts.

Architecture

This WebService runs on top of an store and provides a number of specialised queries to the store. The following API is provided via WebService:

/**
 * The general interface for storage.
 * 
 * Note: For <code>null</code> collection elements in passed domain objects the behaviour is not specified. The store
 * may ignore this value or throw {@link NullPointerException}.
 */
@WebService(name = "", targetNamespace = "http://biosemantic.erasmusmc.org/")
public interface StorageService {

	/**
	 * Adds a concept to a store.
	 * 
	 * @throws StorageServiceIntegrityViolationException
	 *             if such relationship already exists
	 * @throws StorageServiceException
	 *             any other underlying storage problem
	 */
	@WebMethod
	void addConcept(@WebParam(name = "concept") Concept concept) throws StorageServiceIntegrityViolationException,
			StorageServiceException;

	/**
	 * Adds a new relationship to a store.
	 * 
	 * @throws StorageServiceIntegrityViolationException
	 *             if such relationship already exists
	 * @throws StorageServiceException
	 *             any other underlying storage problem
	 */
	@WebMethod
	void addRelation(@WebParam(name = "relationship") Relationship relationship)
			throws StorageServiceIntegrityViolationException, StorageServiceException;

	/**
	 * Returns a concept by its ID or <code>null</code> if no such concept was found.
	 */
	@WebMethod
	Concept getConcept(@WebParam(name = "id") DatabaseId id) throws StorageServiceException;

	/**
	 * Returns relationships between {@link #sourceConceptId} and {@link #targetConceptId}, if any found or
	 * <code>null</code>, if not a single relation was found.
	 * 
	 * Note: either {@link #sourceId} or {@link #targetId} can be <code>null</code>, but not both.
	 * 
	 * @param sourceId
	 *            the source ID; <code>null</code> if relation with any source should match
	 * @param targetId
	 *            the target ID; <code>null</code> if relation with any target should match
	 * @param informationSourceFilter
	 *            the filter for relation information sources; <code>null</code> if no filtering is required
	 * @param maxResults
	 *            the maximum number of results to return; zero means "no limit"
	 * 
	 * @see org.erasmusmc.service.euadr_storage.common.RelationshipHelper#filterRelationInformationSources(Relationship,
	 *      EvidenceType)
	 */
	@WebMethod
	Collection<Relationship> getRelations(@WebParam(name = "sourceId") DatabaseId sourceId,
			@WebParam(name = "targetId") DatabaseId targetId,
			@WebParam(name = "informationSourceFilter") EvidenceType informationSourceFilter,
			@WebParam(name = "maxResults") int maxResults) throws StorageServiceException;

	/**
	 * Returns the number of objects in the storage.
	 */
	@WebMethod
	long getStorageSize() throws StorageServiceException;
}

This interface allows:

  • To query concepts directly by the concept ID (which is URI):
  • To query the relationships between concepts, for example:
  • To query a direct relationship between two concepts with internal IDs 4500388 and 72496:
SELECT SOURCE, TARGET, CREATOR, OBSERVATION_DATE_TIME, INFORMATION_SOURCES_LIST
FROM
{ID} rdf:type {cwa:Relation};
cwa:Relation/source {SOURCE};
cwa:Relation/target {TARGET};
cwa:Relation/creator {CREATOR};
cwa:Relation/observationDateTime {OBSERVATION_DATE_TIME};
cwa:Relation/informationSourcesList {INFORMATION_SOURCES_LIST} 
WHERE SOURCE = cwa:DatabaseId/EMC#4500388 and TARGET = cwa:DatabaseId/EMC#72496 
USING NAMESPACE
    rdf = <http://www.w3.org/1999/02/22-rdf-syntax-ns#>,
    cwa = <http://www.nbic.nl/cwa/>
  • To query, if there is a side effect "anaphylactic shock" (AS) for the drug "Pantoprazole" having ATC code A02BC02:
SELECT DISTINCT SOURCE, TARGET, CREATOR, OBSERVATION_DATE_TIME, INFORMATION_SOURCES_LIST
FROM {} rdf:type {cwa:Relation};
cwa:Relation/source {SOURCE};
cwa:Relation/target {TARGET};
cwa:Relation/creator {CREATOR};
cwa:Relation/observationDateTime {OBSERVATION_DATE_TIME};
cwa:Relation/informationSourcesList {INFORMATION_SOURCES_LIST},
[{SCN_URL} rdf:type {cwa:Concept};
  cwa:Concept/databaseIdsList {} rdfs:#member {SLN},
  {SLN} rdf:type {cwa:DatabaseId};
  cwa:DatabaseId/url {SLN_URL}],
[{TCN_URL} rdf:type {cwa:Concept};
  cwa:Concept/databaseIdsList {} rdfs:#member {TLN},
  {TLN} rdf:type {cwa:DatabaseId};
  cwa:DatabaseId/url {TLN_URL}]
WHERE 
(SOURCE = SOURCE_URL or (SLN_URL = SOURCE_URL and SCN_URL = SOURCE))
and
(TARGET = TARGET_URL or (TLN_URL = TARGET_URL and TCN_URL = TARGET))
and SOURCE_URL = <http://www.nbic.nl/cwa/DatabaseId/EUADR_EVENT#AS>
and TARGET_URL = <http://www.nbic.nl/cwa/DatabaseId/ATC#A02BC02>
USING NAMESPACE
  rdfs = <http://www.w3.org/2000/01/rdf-schema#>,
  rdf = <http://www.w3.org/1999/02/22-rdf-syntax-ns#>,
  cwa = <http://www.nbic.nl/cwa/>

In this case the following graph of nodes should be process to find the solution:

Euadr Storage Architecture.gif

The corresponding SQL query is:

select {r.*}
from relationship as r, concept_database_id as ds, concept_database_id as dt
where
	ds.parentId = r.sourceConceptDbId and ds.source = 1 and ds.code = 'A03BA01'
	and
	dt.parentId = r.targetConceptDbId and dt.source = 11 and dt.code = 'ARF'

Additionally there is an extended interface, which can only be accessed directly, which simplifies the import (as provides bulk-insert functionality) and unit-testing.

The model of EU-ADR project WebServices starts from XSD model, which defines the basic datatypes to be exchanged between WebServices.

EU-ADR XSD Schema
Taverna Workflow Run Sample

EU-ADR Storage Service is based on the following technologies/tools:

  • It is a maven project. It depends on local Nexus maven repository, which contains shared artefacts and releases.
  • common subproject produces both compile-time and test artefacts, which are shared.
  • Project uses JAXB technology to generate beans and JAX-WS RI capability to generate WSDL on the fly.
  • service-db subproject shows how Spring+Hibernate+JAX-WS-Spring can be bound together.
  • JUnit4 annotation-driven tests


Cite error: <ref> tags exist, but no <references/> tag was found