# Mappings

==(Need update: imported from AgroPortal project management Wiki on 2022-11-17)==

  
This page describes the representation of mappings in AgroPortal. To manipulate mappings through the API, refer to the page <https://github.com/agroportal/documentation/wiki/Administration>

## Different types of mappings

### Mappings uploaded (and stored within the portal)

* **RestBackupMapping** - A mapping added by a user using the REST API (or the UI, which is calling the API to create it). Those mappings are the only mapping relations to be hard stored (materialized) into the triplestore.

### Mappings created (automatically by the portal)

* **SameURI** - Created between 2 concepts with the same URI. Those mappings are not hard stored, they are generated on-the-fly.
* **LOOM** - Lexical mappings created between 2 concepts with very similar labels (preferred name). Comparison done after processing the label: removing accents, spaces and special characters. Those mappings are not hard stored, they are generated on-the-fly.
* **CUI** - Created between 2 concepts that have the same CUI (*Concept Unique Identifiers*). The CUI is an unique identifier used by [UMLS](https://www.nlm.nih.gov/research/umls/new_users/online_learning/Meta_005.html). Those mappings are not hard stored, they are generated on-the-fly. To be explicitly recognized, those mappings need te be defined like this:

```javascript
@prefix umls: <http://bioportal.bioontology.org/ontologies/umls/>
<http://purl.lirmm.fr/ontology/MTHMSTFRE/MT060005> a owl:Class ;
	skos:prefLabel """Lumière oesophagienne"""@fre ;
	skos:notation """MT060005"""^^xsd:string ;
	umls:cui """C0940015"""^^xsd:string ;
	umls:tui """T033"""^^xsd:string ;
	umls:hasSTY <http://purl.lirmm.fr/ontology/STY/T033> ;
.
```

Remark:


---

There are no other mappings extracted or autogenerated by the system. If an ontology file contains "mappings" represented with SKOS matching properties or owl:sameAs or any other specific property (e.g., OBO-XREF), those mappings will not be extracted by AgroPortal. There are multiple historical reasons for this (not described here). Eventually this will be fixed (cf. <https://github.com/agroportal/agroportal_web_ui/issues/121>)


---

## Internal mappings representation in the triple store

* Relations used to get mappings are in red
* Modicication to store interportal and external mappings (i.e., mappings with only one concept in AgroPortal) are in green.

 ![Mappings representation](https://github.com/agroportal/documentation/raw/master/diagrams/png/4store_bioportal_mappings_architecture.png)

[Full screen diagram](https://raw.githubusercontent.com/agroportal/documentation/master/diagrams/png/4store_bioportal_mappings_architecture.png)


### Examples of mapping representation

(Remark: the triple store still use the purl.bioontology.org domain, although this is the AgroPortal triple store. This might change one day)

* **SameURI**: point to the subject URI `<http://purl.bioontology.org/ontology/STY/T071> <http://data.bioontology.org/metadata/def/mappingSameURI> <http://purl.bioontology.org/ontology/STY/T071> .`
* **LOOM**: point to a simplified string of the ontology. Removing all special characters, space and characters with accents to make the string comparison `<http://purl.obolibrary.org/obo/PR_O09117-2> <http://data.bioontology.org/metadata/def/mappingLoom> "hyperesthsiedespieds"`
* **CUI**: a unique property URI (generated by the umls2rdf.py script) point to the CUI. And the Portal is checking at this property to compare the CUIs. \`<http://purl.lirmm.fr/ontology/MSHFRE/D011537> <http://bioportal.bioontology.org/ontologies/umls/cui> "C00337
* **RestBackupMapping**: point to the URI of a RestBackupMapping (mapping materialized in the triple store) `<http://purl.obolibrary.org/obo/UBERON_0000479> <http://data.bioontology.org/metadata/def/mappingRest> <http://data.bioontology.org/rest_backup_mappings/fd709e40-fcab-0132-77e3-525400026749>`   
   Note that 2 triples are actually stored :`<http://purl.org/biotop/biotop.owl#Tissue> <http://data.bioontology.org/metadata/def/mappingRest> <http://data.bioontology.org/rest_backup_mappings/fd709e40-fcab-0132-77e3-525400026749>`

  
    
 The URI of the RestBackupMapping is not actually de-referenced byt the API, the corresponding REST call to get the mapping is: http://data.agroportal.lirmm.fr/mappings/fd709e40-fcab-0132-77e3-525400026749 74"\`   
    
 Generated mappings can be retrieved by the API, through the class they are attached but they do not have an id, for instance : http://data.agroportal.lirmm.fr/ontologies/CO_125/classes/http%3A%2F%2Fpurl.obolibrary.org%2Fobo%2FCO_125_0000002/mappings

### Models used in the code

* LinkedData::Models::**RestBackupMapping**
  * uuid (unique id)
  * Class URNs
  * Mapping Process (see below)
* LinkedData::Models::**MappingProcess**
  * Name, source, relation, comment, date, creator...
* LinkedData::Models::**MappingCount**

Used to store the number of mappings between 2 ontologies or for 1 ontology

### Retrieving mappings from triple store

See `self.mappings_ontologies` in ontologies_linked_data/mappings/mappings.rb: <https://github.com/ncbo/ontologies_linked_data/blob/master/lib/ontologies_linked_data/mappings/mappings.rb#L159>

There is one SPARQL query to get all mappings directly from the triple store

* ?s1 may be replaced by a class URI to get all the mappings from this particular class
* ?g may be replaced by a submission graph (in order to get mappings between 2 specific ontologies)

```javascript
SELECT DISTINCT ?s1 ?s2  ?source ?o
WHERE {
{
  GRAPH <http://data.bioontology.org/ontologies/STY/submissions/1> {
      ?s1 <http://bioportal.bioontology.org/ontologies/umls/cui> ?o .
  }
  GRAPH ?g {
      ?s2 <http://bioportal.bioontology.org/ontologies/umls/cui> ?o .
  }
  BIND ('CUI' AS ?source)
}

UNION
{
  GRAPH <http://data.bioontology.org/ontologies/STY/submissions/1> {
      ?s1 <http://data.bioontology.org/metadata/def/mappingSameURI> ?o .
  }
  GRAPH ?g {
      ?s2 <http://data.bioontology.org/metadata/def/mappingSameURI> ?o .
  }
  BIND ('SAME_URI' AS ?source)
}

UNION
{
  GRAPH <http://data.bioontology.org/ontologies/STY/submissions/1> {
      ?s1 <http://data.bioontology.org/metadata/def/mappingLoom> ?o .
  }
  GRAPH ?g {
      ?s2 <http://data.bioontology.org/metadata/def/mappingLoom> ?o .
  }
  BIND ('LOOM' AS ?source)
}

UNION
{
  GRAPH <http://data.bioontology.org/ontologies/STY/submissions/1> {
      ?s1 <http://data.bioontology.org/metadata/def/mappingRest> ?o .
  }
  GRAPH ?g {
      ?s2 <http://data.bioontology.org/metadata/def/mappingRest> ?o .
  }
  BIND ('REST' AS ?source)
}

FILTER ((?s1 != ?s2) || (?source = 'SAME_URI'))
} OFFSET 0 LIMIT 50
```

After mappings have been retrieved they are represented using **LinkedData::Models::Mapping**. But it is not hard stored on the triplestore. Such examples of mappings are available above.


### Retrieving Recent mappings

2 SPARQL queries <https://github.com/ncbo/ontologies_linked_data/blob/master/lib/ontologies_linked_data/mappings/mappings.rb#L504>

* Retrieving the most recent mappings ID (can take a lot of time if a lot of mappings)

```javascript
SELECT DISTINCT ?s
FROM <http://data.bioontology.org/metadata/MappingProcess>
WHERE { ?s <http://data.bioontology.org/metadata/date> ?o }
ORDER BY DESC(?o) LIMIT 5
```

* Getting details on those recent mappings In the last filter "procs" is replaced by `?o = <MappingProcess URI> || ?o = <MappingProcess URI> || etc...`

```javascript
SELECT DISTINCT ?ont1 ?c1 ?ont2 ?c2 ?o ?uuid
WHERE {
  ?uuid <http://data.bioontology.org/metadata/process> ?o .

  ?s1 <http://data.bioontology.org/metadata/ontology> ?ont1 .
  GRAPH ?s1 {
    ?c1 <http://data.bioontology.org/metadata/def/mappingRest> ?uuid .
  }
  ?s2 <http://data.bioontology.org/metadata/ontology> ?ont2 .
  GRAPH ?s2 {
    ?c2 <http://data.bioontology.org/metadata/def/mappingRest> ?uuid .
  }
FILTER(?ont1 != ?ont2)
FILTER(?c1 != ?c2)
FILTER (#{procs})
}
```

### Deleting a mapping

Be careful, the mapping object is fragmented, therefore each fragment needs to be deleted.

* Delete the MappingProcess
* Delete the link between the mapped class URI and the RestBackupMapping (directly using a sparql_update_client... So not using the models)
* Delete the RestBackupMapping

  
 Deleting link between class URI and RestBackupMapping classes.each do |class| graph_delete = RDF::Graph.new graph_delete << [class.id, RDF::URI.new(rest_predicate), mapping.id] Goo.sparql_update_client.delete_data(graph_delete, graph: submission.id) end


## AgroPortal specific implementation

To store inter-portal (between AgroPortal and another BioPortal appliance) and external mappings (between AgroPortal and any external class URI), we have implemented a few changes (represented in green in the above diagram).

As of now, please refer to Section 6.9 of [http://www.lirmm.fr/\\\~jonquet/publications/documents/Article_WIMS2016_Reconciliation_Annane.pdf](http://www.lirmm.fr/%5C\~jonquet/publications/documents/Article_WIMS2016_Reconciliation_Annane.pdf)

 ![Mappings representation with interportal and external mappings](https://github.com/agroportal/documentation/raw/master/diagrams/png/4store_bioportal_mappings_architecture_with_external.png)

[Full screen diagram](https://raw.githubusercontent.com/agroportal/documentation/master/diagrams/png/4store_bioportal_mappings_architecture_with_external.png)

### Added class

To represent those Interportal and External mappings we created 2 new models: ExternalClass and InterportalClass that are used to modelize the mapping classes to represent them in the API.

Those models are created using the string "class_urns" points to. We parse this string that contains the Portal the mapping came from, the ontology acronym/URI and the class URI.

* Example of a class with an External and Interportal Mapping:
  * <http://data.agroportal.lirmm.fr/ontologies/CO_715/classes/http%3A%2F%2Fpurl.obolibrary.org%2Fobo%2FCO_715_0000165/mappings>
  * <http://agroportal.lirmm.fr/ontologies/CO_715/?p=classes&conceptid=http%3A%2F%2Fpurl.obolibrary.org%2Fobo%2FCO_715_0000165#mappings>
* JSON to create an interportal mapping

```javascript
{
  "creator" : "admin",
  "relation" : ["http://www.w3.org/2004/02/skos/core#exactMatch", "http://purl.org/linguistics/gold/translation"],
  "comment" : "Mapping to event in NCBO BioPortal",
  "classes" : { "http://purl.bioontology.org/ontology/STY/T071": "STY" ,
    "http://neurolog.unice.fr/ontoneurolog/v3.0/dolce-particular.owl#event": "ncbo:OntoVIP"
  }
}
```

* JSON to create an external mapping

```javascript
{
  "creator" : "admin",
  "relation" : ["http://www.w3.org/2004/02/skos/core#exactMatch", "http://purl.org/linguistics/gold/translation"],
  "comment" : "Mapping to the event class of the event ontology",
  "classes" : { "http://purl.bioontology.org/ontology/STY/T071": "STY",
    "http://purl.org/NET/c4dm/event.owl#Event": "ext:http://purl.org/NET/c4dm/event.owl"
  }
}
```

# Other source of information on mappings

BioPortal documentation <https://bioportal.bioontology.org/help#Viewing_and_editing_mappings>

Example code for creating API mappings is at <https://github.com/ncbo/ncbo_rest_sample_code/blob/master/java/src/CreateMapping.java>

NCBO documentation   
 <https://www.bioontology.org/wiki/index.php/BioPortal_Mappings>

---

**Documents**

- [💁‍♂️ Acknowledgments](https://wiki.agroportal.eu/s/e6158eda-c109-4385-852c-51a42de9a412/doc/acknowledgments-15GdRXLQdm)
- [📚Publications and references](https://wiki.agroportal.eu/s/e6158eda-c109-4385-852c-51a42de9a412/doc/publications-and-references-87tEoeoGKy)
- [🗽Terms & Conditions](https://wiki.agroportal.eu/s/e6158eda-c109-4385-852c-51a42de9a412/doc/terms-conditions-naDsDo2Zxq)
- [🧞‍♂️Metadata guidelines and recommendations](https://wiki.agroportal.eu/s/e6158eda-c109-4385-852c-51a42de9a412/doc/metadata-guidelines-and-recommendations-pOFbK9sIfp)
- [📜 AgroPortal Release Notes](https://wiki.agroportal.eu/s/e6158eda-c109-4385-852c-51a42de9a412/doc/agroportal-release-notes-btKjZk5tU2)
- [ 👩‍🚀 User Guide](https://wiki.agroportal.eu/s/e6158eda-c109-4385-852c-51a42de9a412/doc/user-guide-ZszoBwfjGF)
- [📎 API Documentation](https://wiki.agroportal.eu/s/e6158eda-c109-4385-852c-51a42de9a412/doc/api-documentation-kMCurGKD97)
- [🤖 Developer Documentation](https://wiki.agroportal.eu/s/e6158eda-c109-4385-852c-51a42de9a412/doc/developer-documentation-LhsrucqGTa)
- [🗃External Documentation](https://wiki.agroportal.eu/s/e6158eda-c109-4385-852c-51a42de9a412/doc/external-documentation-vNPQCdArrr)
- [AgroPortal infrastructure](https://wiki.agroportal.eu/s/e6158eda-c109-4385-852c-51a42de9a412/doc/agroportal-infrastructure-ietsAU4kPs)