-
Notifications
You must be signed in to change notification settings - Fork 15
/
RNAEditor.py
executable file
·336 lines (268 loc) · 15.5 KB
/
RNAEditor.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
#!/usr/bin/python
'''
Created on May 17, 2013
Updated on 23 August 2022
Release Notest:
-Updated to Python3 and PyQt5
Main Class to detect RNA-editing in a given FastQ file
@author: david
'''
from Helper import Helper, Parameters, Communicate
from MapFastq import MapFastq
from CallEditingSites import CallEditingSites
import multiprocessing, argparse, os
import traceback
from PyQt5 import QtGui, QtCore, QtWidgets
import textwrap
import sys
import gc
import subprocess
class RnaEdit(QtCore.QThread):
def __init__(self, fastqFiles, params, textField):
self.c = Communicate()
QtCore.QThread.__init__(self)
if isinstance(params, Parameters):
self.params = params
else:
Helper.error("Params has to be Instance of Parameters")
if isinstance(textField, QtWidgets.QTextEdit) or textField==0:
self.textField=textField
else:
Helper.error("textField has to be Instance of QtGui.QTextEdit or 0")
self.fastqFiles=fastqFiles
#hold the running Popen object
self.runningCommand=False
self.isTerminated = False
#check if the input Files are there
#hold basic statistic values of the run
basicStatDict={}
#set directory where the outputFiles should be written to
if self.params.output=="default":
if self.fastqFiles[0].endswith("noDup.realigned.recalibrated.bam"):
self.sampleName=fastqFiles[0][fastqFiles[0].rfind("/")+1:fastqFiles[0].rfind(".noDup.realigned.recalibrated.bam")]
self.outdir=fastqFiles[0][0:fastqFiles[0].rfind("/")+1]
else:
self.sampleName=fastqFiles[0][fastqFiles[0].rfind("/")+1:fastqFiles[0].rfind(".")]
# outdir = /path/to/output/rnaEditor/samplename/
self.outdir=fastqFiles[0][0:fastqFiles[0].rfind("/")+1]+"rnaEditor/"+self.sampleName+"/"
#output=/path/to/output/rnaEditor/samplename/samplename
self.params.output=self.outdir+self.sampleName
if not os.path.exists(self.outdir):
os.makedirs(self.outdir, mode=755)
os.chmod(self.outdir, 755)
#create folder for html output
if not os.path.exists(self.outdir+"/html"):
os.makedirs(self.outdir+"/html", mode=755)
os.chmod(self.outdir, 755)
self.checkDependencies()
#check if the input Files are there
self.printParameters()
def run(self):
try:
self.startAnalysis()
except Exception:
Helper.error("RnaEditor Failed",self.logFile,self.textField)
""" At this point the RnaEditor has succesfully finished """
fileDir = os.path.dirname(os.path.realpath(__file__))
cmd=["python",fileDir+"/createDiagrams.py","-o", self.params.output]
a=subprocess.call(cmd)
self.c.taskDone.emit(self.params.output+".html")
#self.emit(QtCore.SIGNAL("taskDone"), self.params.output+".html")
def startAnalysis(self):
"""
START MAPPING
"""
if self.fastqFiles[0].endswith("bam"):
if self.fastqFiles[0].endswith("noDup.realigned.recalibrated.bam"):
Helper.info("Bam File given. Skip mapping", self.logFile, self.textField)
self.mapFastQ=None
mapResultFile=self.fastqFiles[0]
else:
Helper.error("Bam File was not mapped with RnaEditor, this is not supported. Please provide the fastq Files to RnaEditor", self.logFile, self.textField, "red")
else:
self.mapFastQ=MapFastq(self)
mapResultFile=self.mapFastQ.startAnalysis()
"""
START CALLING EDITING SITES
"""
self.callEditSites=CallEditingSites(mapResultFile,self)
result = self.callEditSites.startAnalysis()
#finished
self.isTerminated=True
Helper.status("rnaEditor Finished with %s" % self.params.output, self.logFile, self.textField,"green",True)
Helper.status("Open %s to see the results" % self.params.output+".html", self.logFile, self.textField,"green",True)
self.cleanUp()
def stopSafely(self):
self.quit()
Helper.info("Analysis was stopped by User", self.logFile, self.textField)
def stopImmediately(self):
if hasattr(self, 'callEditSites'):
self.callEditSites.cleanUp()
self.isTerminated=True
if self.runningCommand != False:
self.runningCommand.kill()
else:
self.terminate()
self.wait()
Helper.error("Analysis was terminated by User", self.logFile, self.textField)
def cleanUp(self):
#print "deleteAssay " + str(self)
if self.runningCommand != False:
self.runningCommand.kill()
try:
if self.mapFastQ!=None:
self.mapFastQ.cleanUp()
del self.mapFastQ
except AttributeError:
Helper.error("could not delete MapFastQ instance", self.logFile, self.textField)
try:
self.callEditSites.cleanUp()
del self.callEditSites
except AttributeError:
Helper.error("could not delete RnaEdit instance", self.logFile, self.textField)
def checkDependencies(self):
"""checks if all files are there
if all programs are installed properly and if the output directory is writable"""
try:
self.logFile=open(self.params.output + ".log","w+")
except IOError:
Helper.error("Cannot open Log File", textField=self.textField)
if type(self.fastqFiles) == list:
self.fastqFiles=self.fastqFiles
elif type(self.fastqFile) == str:
self.fastqFiles=[self.fastqFiles]
else:
Helper.error("FastQ File has wrong variable type",self.logFile,self.textField)
for file in self.fastqFiles:
if not os.path.isfile(file):
Helper.error("Could not find: %s" %file,self.logFile,self.textField)
'''
Checks the existence of the necessary packages and tools
:param sourceDir: folder which contains all the software
'''
Helper.newline(1)
Helper.info("CHECK DEPENDENCIES",self.logFile,self.textField)
#check if all tools are there
if not os.path.isfile(self.params.sourceDir+"bwa"):
Helper.error("BWA not found in %s" % self.params.sourceDir,self.logFile,self.textField)
if not os.path.isfile(self.params.sourceDir+"picard-tools/SortSam.jar"):
Helper.error("SortSam.jar not found in %s" % self.params.sourceDir+"picard-tools",self.logFile,self.textField)
if not os.path.isfile(self.params.sourceDir+"picard-tools/MarkDuplicates.jar"):
Helper.error("MarkDuplicates.jar not found in %s" % self.params.sourceDir+"picard-tools",self.logFile,self.textField)
if not os.path.isfile(self.params.sourceDir+"GATK/GenomeAnalysisTK.jar"):
Helper.error("GenomeAnalysisTK.jar not found in %s" % self.params.sourceDir+"GATK/",self.logFile,self.textField)
if not os.path.isfile(self.params.sourceDir+"blat"):
Helper.error("blat not found in %s" % self.params.sourceDir,self.logFile,self.textField)
if not os.path.isfile(self.params.sourceDir+"samtools"):
Helper.error("samtools not found in %s" % self.params.sourceDir,self.logFile,self.textField)
if not os.system("java -version")==0:
Helper.error("Java could not be found, Please install java",self.logFile,self.textField)
#check if all files are there
if not os.path.isfile(self.params.refGenome):
Helper.error("Could not find Reference Genome in %s: " % self.params.refGenome,self.logFile,self.textField)
# Files for BWA
if not os.path.isfile(self.params.refGenome+".amb"):
Helper.warning("Could not find %s.amb" % self.params.refGenome,self.logFile,self.textField)
Helper.error("run: 'bwa index %s' to create it" % self.params.refGenome,self.logFile,self.textField)
if not os.path.isfile(self.params.refGenome+".ann"):
Helper.warning("Could not find %s.ann" % self.params.refGenome,self.logFile,self.textField)
Helper.error("run: 'bwa index %s' to create it" % self.params.refGenome,self.logFile,self.textField)
if not os.path.isfile(self.params.refGenome+".bwt"):
Helper.warning("Could not find %s.bwt" % self.params.refGenome,self.logFile,self.textField)
Helper.error("run: 'bwa index %s' to create it" % self.params.refGenome,self.logFile,self.textField)
if not os.path.isfile(self.params.refGenome+".pac"):
Helper.warning("Could not find %s.pac" % self.params.refGenome,self.logFile,self.textField)
Helper.error("run: 'bwa index %s' to create it" % self.params.refGenome,self.logFile,self.textField)
if not os.path.isfile(self.params.refGenome+".sa"):
Helper.warning("Could not find %s.sa" % self.params.refGenome,self.logFile,self.textField)
Helper.error("run: 'bwa index %s' to create it" % self.params.refGenome,self.logFile,self.textField)
#Files for GATK
if self.params.refGenome.endswith("fasta"):
if not os.path.isfile(self.params.refGenome.replace(".fasta",".dict")):
Helper.warning("Could not find %s" % self.params.refGenome.replace(".fasta",".dict"),self.logFile,self.textField)
Helper.error("run: 'java -jar %spicard-tools/CreateSequenceDictionary.jar R=%s O= %s' to create it" % (self.params.sourceDir,self.params.refGenome,self.params.refGenome.replace(".fastq",".dict")),self.logFile,self.textField)
elif self.params.refGenome.endswith("fa"):
if not os.path.isfile(self.params.refGenome.replace(".fa",".dict")):
Helper.warning("Could not find %s" % self.params.refGenome.replace(".fa",".dict"),self.logFile,self.textField)
Helper.error("run: 'java -jar %spicard-tools/CreateSequenceDictionary.jar R=%s O= %s' to create it" % (self.params.sourceDir,self.params.refGenome,self.params.refGenome.replace(".fa",".dict")),self.logFile,self.textField)
else:
Helper.error("RefGenome has wrong suffix. Either '.fa' or '.fasta'")
if not os.path.isfile(self.params.refGenome+".fai"):
Helper.warning("Could not find %s.sai" % self.params.refGenome,self.logFile,self.textField)
Helper.error("run: 'samtools faidx %s' to create it" % self.params.refGenome,self.logFile,self.textField)
#SNP databases
if not os.path.isfile(self.params.dbsnp):
Helper.error("Could not find dbSNP database %s: " % self.params.dbsnp,self.logFile,self.textField)
if not os.path.isfile(self.params.hapmap) and self.params.hapmap != "None":
Helper.error("Could not find Hapmap database %s: " % self.params.hapmap,self.logFile,self.textField)
if not os.path.isfile(self.params.omni) and self.params.omni != "None":
Helper.error("Could not find Omni database %s: " % self.params.omni,self.logFile,self.textField)
if not os.path.isfile(self.params.esp) and self.params.esp != "None":
Helper.error("Could not find 1000G database %s: " % self.params.esp,self.logFile,self.textField)
#region Files
if not os.path.isfile(self.params.aluRegions):
Helper.error("Could not find %s: " % self.params.aluRegions,self.logFile,self.textField)
if not os.path.isfile(self.params.gtfFile):
Helper.error("Could not find %s: " % self.params.gtfFile,self.logFile,self.textField)
Helper.info("Dependencies satisfied", self.logFile, self.textField)
#check if display can activate
def printParameters(self):
Helper.info("*** Start RnaEditor with: ***", self.logFile,self.textField)
if self.fastqFiles[0].endswith(".bam"):
Helper.info("\t Bam File: " + self.fastqFiles[0],self.logFile,self.textField)
else:
if self.params.paired:
Helper.info("\t FastQ-File_1: " + self.fastqFiles[0],self.logFile,self.textField)
Helper.info("\t FastQ-File_2: " + self.fastqFiles[1],self.logFile,self.textField)
else:
Helper.info("\t FastQ-File: " + self.fastqFiles[0],self.logFile,self.textField)
Helper.info("\t outfilePrefix:" + self.params.output,self.logFile,self.textField)
Helper.info("\t refGenome:" + self.params.refGenome,self.logFile,self.textField)
Helper.info("\t dbsnp:" + self.params.dbsnp,self.logFile,self.textField)
Helper.info("\t sourceDir:" + self.params.sourceDir,self.logFile,self.textField)
Helper.info("\t threads:" + self.params.threads,self.logFile,self.textField)
Helper.info("\t maxDiff:" + self.params.maxDiff,self.logFile,self.textField)
Helper.info("\t seedDiff:" + self.params.seedDiff,self.logFile,self.textField)
Helper.info("\t paired:" + str(self.params.paired),self.logFile,self.textField)
Helper.info("\t keepTemp:" + str(self.params.keepTemp),self.logFile,self.textField)
Helper.info("\t overwrite:" + str(self.params.overwrite),self.logFile,self.textField)
Helper.info("",self.logFile,self.textField)
def main(argv):
app = QtWidgets.QApplication(argv)
mainWindow = GuiView()
app.setApplicationName("RNAEditor")
app.setApplicationVersion("0.1")
app_icon = QtGui.QIcon()
app_icon.addFile('ui/icons/rnaEditor_16x16.png', QtCore.QSize(16,16))
app_icon.addFile('ui/icons/rnaEditor_24x24.png', QtCore.QSize(24,24))
app_icon.addFile('ui/icons/rnaEditor_32x32.png', QtCore.QSize(32,32))
app_icon.addFile('ui/icons/rnaEditor_48x48.png', QtCore.QSize(48,48))
app_icon.addFile('ui/icons/rnaEditor_256x256.png', QtCore.QSize(256,256))
app_icon.addFile('ui/icons/rnaEditor_512x512.png', QtCore.QSize(512,512))
app_icon.addFile('ui/icons/rnaEditor_1024x1024.png', QtCore.QSize(1024,1024))
app.setWindowIcon(app_icon)
mainWindow.show()
sys.exit(app.exec_())
if __name__ == '__main__':
if len(sys.argv) > 1:
parser = argparse.ArgumentParser(
prog = 'RnaEditor',
formatter_class=argparse.RawDescriptionHelpFormatter,
description=textwrap.dedent('''\
RnaEditor: easily detect editing sites from deep sequencing data'
----------------------------------------------------------------
run without arguments to start the user interface.
'''))
parser.add_argument('-i', '--input', metavar='Fastq-Files',nargs='+', type=str, help='Input fastq files (maximum two for paired-end sequencing)', required=True)
parser.add_argument('-c', '--conf', metavar='Configuration File', type=str, help='Configuration File used to read Parameters for RnaEditor', required=True, default='configuration.txt')
args = parser.parse_args()
parameters = Parameters(args.conf)
edit=RnaEdit(args.input,parameters,0)
edit.start()
edit.wait()
del edit
else:
from ui.GuiView import GuiView
main(sys.argv)
else:
pass