diff --git a/apollo/annotations/__init__.py b/apollo/annotations/__init__.py index 22fdb5d4..7daecd7f 100644 --- a/apollo/annotations/__init__.py +++ b/apollo/annotations/__init__.py @@ -1246,12 +1246,6 @@ def _write_features(self, new_features_list=None, test=False, verbose=False, tim if verbose: print("empty list, no more features to write") - def _get_subfeatures(self, rec): - if len(rec.features) > 1: - return rec.features[1:] - else: - return None - def _get_type(self, rec): return rec.features[0].type @@ -1262,100 +1256,53 @@ def _process_gff_entry(self, rec, new_feature_list, new_transcript_list, source= disable_cds_recalculation=False, use_name=False, verbose=False): type = self._get_type(rec) print("type " + str(type)) - subfeatures = self._get_subfeatures(rec) - if type in util.gene_types: - print("is gene type") - if subfeatures is not None and len(subfeatures) > 0: - print("has sub features") - feature_data = util._yieldApolloData(subfeatures, use_name=use_name, - disable_cds_recalculation=disable_cds_recalculation) - print("output feature data" + str(feature_data)) + all_features = [] + for feature in rec.features: + sub_features = feature.sub_features + feature_data = None + if type in util.gene_types: + print("is gene type") + if sub_features is not None and len(sub_features) > 0: + print("has sub features") + feature_data = util.yieldApolloData(feature, use_name=use_name, + disable_cds_recalculation=disable_cds_recalculation) + print("output feature data" + str(feature_data)) + new_transcript_list.append(feature_data) + else: + print("NO sub features, just adding directly") + feature_data = util.yieldApolloData(feature, use_name=use_name, + disable_cds_recalculation=disable_cds_recalculation) + print("output feature data" + str(feature_data)) + new_feature_list.append(feature_data) + elif type in util.pseudogenes_types: + if sub_features is not None and len(sub_features) > 0: + feature_data = util.yieldApolloData(feature, use_name=use_name, + disable_cds_recalculation=disable_cds_recalculation) + new_feature_list.append(feature_data) + else: + feature_data = util.yieldApolloData(feature, use_name=use_name, + disable_cds_recalculation=disable_cds_recalculation) + new_feature_list.append(feature_data) + elif type in util.coding_transcript_types: + feature_data = util.yieldApolloData(feature, use_name=use_name, + disable_cds_recalculation=disable_cds_recalculation) new_transcript_list.append(feature_data) - else: - print("NO sub features, just adding directly") - feature_data = util._yieldApolloData(rec.features, use_name=use_name, - disable_cds_recalculation=disable_cds_recalculation) - print("output feature data" + str(feature_data)) + elif type in util.noncoding_transcript_types: + print("a non-coding transcript\n") + feature_data = util.yieldApolloData(feature, use_name=use_name, + disable_cds_recalculation=disable_cds_recalculation) new_feature_list.append(feature_data) - elif type in util.pseudogenes_types: - if subfeatures is not None and len(subfeatures) > 0: - feature_data = util._yieldApolloData(rec.features[1:], use_name=use_name, - disable_cds_recalculation=disable_cds_recalculation) + print("new feature list \n" + str(new_feature_list)) + elif type in util.single_level_feature_types: + feature_data = util.yieldApolloData(feature, use_name=use_name, + disable_cds_recalculation=disable_cds_recalculation) new_feature_list.append(feature_data) else: - feature_data = util._yieldApolloData(rec.features, use_name=use_name, - disable_cds_recalculation=disable_cds_recalculation) - new_feature_list.append(feature_data) - elif type in util.coding_transcript_types or type in util.noncoding_transcript_types: - feature_data = util._yieldApolloData(rec.features, use_name=use_name, - disable_cds_recalculation=disable_cds_recalculation) - new_transcript_list.append(feature_data) - elif type in util.single_level_feature_types: - feature_data = util._yieldApolloData(rec.features, use_name=use_name, - disable_cds_recalculation=disable_cds_recalculation) - new_feature_list.append(feature_data) - else: - print("unknown type " + type + " ") - - # type = self._get_type(rec) - # subfeatures = self._get_subfeatures(rec) - # if type not in util.gene_types and type not in util.coding_transcript_types: - # print("AAAAAA") - # if subfeatures is not None: - # print("BBBBBB") - # # process noncoding transcripts - # for subfeature in subfeatures: - # self._process_gff_entry(subfeature, new_feature_list, new_transcript_list, source, - # disable_cds_recalculation, use_name) - # else: - # print("CCCCCC") - # # if its not a gene or a transcript type then process as a simple singleton - # feature_data = features_to_feature_schema([rec.features[0]], disable_cds_recalculation, use_name) - # if source is not None: - # add_property_to_feature(feature_data[0], "DatasetSource", source) - # if verbose: - # print("adding " + str(type) + " to write list: " + str(feature_data[0])) - # new_feature_list.append(feature_data[0]) - # else: - # print("DDDDDD") - # if type in util.gene_types: - # print("EEEEEE") - # transcript_type = self._get_subfeature_type(rec) - # if transcript_type in util.coding_transcript_types: - # print("FFFFFF") - # feature_data = features_to_feature_schema(subfeatures, use_name=use_name, - # disable_cds_recalculation=disable_cds_recalculation) - # if source is not None: - # add_property_to_feature(feature_data[0], "DatasetSource", source) - # new_transcript_list.append(feature_data) - # if verbose: - # print("adding gene with MRNA type " + str(type) + " to write list: " + str(feature_data)) - # else: - # print("GGGGGG") - # feature_data = features_to_feature_schema(rec.features, use_name=use_name, - # disable_cds_recalculation=disable_cds_recalculation) - # if verbose: - # print("adding gene with noncoding transcript type " + str(type) + " to write list: " + str( - # feature_data)) - # if source is not None: - # add_property_to_feature(feature_data[0], "DatasetSource", source) - # new_feature_list.append(feature_data) - # # self._process_gene(rec.features) - # elif type in util.coding_transcript_types: - # print("HHHHHH") - # feature_data = features_to_apollo_schema(rec.features, use_name=use_name, disable_cds_recalculation=disable_cds_recalculation) - # if source is not None: - # add_property_to_feature(feature_data[0], "DatasetSource", source) - # if verbose: - # print("adding transcript type " + str(type) + " to write list: " + str(feature_data)) - # new_transcript_list.append(feature_data) - # else: - # print("how did we get here?") - # - # # a gene or a transcript - # - return_object = {} - return_object['features'] = [feature_data] + print("unknown type " + type + " ") + if feature_data is not None: + all_features.append(feature_data) + + return_object = {'features': all_features} return return_object def load_gff3(self, organism, gff3, source=None, batch_size=1, diff --git a/apollo/util.py b/apollo/util.py index a01efe5f..3d0caeb3 100644 --- a/apollo/util.py +++ b/apollo/util.py @@ -95,18 +95,23 @@ def _tnType(feature): return 'exon' -def _yieldGeneData(features, disable_cds_recalculation=False, use_name=False): - f = features[0] - current = _yieldSubFeatureData(f, disable_cds_recalculation=disable_cds_recalculation, use_name=use_name) - sub_features = features[1:] +def _yieldGeneData(gene, disable_cds_recalculation=False, use_name=False): + current = _yieldSubFeatureData(gene, disable_cds_recalculation=disable_cds_recalculation, use_name=use_name) + sub_features = gene.sub_features + print("yielding gene data current " + str(current)) if sub_features: current['children'] = [] for sf in sub_features: - if _tnType(sf) in coding_transcript_types + noncoding_transcript_types: - current['children'].append( - _yieldCodingTranscriptData(sf, disable_cds_recalculation=disable_cds_recalculation, - use_name=use_name)) + if _tnType(sf) in coding_transcript_types: + child_data = _yieldCodingTranscriptData(sf, disable_cds_recalculation=disable_cds_recalculation, + use_name=use_name) + print("child data" + str(child_data)) + current['children'].append(child_data) + if _tnType(sf) in noncoding_transcript_types: + child_data = _yieldCodingTranscriptData(sf, disable_cds_recalculation=disable_cds_recalculation, + use_name=use_name) + current['children'].append(child_data) # current = { # 'location': { @@ -175,8 +180,7 @@ def _yieldSubFeatureData(f, disable_cds_recalculation=False, use_name=False): return current -def _yieldCodingTranscriptData(features, disable_cds_recalculation=False, use_name=False): - f = features[0] +def _yieldCodingTranscriptData(f, disable_cds_recalculation=False, use_name=False): current = { 'location': { 'strand': f.strand, @@ -190,17 +194,21 @@ def _yieldCodingTranscriptData(features, disable_cds_recalculation=False, use_na } }, } - subfeatures = features[1:] - if len(subfeatures) > 0: + if len(f.sub_features) > 0: current['children'] = [] - - for sf in subfeatures: - current['children'].append( - _yieldSubFeatureData(sf, disable_cds_recalculation=disable_cds_recalculation, use_name=use_name)) + for sf in f.sub_features: + current['children'].append( + _yieldSubFeatureData(sf, disable_cds_recalculation=disable_cds_recalculation, use_name=use_name)) return current +def print_file(path): + with open(path) as file: + print(file.read()) + file.close() + + # def _yieldNonCodingTranscriptData(features): # pass @@ -209,23 +217,23 @@ def _yieldCodingTranscriptData(features, disable_cds_recalculation=False, use_na # return _yieldSubFeatureData(features[0]) -def _yieldApolloData(features, use_name=False, disable_cds_recalculation=False): - current_feature = features[0] - if _tnType(current_feature) in gene_types: - return _yieldGeneData(features) - if _tnType(current_feature) in pseudogenes_types: - return _yieldGeneData(features) - elif _tnType(current_feature) in coding_transcript_types: - return _yieldCodingTranscriptData(features) - elif _tnType(current_feature) in noncoding_transcript_types: - return _yieldCodingTranscriptData(features) - # return _yieldNonCodingTranscriptData(features) - elif _tnType(current_feature) in single_level_feature_types: - # return _yieldSingleLevelFeatureData(features) - return _yieldSubFeatureData(features) +def yieldApolloData(feature, use_name=False, disable_cds_recalculation=False): + feature_type = _tnType(feature) + if feature_type in gene_types: + return _yieldGeneData(feature) + if feature_type in pseudogenes_types: + return _yieldGeneData(feature) + elif feature_type in coding_transcript_types: + return _yieldCodingTranscriptData(feature) + elif feature_type in noncoding_transcript_types: + return _yieldCodingTranscriptData(feature) + # return _yieldNonCodingTranscriptData(current_feature) + elif feature_type in single_level_feature_types: + # return _yieldSingleLevelFeatureData(current_feature) + return _yieldSubFeatureData(feature) else: - print("nothing there") - return None + print("other type: " + feature_type) + return _yieldSubFeatureData(feature) # for f in features: # @@ -334,8 +342,11 @@ def features_to_apollo_schema(features, use_name=False, disable_cds_recalculatio :return: """ compiled = [] - for x in _yieldApolloData(features, use_name, disable_cds_recalculation): - compiled.append(x) + # for x in _yieldApolloData(features, use_name, disable_cds_recalculation): + # compiled.append(x) + # return compiled + for f in features: + compiled.append(yieldApolloData(f, use_name=use_name, disable_cds_recalculation=disable_cds_recalculation)) return compiled diff --git a/test-data/mrna-top.gff b/test-data/mrna-top.gff index 41b4081f..5933bc2a 100644 --- a/test-data/mrna-top.gff +++ b/test-data/mrna-top.gff @@ -1,5 +1,5 @@ ##gff-version 3 ##sequence-region Merlin 1 172788 -Merlin GeneMark.hmm mRNA 2 691 . + . ID=Merlin_1_mRNA;Parent=Merlin_1;seqid=Merlin;color=#00ff00 +Merlin GeneMark.hmm mRNA 2 691 . + . ID=Merlin_1_mRNA;seqid=Merlin;color=#00ff00 Merlin GeneMark.hmm exon 2 691 . + . ID=Merlin_1_exon;Parent=Merlin_1_mRNA;seqid=Merlin -Merlin GeneMark.hmm CDS 2 691 . + 0 ID=Merlin_1_CDS;Parent=Merlin_1_exon;seqid=Merlin +Merlin GeneMark.hmm CDS 2 691 . + 0 ID=Merlin_1_CDS;Parent=Merlin_1_mRNA;seqid=Merlin diff --git a/test-data/ncrna-top.gff b/test-data/ncrna-top.gff index 65f352d0..b7c52e08 100644 --- a/test-data/ncrna-top.gff +++ b/test-data/ncrna-top.gff @@ -1,4 +1,4 @@ ##gff-version 3 ##sequence-region Merlin 1 172788 -Merlin GeneMark.hmm ncRNA 2 691 . + . ID=Merlin_1_mRNA;Parent=Merlin_1;seqid=Merlin;color=#00ff00 +Merlin GeneMark.hmm ncRNA 2 691 . + . ID=Merlin_1_mRNA;seqid=Merlin;color=#00ff00 Merlin GeneMark.hmm exon 2 691 . + . ID=Merlin_1_exon;Parent=Merlin_1_mRNA;seqid=Merlin diff --git a/test/annotations_test.py b/test/annotations_test.py index 497129f9..9c2afb42 100644 --- a/test/annotations_test.py +++ b/test/annotations_test.py @@ -22,10 +22,11 @@ def test_features_to_apollo_schema_mrna(self): feature_data = None for rec in GFF.parse(in_handle): # feature_data = util.features_to_apollo_schema(rec.features, feature_list, transcript_list) - feature_data = util._yieldApolloData(rec.features) + # feature_data = util.features_to_apollo_schema(rec.features) + for f in rec.features: + feature_data = util.yieldApolloData(f) in_handle.close() - print(str(feature_data)) assert (feature_data['location'] is not None) assert (len(feature_data['children']) == 2) @@ -65,8 +66,8 @@ def test_features_to_apollo_schema_gene(self): print(str(feature_data)) print("final feature list " + str(new_feature_list)) print("final transcript list " + str(new_transcript_list)) - assert (feature_data['location'] is not None) - assert (len(feature_data['children']) == 2) + # assert (feature_data['location'] is not None) + # assert (len(feature_data['children']) == 2) def test_create_mrna(self): path = 'test-data/mrna-top.gff' @@ -123,13 +124,11 @@ def test_create_pseudogene(self): assert (len(transcript_list) == 0) print(transcript_list) - def test_create_ncRNA(self): - path = 'test-data/ncrna-top.gff' - with open(path) as file: - print(file.read()) - file.close() + def test_create_ncRNA(self): + path = 'test-data/ncrna-top.gff' + util.print_file(path) feature_list = [] transcript_list = [] in_handle = open(path) @@ -137,17 +136,12 @@ def test_create_ncRNA(self): wa.annotations._process_gff_entry(rec, feature_list, transcript_list) in_handle.close() - assert (len(feature_list) == 0) - assert (len(transcript_list) == 1) - print(transcript_list) + assert (len(feature_list) == 1) + assert (len(transcript_list) == 0) def test_create_repeat_region(self): path = 'test-data/repeat-region-top.gff' - - with open(path) as file: - print(file.read()) - file.close() - + util.print_file(path) feature_list = [] transcript_list = [] in_handle = open(path)