Skip to content

Commit 8149e2a

Browse files
authored
fixes #2565 - removes featureLocationPublications (#2573)
* 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
1 parent 0afb683 commit 8149e2a

16 files changed

+2253
-1913
lines changed

ChangeLog.md

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ Features
77
- Added ability to use posts to sequence methods [2555](https://github.com/GMOD/Apollo/pull/2558).
88
- Added system info web service [2557](https://github.com/GMOD/Apollo/pull/2557).
99
- Add "merged from" comment to merged in transcript and gene [2567](https://github.com/GMOD/Apollo/issues/2567).
10+
- Added support for "obsolete", and partials in the interface for GFF3s [2573](https://github.com/GMOD/Apollo/pull/2573).
1011

1112
Bug Fixes:
1213

grails-app/controllers/org/bbop/apollo/AnnotatorController.groovy

+72
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@ class AnnotatorController {
236236
feature.name = data.name
237237
feature.symbol = data.symbol
238238
feature.description = data.description
239+
feature.isObsolete = data.obsolete
239240
if(data.containsKey("obsolete")) {
240241
feature.isObsolete = data.getBoolean("obsolete")
241242
}
@@ -328,6 +329,76 @@ class AnnotatorController {
328329
render updateFeatureContainer
329330
}
330331

332+
/**
333+
* updates shallow properties of gene / feature
334+
* @return
335+
*/
336+
@RestApiMethod(description = "Update partial fmin / famx", path = "/annotator/updatePartials", verb = RestApiVerb.POST)
337+
@RestApiParams(params = [
338+
@RestApiParam(name = "username", type = "email", paramType = RestApiParamType.QUERY)
339+
, @RestApiParam(name = "password", type = "password", paramType = RestApiParamType.QUERY)
340+
, @RestApiParam(name = "uniquename", type = "string", paramType = RestApiParamType.QUERY, description = "Uniquename (UUID) of the feature we are editing")
341+
, @RestApiParam(name = "data", type = "string", paramType = RestApiParamType.QUERY, description = "Annotation Info object")
342+
]
343+
)
344+
@Transactional
345+
def updatePartials() {
346+
log.debug "update partials ${params.data}"
347+
JSONObject data = permissionService.handleInput(request, params)
348+
if (!permissionService.hasPermissions(data, PermissionEnum.WRITE)) {
349+
render status: HttpStatus.UNAUTHORIZED
350+
return
351+
}
352+
Feature feature = Feature.findByUniqueName(data.uniquename)
353+
FeatureLocation featureLocation = feature.featureLocation
354+
355+
boolean isFminPartial = feature.featureLocation.isFminPartial
356+
boolean isFmaxPartial = feature.featureLocation.isFmaxPartial
357+
358+
JSONObject originalFeatureJsonObject = featureService.convertFeatureToJSON(feature)
359+
FeatureOperation featureOperation
360+
if(data.containsKey(FeatureStringEnum.IS_FMIN_PARTIAL.value)
361+
&&
362+
data.getBoolean(FeatureStringEnum.IS_FMIN_PARTIAL.value) != isFminPartial
363+
){
364+
featureOperation = FeatureOperation.SET_PARTIAL_FMIN
365+
// featureLocation.isFminPartial = data.getBoolean(FeatureStringEnum.IS_FMIN_PARTIAL.value)
366+
featureService.setPartialFmin(feature,data.getBoolean(FeatureStringEnum.IS_FMIN_PARTIAL.value).booleanValue(),feature.featureLocation.fmin)
367+
}
368+
else
369+
if(data.containsKey(FeatureStringEnum.IS_FMAX_PARTIAL.value)
370+
&&
371+
data.getBoolean(FeatureStringEnum.IS_FMAX_PARTIAL.value) != isFmaxPartial
372+
){
373+
featureOperation = FeatureOperation.SET_PARTIAL_FMAX
374+
featureService.setPartialFmax(feature,data.getBoolean(FeatureStringEnum.IS_FMAX_PARTIAL.value).booleanValue(),feature.featureLocation.fmax)
375+
}
376+
else{
377+
throw new AnnotationException("Partials have not changed, so not doing anything")
378+
}
379+
featureLocation.save(flush: true, failOnError: true,insert:false)
380+
381+
JSONObject updateFeatureContainer = jsonWebUtilityService.createJSONFeatureContainer();
382+
// its either a gene or
383+
384+
User user = permissionService.getCurrentUser(data)
385+
JSONObject currentFeatureJsonObject = featureService.convertFeatureToJSON(feature)
386+
387+
JSONArray oldFeaturesJsonArray = new JSONArray()
388+
oldFeaturesJsonArray.add(originalFeatureJsonObject)
389+
JSONArray newFeaturesJsonArray = new JSONArray()
390+
newFeaturesJsonArray.add(currentFeatureJsonObject)
391+
featureEventService.addNewFeatureEvent(featureOperation,
392+
feature.name,
393+
feature.uniqueName,
394+
data,
395+
oldFeaturesJsonArray,
396+
newFeaturesJsonArray,
397+
user)
398+
399+
render updateFeatureContainer
400+
}
401+
331402

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

9951067
log.warn("Updated generic feature")
9961068
null

grails-app/domain/org/bbop/apollo/FeatureLocation.groovy

+4-10
Original file line numberDiff line numberDiff line change
@@ -35,20 +35,15 @@ class FeatureLocation {
3535
static belongsTo = [Feature]
3636

3737

38-
static hasMany = [
39-
featureLocationPublications: Publication
40-
]
41-
42-
43-
public boolean equals(Object other) {
38+
boolean equals(Object other) {
4439
if (this.is(other)) return true
4540
if (getClass() != other.class) return false
4641
FeatureLocation castOther = (FeatureLocation) other;
4742

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

51-
public int hashCode() {
46+
int hashCode() {
5247
int result = 17;
5348

5449
result = 37 * result + (getFeature() == null ? 0 : this.getFeature().hashCode());
@@ -63,10 +58,10 @@ class FeatureLocation {
6358
* We use this as an artificial accessor in case the property has not been calculatd
6459
* @return
6560
*/
66-
public Integer calculateLength(){
61+
Integer calculateLength(){
6762
return fmax-fmin
6863
}
69-
public FeatureLocation generateClone() {
64+
FeatureLocation generateClone() {
7065
FeatureLocation cloned = new FeatureLocation();
7166
cloned.sequence = this.sequence;
7267
cloned.feature = this.feature;
@@ -79,7 +74,6 @@ class FeatureLocation {
7974
cloned.residueInfo = this.residueInfo;
8075
cloned.locgroup = this.locgroup;
8176
cloned.rank = this.rank;
82-
cloned.featureLocationPublications = this.featureLocationPublications;
8377
return cloned;
8478
}
8579

grails-app/services/org/bbop/apollo/ChadoHandlerService.groovy

+3-3
Original file line numberDiff line numberDiff line change
@@ -456,9 +456,9 @@ class ChadoHandlerService {
456456
endTime = System.currentTimeMillis()
457457
log.debug "Time taken to create Chado featureloc for feature fmin: ${feature.fmin} fmax: ${feature.fmax}: ${endTime - startTime} ms"
458458
exportStatisticsMap['featureloc_count'] += 1
459-
feature.featureLocation.featureLocationPublications.each { featureLocationPublication ->
460-
createChadoFeaturelocPub(chadoFeatureLoc, featureLocationPublication)
461-
}
459+
// feature.featureLocation.featureLocationPublications.each { featureLocationPublication ->
460+
// createChadoFeaturelocPub(chadoFeatureLoc, featureLocationPublication)
461+
// }
462462
return chadoFeatureLoc
463463
}
464464

grails-app/services/org/bbop/apollo/FeatureService.groovy

+49-10
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import org.bbop.apollo.alteration.SequenceAlterationInContext
66
import org.bbop.apollo.geneProduct.GeneProduct
77
import org.bbop.apollo.go.GoAnnotation
88
import org.bbop.apollo.gwt.shared.FeatureStringEnum
9+
import org.bbop.apollo.history.FeatureOperation
910
import org.bbop.apollo.sequence.SequenceTranslationHandler
1011
import org.bbop.apollo.sequence.Strand
1112
import org.bbop.apollo.sequence.TranslationTable
@@ -1966,6 +1967,9 @@ public void setTranslationEnd(Transcript transcript, int translationEnd) {
19661967
if (gsolFeature.symbol) {
19671968
jsonFeature.put(FeatureStringEnum.SYMBOL.value, gsolFeature.symbol);
19681969
}
1970+
if (gsolFeature.isObsolete) {
1971+
jsonFeature.put(FeatureStringEnum.OBSOLETE.value, gsolFeature.isObsolete);
1972+
}
19691973
if (gsolFeature.description) {
19701974
jsonFeature.put(FeatureStringEnum.DESCRIPTION.value, gsolFeature.description);
19711975
}
@@ -2356,20 +2360,21 @@ public void setTranslationEnd(Transcript transcript, int translationEnd) {
23562360

23572361
@Timed
23582362
JSONObject convertFeatureLocationToJSON(FeatureLocation gsolFeatureLocation) throws JSONException {
2359-
JSONObject jsonFeatureLocation = new JSONObject();
2363+
JSONObject jsonFeatureLocation = new JSONObject()
23602364
if (gsolFeatureLocation.id) {
2361-
jsonFeatureLocation.put(FeatureStringEnum.ID.value, gsolFeatureLocation.id);
2365+
jsonFeatureLocation.put(FeatureStringEnum.ID.value, gsolFeatureLocation.id)
23622366
}
2363-
jsonFeatureLocation.put(FeatureStringEnum.FMIN.value, gsolFeatureLocation.getFmin());
2364-
jsonFeatureLocation.put(FeatureStringEnum.FMAX.value, gsolFeatureLocation.getFmax());
2365-
if (gsolFeatureLocation.isIsFminPartial()) {
2366-
jsonFeatureLocation.put(FeatureStringEnum.IS_FMIN_PARTIAL.value, true);
2367+
jsonFeatureLocation.put(FeatureStringEnum.FMIN.value, gsolFeatureLocation.getFmin())
2368+
jsonFeatureLocation.put(FeatureStringEnum.FMAX.value, gsolFeatureLocation.getFmax())
2369+
if(gsolFeatureLocation.getIsFminPartial()){
2370+
jsonFeatureLocation.put(FeatureStringEnum.IS_FMIN_PARTIAL.value, gsolFeatureLocation.getIsFminPartial())
23672371
}
2368-
if (gsolFeatureLocation.isIsFmaxPartial()) {
2369-
jsonFeatureLocation.put(FeatureStringEnum.IS_FMAX_PARTIAL.value, true);
2372+
2373+
if(gsolFeatureLocation.getIsFmaxPartial()){
2374+
jsonFeatureLocation.put(FeatureStringEnum.IS_FMAX_PARTIAL.value, gsolFeatureLocation.getIsFmaxPartial())
23702375
}
2371-
jsonFeatureLocation.put(FeatureStringEnum.STRAND.value, gsolFeatureLocation.getStrand());
2372-
return jsonFeatureLocation;
2376+
jsonFeatureLocation.put(FeatureStringEnum.STRAND.value, gsolFeatureLocation.getStrand())
2377+
return jsonFeatureLocation
23732378
}
23742379

23752380
@Transactional
@@ -3584,4 +3589,38 @@ public void setTranslationEnd(Transcript transcript, int translationEnd) {
35843589

35853590
return false
35863591
}
3592+
3593+
@Transactional
3594+
def setPartialFmin(Feature feature,boolean fminPartial,int fmin){
3595+
FeatureLocation featureLocation = feature.featureLocation
3596+
if(fmin==featureLocation.fmin){
3597+
featureLocation.isFminPartial = fminPartial
3598+
featureLocation.save()
3599+
}
3600+
3601+
List<Feature> childFeatures = feature.parentFeatureRelationships*.childFeature
3602+
if(childFeatures){
3603+
for(childFeature in childFeatures){
3604+
setPartialFmin(childFeature,fminPartial,fmin)
3605+
}
3606+
}
3607+
}
3608+
3609+
@Transactional
3610+
def setPartialFmax(Feature feature,boolean fmaxPartial,int fmax){
3611+
FeatureLocation featureLocation = feature.featureLocation
3612+
if(fmax==featureLocation.fmax){
3613+
featureLocation.isFmaxPartial = fmaxPartial
3614+
featureLocation.save()
3615+
}
3616+
3617+
List<Feature> childFeatures = feature.parentFeatureRelationships*.childFeature
3618+
if(childFeatures){
3619+
for(childFeature in childFeatures){
3620+
setPartialFmax(childFeature,fmaxPartial,fmax)
3621+
}
3622+
}
3623+
3624+
}
3625+
35873626
}

grails-app/services/org/bbop/apollo/Gff3HandlerService.groovy

+12-3
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
package org.bbop.apollo
22

33
import org.apache.commons.lang.WordUtils
4-
import org.bbop.apollo.geneProduct.GeneProduct
5-
import org.bbop.apollo.go.GoAnnotation
64
import org.bbop.apollo.gwt.shared.FeatureStringEnum
75
import org.bbop.apollo.sequence.Strand
86
import org.grails.plugins.metrics.groovy.Timed
9-
import org.springframework.format.datetime.DateFormatter
107
import java.text.SimpleDateFormat
118

129

@@ -53,6 +50,9 @@ class Gff3HandlerService {
5350
writeObject.attributesToExport.add(FeatureStringEnum.COMMENTS.value);
5451
writeObject.attributesToExport.add(FeatureStringEnum.DATE_CREATION.value);
5552
writeObject.attributesToExport.add(FeatureStringEnum.DATE_LAST_MODIFIED.value);
53+
writeObject.attributesToExport.add(FeatureStringEnum.IS_FMIN_PARTIAL.value);
54+
writeObject.attributesToExport.add(FeatureStringEnum.IS_FMAX_PARTIAL.value);
55+
writeObject.attributesToExport.add(FeatureStringEnum.OBSOLETE.value);
5656

5757
if (!writeObject.file.canWrite()) {
5858
throw new IOException("Cannot write GFF3 to: " + writeObject.file.getAbsolutePath());
@@ -355,6 +355,15 @@ class Gff3HandlerService {
355355
String productString = geneProductService.convertGeneProductsToGff3String(feature.geneProducts)
356356
attributes.put(FeatureStringEnum.GENE_PRODUCT.value, encodeString(productString))
357357
}
358+
if (writeObject.attributesToExport.contains(FeatureStringEnum.IS_FMIN_PARTIAL.value) && feature.featureLocation.isFminPartial) {
359+
attributes.put(FeatureStringEnum.IS_FMIN_PARTIAL.value, feature.featureLocation.isFminPartial.toString())
360+
}
361+
if (writeObject.attributesToExport.contains(FeatureStringEnum.OBSOLETE.value) && feature.isObsolete) {
362+
attributes.put(FeatureStringEnum.OBSOLETE.value, feature.isObsolete.toString())
363+
}
364+
if (writeObject.attributesToExport.contains(FeatureStringEnum.IS_FMAX_PARTIAL.value) && feature.featureLocation.isFmaxPartial) {
365+
attributes.put(FeatureStringEnum.IS_FMAX_PARTIAL.value, feature.featureLocation.isFmaxPartial.toString())
366+
}
358367
if (writeObject.attributesToExport.contains(FeatureStringEnum.STATUS.value) && feature.getStatus() != null) {
359368
attributes.put(FeatureStringEnum.STATUS.value, encodeString(feature.getStatus().value));
360369
}

src/groovy/org/bbop/apollo/history/FeatureOperation.groovy

+3
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ enum FeatureOperation {
2323
SET_TRANSLATION_ENDS,
2424
SET_LONGEST_ORF,
2525
FLIP_STRAND,
26+
SET_OBSOLETE,
2627
REMOVE_CDS,
2728
SET_READTHROUGH_STOP_CODON,
2829
UNSET_READTHROUGH_STOP_CODON,
@@ -32,6 +33,8 @@ enum FeatureOperation {
3233
DISSOCIATE_TRANSCRIPT_FROM_GENE,
3334
ASSOCIATE_FEATURE_TO_GENE,
3435
DISSOCIATE_FEATURE_FROM_GENE,
36+
SET_PARTIAL_FMIN,
37+
SET_PARTIAL_FMAX,
3538

3639
// structural data
3740
SET_SYMBOL(false),

0 commit comments

Comments
 (0)