diff --git a/uk/ac/sanger/artemis/io/GFFUtils.java b/uk/ac/sanger/artemis/io/GFFUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..96cefa46d98313c5630d18cc58c3de034891548f --- /dev/null +++ b/uk/ac/sanger/artemis/io/GFFUtils.java @@ -0,0 +1,125 @@ +/* GFFUtils.java + * This file is part of Artemis + * + * Copyright (C) 2013 Genome Research Limited + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ +package uk.ac.sanger.artemis.io; + +import java.util.Vector; + +import uk.ac.sanger.artemis.components.genebuilder.GeneUtils; + + +public class GFFUtils +{ + /** + * Test if this is feature is marked as having a stop codon + * redefined as selenocysteine + * @param f + * @return + */ + public static boolean isSelenocysteine(Feature f) + { + if(!(f instanceof GFFStreamFeature)) + return false; + try + { + ChadoCanonicalGene gffGene = ((GFFStreamFeature)f).getChadoGene(); + if(gffGene == null) + return false; + String transcript = gffGene.getTranscriptFromName( + GeneUtils.getUniqueName(f)); + if(transcript == null) + return false; + Feature pep = gffGene.getProteinOfTranscript(transcript); + if(pep == null) + return false; + if(pep.getQualifierByName("stop_codon_redefined_as_selenocysteine") != null) + return true; + } + catch (Exception e){} + + return false; + } + + /** + * Update the segment range store for GFFStreamFeature with a new location + * @param gff + * @param oldLocation + * @param newLocation + */ + public static void updateSegmentRangeStore(final GFFStreamFeature gff, + final Location oldLocation, + final Location newLocation) + { + final RangeVector rv_new = newLocation.getRanges(); + final RangeVector rv_old = oldLocation.getRanges(); + if(rv_new.size() != rv_old.size()) + { + final RangeVector rangesToAdd = new RangeVector(); + for(Range r: rv_new) + if(!rv_old.containsRange(r)) + rangesToAdd.add(r); + + final Vector<Integer> deleted = new Vector<Integer>(); + for(int ideleted = 0; ideleted < rv_old.size(); ideleted++) + if(!rv_new.containsRange(rv_old.get(ideleted))) + deleted.add(ideleted); + + try + { + if(gff.getQualifierByName("Parent") != null) + GeneUtils.addSegment(gff, rangesToAdd, + gff.getQualifierByName("Parent").getValues().get(0)); + } + catch(Exception e) + { + e.printStackTrace(); + } + + for(Integer d: deleted) + gff.getSegmentRangeStore().remove( + gff.getSegmentID(rv_old.elementAt(d))); + } + else if(gff.getSegmentRangeStore() != null) + { + Vector<Integer> changes = new Vector<Integer>(); + for(int i=0; i<rv_old.size(); i++) + { + Range rnew = rv_new.elementAt(i); + Range rold = rv_old.elementAt(i); + + if(rnew.getStart() != rold.getStart() || + rnew.getEnd() != rold.getEnd() || + (oldLocation.isComplement(rold) != + newLocation.isComplement(rnew))) + changes.add(i); + } + + for(Integer c: changes) + { + Range rnew = rv_new.elementAt(c); + String segId = gff.getSegmentID(rnew); + if(segId == null) + segId = gff.getSegmentID(rv_old.elementAt(c)); + gff.getSegmentRangeStore().put(segId, rnew); + } + } + } + +} \ No newline at end of file