Skip to content

Commit

Permalink
fixes #2565 - removes featureLocationPublications (#2573)
Browse files Browse the repository at this point in the history
* fixes #2565 - removes featureLocationPublications

* partial fmin and fmax get in there , but not yet saved to the DB

* added obsolete to client

* fixed JSON output

* fixed some broken errors

* udpate partials for genes properly now

* implemented in GFF3 output

* fixed partial children

* in transcript panel now

* fixed look and feel

* finished obsoletes

* updated changedoc and rest doc
  • Loading branch information
nathandunn authored Feb 16, 2021
1 parent 0afb683 commit 8149e2a
Show file tree
Hide file tree
Showing 16 changed files with 2,253 additions and 1,913 deletions.
1 change: 1 addition & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Features
- Added ability to use posts to sequence methods [2555](https://github.com/GMOD/Apollo/pull/2558).
- Added system info web service [2557](https://github.com/GMOD/Apollo/pull/2557).
- Add "merged from" comment to merged in transcript and gene [2567](https://github.com/GMOD/Apollo/issues/2567).
- Added support for "obsolete", and partials in the interface for GFF3s [2573](https://github.com/GMOD/Apollo/pull/2573).

Bug Fixes:

Expand Down
72 changes: 72 additions & 0 deletions grails-app/controllers/org/bbop/apollo/AnnotatorController.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ class AnnotatorController {
feature.name = data.name
feature.symbol = data.symbol
feature.description = data.description
feature.isObsolete = data.obsolete
if(data.containsKey("obsolete")) {
feature.isObsolete = data.getBoolean("obsolete")
}
Expand Down Expand Up @@ -328,6 +329,76 @@ class AnnotatorController {
render updateFeatureContainer
}

/**
* updates shallow properties of gene / feature
* @return
*/
@RestApiMethod(description = "Update partial fmin / famx", path = "/annotator/updatePartials", verb = RestApiVerb.POST)
@RestApiParams(params = [
@RestApiParam(name = "username", type = "email", paramType = RestApiParamType.QUERY)
, @RestApiParam(name = "password", type = "password", paramType = RestApiParamType.QUERY)
, @RestApiParam(name = "uniquename", type = "string", paramType = RestApiParamType.QUERY, description = "Uniquename (UUID) of the feature we are editing")
, @RestApiParam(name = "data", type = "string", paramType = RestApiParamType.QUERY, description = "Annotation Info object")
]
)
@Transactional
def updatePartials() {
log.debug "update partials ${params.data}"
JSONObject data = permissionService.handleInput(request, params)
if (!permissionService.hasPermissions(data, PermissionEnum.WRITE)) {
render status: HttpStatus.UNAUTHORIZED
return
}
Feature feature = Feature.findByUniqueName(data.uniquename)
FeatureLocation featureLocation = feature.featureLocation

boolean isFminPartial = feature.featureLocation.isFminPartial
boolean isFmaxPartial = feature.featureLocation.isFmaxPartial

JSONObject originalFeatureJsonObject = featureService.convertFeatureToJSON(feature)
FeatureOperation featureOperation
if(data.containsKey(FeatureStringEnum.IS_FMIN_PARTIAL.value)
&&
data.getBoolean(FeatureStringEnum.IS_FMIN_PARTIAL.value) != isFminPartial
){
featureOperation = FeatureOperation.SET_PARTIAL_FMIN
// featureLocation.isFminPartial = data.getBoolean(FeatureStringEnum.IS_FMIN_PARTIAL.value)
featureService.setPartialFmin(feature,data.getBoolean(FeatureStringEnum.IS_FMIN_PARTIAL.value).booleanValue(),feature.featureLocation.fmin)
}
else
if(data.containsKey(FeatureStringEnum.IS_FMAX_PARTIAL.value)
&&
data.getBoolean(FeatureStringEnum.IS_FMAX_PARTIAL.value) != isFmaxPartial
){
featureOperation = FeatureOperation.SET_PARTIAL_FMAX
featureService.setPartialFmax(feature,data.getBoolean(FeatureStringEnum.IS_FMAX_PARTIAL.value).booleanValue(),feature.featureLocation.fmax)
}
else{
throw new AnnotationException("Partials have not changed, so not doing anything")
}
featureLocation.save(flush: true, failOnError: true,insert:false)

JSONObject updateFeatureContainer = jsonWebUtilityService.createJSONFeatureContainer();
// its either a gene or

User user = permissionService.getCurrentUser(data)
JSONObject currentFeatureJsonObject = featureService.convertFeatureToJSON(feature)

JSONArray oldFeaturesJsonArray = new JSONArray()
oldFeaturesJsonArray.add(originalFeatureJsonObject)
JSONArray newFeaturesJsonArray = new JSONArray()
newFeaturesJsonArray.add(currentFeatureJsonObject)
featureEventService.addNewFeatureEvent(featureOperation,
feature.name,
feature.uniqueName,
data,
oldFeaturesJsonArray,
newFeaturesJsonArray,
user)

render updateFeatureContainer
}


@RestApiMethod(description = "Update exon boundaries", path = "/annotator/setExonBoundaries", verb = RestApiVerb.POST)
@RestApiParams(params = [
Expand Down Expand Up @@ -991,6 +1062,7 @@ class AnnotatorController {
if (!compareNullToBlank(feature.symbol,data.symbol)) return FeatureOperation.SET_SYMBOL
if (!compareNullToBlank(feature.description,data.description)) return FeatureOperation.SET_DESCRIPTION
if (!compareNullToBlank(feature.status,data.status)) return FeatureOperation.SET_STATUS
if(feature.isObsolete != data.obsolete ) return FeatureOperation.SET_OBSOLETE

log.warn("Updated generic feature")
null
Expand Down
14 changes: 4 additions & 10 deletions grails-app/domain/org/bbop/apollo/FeatureLocation.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -35,20 +35,15 @@ class FeatureLocation {
static belongsTo = [Feature]


static hasMany = [
featureLocationPublications: Publication
]


public boolean equals(Object other) {
boolean equals(Object other) {
if (this.is(other)) return true
if (getClass() != other.class) return false
FeatureLocation castOther = (FeatureLocation) other;

return ((this.getFeature() == castOther.getFeature()) || (this.getFeature() != null && castOther.getFeature() != null && this.getFeature().equals(castOther.getFeature()))) && (this.getLocgroup() == castOther.getLocgroup()) && (this.getRank() == castOther.getRank());
}

public int hashCode() {
int hashCode() {
int result = 17;

result = 37 * result + (getFeature() == null ? 0 : this.getFeature().hashCode());
Expand All @@ -63,10 +58,10 @@ class FeatureLocation {
* We use this as an artificial accessor in case the property has not been calculatd
* @return
*/
public Integer calculateLength(){
Integer calculateLength(){
return fmax-fmin
}
public FeatureLocation generateClone() {
FeatureLocation generateClone() {
FeatureLocation cloned = new FeatureLocation();
cloned.sequence = this.sequence;
cloned.feature = this.feature;
Expand All @@ -79,7 +74,6 @@ class FeatureLocation {
cloned.residueInfo = this.residueInfo;
cloned.locgroup = this.locgroup;
cloned.rank = this.rank;
cloned.featureLocationPublications = this.featureLocationPublications;
return cloned;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -456,9 +456,9 @@ class ChadoHandlerService {
endTime = System.currentTimeMillis()
log.debug "Time taken to create Chado featureloc for feature fmin: ${feature.fmin} fmax: ${feature.fmax}: ${endTime - startTime} ms"
exportStatisticsMap['featureloc_count'] += 1
feature.featureLocation.featureLocationPublications.each { featureLocationPublication ->
createChadoFeaturelocPub(chadoFeatureLoc, featureLocationPublication)
}
// feature.featureLocation.featureLocationPublications.each { featureLocationPublication ->
// createChadoFeaturelocPub(chadoFeatureLoc, featureLocationPublication)
// }
return chadoFeatureLoc
}

Expand Down
59 changes: 49 additions & 10 deletions grails-app/services/org/bbop/apollo/FeatureService.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import org.bbop.apollo.alteration.SequenceAlterationInContext
import org.bbop.apollo.geneProduct.GeneProduct
import org.bbop.apollo.go.GoAnnotation
import org.bbop.apollo.gwt.shared.FeatureStringEnum
import org.bbop.apollo.history.FeatureOperation
import org.bbop.apollo.sequence.SequenceTranslationHandler
import org.bbop.apollo.sequence.Strand
import org.bbop.apollo.sequence.TranslationTable
Expand Down Expand Up @@ -1966,6 +1967,9 @@ public void setTranslationEnd(Transcript transcript, int translationEnd) {
if (gsolFeature.symbol) {
jsonFeature.put(FeatureStringEnum.SYMBOL.value, gsolFeature.symbol);
}
if (gsolFeature.isObsolete) {
jsonFeature.put(FeatureStringEnum.OBSOLETE.value, gsolFeature.isObsolete);
}
if (gsolFeature.description) {
jsonFeature.put(FeatureStringEnum.DESCRIPTION.value, gsolFeature.description);
}
Expand Down Expand Up @@ -2356,20 +2360,21 @@ public void setTranslationEnd(Transcript transcript, int translationEnd) {

@Timed
JSONObject convertFeatureLocationToJSON(FeatureLocation gsolFeatureLocation) throws JSONException {
JSONObject jsonFeatureLocation = new JSONObject();
JSONObject jsonFeatureLocation = new JSONObject()
if (gsolFeatureLocation.id) {
jsonFeatureLocation.put(FeatureStringEnum.ID.value, gsolFeatureLocation.id);
jsonFeatureLocation.put(FeatureStringEnum.ID.value, gsolFeatureLocation.id)
}
jsonFeatureLocation.put(FeatureStringEnum.FMIN.value, gsolFeatureLocation.getFmin());
jsonFeatureLocation.put(FeatureStringEnum.FMAX.value, gsolFeatureLocation.getFmax());
if (gsolFeatureLocation.isIsFminPartial()) {
jsonFeatureLocation.put(FeatureStringEnum.IS_FMIN_PARTIAL.value, true);
jsonFeatureLocation.put(FeatureStringEnum.FMIN.value, gsolFeatureLocation.getFmin())
jsonFeatureLocation.put(FeatureStringEnum.FMAX.value, gsolFeatureLocation.getFmax())
if(gsolFeatureLocation.getIsFminPartial()){
jsonFeatureLocation.put(FeatureStringEnum.IS_FMIN_PARTIAL.value, gsolFeatureLocation.getIsFminPartial())
}
if (gsolFeatureLocation.isIsFmaxPartial()) {
jsonFeatureLocation.put(FeatureStringEnum.IS_FMAX_PARTIAL.value, true);

if(gsolFeatureLocation.getIsFmaxPartial()){
jsonFeatureLocation.put(FeatureStringEnum.IS_FMAX_PARTIAL.value, gsolFeatureLocation.getIsFmaxPartial())
}
jsonFeatureLocation.put(FeatureStringEnum.STRAND.value, gsolFeatureLocation.getStrand());
return jsonFeatureLocation;
jsonFeatureLocation.put(FeatureStringEnum.STRAND.value, gsolFeatureLocation.getStrand())
return jsonFeatureLocation
}

@Transactional
Expand Down Expand Up @@ -3584,4 +3589,38 @@ public void setTranslationEnd(Transcript transcript, int translationEnd) {

return false
}

@Transactional
def setPartialFmin(Feature feature,boolean fminPartial,int fmin){
FeatureLocation featureLocation = feature.featureLocation
if(fmin==featureLocation.fmin){
featureLocation.isFminPartial = fminPartial
featureLocation.save()
}

List<Feature> childFeatures = feature.parentFeatureRelationships*.childFeature
if(childFeatures){
for(childFeature in childFeatures){
setPartialFmin(childFeature,fminPartial,fmin)
}
}
}

@Transactional
def setPartialFmax(Feature feature,boolean fmaxPartial,int fmax){
FeatureLocation featureLocation = feature.featureLocation
if(fmax==featureLocation.fmax){
featureLocation.isFmaxPartial = fmaxPartial
featureLocation.save()
}

List<Feature> childFeatures = feature.parentFeatureRelationships*.childFeature
if(childFeatures){
for(childFeature in childFeatures){
setPartialFmax(childFeature,fmaxPartial,fmax)
}
}

}

}
15 changes: 12 additions & 3 deletions grails-app/services/org/bbop/apollo/Gff3HandlerService.groovy
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
package org.bbop.apollo

import org.apache.commons.lang.WordUtils
import org.bbop.apollo.geneProduct.GeneProduct
import org.bbop.apollo.go.GoAnnotation
import org.bbop.apollo.gwt.shared.FeatureStringEnum
import org.bbop.apollo.sequence.Strand
import org.grails.plugins.metrics.groovy.Timed
import org.springframework.format.datetime.DateFormatter
import java.text.SimpleDateFormat


Expand Down Expand Up @@ -53,6 +50,9 @@ class Gff3HandlerService {
writeObject.attributesToExport.add(FeatureStringEnum.COMMENTS.value);
writeObject.attributesToExport.add(FeatureStringEnum.DATE_CREATION.value);
writeObject.attributesToExport.add(FeatureStringEnum.DATE_LAST_MODIFIED.value);
writeObject.attributesToExport.add(FeatureStringEnum.IS_FMIN_PARTIAL.value);
writeObject.attributesToExport.add(FeatureStringEnum.IS_FMAX_PARTIAL.value);
writeObject.attributesToExport.add(FeatureStringEnum.OBSOLETE.value);

if (!writeObject.file.canWrite()) {
throw new IOException("Cannot write GFF3 to: " + writeObject.file.getAbsolutePath());
Expand Down Expand Up @@ -355,6 +355,15 @@ class Gff3HandlerService {
String productString = geneProductService.convertGeneProductsToGff3String(feature.geneProducts)
attributes.put(FeatureStringEnum.GENE_PRODUCT.value, encodeString(productString))
}
if (writeObject.attributesToExport.contains(FeatureStringEnum.IS_FMIN_PARTIAL.value) && feature.featureLocation.isFminPartial) {
attributes.put(FeatureStringEnum.IS_FMIN_PARTIAL.value, feature.featureLocation.isFminPartial.toString())
}
if (writeObject.attributesToExport.contains(FeatureStringEnum.OBSOLETE.value) && feature.isObsolete) {
attributes.put(FeatureStringEnum.OBSOLETE.value, feature.isObsolete.toString())
}
if (writeObject.attributesToExport.contains(FeatureStringEnum.IS_FMAX_PARTIAL.value) && feature.featureLocation.isFmaxPartial) {
attributes.put(FeatureStringEnum.IS_FMAX_PARTIAL.value, feature.featureLocation.isFmaxPartial.toString())
}
if (writeObject.attributesToExport.contains(FeatureStringEnum.STATUS.value) && feature.getStatus() != null) {
attributes.put(FeatureStringEnum.STATUS.value, encodeString(feature.getStatus().value));
}
Expand Down
3 changes: 3 additions & 0 deletions src/groovy/org/bbop/apollo/history/FeatureOperation.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ enum FeatureOperation {
SET_TRANSLATION_ENDS,
SET_LONGEST_ORF,
FLIP_STRAND,
SET_OBSOLETE,
REMOVE_CDS,
SET_READTHROUGH_STOP_CODON,
UNSET_READTHROUGH_STOP_CODON,
Expand All @@ -32,6 +33,8 @@ enum FeatureOperation {
DISSOCIATE_TRANSCRIPT_FROM_GENE,
ASSOCIATE_FEATURE_TO_GENE,
DISSOCIATE_FEATURE_FROM_GENE,
SET_PARTIAL_FMIN,
SET_PARTIAL_FMAX,

// structural data
SET_SYMBOL(false),
Expand Down
Loading

0 comments on commit 8149e2a

Please sign in to comment.