further bugfix and annotation transfer for dna/protein (still issues with non-codon...
[jalview.git] / src / jalview / analysis / Dna.java
1 package jalview.analysis;\r
2 \r
3 import java.util.Enumeration;\r
4 import java.util.Hashtable;\r
5 import java.util.Vector;\r
6 \r
7 import jalview.datamodel.AlignedCodonFrame;\r
8 import jalview.datamodel.Alignment;\r
9 import jalview.datamodel.AlignmentAnnotation;\r
10 import jalview.datamodel.AlignmentI;\r
11 import jalview.datamodel.Annotation;\r
12 import jalview.datamodel.ColumnSelection;\r
13 import jalview.datamodel.DBRefEntry;\r
14 import jalview.datamodel.FeatureProperties;\r
15 import jalview.datamodel.Mapping;\r
16 import jalview.datamodel.Sequence;\r
17 import jalview.datamodel.SequenceFeature;\r
18 import jalview.datamodel.SequenceI;\r
19 import jalview.schemes.ResidueProperties;\r
20 import jalview.util.MapList;\r
21 import jalview.util.ShiftList;\r
22 \r
23 public class Dna\r
24 {\r
25   /**\r
26    * \r
27    * @param cdp1\r
28    * @param cdp2\r
29    * @return -1 if cdp1 aligns before cdp2, 0 if in the same column or cdp2 is\r
30    *         null, +1 if after cdp2\r
31    */\r
32   private static int compare_codonpos(int[] cdp1, int[] cdp2)\r
33   {\r
34     if (cdp2 == null\r
35             || (cdp1[0] == cdp2[0] && cdp1[1] == cdp2[1] && cdp1[2] == cdp2[2]))\r
36       return 0;\r
37     if (cdp1[0] < cdp2[0] || cdp1[1] < cdp2[1] || cdp1[2] < cdp2[2])\r
38       return -1; // one base in cdp1 precedes the corresponding base in the\r
39     // other codon\r
40     return 1; // one base in cdp1 appears after the corresponding base in the\r
41     // other codon.\r
42   }\r
43 \r
44   /**\r
45    * DNA->mapped protein sequence alignment translation given set of sequences\r
46    * 1. id distinct coding regions within selected region for each sequence 2.\r
47    * generate peptides based on inframe (or given) translation or (optionally\r
48    * and where specified) out of frame translations (annotated appropriately) 3.\r
49    * align peptides based on codon alignment\r
50    */\r
51   /**\r
52    * id potential products from dna 1. search for distinct products within\r
53    * selected region for each selected sequence 2. group by associated DB type.\r
54    * 3. return as form for input into above function\r
55    */\r
56   /**\r
57    * \r
58    */\r
59   /**\r
60    * create a new alignment of protein sequences by an inframe translation of\r
61    * the provided NA sequences\r
62    * \r
63    * @param selection\r
64    * @param seqstring\r
65    * @param viscontigs\r
66    * @param gapCharacter\r
67    * @param annotations\r
68    * @param aWidth\r
69    * @param dataset destination dataset for translated sequences and mappings\r
70    * @return\r
71    */\r
72   public static AlignmentI CdnaTranslate(SequenceI[] selection,\r
73           String[] seqstring, int viscontigs[], char gapCharacter,\r
74           AlignmentAnnotation[] annotations, int aWidth, Alignment dataset)\r
75   {\r
76     return CdnaTranslate(selection, seqstring, null, viscontigs,\r
77             gapCharacter, annotations, aWidth, dataset);\r
78   }\r
79 \r
80   /**\r
81    * \r
82    * @param selection\r
83    * @param seqstring\r
84    * @param product - array of DbRefEntry objects from which exon map in seqstring is derived\r
85    * @param viscontigs\r
86    * @param gapCharacter\r
87    * @param annotations\r
88    * @param aWidth\r
89    * @param dataset\r
90    * @return\r
91    */\r
92   public static AlignmentI CdnaTranslate(SequenceI[] selection,\r
93           String[] seqstring, DBRefEntry[] product, int viscontigs[],\r
94           char gapCharacter, AlignmentAnnotation[] annotations, int aWidth, Alignment dataset)\r
95   {\r
96     AlignedCodonFrame codons = new AlignedCodonFrame(aWidth); // stores hash of\r
97     // subsequent\r
98     // positions for\r
99     // each codon\r
100     // start position\r
101     // in alignment\r
102     int s, sSize = selection.length;\r
103     Vector pepseqs = new Vector();\r
104     for (s = 0; s < sSize; s++)\r
105     {\r
106       SequenceI newseq = translateCodingRegion(selection[s], seqstring[s],\r
107               viscontigs, codons, gapCharacter, (product!=null) ? product[s] : null); // possibly anonymous product\r
108       if (newseq != null)\r
109       {\r
110         pepseqs.addElement(newseq);\r
111         SequenceI ds = newseq;\r
112         while (ds.getDatasetSequence()!=null)\r
113         {\r
114           ds = ds.getDatasetSequence();\r
115         }\r
116         dataset.addSequence(ds);\r
117       }\r
118     }\r
119     if (codons.aaWidth == 0)\r
120       return null;\r
121     SequenceI[] newseqs = new SequenceI[pepseqs.size()];\r
122     pepseqs.copyInto(newseqs);\r
123     AlignmentI al = new Alignment(newseqs);\r
124     al.padGaps(); // ensure we look aligned.\r
125     al.setDataset(dataset);\r
126     translateAlignedAnnotations(annotations, al, codons);\r
127     al.addCodonFrame(codons);\r
128     return al;\r
129   }\r
130   /**\r
131    * fake the collection of DbRefs with associated exon mappings to identify\r
132    * if a translation would generate distinct product in the currently selected region.\r
133    * @param selection\r
134    * @param viscontigs\r
135    * @return\r
136    */\r
137   public static boolean canTranslate(SequenceI[] selection, int viscontigs[])\r
138   {\r
139     for (int gd=0; gd<selection.length; gd++)\r
140     {\r
141       SequenceI dna = selection[gd];\r
142       jalview.datamodel.DBRefEntry[] dnarefs = jalview.util.DBRefUtils\r
143       .selectRefs(dna.getDBRef(),\r
144               jalview.datamodel.DBRefSource.DNACODINGDBS);\r
145       if (dnarefs != null)\r
146       {\r
147         // intersect with pep\r
148         // intersect with pep\r
149         Vector mappedrefs = new Vector();\r
150         DBRefEntry[] refs=dna.getDBRef();\r
151         for (int d=0; d<refs.length; d++)\r
152         {\r
153           if (refs[d].getMap()!=null && refs[d].getMap().getMap()!=null && refs[d].getMap().getMap().getFromRatio()==3\r
154                   && refs[d].getMap().getMap().getToRatio()==1)\r
155           {\r
156             mappedrefs.addElement(refs[d]); // add translated protein maps\r
157           }\r
158         }\r
159         dnarefs = new DBRefEntry[mappedrefs.size()];\r
160         mappedrefs.copyInto(dnarefs);\r
161         for (int d = 0; d < dnarefs.length; d++)\r
162         {\r
163           Mapping mp = dnarefs[d].getMap();\r
164           if (mp != null)\r
165           {\r
166             for (int vc=0; vc<viscontigs.length; vc+=2)\r
167             {\r
168               int[] mpr=mp.locateMappedRange(viscontigs[vc], viscontigs[vc+1]);\r
169               if (mpr!=null) {\r
170                 return true;\r
171               }\r
172             }\r
173           }\r
174         }\r
175       }\r
176     }\r
177     return false;\r
178   }\r
179   /**\r
180    * generate a set of translated protein products from annotated sequenceI\r
181    * @param selection\r
182    * @param viscontigs\r
183    * @param gapCharacter\r
184    * @param dataset destination dataset for translated sequences\r
185    * @param annotations\r
186    * @param aWidth\r
187    * @return\r
188    */\r
189   public static AlignmentI CdnaTranslate(SequenceI[] selection,\r
190           int viscontigs[], char gapCharacter, Alignment dataset)\r
191   {\r
192     int alwidth=0;\r
193     Vector cdnasqs=new Vector();\r
194     Vector cdnasqi=new Vector();\r
195     Vector cdnaprod=new Vector();\r
196     for (int gd=0; gd<selection.length; gd++)\r
197     {\r
198       SequenceI dna = selection[gd];\r
199       jalview.datamodel.DBRefEntry[] dnarefs = jalview.util.DBRefUtils\r
200       .selectRefs(dna.getDBRef(),\r
201               jalview.datamodel.DBRefSource.DNACODINGDBS);\r
202       if (dnarefs != null)\r
203       {\r
204         // intersect with pep\r
205         Vector mappedrefs = new Vector();\r
206         DBRefEntry[] refs=dna.getDBRef();\r
207         for (int d=0; d<refs.length; d++)\r
208         {\r
209           if (refs[d].getMap()!=null && refs[d].getMap().getMap()!=null && refs[d].getMap().getMap().getFromRatio()==3\r
210                   && refs[d].getMap().getMap().getToRatio()==1)\r
211           {\r
212             mappedrefs.addElement(refs[d]); // add translated protein maps\r
213           }\r
214         }\r
215         dnarefs = new DBRefEntry[mappedrefs.size()];\r
216         mappedrefs.copyInto(dnarefs);\r
217         for (int d = 0; d < dnarefs.length; d++)\r
218         {\r
219           Mapping mp = dnarefs[d].getMap();\r
220           StringBuffer sqstr=new StringBuffer();\r
221           if (mp != null)\r
222           {\r
223             Mapping intersect = mp.intersectVisContigs(viscontigs);\r
224             // generate seqstring for this sequence based on mapping\r
225             \r
226             if (sqstr.length()>alwidth)\r
227               alwidth = sqstr.length();\r
228             cdnasqs.addElement(sqstr.toString());\r
229             cdnasqi.addElement(dna);\r
230             cdnaprod.addElement(intersect);\r
231           }\r
232         }\r
233       }\r
234       SequenceI[] cdna = new SequenceI[cdnasqs.size()];\r
235       DBRefEntry[] prods = new DBRefEntry[cdnaprod.size()];\r
236       String[] xons = new String[cdnasqs.size()];\r
237       cdnasqs.copyInto(xons);\r
238       cdnaprod.copyInto(prods);\r
239       cdnasqi.copyInto(cdna);\r
240       return CdnaTranslate(cdna, xons, prods, viscontigs, gapCharacter, null, alwidth, dataset);\r
241     }\r
242     return null;\r
243   }\r
244 \r
245   /**\r
246    * translate na alignment annotations onto translated amino acid alignment al\r
247    * using codon mapping codons\r
248    * \r
249    * @param annotations\r
250    * @param al\r
251    * @param codons\r
252    */\r
253   public static void translateAlignedAnnotations(\r
254           AlignmentAnnotation[] annotations, AlignmentI al,\r
255           AlignedCodonFrame codons)\r
256   {\r
257     // //////////////////////////////\r
258     // Copy annotations across\r
259     //\r
260     // Can only do this for columns with consecutive codons, or where\r
261     // annotation is sequence associated.\r
262 \r
263     int pos, a, aSize;\r
264     if (annotations != null)\r
265     {\r
266       for (int i = 0; i < annotations.length; i++)\r
267       {\r
268         // Skip any autogenerated annotation\r
269         if (annotations[i].autoCalculated)\r
270         {\r
271           continue;\r
272         }\r
273 \r
274         aSize = codons.getaaWidth(); // aa alignment width.\r
275         jalview.datamodel.Annotation[] anots = (annotations[i].annotations == null) ? null\r
276                 : new jalview.datamodel.Annotation[aSize];\r
277         if (anots != null)\r
278         {\r
279           for (a = 0; a < aSize; a++)\r
280           {\r
281             // process through codon map.\r
282             if (codons.codons[a] != null\r
283                     && codons.codons[a][0] == (codons.codons[a][2] - 2))\r
284             {\r
285               anots[a] = getCodonAnnotation(codons.codons[a], annotations[i].annotations);\r
286             }\r
287           }\r
288         }\r
289 \r
290         jalview.datamodel.AlignmentAnnotation aa = new jalview.datamodel.AlignmentAnnotation(\r
291                 annotations[i].label, annotations[i].description, anots);\r
292         aa.graph = annotations[i].graph;\r
293         aa.graphGroup = annotations[i].graphGroup;\r
294         aa.graphHeight = annotations[i].graphHeight;\r
295         if (annotations[i].getThreshold()!=null)\r
296         {\r
297           aa.setThreshold(new jalview.datamodel.GraphLine(annotations[i].getThreshold()));        \r
298         }\r
299         if (annotations[i].hasScore)\r
300         {\r
301           aa.setScore(annotations[i].getScore());\r
302         }\r
303         if (annotations[i].sequenceRef != null)\r
304         {\r
305           SequenceI aaSeq = codons\r
306                   .getAaForDnaSeq(annotations[i].sequenceRef);\r
307           if (aaSeq != null)\r
308           {\r
309             // aa.compactAnnotationArray(); // throw away alignment annotation\r
310             // positioning\r
311             aa.setSequenceRef(aaSeq);\r
312             aa.createSequenceMapping(aaSeq, aaSeq.getStart(), true); // rebuild\r
313             // mapping\r
314             aa.adjustForAlignment();\r
315             aaSeq.addAlignmentAnnotation(aa);\r
316           }\r
317 \r
318         }\r
319         al.addAnnotation(aa);\r
320       }\r
321     }\r
322   }\r
323 \r
324   private static Annotation getCodonAnnotation(int[] is, Annotation[] annotations)\r
325   { \r
326     // Have a look at all the codon positions for annotation and put the first\r
327     // one found into the translated annotation pos.\r
328     for (int p=0; p<3; p++)\r
329     {\r
330       if (annotations[is[p]]!=null)\r
331       {\r
332         return new Annotation(annotations[is[p]]);\r
333       }\r
334     }\r
335     return null;\r
336   }\r
337 \r
338   /**\r
339    * Translate a na sequence\r
340    * \r
341    * @param selection sequence displayed under viscontigs visible columns\r
342    * @param seqstring ORF read in some global alignment reference frame\r
343    * @param viscontigs mapping from global reference frame to visible seqstring ORF read\r
344    * @param codons Definition of global ORF alignment reference frame\r
345    * @param gapCharacter\r
346    * @param newSeq\r
347    * @return sequence ready to be added to alignment.\r
348    */\r
349   public static SequenceI translateCodingRegion(SequenceI selection,\r
350           String seqstring, int[] viscontigs, AlignedCodonFrame codons,\r
351           char gapCharacter, DBRefEntry product)\r
352   {\r
353     Vector skip=new Vector();\r
354     int skipint[]=null;\r
355     ShiftList vismapping = new ShiftList(); // map from viscontigs to seqstring\r
356     // intervals\r
357     int vc, scontigs[] = new int[viscontigs.length];\r
358     int npos = 0;\r
359     for (vc = 0; vc < viscontigs.length; vc += 2)\r
360     {\r
361       if (vc==0) {\r
362       vismapping.addShift(npos, viscontigs[vc]);\r
363       } else {\r
364         // hidden region\r
365         vismapping.addShift(npos, viscontigs[vc]-viscontigs[vc-1]+1);\r
366       }\r
367       scontigs[vc] = viscontigs[vc];\r
368       scontigs[vc + 1] = viscontigs[vc+1];\r
369     }\r
370 \r
371     StringBuffer protein = new StringBuffer();\r
372     String seq = seqstring.replace('U', 'T');\r
373     char codon[] = new char[3];\r
374     int cdp[] = new int[3], rf = 0, lastnpos = 0, nend;\r
375     int aspos = 0;\r
376     int resSize = 0;\r
377     for (npos = 0, nend = seq.length(); npos < nend; npos++)\r
378     {\r
379       if (!jalview.util.Comparison.isGap(seq.charAt(npos)))\r
380       {\r
381         cdp[rf] = npos; // store position\r
382         codon[rf++] = seq.charAt(npos); // store base\r
383       }\r
384       // filled an RF yet ?\r
385       if (rf == 3)\r
386       {\r
387         String aa = ResidueProperties.codonTranslate(new String(codon));\r
388         rf = 0;\r
389         if (aa == null)\r
390         {\r
391           aa = String.valueOf(gapCharacter);\r
392           if (skipint==null)\r
393           {\r
394             skipint = new int[] { cdp[0],cdp[2] };\r
395           }\r
396           skipint[1] = cdp[2];\r
397         } else {\r
398           if (skipint!=null)\r
399           {\r
400             // edit scontigs\r
401             skipint[0] = vismapping.shift(skipint[0]);\r
402             skipint[1] = vismapping.shift(skipint[1]);\r
403             for (vc=0; vc<scontigs.length; vc+=2)\r
404             {\r
405               if (scontigs[vc+1]<skipint[0])\r
406               {\r
407                 continue;\r
408               }\r
409               if (scontigs[vc]<=skipint[0])\r
410               {\r
411                if (skipint[0]==scontigs[vc])\r
412                {\r
413                  \r
414                } else {\r
415                  int[] t = new int[scontigs.length+2];\r
416                  System.arraycopy(scontigs, 0, t, 0, vc-1);\r
417                  // scontigs[vc]; //\r
418                }\r
419               }\r
420             }\r
421             skip.addElement(skipint);\r
422             skipint=null;\r
423           }\r
424           if (aa.equals("STOP"))\r
425           {\r
426             aa = "X";\r
427           }\r
428           resSize++;\r
429         }\r
430         // insert/delete gaps prior to this codon - if necessary\r
431         boolean findpos = true;\r
432         while (findpos)\r
433         {\r
434           // first ensure that the codons array is long enough.\r
435           codons.checkCodonFrameWidth(aspos);\r
436           // now check to see if we place the aa at the current aspos in the\r
437           // protein alignment\r
438           switch (Dna.compare_codonpos(cdp, codons.codons[aspos]))\r
439           {\r
440           case -1:\r
441             codons.insertAAGap(aspos, gapCharacter);\r
442             findpos = false;\r
443             break;\r
444           case +1:\r
445             // this aa appears after the aligned codons at aspos, so prefix it\r
446             // with a gap\r
447             aa = "" + gapCharacter + aa;\r
448             aspos++;\r
449             //if (aspos >= codons.aaWidth)\r
450             //  codons.aaWidth = aspos + 1;\r
451             break; // check the next position for alignment\r
452           case 0:\r
453             // codon aligns at aspos position.\r
454             findpos = false;\r
455           }\r
456         }\r
457         // codon aligns with all other sequence residues found at aspos\r
458         protein.append(aa);\r
459         lastnpos = npos;\r
460         if (codons.codons[aspos] == null)\r
461         {\r
462           // mark this column as aligning to this aligned reading frame\r
463           codons.codons[aspos] = new int[]\r
464           { cdp[0], cdp[1], cdp[2] };\r
465         }\r
466         aspos++;\r
467         if (aspos >= codons.aaWidth)\r
468         {\r
469           codons.aaWidth = aspos + 1;\r
470         }\r
471       }\r
472     }\r
473     if (resSize > 0)\r
474     {\r
475       SequenceI newseq = new Sequence(selection.getName(), protein\r
476               .toString());\r
477       if (rf != 0)\r
478       {\r
479         jalview.bin.Cache.log\r
480                 .debug("trimming contigs for incomplete terminal codon.");\r
481         // map and trim contigs to ORF region\r
482         vc = scontigs.length - 1;\r
483         lastnpos = vismapping.shift(lastnpos); // place npos in context of\r
484         // whole dna alignment (rather\r
485         // than visible contigs)\r
486         // incomplete ORF could be broken over one or two visible contig\r
487         // intervals.\r
488         while (vc >= 0 && scontigs[vc] > lastnpos)\r
489         {\r
490           if (vc > 0 && scontigs[vc - 1] > lastnpos)\r
491           {\r
492             vc -= 2;\r
493           }\r
494           else\r
495           {\r
496             // correct last interval in list.\r
497             scontigs[vc] = lastnpos;\r
498           }\r
499         }\r
500 \r
501         if (vc > 0 && (vc + 1) < scontigs.length)\r
502         {\r
503           // truncate map list to just vc elements\r
504           int t[] = new int[vc + 1];\r
505           System.arraycopy(scontigs, 0, t, 0, vc + 1);\r
506           scontigs = t;\r
507         }\r
508         if (vc <= 0)\r
509           scontigs = null;\r
510       }\r
511       if (scontigs != null)\r
512       {\r
513         npos = 0;\r
514         // map scontigs to actual sequence positions on selection\r
515         for (vc = 0; vc < scontigs.length; vc += 2)\r
516         {\r
517           scontigs[vc] = selection.findPosition(scontigs[vc]); // not from 1!\r
518           scontigs[vc + 1] = selection\r
519                   .findPosition(scontigs[vc + 1]); // exclusive\r
520           if (scontigs[vc + 1] == selection.getEnd())\r
521             break;\r
522         }\r
523         // trim trailing empty intervals.\r
524         if ((vc + 2) < scontigs.length)\r
525         {\r
526           int t[] = new int[vc + 2];\r
527           System.arraycopy(scontigs, 0, t, 0, vc + 2);\r
528           scontigs = t;\r
529         }\r
530         /*\r
531          * delete intervals in scontigs which are not translated.\r
532          * 1. map skip into sequence position intervals\r
533          * 2. truncate existing ranges and add new ranges to exclude untranslated regions.\r
534         if (skip.size()>0)\r
535         {\r
536           Vector narange = new Vector();\r
537           for (vc=0; vc<scontigs.length; vc++)\r
538           {\r
539             narange.addElement(new int[] {scontigs[vc]});\r
540           }\r
541           int sint=0,iv[];\r
542           vc = 0;\r
543           while (sint<skip.size())\r
544           {\r
545             skipint = (int[]) skip.elementAt(sint);\r
546             do {\r
547               iv = (int[]) narange.elementAt(vc);\r
548               if (iv[0]>=skipint[0] && iv[0]<=skipint[1])\r
549               {\r
550                 if (iv[0]==skipint[0])\r
551                 {\r
552                   // delete beginning of range\r
553                 } else {\r
554                   // truncate range and create new one if necessary\r
555                   iv = (int[]) narange.elementAt(vc+1);\r
556                   if (iv[0]<=skipint[1])\r
557                   {\r
558                     // truncate range\r
559                     iv[0] = skipint[1];\r
560                   } else {\r
561                     \r
562                   }\r
563                 }\r
564               } else\r
565                 if (iv[0]<skipint[0])\r
566                 {\r
567                   iv = (int[]) narange.elementAt(vc+1);\r
568                 }\r
569             } while (iv[0])\r
570           }\r
571         }*/\r
572         MapList map = new MapList(scontigs, new int[]\r
573                                                     { 1, resSize }, 3, 1);\r
574         \r
575         // update newseq as if it was generated as mapping from product\r
576         \r
577         if (product != null)\r
578         {\r
579           newseq.setName(product.getSource() + "|"\r
580                   + product.getAccessionId());\r
581           if (product.getMap() != null)\r
582           {\r
583             //Mapping mp = product.getMap();\r
584             //newseq.setStart(mp.getPosition(scontigs[0]));\r
585             //newseq.setEnd(mp\r
586             //        .getPosition(scontigs[scontigs.length - 1]));\r
587           }\r
588         }\r
589         transferCodedFeatures(selection, newseq, map, null, null);\r
590         SequenceI rseq = newseq.deriveSequence(); // construct a dataset\r
591         // sequence for our new\r
592         // peptide, regardless.\r
593         // store a mapping (this actually stores a mapping between the dataset\r
594         // sequences for the two sequences\r
595         codons.addMap(selection, rseq, map);\r
596         return rseq;\r
597       }\r
598     }\r
599     // register the mapping somehow\r
600     // \r
601     return null;\r
602   }\r
603 \r
604   /**\r
605    * Given a peptide newly translated from a dna sequence, copy over and set any\r
606    * features on the peptide from the DNA. If featureTypes is null, all features\r
607    * on the dna sequence are searched (rather than just the displayed ones), and\r
608    * similarly for featureGroups.\r
609    * \r
610    * @param dna\r
611    * @param pep\r
612    * @param map\r
613    * @param featureTypes\r
614    *          hash who's keys are the displayed feature type strings\r
615    * @param featureGroups\r
616    *          hash where keys are feature groups and values are Boolean objects\r
617    *          indicating if they are displayed.\r
618    */\r
619   private static void transferCodedFeatures(SequenceI dna, SequenceI pep,\r
620           MapList map, Hashtable featureTypes, Hashtable featureGroups)\r
621   {\r
622     SequenceFeature[] sf = dna.getDatasetSequence().getSequenceFeatures();\r
623     Boolean fgstate;\r
624     jalview.datamodel.DBRefEntry[] dnarefs = jalview.util.DBRefUtils\r
625             .selectRefs(dna.getDBRef(),\r
626                     jalview.datamodel.DBRefSource.DNACODINGDBS);\r
627     if (dnarefs != null)\r
628     {\r
629       // intersect with pep\r
630       for (int d = 0; d < dnarefs.length; d++)\r
631       {\r
632         Mapping mp = dnarefs[d].getMap();\r
633         if (mp != null)\r
634         {\r
635         }\r
636       }\r
637     }\r
638     if (sf != null)\r
639     {\r
640       for (int f = 0; f < sf.length; f++)\r
641       {\r
642         fgstate = (featureGroups == null) ? null : ((Boolean) featureGroups\r
643                 .get(sf[f].featureGroup));\r
644         if ((featureTypes == null || featureTypes.containsKey(sf[f]\r
645                 .getType()))\r
646                 && (fgstate == null || fgstate.booleanValue()))\r
647         {\r
648           if (FeatureProperties.isCodingFeature(null, sf[f].getType()))\r
649           {\r
650             // if (map.intersectsFrom(sf[f].begin, sf[f].end))\r
651             {\r
652 \r
653             }\r
654           }\r
655         }\r
656       }\r
657     }\r
658   }\r
659 }\r