Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package org.reactome.server.analysis.core.importer;

import org.reactome.server.analysis.core.model.IdentifiersMap;
import org.reactome.server.analysis.core.model.InteractorNode;
import org.reactome.server.analysis.core.model.resource.Resource;

import java.util.HashMap;
import java.util.Map;

/**
* The interactor nodes of the interactors container: created once for each
* primary identifier, and found in the container's map by that identifier and
* by every alias recorded for them (gene names, secondary identifiers), so an
* analysis can be submitted with any of them.
*
* An interaction partner is found by its primary identifier alone. Looking it
* up in the container's map, aliases included, found another protein whenever
* the partner's identifier was one of that protein's aliases, and the partner
* was never created: which of the two survived depended on the order the
* interactions were read in. Keys are trimmed and upper-cased, as
* IdentifiersMap keys them, so a primary identifier finds what it found before.
*/
class InteractorNodes {

private final IdentifiersMap<InteractorNode> interactorsMap;

private final Map<Resource, Map<String, InteractorNode>> byPrimaryIdentifier = new HashMap<>();

private int created = 0;

InteractorNodes(IdentifiersMap<InteractorNode> interactorsMap) {
this.interactorsMap = interactorsMap;
}

/** The interactor for this primary identifier in this resource, created if there is none yet. */
InteractorNode getOrCreate(Resource resource, String identifier) {
Map<String, InteractorNode> nodes = byPrimaryIdentifier.computeIfAbsent(resource, r -> new HashMap<>());
String key = identifier.trim().toUpperCase();
InteractorNode node = nodes.get(key);
if (node == null) {
node = new InteractorNode(identifier);
nodes.put(key, node);
interactorsMap.add(identifier, resource, node);
created++;
}
return node;
}

/** Lets an analysis find this interactor by an alias as well; never used to find a partner. */
void addAlias(String alias, Resource resource, InteractorNode node) {
interactorsMap.add(alias, resource, node);
}

/** How many interactors have been created. */
int created() {
return created;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ public class InteractorsBuilder {
//Will contain the RADIX-TREE with the map (identifiers -> [InteractorNode])
private IdentifiersMap<InteractorNode> interactorsMap = new IdentifiersMap<>();

//Keeps track of the number of interactors that have been included
private int n = 0;
//Creates each interactor once, by its primary identifier, and records its aliases
private InteractorNodes interactorNodes = new InteractorNodes(interactorsMap);

public void build(Set<SpeciesNode> speciesNodes, EntitiesContainer entities, InteractionsService interactionsService) {
if (Main.VERBOSE) System.out.print("Starting creation of the interactors container...");
Expand Down Expand Up @@ -108,7 +108,7 @@ public void build(Set<SpeciesNode> speciesNodes, EntitiesContainer entities, Int
Resource resource = ResourceFactory.getResource(interactsWith.getDatabaseName());
String variantIdentifier = interactor.fetchSingleValue("getVariantIdentifier");
String identifier = variantIdentifier != null ? variantIdentifier : interactor.getIdentifier();
InteractorNode interactorNode = getOrCreate(resource, identifier);
InteractorNode interactorNode = interactorNodes.getOrCreate(resource, identifier);
for (MapSet<Long, AnalysisReaction> prs : compressedResult.getElements(target)) {
for (Long pathwayId : prs.keySet()) {
interactorNode.addInteractsWith(pathwayId, target);
Expand All @@ -120,39 +120,23 @@ public void build(Set<SpeciesNode> speciesNodes, EntitiesContainer entities, Int
ReferenceSequence rs = (ReferenceSequence) interactor;
if (rs.getGeneName() != null) {
for (String alias : rs.getGeneName()) {
interactorsMap.add(alias, resource, interactorNode);
interactorNodes.addAlias(alias, resource, interactorNode);
}
}
if (rs.getSecondaryIdentifier() != null){
for (String si : rs.getSecondaryIdentifier()) {
if(!si.contains(" ")) interactorsMap.add(si, resource, interactorNode);
if(!si.contains(" ")) interactorNodes.addAlias(si, resource, interactorNode);
}
}
}
}
}
}
if (Main.VERBOSE)
System.out.println("\rInteractors container successfully created >> " + n + " interactors have been added to Reactome.");
System.out.println("\rInteractors container successfully created >> " + interactorNodes.created() + " interactors have been added to Reactome.");
}

public IdentifiersMap<InteractorNode> getInteractorsMap() {
return interactorsMap;
}

private InteractorNode getOrCreate(Resource resource, String identifier) {
MapSet<Resource, InteractorNode> map = interactorsMap.get(identifier);
Set<InteractorNode> interactors = map.getElements(resource);
if (interactors == null || interactors.isEmpty()) {
InteractorNode interactorNode = new InteractorNode(identifier);
interactorsMap.add(identifier, resource, interactorNode);
n++;
return interactorNode;
} else {
//Using IdentifiersMap causes this "oddity" here, but is a minor inconvenient
if (interactors.size() > 1)
logger.error("Duplicate interactors found for " + identifier + " [" + resource.getName() + "]");
return interactors.iterator().next();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package org.reactome.server.analysis.core.importer;

import org.junit.Test;
import org.reactome.server.analysis.core.model.IdentifiersMap;
import org.reactome.server.analysis.core.model.InteractorNode;
import org.reactome.server.analysis.core.model.resource.Resource;
import org.reactome.server.analysis.core.model.resource.ResourceFactory;

import java.util.Set;

import static org.junit.Assert.*;

public class InteractorNodesTest {

private final Resource uniprot = ResourceFactory.getResource("UniProt");

@Test
public void aPartnerWhoseIdentifierIsAnotherProteinsAliasIsItsOwnInteractor() {
// Release 98: Q6NSH3 is a secondary identifier of P0DMU9, and an
// interaction partner of its own in the Neurofascin interactions.
IdentifiersMap<InteractorNode> map = new IdentifiersMap<>();
InteractorNodes nodes = new InteractorNodes(map);
InteractorNode p0dmu9 = nodes.getOrCreate(uniprot, "P0DMU9");
nodes.addAlias("Q6NSH3", uniprot, p0dmu9);

InteractorNode q6nsh3 = nodes.getOrCreate(uniprot, "Q6NSH3");

assertNotSame(p0dmu9, q6nsh3);
assertEquals(2, nodes.created());
// An analysis submitting Q6NSH3 finds both: the protein, and the one it
// is an alias of.
Set<InteractorNode> found = map.get("Q6NSH3").getElements(uniprot);
assertTrue(found.contains(p0dmu9));
assertTrue(found.contains(q6nsh3));
}

@Test
public void aPrimaryIdentifierFindsItsInteractorWhateverTheCase() {
IdentifiersMap<InteractorNode> map = new IdentifiersMap<>();
InteractorNodes nodes = new InteractorNodes(map);
InteractorNode first = nodes.getOrCreate(uniprot, "P12345");

assertSame(first, nodes.getOrCreate(uniprot, "p12345"));
assertSame(first, nodes.getOrCreate(uniprot, " P12345 "));
assertEquals(1, nodes.created());
}

@Test
public void theSameIdentifierInAnotherResourceIsAnotherInteractor() {
InteractorNodes nodes = new InteractorNodes(new IdentifiersMap<>());
Resource ensembl = ResourceFactory.getResource("ENSEMBL");

assertNotSame(nodes.getOrCreate(uniprot, "X1"), nodes.getOrCreate(ensembl, "X1"));
assertEquals(2, nodes.created());
}
}
Loading