Mercurial > repos > yating-l > jbrowsearchivecreator
diff TrackHub.py @ 6:237707a6b74d draft
planemo upload for repository https://github.com/Yating-L/jbrowse-archive-creator.git commit a500f7ab2119cc5faaf80393bd87428389d06880-dirty
author | yating-l |
---|---|
date | Thu, 15 Feb 2018 17:05:05 -0500 |
parents | 7e471cdd9e71 |
children | 5d5fdcb798da |
line wrap: on
line diff
--- a/TrackHub.py Fri Jul 07 17:21:23 2017 -0400 +++ b/TrackHub.py Thu Feb 15 17:05:05 2018 -0500 @@ -5,164 +5,184 @@ import shutil import zipfile import json -import utils +import tempfile +import logging +from mako.lookup import TemplateLookup + +from datatypes.Datatype import Datatype +from tracks.TrackStyles import TrackStyles +from util import subtools +from util import santitizer class TrackHub: - def __init__(self, inputFiles, reference, outputDirect, tool_dir, genome, extra_files_path, metaData, jbrowse_host): - self.input_files = inputFiles.tracks - self.outfile = outputDirect - self.outfolder = extra_files_path - self.out_path = os.path.join(extra_files_path, 'myHub') - self.reference = reference - self.tool_dir = tool_dir - self.metaData = metaData - self.raw = os.path.join(self.out_path, 'raw') - self.json = os.path.join(self.out_path, 'json') - self.jbrowse_host = jbrowse_host - try: - if os.path.exists(self.json): - shutil.rmtree(self.json) - os.makedirs(self.json) - except OSError as e: - print "Cannot create json folder error({0}): {1}".format(e.errno, e.strerror) - else: - print "Create jbrowse folder {}".format(self.out_path) - - def createHub(self): - self.prepareRefseq() - for input_file in self.input_files: - self.addTrack(input_file) - self.indexName() - slink = self.makeArchive() - self.outHtml(slink) - print "Success!\n" + def __init__(self, inputFastaFile, outputFile, extra_files_path, tool_directory, trackType): + + self.rootAssemblyHub = None + + self.mySpecieFolderPath = None + + # Store intermediate files, will be removed if not in debug mode + self.myTracksFolderPath = None + + # Store binary files: Bam, BigWig + self.myBinaryFolderPath = None + + self.tool_directory = tool_directory + self.trackType = trackType + self.reference_genome = inputFastaFile + self.genome_name = inputFastaFile.assembly_id + self.extra_files_path = extra_files_path + self.outputFile = outputFile + self.chromSizesFile = None + + + # Set all the missing variables of this class, and create physically the folders/files + self.rootAssemblyHub = self.__createAssemblyHub__(extra_files_path=extra_files_path) + # Init the Datatype + Datatype.pre_init(self.reference_genome, self.chromSizesFile, + self.extra_files_path, self.tool_directory, + self.mySpecieFolderPath, self.myTracksFolderPath, self.myBinaryFolderPath, self.trackType) + + self._prepareRefseq() + self.trackList = os.path.join(self.mySpecieFolderPath, "trackList.json") + self._createTrackList() + + self.myTrackStyle = TrackStyles(self.tool_directory, self.mySpecieFolderPath, self.trackList) + #self.cssFolderPath = os.path.join(self.mySpecieFolderPath, 'css') + #self.cssFilePath = os.path.join(self.cssFolderPath, 'custom_track_styles.css') + self.logger = logging.getLogger(__name__) + - def prepareRefseq(self): - try: + + def addTrack(self, trackDbObject): + if trackDbObject['dataType'].lower() == 'bam': + #new_track = subprocess.Popen(['echo', trackDbObject['options']], stdout=subprocess.PIPE) + #subprocess.call(['add-track-json.pl', json_file], stdin=new_track.stdout) + subtools.add_track_json(self.trackList, trackDbObject['options']) + #subtools.add_track_json(self.trackList, trackDbObject['track_json']) + elif trackDbObject['dataType'].lower() == 'bigwig': + subtools.add_track_json(self.trackList, trackDbObject['options']) + else: + if trackDbObject['trackType'] == 'HTMLFeatures': + self._customizeHTMLFeature(trackDbObject) + subtools.flatfile_to_json(trackDbObject['trackDataURL'], trackDbObject['dataType'], trackDbObject['trackType'], trackDbObject['trackLabel'], self.mySpecieFolderPath, trackDbObject['options']) + + + def terminate(self, debug=False): + """ Write html file """ + self._indexName() + if not debug: + self._removeRaw() + #self._makeArchive() + self._outHtml() + print "Success!\n" + + + def _customizeHTMLFeature(self, trackDbObject): + if trackDbObject['options']: + subfeatures = trackDbObject['options'].get('subfeatureClasses') + feature_color = trackDbObject['options']['feature_color'] + if subfeatures: + for key, value in subfeatures.items(): + self.myTrackStyle.addCustomColor(value, feature_color) + else: + customizedFeature = santitizer.sanitize_name(trackDbObject['trackLabel']) + clientConfig = json.loads(trackDbObject['options']['clientConfig']) + clientConfig['renderClassName'] = customizedFeature + trackDbObject['options']['clientConfig'] = json.dumps(clientConfig) + self.myTrackStyle.addCustomColor(customizedFeature, feature_color) + + def _removeRaw(self): + if os.path.exists(self.myTracksFolderPath): + shutil.rmtree(self.myTracksFolderPath) + + def _createTrackList(self): + if not os.path.exists(self.trackList): + os.mknod(self.trackList) + + def _prepareRefseq(self): + subtools.prepare_refseqs(self.reference_genome.false_path, self.mySpecieFolderPath) + #try: #print os.path.join(self.tool_dir, 'prepare-refseqs.pl') + ", '--fasta', " + self.reference +", '--out', self.json])" - subprocess.call(['prepare-refseqs.pl', '--fasta', self.reference, '--out', self.json]) - except OSError as e: - print "Cannot prepare reference error({0}): {1}".format(e.errno, e.strerror) - #TODO: hard coded the bam and bigwig tracks. Need to allow users to customize the settings - def addTrack(self, track): - #print "false_path" , track['false_path'] - if track['false_path'] in self.metaData.keys(): - metadata = self.metaData[track['false_path']] - else: - metadata = {} - self.SetMetadata(track, metadata) - if track['dataType'] == 'bam': - self.Bam(track, metadata) - # print "add bam track\n" - elif track['dataType'] == 'bigwig': - self.BigWig(track, metadata) - else: - flat_file = os.path.join(self.raw, track['fileName']) - if track['dataType'] == 'bed': - subprocess.call(['flatfile-to-json.pl', '--bed', flat_file, '--trackType', metadata['type'], '--trackLabel', metadata['label'], '--Config', '{"category" : "%s"}' % metadata['category'], '--clientConfig', '{"color" : "%s"}' % metadata['color'], '--out', self.json]) - elif track['dataType'] == 'bedSpliceJunctions' or track['dataType'] == 'gtf' or track['dataType'] == 'blastxml': - subprocess.call(['flatfile-to-json.pl', '--gff', flat_file, '--trackType', metadata['type'], '--trackLabel', metadata['label'], '--Config', '{"glyph": "JBrowse/View/FeatureGlyph/Segments", "category" : "%s"}' % metadata['category'], '--clientConfig', '{"color" : "%s"}' % metadata['color'], '--out', self.json]) - elif track['dataType'] == 'gff3_transcript': - subprocess.call(['flatfile-to-json.pl', '--gff', flat_file, '--trackType', metadata['type'], '--trackLabel', metadata['label'], '--Config', '{"transcriptType": "transcript", "category" : "%s"}' % metadata['category'], '--clientConfig', '{"color" : "%s"}' % metadata['color'], '--out', self.json]) - else: - subprocess.call(['flatfile-to-json.pl', '--gff', flat_file, '--trackType', metadata['type'], '--trackLabel', metadata['label'], '--Config', '{"category" : "%s"}' % metadata['category'], '--clientConfig', '{"color" : "%s"}' % metadata['color'], '--out', self.json]) - - def indexName(self): - subprocess.call(['generate-names.pl', '-v', '--out', self.json]) + #subprocess.call(['prepare-refseqs.pl', '--fasta', self.reference_genome.false_path, '--out', self.mySpecieFolderPath]) + #except OSError as e: + #print "Cannot prepare reference error({0}): {1}".format(e.errno, e.strerror) + + def _indexName(self): + #subprocess.call(['generate-names.pl', '-v', '--out', self.mySpecieFolderPath]) + subtools.generate_names(self.mySpecieFolderPath) print "finished name index \n" - def makeArchive(self): - file_dir = os.path.abspath(self.outfile) - source_dir = os.path.dirname(file_dir) - folder_name = os.path.basename(self.outfolder) - source_name = os.path.basename(self.out_path) - source = os.path.join(source_dir, folder_name, source_name) - slink = source.replace('/', '_') - slink = os.path.join('/var/www/html/JBrowse-1.12.1/data', slink) - try: - if os.path.islink(slink): - os.unlink(slink) - except OSError as oserror: - print "Cannot create symlink to the data({0}): {1}".format(oserror.errno, oserror.strerror) - os.symlink(source, slink) - return slink - - def outHtml(self, slink): - with open(self.outfile, 'w') as htmlfile: - htmlstr = 'The JBrowse Hub is created: <br>' - url = self.jbrowse_host + "/JBrowse-1.12.1/index.html?data=%s" - jbrowse_hub = '<li><a href = "%s" target="_blank">View JBrowse Hub</a></li>' % url - link_name = os.path.basename(slink) - relative_path = os.path.join('data', link_name + '/json') - htmlstr += jbrowse_hub % relative_path - htmlfile.write(htmlstr) + def _outHtml(self): + mylookup = TemplateLookup(directories=[os.path.join(self.tool_directory, 'templates')], + output_encoding='utf-8', encoding_errors='replace') + htmlTemplate = mylookup.get_template("display.txt") - def createTrackList(self): - trackList = os.path.join(self.json, "trackList.json") - if not os.path.exists(trackList): - os.mknod(trackList) - - def Bam(self, track, metadata): - #create trackList.json if not exist - self.createTrackList() - json_file = os.path.join(self.json, "trackList.json") - bam_track = dict() - bam_track['type'] = 'JBrowse/View/Track/Alignments2' - bam_track['storeClass'] = 'JBrowse/Store/SeqFeature/BAM' - bam_track['urlTemplate'] = os.path.join('../raw', track['fileName']) - bam_track['baiUrlTemplate'] = os.path.join('../raw', track['index']) - bam_track['label'] = metadata['label'] - bam_track['category'] = metadata['category'] - bam_track = json.dumps(bam_track) - #Use add-track-json.pl to add bam track to json file - new_track = subprocess.Popen(['echo', bam_track], stdout=subprocess.PIPE) - subprocess.call(['add-track-json.pl', json_file], stdin=new_track.stdout) - - def BigWig(self, track, metadata): - #create trackList.json if not exist - self.createTrackList() - json_file = os.path.join(self.json, "trackList.json") - bigwig_track = dict() - bigwig_track['urlTemplate'] = os.path.join('../raw', track['fileName']) - bigwig_track['type'] = 'JBrowse/View/Track/Wiggle/XYPlot' - bigwig_track['storeClass'] = 'JBrowse/Store/SeqFeature/BigWig' - bigwig_track['label'] = metadata['label'] - bigwig_track['style'] = metadata['style'] - bigwig_track['category'] = metadata['category'] - bigwig_track = json.dumps(bigwig_track) - #Use add-track-json.pl to add bigwig track to json file - new_track = subprocess.Popen(['echo', bigwig_track], stdout=subprocess.PIPE) - #output = new_track.communicate()[0] - subprocess.call(['add-track-json.pl', json_file], stdin=new_track.stdout) - - #If the metadata is not set, use the default value - def SetMetadata(self, track, metadata): - if 'label' not in metadata.keys() or metadata['label'] == '': - metadata['label'] = track['fileName'] - if 'color' not in metadata.keys() or metadata['color'] == '': - metadata['color'] = "#daa520" - if track['dataType'] == 'bigwig': - if 'style' not in metadata.keys(): - metadata['style'] = {} - if 'pos_color' not in metadata['style'] or metadata['style']['pos_color'] == '': - metadata['style']['pos_color'] = "#FFA600" - if 'neg_color' not in metadata['style'] or metadata['style']['neg_color'] == '': - metadata['style']['neg_color'] = "#005EFF" - if 'category' not in metadata.keys() or metadata['category'] == '': - metadata['category'] = "Default group" - if track['dataType'] == 'blastxml': - metadata['type'] = "G-OnRamp_plugin/BlastAlignment" - elif track['dataType'] == 'bigpsl': - metadata['type'] = "G-OnRamp_plugin/BlatAlignment" - elif track['dataType'] == 'gff3_transcript' or track['dataType'] == 'gff3_mrna': - metadata['type'] = "G-OnRamp_plugin/GenePred" - else: - metadata['type'] = "CanvasFeatures" + with open(self.outputFile, 'w') as htmlfile: + htmlMakoRendered = htmlTemplate.render( + species_folder = os.path.relpath(self.mySpecieFolderPath, self.extra_files_path), + trackList = os.path.relpath(self.trackList, self.extra_files_path) + ) + htmlfile.write(htmlMakoRendered) + #with open(self.outputFile, 'w') as htmlfile: + # htmlstr = 'The new Organism "%s" is created on Apollo: <br>' % self.genome_name + # jbrowse_hub = '<li><a href = "%s" target="_blank">View JBrowse Hub on Apollo</a></li>' % host_name + # htmlstr += jbrowse_hub + # htmlfile.write(htmlstr) + + def __createAssemblyHub__(self, extra_files_path): + # Get all necessaries infos first + # 2bit file creation from input fasta - + # baseNameFasta = os.path.basename(fasta_file_name) + # suffixTwoBit, extensionTwoBit = os.path.splitext(baseNameFasta) + # nameTwoBit = suffixTwoBit + '.2bit' + twoBitFile = tempfile.NamedTemporaryFile(bufsize=0) + subtools.faToTwoBit(self.reference_genome.false_path, twoBitFile.name) + + # Generate the twoBitInfo + twoBitInfoFile = tempfile.NamedTemporaryFile(bufsize=0) + subtools.twoBitInfo(twoBitFile.name, twoBitInfoFile.name) + + # Then we get the output to generate the chromSizes + self.chromSizesFile = tempfile.NamedTemporaryFile(bufsize=0, suffix=".chrom.sizes") + subtools.sortChromSizes(twoBitInfoFile.name, self.chromSizesFile.name) + + # We can get the biggest scaffold here, with chromSizesFile + with open(self.chromSizesFile.name, 'r') as chrom_sizes: + # TODO: Check if exists + self.default_pos = chrom_sizes.readline().split()[0] + # TODO: Manage to put every fill Function in a file dedicated for reading reasons + # Create the root directory + myHubPath = os.path.join(extra_files_path, "myHub") + if not os.path.exists(myHubPath): + os.makedirs(myHubPath) + # Create the specie folder + # TODO: Generate the name depending on the specie + mySpecieFolderPath = os.path.join(myHubPath, self.genome_name) + if not os.path.exists(mySpecieFolderPath): + os.makedirs(mySpecieFolderPath) + self.mySpecieFolderPath = mySpecieFolderPath + # We create the 2bit file while we just created the specie folder + #self.twoBitName = self.genome_name + ".2bit" + #self.two_bit_final_path = os.path.join(self.mySpecieFolderPath, self.twoBitName) + #shutil.copyfile(twoBitFile.name, self.two_bit_final_path) + + # Create the folder tracks into the specie folder + tracksFolderPath = os.path.join(mySpecieFolderPath, "raw") + if not os.path.exists(tracksFolderPath): + os.makedirs(tracksFolderPath) + self.myTracksFolderPath = tracksFolderPath + + myBinaryFolderPath = os.path.join(mySpecieFolderPath, 'bbi') + if not os.path.exists(myBinaryFolderPath): + os.makedirs(myBinaryFolderPath) + self.myBinaryFolderPath = myBinaryFolderPath + + return myHubPath