EU-ADR
Contents
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:
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.
- RDF Schema can be downloaded from here.
- SQL Schema can be downloaded from here.
- WebService XSD Schema can be downloaded here and here.
- Taverna flow can be downloaded from File:EU-ADR Taverna Workflow.t2flow.
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