7658539f5ca5ffdd5ddb5ee761fd2856ad607ef6
[jalview.git] / examples / groovy / FastQParser.groovy
1 import htsjdk.samtools.cram.encoding.readfeatures.BaseQualityScore
2 import htsjdk.samtools.fastq.FastqReader
3 import htsjdk.samtools.fastq.FastqRecord
4 import jalview.datamodel.AlignmentI
5 import jalview.datamodel.SequenceI
6 import jalview.datamodel.Sequence
7 import jalview.datamodel.SequenceFeature
8 import jalview.io.FileFormatI
9 import jalview.io.FileFormats
10 import jalview.io.FileParse
11 import jalview.io.AlignFile
12 import jalview.io.DataSourceType
13
14 /*
15  * Prototype Jalview FASTQ importer based on HTS JDK 2.20
16  */
17
18 /*
19  * EDIT THE FILE PATH BELOW TO IMPORT A FASTQ FILE
20  */
21 FASTQ_FILE = "/Users/jprocter/Downloads/small_normalised_illumina_adeno.fastq.gz"
22 FASTQ_FILE = "/Users/jprocter/Downloads/test.fastq"
23
24
25 /*
26  * A parser class to read or write the format
27  * based on the fileFormat.groovy example for creating your own alignment parser/writer
28  */
29 class FastQFile extends AlignFile 
30 {
31   FastqReader fqreader;
32   @Override
33   protected boolean isParseImmediately()
34   {
35     return false;
36   }
37   /*
38    * Constructor for reading a file; the superclass
39    * constructor will call the parse() method
40    */
41   FastQFile(FileParse src) 
42   {
43     super(src)
44   }
45
46   /*
47    * Constructor for writing out an alignment
48    */
49   FastQFile(AlignmentI al) 
50   {
51     throw new Error("Unimplemented");
52   }
53   
54   /*
55    * Parse a formatted data file (with no error checking!)
56    */
57   void parse() 
58   {
59     fqreader = new FastqReader(getReader());
60
61     FastqRecord record
62     while (fqreader.hasNext() && (record = fqreader.next())!=null)
63     {
64       // Create a sequence from read name and sequence string. start & end are 1-length
65       Sequence seq = new Sequence(record.getReadName(), record.getReadString());
66       byte[] qualities = record.getBaseQualities();
67       if (qualities!=null)
68       {
69         
70         // Two options here: create an annotation row, or create features.
71         // annotations take far longer to create and manipulate in Jalview 2.11 (this is changing in 2.12!)
72         // so we create sequence features for now
73         boolean makeAnn=false;
74         
75         jalview.datamodel.Annotation[] anns=new jalview.datamodel.Annotation[qualities.length];
76         int p = 0;
77         for (byte q:qualities)
78         {
79           if (makeAnn) { anns[p++]=new jalview.datamodel.Annotation(Float.valueOf(q)) }
80           else { 
81             SequenceFeature sf = new SequenceFeature("Phred","Score", p+1,p+1,Float.valueOf(q),"");
82             seq.addSequenceFeature(sf);
83             p++;
84           }
85         }
86         if (makeAnn) {
87           jalview.datamodel.AlignmentAnnotation qalAnnot = new jalview.datamodel.AlignmentAnnotation("PhredScore","Base qualities: "+record.getBaseQualityHeader(),anns);
88           qalAnnot.visible=false; // hidden by default
89           seq.addAlignmentAnnotation(qalAnnot);
90           annotations.add(qalAnnot);
91         }
92       }
93       addSequence(seq)
94     }
95     fqreader.close();
96   }
97   
98   /*
99    * Print the formatted sequences
100    * (addSuffix always defaults to true as no user preference for it)
101    */
102   String print(SequenceI[] seqs, boolean addSuffix) 
103   {
104       // not supported
105   }
106 }
107
108 /*
109  * Define and register the fileformat class for handling FastQ
110  */
111 def myFormat = { ->
112   [
113     getName: { -> 'FASTQ Parser (Groovy)' },
114     
115     toString: { -> getName() },
116     
117     getExtensions: { 'fq,fastq'},
118     
119     getReader: { FileParse source -> new FastQFile(source) },
120     
121     getWriter: { AlignmentI al -> new FastQFile(al) },
122     
123     isReadable: { -> true },
124     
125     isWritable: { -> false },
126     
127     isTextFormat: { -> true },
128     
129     isStructureFile: { -> false },
130     
131     isComplexAlignFile: { -> false },
132
133    ] as FileFormatI
134 }
135
136 // read in the file specified at the top of the Groovy script
137
138 FastQFile parser = new FastQFile(new FileParse(FASTQ_FILE, DataSourceType.FILE));
139 AlignmentI al = new jalview.datamodel.Alignment(parser.getSeqsAsArray());
140 parser.addAnnotations(al);
141 jalview.gui.AlignFrame newwindow = new jalview.gui.AlignFrame(al,800,600);
142 jalview.gui.Desktop.addInternalFrame(newwindow, parser.getDataName(), 800,600);
143
144
145 /*
146  * Register the file format. After running this script in Jalview's
147  * Groovy console, the new format should be shown in open file.
148  *
149  * However, we don't yet have a way of dynamically updating the IdentifyFile routine,
150  * so a FastQ file selected in the file browser won't be imported using this reader
151  *
152  */
153
154  // FileFormats.instance.registerFileFormat(myFormat())
155