Commit ff277f41 authored by Frederic Bastian's avatar Frederic Bastian

Merge branch 'hotfix_rankComparator'

parents a33ad31c b6dd5a91
......@@ -2,7 +2,6 @@ package org.bgee.model.expressiondata;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.Set;
......@@ -30,7 +29,7 @@ import org.bgee.model.ontology.RelationType;
//TODO: Actually, maybe we should have an UtilsFactory, as we have a ServiceFactory.
//Could return also the ExpressionCallUtils, the ExpressionCall.RankComparator...
//that would be much cleaner for unit tests.
public class ConditionGraph implements Comparator<Condition> {
public class ConditionGraph {
private static final Logger log = LogManager.getLogger(ConditionGraph.class.getName());
......@@ -371,35 +370,6 @@ public class ConditionGraph implements Comparator<Condition> {
return log.exit(true);
}
/**
* Compare two {@code Condition}s based on their relations between each other.
* Will return a negative {@code int} if {@code cond1} is more precise than {@code cond2},
* a positive {@code int} if {@code cond1} is less precise than {@code cond2},
* {@code 0} if {@code cond1} and {@code cond2} are unrelated.
* <p>
* For a comparison of {@code Condition}s simply based on their attributes,
* see {@code Condition#compareTo(Condition)}.
*
* @param cond1 The first {@code Condition} to be compared.
* @param cond2 The second {@code Condition} to be compared.
* @return a negative {@code int}, zero, or a positive {@code int}
* as the first argument is more precise than, unrelated to, or less precise
* than the second.
* @see #isConditionMorePrecise(Condition, Condition)
*/
@Override
public int compare(Condition cond1, Condition cond2) {
log.entry(cond1, cond2);
if (this.isConditionMorePrecise(cond1, cond2)) {
return log.exit(1);
}
if (this.isConditionMorePrecise(cond2, cond1)) {
return log.exit(-1);
}
return log.exit(0);
}
/**
* Get all the {@code Condition}s that are less precise than {@code cond},
* among the {@code Condition}s provided at instantiation.
......
......@@ -15,7 +15,7 @@ import org.bgee.model.source.Source;
* @author Frederic Bastian
* @author Philippe Moret
* @author Valentine Rech de Laval
* @version Bgee 13, Nov. 2016
* @version Bgee 13, Jun. 2018
* @since Bgee 13, Mar. 2013
*/
public class Species extends NamedEntity<Integer> {
......@@ -39,14 +39,6 @@ public class Species extends NamedEntity<Integer> {
/**@see #getPreferredDisplayOrder() */
private final Integer preferredDisplayOrder;
/**
* 0-arg constructor private, at least an ID must be provided, see {@link #Species(String)}.
*/
@SuppressWarnings("unused")
private Species() {
this(null);
}
/**
* Constructor providing the {@code id} of this {@code Species}.
......@@ -268,19 +260,9 @@ public class Species extends NamedEntity<Integer> {
return preferredDisplayOrder;
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + ((genus == null) ? 0 : genus.hashCode());
result = prime * result + ((speciesName == null) ? 0 : speciesName.hashCode());
result = prime * result + ((genomeVersion == null) ? 0 : genomeVersion.hashCode());
result = prime * result + ((dataTypesByDataSourcesForData == null) ? 0 : dataTypesByDataSourcesForData.hashCode());
result = prime * result + ((dataTypesByDataSourcesForAnnotation == null) ? 0 : dataTypesByDataSourcesForAnnotation.hashCode());
result = prime * result + ((parentTaxonId == null) ? 0 : parentTaxonId.hashCode());
result = prime * result + ((preferredDisplayOrder == null) ? 0 : preferredDisplayOrder.hashCode());
return result;
}
//we based hashCode/equals of NamedEntity on methods from parent class Entity:
//only the ID matter for NamedEntity, as for Entity.
@Override
public String toString() {
......@@ -294,60 +276,4 @@ public class Species extends NamedEntity<Integer> {
.append(", preferredDisplayOrder=").append(preferredDisplayOrder).append("]");
return builder.toString();
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!super.equals(obj)) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
Species other = (Species) obj;
if (genus == null) {
if (other.genus != null) {
return false;
}
} else if (!genus.equals(other.genus)) {
return false;
}
if (speciesName == null) {
if (other.speciesName != null) {
return false;
}
} else if (!speciesName.equals(other.speciesName)) {
return false;
}
if (genomeVersion == null) {
if (other.genomeVersion != null) {
return false;
}
} else if (!genomeVersion.equals(other.genomeVersion)) {
return false;
}
if (dataTypesByDataSourcesForData == null) {
if (other.dataTypesByDataSourcesForData != null)
return false;
} else if (!dataTypesByDataSourcesForData.equals(other.dataTypesByDataSourcesForData))
return false;
if (dataTypesByDataSourcesForAnnotation == null) {
if (other.dataTypesByDataSourcesForAnnotation != null)
return false;
} else if (!dataTypesByDataSourcesForAnnotation.equals(other.dataTypesByDataSourcesForAnnotation))
return false;
if (parentTaxonId == null) {
if (other.parentTaxonId != null)
return false;
} else if (!parentTaxonId.equals(other.parentTaxonId))
return false;
if (preferredDisplayOrder == null) {
if (other.preferredDisplayOrder != null)
return false;
} else if (!preferredDisplayOrder.equals(other.preferredDisplayOrder))
return false;
return true;
}
}
......@@ -52,6 +52,17 @@ public class ConditionGraphTest extends TestAncestor {
* {@code false} if it should be loaded directly from {@code Ontology}s.
*/
private void loadConditionGraph(boolean fromService) {
// anat1
// / \ \
// anat2 anat3\
// \ \
// anat4
//
// stage1
// / \ \
// stage2 stage3\
// \ \
// stage4
String anatEntityId1 = "anat1";
AnatEntity anatEntity1 = new AnatEntity(anatEntityId1);
String anatEntityId2 = "anat2";
......@@ -213,49 +224,6 @@ public class ConditionGraphTest extends TestAncestor {
}
/**
* Test {@link ConditionGraph#compare(Condition, Condition)}
*/
@Test
public void testCompareDifferentLoadings() {
this.loadConditionGraph(true);
this.testCompare();
this.loadConditionGraph(false);
this.testCompare();
}
/**
* Test {@link ConditionGraph#compare(Condition, Condition)}
*/
private void testCompare() {
assertEquals("Incorrect comparison based on rels between Conditions", 1,
this.conditionGraph.compare(this.conditions.get(0), this.conditions.get(1)));
assertEquals("Incorrect comparison based on rels between Conditions", -1,
this.conditionGraph.compare(this.conditions.get(1), this.conditions.get(0)));
assertEquals("Incorrect comparison based on rels between Conditions", 1,
this.conditionGraph.compare(this.conditions.get(0), this.conditions.get(2)));
assertEquals("Incorrect comparison based on rels between Conditions", -1,
this.conditionGraph.compare(this.conditions.get(2), this.conditions.get(0)));
assertEquals("Incorrect comparison based on rels between Conditions", 0,
this.conditionGraph.compare(this.conditions.get(1), this.conditions.get(2)));
assertEquals("Incorrect comparison based on rels between Conditions", 0,
this.conditionGraph.compare(this.conditions.get(2), this.conditions.get(1)));
assertEquals("Incorrect comparison based on rels between Conditions", 0,
this.conditionGraph.compare(this.conditions.get(5), this.conditions.get(1)));
assertEquals("Incorrect comparison based on rels between Conditions", 0,
this.conditionGraph.compare(this.conditions.get(1), this.conditions.get(5)));
assertEquals("Incorrect comparison based on rels between Conditions", 1,
this.conditionGraph.compare(this.conditions.get(0), this.conditions.get(4)));
assertEquals("Incorrect comparison based on rels between Conditions", -1,
this.conditionGraph.compare(this.conditions.get(4), this.conditions.get(0)));
assertEquals("Incorrect comparison based on rels between Conditions", 0,
this.conditionGraph.compare(this.conditions.get(1), this.conditions.get(1)));
assertEquals("Incorrect comparison based on rels between Conditions", 1,
this.conditionGraph.compare(this.conditions.get(0), this.conditions.get(3)));
assertEquals("Incorrect comparison based on rels between Conditions", -1,
this.conditionGraph.compare(this.conditions.get(3), this.conditions.get(0)));
}
/**
* Test the method {@link ConditionGraph#getDescendantConditions(Condition)}.
*/
......
......@@ -466,7 +466,7 @@ public class GenerateRankFile {
* for injection purposes.
* TODO: to remove once we'll have created an UtilsFactory in bgee-core
*/
private final Function<ConditionGraph, ExpressionCall.RankComparator> rankComparatorSupplier;
private final BiFunction<Collection<ExpressionCall>, ConditionGraph, List<ExpressionCall>> rankOrderingFuncSupplier;
/**
* A {@code Function} matching the signature of the method of {@code ExpressionCall::identifyRedundantCalls},
* for injection purposes.
......@@ -493,7 +493,7 @@ public class GenerateRankFile {
* @param uberonOnt An {@code Uberon} utiliy to extract XRefs to BTO from.
*/
public GenerateRankFile(Supplier<ServiceFactory> serviceFactorySupplier, Uberon uberonOnt) {
this(serviceFactorySupplier, uberonOnt, ConditionGraph::new, ExpressionCall.RankComparator::new,
this(serviceFactorySupplier, uberonOnt, ConditionGraph::new, ExpressionCall::filterAndOrderCallsByRank,
ExpressionCall::identifyRedundantCalls);
}
/**
......@@ -501,19 +501,19 @@ public class GenerateRankFile {
* to be able to provide one to each thread.
* @param uberonOnt An {@code Uberon} utiliy to extract XRefs to BTO from.
* @param condGraphSupplier To inject {@code ConditionGraph} instances.
* @param rankComparatorSupplier To inject {@code ExpressionCall.RankComparator} instances.
* @param rankOrderingFuncSupplier To inject the method {@code ExpressionCall::filterAndOrderCallsByRank}.
* @param redundantCallsFuncSupplier To inject the method {@code ExpressionCall::identifyRedundantCalls}.
*/
//TODO: stop using these functional interfaces once we'll have created an UtilsFactory in bgee-core
protected GenerateRankFile(Supplier<ServiceFactory> serviceFactorySupplier, Uberon uberonOnt,
TriFunction<Collection<Condition>, Ontology<AnatEntity, String>, Ontology<DevStage, String>,
ConditionGraph> condGraphSupplier,
Function<ConditionGraph, ExpressionCall.RankComparator> rankComparatorSupplier,
BiFunction<Collection<ExpressionCall>, ConditionGraph, List<ExpressionCall>> rankOrderingFuncSupplier,
BiFunction<List<ExpressionCall>, ConditionGraph, Set<ExpressionCall>> redundantCallsFuncSupplier) {
this.serviceFactorySupplier = serviceFactorySupplier;
this.uberonOnt = uberonOnt;
this.condGraphSupplier = condGraphSupplier;
this.rankComparatorSupplier = rankComparatorSupplier;
this.rankOrderingFuncSupplier = rankOrderingFuncSupplier;
this.redundantCallsFuncSupplier = redundantCallsFuncSupplier;
}
......
......@@ -292,14 +292,8 @@ public class CommandGene extends CommandParent {
ConditionGraph organStageGraph = new ConditionGraph(
orderedCalls.stream().map(ExpressionCall::getCondition).collect(Collectors.toSet()),
serviceFactory);
Collections.sort(orderedCalls, new ExpressionCall.RankComparator(organStageGraph));
//ORGAN
//We need the ConditionGraph for sorting the calls. Creating the AnatEntityOntology for this graph is costly,
//so we re-use the AnatEntityOntology already produced for the organStageGraph
ConditionGraph organGraph = new ConditionGraph(
organCalls.stream().map(ExpressionCall::getCondition).collect(Collectors.toSet()),
organStageGraph.getAnatEntityOntology(), null);
Collections.sort(organCalls, new ExpressionCall.RankComparator(organGraph));
orderedCalls = ExpressionCall.filterAndOrderCallsByRank(orderedCalls, organStageGraph);
//REDUNDANT ORGAN-STAGE CALLS
final Set<ExpressionCall> redundantCalls = ExpressionCall.identifyRedundantCalls(
orderedCalls, organStageGraph);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment