24 new commits in galaxy-central: https://bitbucket.org/galaxy/galaxy-central/changeset/1d0bb560bd3d/ changeset: 1d0bb560bd3d user: ichorny date: 2011-10-21 23:01:48 summary: add actual user changes to galaxy-central affected #: 14 files diff -r 070513d25b63110ef6569a9b09101864009f2ba4 -r 1d0bb560bd3d584708972001afd054774e9e89c5 lib/galaxy/jobs/__init__.py --- a/lib/galaxy/jobs/__init__.py +++ b/lib/galaxy/jobs/__init__.py @@ -10,7 +10,7 @@ from galaxy.util.json import from_json_string from galaxy.util.expressions import ExpressionContext from galaxy.jobs.actions.post import ActionBox - +import subprocess, pwd from sqlalchemy.sql.expression import and_, or_ import pkg_resources @@ -362,6 +362,9 @@ self.sa_session.expunge_all() #this prevents the metadata reverting that has been seen in conjunction with the PBS job runner if not os.path.exists( self.working_directory ): os.mkdir( self.working_directory ) + if self.app.config.drmaa_external_runjob_script: + os.chmod(self.working_directory , 0777) + # Restore parameters from the database job = self.get_job() if job.user is None and job.galaxy_session is None: @@ -695,6 +698,16 @@ # fix permissions for path in [ dp.real_path for dp in self.get_output_fnames() ]: + #change the ownership of the files in file_path directory back to galaxy user + if self.app.config.drmaa_external_runjob_script and self.app.config.external_chown_script: + galaxy_user_name = pwd.getpwuid(os.getuid())[0] + galaxy_group_id = str(pwd.getpwuid(os.getuid())[3]) + p = subprocess.Popen([ '/usr/bin/sudo', '-E', self.app.config.external_chown_script, path,galaxy_user_name,galaxy_group_id], shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + (stdoutdata, stderrdata) = p.communicate() + exitcode = p.returncode + if exitcode != 0: + ## There was an error in the child process + raise RuntimeError("External_chown_script failed (exit code %s) with error %s" % (str(exitcode), stderrdata)) util.umask_fix_perms( path, self.app.config.umask, 0666, self.app.config.gid ) self.sa_session.flush() log.debug( 'job %d ended' % self.job_id ) @@ -765,7 +778,7 @@ jeha_false_path = None if self.app.config.outputs_to_working_directory: self.output_paths = [] - self.output_dataset_paths = {} + output_dataset_paths = {} for name, data in [ ( da.name, da.dataset.dataset ) for da in job.output_datasets + job.output_library_datasets ]: false_path = os.path.abspath( os.path.join( self.working_directory, "galaxy_dataset_%d.dat" % data.id ) ) dsp = DatasetPath( data.id, data.file_name, false_path ) @@ -895,7 +908,7 @@ else: self.prepare_input_files_cmds = None self.status = task.states.NEW - + def get_job( self ): if self.job_id: return self.sa_session.query( model.Job ).get( self.job_id ) @@ -1123,7 +1136,7 @@ def __get_runner_name( self, job_wrapper ): if self.app.config.use_tasked_jobs and job_wrapper.tool.parallelism is not None and not isinstance(job_wrapper, TaskWrapper): - runnner_name = "tasks" + runner_name = "tasks" else: runner_name = ( job_wrapper.get_job_runner().split(":", 1) )[0] return runner_name diff -r 070513d25b63110ef6569a9b09101864009f2ba4 -r 1d0bb560bd3d584708972001afd054774e9e89c5 lib/galaxy/jobs/runners/drmaa.py --- a/lib/galaxy/jobs/runners/drmaa.py +++ b/lib/galaxy/jobs/runners/drmaa.py @@ -1,4 +1,10 @@ import os, sys, logging, threading, time +import pprint, pwd +from pwd import getpwnam +import subprocess +import inspect +import simplejson as json + from Queue import Queue, Empty from galaxy import model @@ -8,6 +14,7 @@ import pkg_resources + if sys.version_info[:2] == ( 2, 4 ): pkg_resources.require( "ctypes" ) pkg_resources.require( "drmaa" ) @@ -42,9 +49,23 @@ fi export PYTHONPATH fi +%s cd %s %s +%s +%s +%s """ +def __lineno__(): + """Returns the current line number in our program.""" + return inspect.currentframe().f_back.f_lineno + +def __filename__(): + """Returns the current filename in our program.""" + return inspect.currentframe().f_back.f_code.co_filename + +DRMAA_jobTemplate_attributes = [ 'args', 'remoteCommand', 'outputPath', 'errorPath', 'nativeSpecification', + 'name','email','project' ] class DRMAAJobState( object ): def __init__( self ): @@ -90,6 +111,10 @@ worker.start() self.work_threads.append( worker ) log.debug( "%d workers ready" % nworkers ) + # external_runJob_script can be None, in which case it's not used. + self.external_runJob_script = app.config.drmaa_external_runjob_script + self.external_killJob_script = app.config.drmaa_external_killjob_script + self.TMPDIR = app.config.TMPDIR def get_native_spec( self, url ): """Get any native DRM arguments specified by the site configuration""" @@ -118,7 +143,6 @@ def queue_job( self, job_wrapper ): """Create job script and submit it to the DRM""" - try: job_wrapper.prepare() command_line = self.build_command_line( job_wrapper, include_metadata=True ) @@ -128,7 +152,7 @@ return runner_url = job_wrapper.get_job_runner() - + # This is silly, why would we queue a job with no command line? if not command_line: job_wrapper.finish( '', '' ) @@ -144,8 +168,8 @@ job_wrapper.change_state( model.Job.states.QUEUED ) # define job attributes - ofile = "%s/%s.o" % (self.app.config.cluster_files_directory, job_wrapper.job_id) - efile = "%s/%s.e" % (self.app.config.cluster_files_directory, job_wrapper.job_id) + ofile = "%s/%s.o" % (self.app.config.cluster_files_directory, job_wrapper.get_id_tag()) + efile = "%s/%s.e" % (self.app.config.cluster_files_directory, job_wrapper.get_id_tag()) jt = self.ds.createJobTemplate() jt.remoteCommand = "%s/database/pbs/galaxy_%s.sh" % (os.getcwd(), job_wrapper.get_id_tag()) jt.outputPath = ":%s" % ofile @@ -153,17 +177,31 @@ native_spec = self.get_native_spec( runner_url ) if native_spec is not None: jt.nativeSpecification = native_spec + #set and export galaxy user PATH enviroment to actual user if submitting jobs as actual user + try: + if self.external_runJob_script: + export_path = 'export PATH=%s:$PATH' %(os.environ['PATH']) + else: + export_path = '' + except: + export_path = '' + + if self.TMPDIR: + export_tmp = 'export TMPDIR=%s' %self.TMPDIR + else: + export_tmp = '' - script = drm_template % (job_wrapper.galaxy_lib_dir, os.path.abspath( job_wrapper.working_directory ), command_line) - try: - fh = file( jt.remoteCommand, "w" ) - fh.write( script ) - fh.close() - os.chmod( jt.remoteCommand, 0750 ) - except: - job_wrapper.fail( "failure preparing job script", exception=True ) - log.exception("failure running job %s" % job_wrapper.get_id_tag()) - return + if self.external_runJob_script == None: + script = drm_template % (job_wrapper.galaxy_lib_dir, export_path, os.path.abspath( job_wrapper.working_directory ),export_tmp, command_line,'','') + else: + touchcmd = 'touch ' + os.path.abspath( job_wrapper.working_directory ) + '/just_in_cases.txt' + chmodcmd = 'chmod -Rf a+rwx ' + os.path.abspath( job_wrapper.working_directory ) + '/*' + script = drm_template % (job_wrapper.galaxy_lib_dir, export_path, os.path.abspath( job_wrapper.working_directory ), export_tmp, command_line, touchcmd,chmodcmd) + + fh = file( jt.remoteCommand, "w" ) + fh.write( script ) + fh.close() + os.chmod( jt.remoteCommand, 0755 ) # job was deleted while we were preparing it if job_wrapper.get_state() == model.Job.states.DELETED: @@ -178,7 +216,12 @@ log.debug("(%s) submitting file %s" % ( galaxy_id_tag, jt.remoteCommand ) ) log.debug("(%s) command is: %s" % ( galaxy_id_tag, command_line ) ) # runJob will raise if there's a submit problem - job_id = self.ds.runJob(jt) + if self.external_runJob_script is None: + job_id = self.ds.runJob(jt) + else: + userid = self.get_qsub_user(job_wrapper) + filename = self.store_jobtemplate(job_wrapper, jt) + job_id = self.external_runjob(filename, userid) log.info("(%s) queued as %s" % ( galaxy_id_tag, job_id ) ) # store runner information for tracking if Galaxy restarts @@ -272,15 +315,23 @@ efile = drm_job_state.efile job_file = drm_job_state.job_file # collect the output - try: - ofh = file(ofile, "r") - efh = file(efile, "r") - stdout = ofh.read( 32768 ) - stderr = efh.read( 32768 ) - except: - stdout = '' - stderr = 'Job output not returned from cluster' - log.debug(stderr) + # JED - HACK to wait for the files to appear + which_try = 0 + while which_try < 60: + try: + ofh = file(ofile, "r") + efh = file(efile, "r") + stdout = ofh.read( 32768 ) + stderr = efh.read( 32768 ) + which_try = 60 + except: + if which_try == 60: + stdout = '' + stderr = 'Job output not returned from cluster' + log.debug(stderr) + else: + which_try += 1 + time.sleep(1) try: drm_job_state.job_wrapper.finish( stdout, stderr ) @@ -320,13 +371,20 @@ def stop_job( self, job ): """Attempts to delete a job from the DRM queue""" - try: - self.ds.control( job.job_runner_external_id, drmaa.JobControlAction.TERMINATE ) - log.debug( "(%s/%s) Removed from DRM queue at user's request" % ( job.id, job.job_runner_external_id ) ) - except drmaa.InvalidJobException: - log.debug( "(%s/%s) User killed running job, but it was already dead" % ( job.id, job.job_runner_external_id ) ) - except Exception, e: - log.debug( "(%s/%s) User killed running job, but error encountered removing from DRM queue: %s" % ( job.id, job.job_runner_external_id, e ) ) + if self.external_killJob_script is None: + try: + self.ds.control( job.job_runner_external_id, drmaa.JobControlAction.TERMINATE ) + log.debug( "(%s/%s) Removed from DRM queue at user's request" % ( job.id, job.job_runner_external_id ) ) + except drmaa.InvalidJobException: + log.debug( "(%s/%s) User killed running job, but it was already dead" % ( job.id, job.job_runner_external_id ) ) + except Exception, e: + log.debug( "(%s/%s) User killed running job, but error encountered removing from DRM queue: %s" % ( job.id, job.job_runner_external_id, e ) ) + else: + try: + subprocess.Popen(['/usr/bin/sudo','-E', self.external_killJob_script, str(job.job_runner_external_id), str(self.job_user_uid[2])],shell=False) + log.debug( "(%s/%s) Removed from DRM queue at user's request" % ( job.id, job.job_runner_external_id ) ) + except Exception, e: + log.debug( "(%s/%s) User killed running job, but error encountered removing from DRM queue: %s" % ( job.id, job.job_runner_external_id, e ) ) def recover( self, job, job_wrapper ): """Recovers jobs stuck in the queued/running state when Galaxy started""" @@ -348,3 +406,52 @@ drm_job_state.old_state = drmaa.JobState.QUEUED_ACTIVE drm_job_state.running = False self.monitor_queue.put( drm_job_state ) + + def get_qsub_user(self, job_wrapper): + """ Returns the UserID (or Username) that should be used to execute the job. """ + #TODO: + #add some logic to decide on an SGE user for the given job. + job_user_name = job_wrapper.user.split('@') + self.job_user_uid = getpwnam(job_user_name[0]) + log.debug (" (%s) is the uid being passed to the DRM queu\n" % ( self.job_user_uid[2]) ) + return self.job_user_uid[2] + + def store_jobtemplate(self, job_wrapper, jt): + """ Stores the content of a DRMAA JobTemplate object in a file as a JSON string. + Path is hard-coded, but it's no worse than other path in this module. + Uses Galaxy's JobID, so file is expected to be unique.""" + filename = "%s/database/pbs/%s.jt_json" % (os.getcwd(), job_wrapper.get_id_tag()) + data = {} + for attr in DRMAA_jobTemplate_attributes: + try: + data[attr] = getattr(jt, attr) + except: + pass + s = json.dumps(data); + f = open(filename,'w') + f.write(s) + f.close() + return filename + + def external_runjob(self, jobtemplate_filename, username): + """ runs an external script the will QSUB a new job. + The external script will be run with sudo, and will setuid() to the specified user. + Effectively, will QSUB as a different user (then the one used by Galaxy). + """ + p = subprocess.Popen([ '/usr/bin/sudo', '-E', self.external_runJob_script, str(username), jobtemplate_filename ], + shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + (stdoutdata, stderrdata) = p.communicate() + exitcode = p.returncode + #os.unlink(jobtemplate_filename) + if exitcode != 0: + # There was an error in the child process + raise RuntimeError("External_runjob failed (exit code %s)\nCalled from %s:%d\nChild process reported error:\n%s" % (str(exitcode), __filename__(), __lineno__(), stderrdata)) + if not stdoutdata.strip(): + raise RuntimeError("External_runjob did return the job id: %s" % (stdoutdata)) + + # The expected output is a single line containing a single numeric value: + # the DRMAA job-ID. If not the case, will throw an error. + jobId = stdoutdata + return jobId; + + diff -r 070513d25b63110ef6569a9b09101864009f2ba4 -r 1d0bb560bd3d584708972001afd054774e9e89c5 lib/galaxy/jobs/splitters/multi.py --- a/lib/galaxy/jobs/splitters/multi.py +++ b/lib/galaxy/jobs/splitters/multi.py @@ -33,6 +33,7 @@ subdir_index[0] = subdir_index[0] + 1 if not os.path.exists(dir): os.makedirs(dir) + os.chmod(dir,0777) task_dirs.append(dir) return dir diff -r 070513d25b63110ef6569a9b09101864009f2ba4 -r 1d0bb560bd3d584708972001afd054774e9e89c5 lib/galaxy/model/__init__.py --- a/lib/galaxy/model/__init__.py +++ b/lib/galaxy/model/__init__.py @@ -480,6 +480,23 @@ rval = galaxy.datatypes.data.nice_size( rval ) return rval + def get_api_value( self, view='collection', value_mapper = None ): + if value_mapper is None: + value_mapper = {} + rval = {} + try: + visible_keys = self.__getattribute__( 'api_' + view + '_visible_keys' ) + except AttributeError: + raise Exception( 'Unknown API view: %s' % view ) + for key in visible_keys: + try: + rval[key] = self.__getattribute__( key ) + if key in value_mapper: + rval[key] = value_mapper.get( key )( rval[key] ) + except AttributeError: + rval[key] = None + return rval + class HistoryUserShareAssociation( object ): def __init__( self ): self.history = None @@ -632,7 +649,7 @@ permitted_actions = get_permitted_actions( filter='DATASET' ) file_path = "/tmp/" engine = None - def __init__( self, id=None, state=None, external_filename=None, extra_files_path=None, file_size=None, purgable=True ): + def __init__( self, id=None, state=None, external_filename=None, extra_files_path=None, file_size=None, purgable=True): self.id = id self.state = state self.deleted = False @@ -653,6 +670,7 @@ # Create directory if it does not exist if not os.path.exists( dir ): os.makedirs( dir ) + os.chmod(dir, 0777) # Return filename inside hashed directory return os.path.abspath( os.path.join( dir, "dataset_%d.dat" % self.id ) ) else: @@ -1131,6 +1149,28 @@ return hda_name def get_access_roles( self, trans ): return self.dataset.get_access_roles( trans ) + def get_api_value( self, view='collection' ): + # Since this class is a proxy to rather complex attributes we want to + # display in other objects, we can't use the simpler method used by + # other model classes. + hda = self + rval = dict( name = hda.name, + extension = hda.extension, + deleted = hda.deleted, + visible = hda.visible, + state = hda.state, + file_size = int( hda.get_size() ), + genome_build = hda.dbkey, + misc_info = hda.info, + misc_blurb = hda.blurb ) + for name, spec in hda.metadata.spec.items(): + val = hda.metadata.get( name ) + if isinstance( val, MetadataFile ): + val = val.file_name + elif isinstance( val, list ): + val = ', '.join( [str(v) for v in val] ) + rval['metadata_' + name] = val + return rval def quota_amount( self, user ): """ If the user has multiple instances of this dataset, it will not affect their disk usage statistic. @@ -1794,6 +1834,8 @@ # File Exists is okay, otherwise reraise if e.errno != errno.EEXIST: raise + + os.chmod(path, 0777) # Return filename inside hashed directory return os.path.abspath( os.path.join( path, "metadata_%d.dat" % self.id ) ) diff -r 070513d25b63110ef6569a9b09101864009f2ba4 -r 1d0bb560bd3d584708972001afd054774e9e89c5 lib/galaxy/tools/__init__.py --- a/lib/galaxy/tools/__init__.py +++ b/lib/galaxy/tools/__init__.py @@ -29,6 +29,9 @@ from cgi import FieldStorage from galaxy.util.hash_util import * from galaxy.util import listify +from galaxy.web import security +import socket + log = logging.getLogger( __name__ ) @@ -104,14 +107,6 @@ try: path = elem.get( "file" ) tool = self.load_tool( os.path.join( tool_path, path ), guid=guid ) - if guid is not None: - # Tool was installed from a Galaxy tool shed. - tool.tool_shed = elem.find( "tool_shed" ).text - tool.repository_name = elem.find( "repository_name" ).text - tool.repository_owner = elem.find( "repository_owner" ).text - tool.changeset_revision = elem.find( "changeset_revision" ).text - tool.old_id = elem.find( "id" ).text - tool.version = elem.find( "version" ).text if self.app.config.get_bool( 'enable_tool_tags', False ): tag_names = elem.get( "tags", "" ).split( "," ) for tag_name in tag_names: @@ -372,7 +367,9 @@ # legacy basic mode - provide compatible defaults self.attributes['split_size'] = 20 self.attributes['split_mode'] = 'number_of_parts' - + + + class Tool: """ Represents a computational tool that can be executed through Galaxy. @@ -393,15 +390,9 @@ # easily ensure that parameter dependencies like index files or # tool_data_table_conf.xml entries exist. self.input_params = [] - # Attributes of tools installed from Galaxy tool sheds. - self.tool_shed = None - self.repository_name = None - self.repository_owner = None - self.changeset_revision = None - self.old_id = None - self.version = None # Parse XML element containing configuration self.parse( root, guid=guid ) + self.external_runJob_script = app.config.drmaa_external_runjob_script @property def sa_session( self ): @@ -420,14 +411,14 @@ raise Exception, "Missing tool 'name'" # Get the UNIQUE id for the tool # TODO: can this be generated automatically? - if guid is None: + if guid is not None: + self.id = guid + else: self.id = root.get( "id" ) - self.version = root.get( "version" ) - else: - self.id = guid if not self.id: - raise Exception, "Missing tool 'id'" - if not self.version: + raise Exception, "Missing tool 'id'" + self.version = root.get( "version" ) + if not self.version: # For backward compatibility, some tools may not have versions yet. self.version = "1.0.0" # Support multi-byte tools @@ -814,8 +805,7 @@ if elem.tag == "repeat": group = Repeat() group.name = elem.get( "name" ) - group.title = elem.get( "title" ) - group.help = elem.get( "help", None ) + group.title = elem.get( "title" ) group.inputs = self.parse_input_elem( elem, enctypes, context ) group.default = int( elem.get( "default", 0 ) ) group.min = int( elem.get( "min", 0 ) ) @@ -1578,13 +1568,13 @@ DatasetFilenameWrapper( converted_dataset, datatypes_registry = self.app.datatypes_registry, tool = Bunch( conversion_name = Bunch( extensions = conv_ext ) ), - name = conversion_name ) + name = conversion_name, config_info = self.app.config ) # Wrap actual input dataset input_values[ input.name ] = \ - DatasetFilenameWrapper( input_values[ input.name ], + DatasetFilenameWrapper( input_values[ input.name ], datatypes_registry = self.app.datatypes_registry, tool = self, - name = input.name ) + name = input.name, config_info = self.app.config ) elif isinstance( input, SelectToolParameter ): input_values[ input.name ] = SelectToolParameterWrapper( input, input_values[ input.name ], self.app, other_values = param_dict ) @@ -1622,28 +1612,28 @@ param_dict[name] = DatasetFilenameWrapper( data, datatypes_registry = self.app.datatypes_registry, tool = self, - name = name ) + name = name, config_info = self.app.config ) if data: for child in data.children: - param_dict[ "_CHILD___%s___%s" % ( name, child.designation ) ] = DatasetFilenameWrapper( child ) + param_dict[ "_CHILD___%s___%s" % ( name, child.designation ) ] = DatasetFilenameWrapper( child,config_info = self.app.config ) for name, hda in output_datasets.items(): # Write outputs to the working directory (for security purposes) # if desired. if self.app.config.outputs_to_working_directory: try: false_path = [ dp.false_path for dp in output_paths if dp.real_path == hda.file_name ][0] - param_dict[name] = DatasetFilenameWrapper( hda, false_path = false_path ) + param_dict[name] = DatasetFilenameWrapper( hda, false_path = false_path, config_info = self.app.config ) open( false_path, 'w' ).close() except IndexError: log.warning( "Unable to determine alternate path for writing job outputs, outputs will be written to their real paths" ) - param_dict[name] = DatasetFilenameWrapper( hda ) + param_dict[name] = DatasetFilenameWrapper( hda, config_info = self.app.config ) else: - param_dict[name] = DatasetFilenameWrapper( hda ) + param_dict[name] = DatasetFilenameWrapper( hda, config_info = self.app.config ) # Provide access to a path to store additional files # TODO: path munging for cluster/dataset server relocatability param_dict[name].files_path = os.path.abspath(os.path.join( job_working_directory, "dataset_%s_files" % (hda.dataset.id) )) for child in hda.children: - param_dict[ "_CHILD___%s___%s" % ( name, child.designation ) ] = DatasetFilenameWrapper( child ) + param_dict[ "_CHILD___%s___%s" % ( name, child.designation ) ] = DatasetFilenameWrapper( child, config_info = self.app.config ) for out_name, output in self.outputs.iteritems(): if out_name not in param_dict and output.filters: # Assume the reason we lack this output is because a filter @@ -1702,8 +1692,10 @@ fd, config_filename = tempfile.mkstemp( dir=directory ) os.close( fd ) f = open( config_filename, "wt" ) + os.chmod(config_filename, 0777) f.write( fill_template( template_text, context=param_dict ) ) f.close() + os.chmod(config_filename, 0777) param_dict[name] = config_filename config_filenames.append( config_filename ) return config_filenames @@ -1836,13 +1828,15 @@ """ for name, hda in output.items(): temp_file_path = os.path.join( job_working_directory, "dataset_%s_files" % ( hda.dataset.id ) ) - try: - if len( os.listdir( temp_file_path ) ) > 0: - store_file_path = os.path.join( - os.path.join( self.app.config.file_path, *directory_hash_id( hda.dataset.id ) ), + #try: + if os.path.exists(temp_file_path) and len( os.listdir( temp_file_path ) ) > 0: + store_file_path = os.path.join( + os.path.join( self.app.config.file_path, *directory_hash_id( hda.dataset.id ) ), "dataset_%d_files" % hda.dataset.id ) - shutil.move( temp_file_path, store_file_path ) - # Fix permissions + os.mkdir(store_file_path) + os.system('mv %s/* %s/' %(temp_file_path ,store_file_path)) + # Fix permissions + if self.external_runJob_script == None: for basedir, dirs, files in os.walk( store_file_path ): util.umask_fix_perms( basedir, self.app.config.umask, 0777, self.app.config.gid ) for file in files: @@ -1851,8 +1845,8 @@ if os.path.islink( path ): continue util.umask_fix_perms( path, self.app.config.umask, 0666, self.app.config.gid ) - except: - continue + #except: + #continue def collect_child_datasets( self, output): """ @@ -2243,7 +2237,7 @@ def items( self ): return iter( [ ( k, self.get( k ) ) for k, v in self.metadata.items() ] ) - def __init__( self, dataset, datatypes_registry = None, tool = None, name = None, false_path = None ): + def __init__( self, dataset, datatypes_registry = None, tool = None, name = None, false_path = None , config_info=None): if not dataset: try: # TODO: allow this to work when working with grouping @@ -2255,6 +2249,14 @@ self.dataset = dataset self.metadata = self.MetadataWrapper( dataset.metadata ) self.false_path = false_path + + # create web_display_url attribute + sec = security.SecurityHelper( id_secret=config_info.id_secret ) + try: + url = 'http://' + socket.getfqdn() + config_info.cookie_path + '/datasets/' + sec.encode_id(dataset.id) + '/display/?preview=True' + self.web_display_url = url + except: + self.web_display_url = None def __str__( self ): if self.false_path is not None: diff -r 070513d25b63110ef6569a9b09101864009f2ba4 -r 1d0bb560bd3d584708972001afd054774e9e89c5 lib/galaxy/tools/actions/__init__.py --- a/lib/galaxy/tools/actions/__init__.py +++ b/lib/galaxy/tools/actions/__init__.py @@ -150,7 +150,7 @@ galaxy.tools.DatasetFilenameWrapper( input_values[ input.name ], datatypes_registry = trans.app.datatypes_registry, tool = tool, - name = input.name ) + name = input.name, config_info = trans.app.config) elif isinstance( input, SelectToolParameter ): input_values[ input.name ] = galaxy.tools.SelectToolParameterWrapper( input, input_values[ input.name ], tool.app, other_values = incoming ) else: @@ -282,9 +282,12 @@ trans.sa_session.flush() trans.app.security_agent.set_all_dataset_permissions( data.dataset, output_permissions ) # Create an empty file immediately - open( data.file_name, "w" ).close() - # Fix permissions - util.umask_fix_perms( data.file_name, trans.app.config.umask, 0666 ) + self.external_runJob_script = trans.app.config.drmaa_external_runjob_script + if self.external_runJob_script == None: + open( data.file_name, "w" ).close() + # Fix permissions + util.umask_fix_perms( data.file_name, trans.app.config.umask, 0666) + log.debug('.DAT file name = %s\n' %(data.file_name)) # This may not be neccesary with the new parent/child associations data.designation = name # Copy metadata from one of the inputs if requested. diff -r 070513d25b63110ef6569a9b09101864009f2ba4 -r 1d0bb560bd3d584708972001afd054774e9e89c5 lib/galaxy/tools/actions/upload_common.py --- a/lib/galaxy/tools/actions/upload_common.py +++ b/lib/galaxy/tools/actions/upload_common.py @@ -279,8 +279,10 @@ is_binary = None try: link_data_only = uploaded_dataset.link_data_only + chmod_flag = 1 except: link_data_only = 'copy_files' + chmod_flag = 0 json = dict( file_type = uploaded_dataset.file_type, ext = uploaded_dataset.ext, name = uploaded_dataset.name, @@ -291,8 +293,12 @@ link_data_only = link_data_only, space_to_tab = uploaded_dataset.space_to_tab, path = uploaded_dataset.path ) + if chmod_flag == 0 and trans.app.config.drmaa_external_runjob_script: + os.chmod(uploaded_dataset.path, 0777) json_file.write( to_json_string( json ) + '\n' ) json_file.close() + if trans.app.config.drmaa_external_runjob_script: + os.chmod(json_file_path, 0777) return json_file_path def create_job( trans, params, tool, json_file_path, data_list, folder=None, return_job=False ): """ @@ -325,12 +331,17 @@ # Create an empty file immediately if not dataset.dataset.external_filename: open( dataset.file_name, "w" ).close() + if trans.app.config.drmaa_external_runjob_script: + os.chmod(dataset.file_name, 0777) else: for i, dataset in enumerate( data_list ): job.add_output_dataset( 'output%i' % i, dataset ) # Create an empty file immediately if not dataset.dataset.external_filename: open( dataset.file_name, "w" ).close() + if trans.app.config.drmaa_external_runjob_script: + os.chmod(dataset.file_name, 0777) + job.state = job.states.NEW trans.sa_session.add( job ) trans.sa_session.flush() diff -r 070513d25b63110ef6569a9b09101864009f2ba4 -r 1d0bb560bd3d584708972001afd054774e9e89c5 scripts/drmaa_external_killer.py --- /dev/null +++ b/scripts/drmaa_external_killer.py @@ -0,0 +1,63 @@ +#!/usr/bin/env python +import os +import sys +import errno +import pwd +#import drmaa +new_path = [ os.path.join( os.getcwd(), "lib" ) ] +new_path.extend( sys.path[1:] ) # remove scripts/ from the path +sys.path = new_path + +from galaxy import eggs +import pkg_resources +pkg_resources.require("simplejson") +import simplejson as json +pkg_resources.require("drmaa") +import drmaa + + + +def validate_paramters(): + if len(sys.argv)<3: + sys.stderr.write("usage: %s [job ID] [user uid]\n" % sys.argv[0]) + exit(1) + + jobID = sys.argv[1] + uid = int(sys.argv[2]) + + + + return jobID, uid + +def set_user(uid): + try: + gid = pwd.getpwuid(uid).pw_gid + os.setgid(gid) + os.setuid(uid) + except OSError, e: + if e.errno == errno.EPERM: + sys.stderr.write("error: setuid(%d) failed: permission denied. Did you setup 'sudo' correctly for this script?\n" % uid ) + exit(1) + else: + pass + if os.getuid()==0: + sys.stderr.write("error: UID is 0 (root) after changing user. This script should not be run as root. aborting.\n" ) + exit(1) + if os.geteuid()==0: + sys.stderr.write("error: EUID is 0 (root) after changing user. This script should not be run as root. aborting.\n" ) + exit(1) + +def main(): + jobID, uid = validate_paramters() + set_user(uid) + s=drmaa.Session() + s.initialize() + s.control(jobID,drmaa.JobControlAction.TERMINATE) + s.exit() + + + +if __name__ == "__main__": + main() + + diff -r 070513d25b63110ef6569a9b09101864009f2ba4 -r 1d0bb560bd3d584708972001afd054774e9e89c5 scripts/drmaa_external_runner.py --- /dev/null +++ b/scripts/drmaa_external_runner.py @@ -0,0 +1,108 @@ +#!/usr/bin/env python +import os +import sys +import errno +import pwd + +#import simplejson as json +#import drmaa +new_path = [ os.path.join( os.getcwd(), "lib" ) ] +new_path.extend( sys.path[1:] ) # remove scripts/ from the path +sys.path = new_path + +from galaxy import eggs +import pkg_resources +pkg_resources.require("simplejson") +import simplejson as json +pkg_resources.require("drmaa") +import drmaa + +DRMAA_jobTemplate_attributes = [ 'args', 'remoteCommand', 'outputPath', 'errorPath', 'nativeSpecification', + 'name','email','project' ] + +def load_job_template_from_file(jt, filename): + f = open(filename,'r') + data = json.load(f) + for attr in DRMAA_jobTemplate_attributes: + if attr in data: + setattr(jt, attr, data[attr]) + +def valid_numeric_userid(userid): + try: + uid = int(userid) + except: + return False + try: + pw = pwd.getpwuid(uid) + except KeyError: + sys.stderr.write("error: User-ID (%d) is not valid.\n" % uid) + exit(1) + return True + +def get_user_id_by_name(username): + try: + pw = pwd.getpwnam(username) + except KeyError: + sys.stderr.write("error: User name (%s) is not valid.\n" % username) + exit(1) + return pw.pw_uid +def validate_paramters(): + if len(sys.argv)<3: + sys.stderr.write("usage: %s [USER-ID] [JSON-JOB-TEMPLATE-FILE]\n" % sys.argv[0]) + exit(1) + + userid = sys.argv[1] + json_filename = sys.argv[2] + + if valid_numeric_userid(userid): + uid = int(userid) + else: + uid = get_user_id_by_name(userid) + + if uid == 0: + sys.stderr.write("error: userid must not be 0 (root)\n") + exit(1) + + if not os.path.exists(json_filename): + sys.stderr.write("error: JobTemplate file (%s) doesn't exist\n" % ( json_filename ) ) + exit(1) + + return uid, json_filename + +def set_user(uid): + try: + # Get user's default group and set it to current process to make sure file permissions are inherited correctly + # Solves issue with permission denied for JSON files + gid = pwd.getpwuid(uid).pw_gid + os.setgid(gid) + os.setuid(uid) + except OSError, e: + if e.errno == errno.EPERM: + sys.stderr.write("error: setuid(%d) failed: permission denied. Did you setup 'sudo' correctly for this script?\n" % uid ) + exit(1) + else: + pass + if os.getuid()==0: + sys.stderr.write("error: UID is 0 (root) after changing user. This script should not be run as root. aborting.\n" ) + exit(1) + if os.geteuid()==0: + sys.stderr.write("error: EUID is 0 (root) after changing user. This script should not be run as root. aborting.\n" ) + exit(1) +def main(): + userid, json_filename = validate_paramters() + set_user(userid) + s = drmaa.Session() + s.initialize() + jt = s.createJobTemplate() + load_job_template_from_file(jt, json_filename) + # runJob will raise if there's a submittion error + jobId = s.runJob(jt) + s.deleteJobTemplate(jt) + s.exit() + + # Print the Job-ID and exit. Galaxy will pick it up from there. + print jobId + +if __name__ == "__main__": + main() + diff -r 070513d25b63110ef6569a9b09101864009f2ba4 -r 1d0bb560bd3d584708972001afd054774e9e89c5 scripts/external_chown_script.py --- /dev/null +++ b/scripts/external_chown_script.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python +import os +import sys +import errno +import pwd +#import drmaa +new_path = [ os.path.join( os.getcwd(), "lib" ) ] +new_path.extend( sys.path[1:] ) # remove scripts/ from the path +sys.path = new_path + +from galaxy import eggs +import pkg_resources +pkg_resources.require("simplejson") +import simplejson as json +pkg_resources.require("drmaa") +import drmaa + + + +def validate_paramters(): + if len(sys.argv)<4: + sys.stderr.write("usage: %s path user_name gid\n" % sys.argv[0]) + exit(1) + + path = sys.argv[1] + galaxy_user_name = sys.argv[2] + gid = sys.argv[3] + + + + return path, galaxy_user_name, gid + +def main(): + path, galaxy_user_name, gid = validate_paramters() + os.system('chown %s %s' %(galaxy_user_name, path)) + os.system('chgrp %s %s' %(gid, path)) + + + +if __name__ == "__main__": + main() + + diff -r 070513d25b63110ef6569a9b09101864009f2ba4 -r 1d0bb560bd3d584708972001afd054774e9e89c5 tools/data_source/upload.py --- a/tools/data_source/upload.py +++ b/tools/data_source/upload.py @@ -165,6 +165,7 @@ dataset.path = uncompressed else: shutil.move( uncompressed, dataset.path ) + os.chmod(dataset.path, 0644) dataset.name = dataset.name.rstrip( '.gz' ) data_type = 'gzip' if not data_type and bz2 is not None: @@ -197,6 +198,7 @@ dataset.path = uncompressed else: shutil.move( uncompressed, dataset.path ) + os.chmod(dataset.path, 0644) dataset.name = dataset.name.rstrip( '.bz2' ) data_type = 'bz2' if not data_type: @@ -253,6 +255,7 @@ dataset.path = uncompressed else: shutil.move( uncompressed, dataset.path ) + os.chmod(dataset.path, 0644) dataset.name = uncompressed_name data_type = 'zip' if not data_type: @@ -312,9 +315,18 @@ pass else: # This should not happen, but it's here just in case - shutil.copy( dataset.path, output_path ) + shutil.move( dataset.path, output_path ) + try: + os.chmod(output_path,0644) + except: + pass elif link_data_only == 'copy_files': shutil.move( dataset.path, output_path ) + try: + os.chmod(output_path,0644) + except: + pass + # Write the job info stdout = stdout or 'uploaded %s file' % data_type info = dict( type = 'dataset', diff -r 070513d25b63110ef6569a9b09101864009f2ba4 -r 1d0bb560bd3d584708972001afd054774e9e89c5 tools/ngs_rna/cufflinks_wrapper.xml --- a/tools/ngs_rna/cufflinks_wrapper.xml +++ b/tools/ngs_rna/cufflinks_wrapper.xml @@ -1,5 +1,4 @@ -<tool id="cufflinks" name="Cufflinks" version="0.0.5"> - <!-- Wrapper supports Cufflinks versions v1.0.0-v1.0.3 --> +<tool id="cufflinks" name="Cufflinks" version="0.9.1"><description>transcript assembly and FPKM (RPKM) estimates for RNA-Seq data</description><requirements><requirement type="package">cufflinks</requirement> @@ -15,10 +14,27 @@ ## Include reference annotation? #if $reference_annotation.use_ref == "Use reference annotation": - -G $reference_annotation.reference_annotation_file + #if $reference_annotation.annotationSource.reference_annotation_file == "indexed": + -G "${ filter( lambda x: str( x[0] ) == str( $reference_annotation.annotationSource.indices ), $__app__.tool_data_tables[ 'gtf_index' ].get_fields() )[0][-1] }" + #else: + #if $reference_annotation.annotationSource.reference_annotation_file == "attribute": + -G "${ filter( lambda x: str( x[0] ) == str( $input.metadata.dbkey ), $__app__.tool_data_tables[ 'gtf_index' ].get_fields() )[0][-1] }" + #else: + -G "${reference_annotation.annotationSource.ownFile}" + #end if + #end if #end if + #if $reference_annotation.use_ref == "Use reference annotation guide": - -g $reference_annotation.reference_annotation_guide_file + #if $reference_annotation.annotationSource.reference_annotation_file == "indexed": + -g "${ filter( lambda x: str( x[0] ) == str( $reference_annotation.annotationSource.indices ), $__app__.tool_data_tables[ 'gtf_index' ].get_fields() )[0][-1] }" + #else: + #if $reference_annotation.annotationSource.reference_annotation_file == "attribute": + -g "${ filter( lambda x: str( x[0] ) == str( $input.metadata.dbkey ), $__app__.tool_data_tables[ 'gtf_index' ].get_fields() )[0][-1] }" + #else: + -g "${reference_annotation.annotationSource.ownFile}" + #end if + #end if #end if ## Set paired-end parameters? @@ -61,10 +77,44 @@ </param><when value="No"></when><when value="Use reference annotation"> - <param format="gff3,gtf" name="reference_annotation_file" type="data" label="Reference Annotation" help="Make sure your annotation file is in GTF format and that Galaxy knows that your file is GTF--not GFF."/> - </when> + <conditional name="annotationSource"> + <param name="reference_annotation_file" type="select" label="Please select a reference Aonnotation"> + <option value="indexed">Use a built-in index</option> + <option value="history">Use one from the history</option> + <option value="attribute">Use input bam metadata.dbkey attribute</option> + </param> + <when value="indexed"> + <param name="indices" type="select" label="Select genome for gtf annotation"> + <options from_data_table="gtf_index"> + <filter type="sort_by" column="3" /> + <validator type="no_options" message="No indexes are available for the selected input dataset" /> + </options> + </param> + </when> + <when value="history"> + <param name="ownFile" type="data" format="gff3, gtf" label="Select a reference annotation file" /> + </when> + </conditional> + </when><when value="Use reference annotation guide"> - <param format="gff3,gtf" name="reference_annotation_guide_file" type="data" label="Reference Annotation" help="Make sure your annotation file is in GTF format and that Galaxy knows that your file is GTF--not GFF."/> + <conditional name="annotationSource"> + <param name="reference_annotation_file" type="select" label="Please select a reference Aonnotation"> + <option value="indexed">Use a built-in index</option> + <option value="history">Use one from the history</option> + <option value="attribute">Use input bam metadata.dbkey attribute</option> + </param> + <when value="indexed"> + <param name="indices" type="select" label="Select genome for gtf annotation"> + <options from_data_table="gtf_index"> + <filter type="sort_by" column="3" /> + <validator type="no_options" message="No indexes are available for the selected input dataset" /> + </options> + </param> + </when> + <when value="history"> + <param name="ownFile" type="data" format="gff3, gtf" label="Select a reference annotation file" /> + </when> + </conditional></when></conditional><conditional name="bias_correction"> diff -r 070513d25b63110ef6569a9b09101864009f2ba4 -r 1d0bb560bd3d584708972001afd054774e9e89c5 tools/ngs_rna/tophat_wrapper.xml --- a/tools/ngs_rna/tophat_wrapper.xml +++ b/tools/ngs_rna/tophat_wrapper.xml @@ -1,7 +1,8 @@ -<tool id="tophat" name="Tophat for Illumina" version="1.5.0"> +<tool id="tophat" name="Tophat" version="1.2.1"><description>Find splice junctions using RNA-seq data</description> - <version_command>tophat --version</version_command><requirements> + <requirement type="package">samtools</requirement> + <requirement type="package">bowtie</requirement><requirement type="package">tophat</requirement></requirements><command interpreter="python"> @@ -17,14 +18,18 @@ #if $refGenomeSource.genomeSource == "history": --own-file=$refGenomeSource.ownFile #else: - --indexes-path="${ filter( lambda x: str( x[0] ) == str( $refGenomeSource.index ), $__app__.tool_data_tables[ 'tophat_indexes' ].get_fields() )[0][-1] }" + #if $refGenomeSource.genomeSource == "indexed": + --indexes-path="${ filter( lambda x: str( x[0] ) == str( $refGenomeSource.index ), $__app__.tool_data_tables[ 'tophat_indexes' ].get_fields() )[0][-1] }" + #else: + --indexes-path="${ filter( lambda x: str( x[0] ) == str( $singlePaired.input1.metadata.dbkey ), $__app__.tool_data_tables[ 'tophat_indexes' ].get_fields() )[0][-1] }" + #end if #end if ## Are reads single-end or paired? --single-paired=$singlePaired.sPaired ## First input file always required. - --input1=$input1 + --input1=$singlePaired.input1 ## Set params based on whether reads are single-end or paired. #if $singlePaired.sPaired == "single": @@ -52,7 +57,15 @@ ## Supplying junctions parameters. #if $singlePaired.sParams.own_junctions.use_junctions == "Yes": #if $singlePaired.sParams.own_junctions.gene_model_ann.use_annotations == "Yes": - -G $singlePaired.sParams.own_junctions.gene_model_ann.gene_annotation_model + #if $singlePaired.sParams.own_junctions.gene_model_ann.annotationSource.reference_annotation_file == "indexed": + -G "${ filter( lambda x: str( x[0] ) == str( $refGenomeSource.index ), $__app__.tool_data_tables[ 'gtf_index' ].get_fields() )[0][-1] }" + #else: + #if $singlePaired.sParams.own_junctions.gene_model_ann.annotationSource.reference_annotation_file == "attribute": + -G "${ filter( lambda x: str( x[0] ) == str( $singlePaired.input1.metadata.dbkey ), $__app__.tool_data_tables[ 'gtf_index' ].get_fields() )[0][-1] }" + #else + -G "${singlePaired.sParams.own_junctions.gene_model_ann.annotationSource.owngtfFile}" + #end if + #end if #end if #if $singlePaired.sParams.own_junctions.raw_juncs.use_juncs == "Yes": -j $singlePaired.sParams.own_junctions.raw_juncs.raw_juncs @@ -111,7 +124,15 @@ ## Supplying junctions parameters. #if $singlePaired.pParams.own_junctions.use_junctions == "Yes": #if $singlePaired.pParams.own_junctions.gene_model_ann.use_annotations == "Yes": - -G $singlePaired.pParams.own_junctions.gene_model_ann.gene_annotation_model + #if $singlePaired.pParams.own_junctions.gene_model_ann.annotationSource.reference_annotation_file == "indexed": + -G "${ filter( lambda x: str( x[0] ) == str( $refGenomeSource.index ), $__app__.tool_data_tables[ 'gtf_index' ].get_fields() )[0][-1] }" + #else: + #if $singlePaired.pParams.own_junctions.gene_model_ann.annotationSource.reference_annotation_file == "attribute": + -G "${ filter( lambda x: str( x[0] ) == str( $singlePaired.input1.metadata.dbkey ), $__app__.tool_data_tables[ 'gtf_index' ].get_fields() )[0][-1] }" + #else + -G "${singlePaired.sParams.own_junctions.gene_model_ann.annotationSource.owngtfFile}" + #end if + #end if #end if #if $singlePaired.pParams.own_junctions.raw_juncs.use_juncs == "Yes": -j $singlePaired.pParams.own_junctions.raw_juncs.raw_juncs @@ -145,18 +166,15 @@ #end if </command><inputs> - <param format="fastqsanger" name="input1" type="data" label="RNA-Seq FASTQ file" help="Nucleotide-space: Must have Sanger-scaled quality values with ASCII offset 33" /><conditional name="refGenomeSource"><param name="genomeSource" type="select" label="Will you select a reference genome from your history or use a built-in index?" help="Built-ins were indexed using default options"><option value="indexed">Use a built-in index</option><option value="history">Use one from the history</option> + <option value="attribute">Use input fastq metadata.dbkey attribute</option></param><when value="indexed"><param name="index" type="select" label="Select a reference genome" help="If your genome of interest is not listed, contact the Galaxy team"> - <options from_data_table="tophat_indexes"> - <filter type="sort_by" column="2"/> - <validator type="no_options" message="No indexes are available for the selected input dataset"/> - </options> + <options from_data_table="tophat_indexes" /></param></when><when value="history"> @@ -169,6 +187,7 @@ <option value="paired">Paired-end</option></param><when value="single"> + <param format="fastqsanger" name="input1" type="data" label="RNA-Seq FASTQ file" help="Must have Sanger-scaled quality values with ASCII offset 33"/><conditional name="sParams"><param name="sSettingsType" type="select" label="TopHat settings to use" help="You can use the default settings or set custom values for any of Tophat's parameters."><option value="preSet">Use Defaults</option> @@ -218,7 +237,16 @@ </param><when value="No" /><when value="Yes"> - <param format="gtf" name="gene_annotation_model" type="data" label="Gene Model Annotations" help="TopHat will use the exon records in this file to build a set of known splice junctions for each gene, and will attempt to align reads to these junctions even if they would not normally be covered by the initial mapping."/> + <conditional name="annotationSource"> + <param name="reference_annotation_file" type="select" label="Please select a reference Aonnotation"> + <option value="indexed">Use a built-in index</option> + <option value="history">Use one from the history</option> + <option value="attribute">Use metadata.bkey attribute from input fastq file</option> + </param> + <when value="history"> + <param name="owngtfFile" type="data" format="gff3, gtf" label="Select a reference annotation file" /> + </when> + </conditional></when></conditional><conditional name="raw_juncs"> @@ -263,7 +291,7 @@ <param name="max_coverage_intron" type="integer" value="20000" label="Maximum intron length that may be found during coverage search" /></when><when value="No" /> - </conditional> + </conditional><param name="microexon_search" type="select" label="Use Microexon Search" help="With this option, the pipeline will attempt to find alignments incident to microexons. Works only for reads 50bp or longer."><option value="No">No</option><option value="Yes">Yes</option> @@ -272,7 +300,8 @@ </conditional><!-- sParams --></when><!-- single --><when value="paired"> - <param format="fastqsanger" name="input2" type="data" label="RNA-Seq FASTQ file" help="Nucleotide-space: Must have Sanger-scaled quality values with ASCII offset 33" /> + <param format="fastqsanger" name="input1" type="data" label="RNA-Seq FASTQ file" help="Must have Sanger-scaled quality values with ASCII offset 33"/> + <param format="fastqsanger" name="input2" type="data" label="RNA-Seq FASTQ file" help="Must have Sanger-scaled quality values with ASCII offset 33"/><param name="mate_inner_distance" type="integer" value="20" label="Mean Inner Distance between Mate Pairs" /><conditional name="pParams"><param name="pSettingsType" type="select" label="TopHat settings to use" help="For most mapping needs use Commonly used settings. If you want full control use Full parameter list"> @@ -323,7 +352,16 @@ </param><when value="No" /><when value="Yes"> - <param format="gtf" name="gene_annotation_model" type="data" label="Gene Model Annotations" help="TopHat will use the exon records in this file to build a set of known splice junctions for each gene, and will attempt to align reads to these junctions even if they would not normally be covered by the initial mapping."/> + <conditional name="annotationSource"> + <param name="reference_annotation_file" type="select" label="Please select a reference Aonnotation"> + <option value="indexed">Use a built-in index</option> + <option value="history">Use one from the history</option> + <option value="attribute">Use metadata.bkey attribute from input fastq files</option> + </param> + <when value="history"> + <param name="owngtfFile" type="data" format="gff3, gtf" label="Select a reference annotation file" /> + </when> + </conditional></when></conditional><conditional name="raw_juncs"> @@ -387,7 +425,7 @@ ( singlePaired['sParams']['indel_search']['allow_indel_search'] == 'Yes' ) ) or ( ( 'pParams' in singlePaired ) and ( 'indel_search' in singlePaired['pParams'] ) and ( singlePaired['pParams']['indel_search']['allow_indel_search'] == 'Yes' ) ) - ) + ) </filter><actions><conditional name="refGenomeSource.genomeSource"> @@ -475,49 +513,46 @@ </outputs><tests> - <!-- Test base-space single-end reads with pre-built index and preset parameters --> + <!-- Test single-end reads with pre-built index and preset parameters --><test><!-- TopHat commands: - tophat -o tmp_dir -p 1 tophat_in1 test-data/tophat_in2.fastqsanger - Rename the files in tmp_dir appropriately + tophat -o tmp_dir -p 1 /afs/bx.psu.edu/depot/data/genome/test/tophat/tophat_in1 test-data/tophat_in2.fastqsanger --> - <param name="input1" ftype="fastqsanger" value="tophat_in2.fastqsanger" /><param name="genomeSource" value="indexed" /><param name="index" value="tophat_test" /><param name="sPaired" value="single" /> + <param name="input1" ftype="fastqsanger" value="tophat_in2.fastqsanger" /><param name="sSettingsType" value="preSet" /><output name="junctions" file="tophat_out1j.bed" /><output name="accepted_hits" file="tophat_out1h.bam" compare="sim_size" /></test> - <!-- Test using base-space test data: paired-end reads, index from history. --> + <!-- Test using test data: paired-end reads, index from history. --><test><!-- TopHat commands: bowtie-build -f test-data/tophat_in1.fasta tophat_in1 tophat -o tmp_dir -p 1 -r 20 tophat_in1 test-data/tophat_in2.fastqsanger test-data/tophat_in3.fastqsanger - Rename the files in tmp_dir appropriately --> - <param name="input1" ftype="fastqsanger" value="tophat_in2.fastqsanger" /><param name="genomeSource" value="history" /><param name="ownFile" ftype="fasta" value="tophat_in1.fasta" /><param name="sPaired" value="paired" /> + <param name="input1" ftype="fastqsanger" value="tophat_in2.fastqsanger" /><param name="input2" ftype="fastqsanger" value="tophat_in3.fastqsanger" /><param name="mate_inner_distance" value="20" /><param name="pSettingsType" value="preSet" /><output name="junctions" file="tophat_out2j.bed" /><output name="accepted_hits" file="tophat_out2h.bam" compare="sim_size" /></test> - <!-- Test base-space single-end reads with user-supplied reference fasta and full parameters --> + <!-- Test single-end reads with user-supplied reference fasta and full parameters --><test><!-- Tophat commands: bowtie-build -f test-data/tophat_in1.fasta tophat_in1 tophat -o tmp_dir -p 1 -a 8 -m 0 -i 70 -I 500000 -F 0.15 -g 40 +allow-indels +coverage-search +min-coverage-intron 50 +max-coverage-intro 20000 +segment-mismatches 2 +segment-length 25 +closure-search +min-closure-exon 50 +min-closure-intron 50 +max-closure-intro 5000 +microexon-search tophat_in1 test-data/tophat_in2.fastqsanger Replace the + with double-dash - Rename the files in tmp_dir appropriately --> - <param name="input1" ftype="fastqsanger" value="tophat_in2.fastqsanger"/><param name="genomeSource" value="history"/><param name="ownFile" value="tophat_in1.fasta"/><param name="sPaired" value="single"/> + <param name="input1" ftype="fastqsanger" value="tophat_in2.fastqsanger"/><param name="sSettingsType" value="full"/><param name="library_type" value="FR Unstranded"/><param name="anchor_length" value="8"/> @@ -550,17 +585,16 @@ <output name="junctions" file="tophat_out3j.bed" /><output name="accepted_hits" file="tophat_out3h.bam" compare="sim_size" /></test> - <!-- Test base-space paired-end reads with user-supplied reference fasta and full parameters --> + <!-- Test paired-end reads with user-supplied reference fasta and full parameters --><test><!-- TopHat commands: - tophat -o tmp_dir -r 20 -p 1 -a 8 -m 0 -i 70 -I 500000 -F 0.15 -g 40 +coverage-search +min-coverage-intron 50 +max-coverage-intro 20000 +segment-mismatches 2 +segment-length 25 +closure-search +min-closure-exon 50 +min-closure-intron 50 +max-closure-intron 5000 +microexon-search tophat_in1 test-data/tophat_in2.fastqsanger test-data/tophat_in3.fastqsanger + tophat -o tmp_dir -r 20 -p 1 -a 8 -m 0 -i 70 -I 500000 -F 0.15 -g 40 +coverage-search +min-coverage-intron 50 +max-coverage-intro 20000 +segment-mismatches 2 +segment-length 25 +closure-search +min-closure-exon 50 +min-closure-intron 50 +max-closure-intron 5000 +microexon-search /afs/bx.psu.edu/depot/data/genome/test/tophat/tophat_in1 test-data/tophat_in2.fastqsanger test-data/tophat_in3.fastqsanger Replace the + with double-dash - Rename the files in tmp_dir appropriately --> - <param name="input1" ftype="fastqsanger" value="tophat_in2.fastqsanger"/><param name="genomeSource" value="indexed"/><param name="index" value="tophat_test"/><param name="sPaired" value="paired"/> + <param name="input1" ftype="fastqsanger" value="tophat_in2.fastqsanger"/><param name="input2" ftype="fastqsanger" value="tophat_in3.fastqsanger"/><param name="mate_inner_distance" value="20"/><param name="pSettingsType" value="full"/> @@ -628,9 +662,7 @@ .. _BED: http://genome.ucsc.edu/FAQ/FAQformat.html#format1 .. _BAM: http://samtools.sourceforge.net/ - -Two other possible outputs, depending on the options you choose, are insertions and deletions, both of which are in BED format. - + ------- **Tophat settings** @@ -649,7 +681,7 @@ --mate-std-dev INT The standard deviation for the distribution on inner distances between mate pairs. The default is 20bp. -a/--min-anchor-length INT The "anchor length". TopHat will report junctions spanned by reads with at least this many bases on each side of the junction. Note that individual spliced alignments may span a junction with fewer than this many bases on one side. However, every junction involved in spliced alignments is supported by at least one - read with this many bases on each side. This must be at least 3 and the default is 8. + read with this many bases on each side. This must be at least 3 and the default is 8. -m/--splice-mismatches INT The maximum number of mismatches that may appear in the "anchor" region of a spliced alignment. The default is 0. -i/--min-intron-length INT The minimum intron length. TopHat will ignore donor/acceptor pairs closer than this many bases apart. The default is 70. -I/--max-intron-length INT The maximum intron length. When searching for junctions ab initio, TopHat will ignore donor/acceptor pairs farther than this many bases apart, except when such a pair is supported by a split segment alignment of a long read. The default is 500000. diff -r 070513d25b63110ef6569a9b09101864009f2ba4 -r 1d0bb560bd3d584708972001afd054774e9e89c5 universe_wsgi.ini.sample --- a/universe_wsgi.ini.sample +++ b/universe_wsgi.ini.sample @@ -446,6 +446,14 @@ # large servers. #enable_tool_tags = False +# Enable a feature when running workflows. When enabled, default datasets +# are selected for "Set at Runtime" inputs from the history such that the +# same input will not be selected twice, unless there are more inputs than +# compatible datasets in the history. +# When False, the most recently added compatible item in the history will +# be used for each "Set at Runtime" input, independent of others in the Workflow +#enable_unique_workflow_defaults = False + # Enable Galaxy's "Upload via FTP" interface. You'll need to install and # configure an FTP server (we've used ProFTPd since it can use Galaxy's # database for authentication) and set the following two options. @@ -533,6 +541,30 @@ # currently available are 'pbs' and 'drmaa'. #start_job_runners = None +# Uncomment drmaa_external_runjob_script , drmaa_external_killjob_script, and external_chown_script pameters and have them point to the +# absolute path for scripts/drmaa_external_runner.py and scripts/drmaa_external_killer.py. +# The scripts directory is located in the top level galaxy directory. The parameters when +# uncommented allow for submission to the drmaa queue with the user name of the user submitting +# the job and not the galaxy user. In order for this to work the actual user must log into galaxy +# and the galaxy authentication must be consistent with the authentication on the server in which the +# drmaa queue is running (i.e. the username must have an account on the server and be allowed to +# submit jobs to the queue). The galaxy user must also be given sudo permission to execute +# scripts/drmaa_external_runner.py and scripts/drmaa_external_killer.py in /etc/sudoers +# Example: +# galaxy ALL = (root) NOPASSWD: SETENV: /opt/galaxy/scripts/drmaa_external_runner.py +# galaxy ALL = (root) NOPASSWD: SETENV: /opt/galaxy/scripts/drmaa_external_killer.py +# Also the +# Defaults requiretty +# in /etc/sudoers must be commented out +#drmaa_external_runjob_script = /opt/galaxy/scripts/drmaa_external_runner.py +#drmaa_external_killjob_script = /opt/galaxy/scripts/drmaa_external_killer.py +#external_chown_script = /opt/galaxy/scripts/external_chown_script.py + +#important if running as actual user since enviromental variables are not passed +#will supercede an other definition of TMPDIR if using drmaa +#TMPDIR = /opt/galaxy/database/tmp + + # The URL for the default runner to use when a tool doesn't explicitly define a # runner below. #default_cluster_job_runner = local:/// @@ -554,7 +586,9 @@ # run with the runner defined with default_cluster_job_runner. [galaxy:tool_runners] - +binsort = drmaa://-cwd -V -pe threaded 4/ +bwa_wrapper = drmaa://-cwd -V -pe threaded 4/ +unified_genotyper = drmaa://-cwd -V -pe threaded 2/ biomart = local:/// encode_db1 = local:/// hbvar = local:/// https://bitbucket.org/galaxy/galaxy-central/changeset/28ab7dde0972/ changeset: 28ab7dde0972 user: ichorny date: 2011-10-21 23:05:06 summary: merge with galaxy central affected #: 27 files diff -r 1d0bb560bd3d584708972001afd054774e9e89c5 -r 28ab7dde097298b7565a6238f0bbcade29a73ae9 lib/galaxy/util/__init__.py --- a/lib/galaxy/util/__init__.py +++ b/lib/galaxy/util/__init__.py @@ -133,6 +133,8 @@ def restore_text(text): """Restores sanitized text""" + if not text: + return text for key, value in mapped_chars.items(): text = text.replace(value, key) return text diff -r 1d0bb560bd3d584708972001afd054774e9e89c5 -r 28ab7dde097298b7565a6238f0bbcade29a73ae9 lib/galaxy/web/api/histories.py --- a/lib/galaxy/web/api/histories.py +++ b/lib/galaxy/web/api/histories.py @@ -88,9 +88,9 @@ state = states.QUEUED elif summary[states.OK] == num_sets: state = states.OK + item['state_details'] = summary item['contents_url'] = url_for( 'history_contents', history_id=history_id ) item['state'] = state - item['state_details'] = summary except Exception, e: item = "Error in history API at showing history detail" log.error(item + ": %s" % str(e)) diff -r 1d0bb560bd3d584708972001afd054774e9e89c5 -r 28ab7dde097298b7565a6238f0bbcade29a73ae9 lib/galaxy/web/api/history_contents.py --- a/lib/galaxy/web/api/history_contents.py +++ b/lib/galaxy/web/api/history_contents.py @@ -14,7 +14,7 @@ log = logging.getLogger( __name__ ) -class HistoryContentsController( BaseAPIController, UsesHistoryDatasetAssociation, UsesHistory ): +class HistoryContentsController( BaseAPIController, UsesHistoryDatasetAssociation, UsesHistory, UsesLibrary, UsesLibraryItems ): @web.expose_api def index( self, trans, history_id, **kwd ): @@ -85,7 +85,7 @@ if from_ld_id: try: - ld = get_library_content_for_access( trans, from_ld_id ) + ld = self.get_library_dataset( trans, from_ld_id, check_ownership=False, check_accessible=False ) assert type( ld ) is trans.app.model.LibraryDataset, "Library content id ( %s ) is not a dataset" % from_ld_id except AssertionError, e: trans.response.status = 400 diff -r 1d0bb560bd3d584708972001afd054774e9e89c5 -r 28ab7dde097298b7565a6238f0bbcade29a73ae9 lib/galaxy/web/api/library_contents.py --- a/lib/galaxy/web/api/library_contents.py +++ b/lib/galaxy/web/api/library_contents.py @@ -75,9 +75,9 @@ """ class_name, content_id = self.__decode_library_content_id( trans, id ) if class_name == 'LibraryFolder': - content = self.get_library_folder( trans, content_id, check_ownership=False, check_accessibility=True ) + content = self.get_library_folder( trans, content_id, check_ownership=False, check_accessible=True ) else: - content = self.get_library_dataset( trans, content_id, check_ownership=False, check_accessibility=True ) + content = self.get_library_dataset( trans, content_id, check_ownership=False, check_accessible=True ) return self.encode_all_ids( trans, content.get_api_value( view='element' ) ) @web.expose_api @@ -100,9 +100,10 @@ return "Missing requred 'folder_id' parameter." else: folder_id = payload.pop( 'folder_id' ) + class_name, folder_id = self.__decode_library_content_id( trans, folder_id ) try: # security is checked in the downstream controller - parent = self.get_library_folder( trans, folder_id, check_ownership=False, check_accessibility=False ) + parent = self.get_library_folder( trans, folder_id, check_ownership=False, check_accessible=False ) except Exception, e: return str( e ) # The rest of the security happens in the library_common controller. @@ -128,6 +129,23 @@ url = url_for( 'library_content', library_id=library_id, id=encoded_id ) ) ) return rval + @web.expose_api + def update( self, trans, id, library_id, payload, **kwd ): + """ + PUT /api/libraries/{encoded_library_id}/contents/{encoded_content_type_and_id} + Sets relationships among items + """ + if 'converted_dataset_id' in payload: + converted_id = payload.pop( 'converted_dataset_id' ) + content = self.get_library_dataset( trans, id, check_ownership=False, check_accessible=False ) + content_conv = self.get_library_dataset( trans, converted_id, check_ownership=False, check_accessible=False ) + assoc = trans.app.model.ImplicitlyConvertedDatasetAssociation( parent = content.library_dataset_dataset_association, + dataset = content_conv.library_dataset_dataset_association, + file_type = content_conv.library_dataset_dataset_association.extension, + metadata_safe = True ) + trans.sa_session.add( assoc ) + trans.sa_session.flush() + def __decode_library_content_id( self, trans, content_id ): if ( len( content_id ) % 16 == 0 ): return 'LibraryDataset', content_id diff -r 1d0bb560bd3d584708972001afd054774e9e89c5 -r 28ab7dde097298b7565a6238f0bbcade29a73ae9 lib/galaxy/web/controllers/admin.py --- a/lib/galaxy/web/controllers/admin.py +++ b/lib/galaxy/web/controllers/admin.py @@ -708,7 +708,7 @@ def browse_tool_shed( self, trans, **kwd ): tool_shed_url = kwd[ 'tool_shed_url' ] galaxy_url = trans.request.host - url = '%s/repository/browse_downloadable_repositories?galaxy_url=%s&webapp=galaxy' % ( tool_shed_url, galaxy_url ) + url = '%s/repository/browse_valid_repositories?galaxy_url=%s&webapp=galaxy' % ( tool_shed_url, galaxy_url ) return trans.response.send_redirect( url ) @web.expose @web.require_admin diff -r 1d0bb560bd3d584708972001afd054774e9e89c5 -r 28ab7dde097298b7565a6238f0bbcade29a73ae9 lib/galaxy/webapps/community/controllers/repository.py --- a/lib/galaxy/webapps/community/controllers/repository.py +++ b/lib/galaxy/webapps/community/controllers/repository.py @@ -183,7 +183,7 @@ .outerjoin( model.RepositoryCategoryAssociation.table ) \ .outerjoin( model.Category.table ) -class DownloadableRepositoryListGrid( RepositoryListGrid ): +class ValidRepositoryListGrid( RepositoryListGrid ): class RevisionColumn( grids.GridColumn ): def __init__( self, col_name ): grids.GridColumn.__init__( self, col_name ) @@ -196,7 +196,7 @@ if len( select_field.options ) > 1: return select_field.get_html() return repository.revision - title = "Downloadable repositories" + title = "Valid repositories" columns = [ RepositoryListGrid.NameColumn( "Name", key="name", @@ -210,11 +210,6 @@ attach_popup=False, key="User.username" ) ] - columns.append( grids.MulticolFilterColumn( "Search repository name, description", - cols_to_filter=[ columns[0], columns[1] ], - key="free-text-search", - visible=False, - filterable="standard" ) ) operations = [] def build_initial_query( self, trans, **kwd ): return trans.sa_session.query( self.model_class ) \ @@ -237,7 +232,7 @@ return repository_metadata.repository.user.username return 'no user' # Grid definition - title = "Matched repositories" + title = "Repositories with matching tools" model_class = model.RepositoryMetadata template='/webapps/community/repository/grid.mako' default_sort_key = "Repository.name" @@ -282,21 +277,19 @@ .filter( self.model_class.table.c.repository_id == 0 ) class InstallMatchedRepositoryListGrid( MatchedRepositoryListGrid ): - # Grid definition - title = "Repositories that contain tools matching search criteria" columns = [ col for col in MatchedRepositoryListGrid.columns ] # Override the NameColumn columns[ 0 ] = MatchedRepositoryListGrid.NameColumn( "Name", link=( lambda item: dict( operation="view_or_manage_repository", id=item.id, webapp="galaxy" ) ), - attach_popup=True ) + attach_popup=False ) class RepositoryController( BaseUIController, ItemRatings ): install_matched_repository_list_grid = InstallMatchedRepositoryListGrid() matched_repository_list_grid = MatchedRepositoryListGrid() - downloadable_repository_list_grid = DownloadableRepositoryListGrid() + valid_repository_list_grid = ValidRepositoryListGrid() repository_list_grid = RepositoryListGrid() category_list_grid = CategoryListGrid() @@ -340,7 +333,7 @@ # Render the list view return self.category_list_grid( trans, **kwd ) @web.expose - def browse_downloadable_repositories( self, trans, **kwd ): + def browse_valid_repositories( self, trans, **kwd ): webapp = kwd.get( 'webapp', 'community' ) galaxy_url = kwd.get( 'galaxy_url', None ) if galaxy_url: @@ -352,6 +345,7 @@ repository = get_repository( trans, repository_id ) return trans.response.send_redirect( web.url_for( controller='repository', action='preview_tools_in_changeset', + webapp=webapp, repository_id=repository_id, changeset_revision=repository.tip ) ) # The changeset_revision_select_field in the RepositoryListGrid performs a refresh_on_change @@ -371,16 +365,16 @@ webapp=webapp, repository_id=trans.security.encode_id( repository.id ), changeset_revision=v ) ) - url_args = dict( action='browse_downloadable_repositories', + url_args = dict( action='browse_valid_repositories', operation='preview_tools_in_changeset', webapp=webapp, repository_id=repository_id ) - self.downloadable_repository_list_grid.operations = [ grids.GridOperation( "Preview and install", - url_args=url_args, - allow_multiple=False, - async_compatible=False ) ] + self.valid_repository_list_grid.operations = [ grids.GridOperation( "Preview and install", + url_args=url_args, + allow_multiple=False, + async_compatible=False ) ] # Render the list view - return self.downloadable_repository_list_grid( trans, **kwd ) + return self.valid_repository_list_grid( trans, **kwd ) @web.expose def find_tools( self, trans, **kwd ): params = util.Params( kwd ) @@ -391,38 +385,35 @@ if galaxy_url: trans.set_cookie( galaxy_url, name='toolshedgalaxyurl' ) if 'operation' in kwd: - operation = kwd[ 'operation' ].lower() - is_admin = trans.user_is_admin() - if operation == "view_or_manage_repository": - # The received id is a RepositoryMetadata id, so we have to get the repository id. - repository_metadata = get_repository_metadata_by_id( trans, kwd[ 'id' ] ) - repository_id = trans.security.encode_id( repository_metadata.repository.id ) - repository = get_repository( trans, repository_id ) - kwd[ 'id' ] = repository_id - kwd[ 'changeset_revision' ] = repository_metadata.changeset_revision - if webapp == 'community' and ( is_admin or repository.user == trans.user ): - a = 'manage_repository' - else: - a = 'view_repository' - return trans.response.send_redirect( web.url_for( controller='repository', - action=a, - **kwd ) ) - if operation == "install": - repo_info_dict = {} - galaxy_url = trans.get_cookie( name='toolshedgalaxyurl' ) - # TODO: support https in the following url. - url = 'http://%s/admin/install_tool_shed_repository?tool_shed_url=%s&webapp=%s' % ( galaxy_url, trans.request.host, webapp ) - repository_metadata_ids = util.listify( kwd[ 'id' ] ) - for repository_metadata_id in repository_metadata_ids: - repository_metadata = get_repository_metadata_by_id( trans, repository_metadata_id ) - repository = get_repository( trans, trans.security.encode_id( repository_metadata.repository_id ) ) - repository_id = trans.security.encode_id( repository.id ) - changeset_revision = repository_metadata.changeset_revision - repository_clone_url = generate_clone_url( trans, repository_id ) - repo_info_dict[ repository.name ] = ( repository.description, repository_clone_url, changeset_revision ) - encoded_repo_info_dict = self.__encode( repo_info_dict ) - url += '&repo_info_dict=%s' % encoded_repo_info_dict - return trans.response.send_redirect( url ) + item_id = kwd.get( 'id', '' ) + if item_id: + operation = kwd[ 'operation' ].lower() + is_admin = trans.user_is_admin() + if operation == "view_or_manage_repository": + # The received id is a RepositoryMetadata id, so we have to get the repository id. + repository_metadata = get_repository_metadata_by_id( trans, item_id ) + repository_id = trans.security.encode_id( repository_metadata.repository.id ) + repository = get_repository( trans, repository_id ) + kwd[ 'id' ] = repository_id + kwd[ 'changeset_revision' ] = repository_metadata.changeset_revision + if webapp == 'community' and ( is_admin or repository.user == trans.user ): + a = 'manage_repository' + else: + a = 'view_repository' + return trans.response.send_redirect( web.url_for( controller='repository', + action=a, + **kwd ) ) + if operation == "install": + galaxy_url = trans.get_cookie( name='toolshedgalaxyurl' ) + encoded_repo_info_dict = self.__encode_repo_info_dict( trans, webapp, util.listify( item_id ) ) + # TODO: support https in the following url. + url = 'http://%s/admin/install_tool_shed_repository?tool_shed_url=%s&webapp=%s&repo_info_dict=%s' % \ + ( galaxy_url, trans.request.host, webapp, encoded_repo_info_dict ) + return trans.response.send_redirect( url ) + else: + # This can only occur when there is a multi-select grid with check boxes and an operation, + # and the user clicked the operation button without checking any of the check boxes. + return trans.show_error_message( "No items were selected." ) tool_ids = [ item.lower() for item in util.listify( kwd.get( 'tool_id', '' ) ) ] tool_names = [ item.lower() for item in util.listify( kwd.get( 'tool_name', '' ) ) ] tool_versions = [ item.lower() for item in util.listify( kwd.get( 'tool_version', '' ) ) ] @@ -436,7 +427,12 @@ kwd[ 'match_tuples' ] = match_tuples # Render the list view if webapp == 'galaxy': - # Our request originated from a Galaxy instance. + # Our initial request originated from a Galaxy instance. + global_actions = [ grids.GridAction( "Browse valid repositories", + dict( controller='repository', action='browse_valid_repositories', webapp=webapp ) ), + grids.GridAction( "Search for valid tools", + dict( controller='repository', action='find_tools', webapp=webapp ) ) ] + self.install_matched_repository_list_grid.global_actions = global_actions install_url_args = dict( controller='repository', action='find_tools', webapp=webapp ) operations = [ grids.GridOperation( "Install", url_args=install_url_args, allow_multiple=True, async_compatible=False ) ] self.install_matched_repository_list_grid.operations = operations @@ -583,8 +579,21 @@ if self.__in_tool_dict( tool_dict, exact_matches_checked, tool_name=tool_name, tool_version=tool_version ): match_tuples.append( ( repository_metadata.repository_id, repository_metadata.changeset_revision ) ) return match_tuples - def __encode( self, repo_info_dict ): - value = simplejson.dumps( repo_info_dict ) + def __encode_repo_info_dict( self, trans, webapp, repository_metadata_ids ): + repo_info_dict = {} + for repository_metadata_id in repository_metadata_ids: + repository_metadata = get_repository_metadata_by_id( trans, repository_metadata_id ) + repository = get_repository( trans, trans.security.encode_id( repository_metadata.repository_id ) ) + repository_id = trans.security.encode_id( repository.id ) + changeset_revision = repository_metadata.changeset_revision + repository_clone_url = generate_clone_url( trans, repository_id ) + repo_info_dict[ repository.name ] = ( repository.description, repository_clone_url, changeset_revision ) + return self.__encode( repo_info_dict ) + def __encode( self, val ): + if isinstance( val, dict ): + value = simplejson.dumps( val ) + else: + value = val a = hmac_new( 'ToolShedAndGalaxyMustHaveThisSameKey', value ) b = binascii.hexlify( value ) return "%s:%s" % ( a, b ) @@ -620,14 +629,18 @@ params = util.Params( kwd ) message = util.restore_text( params.get( 'message', '' ) ) status = params.get( 'status', 'done' ) + webapp = params.get( 'webapp', 'community' ) galaxy_url = trans.get_cookie( name='toolshedgalaxyurl' ) + repository_clone_url = generate_clone_url( trans, repository_id ) repository = get_repository( trans, repository_id ) changeset_revision = util.restore_text( params.get( 'changeset_revision', repository.tip ) ) + repo_info_dict = {} + repo_info_dict[ repository.name ] = ( repository.description, repository_clone_url, changeset_revision ) + encoded_repo_info_dict = self.__encode( repo_info_dict ) # Redirect back to local Galaxy to perform install. - repository_clone_url = generate_clone_url( trans, repository_id ) # TODO: support https in the following url. - url = 'http://%s/admin/install_tool_shed_repository?tool_shed_url=%s&name=%s&description=%s&repository_clone_url=%s&changeset_revision=%s' % \ - ( galaxy_url, trans.request.host, repository.name, repository.description, repository_clone_url, changeset_revision ) + url = 'http://%s/admin/install_tool_shed_repository?tool_shed_url=%s&repo_info_dict=%s' % \ + ( galaxy_url, trans.request.host, encoded_repo_info_dict ) return trans.response.send_redirect( url ) @web.expose def check_for_updates( self, trans, **kwd ): diff -r 1d0bb560bd3d584708972001afd054774e9e89c5 -r 28ab7dde097298b7565a6238f0bbcade29a73ae9 templates/grid_base.mako --- a/templates/grid_base.mako +++ b/templates/grid_base.mako @@ -777,6 +777,7 @@ show_item_checkboxes = True %><form action="${url()}" method="post" onsubmit="return false;"> + <input type="hidden" name="webapp" value="${webapp}"/><table id="grid-table" class="grid"><thead id="grid-table-header"><tr> diff -r 1d0bb560bd3d584708972001afd054774e9e89c5 -r 28ab7dde097298b7565a6238f0bbcade29a73ae9 templates/webapps/community/repository/find_tools.mako --- a/templates/webapps/community/repository/find_tools.mako +++ b/templates/webapps/community/repository/find_tools.mako @@ -10,6 +10,13 @@ %><%inherit file="${inherit(context)}"/> +%if webapp == 'galaxy': + <br/><br/> + <ul class="manage-table-actions"> + <li><a class="action-button" href="${h.url_for( controller='repository', action='browse_valid_repositories', webapp=webapp )}">Browse valid repositories</a></li> + </ul> +%endif + %if message: ${render_msg( message, status )} %endif diff -r 1d0bb560bd3d584708972001afd054774e9e89c5 -r 28ab7dde097298b7565a6238f0bbcade29a73ae9 templates/webapps/community/repository/preview_tools_in_changeset.mako --- a/templates/webapps/community/repository/preview_tools_in_changeset.mako +++ b/templates/webapps/community/repository/preview_tools_in_changeset.mako @@ -64,7 +64,12 @@ <br/><br/><ul class="manage-table-actions"> - <a class="action-button" href="${h.url_for( controller='repository', action='install_repository_revision', repository_id=trans.security.encode_id( repository.id ), webapp=webapp, changeset_revision=changeset_revision )}">Install to local Galaxy</a> + <li><a class="action-button" href="${h.url_for( controller='repository', action='install_repository_revision', repository_id=trans.security.encode_id( repository.id ), webapp=webapp, changeset_revision=changeset_revision )}">Install to local Galaxy</a></li> + <li><a class="action-button" id="repository-${repository.id}-popup" class="menubutton">Tool Shed Actions</a></li> + <div popupmenu="repository-${repository.id}-popup"> + <a class="action-button" href="${h.url_for( controller='repository', action='browse_valid_repositories', webapp=webapp )}">Browse valid repositories</a> + <a class="action-button" href="${h.url_for( controller='repository', action='find_tools', webapp=webapp )}">Search for valid tools</a> + </div></ul> %if message: diff -r 1d0bb560bd3d584708972001afd054774e9e89c5 -r 28ab7dde097298b7565a6238f0bbcade29a73ae9 templates/webapps/community/repository/tool_form.mako --- a/templates/webapps/community/repository/tool_form.mako +++ b/templates/webapps/community/repository/tool_form.mako @@ -111,7 +111,12 @@ <br/><br/><ul class="manage-table-actions"> %if webapp == 'galaxy': - <a class="action-button" href="${h.url_for( controller='repository', action='install_repository_revision', repository_id=trans.security.encode_id( repository.id ), webapp=webapp, changeset_revision=changeset_revision )}">Install to local Galaxy</a> + <li><a class="action-button" href="${h.url_for( controller='repository', action='install_repository_revision', repository_id=trans.security.encode_id( repository.id ), webapp=webapp, changeset_revision=changeset_revision )}">Install to local Galaxy</a></li> + <li><a class="action-button" id="repository-${repository.id}-popup" class="menubutton">Tool Shed Actions</a></li> + <div popupmenu="repository-${repository.id}-popup"> + <a class="action-button" href="${h.url_for( controller='repository', action='browse_valid_repositories', webapp=webapp )}">Browse valid repositories</a> + <a class="action-button" href="${h.url_for( controller='repository', action='find_tools', webapp=webapp )}">Search for valid tools</a> + </div> %else: %if is_new: <a class="action-button" href="${h.url_for( controller='upload', action='upload', repository_id=trans.security.encode_id( repository.id ), webapp=webapp )}">Upload files to repository</a> diff -r 1d0bb560bd3d584708972001afd054774e9e89c5 -r 28ab7dde097298b7565a6238f0bbcade29a73ae9 templates/webapps/community/repository/view_repository.mako --- a/templates/webapps/community/repository/view_repository.mako +++ b/templates/webapps/community/repository/view_repository.mako @@ -94,7 +94,12 @@ </div> %endif %else: - <a class="action-button" href="${h.url_for( controller='repository', action='install_repository_revision', repository_id=trans.security.encode_id( repository.id ), webapp=webapp, changeset_revision=changeset_revision )}">Install to local Galaxy</a> + <li><a class="action-button" href="${h.url_for( controller='repository', action='install_repository_revision', repository_id=trans.security.encode_id( repository.id ), webapp=webapp, changeset_revision=changeset_revision )}">Install to local Galaxy</a></li> + <li><a class="action-button" id="repository-${repository.id}-popup" class="menubutton">Tool Shed Actions</a></li> + <div popupmenu="repository-${repository.id}-popup"> + <a class="action-button" href="${h.url_for( controller='repository', action='browse_valid_repositories', webapp=webapp )}">Browse valid repositories</a> + <a class="action-button" href="${h.url_for( controller='repository', action='find_tools', webapp=webapp )}">Search for valid tools</a> + </div> %endif </ul> diff -r 1d0bb560bd3d584708972001afd054774e9e89c5 -r 28ab7dde097298b7565a6238f0bbcade29a73ae9 templates/webapps/community/repository/view_tool_metadata.mako --- a/templates/webapps/community/repository/view_tool_metadata.mako +++ b/templates/webapps/community/repository/view_tool_metadata.mako @@ -34,7 +34,12 @@ <br/><br/><ul class="manage-table-actions"> %if webapp == 'galaxy': - <a class="action-button" href="${h.url_for( controller='repository', action='install_repository_revision', repository_id=trans.security.encode_id( repository.id ), webapp=webapp, changeset_revision=changeset_revision )}">Install to local Galaxy</a> + <li><a class="action-button" href="${h.url_for( controller='repository', action='install_repository_revision', repository_id=trans.security.encode_id( repository.id ), webapp=webapp, changeset_revision=changeset_revision )}">Install to local Galaxy</a></li> + <li><a class="action-button" id="repository-${repository.id}-popup" class="menubutton">Tool Shed Actions</a></li> + <div popupmenu="repository-${repository.id}-popup"> + <a class="action-button" href="${h.url_for( controller='repository', action='browse_valid_repositories', webapp=webapp )}">Browse valid repositories</a> + <a class="action-button" href="${h.url_for( controller='repository', action='find_tools', webapp=webapp )}">Search for valid tools</a> + </div> %else: %if is_new: <a class="action-button" href="${h.url_for( controller='upload', action='upload', repository_id=trans.security.encode_id( repository.id ), webapp=webapp )}">Upload files to repository</a> diff -r 1d0bb560bd3d584708972001afd054774e9e89c5 -r 28ab7dde097298b7565a6238f0bbcade29a73ae9 templates/webapps/galaxy/admin/tool_sheds.mako --- a/templates/webapps/galaxy/admin/tool_sheds.mako +++ b/templates/webapps/galaxy/admin/tool_sheds.mako @@ -16,7 +16,7 @@ <div class="toolFormTitle">Accessible Galaxy tool sheds</div><div class="toolFormBody"><div class="form-row"> - <table cellspacing="0" cellpadding="0" border="0" width="100%" class="grid" id="library-grid"> + <table class="grid"><% shed_id = 0 %> %for name, url in trans.app.tool_shed_registry.tool_sheds.items(): <tr class="libraryTitle"> @@ -25,7 +25,7 @@ <a class="view-info" href="${h.url_for( controller='admin', action='browse_tool_shed', tool_shed_url=url )}">${name}</a></div><div popupmenu="dataset-${shed_id}-popup"> - <a class="action-button" href="${h.url_for( controller='admin', action='browse_tool_shed', tool_shed_url=url )}">Browse downloadable repositories</a> + <a class="action-button" href="${h.url_for( controller='admin', action='browse_tool_shed', tool_shed_url=url )}">Browse valid repositories</a><a class="action-button" href="${h.url_for( controller='admin', action='find_tools_in_tool_shed', tool_shed_url=url )}">Search for valid tools</a></div></td> diff -r 1d0bb560bd3d584708972001afd054774e9e89c5 -r 28ab7dde097298b7565a6238f0bbcade29a73ae9 tools/filters/sff_extract.py --- a/tools/filters/sff_extract.py +++ b/tools/filters/sff_extract.py @@ -27,7 +27,7 @@ __author__ = 'Jose Blanca and Bastien Chevreux' __copyright__ = 'Copyright 2008, Jose Blanca, COMAV, and Bastien Chevreux' __license__ = 'GPLv3 or later' -__version__ = '0.2.8' +__version__ = '0.2.10' __email__ = 'jblanca@btc.upv.es' __status__ = 'beta' @@ -298,7 +298,8 @@ #we check that we're removing the asked tag if tag is not None and tag != last_tag: - raise RuntimeError("The given xml tag wasn't the last one in the file") + etxt=join('The given xml tag (',tag,') was not the last one in the file'); + raise RuntimeError(etxt) # while we are at it: also remove all white spaces in that line :-) i -= 1 @@ -843,7 +844,7 @@ if len(boundaries) == 3: # case: mask char on both sides of sequence #print "bounds3" - data['clip_adapter_left']=1+boundaries[0][1] + data['clip_adapter_left']=boundaries[0][1] data['clip_adapter_right']=boundaries[2][0] elif len(boundaries) == 2: # case: mask char left or right of sequence @@ -851,7 +852,7 @@ if maskedseq[0] == maskchar : # case: mask char left #print "left" - data['clip_adapter_left']=1+boundaries[0][1] + data['clip_adapter_left']=boundaries[0][1] else: # case: mask char right #print "right" @@ -1192,7 +1193,11 @@ ''' left, right = return_merged_clips(data) seq = data['bases'] - new_seq = ''.join((seq[:left-1].lower(), seq[left-1:right], seq[right:].lower())) + if left >= right: + new_seq = seq.lower() + else: + new_seq = ''.join((seq[:left-1].lower(), seq[left-1:right], seq[right:].lower())) + return new_seq def clip_read(data): @@ -1209,14 +1214,14 @@ -def tests_for_ssaha(linker_fname): +def tests_for_ssaha(): '''Tests whether SSAHA2 can be successfully called.''' try: print "Testing whether SSAHA2 is installed and can be launched ... ", sys.stdout.flush() fh = open('/dev/null', 'w') - retcode = subprocess.call(["ssaha2", "-v"], stdout = fh) + retcode = subprocess.call(["ssaha2"], stdout = fh) fh.close() print "ok." except : @@ -1247,6 +1252,8 @@ '''Launches SSAHA2 on the linker and query file, string SSAHA2 output into the output filehandle''' + tests_for_ssaha() + try: print "Searching linker sequences with SSAHA2 (this may take a while) ... ", sys.stdout.flush() diff -r 1d0bb560bd3d584708972001afd054774e9e89c5 -r 28ab7dde097298b7565a6238f0bbcade29a73ae9 tools/filters/sff_extractor.xml --- a/tools/filters/sff_extractor.xml +++ b/tools/filters/sff_extractor.xml @@ -1,4 +1,4 @@ -<tool id="Sff_extractor" name="SFF converter" version="1.0.0"> +<tool id="Sff_extractor" name="SFF converter" version="1.0.1"><description></description><command interpreter="python"> #if str($fastq_output) == "fastq_false" #sff_extract.py $clip --seq_file=$out_file3 --qual_file=$out_file4 --xml_file=$out_file2 $input diff -r 1d0bb560bd3d584708972001afd054774e9e89c5 -r 28ab7dde097298b7565a6238f0bbcade29a73ae9 tools/gatk/count_covariates.xml --- a/tools/gatk/count_covariates.xml +++ b/tools/gatk/count_covariates.xml @@ -59,14 +59,16 @@ #end for ' #end for - #if str( $gatk_param_type.input_intervals ) != "None": - -d "-L" "${gatk_param_type.input_intervals}" "${gatk_param_type.input_intervals.ext}" "input_intervals" - #end if - #if str( $gatk_param_type.input_exclude_intervals ) != "None": - -d "-XL" "${gatk_param_type.input_exclude_intervals}" "${gatk_param_type.input_exclude_intervals.ext}" "input_intervals" - #end if + #for $interval_count, $input_intervals in enumerate( $gatk_param_type.input_interval_repeat ): + -d "--intervals" "${input_intervals.input_intervals}" "${input_intervals.input_intervals.ext}" "input_intervals_${interval_count}" + #end for + #for $interval_count, $input_intervals in enumerate( $gatk_param_type.input_exclude_interval_repeat ): + -d "--excludeIntervals" "${input_intervals.input_exclude_intervals}" "${input_intervals.input_exclude_intervals.ext}" "input_exlude_intervals_${interval_count}" + #end for + -p '--BTI_merge_rule "${gatk_param_type.BTI_merge_rule}"' + -p '--downsampling_type "${gatk_param_type.downsampling_type.downsampling_type_selector}"' #if str( $gatk_param_type.downsampling_type.downsampling_type_selector ) != "NONE": -p '--${gatk_param_type.downsampling_type.downsample_to_type.downsample_to_type_selector} "${gatk_param_type.downsampling_type.downsample_to_type.downsample_to_value}"' @@ -78,11 +80,18 @@ --defaultBaseQualities "${gatk_param_type.default_base_qualities}" --validation_strictness "${gatk_param_type.validation_strictness}" --interval_merging "${gatk_param_type.interval_merging}" + ${gatk_param_type.disable_experimental_low_memory_sharding} + ${gatk_param_type.non_deterministic_random_seed} ' - #if str( $gatk_param_type.read_group_black_list ) != "None": - -d "-read_group_black_list" "${gatk_param_type.read_group_black_list}" "txt" "input_read_group_black_list" - #end if + #for $rg_black_list_count, $rg_black_list in enumerate( $gatk_param_type.read_group_black_list_repeat ): + #if $rg_black_list.read_group_black_list_type.read_group_black_list_type_selector == "file": + -d "--read_group_black_list" "${rg_black_list.read_group_black_list_type.read_group_black_list}" "txt" "input_read_group_black_list_${rg_black_list_count}" + #else + -p '--read_group_black_list "${rg_black_list.read_group_black_list_type.read_group_black_list}"' + #end if + #end for #end if + #if str( $reference_source.reference_source_selector ) == "history": -d "-R" "${reference_source.ref_file}" "${reference_source.ref_file.ext}" "gatk_input" #end if @@ -202,7 +211,7 @@ </when><when value="advanced"><repeat name="sample_metadata" title="Sample Metadata"> - <param name="sample_metadata_file" type="data" format="txt" label="Sample file(s) in JSON format" /> + <param name="sample_metadata_file" type="data" format="txt" label="Sample file in JSON format" /></repeat><repeat name="read_filter" title="Read Filter"><conditional name="read_filter_type"> @@ -218,12 +227,18 @@ </when></conditional></repeat> - <param name="input_intervals" type="data" format="picard_interval_list" optional="True" label="A list of genomic intervals over which to operate" /> - <param name="input_exclude_intervals" type="data" format="picard_interval_list" optional="True" label="A list of genomic intervals to exclude from processing" /> + <repeat name="input_interval_repeat" title="Operate on Genomic intervals"> + <param name="input_intervals" type="data" format="bed,gatk_interval,picard_interval_list" label="Genomic intervals" /> + </repeat> + <repeat name="input_exclude_interval_repeat" title="Exclude Genomic intervals"> + <param name="input_exclude_intervals" type="data" format="bed,gatk_interval,picard_interval_list" label="Genomic intervals" /> + </repeat> + <param name="BTI_merge_rule" type="select" label="BTI merge rule"><option value="UNION" selected="True">UNION</option><option value="INTERSECTION">INTERSECTION</option></param> + <conditional name="downsampling_type"><param name="downsampling_type_selector" type="select" label="Type of reads downsampling to employ at a given locus" help="Downsampling Type"><option value="NONE" selected="True">NONE</option> @@ -240,7 +255,7 @@ <option value="downsample_to_coverage">Downsample by Coverage</option></param><when value="downsample_to_fraction"> - <param name="downsample_to_value" type="float" label="Fraction [0.0-1.0] of reads to downsample to" value="0.1"/> + <param name="downsample_to_value" type="float" label="Fraction [0.0-1.0] of reads to downsample to" value="1" min="0" max="1"/></when><when value="downsample_to_coverage"><param name="downsample_to_value" type="integer" label="Coverage to downsample to at any given locus" value="0"/> @@ -254,7 +269,7 @@ <option value="downsample_to_coverage">Downsample by Coverage</option></param><when value="downsample_to_fraction"> - <param name="downsample_to_value" type="float" label="Fraction [0.0-1.0] of reads to downsample to" value="0.1"/> + <param name="downsample_to_value" type="float" label="Fraction [0.0-1.0] of reads to downsample to" value="1" min="0" max="1"/></when><when value="downsample_to_coverage"><param name="downsample_to_value" type="integer" label="Coverage to downsample to at any given locus" value="0"/> @@ -267,19 +282,38 @@ <option value="CALCULATE_AS_NECESSARY">CALCULATE_AS_NECESSARY</option><option value="RECALCULATE">RECALCULATE</option></param> - <param name="baq_gap_open_penalty" type="integer" label="BAQ gap open penalty (Phred Scaled)" value="40" help="Default value is 40. 30 is perhaps better for whole genome call sets."/> + <param name="baq_gap_open_penalty" type="float" label="BAQ gap open penalty (Phred Scaled)" value="40" help="Default value is 40. 30 is perhaps better for whole genome call sets."/><param name="use_original_qualities" type="boolean" truevalue="--useOriginalQualities" falsevalue="" label="Use the original base quality scores from the OQ tag" /><param name="default_base_qualities" type="integer" label="Value to be used for all base quality scores, when some are missing" value="-1"/><param name="validation_strictness" type="select" label="How strict should we be with validation"><option value="STRICT" selected="True">STRICT</option><option value="LENIENT">LENIENT</option><option value="SILENT">SILENT</option> + <!-- <option value="DEFAULT_STRINGENCY">DEFAULT_STRINGENCY</option> listed in docs, but not valid value...--></param><param name="interval_merging" type="select" label="Interval merging rule"><option value="ALL" selected="True">ALL</option><option value="OVERLAPPING_ONLY">OVERLAPPING_ONLY</option></param> - <param name="read_group_black_list" type="data" format="txt" optional="True" label="Read group black list" /> + + <repeat name="read_group_black_list_repeat" title="Read group black list"> + <conditional name="read_group_black_list_type"> + <param name="read_group_black_list_type_selector" type="select" label="Type of reads read group black list"> + <option value="file" selected="True">Filters in file</option> + <option value="text">Specify filters as a string</option> + </param> + <when value="file"> + <param name="read_group_black_list" type="data" format="txt" label="Read group black list file" /> + </when> + <when value="text"> + <param name="read_group_black_list" type="text" value="tag:string" label="Read group black list tag:string" /> + </when> + </conditional> + </repeat> + + <param name="disable_experimental_low_memory_sharding" type="boolean" truevalue="--disable_experimental_low_memory_sharding" falsevalue="" label="Disable experimental low-memory sharding functionality." checked="False"/> + <param name="non_deterministic_random_seed" type="boolean" truevalue="--nonDeterministicRandomSeed" falsevalue="" label="Makes the GATK behave non deterministically, that is, the random numbers generated will be different in every run" checked="False" /> + </when></conditional> diff -r 1d0bb560bd3d584708972001afd054774e9e89c5 -r 28ab7dde097298b7565a6238f0bbcade29a73ae9 tools/gatk/indel_realigner.xml --- a/tools/gatk/indel_realigner.xml +++ b/tools/gatk/indel_realigner.xml @@ -165,7 +165,7 @@ </when><when value="advanced"><repeat name="sample_metadata" title="Sample Metadata"> - <param name="sample_metadata_file" type="data" format="txt" label="Sample file(s) in JSON format" /> + <param name="sample_metadata_file" type="data" format="txt" label="Sample file in JSON format" /></repeat><repeat name="read_filter" title="Read Filter"><conditional name="read_filter_type"> @@ -181,12 +181,18 @@ </when></conditional></repeat> - <param name="input_intervals" type="data" format="picard_interval_list" optional="True" label="A list of genomic intervals over which to operate" /> - <param name="input_exclude_intervals" type="data" format="picard_interval_list" optional="True" label="A list of genomic intervals to exclude from processing" /> + <repeat name="input_interval_repeat" title="Operate on Genomic intervals"> + <param name="input_intervals" type="data" format="bed,gatk_interval,picard_interval_list" label="Genomic intervals" /> + </repeat> + <repeat name="input_exclude_interval_repeat" title="Exclude Genomic intervals"> + <param name="input_exclude_intervals" type="data" format="bed,gatk_interval,picard_interval_list" label="Genomic intervals" /> + </repeat> + <param name="BTI_merge_rule" type="select" label="BTI merge rule"><option value="UNION" selected="True">UNION</option><option value="INTERSECTION">INTERSECTION</option></param> + <conditional name="downsampling_type"><param name="downsampling_type_selector" type="select" label="Type of reads downsampling to employ at a given locus" help="Downsampling Type"><option value="NONE" selected="True">NONE</option> @@ -203,7 +209,7 @@ <option value="downsample_to_coverage">Downsample by Coverage</option></param><when value="downsample_to_fraction"> - <param name="downsample_to_value" type="float" label="Fraction [0.0-1.0] of reads to downsample to" value="0.1"/> + <param name="downsample_to_value" type="float" label="Fraction [0.0-1.0] of reads to downsample to" value="1" min="0" max="1"/></when><when value="downsample_to_coverage"><param name="downsample_to_value" type="integer" label="Coverage to downsample to at any given locus" value="0"/> @@ -217,7 +223,7 @@ <option value="downsample_to_coverage">Downsample by Coverage</option></param><when value="downsample_to_fraction"> - <param name="downsample_to_value" type="float" label="Fraction [0.0-1.0] of reads to downsample to" value="0.1"/> + <param name="downsample_to_value" type="float" label="Fraction [0.0-1.0] of reads to downsample to" value="1" min="0" max="1"/></when><when value="downsample_to_coverage"><param name="downsample_to_value" type="integer" label="Coverage to downsample to at any given locus" value="0"/> @@ -230,19 +236,38 @@ <option value="CALCULATE_AS_NECESSARY">CALCULATE_AS_NECESSARY</option><option value="RECALCULATE">RECALCULATE</option></param> - <param name="baq_gap_open_penalty" type="integer" label="BAQ gap open penalty (Phred Scaled)" value="40" help="Default value is 40. 30 is perhaps better for whole genome call sets."/> + <param name="baq_gap_open_penalty" type="float" label="BAQ gap open penalty (Phred Scaled)" value="40" help="Default value is 40. 30 is perhaps better for whole genome call sets."/><param name="use_original_qualities" type="boolean" truevalue="--useOriginalQualities" falsevalue="" label="Use the original base quality scores from the OQ tag" /><param name="default_base_qualities" type="integer" label="Value to be used for all base quality scores, when some are missing" value="-1"/><param name="validation_strictness" type="select" label="How strict should we be with validation"><option value="STRICT" selected="True">STRICT</option><option value="LENIENT">LENIENT</option><option value="SILENT">SILENT</option> + <!-- <option value="DEFAULT_STRINGENCY">DEFAULT_STRINGENCY</option> listed in docs, but not valid value...--></param><param name="interval_merging" type="select" label="Interval merging rule"><option value="ALL" selected="True">ALL</option><option value="OVERLAPPING_ONLY">OVERLAPPING_ONLY</option></param> - <param name="read_group_black_list" type="data" format="txt" optional="True" label="Read group black list" /> + + <repeat name="read_group_black_list_repeat" title="Read group black list"> + <conditional name="read_group_black_list_type"> + <param name="read_group_black_list_type_selector" type="select" label="Type of reads read group black list"> + <option value="file" selected="True">Filters in file</option> + <option value="text">Specify filters as a string</option> + </param> + <when value="file"> + <param name="read_group_black_list" type="data" format="txt" label="Read group black list file" /> + </when> + <when value="text"> + <param name="read_group_black_list" type="text" value="tag:string" label="Read group black list tag:string" /> + </when> + </conditional> + </repeat> + + <param name="disable_experimental_low_memory_sharding" type="boolean" truevalue="--disable_experimental_low_memory_sharding" falsevalue="" label="Disable experimental low-memory sharding functionality." checked="False"/> + <param name="non_deterministic_random_seed" type="boolean" truevalue="--nonDeterministicRandomSeed" falsevalue="" label="Makes the GATK behave non deterministically, that is, the random numbers generated will be different in every run" checked="False" /> + </when></conditional> diff -r 1d0bb560bd3d584708972001afd054774e9e89c5 -r 28ab7dde097298b7565a6238f0bbcade29a73ae9 tools/gatk/realigner_target_creator.xml --- a/tools/gatk/realigner_target_creator.xml +++ b/tools/gatk/realigner_target_creator.xml @@ -47,12 +47,13 @@ #end for ' #end for - #if str( $gatk_param_type.input_intervals ) != "None": - -d "-L" "${gatk_param_type.input_intervals}" "${gatk_param_type.input_intervals.ext}" "input_intervals" - #end if - #if str( $gatk_param_type.input_exclude_intervals ) != "None": - -d "-XL" "${gatk_param_type.input_exclude_intervals}" "${gatk_param_type.input_exclude_intervals.ext}" "input_intervals" - #end if + #for $interval_count, $input_intervals in enumerate( $gatk_param_type.input_interval_repeat ): + -d "--intervals" "${input_intervals.input_intervals}" "${input_intervals.input_intervals.ext}" "input_intervals_${interval_count}" + #end for + + #for $interval_count, $input_intervals in enumerate( $gatk_param_type.input_exclude_interval_repeat ): + -d "--excludeIntervals" "${input_intervals.input_exclude_intervals}" "${input_intervals.input_exclude_intervals.ext}" "input_exlude_intervals_${interval_count}" + #end for -p '--BTI_merge_rule "${gatk_param_type.BTI_merge_rule}"' @@ -67,11 +68,18 @@ --defaultBaseQualities "${gatk_param_type.default_base_qualities}" --validation_strictness "${gatk_param_type.validation_strictness}" --interval_merging "${gatk_param_type.interval_merging}" + ${gatk_param_type.disable_experimental_low_memory_sharding} + ${gatk_param_type.non_deterministic_random_seed} ' - #if str( $gatk_param_type.read_group_black_list ) != "None": - -d "-read_group_black_list" "${gatk_param_type.read_group_black_list}" "txt" "input_read_group_black_list" - #end if + #for $rg_black_list_count, $rg_black_list in enumerate( $gatk_param_type.read_group_black_list_repeat ): + #if $rg_black_list.read_group_black_list_type.read_group_black_list_type_selector == "file": + -d "--read_group_black_list" "${rg_black_list.read_group_black_list_type.read_group_black_list}" "txt" "input_read_group_black_list_${rg_black_list_count}" + #else + -p '--read_group_black_list "${rg_black_list.read_group_black_list_type.read_group_black_list}"' + #end if + #end for #end if + #if $reference_source.reference_source_selector == "history": -d "-R" "${reference_source.ref_file}" "${reference_source.ref_file.ext}" "gatk_input" #end if @@ -151,7 +159,7 @@ </when><when value="advanced"><repeat name="sample_metadata" title="Sample Metadata"> - <param name="sample_metadata_file" type="data" format="txt" label="Sample file(s) in JSON format" /> + <param name="sample_metadata_file" type="data" format="txt" label="Sample file in JSON format" /></repeat><repeat name="read_filter" title="Read Filter"><conditional name="read_filter_type"> @@ -167,8 +175,12 @@ </when></conditional></repeat> - <param name="input_intervals" type="data" format="picard_interval_list" optional="True" label="A list of genomic intervals over which to operate" /> - <param name="input_exclude_intervals" type="data" format="picard_interval_list" optional="True" label="A list of genomic intervals to exclude from processing" /> + <repeat name="input_interval_repeat" title="Operate on Genomic intervals"> + <param name="input_intervals" type="data" format="bed,gatk_interval,picard_interval_list" label="Genomic intervals" /> + </repeat> + <repeat name="input_exclude_interval_repeat" title="Exclude Genomic intervals"> + <param name="input_exclude_intervals" type="data" format="bed,gatk_interval,picard_interval_list" label="Genomic intervals" /> + </repeat><param name="BTI_merge_rule" type="select" label="BTI merge rule"><option value="UNION" selected="True">UNION</option> @@ -191,7 +203,7 @@ <option value="downsample_to_coverage">Downsample by Coverage</option></param><when value="downsample_to_fraction"> - <param name="downsample_to_value" type="float" label="Fraction [0.0-1.0] of reads to downsample to" value="0.1"/> + <param name="downsample_to_value" type="float" label="Fraction [0.0-1.0] of reads to downsample to" value="1" min="0" max="1"/></when><when value="downsample_to_coverage"><param name="downsample_to_value" type="integer" label="Coverage to downsample to at any given locus" value="0"/> @@ -205,7 +217,7 @@ <option value="downsample_to_coverage">Downsample by Coverage</option></param><when value="downsample_to_fraction"> - <param name="downsample_to_value" type="float" label="Fraction [0.0-1.0] of reads to downsample to" value="0.1"/> + <param name="downsample_to_value" type="float" label="Fraction [0.0-1.0] of reads to downsample to" value="1" min="0" max="1"/></when><when value="downsample_to_coverage"><param name="downsample_to_value" type="integer" label="Coverage to downsample to at any given locus" value="0"/> @@ -218,19 +230,38 @@ <option value="CALCULATE_AS_NECESSARY">CALCULATE_AS_NECESSARY</option><option value="RECALCULATE">RECALCULATE</option></param> - <param name="baq_gap_open_penalty" type="integer" label="BAQ gap open penalty (Phred Scaled)" value="40" help="Default value is 40. 30 is perhaps better for whole genome call sets."/> + <param name="baq_gap_open_penalty" type="float" label="BAQ gap open penalty (Phred Scaled)" value="40" help="Default value is 40. 30 is perhaps better for whole genome call sets."/><param name="use_original_qualities" type="boolean" truevalue="--useOriginalQualities" falsevalue="" label="Use the original base quality scores from the OQ tag" /><param name="default_base_qualities" type="integer" label="Value to be used for all base quality scores, when some are missing" value="-1"/><param name="validation_strictness" type="select" label="How strict should we be with validation"><option value="STRICT" selected="True">STRICT</option><option value="LENIENT">LENIENT</option><option value="SILENT">SILENT</option> + <!-- <option value="DEFAULT_STRINGENCY">DEFAULT_STRINGENCY</option> listed in docs, but not valid value...--></param><param name="interval_merging" type="select" label="Interval merging rule"><option value="ALL" selected="True">ALL</option><option value="OVERLAPPING_ONLY">OVERLAPPING_ONLY</option></param> - <param name="read_group_black_list" type="data" format="txt" optional="True" label="Read group black list" /> + + <repeat name="read_group_black_list_repeat" title="Read group black list"> + <conditional name="read_group_black_list_type"> + <param name="read_group_black_list_type_selector" type="select" label="Type of reads read group black list"> + <option value="file" selected="True">Filters in file</option> + <option value="text">Specify filters as a string</option> + </param> + <when value="file"> + <param name="read_group_black_list" type="data" format="txt" label="Read group black list file" /> + </when> + <when value="text"> + <param name="read_group_black_list" type="text" value="tag:string" label="Read group black list tag:string" /> + </when> + </conditional> + </repeat> + + <param name="disable_experimental_low_memory_sharding" type="boolean" truevalue="--disable_experimental_low_memory_sharding" falsevalue="" label="Disable experimental low-memory sharding functionality." checked="False"/> + <param name="non_deterministic_random_seed" type="boolean" truevalue="--nonDeterministicRandomSeed" falsevalue="" label="Makes the GATK behave non deterministically, that is, the random numbers generated will be different in every run" checked="False" /> + </when></conditional> diff -r 1d0bb560bd3d584708972001afd054774e9e89c5 -r 28ab7dde097298b7565a6238f0bbcade29a73ae9 tools/gatk/table_recalibration.xml --- a/tools/gatk/table_recalibration.xml +++ b/tools/gatk/table_recalibration.xml @@ -35,29 +35,16 @@ #end for ' #end for - #if str( $gatk_param_type.input_intervals ) != "None": - -d "-L" "${gatk_param_type.input_intervals}" "${gatk_param_type.input_intervals.ext}" "input_intervals" - #end if - #if str( $gatk_param_type.input_exclude_intervals ) != "None": - -d "-XL" "${gatk_param_type.input_exclude_intervals}" "${gatk_param_type.input_exclude_intervals.ext}" "input_intervals" - #end if - #set $rod_binding_names = dict() - #for $rod_binding in $gatk_param_type.rod_bind: - #if str( $rod_binding.rod_bind_type.rod_bind_type_selector ) == 'custom': - #set $rod_bind_name = $rod_binding.rod_bind_type.custom_rod_name - #else - #set $rod_bind_name = $rod_binding.rod_bind_type.rod_bind_type_selector - #end if - #set $rod_binding_names[$rod_bind_name] = $rod_binding_names.get( $rod_bind_name, -1 ) + 1 - -d "-B:${rod_bind_name},%(file_type)s" "${rod_binding.rod_bind_type.input_rod}" "${rod_binding.rod_bind_type.input_rod.ext}" "input_${rod_bind_name}_${rod_binding_names[$rod_bind_name]}" - #if str( $rod_binding.rod_bind_type.rodToIntervalTrackName ): - -p '--rodToIntervalTrackName "${rod_bind_name}"' - #end if + #for $interval_count, $input_intervals in enumerate( $gatk_param_type.input_interval_repeat ): + -d "--intervals" "${input_intervals.input_intervals}" "${input_intervals.input_intervals.ext}" "input_intervals_${interval_count}" #end for + + #for $interval_count, $input_intervals in enumerate( $gatk_param_type.input_exclude_interval_repeat ): + -d "--excludeIntervals" "${input_intervals.input_exclude_intervals}" "${input_intervals.input_exclude_intervals.ext}" "input_exlude_intervals_${interval_count}" + #end for + -p '--BTI_merge_rule "${gatk_param_type.BTI_merge_rule}"' - #if str( $gatk_param_type.input_dbsnp_rod ) != "None": - -d "-D" "${gatk_param_type.input_dbsnp_rod}" "${gatk_param_type.input_dbsnp_rod.ext}" "dbsnp_rod" - #end if + -p '--downsampling_type "${gatk_param_type.downsampling_type.downsampling_type_selector}"' #if str( $gatk_param_type.downsampling_type.downsampling_type_selector ) != "NONE": -p '--${gatk_param_type.downsampling_type.downsample_to_type.downsample_to_type_selector} "${gatk_param_type.downsampling_type.downsample_to_type.downsample_to_value}"' @@ -69,11 +56,18 @@ --defaultBaseQualities "${gatk_param_type.default_base_qualities}" --validation_strictness "${gatk_param_type.validation_strictness}" --interval_merging "${gatk_param_type.interval_merging}" + ${gatk_param_type.disable_experimental_low_memory_sharding} + ${gatk_param_type.non_deterministic_random_seed} ' - #if str( $gatk_param_type.read_group_black_list ) != "None": - -d "-read_group_black_list" "${gatk_param_type.read_group_black_list}" "txt" "input_read_group_black_list" - #end if + #for $rg_black_list_count, $rg_black_list in enumerate( $gatk_param_type.read_group_black_list_repeat ): + #if $rg_black_list.read_group_black_list_type.read_group_black_list_type_selector == "file": + -d "--read_group_black_list" "${rg_black_list.read_group_black_list_type.read_group_black_list}" "txt" "input_read_group_black_list_${rg_black_list_count}" + #else + -p '--read_group_black_list "${rg_black_list.read_group_black_list_type.read_group_black_list}"' + #end if + #end for #end if + #if str( $reference_source.reference_source_selector ) == "history": -d "-R" "${reference_source.ref_file}" "${reference_source.ref_file.ext}" "gatk_input" #end if @@ -147,7 +141,7 @@ </when><when value="advanced"><repeat name="sample_metadata" title="Sample Metadata"> - <param name="sample_metadata_file" type="data" format="txt" label="Sample file(s) in JSON format" /> + <param name="sample_metadata_file" type="data" format="txt" label="Sample file in JSON format" /></repeat><repeat name="read_filter" title="Read Filter"><conditional name="read_filter_type"> @@ -163,35 +157,18 @@ </when></conditional></repeat> - <param name="input_intervals" type="data" format="picard_interval_list" optional="True" label="A list of genomic intervals over which to operate" /> - <param name="input_exclude_intervals" type="data" format="picard_interval_list" optional="True" label="A list of genomic intervals to exclude from processing" /> - <repeat name="rod_bind" title="Binding for reference-ordered data"> - <conditional name="rod_bind_type"> - <param name="rod_bind_type_selector" type="select" label="Binding Type"> - <option value="snps" selected="True">SNPs</option> - <option value="indels">INDELs</option> - <option value="custom">Custom</option> - </param> - <when value="snps"> - <param name="input_rod" type="data" format="vcf,gatk_dbsnp,bed" label="ROD file" /> - <param name="rodToIntervalTrackName" type="boolean" truevalue="--rodToIntervalTrackName" falsevalue="" label="Use ROD as interval List (-BTI, --rodToIntervalTrackName)" help="Only one ROD may have this option specified" /> - </when> - <when value="indels"> - <param name="input_rod" type="data" format="vcf,gatk_dbsnp,bed" label="ROD file" /> - <param name="rodToIntervalTrackName" type="boolean" truevalue="--rodToIntervalTrackName" falsevalue="" label="Use ROD as interval List (-BTI, --rodToIntervalTrackName)" help="Only one ROD may have this option specified" /> - </when> - <when value="custom"> - <param name="custom_rod_name" type="text" value="Unknown" label="ROD Name"/> - <param name="input_rod" type="data" format="vcf,gatk_dbsnp,bed" label="ROD file" /> - <param name="rodToIntervalTrackName" type="boolean" truevalue="--rodToIntervalTrackName" falsevalue="" label="Use ROD as interval List (-BTI, --rodToIntervalTrackName)" help="Only one ROD may have this option specified" /> - </when> - </conditional> + <repeat name="input_interval_repeat" title="Operate on Genomic intervals"> + <param name="input_intervals" type="data" format="bed,gatk_interval,picard_interval_list" label="Genomic intervals" /></repeat> + <repeat name="input_exclude_interval_repeat" title="Exclude Genomic intervals"> + <param name="input_exclude_intervals" type="data" format="bed,gatk_interval,picard_interval_list" label="Genomic intervals" /> + </repeat> + <param name="BTI_merge_rule" type="select" label="BTI merge rule"><option value="UNION" selected="True">UNION</option><option value="INTERSECTION">INTERSECTION</option></param> - <param name="input_dbsnp_rod" type="data" format="gatk_dbsnp" optional="True" label="dbSNP reference ordered data (ROD)" /> + <conditional name="downsampling_type"><param name="downsampling_type_selector" type="select" label="Type of reads downsampling to employ at a given locus" help="Downsampling Type"><option value="NONE" selected="True">NONE</option> @@ -208,7 +185,7 @@ <option value="downsample_to_coverage">Downsample by Coverage</option></param><when value="downsample_to_fraction"> - <param name="downsample_to_value" type="float" label="Fraction [0.0-1.0] of reads to downsample to" value="0.1"/> + <param name="downsample_to_value" type="float" label="Fraction [0.0-1.0] of reads to downsample to" value="1" min="0" max="1"/></when><when value="downsample_to_coverage"><param name="downsample_to_value" type="integer" label="Coverage to downsample to at any given locus" value="0"/> @@ -222,7 +199,7 @@ <option value="downsample_to_coverage">Downsample by Coverage</option></param><when value="downsample_to_fraction"> - <param name="downsample_to_value" type="float" label="Fraction [0.0-1.0] of reads to downsample to" value="0.1"/> + <param name="downsample_to_value" type="float" label="Fraction [0.0-1.0] of reads to downsample to" value="1" min="0" max="1"/></when><when value="downsample_to_coverage"><param name="downsample_to_value" type="integer" label="Coverage to downsample to at any given locus" value="0"/> @@ -235,19 +212,38 @@ <option value="CALCULATE_AS_NECESSARY">CALCULATE_AS_NECESSARY</option><option value="RECALCULATE">RECALCULATE</option></param> - <param name="baq_gap_open_penalty" type="integer" label="BAQ gap open penalty (Phred Scaled)" value="40" help="Default value is 40. 30 is perhaps better for whole genome call sets."/> + <param name="baq_gap_open_penalty" type="float" label="BAQ gap open penalty (Phred Scaled)" value="40" help="Default value is 40. 30 is perhaps better for whole genome call sets."/><param name="use_original_qualities" type="boolean" truevalue="--useOriginalQualities" falsevalue="" label="Use the original base quality scores from the OQ tag" /><param name="default_base_qualities" type="integer" label="Value to be used for all base quality scores, when some are missing" value="-1"/><param name="validation_strictness" type="select" label="How strict should we be with validation"><option value="STRICT" selected="True">STRICT</option><option value="LENIENT">LENIENT</option><option value="SILENT">SILENT</option> + <!-- <option value="DEFAULT_STRINGENCY">DEFAULT_STRINGENCY</option> listed in docs, but not valid value...--></param><param name="interval_merging" type="select" label="Interval merging rule"><option value="ALL" selected="True">ALL</option><option value="OVERLAPPING_ONLY">OVERLAPPING_ONLY</option></param> - <param name="read_group_black_list" type="data" format="txt" optional="True" label="Read group black list" /> + + <repeat name="read_group_black_list_repeat" title="Read group black list"> + <conditional name="read_group_black_list_type"> + <param name="read_group_black_list_type_selector" type="select" label="Type of reads read group black list"> + <option value="file" selected="True">Filters in file</option> + <option value="text">Specify filters as a string</option> + </param> + <when value="file"> + <param name="read_group_black_list" type="data" format="txt" label="Read group black list file" /> + </when> + <when value="text"> + <param name="read_group_black_list" type="text" value="tag:string" label="Read group black list tag:string" /> + </when> + </conditional> + </repeat> + + <param name="disable_experimental_low_memory_sharding" type="boolean" truevalue="--disable_experimental_low_memory_sharding" falsevalue="" label="Disable experimental low-memory sharding functionality." checked="False"/> + <param name="non_deterministic_random_seed" type="boolean" truevalue="--nonDeterministicRandomSeed" falsevalue="" label="Makes the GATK behave non deterministically, that is, the random numbers generated will be different in every run" checked="False" /> + </when></conditional> diff -r 1d0bb560bd3d584708972001afd054774e9e89c5 -r 28ab7dde097298b7565a6238f0bbcade29a73ae9 tools/gatk/unified_genotyper.xml --- a/tools/gatk/unified_genotyper.xml +++ b/tools/gatk/unified_genotyper.xml @@ -56,12 +56,13 @@ #end for ' #end for - #if str( $gatk_param_type.input_intervals ) != "None": - -d "-L" "${gatk_param_type.input_intervals}" "${gatk_param_type.input_intervals.ext}" "input_intervals" - #end if - #if str( $gatk_param_type.input_exclude_intervals ) != "None": - -d "-XL" "${gatk_param_type.input_exclude_intervals}" "${gatk_param_type.input_exclude_intervals.ext}" "input_intervals" - #end if + #for $interval_count, $input_intervals in enumerate( $gatk_param_type.input_interval_repeat ): + -d "--intervals" "${input_intervals.input_intervals}" "${input_intervals.input_intervals.ext}" "input_intervals_${interval_count}" + #end for + + #for $interval_count, $input_intervals in enumerate( $gatk_param_type.input_exclude_interval_repeat ): + -d "--excludeIntervals" "${input_intervals.input_exclude_intervals}" "${input_intervals.input_exclude_intervals.ext}" "input_exlude_intervals_${interval_count}" + #end for -p '--BTI_merge_rule "${gatk_param_type.BTI_merge_rule}"' @@ -76,11 +77,18 @@ --defaultBaseQualities "${gatk_param_type.default_base_qualities}" --validation_strictness "${gatk_param_type.validation_strictness}" --interval_merging "${gatk_param_type.interval_merging}" + ${gatk_param_type.disable_experimental_low_memory_sharding} + ${gatk_param_type.non_deterministic_random_seed} ' - #if str( $gatk_param_type.read_group_black_list ) != "None": - -d "-read_group_black_list" "${gatk_param_type.read_group_black_list}" "txt" "input_read_group_black_list" - #end if + #for $rg_black_list_count, $rg_black_list in enumerate( $gatk_param_type.read_group_black_list_repeat ): + #if $rg_black_list.read_group_black_list_type.read_group_black_list_type_selector == "file": + -d "--read_group_black_list" "${rg_black_list.read_group_black_list_type.read_group_black_list}" "txt" "input_read_group_black_list_${rg_black_list_count}" + #else + -p '--read_group_black_list "${rg_black_list.read_group_black_list_type.read_group_black_list}"' + #end if + #end for #end if + #if $reference_source.reference_source_selector == "history": -d "-R" "${reference_source.ref_file}" "${reference_source.ref_file.ext}" "gatk_input" #end if @@ -194,7 +202,7 @@ </when><when value="advanced"><repeat name="sample_metadata" title="Sample Metadata"> - <param name="sample_metadata_file" type="data" format="txt" label="Sample file(s) in JSON format" /> + <param name="sample_metadata_file" type="data" format="txt" label="Sample file in JSON format" /></repeat><repeat name="read_filter" title="Read Filter"><conditional name="read_filter_type"> @@ -210,8 +218,12 @@ </when></conditional></repeat> - <param name="input_intervals" type="data" format="picard_interval_list" optional="True" label="A list of genomic intervals over which to operate" /> - <param name="input_exclude_intervals" type="data" format="picard_interval_list" optional="True" label="A list of genomic intervals to exclude from processing" /> + <repeat name="input_interval_repeat" title="Operate on Genomic intervals"> + <param name="input_intervals" type="data" format="bed,gatk_interval,picard_interval_list" label="Genomic intervals" /> + </repeat> + <repeat name="input_exclude_interval_repeat" title="Exclude Genomic intervals"> + <param name="input_exclude_intervals" type="data" format="bed,gatk_interval,picard_interval_list" label="Genomic intervals" /> + </repeat><param name="BTI_merge_rule" type="select" label="BTI merge rule"><option value="UNION" selected="True">UNION</option> @@ -234,7 +246,7 @@ <option value="downsample_to_coverage">Downsample by Coverage</option></param><when value="downsample_to_fraction"> - <param name="downsample_to_value" type="float" label="Fraction [0.0-1.0] of reads to downsample to" value="0.1"/> + <param name="downsample_to_value" type="float" label="Fraction [0.0-1.0] of reads to downsample to" value="1" min="0" max="1"/></when><when value="downsample_to_coverage"><param name="downsample_to_value" type="integer" label="Coverage to downsample to at any given locus" value="0"/> @@ -248,7 +260,7 @@ <option value="downsample_to_coverage">Downsample by Coverage</option></param><when value="downsample_to_fraction"> - <param name="downsample_to_value" type="float" label="Fraction [0.0-1.0] of reads to downsample to" value="0.1"/> + <param name="downsample_to_value" type="float" label="Fraction [0.0-1.0] of reads to downsample to" value="1" min="0" max="1"/></when><when value="downsample_to_coverage"><param name="downsample_to_value" type="integer" label="Coverage to downsample to at any given locus" value="0"/> @@ -261,19 +273,38 @@ <option value="CALCULATE_AS_NECESSARY">CALCULATE_AS_NECESSARY</option><option value="RECALCULATE">RECALCULATE</option></param> - <param name="baq_gap_open_penalty" type="integer" label="BAQ gap open penalty (Phred Scaled)" value="40" help="Default value is 40. 30 is perhaps better for whole genome call sets."/> + <param name="baq_gap_open_penalty" type="float" label="BAQ gap open penalty (Phred Scaled)" value="40" help="Default value is 40. 30 is perhaps better for whole genome call sets."/><param name="use_original_qualities" type="boolean" truevalue="--useOriginalQualities" falsevalue="" label="Use the original base quality scores from the OQ tag" /><param name="default_base_qualities" type="integer" label="Value to be used for all base quality scores, when some are missing" value="-1"/><param name="validation_strictness" type="select" label="How strict should we be with validation"><option value="STRICT" selected="True">STRICT</option><option value="LENIENT">LENIENT</option><option value="SILENT">SILENT</option> + <!-- <option value="DEFAULT_STRINGENCY">DEFAULT_STRINGENCY</option> listed in docs, but not valid value...--></param><param name="interval_merging" type="select" label="Interval merging rule"><option value="ALL" selected="True">ALL</option><option value="OVERLAPPING_ONLY">OVERLAPPING_ONLY</option></param> - <param name="read_group_black_list" type="data" format="txt" optional="True" label="Read group black list" /> + + <repeat name="read_group_black_list_repeat" title="Read group black list"> + <conditional name="read_group_black_list_type"> + <param name="read_group_black_list_type_selector" type="select" label="Type of reads read group black list"> + <option value="file" selected="True">Filters in file</option> + <option value="text">Specify filters as a string</option> + </param> + <when value="file"> + <param name="read_group_black_list" type="data" format="txt" label="Read group black list file" /> + </when> + <when value="text"> + <param name="read_group_black_list" type="text" value="tag:string" label="Read group black list tag:string" /> + </when> + </conditional> + </repeat> + + <param name="disable_experimental_low_memory_sharding" type="boolean" truevalue="--disable_experimental_low_memory_sharding" falsevalue="" label="Disable experimental low-memory sharding functionality." checked="False"/> + <param name="non_deterministic_random_seed" type="boolean" truevalue="--nonDeterministicRandomSeed" falsevalue="" label="Makes the GATK behave non deterministically, that is, the random numbers generated will be different in every run" checked="False" /> + </when></conditional> diff -r 1d0bb560bd3d584708972001afd054774e9e89c5 -r 28ab7dde097298b7565a6238f0bbcade29a73ae9 tools/gatk/variant_annotator.xml --- a/tools/gatk/variant_annotator.xml +++ b/tools/gatk/variant_annotator.xml @@ -89,14 +89,16 @@ #end for ' #end for - #if str( $gatk_param_type.input_intervals ) != "None": - -d "-L" "${gatk_param_type.input_intervals}" "${gatk_param_type.input_intervals.ext}" "input_intervals" - #end if - #if str( $gatk_param_type.input_exclude_intervals ) != "None": - -d "-XL" "${gatk_param_type.input_exclude_intervals}" "${gatk_param_type.input_exclude_intervals.ext}" "input_intervals" - #end if + #for $interval_count, $input_intervals in enumerate( $gatk_param_type.input_interval_repeat ): + -d "--intervals" "${input_intervals.input_intervals}" "${input_intervals.input_intervals.ext}" "input_intervals_${interval_count}" + #end for + #for $interval_count, $input_intervals in enumerate( $gatk_param_type.input_exclude_interval_repeat ): + -d "--excludeIntervals" "${input_intervals.input_exclude_intervals}" "${input_intervals.input_exclude_intervals.ext}" "input_exlude_intervals_${interval_count}" + #end for + -p '--BTI_merge_rule "${gatk_param_type.BTI_merge_rule}"' + -p '--downsampling_type "${gatk_param_type.downsampling_type.downsampling_type_selector}"' #if str( $gatk_param_type.downsampling_type.downsampling_type_selector ) != "NONE": -p '--${gatk_param_type.downsampling_type.downsample_to_type.downsample_to_type_selector} "${gatk_param_type.downsampling_type.downsample_to_type.downsample_to_value}"' @@ -108,10 +110,16 @@ --defaultBaseQualities "${gatk_param_type.default_base_qualities}" --validation_strictness "${gatk_param_type.validation_strictness}" --interval_merging "${gatk_param_type.interval_merging}" + ${gatk_param_type.disable_experimental_low_memory_sharding} + ${gatk_param_type.non_deterministic_random_seed} ' - #if str( $gatk_param_type.read_group_black_list ) != "None": - -d "-read_group_black_list" "${gatk_param_type.read_group_black_list}" "txt" "input_read_group_black_list" - #end if + #for $rg_black_list_count, $rg_black_list in enumerate( $gatk_param_type.read_group_black_list_repeat ): + #if $rg_black_list.read_group_black_list_type.read_group_black_list_type_selector == "file": + -d "--read_group_black_list" "${rg_black_list.read_group_black_list_type.read_group_black_list}" "txt" "input_read_group_black_list_${rg_black_list_count}" + #else + -p '--read_group_black_list "${rg_black_list.read_group_black_list_type.read_group_black_list}"' + #end if + #end for #end if #if str( $reference_source.reference_source_selector ) == "history": -d "-R" "${reference_source.ref_file}" "${reference_source.ref_file.ext}" "gatk_input" @@ -252,28 +260,34 @@ </when><when value="advanced"><repeat name="sample_metadata" title="Sample Metadata"> - <param name="sample_metadata_file" type="data" format="txt" label="Sample file(s) in JSON format" /> + <param name="sample_metadata_file" type="data" format="txt" label="Sample file in JSON format" /></repeat><repeat name="read_filter" title="Read Filter"><conditional name="read_filter_type"> - <param name="read_filter_type_selector" type="select" label="Read Filter Type"> - <option value="MaxReadLength" selected="True">MaxReadLength</option> - <option value="ZeroMappingQualityRead">ZeroMappingQualityRead</option> - </param> - <when value="ZeroMappingQualityRead"> - <!-- no extra options --> - </when> - <when value="MaxReadLength"> - <param name="maxReadLength" type="integer" value="76" label="Max Read Length"/> - </when> + <param name="read_filter_type_selector" type="select" label="Read Filter Type"> + <option value="MaxReadLength" selected="True">MaxReadLength</option> + <option value="ZeroMappingQualityRead">ZeroMappingQualityRead</option> + </param> + <when value="ZeroMappingQualityRead"> + <!-- no extra options --> + </when> + <when value="MaxReadLength"> + <param name="maxReadLength" type="integer" value="76" label="Max Read Length"/> + </when></conditional></repeat> - <param name="input_intervals" type="data" format="picard_interval_list" optional="True" label="A list of genomic intervals over which to operate" /> - <param name="input_exclude_intervals" type="data" format="picard_interval_list" optional="True" label="A list of genomic intervals to exclude from processing" /> + <repeat name="input_interval_repeat" title="Operate on Genomic intervals"> + <param name="input_intervals" type="data" format="bed,gatk_interval,picard_interval_list" label="Genomic intervals" /> + </repeat> + <repeat name="input_exclude_interval_repeat" title="Exclude Genomic intervals"> + <param name="input_exclude_intervals" type="data" format="bed,gatk_interval,picard_interval_list" label="Genomic intervals" /> + </repeat> + <param name="BTI_merge_rule" type="select" label="BTI merge rule"><option value="UNION" selected="True">UNION</option><option value="INTERSECTION">INTERSECTION</option></param> + <conditional name="downsampling_type"><param name="downsampling_type_selector" type="select" label="Type of reads downsampling to employ at a given locus" help="Downsampling Type"><option value="NONE" selected="True">NONE</option> @@ -281,55 +295,74 @@ <option value="BY_SAMPLE">BY_SAMPLE</option></param><when value="NONE"> - <!-- no more options here --> - </when> + <!-- no more options here --> + </when><when value="ALL_READS"> - <conditional name="downsample_to_type"> - <param name="downsample_to_type_selector" type="select" label="Type of reads downsampling to employ at a given locus" help="Downsampling Type"> - <option value="downsample_to_fraction" selected="True">Downsample by Fraction</option> - <option value="downsample_to_coverage">Downsample by Coverage</option> - </param> - <when value="downsample_to_fraction"> - <param name="downsample_to_value" type="float" label="Fraction [0.0-1.0] of reads to downsample to" value="0.1"/> - </when> - <when value="downsample_to_coverage"> - <param name="downsample_to_value" type="integer" label="Coverage to downsample to at any given locus" value="0"/> - </when> - </conditional> - </when> + <conditional name="downsample_to_type"> + <param name="downsample_to_type_selector" type="select" label="Type of reads downsampling to employ at a given locus" help="Downsampling Type"> + <option value="downsample_to_fraction" selected="True">Downsample by Fraction</option> + <option value="downsample_to_coverage">Downsample by Coverage</option> + </param> + <when value="downsample_to_fraction"> + <param name="downsample_to_value" type="float" label="Fraction [0.0-1.0] of reads to downsample to" value="1" min="0" max="1"/> + </when> + <when value="downsample_to_coverage"> + <param name="downsample_to_value" type="integer" label="Coverage to downsample to at any given locus" value="0"/> + </when> + </conditional> + </when><when value="BY_SAMPLE"> - <conditional name="downsample_to_type"> - <param name="downsample_to_type_selector" type="select" label="Type of reads downsampling to employ at a given locus" help="Downsampling Type"> - <option value="downsample_to_fraction" selected="True">Downsample by Fraction</option> - <option value="downsample_to_coverage">Downsample by Coverage</option> - </param> - <when value="downsample_to_fraction"> - <param name="downsample_to_value" type="float" label="Fraction [0.0-1.0] of reads to downsample to" value="0.1"/> - </when> - <when value="downsample_to_coverage"> - <param name="downsample_to_value" type="integer" label="Coverage to downsample to at any given locus" value="0"/> - </when> - </conditional> - </when> + <conditional name="downsample_to_type"> + <param name="downsample_to_type_selector" type="select" label="Type of reads downsampling to employ at a given locus" help="Downsampling Type"> + <option value="downsample_to_fraction" selected="True">Downsample by Fraction</option> + <option value="downsample_to_coverage">Downsample by Coverage</option> + </param> + <when value="downsample_to_fraction"> + <param name="downsample_to_value" type="float" label="Fraction [0.0-1.0] of reads to downsample to" value="1" min="0" max="1"/> + </when> + <when value="downsample_to_coverage"> + <param name="downsample_to_value" type="integer" label="Coverage to downsample to at any given locus" value="0"/> + </when> + </conditional> + </when></conditional><param name="baq" type="select" label="Type of BAQ calculation to apply in the engine"><option value="OFF" selected="True">OFF</option><option value="CALCULATE_AS_NECESSARY">CALCULATE_AS_NECESSARY</option><option value="RECALCULATE">RECALCULATE</option></param> - <param name="baq_gap_open_penalty" type="integer" label="BAQ gap open penalty (Phred Scaled)" value="40" help="Default value is 40. 30 is perhaps better for whole genome call sets."/> + <param name="baq_gap_open_penalty" type="float" label="BAQ gap open penalty (Phred Scaled)" value="40" help="Default value is 40. 30 is perhaps better for whole genome call sets."/><param name="use_original_qualities" type="boolean" truevalue="--useOriginalQualities" falsevalue="" label="Use the original base quality scores from the OQ tag" /><param name="default_base_qualities" type="integer" label="Value to be used for all base quality scores, when some are missing" value="-1"/><param name="validation_strictness" type="select" label="How strict should we be with validation"><option value="STRICT" selected="True">STRICT</option><option value="LENIENT">LENIENT</option><option value="SILENT">SILENT</option> + <!-- <option value="DEFAULT_STRINGENCY">DEFAULT_STRINGENCY</option> listed in docs, but not valid value...--></param><param name="interval_merging" type="select" label="Interval merging rule"><option value="ALL" selected="True">ALL</option><option value="OVERLAPPING_ONLY">OVERLAPPING_ONLY</option></param> - <param name="read_group_black_list" type="data" format="txt" optional="True" label="Read group black list" /> + + <repeat name="read_group_black_list_repeat" title="Read group black list"> + <conditional name="read_group_black_list_type"> + <param name="read_group_black_list_type_selector" type="select" label="Type of reads read group black list"> + <option value="file" selected="True">Filters in file</option> + <option value="text">Specify filters as a string</option> + </param> + <when value="file"> + <param name="read_group_black_list" type="data" format="txt" label="Read group black list file" /> + </when> + <when value="text"> + <param name="read_group_black_list" type="text" value="tag:string" label="Read group black list tag:string" /> + </when> + </conditional> + </repeat> + + <param name="disable_experimental_low_memory_sharding" type="boolean" truevalue="--disable_experimental_low_memory_sharding" falsevalue="" label="Disable experimental low-memory sharding functionality." checked="False"/> + <param name="non_deterministic_random_seed" type="boolean" truevalue="--nonDeterministicRandomSeed" falsevalue="" label="Makes the GATK behave non deterministically, that is, the random numbers generated will be different in every run" checked="False" /> + </when></conditional> diff -r 1d0bb560bd3d584708972001afd054774e9e89c5 -r 28ab7dde097298b7565a6238f0bbcade29a73ae9 tools/gatk/variant_apply_recalibration.xml --- a/tools/gatk/variant_apply_recalibration.xml +++ b/tools/gatk/variant_apply_recalibration.xml @@ -37,14 +37,16 @@ #end for ' #end for - #if str( $gatk_param_type.input_intervals ) != "None": - -d "-L" "${gatk_param_type.input_intervals}" "${gatk_param_type.input_intervals.ext}" "input_intervals" - #end if - #if str( $gatk_param_type.input_exclude_intervals ) != "None": - -d "-XL" "${gatk_param_type.input_exclude_intervals}" "${gatk_param_type.input_exclude_intervals.ext}" "input_intervals" - #end if + #for $interval_count, $input_intervals in enumerate( $gatk_param_type.input_interval_repeat ): + -d "--intervals" "${input_intervals.input_intervals}" "${input_intervals.input_intervals.ext}" "input_intervals_${interval_count}" + #end for + #for $interval_count, $input_intervals in enumerate( $gatk_param_type.input_exclude_interval_repeat ): + -d "--excludeIntervals" "${input_intervals.input_exclude_intervals}" "${input_intervals.input_exclude_intervals.ext}" "input_exlude_intervals_${interval_count}" + #end for + -p '--BTI_merge_rule "${gatk_param_type.BTI_merge_rule}"' + -p '--downsampling_type "${gatk_param_type.downsampling_type.downsampling_type_selector}"' #if str( $gatk_param_type.downsampling_type.downsampling_type_selector ) != "NONE": -p '--${gatk_param_type.downsampling_type.downsample_to_type.downsample_to_type_selector} "${gatk_param_type.downsampling_type.downsample_to_type.downsample_to_value}"' @@ -56,11 +58,18 @@ --defaultBaseQualities "${gatk_param_type.default_base_qualities}" --validation_strictness "${gatk_param_type.validation_strictness}" --interval_merging "${gatk_param_type.interval_merging}" + ${gatk_param_type.disable_experimental_low_memory_sharding} + ${gatk_param_type.non_deterministic_random_seed} ' - #if str( $gatk_param_type.read_group_black_list ) != "None": - -d "-read_group_black_list" "${gatk_param_type.read_group_black_list}" "txt" "input_read_group_black_list" - #end if + #for $rg_black_list_count, $rg_black_list in enumerate( $gatk_param_type.read_group_black_list_repeat ): + #if $rg_black_list.read_group_black_list_type.read_group_black_list_type_selector == "file": + -d "--read_group_black_list" "${rg_black_list.read_group_black_list_type.read_group_black_list}" "txt" "input_read_group_black_list_${rg_black_list_count}" + #else + -p '--read_group_black_list "${rg_black_list.read_group_black_list_type.read_group_black_list}"' + #end if + #end for #end if + #if str( $reference_source.reference_source_selector ) == "history": -d "-R" "${reference_source.ref_file}" "${reference_source.ref_file.ext}" "gatk_input" #end if @@ -118,28 +127,34 @@ </when><when value="advanced"><repeat name="sample_metadata" title="Sample Metadata"> - <param name="sample_metadata_file" type="data" format="txt" label="Sample file(s) in JSON format" /> + <param name="sample_metadata_file" type="data" format="txt" label="Sample file in JSON format" /></repeat><repeat name="read_filter" title="Read Filter"><conditional name="read_filter_type"> - <param name="read_filter_type_selector" type="select" label="Read Filter Type"> - <option value="MaxReadLength" selected="True">MaxReadLength</option> - <option value="ZeroMappingQualityRead">ZeroMappingQualityRead</option> - </param> - <when value="ZeroMappingQualityRead"> - <!-- no extra options --> - </when> - <when value="MaxReadLength"> - <param name="maxReadLength" type="integer" value="76" label="Max Read Length"/> - </when> + <param name="read_filter_type_selector" type="select" label="Read Filter Type"> + <option value="MaxReadLength" selected="True">MaxReadLength</option> + <option value="ZeroMappingQualityRead">ZeroMappingQualityRead</option> + </param> + <when value="ZeroMappingQualityRead"> + <!-- no extra options --> + </when> + <when value="MaxReadLength"> + <param name="maxReadLength" type="integer" value="76" label="Max Read Length"/> + </when></conditional></repeat> - <param name="input_intervals" type="data" format="picard_interval_list" optional="True" label="A list of genomic intervals over which to operate" /> - <param name="input_exclude_intervals" type="data" format="picard_interval_list" optional="True" label="A list of genomic intervals to exclude from processing" /> + <repeat name="input_interval_repeat" title="Operate on Genomic intervals"> + <param name="input_intervals" type="data" format="bed,gatk_interval,picard_interval_list" label="Genomic intervals" /> + </repeat> + <repeat name="input_exclude_interval_repeat" title="Exclude Genomic intervals"> + <param name="input_exclude_intervals" type="data" format="bed,gatk_interval,picard_interval_list" label="Genomic intervals" /> + </repeat> + <param name="BTI_merge_rule" type="select" label="BTI merge rule"><option value="UNION" selected="True">UNION</option><option value="INTERSECTION">INTERSECTION</option></param> + <conditional name="downsampling_type"><param name="downsampling_type_selector" type="select" label="Type of reads downsampling to employ at a given locus" help="Downsampling Type"><option value="NONE" selected="True">NONE</option> @@ -147,55 +162,74 @@ <option value="BY_SAMPLE">BY_SAMPLE</option></param><when value="NONE"> - <!-- no more options here --> - </when> + <!-- no more options here --> + </when><when value="ALL_READS"> - <conditional name="downsample_to_type"> - <param name="downsample_to_type_selector" type="select" label="Type of reads downsampling to employ at a given locus" help="Downsampling Type"> - <option value="downsample_to_fraction" selected="True">Downsample by Fraction</option> - <option value="downsample_to_coverage">Downsample by Coverage</option> - </param> - <when value="downsample_to_fraction"> - <param name="downsample_to_value" type="float" label="Fraction [0.0-1.0] of reads to downsample to" value="0.1"/> - </when> - <when value="downsample_to_coverage"> - <param name="downsample_to_value" type="integer" label="Coverage to downsample to at any given locus" value="0"/> - </when> - </conditional> - </when> + <conditional name="downsample_to_type"> + <param name="downsample_to_type_selector" type="select" label="Type of reads downsampling to employ at a given locus" help="Downsampling Type"> + <option value="downsample_to_fraction" selected="True">Downsample by Fraction</option> + <option value="downsample_to_coverage">Downsample by Coverage</option> + </param> + <when value="downsample_to_fraction"> + <param name="downsample_to_value" type="float" label="Fraction [0.0-1.0] of reads to downsample to" value="1" min="0" max="1"/> + </when> + <when value="downsample_to_coverage"> + <param name="downsample_to_value" type="integer" label="Coverage to downsample to at any given locus" value="0"/> + </when> + </conditional> + </when><when value="BY_SAMPLE"> - <conditional name="downsample_to_type"> - <param name="downsample_to_type_selector" type="select" label="Type of reads downsampling to employ at a given locus" help="Downsampling Type"> - <option value="downsample_to_fraction" selected="True">Downsample by Fraction</option> - <option value="downsample_to_coverage">Downsample by Coverage</option> - </param> - <when value="downsample_to_fraction"> - <param name="downsample_to_value" type="float" label="Fraction [0.0-1.0] of reads to downsample to" value="0.1"/> - </when> - <when value="downsample_to_coverage"> - <param name="downsample_to_value" type="integer" label="Coverage to downsample to at any given locus" value="0"/> - </when> - </conditional> - </when> + <conditional name="downsample_to_type"> + <param name="downsample_to_type_selector" type="select" label="Type of reads downsampling to employ at a given locus" help="Downsampling Type"> + <option value="downsample_to_fraction" selected="True">Downsample by Fraction</option> + <option value="downsample_to_coverage">Downsample by Coverage</option> + </param> + <when value="downsample_to_fraction"> + <param name="downsample_to_value" type="float" label="Fraction [0.0-1.0] of reads to downsample to" value="1" min="0" max="1"/> + </when> + <when value="downsample_to_coverage"> + <param name="downsample_to_value" type="integer" label="Coverage to downsample to at any given locus" value="0"/> + </when> + </conditional> + </when></conditional><param name="baq" type="select" label="Type of BAQ calculation to apply in the engine"><option value="OFF" selected="True">OFF</option><option value="CALCULATE_AS_NECESSARY">CALCULATE_AS_NECESSARY</option><option value="RECALCULATE">RECALCULATE</option></param> - <param name="baq_gap_open_penalty" type="integer" label="BAQ gap open penalty (Phred Scaled)" value="40" help="Default value is 40. 30 is perhaps better for whole genome call sets."/> + <param name="baq_gap_open_penalty" type="float" label="BAQ gap open penalty (Phred Scaled)" value="40" help="Default value is 40. 30 is perhaps better for whole genome call sets."/><param name="use_original_qualities" type="boolean" truevalue="--useOriginalQualities" falsevalue="" label="Use the original base quality scores from the OQ tag" /><param name="default_base_qualities" type="integer" label="Value to be used for all base quality scores, when some are missing" value="-1"/><param name="validation_strictness" type="select" label="How strict should we be with validation"><option value="STRICT" selected="True">STRICT</option><option value="LENIENT">LENIENT</option><option value="SILENT">SILENT</option> + <!-- <option value="DEFAULT_STRINGENCY">DEFAULT_STRINGENCY</option> listed in docs, but not valid value...--></param><param name="interval_merging" type="select" label="Interval merging rule"><option value="ALL" selected="True">ALL</option><option value="OVERLAPPING_ONLY">OVERLAPPING_ONLY</option></param> - <param name="read_group_black_list" type="data" format="txt" optional="True" label="Read group black list" /> + + <repeat name="read_group_black_list_repeat" title="Read group black list"> + <conditional name="read_group_black_list_type"> + <param name="read_group_black_list_type_selector" type="select" label="Type of reads read group black list"> + <option value="file" selected="True">Filters in file</option> + <option value="text">Specify filters as a string</option> + </param> + <when value="file"> + <param name="read_group_black_list" type="data" format="txt" label="Read group black list file" /> + </when> + <when value="text"> + <param name="read_group_black_list" type="text" value="tag:string" label="Read group black list tag:string" /> + </when> + </conditional> + </repeat> + + <param name="disable_experimental_low_memory_sharding" type="boolean" truevalue="--disable_experimental_low_memory_sharding" falsevalue="" label="Disable experimental low-memory sharding functionality." checked="False"/> + <param name="non_deterministic_random_seed" type="boolean" truevalue="--nonDeterministicRandomSeed" falsevalue="" label="Makes the GATK behave non deterministically, that is, the random numbers generated will be different in every run" checked="False" /> + </when></conditional> diff -r 1d0bb560bd3d584708972001afd054774e9e89c5 -r 28ab7dde097298b7565a6238f0bbcade29a73ae9 tools/gatk/variant_combine.xml --- a/tools/gatk/variant_combine.xml +++ b/tools/gatk/variant_combine.xml @@ -28,7 +28,6 @@ --rod_priority_list "${ ','.join( $priority_order ) }" ' - ##start standard gatk options #if $gatk_param_type.gatk_param_type_selector == "advanced": #for $sample_metadata in $gatk_param_type.sample_metadata: @@ -44,13 +43,16 @@ #end for ' #end for - #if str( $gatk_param_type.input_intervals ) != "None": - -d "-L" "${gatk_param_type.input_intervals}" "${gatk_param_type.input_intervals.ext}" "input_intervals" - #end if - #if str( $gatk_param_type.input_exclude_intervals ) != "None": - -d "-XL" "${gatk_param_type.input_exclude_intervals}" "${gatk_param_type.input_exclude_intervals.ext}" "input_intervals" - #end if + #for $interval_count, $input_intervals in enumerate( $gatk_param_type.input_interval_repeat ): + -d "--intervals" "${input_intervals.input_intervals}" "${input_intervals.input_intervals.ext}" "input_intervals_${interval_count}" + #end for + + #for $interval_count, $input_intervals in enumerate( $gatk_param_type.input_exclude_interval_repeat ): + -d "--excludeIntervals" "${input_intervals.input_exclude_intervals}" "${input_intervals.input_exclude_intervals.ext}" "input_exlude_intervals_${interval_count}" + #end for + -p '--BTI_merge_rule "${gatk_param_type.BTI_merge_rule}"' + -p '--downsampling_type "${gatk_param_type.downsampling_type.downsampling_type_selector}"' #if str( $gatk_param_type.downsampling_type.downsampling_type_selector ) != "NONE": -p '--${gatk_param_type.downsampling_type.downsample_to_type.downsample_to_type_selector} "${gatk_param_type.downsampling_type.downsample_to_type.downsample_to_value}"' @@ -62,11 +64,18 @@ --defaultBaseQualities "${gatk_param_type.default_base_qualities}" --validation_strictness "${gatk_param_type.validation_strictness}" --interval_merging "${gatk_param_type.interval_merging}" + ${gatk_param_type.disable_experimental_low_memory_sharding} + ${gatk_param_type.non_deterministic_random_seed} ' - #if str( $gatk_param_type.read_group_black_list ) != "None": - -d "-read_group_black_list" "${gatk_param_type.read_group_black_list}" "txt" "input_read_group_black_list" - #end if + #for $rg_black_list_count, $rg_black_list in enumerate( $gatk_param_type.read_group_black_list_repeat ): + #if $rg_black_list.read_group_black_list_type.read_group_black_list_type_selector == "file": + -d "--read_group_black_list" "${rg_black_list.read_group_black_list_type.read_group_black_list}" "txt" "input_read_group_black_list_${rg_black_list_count}" + #else + -p '--read_group_black_list "${rg_black_list.read_group_black_list_type.read_group_black_list}"' + #end if + #end for #end if + #if $reference_source.reference_source_selector == "history": -d "-R" "${reference_source.ref_file}" "${reference_source.ref_file.ext}" "gatk_input" #end if @@ -138,7 +147,7 @@ </when><when value="advanced"><repeat name="sample_metadata" title="Sample Metadata"> - <param name="sample_metadata_file" type="data" format="txt" label="Sample file(s) in JSON format" /> + <param name="sample_metadata_file" type="data" format="txt" label="Sample file in JSON format" /></repeat><repeat name="read_filter" title="Read Filter"><conditional name="read_filter_type"> @@ -154,12 +163,18 @@ </when></conditional></repeat> - <param name="input_intervals" type="data" format="picard_interval_list" optional="True" label="A list of genomic intervals over which to operate" /> - <param name="input_exclude_intervals" type="data" format="picard_interval_list" optional="True" label="A list of genomic intervals to exclude from processing" /> + <repeat name="input_interval_repeat" title="Operate on Genomic intervals"> + <param name="input_intervals" type="data" format="bed,gatk_interval,picard_interval_list" label="Genomic intervals" /> + </repeat> + <repeat name="input_exclude_interval_repeat" title="Exclude Genomic intervals"> + <param name="input_exclude_intervals" type="data" format="bed,gatk_interval,picard_interval_list" label="Genomic intervals" /> + </repeat> + <param name="BTI_merge_rule" type="select" label="BTI merge rule"><option value="UNION" selected="True">UNION</option><option value="INTERSECTION">INTERSECTION</option></param> + <conditional name="downsampling_type"><param name="downsampling_type_selector" type="select" label="Type of reads downsampling to employ at a given locus" help="Downsampling Type"><option value="NONE" selected="True">NONE</option> @@ -176,7 +191,7 @@ <option value="downsample_to_coverage">Downsample by Coverage</option></param><when value="downsample_to_fraction"> - <param name="downsample_to_value" type="float" label="Fraction [0.0-1.0] of reads to downsample to" value="0.1"/> + <param name="downsample_to_value" type="float" label="Fraction [0.0-1.0] of reads to downsample to" value="1" min="0" max="1"/></when><when value="downsample_to_coverage"><param name="downsample_to_value" type="integer" label="Coverage to downsample to at any given locus" value="0"/> @@ -190,7 +205,7 @@ <option value="downsample_to_coverage">Downsample by Coverage</option></param><when value="downsample_to_fraction"> - <param name="downsample_to_value" type="float" label="Fraction [0.0-1.0] of reads to downsample to" value="0.1"/> + <param name="downsample_to_value" type="float" label="Fraction [0.0-1.0] of reads to downsample to" value="1" min="0" max="1"/></when><when value="downsample_to_coverage"><param name="downsample_to_value" type="integer" label="Coverage to downsample to at any given locus" value="0"/> @@ -203,19 +218,38 @@ <option value="CALCULATE_AS_NECESSARY">CALCULATE_AS_NECESSARY</option><option value="RECALCULATE">RECALCULATE</option></param> - <param name="baq_gap_open_penalty" type="integer" label="BAQ gap open penalty (Phred Scaled)" value="40" help="Default value is 40. 30 is perhaps better for whole genome call sets."/> + <param name="baq_gap_open_penalty" type="float" label="BAQ gap open penalty (Phred Scaled)" value="40" help="Default value is 40. 30 is perhaps better for whole genome call sets."/><param name="use_original_qualities" type="boolean" truevalue="--useOriginalQualities" falsevalue="" label="Use the original base quality scores from the OQ tag" /><param name="default_base_qualities" type="integer" label="Value to be used for all base quality scores, when some are missing" value="-1"/><param name="validation_strictness" type="select" label="How strict should we be with validation"><option value="STRICT" selected="True">STRICT</option><option value="LENIENT">LENIENT</option><option value="SILENT">SILENT</option> + <!-- <option value="DEFAULT_STRINGENCY">DEFAULT_STRINGENCY</option> listed in docs, but not valid value...--></param><param name="interval_merging" type="select" label="Interval merging rule"><option value="ALL" selected="True">ALL</option><option value="OVERLAPPING_ONLY">OVERLAPPING_ONLY</option></param> - <param name="read_group_black_list" type="data" format="txt" optional="True" label="Read group black list" /> + + <repeat name="read_group_black_list_repeat" title="Read group black list"> + <conditional name="read_group_black_list_type"> + <param name="read_group_black_list_type_selector" type="select" label="Type of reads read group black list"> + <option value="file" selected="True">Filters in file</option> + <option value="text">Specify filters as a string</option> + </param> + <when value="file"> + <param name="read_group_black_list" type="data" format="txt" label="Read group black list file" /> + </when> + <when value="text"> + <param name="read_group_black_list" type="text" value="tag:string" label="Read group black list tag:string" /> + </when> + </conditional> + </repeat> + + <param name="disable_experimental_low_memory_sharding" type="boolean" truevalue="--disable_experimental_low_memory_sharding" falsevalue="" label="Disable experimental low-memory sharding functionality." checked="False"/> + <param name="non_deterministic_random_seed" type="boolean" truevalue="--nonDeterministicRandomSeed" falsevalue="" label="Makes the GATK behave non deterministically, that is, the random numbers generated will be different in every run" checked="False" /> + </when></conditional> diff -r 1d0bb560bd3d584708972001afd054774e9e89c5 -r 28ab7dde097298b7565a6238f0bbcade29a73ae9 tools/gatk/variant_eval.xml --- a/tools/gatk/variant_eval.xml +++ b/tools/gatk/variant_eval.xml @@ -56,13 +56,16 @@ #end for ' #end for - #if str( $gatk_param_type.input_intervals ) != "None": - -d "-L" "${gatk_param_type.input_intervals}" "${gatk_param_type.input_intervals.ext}" "input_intervals" - #end if - #if str( $gatk_param_type.input_exclude_intervals ) != "None": - -d "-XL" "${gatk_param_type.input_exclude_intervals}" "${gatk_param_type.input_exclude_intervals.ext}" "input_intervals" - #end if + #for $interval_count, $input_intervals in enumerate( $gatk_param_type.input_interval_repeat ): + -d "--intervals" "${input_intervals.input_intervals}" "${input_intervals.input_intervals.ext}" "input_intervals_${interval_count}" + #end for + + #for $interval_count, $input_intervals in enumerate( $gatk_param_type.input_exclude_interval_repeat ): + -d "--excludeIntervals" "${input_intervals.input_exclude_intervals}" "${input_intervals.input_exclude_intervals.ext}" "input_exlude_intervals_${interval_count}" + #end for + -p '--BTI_merge_rule "${gatk_param_type.BTI_merge_rule}"' + -p '--downsampling_type "${gatk_param_type.downsampling_type.downsampling_type_selector}"' #if str( $gatk_param_type.downsampling_type.downsampling_type_selector ) != "NONE": -p '--${gatk_param_type.downsampling_type.downsample_to_type.downsample_to_type_selector} "${gatk_param_type.downsampling_type.downsample_to_type.downsample_to_value}"' @@ -74,11 +77,18 @@ --defaultBaseQualities "${gatk_param_type.default_base_qualities}" --validation_strictness "${gatk_param_type.validation_strictness}" --interval_merging "${gatk_param_type.interval_merging}" + ${gatk_param_type.disable_experimental_low_memory_sharding} + ${gatk_param_type.non_deterministic_random_seed} ' - #if str( $gatk_param_type.read_group_black_list ) != "None": - -d "-read_group_black_list" "${gatk_param_type.read_group_black_list}" "txt" "input_read_group_black_list" - #end if + #for $rg_black_list_count, $rg_black_list in enumerate( $gatk_param_type.read_group_black_list_repeat ): + #if $rg_black_list.read_group_black_list_type.read_group_black_list_type_selector == "file": + -d "--read_group_black_list" "${rg_black_list.read_group_black_list_type.read_group_black_list}" "txt" "input_read_group_black_list_${rg_black_list_count}" + #else + -p '--read_group_black_list "${rg_black_list.read_group_black_list_type.read_group_black_list}"' + #end if + #end for #end if + #if $reference_source.reference_source_selector == "history": -d "-R" "${reference_source.ref_file}" "${reference_source.ref_file.ext}" "gatk_input" #end if @@ -195,7 +205,7 @@ </when><when value="advanced"><repeat name="sample_metadata" title="Sample Metadata"> - <param name="sample_metadata_file" type="data" format="txt" label="Sample file(s) in JSON format" /> + <param name="sample_metadata_file" type="data" format="txt" label="Sample file in JSON format" /></repeat><repeat name="read_filter" title="Read Filter"><conditional name="read_filter_type"> @@ -211,12 +221,18 @@ </when></conditional></repeat> - <param name="input_intervals" type="data" format="picard_interval_list" optional="True" label="A list of genomic intervals over which to operate" /> - <param name="input_exclude_intervals" type="data" format="picard_interval_list" optional="True" label="A list of genomic intervals to exclude from processing" /> + <repeat name="input_interval_repeat" title="Operate on Genomic intervals"> + <param name="input_intervals" type="data" format="bed,gatk_interval,picard_interval_list" label="Genomic intervals" /> + </repeat> + <repeat name="input_exclude_interval_repeat" title="Exclude Genomic intervals"> + <param name="input_exclude_intervals" type="data" format="bed,gatk_interval,picard_interval_list" label="Genomic intervals" /> + </repeat> + <param name="BTI_merge_rule" type="select" label="BTI merge rule"><option value="UNION" selected="True">UNION</option><option value="INTERSECTION">INTERSECTION</option></param> + <conditional name="downsampling_type"><param name="downsampling_type_selector" type="select" label="Type of reads downsampling to employ at a given locus" help="Downsampling Type"><option value="NONE" selected="True">NONE</option> @@ -233,7 +249,7 @@ <option value="downsample_to_coverage">Downsample by Coverage</option></param><when value="downsample_to_fraction"> - <param name="downsample_to_value" type="float" label="Fraction [0.0-1.0] of reads to downsample to" value="0.1"/> + <param name="downsample_to_value" type="float" label="Fraction [0.0-1.0] of reads to downsample to" value="1" min="0" max="1"/></when><when value="downsample_to_coverage"><param name="downsample_to_value" type="integer" label="Coverage to downsample to at any given locus" value="0"/> @@ -247,7 +263,7 @@ <option value="downsample_to_coverage">Downsample by Coverage</option></param><when value="downsample_to_fraction"> - <param name="downsample_to_value" type="float" label="Fraction [0.0-1.0] of reads to downsample to" value="0.1"/> + <param name="downsample_to_value" type="float" label="Fraction [0.0-1.0] of reads to downsample to" value="1" min="0" max="1"/></when><when value="downsample_to_coverage"><param name="downsample_to_value" type="integer" label="Coverage to downsample to at any given locus" value="0"/> @@ -260,19 +276,38 @@ <option value="CALCULATE_AS_NECESSARY">CALCULATE_AS_NECESSARY</option><option value="RECALCULATE">RECALCULATE</option></param> - <param name="baq_gap_open_penalty" type="integer" label="BAQ gap open penalty (Phred Scaled)" value="40" help="Default value is 40. 30 is perhaps better for whole genome call sets."/> + <param name="baq_gap_open_penalty" type="float" label="BAQ gap open penalty (Phred Scaled)" value="40" help="Default value is 40. 30 is perhaps better for whole genome call sets."/><param name="use_original_qualities" type="boolean" truevalue="--useOriginalQualities" falsevalue="" label="Use the original base quality scores from the OQ tag" /><param name="default_base_qualities" type="integer" label="Value to be used for all base quality scores, when some are missing" value="-1"/><param name="validation_strictness" type="select" label="How strict should we be with validation"><option value="STRICT" selected="True">STRICT</option><option value="LENIENT">LENIENT</option><option value="SILENT">SILENT</option> + <!-- <option value="DEFAULT_STRINGENCY">DEFAULT_STRINGENCY</option> listed in docs, but not valid value...--></param><param name="interval_merging" type="select" label="Interval merging rule"><option value="ALL" selected="True">ALL</option><option value="OVERLAPPING_ONLY">OVERLAPPING_ONLY</option></param> - <param name="read_group_black_list" type="data" format="txt" optional="True" label="Read group black list" /> + + <repeat name="read_group_black_list_repeat" title="Read group black list"> + <conditional name="read_group_black_list_type"> + <param name="read_group_black_list_type_selector" type="select" label="Type of reads read group black list"> + <option value="file" selected="True">Filters in file</option> + <option value="text">Specify filters as a string</option> + </param> + <when value="file"> + <param name="read_group_black_list" type="data" format="txt" label="Read group black list file" /> + </when> + <when value="text"> + <param name="read_group_black_list" type="text" value="tag:string" label="Read group black list tag:string" /> + </when> + </conditional> + </repeat> + + <param name="disable_experimental_low_memory_sharding" type="boolean" truevalue="--disable_experimental_low_memory_sharding" falsevalue="" label="Disable experimental low-memory sharding functionality." checked="False"/> + <param name="non_deterministic_random_seed" type="boolean" truevalue="--nonDeterministicRandomSeed" falsevalue="" label="Makes the GATK behave non deterministically, that is, the random numbers generated will be different in every run" checked="False" /> + </when></conditional> diff -r 1d0bb560bd3d584708972001afd054774e9e89c5 -r 28ab7dde097298b7565a6238f0bbcade29a73ae9 tools/gatk/variant_filtration.xml --- a/tools/gatk/variant_filtration.xml +++ b/tools/gatk/variant_filtration.xml @@ -50,14 +50,16 @@ #end for ' #end for - #if str( $gatk_param_type.input_intervals ) != "None": - -d "-L" "${gatk_param_type.input_intervals}" "${gatk_param_type.input_intervals.ext}" "input_intervals" - #end if - #if str( $gatk_param_type.input_exclude_intervals ) != "None": - -d "-XL" "${gatk_param_type.input_exclude_intervals}" "${gatk_param_type.input_exclude_intervals.ext}" "input_intervals" - #end if + #for $interval_count, $input_intervals in enumerate( $gatk_param_type.input_interval_repeat ): + -d "--intervals" "${input_intervals.input_intervals}" "${input_intervals.input_intervals.ext}" "input_intervals_${interval_count}" + #end for + #for $interval_count, $input_intervals in enumerate( $gatk_param_type.input_exclude_interval_repeat ): + -d "--excludeIntervals" "${input_intervals.input_exclude_intervals}" "${input_intervals.input_exclude_intervals.ext}" "input_exlude_intervals_${interval_count}" + #end for + -p '--BTI_merge_rule "${gatk_param_type.BTI_merge_rule}"' + -p '--downsampling_type "${gatk_param_type.downsampling_type.downsampling_type_selector}"' #if str( $gatk_param_type.downsampling_type.downsampling_type_selector ) != "NONE": -p '--${gatk_param_type.downsampling_type.downsample_to_type.downsample_to_type_selector} "${gatk_param_type.downsampling_type.downsample_to_type.downsample_to_value}"' @@ -69,11 +71,18 @@ --defaultBaseQualities "${gatk_param_type.default_base_qualities}" --validation_strictness "${gatk_param_type.validation_strictness}" --interval_merging "${gatk_param_type.interval_merging}" + ${gatk_param_type.disable_experimental_low_memory_sharding} + ${gatk_param_type.non_deterministic_random_seed} ' - #if str( $gatk_param_type.read_group_black_list ) != "None": - -d "-read_group_black_list" "${gatk_param_type.read_group_black_list}" "txt" "input_read_group_black_list" - #end if + #for $rg_black_list_count, $rg_black_list in enumerate( $gatk_param_type.read_group_black_list_repeat ): + #if $rg_black_list.read_group_black_list_type.read_group_black_list_type_selector == "file": + -d "--read_group_black_list" "${rg_black_list.read_group_black_list_type.read_group_black_list}" "txt" "input_read_group_black_list_${rg_black_list_count}" + #else + -p '--read_group_black_list "${rg_black_list.read_group_black_list_type.read_group_black_list}"' + #end if + #end for #end if + #if str( $reference_source.reference_source_selector ) == "history": -d "-R" "${reference_source.ref_file}" "${reference_source.ref_file.ext}" "gatk_input" #end if @@ -152,7 +161,7 @@ </when><when value="advanced"><repeat name="sample_metadata" title="Sample Metadata"> - <param name="sample_metadata_file" type="data" format="txt" label="Sample file(s) in JSON format" /> + <param name="sample_metadata_file" type="data" format="txt" label="Sample file in JSON format" /></repeat><repeat name="read_filter" title="Read Filter"><conditional name="read_filter_type"> @@ -168,12 +177,18 @@ </when></conditional></repeat> - <param name="input_intervals" type="data" format="picard_interval_list" optional="True" label="A list of genomic intervals over which to operate" /> - <param name="input_exclude_intervals" type="data" format="picard_interval_list" optional="True" label="A list of genomic intervals to exclude from processing" /> + <repeat name="input_interval_repeat" title="Operate on Genomic intervals"> + <param name="input_intervals" type="data" format="bed,gatk_interval,picard_interval_list" label="Genomic intervals" /> + </repeat> + <repeat name="input_exclude_interval_repeat" title="Exclude Genomic intervals"> + <param name="input_exclude_intervals" type="data" format="bed,gatk_interval,picard_interval_list" label="Genomic intervals" /> + </repeat> + <param name="BTI_merge_rule" type="select" label="BTI merge rule"><option value="UNION" selected="True">UNION</option><option value="INTERSECTION">INTERSECTION</option></param> + <conditional name="downsampling_type"><param name="downsampling_type_selector" type="select" label="Type of reads downsampling to employ at a given locus" help="Downsampling Type"><option value="NONE" selected="True">NONE</option> @@ -190,7 +205,7 @@ <option value="downsample_to_coverage">Downsample by Coverage</option></param><when value="downsample_to_fraction"> - <param name="downsample_to_value" type="float" label="Fraction [0.0-1.0] of reads to downsample to" value="0.1"/> + <param name="downsample_to_value" type="float" label="Fraction [0.0-1.0] of reads to downsample to" value="1" min="0" max="1"/></when><when value="downsample_to_coverage"><param name="downsample_to_value" type="integer" label="Coverage to downsample to at any given locus" value="0"/> @@ -204,7 +219,7 @@ <option value="downsample_to_coverage">Downsample by Coverage</option></param><when value="downsample_to_fraction"> - <param name="downsample_to_value" type="float" label="Fraction [0.0-1.0] of reads to downsample to" value="0.1"/> + <param name="downsample_to_value" type="float" label="Fraction [0.0-1.0] of reads to downsample to" value="1" min="0" max="1"/></when><when value="downsample_to_coverage"><param name="downsample_to_value" type="integer" label="Coverage to downsample to at any given locus" value="0"/> @@ -217,19 +232,38 @@ <option value="CALCULATE_AS_NECESSARY">CALCULATE_AS_NECESSARY</option><option value="RECALCULATE">RECALCULATE</option></param> - <param name="baq_gap_open_penalty" type="integer" label="BAQ gap open penalty (Phred Scaled)" value="40" help="Default value is 40. 30 is perhaps better for whole genome call sets."/> + <param name="baq_gap_open_penalty" type="float" label="BAQ gap open penalty (Phred Scaled)" value="40" help="Default value is 40. 30 is perhaps better for whole genome call sets."/><param name="use_original_qualities" type="boolean" truevalue="--useOriginalQualities" falsevalue="" label="Use the original base quality scores from the OQ tag" /><param name="default_base_qualities" type="integer" label="Value to be used for all base quality scores, when some are missing" value="-1"/><param name="validation_strictness" type="select" label="How strict should we be with validation"><option value="STRICT" selected="True">STRICT</option><option value="LENIENT">LENIENT</option><option value="SILENT">SILENT</option> + <!-- <option value="DEFAULT_STRINGENCY">DEFAULT_STRINGENCY</option> listed in docs, but not valid value...--></param><param name="interval_merging" type="select" label="Interval merging rule"><option value="ALL" selected="True">ALL</option><option value="OVERLAPPING_ONLY">OVERLAPPING_ONLY</option></param> - <param name="read_group_black_list" type="data" format="txt" optional="True" label="Read group black list" /> + + <repeat name="read_group_black_list_repeat" title="Read group black list"> + <conditional name="read_group_black_list_type"> + <param name="read_group_black_list_type_selector" type="select" label="Type of reads read group black list"> + <option value="file" selected="True">Filters in file</option> + <option value="text">Specify filters as a string</option> + </param> + <when value="file"> + <param name="read_group_black_list" type="data" format="txt" label="Read group black list file" /> + </when> + <when value="text"> + <param name="read_group_black_list" type="text" value="tag:string" label="Read group black list tag:string" /> + </when> + </conditional> + </repeat> + + <param name="disable_experimental_low_memory_sharding" type="boolean" truevalue="--disable_experimental_low_memory_sharding" falsevalue="" label="Disable experimental low-memory sharding functionality." checked="False"/> + <param name="non_deterministic_random_seed" type="boolean" truevalue="--nonDeterministicRandomSeed" falsevalue="" label="Makes the GATK behave non deterministically, that is, the random numbers generated will be different in every run" checked="False" /> + </when></conditional> diff -r 1d0bb560bd3d584708972001afd054774e9e89c5 -r 28ab7dde097298b7565a6238f0bbcade29a73ae9 tools/gatk/variant_recalibrator.xml --- a/tools/gatk/variant_recalibrator.xml +++ b/tools/gatk/variant_recalibrator.xml @@ -58,14 +58,16 @@ #end for ' #end for - #if str( $gatk_param_type.input_intervals ) != "None": - -d "-L" "${gatk_param_type.input_intervals}" "${gatk_param_type.input_intervals.ext}" "input_intervals" - #end if - #if str( $gatk_param_type.input_exclude_intervals ) != "None": - -d "-XL" "${gatk_param_type.input_exclude_intervals}" "${gatk_param_type.input_exclude_intervals.ext}" "input_intervals" - #end if + #for $interval_count, $input_intervals in enumerate( $gatk_param_type.input_interval_repeat ): + -d "--intervals" "${input_intervals.input_intervals}" "${input_intervals.input_intervals.ext}" "input_intervals_${interval_count}" + #end for + #for $interval_count, $input_intervals in enumerate( $gatk_param_type.input_exclude_interval_repeat ): + -d "--excludeIntervals" "${input_intervals.input_exclude_intervals}" "${input_intervals.input_exclude_intervals.ext}" "input_exlude_intervals_${interval_count}" + #end for + -p '--BTI_merge_rule "${gatk_param_type.BTI_merge_rule}"' + -p '--downsampling_type "${gatk_param_type.downsampling_type.downsampling_type_selector}"' #if str( $gatk_param_type.downsampling_type.downsampling_type_selector ) != "NONE": -p '--${gatk_param_type.downsampling_type.downsample_to_type.downsample_to_type_selector} "${gatk_param_type.downsampling_type.downsample_to_type.downsample_to_value}"' @@ -77,11 +79,18 @@ --defaultBaseQualities "${gatk_param_type.default_base_qualities}" --validation_strictness "${gatk_param_type.validation_strictness}" --interval_merging "${gatk_param_type.interval_merging}" + ${gatk_param_type.disable_experimental_low_memory_sharding} + ${gatk_param_type.non_deterministic_random_seed} ' - #if str( $gatk_param_type.read_group_black_list ) != "None": - -d "-read_group_black_list" "${gatk_param_type.read_group_black_list}" "txt" "input_read_group_black_list" - #end if + #for $rg_black_list_count, $rg_black_list in enumerate( $gatk_param_type.read_group_black_list_repeat ): + #if $rg_black_list.read_group_black_list_type.read_group_black_list_type_selector == "file": + -d "--read_group_black_list" "${rg_black_list.read_group_black_list_type.read_group_black_list}" "txt" "input_read_group_black_list_${rg_black_list_count}" + #else + -p '--read_group_black_list "${rg_black_list.read_group_black_list_type.read_group_black_list}"' + #end if + #end for #end if + #if str( $reference_source.reference_source_selector ) == "history": -d "-R" "${reference_source.ref_file}" "${reference_source.ref_file.ext}" "gatk_input" #end if @@ -382,28 +391,34 @@ </when><when value="advanced"><repeat name="sample_metadata" title="Sample Metadata"> - <param name="sample_metadata_file" type="data" format="txt" label="Sample file(s) in JSON format" /> + <param name="sample_metadata_file" type="data" format="txt" label="Sample file in JSON format" /></repeat><repeat name="read_filter" title="Read Filter"><conditional name="read_filter_type"> - <param name="read_filter_type_selector" type="select" label="Read Filter Type"> - <option value="MaxReadLength" selected="True">MaxReadLength</option> - <option value="ZeroMappingQualityRead">ZeroMappingQualityRead</option> - </param> - <when value="ZeroMappingQualityRead"> - <!-- no extra options --> - </when> - <when value="MaxReadLength"> - <param name="maxReadLength" type="integer" value="76" label="Max Read Length"/> - </when> + <param name="read_filter_type_selector" type="select" label="Read Filter Type"> + <option value="MaxReadLength" selected="True">MaxReadLength</option> + <option value="ZeroMappingQualityRead">ZeroMappingQualityRead</option> + </param> + <when value="ZeroMappingQualityRead"> + <!-- no extra options --> + </when> + <when value="MaxReadLength"> + <param name="maxReadLength" type="integer" value="76" label="Max Read Length"/> + </when></conditional></repeat> - <param name="input_intervals" type="data" format="picard_interval_list" optional="True" label="A list of genomic intervals over which to operate" /> - <param name="input_exclude_intervals" type="data" format="picard_interval_list" optional="True" label="A list of genomic intervals to exclude from processing" /> + <repeat name="input_interval_repeat" title="Operate on Genomic intervals"> + <param name="input_intervals" type="data" format="bed,gatk_interval,picard_interval_list" label="Genomic intervals" /> + </repeat> + <repeat name="input_exclude_interval_repeat" title="Exclude Genomic intervals"> + <param name="input_exclude_intervals" type="data" format="bed,gatk_interval,picard_interval_list" label="Genomic intervals" /> + </repeat> + <param name="BTI_merge_rule" type="select" label="BTI merge rule"><option value="UNION" selected="True">UNION</option><option value="INTERSECTION">INTERSECTION</option></param> + <conditional name="downsampling_type"><param name="downsampling_type_selector" type="select" label="Type of reads downsampling to employ at a given locus" help="Downsampling Type"><option value="NONE" selected="True">NONE</option> @@ -411,55 +426,74 @@ <option value="BY_SAMPLE">BY_SAMPLE</option></param><when value="NONE"> - <!-- no more options here --> - </when> + <!-- no more options here --> + </when><when value="ALL_READS"> - <conditional name="downsample_to_type"> - <param name="downsample_to_type_selector" type="select" label="Type of reads downsampling to employ at a given locus" help="Downsampling Type"> - <option value="downsample_to_fraction" selected="True">Downsample by Fraction</option> - <option value="downsample_to_coverage">Downsample by Coverage</option> - </param> - <when value="downsample_to_fraction"> - <param name="downsample_to_value" type="float" label="Fraction [0.0-1.0] of reads to downsample to" value="0.1"/> - </when> - <when value="downsample_to_coverage"> - <param name="downsample_to_value" type="integer" label="Coverage to downsample to at any given locus" value="0"/> - </when> - </conditional> - </when> + <conditional name="downsample_to_type"> + <param name="downsample_to_type_selector" type="select" label="Type of reads downsampling to employ at a given locus" help="Downsampling Type"> + <option value="downsample_to_fraction" selected="True">Downsample by Fraction</option> + <option value="downsample_to_coverage">Downsample by Coverage</option> + </param> + <when value="downsample_to_fraction"> + <param name="downsample_to_value" type="float" label="Fraction [0.0-1.0] of reads to downsample to" value="1" min="0" max="1"/> + </when> + <when value="downsample_to_coverage"> + <param name="downsample_to_value" type="integer" label="Coverage to downsample to at any given locus" value="0"/> + </when> + </conditional> + </when><when value="BY_SAMPLE"> - <conditional name="downsample_to_type"> - <param name="downsample_to_type_selector" type="select" label="Type of reads downsampling to employ at a given locus" help="Downsampling Type"> - <option value="downsample_to_fraction" selected="True">Downsample by Fraction</option> - <option value="downsample_to_coverage">Downsample by Coverage</option> - </param> - <when value="downsample_to_fraction"> - <param name="downsample_to_value" type="float" label="Fraction [0.0-1.0] of reads to downsample to" value="0.1"/> - </when> - <when value="downsample_to_coverage"> - <param name="downsample_to_value" type="integer" label="Coverage to downsample to at any given locus" value="0"/> - </when> - </conditional> - </when> + <conditional name="downsample_to_type"> + <param name="downsample_to_type_selector" type="select" label="Type of reads downsampling to employ at a given locus" help="Downsampling Type"> + <option value="downsample_to_fraction" selected="True">Downsample by Fraction</option> + <option value="downsample_to_coverage">Downsample by Coverage</option> + </param> + <when value="downsample_to_fraction"> + <param name="downsample_to_value" type="float" label="Fraction [0.0-1.0] of reads to downsample to" value="1" min="0" max="1"/> + </when> + <when value="downsample_to_coverage"> + <param name="downsample_to_value" type="integer" label="Coverage to downsample to at any given locus" value="0"/> + </when> + </conditional> + </when></conditional><param name="baq" type="select" label="Type of BAQ calculation to apply in the engine"><option value="OFF" selected="True">OFF</option><option value="CALCULATE_AS_NECESSARY">CALCULATE_AS_NECESSARY</option><option value="RECALCULATE">RECALCULATE</option></param> - <param name="baq_gap_open_penalty" type="integer" label="BAQ gap open penalty (Phred Scaled)" value="40" help="Default value is 40. 30 is perhaps better for whole genome call sets."/> + <param name="baq_gap_open_penalty" type="float" label="BAQ gap open penalty (Phred Scaled)" value="40" help="Default value is 40. 30 is perhaps better for whole genome call sets."/><param name="use_original_qualities" type="boolean" truevalue="--useOriginalQualities" falsevalue="" label="Use the original base quality scores from the OQ tag" /><param name="default_base_qualities" type="integer" label="Value to be used for all base quality scores, when some are missing" value="-1"/><param name="validation_strictness" type="select" label="How strict should we be with validation"><option value="STRICT" selected="True">STRICT</option><option value="LENIENT">LENIENT</option><option value="SILENT">SILENT</option> + <!-- <option value="DEFAULT_STRINGENCY">DEFAULT_STRINGENCY</option> listed in docs, but not valid value...--></param><param name="interval_merging" type="select" label="Interval merging rule"><option value="ALL" selected="True">ALL</option><option value="OVERLAPPING_ONLY">OVERLAPPING_ONLY</option></param> - <param name="read_group_black_list" type="data" format="txt" optional="True" label="Read group black list" /> + + <repeat name="read_group_black_list_repeat" title="Read group black list"> + <conditional name="read_group_black_list_type"> + <param name="read_group_black_list_type_selector" type="select" label="Type of reads read group black list"> + <option value="file" selected="True">Filters in file</option> + <option value="text">Specify filters as a string</option> + </param> + <when value="file"> + <param name="read_group_black_list" type="data" format="txt" label="Read group black list file" /> + </when> + <when value="text"> + <param name="read_group_black_list" type="text" value="tag:string" label="Read group black list tag:string" /> + </when> + </conditional> + </repeat> + + <param name="disable_experimental_low_memory_sharding" type="boolean" truevalue="--disable_experimental_low_memory_sharding" falsevalue="" label="Disable experimental low-memory sharding functionality." checked="False"/> + <param name="non_deterministic_random_seed" type="boolean" truevalue="--nonDeterministicRandomSeed" falsevalue="" label="Makes the GATK behave non deterministically, that is, the random numbers generated will be different in every run" checked="False" /> + </when></conditional> diff -r 1d0bb560bd3d584708972001afd054774e9e89c5 -r 28ab7dde097298b7565a6238f0bbcade29a73ae9 tools/gatk/variants_validate.xml --- a/tools/gatk/variants_validate.xml +++ b/tools/gatk/variants_validate.xml @@ -42,13 +42,16 @@ #end for ' #end for - #if str( $gatk_param_type.input_intervals ) != "None": - -d "-L" "${gatk_param_type.input_intervals}" "${gatk_param_type.input_intervals.ext}" "input_intervals" - #end if - #if str( $gatk_param_type.input_exclude_intervals ) != "None": - -d "-XL" "${gatk_param_type.input_exclude_intervals}" "${gatk_param_type.input_exclude_intervals.ext}" "input_intervals" - #end if + #for $interval_count, $input_intervals in enumerate( $gatk_param_type.input_interval_repeat ): + -d "--intervals" "${input_intervals.input_intervals}" "${input_intervals.input_intervals.ext}" "input_intervals_${interval_count}" + #end for + + #for $interval_count, $input_intervals in enumerate( $gatk_param_type.input_exclude_interval_repeat ): + -d "--excludeIntervals" "${input_intervals.input_exclude_intervals}" "${input_intervals.input_exclude_intervals.ext}" "input_exlude_intervals_${interval_count}" + #end for + -p '--BTI_merge_rule "${gatk_param_type.BTI_merge_rule}"' + -p '--downsampling_type "${gatk_param_type.downsampling_type.downsampling_type_selector}"' #if str( $gatk_param_type.downsampling_type.downsampling_type_selector ) != "NONE": -p '--${gatk_param_type.downsampling_type.downsample_to_type.downsample_to_type_selector} "${gatk_param_type.downsampling_type.downsample_to_type.downsample_to_value}"' @@ -60,11 +63,18 @@ --defaultBaseQualities "${gatk_param_type.default_base_qualities}" --validation_strictness "${gatk_param_type.validation_strictness}" --interval_merging "${gatk_param_type.interval_merging}" + ${gatk_param_type.disable_experimental_low_memory_sharding} + ${gatk_param_type.non_deterministic_random_seed} ' - #if str( $gatk_param_type.read_group_black_list ) != "None": - -d "-read_group_black_list" "${gatk_param_type.read_group_black_list}" "txt" "input_read_group_black_list" - #end if + #for $rg_black_list_count, $rg_black_list in enumerate( $gatk_param_type.read_group_black_list_repeat ): + #if $rg_black_list.read_group_black_list_type.read_group_black_list_type_selector == "file": + -d "--read_group_black_list" "${rg_black_list.read_group_black_list_type.read_group_black_list}" "txt" "input_read_group_black_list_${rg_black_list_count}" + #else + -p '--read_group_black_list "${rg_black_list.read_group_black_list_type.read_group_black_list}"' + #end if + #end for #end if + #if $reference_source.reference_source_selector == "history": -d "-R" "${reference_source.ref_file}" "${reference_source.ref_file.ext}" "gatk_input" #end if @@ -120,7 +130,7 @@ </when><when value="advanced"><repeat name="sample_metadata" title="Sample Metadata"> - <param name="sample_metadata_file" type="data" format="txt" label="Sample file(s) in JSON format" /> + <param name="sample_metadata_file" type="data" format="txt" label="Sample file in JSON format" /></repeat><repeat name="read_filter" title="Read Filter"><conditional name="read_filter_type"> @@ -136,12 +146,18 @@ </when></conditional></repeat> - <param name="input_intervals" type="data" format="picard_interval_list" optional="True" label="A list of genomic intervals over which to operate" /> - <param name="input_exclude_intervals" type="data" format="picard_interval_list" optional="True" label="A list of genomic intervals to exclude from processing" /> + <repeat name="input_interval_repeat" title="Operate on Genomic intervals"> + <param name="input_intervals" type="data" format="bed,gatk_interval,picard_interval_list" label="Genomic intervals" /> + </repeat> + <repeat name="input_exclude_interval_repeat" title="Exclude Genomic intervals"> + <param name="input_exclude_intervals" type="data" format="bed,gatk_interval,picard_interval_list" label="Genomic intervals" /> + </repeat> + <param name="BTI_merge_rule" type="select" label="BTI merge rule"><option value="UNION" selected="True">UNION</option><option value="INTERSECTION">INTERSECTION</option></param> + <conditional name="downsampling_type"><param name="downsampling_type_selector" type="select" label="Type of reads downsampling to employ at a given locus" help="Downsampling Type"><option value="NONE" selected="True">NONE</option> @@ -158,7 +174,7 @@ <option value="downsample_to_coverage">Downsample by Coverage</option></param><when value="downsample_to_fraction"> - <param name="downsample_to_value" type="float" label="Fraction [0.0-1.0] of reads to downsample to" value="0.1"/> + <param name="downsample_to_value" type="float" label="Fraction [0.0-1.0] of reads to downsample to" value="1" min="0" max="1"/></when><when value="downsample_to_coverage"><param name="downsample_to_value" type="integer" label="Coverage to downsample to at any given locus" value="0"/> @@ -172,7 +188,7 @@ <option value="downsample_to_coverage">Downsample by Coverage</option></param><when value="downsample_to_fraction"> - <param name="downsample_to_value" type="float" label="Fraction [0.0-1.0] of reads to downsample to" value="0.1"/> + <param name="downsample_to_value" type="float" label="Fraction [0.0-1.0] of reads to downsample to" value="1" min="0" max="1"/></when><when value="downsample_to_coverage"><param name="downsample_to_value" type="integer" label="Coverage to downsample to at any given locus" value="0"/> @@ -185,19 +201,38 @@ <option value="CALCULATE_AS_NECESSARY">CALCULATE_AS_NECESSARY</option><option value="RECALCULATE">RECALCULATE</option></param> - <param name="baq_gap_open_penalty" type="integer" label="BAQ gap open penalty (Phred Scaled)" value="40" help="Default value is 40. 30 is perhaps better for whole genome call sets."/> + <param name="baq_gap_open_penalty" type="float" label="BAQ gap open penalty (Phred Scaled)" value="40" help="Default value is 40. 30 is perhaps better for whole genome call sets."/><param name="use_original_qualities" type="boolean" truevalue="--useOriginalQualities" falsevalue="" label="Use the original base quality scores from the OQ tag" /><param name="default_base_qualities" type="integer" label="Value to be used for all base quality scores, when some are missing" value="-1"/><param name="validation_strictness" type="select" label="How strict should we be with validation"><option value="STRICT" selected="True">STRICT</option><option value="LENIENT">LENIENT</option><option value="SILENT">SILENT</option> + <!-- <option value="DEFAULT_STRINGENCY">DEFAULT_STRINGENCY</option> listed in docs, but not valid value...--></param><param name="interval_merging" type="select" label="Interval merging rule"><option value="ALL" selected="True">ALL</option><option value="OVERLAPPING_ONLY">OVERLAPPING_ONLY</option></param> - <param name="read_group_black_list" type="data" format="txt" optional="True" label="Read group black list" /> + + <repeat name="read_group_black_list_repeat" title="Read group black list"> + <conditional name="read_group_black_list_type"> + <param name="read_group_black_list_type_selector" type="select" label="Type of reads read group black list"> + <option value="file" selected="True">Filters in file</option> + <option value="text">Specify filters as a string</option> + </param> + <when value="file"> + <param name="read_group_black_list" type="data" format="txt" label="Read group black list file" /> + </when> + <when value="text"> + <param name="read_group_black_list" type="text" value="tag:string" label="Read group black list tag:string" /> + </when> + </conditional> + </repeat> + + <param name="disable_experimental_low_memory_sharding" type="boolean" truevalue="--disable_experimental_low_memory_sharding" falsevalue="" label="Disable experimental low-memory sharding functionality." checked="False"/> + <param name="non_deterministic_random_seed" type="boolean" truevalue="--nonDeterministicRandomSeed" falsevalue="" label="Makes the GATK behave non deterministically, that is, the random numbers generated will be different in every run" checked="False" /> + </when></conditional> https://bitbucket.org/galaxy/galaxy-central/changeset/603924d3abc3/ changeset: 603924d3abc3 user: ichorny date: 2011-10-21 23:18:09 summary: added altered config.py affected #: 1 file diff -r 28ab7dde097298b7565a6238f0bbcade29a73ae9 -r 603924d3abc3057def82337b53178ad48a71b1d1 lib/galaxy/config.py --- a/lib/galaxy/config.py +++ b/lib/galaxy/config.py @@ -104,6 +104,10 @@ self.pbs_dataset_server = kwargs.get('pbs_dataset_server', "" ) self.pbs_dataset_path = kwargs.get('pbs_dataset_path', "" ) self.pbs_stage_path = kwargs.get('pbs_stage_path', "" ) + self.drmaa_external_runjob_script = kwargs.get('drmaa_external_runjob_script', None ) + self.drmaa_external_killjob_script = kwargs.get('drmaa_external_killjob_script', None) + self.external_chown_script = kwargs.get('external_chown_script', None) + self.TMPDIR = kwargs.get('TMPDIR', None) self.use_heartbeat = string_as_bool( kwargs.get( 'use_heartbeat', 'False' ) ) self.use_memdump = string_as_bool( kwargs.get( 'use_memdump', 'False' ) ) self.log_actions = string_as_bool( kwargs.get( 'log_actions', 'False' ) ) @@ -215,12 +219,21 @@ os.makedirs( path ) except Exception, e: raise ConfigurationError( "Unable to create missing directory: %s\n%s" % ( path, e ) ) + if self.drmaa_external_runjob_script: + os.chmod(self.new_file_path, 0777) + os.chmod(self.job_working_directory, 0777) + os.chmod(self.cluster_files_directory, 0777) + else: + os.chmod(self.new_file_path, 0755) + os.chmod(self.job_working_directory, 0755) + os.chmod(self.cluster_files_directory, 0755) + # Check that required files exist for path in self.tool_configs: if not os.path.isfile(path): raise ConfigurationError("File not found: %s" % path ) if not os.path.isfile( self.datatypes_config ): - raise ConfigurationError("File not found: %s" % path ) + raise ConfigurationError("File not found: %s" % self.datatypes_config ) # Check for deprecated options. for key in self.config_dict.keys(): if key in self.deprecated_options: https://bitbucket.org/galaxy/galaxy-central/changeset/125d735c689e/ changeset: 125d735c689e user: natefoo date: 2011-10-25 17:14:04 summary: merge affected #: 50 files diff -r 603924d3abc3057def82337b53178ad48a71b1d1 -r 125d735c689ee60ad9bd9601c7a22738ba3523de README.txt --- a/README.txt +++ b/README.txt @@ -7,7 +7,7 @@ HOW TO START ============ -Galaxy requires Python 2.4, 2.5 or 2.6. To check your python version, run: +Galaxy requires Python 2.5, 2.6 or 2.7. To check your python version, run: % python -V Python 2.4.4 diff -r 603924d3abc3057def82337b53178ad48a71b1d1 -r 125d735c689ee60ad9bd9601c7a22738ba3523de lib/galaxy/web/controllers/tracks.py --- a/lib/galaxy/web/controllers/tracks.py +++ b/lib/galaxy/web/controllers/tracks.py @@ -646,7 +646,7 @@ # TODO: unpack and validate bookmarks: def unpack_bookmarks( bookmarks_json ): - return + return bookmarks_json # Unpack and validate view content. view_content = unpack_collection( decoded_payload[ 'view' ] ) diff -r 603924d3abc3057def82337b53178ad48a71b1d1 -r 125d735c689ee60ad9bd9601c7a22738ba3523de static/images/fugue/application-dock-270-bw.png Binary file static/images/fugue/application-dock-270-bw.png has changed diff -r 603924d3abc3057def82337b53178ad48a71b1d1 -r 125d735c689ee60ad9bd9601c7a22738ba3523de static/images/fugue/application-dock-270.png Binary file static/images/fugue/application-dock-270.png has changed diff -r 603924d3abc3057def82337b53178ad48a71b1d1 -r 125d735c689ee60ad9bd9601c7a22738ba3523de static/images/fugue/block--plus-bw.png Binary file static/images/fugue/block--plus-bw.png has changed diff -r 603924d3abc3057def82337b53178ad48a71b1d1 -r 125d735c689ee60ad9bd9601c7a22738ba3523de static/images/fugue/block--plus.png Binary file static/images/fugue/block--plus.png has changed diff -r 603924d3abc3057def82337b53178ad48a71b1d1 -r 125d735c689ee60ad9bd9601c7a22738ba3523de static/images/fugue/bookmarks-bw.png Binary file static/images/fugue/bookmarks-bw.png has changed diff -r 603924d3abc3057def82337b53178ad48a71b1d1 -r 125d735c689ee60ad9bd9601c7a22738ba3523de static/images/fugue/bookmarks.png Binary file static/images/fugue/bookmarks.png has changed diff -r 603924d3abc3057def82337b53178ad48a71b1d1 -r 125d735c689ee60ad9bd9601c7a22738ba3523de static/images/fugue/cross-circle-bw.png Binary file static/images/fugue/cross-circle-bw.png has changed diff -r 603924d3abc3057def82337b53178ad48a71b1d1 -r 125d735c689ee60ad9bd9601c7a22738ba3523de static/images/fugue/cross-circle.png Binary file static/images/fugue/cross-circle.png has changed diff -r 603924d3abc3057def82337b53178ad48a71b1d1 -r 125d735c689ee60ad9bd9601c7a22738ba3523de static/images/fugue/cross-small-bw.png Binary file static/images/fugue/cross-small-bw.png has changed diff -r 603924d3abc3057def82337b53178ad48a71b1d1 -r 125d735c689ee60ad9bd9601c7a22738ba3523de static/images/fugue/disk--arrow-bw.png Binary file static/images/fugue/disk--arrow-bw.png has changed diff -r 603924d3abc3057def82337b53178ad48a71b1d1 -r 125d735c689ee60ad9bd9601c7a22738ba3523de static/images/fugue/disk--arrow.png Binary file static/images/fugue/disk--arrow.png has changed diff -r 603924d3abc3057def82337b53178ad48a71b1d1 -r 125d735c689ee60ad9bd9601c7a22738ba3523de static/images/fugue/gear-bw.png Binary file static/images/fugue/gear-bw.png has changed diff -r 603924d3abc3057def82337b53178ad48a71b1d1 -r 125d735c689ee60ad9bd9601c7a22738ba3523de static/images/fugue/gear.png Binary file static/images/fugue/gear.png has changed diff -r 603924d3abc3057def82337b53178ad48a71b1d1 -r 125d735c689ee60ad9bd9601c7a22738ba3523de static/images/fugue/plus-button-bw.png Binary file static/images/fugue/plus-button-bw.png has changed diff -r 603924d3abc3057def82337b53178ad48a71b1d1 -r 125d735c689ee60ad9bd9601c7a22738ba3523de static/images/fugue/plus-button.png Binary file static/images/fugue/plus-button.png has changed diff -r 603924d3abc3057def82337b53178ad48a71b1d1 -r 125d735c689ee60ad9bd9601c7a22738ba3523de static/images/fugue/toolbox-bw.png Binary file static/images/fugue/toolbox-bw.png has changed diff -r 603924d3abc3057def82337b53178ad48a71b1d1 -r 125d735c689ee60ad9bd9601c7a22738ba3523de static/images/fugue/toolbox.png Binary file static/images/fugue/toolbox.png has changed diff -r 603924d3abc3057def82337b53178ad48a71b1d1 -r 125d735c689ee60ad9bd9601c7a22738ba3523de static/images/fugue/ui-slider-050-bw.png Binary file static/images/fugue/ui-slider-050-bw.png has changed diff -r 603924d3abc3057def82337b53178ad48a71b1d1 -r 125d735c689ee60ad9bd9601c7a22738ba3523de static/images/fugue/ui-slider-050.png Binary file static/images/fugue/ui-slider-050.png has changed diff -r 603924d3abc3057def82337b53178ad48a71b1d1 -r 125d735c689ee60ad9bd9601c7a22738ba3523de static/june_2007_style/blue/trackster.css --- a/static/june_2007_style/blue/trackster.css +++ b/static/june_2007_style/blue/trackster.css @@ -3,9 +3,30 @@ .content{font:10px verdana;} .nav-controls{text-align:center;padding:1px 0;} .nav-controls input{margin:0 5px;} +.menu-button{padding: 0px 4px 0px 4px;} #zoom-in,#zoom-out{display:inline-block;height:16px;width:16px;margin-bottom:-3px;cursor:pointer;} #zoom-out{background:transparent url(../images/fugue/magnifier-zoom-out.png) center center no-repeat;} #zoom-in{margin-left:10px;background:transparent url(../images/fugue/magnifier-zoom.png) center center no-repeat;} +.overview-icon{background:transparent url(../images/fugue/application-dock-270-bw.png) no-repeat;} +.overview-icon:hover{background:transparent url(../images/fugue/application-dock-270.png) no-repeat;} +.settings-icon{background:transparent url(../images/fugue/gear-bw.png) no-repeat;} +.settings-icon:hover{background:transparent url(../images/fugue/gear.png) no-repeat;} +.tools-icon{background:transparent url(../images/fugue/toolbox-bw.png) no-repeat;} +.tools-icon:hover{background:transparent url(../images/fugue/toolbox.png) no-repeat;} +.filters-icon{background:transparent url(../images/fugue/ui-slider-050-bw.png) no-repeat;} +.filters-icon:hover{background:transparent url(../images/fugue/ui-slider-050.png) no-repeat;} +.remove-icon,.overview-close{background:transparent url(../images/fugue/cross-small-bw.png) no-repeat;} +.remove-icon:hover,.overview-close:hover{background:transparent url(../images/fugue/cross-circle.png) no-repeat;} +#close-icon{background:transparent url(../images/fugue/cross-circle-bw.png) no-repeat;margin-right:0px;} +#close-icon:hover{background:transparent url(../images/fugue/cross-circle.png) no-repeat;} +#add-tracks-icon{background:transparent url(../images/fugue/plus-button-bw.png) no-repeat;} +#add-tracks-icon:hover{background:transparent url(../images/fugue/plus-button.png) no-repeat;} +#add-group-icon{background:transparent url(../images/fugue/block--plus-bw.png) no-repeat;} +#add-group-icon:hover{background:transparent url(../images/fugue/block--plus.png) no-repeat;} +#bookmarks-icon{background:transparent url(../images/fugue/bookmarks-bw.png) no-repeat;} +#bookmarks-icon:hover{background:transparent url(../images/fugue/bookmarks.png) no-repeat;} +#save-icon{background:transparent url(../images/fugue/disk--arrow-bw.png) no-repeat;} +#save-icon:hover{background:transparent url(../images/fugue/disk--arrow.png) no-repeat;} .nav-input{font-size:12px;width:30em;z-index:1000;} .location{display:inline-block;width:15em;margin:0 10px;} .draghandle{margin-top:2px;cursor:move;float:left;background:transparent url(../images/visualization/draggable_horizontal.png) center center no-repeat;width:10px;height:12px;} @@ -19,12 +40,13 @@ .viewport-canvas{width:100%;height:100px;} .yaxislabel{color:#777;z-index:100;} .line-track .track-content{border-top:1px solid #eee;border-bottom:1px solid #eee;} -.group-handle{cursor:move;float:left;background:#eee url('/static/images/tracks/block.png');width:12px;height:12px;} +.group-handle{cursor:move;float:left;background:#eee url('../images/tracks/block.png');width:12px;height:12px;} .group{min-height:20px;border-top:2px solid #888;border-bottom:2px solid #888;} .track{background:white;} .track-header{text-align:left;padding:4px 0px;color:#666;} .track-header .menubutton{margin-left:0px;} -.track-content{text-align:center;border-top:1px solid #eee;border-bottom:2px solid #eee;background:#eee url('/static/images/tracks/diag_bg.gif');min-height:16px;} +.track-content{text-align:center;border-top:1px solid #eee;border-bottom:2px solid #eee;background:#eee url('../images/tracks/diag_bg.gif');min-height:16px;} +.track-name{float:left;margin-top:2px;height:16px;} .label-track .track-content{background:white;} .track-tile{background:white;} .track-tile canvas{position:relative;z-index:100;} diff -r 603924d3abc3057def82337b53178ad48a71b1d1 -r 125d735c689ee60ad9bd9601c7a22738ba3523de static/june_2007_style/trackster.css.tmpl --- a/static/june_2007_style/trackster.css.tmpl +++ b/static/june_2007_style/trackster.css.tmpl @@ -130,7 +130,7 @@ .group-handle { cursor: move; float: left; - background: #eee url('/static/images/tracks/block.png'); + background: #eee url('../images/tracks/block.png'); width: 12px; height: 12px; } @@ -159,10 +159,16 @@ text-align: center; border-top: 1px solid #eee; border-bottom: 2px solid #eee; - background: #eee url('/static/images/tracks/diag_bg.gif'); + background: #eee url('../images/tracks/diag_bg.gif'); min-height: 16px; } +.track-name { + float: left; + margin-top: 2px; + height: 16px; +} + .label-track .track-content { background: white; } @@ -288,6 +294,70 @@ font-weight: bold; padding-top: 0.2em; } +.menu-button { + padding: 0px 4px 0px 4px; +} +.settings-icon { + background: transparent url(../images/fugue/gear-bw.png) no-repeat; +} +.settings-icon:hover { + background: transparent url(../images/fugue/gear.png) no-repeat; +} +.overview-icon { + background:transparent url(../images/fugue/application-dock-270-bw.png) no-repeat; +} +.overview-icon:hover { + background:transparent url(../images/fugue/application-dock-270.png) no-repeat; +} + +.tools-icon { + background: transparent url(../images/fugue/toolbox-bw.png) no-repeat; +} +.tools-icon:hover { + background: transparent url(../images/fugue/toolbox.png) no-repeat; +} +.filters-icon { + background: transparent url(../images/fugue/ui-slider-050-bw.png) no-repeat; +} +.filters-icon:hover { + background: transparent url(../images/fugue/ui-slider-050.png) no-repeat; +} +.remove-icon, .overview-close { + background: transparent url(../images/fugue/cross-small-bw.png) no-repeat; +} +.remove-icon:hover, .overview-close:hover { + background: transparent url(../images/fugue/cross-circle.png) no-repeat; +} +#close-icon { + background: transparent url(../images/fugue/cross-circle-bw.png) no-repeat;margin-right:0px; +} +#close-icon:hover { + background: transparent url(../images/fugue/cross-circle.png) no-repeat; +} +#add-tracks-icon { + background: transparent url(../images/fugue/plus-button-bw.png) no-repeat; +} +#add-tracks-icon:hover { + background: transparent url(../images/fugue/plus-button.png) no-repeat; +} +#add-group-icon { + background: transparent url(../images/fugue/block--plus-bw.png) no-repeat; +} +#add-group-icon:hover { + background: transparent url(../images/fugue/block--plus.png) no-repeat; +} +#bookmarks-icon { + background: transparent url(../images/fugue/bookmarks-bw.png) no-repeat; +} +#bookmarks-icon:hover { + background: transparent url(../images/fugue/bookmarks.png) no-repeat; +} +#save-icon { + background: transparent url(../images/fugue/disk--arrow-bw.png) no-repeat; +} +#save-icon:hover { + background: transparent url(../images/fugue/disk--arrow.png) no-repeat; +} .child-track-icon { background:url('../images/fugue/arrow-000-small-bw.png') no-repeat; width: 30px; @@ -317,7 +387,6 @@ .delete-icon-container { float:right; } - .icon { display:inline-block; width:16px; diff -r 603924d3abc3057def82337b53178ad48a71b1d1 -r 125d735c689ee60ad9bd9601c7a22738ba3523de static/scripts/galaxy.base.js --- a/static/scripts/galaxy.base.js +++ b/static/scripts/galaxy.base.js @@ -698,6 +698,8 @@ }); // Tooltips if ( $.fn.tipsy ) { + // FIXME: tipsy gravity cannot be updated, so need classes that specify N/S gravity and + // initialize each separately. $(".tooltip").tipsy( { gravity: 's' } ); } // Make popup menus. diff -r 603924d3abc3057def82337b53178ad48a71b1d1 -r 125d735c689ee60ad9bd9601c7a22738ba3523de static/scripts/packed/trackster.js --- a/static/scripts/packed/trackster.js +++ b/static/scripts/packed/trackster.js @@ -1,1 +1,1 @@ -var class_module=function(b,a){var c=function(){var f=arguments[0];for(var e=1;e<arguments.length;e++){var d=arguments[e];for(key in d){f[key]=d[key]}}return f};a.extend=c};var requestAnimationFrame=(function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(b,a){window.setTimeout(b,1000/60)}})();var BEFORE=1001,CONTAINS=1002,OVERLAP_START=1003,OVERLAP_END=1004,CONTAINED_BY=1005,AFTER=1006;var compute_overlap=function(e,b){var g=e[0],f=e[1],d=b[0],c=b[1],a;if(g<d){if(f<d){a=BEFORE}else{if(f<=c){a=OVERLAP_START}else{a=CONTAINS}}}else{if(g>c){a=AFTER}else{if(f<=c){a=CONTAINED_BY}else{a=OVERLAP_END}}}return a};var is_overlap=function(c,b){var a=compute_overlap(c,b);return(a!==BEFORE&&a!==AFTER)};var trackster_module=function(f,Z){var q=f("class").extend,t=f("slotting"),N=f("painters");var ag=function(ah,ai){this.document=ah;this.default_font=ai!==undefined?ai:"9px Monaco, Lucida Console, monospace";this.dummy_canvas=this.new_canvas();this.dummy_context=this.dummy_canvas.getContext("2d");this.dummy_context.font=this.default_font;this.char_width_px=this.dummy_context.measureText("A").width;this.patterns={};this.load_pattern("right_strand","/visualization/strand_right.png");this.load_pattern("left_strand","/visualization/strand_left.png");this.load_pattern("right_strand_inv","/visualization/strand_right_inv.png");this.load_pattern("left_strand_inv","/visualization/strand_left_inv.png")};q(ag.prototype,{load_pattern:function(ah,al){var ai=this.patterns,aj=this.dummy_context,ak=new Image();ak.src=image_path+al;ak.onload=function(){ai[ah]=aj.createPattern(ak,"repeat")}},get_pattern:function(ah){return this.patterns[ah]},new_canvas:function(){var ah=this.document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(ah)}ah.manager=this;return ah}});var o={};var m=function(ah,ai){o[ah.attr("id")]=ai};var n=function(ah,aj,al,ak){al=".group";var ai={};o[ah.attr("id")]=ak;ah.bind("drag",{handle:"."+aj,relative:true},function(au,av){var at=$(this);var ay=$(this).parent(),ap=ay.children(),ar=o[$(this).attr("id")],ao,an,aw,am,aq;an=$(this).parents(al);if(an.length!==0){aw=an.position().top;am=aw+an.outerHeight();if(av.offsetY<aw){$(this).insertBefore(an);var ax=o[an.attr("id")];ax.remove_drawable(ar);ax.container.add_drawable_before(ar,ax);return}else{if(av.offsetY>am){$(this).insertAfter(an);var ax=o[an.attr("id")];ax.remove_drawable(ar);ax.container.add_drawable(ar);return}}}an=null;for(aq=0;aq<ap.length;aq++){ao=$(ap.get(aq));aw=ao.position().top;am=aw+ao.outerHeight();if(ao.is(al)&&this!==ao.get(0)&&av.offsetY>=aw&&av.offsetY<=am){if(av.offsetY-aw<am-av.offsetY){ao.find(".content-div").prepend(this)}else{ao.find(".content-div").append(this)}if(ar.container){ar.container.remove_drawable(ar)}o[ao.attr("id")].add_drawable(ar);return}}for(aq=0;aq<ap.length;aq++){if(av.offsetY<$(ap.get(aq)).position().top){break}}if(aq===ap.length){if(this!==ap.get(aq-1)){ay.append(this);o[ay.attr("id")].move_drawable(ar,aq)}}else{if(this!==ap.get(aq)){$(this).insertBefore(ap.get(aq));o[ay.attr("id")].move_drawable(ar,(av.deltaY>0?aq-1:aq))}}}).bind("dragstart",function(){ai["border-top"]=ah.css("border-top");ai["border-bottom"]=ah.css("border-bottom");$(this).css({"border-top":"1px solid blue","border-bottom":"1px solid blue"})}).bind("dragend",function(){$(this).css(ai)})};Z.moveable=n;var af=16,I=9,F=20,U=I+2,A=100,K=12000,S=200,D=5,w=10,M=5000,x=100,p="There was an error in indexing this dataset. ",L="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",G="No data for this chrom/contig.",u="Currently indexing... please wait",y="Tool cannot be rerun: ",a="Loading data...",aa="Ready for display",d=10,v=5,C=5;function ab(ai,ah){if(!ah){ah=0}var aj=Math.pow(10,ah);return Math.round(ai*aj)/aj}var c=function(ah){this.num_elements=ah;this.clear()};q(c.prototype,{get:function(ai){var ah=this.key_ary.indexOf(ai);if(ah!==-1){if(this.obj_cache[ai].stale){this.key_ary.splice(ah,1);delete this.obj_cache[ai]}else{this.move_key_to_end(ai,ah)}}return this.obj_cache[ai]},set:function(ai,aj){if(!this.obj_cache[ai]){if(this.key_ary.length>=this.num_elements){var ah=this.key_ary.shift();delete this.obj_cache[ah]}this.key_ary.push(ai)}this.obj_cache[ai]=aj;return aj},move_key_to_end:function(ai,ah){this.key_ary.splice(ah,1);this.key_ary.push(ai)},clear:function(){this.obj_cache={};this.key_ary=[]},size:function(){return this.key_ary.length}});var T=function(ai,ah,aj){c.call(this,ai);this.track=ah;this.subset=(aj!==undefined?aj:true)};q(T.prototype,c.prototype,{load_data:function(aq,al,ao,ai,an){var ap=this.track.view.chrom,ak={chrom:ap,low:aq,high:al,mode:ao,resolution:ai,dataset_id:this.track.dataset_id,hda_ldda:this.track.hda_ldda};$.extend(ak,an);if(this.track.filters_manager){var ar=[];var ah=this.track.filters_manager.filters;for(var am=0;am<ah.length;am++){ar[ar.length]=ah[am].name}ak.filter_cols=JSON.stringify(ar)}var aj=this;return $.getJSON(this.track.data_url,ak,function(at){aj.set_data(aq,al,ao,at)})},get_data:function(ah,al,am,ai,ak){var aj=this.get_data_from_cache(ah,al,am);if(aj){return aj}aj=this.load_data(ah,al,am,ai,ak);this.set_data(ah,al,am,aj);return aj},DEEP_DATA_REQ:"deep",BROAD_DATA_REQ:"breadth",get_more_data:function(ap,ak,ao,aj,an,al){var aq=this.get_data_from_cache(ap,ak,ao);if(!aq){console.log("ERROR: no current data for: ",this.track,ap,ak,ao,aj,an);return}aq.stale=true;var ai=ap;if(al===this.DEEP_DATA_REQ){$.extend(an,{start_val:aq.data.length+1})}else{if(al===this.BROAD_DATA_REQ){ai=(aq.max_high?aq.max_high:aq.data[aq.data.length-1][2])+1}}var ah=this,am=this.load_data(ai,ak,ao,aj,an);new_data_available=$.Deferred();this.set_data(ap,ak,ao,new_data_available);$.when(am).then(function(ar){if(ar.data){ar.data=aq.data.concat(ar.data);if(ar.max_low){ar.max_low=aq.max_low}if(ar.message){ar.message=ar.message.replace(/[0-9]+/,ar.data.length)}}ah.set_data(ap,ak,ao,ar);new_data_available.resolve(ar)});return new_data_available},get_data_from_cache:function(ah,ai,aj){return this.get(this.gen_key(ah,ai,aj))},set_data:function(ai,aj,ak,ah){return this.set(this.gen_key(ai,aj,ak),ah)},gen_key:function(ah,aj,ak){var ai=ah+"_"+aj+"_"+ak;return ai},split_key:function(ah){return ah.split("_")}});var J=function(ai,ah,aj){T.call(this,ai,ah,aj)};q(J.prototype,T.prototype,c.prototype,{load_data:function(aj,ah,al,am,ai,ak){if(ai>1){return}return T.prototype.load_data.call(this,aj,ah,al,am,ai,ak)}});var r=function(ak,ai,ah,aj,al){this.name=ak;this.view=ai;this.container=ah;this.drag_handle_class=al;this.config=new H({track:this,params:[{key:"name",label:"Name",type:"text",default_value:ak}],saved_values:aj,onchange:function(){this.track.set_name(this.track.config.values.name)}});this.prefs=this.config.values};q(r.prototype,{init:function(){},request_draw:function(){},_draw:function(){},to_json:function(){},make_name_popup_menu:function(){},set_name:function(ah){this.old_name=this.name;this.name=ah;this.name_div.text(this.name)},revert_name:function(){this.name=this.old_name;this.name_div.text(this.name)},remove:function(){this.container.remove_drawable(this);this.container_div.fadeOut("slow",function(){$(this).remove();view.update_intro_div();view.has_changes=true})}});var z=function(al,ak,ai,ah,aj,am){r.call(this,ak,ai,ah,aj,am);this.obj_type=al;this.drawables=[]};q(z.prototype,r.prototype,{init:function(){for(var ah=0;ah<this.drawables.length;ah++){this.drawables[ah].init()}},_draw:function(){for(var ah=0;ah<this.drawables.length;ah++){this.drawables[ah]._draw()}},to_json:function(){var ai=[];for(var ah=0;ah<this.drawables.length;ah++){ai.push(this.drawables[ah].to_json())}return{name:this.name,prefs:this.prefs,obj_type:this.obj_type,drawables:ai}},add_drawable:function(ah){this.drawables.push(ah);ah.container=this},add_drawable_before:function(aj,ah){var ai=this.drawables.indexOf(ah);if(ai!=-1){this.drawables.splice(ai,0,aj);return true}return false},remove_drawable:function(ai){var ah=this.drawables.indexOf(ai);if(ah!=-1){this.drawables.splice(ah,1);ai.container=null;return true}return false},move_drawable:function(ai,aj){var ah=this.drawables.indexOf(ai);if(ah!=-1){this.drawables.splice(ah,1);this.drawables.splice(aj,0,ai);return true}return false}});var R=function(ak,ai,ah,aj){z.call(this,"DrawableGroup",ak,ai,ah,aj,"group-handle");if(!R.id_counter){R.id_counter=0}var al=R.id_counter++;this.container_div=$("<div/>").addClass("group").attr("id","group_"+al).appendTo(this.container.content_div);this.header_div=$("<div/>").addClass("track-header").appendTo(this.container_div);this.header_div.append($("<div/>").addClass(this.drag_handle_class));this.name_div=$("<div/>").addClass("group-name menubutton popup").text(this.name).appendTo(this.header_div);this.content_div=$("<div/>").addClass("content-div").attr("id","group_"+al+"_content_div").appendTo(this.container_div);m(this.container_div,this);m(this.content_div,this);n(this.container_div,this.drag_handle_class,".group",this);this.make_name_popup_menu()};q(R.prototype,r.prototype,z.prototype,{make_name_popup_menu:function(){var ai=this;var ah={};ah["Edit configuration"]=function(){var al=function(){hide_modal();$(window).unbind("keypress.check_enter_esc")},aj=function(){ai.config.update_from_form($(".dialog-box"));hide_modal();$(window).unbind("keypress.check_enter_esc")},ak=function(am){if((am.keyCode||am.which)===27){al()}else{if((am.keyCode||am.which)===13){aj()}}};$(window).bind("keypress.check_enter_esc",ak);show_modal("Configure Group",ai.config.build_form(),{Cancel:al,OK:aj})};ah.Remove=function(){ai.remove()};make_popupmenu(ai.name_div,ah)}});var ae=function(ah,ak,aj,ai){z.call(this,"View");this.container=ah;this.chrom=null;this.vis_id=aj;this.dbkey=ai;this.title=ak;this.label_tracks=[];this.tracks_to_be_redrawn=[];this.max_low=0;this.max_high=0;this.zoom_factor=3;this.min_separation=30;this.has_changes=false;this.load_chroms_deferred=null;this.init();this.canvas_manager=new ag(ah.get(0).ownerDocument);this.reset()};q(ae.prototype,z.prototype,{init:function(){var aj=this.container,ah=this;this.top_container=$("<div/>").addClass("top-container").appendTo(aj);this.browser_content_div=$("<div/>").addClass("content").css("position","relative").appendTo(aj);this.bottom_container=$("<div/>").addClass("bottom-container").appendTo(aj);this.top_labeltrack=$("<div/>").addClass("top-labeltrack").appendTo(this.top_container);this.viewport_container=$("<div/>").addClass("viewport-container").attr("id","viewport-container").appendTo(this.browser_content_div);this.content_div=this.viewport_container;m(this.viewport_container,ah);this.intro_div=$("<div/>").addClass("intro");var ak=$("<div/>").text("Add Datasets to Visualization").addClass("action-button").appendTo(this.intro_div).click(function(){add_tracks()});this.nav_labeltrack=$("<div/>").addClass("nav-labeltrack").appendTo(this.bottom_container);this.nav_container=$("<div/>").addClass("nav-container").prependTo(this.top_container);this.nav=$("<div/>").addClass("nav").appendTo(this.nav_container);this.overview=$("<div/>").addClass("overview").appendTo(this.bottom_container);this.overview_viewport=$("<div/>").addClass("overview-viewport").appendTo(this.overview);this.overview_close=$("<a href='javascript:void(0);'>Close Overview</a>").addClass("overview-close").hide().appendTo(this.overview_viewport);this.overview_highlight=$("<div/>").addClass("overview-highlight").hide().appendTo(this.overview_viewport);this.overview_box_background=$("<div/>").addClass("overview-boxback").appendTo(this.overview_viewport);this.overview_box=$("<div/>").addClass("overview-box").appendTo(this.overview_viewport);this.default_overview_height=this.overview_box.height();this.nav_controls=$("<div/>").addClass("nav-controls").appendTo(this.nav);this.chrom_select=$("<select/>").attr({name:"chrom"}).css("width","15em").addClass("no-autocomplete").append("<option value=''>Loading</option>").appendTo(this.nav_controls);var ai=function(al){if(al.type==="focusout"||(al.keyCode||al.which)===13||(al.keyCode||al.which)===27){if((al.keyCode||al.which)!==27){ah.go_to($(this).val())}$(this).hide();$(this).val("");ah.location_span.show();ah.chrom_select.show()}};this.nav_input=$("<input/>").addClass("nav-input").hide().bind("keyup focusout",ai).appendTo(this.nav_controls);this.location_span=$("<span/>").addClass("location").appendTo(this.nav_controls);this.location_span.click(function(){ah.location_span.hide();ah.chrom_select.hide();ah.nav_input.val(ah.chrom+":"+ah.low+"-"+ah.high);ah.nav_input.css("display","inline-block");ah.nav_input.select();ah.nav_input.focus()});if(this.vis_id!==undefined){this.hidden_input=$("<input/>").attr("type","hidden").val(this.vis_id).appendTo(this.nav_controls)}this.zo_link=$("<a id='zoom-out' />").click(function(){ah.zoom_out();ah.request_redraw()}).appendTo(this.nav_controls);this.zi_link=$("<a id='zoom-in' />").click(function(){ah.zoom_in();ah.request_redraw()}).appendTo(this.nav_controls);this.load_chroms_deferred=this.load_chroms({low:0});this.chrom_select.bind("change",function(){ah.change_chrom(ah.chrom_select.val())});this.browser_content_div.click(function(al){$(this).find("input").trigger("blur")});this.browser_content_div.bind("dblclick",function(al){ah.zoom_in(al.pageX,this.viewport_container)});this.overview_box.bind("dragstart",function(al,am){this.current_x=am.offsetX}).bind("drag",function(al,an){var ao=an.offsetX-this.current_x;this.current_x=an.offsetX;var am=Math.round(ao/ah.viewport_container.width()*(ah.max_high-ah.max_low));ah.move_delta(-am)});this.overview_close.click(function(){ah.reset_overview()});this.viewport_container.bind("draginit",function(al,am){if(al.clientX>ah.viewport_container.width()-16){return false}}).bind("dragstart",function(al,am){am.original_low=ah.low;am.current_height=al.clientY;am.current_x=am.offsetX}).bind("drag",function(an,ap){var al=$(this);var aq=ap.offsetX-ap.current_x;var am=al.scrollTop()-(an.clientY-ap.current_height);al.scrollTop(am);ap.current_height=an.clientY;ap.current_x=ap.offsetX;var ao=Math.round(aq/ah.viewport_container.width()*(ah.high-ah.low));ah.move_delta(ao)}).bind("mousewheel",function(an,ap,am,al){if(am){var ao=Math.round(-am/ah.viewport_container.width()*(ah.high-ah.low));ah.move_delta(ao)}});this.top_labeltrack.bind("dragstart",function(al,am){return $("<div />").css({height:ah.browser_content_div.height()+ah.top_labeltrack.height()+ah.nav_labeltrack.height()+1,top:"0px",position:"absolute","background-color":"#ccf",opacity:0.5,"z-index":1000}).appendTo($(this))}).bind("drag",function(ap,aq){$(aq.proxy).css({left:Math.min(ap.pageX,aq.startX),width:Math.abs(ap.pageX-aq.startX)});var am=Math.min(ap.pageX,aq.startX)-ah.container.offset().left,al=Math.max(ap.pageX,aq.startX)-ah.container.offset().left,ao=(ah.high-ah.low),an=ah.viewport_container.width();ah.update_location(Math.round(am/an*ao)+ah.low,Math.round(al/an*ao)+ah.low)}).bind("dragend",function(aq,ar){var am=Math.min(aq.pageX,ar.startX),al=Math.max(aq.pageX,ar.startX),ao=(ah.high-ah.low),an=ah.viewport_container.width(),ap=ah.low;ah.low=Math.round(am/an*ao)+ap;ah.high=Math.round(al/an*ao)+ap;$(ar.proxy).remove();ah.request_redraw()});this.add_label_track(new ad(this,{content_div:this.top_labeltrack}));this.add_label_track(new ad(this,{content_div:this.nav_labeltrack}));$(window).bind("resize",function(){ah.resize_window()});$(document).bind("redraw",function(){ah.redraw()});this.reset();$(window).trigger("resize");this.update_intro_div()},update_intro_div:function(){if(this.num_tracks===0){this.intro_div.appendTo(this.viewport_container)}else{this.intro_div.remove()}},update_location:function(ah,ai){this.location_span.text(commatize(ah)+" - "+commatize(ai));this.nav_input.val(this.chrom+":"+commatize(ah)+"-"+commatize(ai))},load_chroms:function(aj){aj.num=x;$.extend(aj,(this.vis_id!==undefined?{vis_id:this.vis_id}:{dbkey:this.dbkey}));var ah=this,ai=$.Deferred();$.ajax({url:chrom_url,data:aj,dataType:"json",success:function(al){if(al.chrom_info.length===0){alert("Invalid chromosome: "+aj.chrom);return}if(al.reference){ah.add_label_track(new B(ah))}ah.chrom_data=al.chrom_info;var ao='<option value="">Select Chrom/Contig</option>';for(var an=0,ak=ah.chrom_data.length;an<ak;an++){var am=ah.chrom_data[an].chrom;ao+='<option value="'+am+'">'+am+"</option>"}if(al.prev_chroms){ao+='<option value="previous">Previous '+x+"</option>"}if(al.next_chroms){ao+='<option value="next">Next '+x+"</option>"}ah.chrom_select.html(ao);ah.chrom_start_index=al.start_index;ai.resolve(al)},error:function(){alert("Could not load chroms for this dbkey:",ah.dbkey)}});return ai},change_chrom:function(am,ai,ao){if(!am||am==="None"){return}var aj=this;if(am==="previous"){aj.load_chroms({low:this.chrom_start_index-x});return}if(am==="next"){aj.load_chroms({low:this.chrom_start_index+x});return}var an=$.grep(aj.chrom_data,function(ap,aq){return ap.chrom===am})[0];if(an===undefined){aj.load_chroms({chrom:am},function(){aj.change_chrom(am,ai,ao)});return}else{if(am!==aj.chrom){aj.chrom=am;aj.chrom_select.val(aj.chrom);aj.max_high=an.len-1;aj.reset();aj.request_redraw(true);for(var al=0,ah=aj.drawables.length;al<ah;al++){var ak=aj.drawables[al];if(ak.init){ak.init()}}}if(ai!==undefined&&ao!==undefined){aj.low=Math.max(ai,0);aj.high=Math.min(ao,aj.max_high)}aj.reset_overview();aj.request_redraw()}},go_to:function(al){var ap=this,ah,ak,ai=al.split(":"),an=ai[0],ao=ai[1];if(ao!==undefined){try{var am=ao.split("-");ah=parseInt(am[0].replace(/,/g,""),10);ak=parseInt(am[1].replace(/,/g,""),10)}catch(aj){return false}}ap.change_chrom(an,ah,ak)},move_fraction:function(aj){var ah=this;var ai=ah.high-ah.low;this.move_delta(aj*ai)},move_delta:function(aj){var ah=this;var ai=ah.high-ah.low;if(ah.low-aj<ah.max_low){ah.low=ah.max_low;ah.high=ah.max_low+ai}else{if(ah.high-aj>ah.max_high){ah.high=ah.max_high;ah.low=ah.max_high-ai}else{ah.high-=aj;ah.low-=aj}}ah.request_redraw()},add_drawable:function(ah){z.prototype.add_drawable.call(this,ah);ah.init();this.has_changes=true;this.update_intro_div()},add_label_track:function(ah){ah.view=this;ah.init();this.label_tracks.push(ah)},remove_drawable:function(aj,ai){z.prototype.remove_drawable.call(this,aj);if(ai){var ah=this;aj.container_div.fadeOut("slow",function(){$(this).remove();ah.update_intro_div()});this.has_changes=true}},reset:function(){this.low=this.max_low;this.high=this.max_high;this.viewport_container.find(".yaxislabel").remove()},request_redraw:function(ap,ah,ao,ai){var an=this,al=(ai?[ai]:an.drawables),aj;var ai;for(var am=0;am<al.length;am++){ai=al[am];aj=-1;for(var ak=0;ak<an.tracks_to_be_redrawn.length;ak++){if(an.tracks_to_be_redrawn[ak][0]===ai){aj=ak;break}}if(aj<0){an.tracks_to_be_redrawn.push([ai,ah,ao])}else{an.tracks_to_be_redrawn[am][1]=ah;an.tracks_to_be_redrawn[am][2]=ao}}requestAnimationFrame(function(){an._redraw(ap)})},_redraw:function(ar){var ao=this.low,ak=this.high;if(ao<this.max_low){ao=this.max_low}if(ak>this.max_high){ak=this.max_high}var aq=this.high-this.low;if(this.high!==0&&aq<this.min_separation){ak=ao+this.min_separation}this.low=Math.floor(ao);this.high=Math.ceil(ak);this.resolution=Math.pow(D,Math.ceil(Math.log((this.high-this.low)/S)/Math.log(D)));this.zoom_res=Math.pow(w,Math.max(0,Math.ceil(Math.log(this.resolution,w)/Math.log(w))));var ah=(this.low/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var an=((this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var at=13;this.overview_box.css({left:ah,width:Math.max(at,an)}).show();if(an<at){this.overview_box.css("left",ah-(at-an)/2)}if(this.overview_highlight){this.overview_highlight.css({left:ah,width:an})}this.update_location(this.low,this.high);if(!ar){var aj,ai,ap;for(var al=0,am=this.tracks_to_be_redrawn.length;al<am;al++){aj=this.tracks_to_be_redrawn[al][0];ai=this.tracks_to_be_redrawn[al][1];ap=this.tracks_to_be_redrawn[al][2];if(aj){aj._draw(ai,ap)}}this.tracks_to_be_redrawn=[];for(al=0,am=this.label_tracks.length;al<am;al++){this.label_tracks[al]._draw()}}},zoom_in:function(ai,aj){if(this.max_high===0||this.high-this.low<this.min_separation){return}var ak=this.high-this.low,al=ak/2+this.low,ah=(ak/this.zoom_factor)/2;if(ai){al=ai/this.viewport_container.width()*(this.high-this.low)+this.low}this.low=Math.round(al-ah);this.high=Math.round(al+ah);this.request_redraw()},zoom_out:function(){if(this.max_high===0){return}var ai=this.high-this.low,aj=ai/2+this.low,ah=(ai*this.zoom_factor)/2;this.low=Math.round(aj-ah);this.high=Math.round(aj+ah);this.request_redraw()},resize_window:function(){this.viewport_container.height(this.container.height()-this.top_container.height()-this.bottom_container.height());this.nav_container.width(this.container.width());this.request_redraw()},set_overview:function(ah){$.when(ah.get_overview_tile()).then(function(ai){view.overview_viewport.find(".track-tile").remove();view.overview_close.show();view.overview_viewport.append(ai.canvas);view.overview_highlight.show().height(ai.canvas.height());view.overview_viewport.height(ai.canvas.height()+view.overview_box.outerHeight());view.resize_window();if(view.overview_track){view.overview_track.set_is_overview(false)}view.overview_track=ah;ah.set_is_overview(true)});view.has_changes=true},reset_overview:function(){this.overview_viewport.find(".track-tile").remove();this.overview_viewport.height(this.default_overview_height);this.overview_box.height(this.default_overview_height);this.overview_close.hide();this.overview_highlight.hide();view.resize_window();if(view.overview_track){view.overview_track.set_is_overview(false)}view.overview_track=null}});var s=function(aj,an){this.track=aj;this.name=an.name;this.params=[];var av=an.params;for(var ak=0;ak<av.length;ak++){var ap=av[ak],ai=ap.name,au=ap.label,al=unescape(ap.html),aw=ap.value,ar=ap.type;if(ar==="number"){this.params[this.params.length]=new g(ai,au,al,aw,ap.min,ap.max)}else{if(ar=="select"){this.params[this.params.length]=new P(ai,au,al,aw)}else{console.log("WARNING: unrecognized tool parameter type:",ai,ar)}}}this.parent_div=$("<div/>").addClass("dynamic-tool").hide();this.parent_div.bind("drag",function(ay){ay.stopPropagation()}).click(function(ay){ay.stopPropagation()}).bind("dblclick",function(ay){ay.stopPropagation()});var at=$("<div class='tool-name'>").appendTo(this.parent_div).text(this.name);var aq=this.params;var ao=this;$.each(this.params,function(az,aC){var aB=$("<div>").addClass("param-row").appendTo(ao.parent_div);var ay=$("<div>").addClass("param-label").text(aC.label).appendTo(aB);var aA=$("<div/>").addClass("slider").html(aC.html).appendTo(aB);aA.find(":input").val(aC.value);$("<div style='clear: both;'/>").appendTo(aB)});this.parent_div.find("input").click(function(){$(this).select()});var ax=$("<div>").addClass("param-row").appendTo(this.parent_div);var am=$("<input type='submit'>").attr("value","Run on complete dataset").appendTo(ax);var ah=$("<input type='submit'>").attr("value","Run on visible region").css("margin-left","3em").appendTo(ax);var ao=this;ah.click(function(){ao.run_on_region()});am.click(function(){ao.run_on_dataset()})};q(s.prototype,{get_param_values_dict:function(){var ah={};this.parent_div.find(":input").each(function(){var ai=$(this).attr("name"),aj=$(this).val();ah[ai]=JSON.stringify(aj)});return ah},get_param_values:function(){var ai=[];var ah={};this.parent_div.find(":input").each(function(){var aj=$(this).attr("name"),ak=$(this).val();if(aj){ai[ai.length]=ak}});return ai},run_on_dataset:function(){var ah=this;ah.run({dataset_id:this.track.original_dataset_id,tool_id:ah.name},null,function(ai){show_modal(ah.name+" is Running",ah.name+" is running on the complete dataset. Tool outputs are in dataset's history.",{Close:hide_modal})})},run_on_region:function(){var ai={dataset_id:this.track.original_dataset_id,chrom:this.track.view.chrom,low:this.track.view.low,high:this.track.view.high,tool_id:this.name},al=this.track,aj=ai.tool_id+al.tool_region_and_parameters_str(ai.chrom,ai.low,ai.high),ah,am;if(al.container===view){var ak=new R(this.name,this.track.view,this.track.container);al.container.add_drawable(ak);al.container.remove_drawable(al);ak.add_drawable(al);al.container_div.appendTo(ak.content_div);ah=ak}else{ah=al.container}if(al instanceof e){am=new W(aj,view,ah,"hda");am.change_mode(al.mode);ah.add_drawable(am)}am.content_div.text("Starting job.");this.run(ai,am,function(an){am.dataset_id=an.dataset_id;am.content_div.text("Running job.");am.init()})},run:function(ai,aj,ak){$.extend(ai,this.get_param_values_dict());var ah=function(){$.getJSON(rerun_tool_url,ai,function(al){if(al==="no converter"){aj.container_div.addClass("error");aj.content_div.text(L)}else{if(al.error){aj.container_div.addClass("error");aj.content_div.text(y+al.message)}else{if(al==="pending"){aj.container_div.addClass("pending");aj.content_div.text("Converting input data so that it can be used quickly with tool.");setTimeout(ah,2000)}else{ak(al)}}}})};ah()}});var P=function(ai,ah,aj,ak){this.name=ai;this.label=ah;this.html=aj;this.value=ak};var g=function(aj,ai,al,am,ak,ah){P.call(this,aj,ai,al,am);this.min=ak;this.max=ah};var h=function(ai,ah,aj,ak){this.name=ai;this.index=ah;this.tool_id=aj;this.tool_exp_name=ak};var X=function(ai,ah,aj,ak){h.call(this,ai,ah,aj,ak);this.low=-Number.MAX_VALUE;this.high=Number.MAX_VALUE;this.min=Number.MAX_VALUE;this.max=-Number.MAX_VALUE;this.container=null;this.slider=null;this.slider_label=null};q(X.prototype,{applies_to:function(ah){if(ah.length>this.index){return true}return false},keep:function(ah){if(!this.applies_to(ah)){return true}var ai=ah[this.index];return(isNaN(ai)||(ai>=this.low&&ai<=this.high))},update_attrs:function(ai){var ah=false;if(!this.applies_to(ai)){return ah}if(ai[this.index]<this.min){this.min=Math.floor(ai[this.index]);ah=true}if(ai[this.index]>this.max){this.max=Math.ceil(ai[this.index]);ah=true}return ah},update_ui_elt:function(){if(this.min!=this.max){this.container.show()}else{this.container.hide()}var aj=function(am,ak){var al=ak-am;return(al<=2?0.01:1)};var ai=this.slider.slider("option","min"),ah=this.slider.slider("option","max");if(this.min<ai||this.max>ah){this.slider.slider("option","min",this.min);this.slider.slider("option","max",this.max);this.slider.slider("option","step",aj(this.min,this.max));this.slider.slider("option","values",[this.min,this.max])}}});var ac=function(at,aA){this.track=at;this.filters=[];for(var av=0;av<aA.length;av++){var aw=aA[av],aB=aw.name,ah=aw.type,aj=aw.index,az=aw.tool_id,ay=aw.tool_exp_name;if(ah==="int"||ah==="float"){this.filters[av]=new X(aB,aj,az,ay)}else{console.log("ERROR: unsupported filter: ",aB,ah)}}var ak=function(aC,aD,aE){aC.click(function(){var aF=aD.text();max=parseFloat(aE.slider("option","max")),input_size=(max<=1?4:max<=1000000?max.toString().length:6),multi_value=false;if(aE.slider("option","values")){input_size=2*input_size+1;multi_value=true}aD.text("");$("<input type='text'/>").attr("size",input_size).attr("maxlength",input_size).attr("value",aF).appendTo(aD).focus().select().click(function(aG){aG.stopPropagation()}).blur(function(){$(this).remove();aD.text(aF)}).keyup(function(aK){if(aK.keyCode===27){$(this).trigger("blur")}else{if(aK.keyCode===13){var aI=aE.slider("option","min"),aG=aE.slider("option","max"),aJ=function(aL){return(isNaN(aL)||aL>aG||aL<aI)},aH=$(this).val();if(!multi_value){aH=parseFloat(aH);if(aJ(aH)){alert("Parameter value must be in the range ["+aI+"-"+aG+"]");return $(this)}}else{aH=aH.split("-");aH=[parseFloat(aH[0]),parseFloat(aH[1])];if(aJ(aH[0])||aJ(aH[1])){alert("Parameter value must be in the range ["+aI+"-"+aG+"]");return $(this)}}aE.slider((multi_value?"values":"value"),aH)}}})})};this.parent_div=$("<div/>").addClass("filters").hide();this.parent_div.bind("drag",function(aC){aC.stopPropagation()}).click(function(aC){aC.stopPropagation()}).bind("dblclick",function(aC){aC.stopPropagation()}).bind("keydown",function(aC){aC.stopPropagation()});var ax=$("<div/>").addClass("sliders").appendTo(this.parent_div);var ap=this;$.each(this.filters,function(aF,aH){aH.container=$("<div/>").addClass("filter-row slider-row").appendTo(ax);var aG=$("<div/>").addClass("elt-label").appendTo(aH.container);var aE=$("<span/>").addClass("slider-name").text(aH.name+" ").appendTo(aG);var aD=$("<span/>");var aJ=$("<span/>").addClass("slider-value").appendTo(aG).append("[").append(aD).append("]");var aC=$("<div/>").addClass("slider").appendTo(aH.container);aH.control_element=$("<div/>").attr("id",aH.name+"-filter-control").appendTo(aC);var aI=[0,0];aH.control_element.slider({range:true,min:Number.MAX_VALUE,max:-Number.MIN_VALUE,values:[0,0],slide:function(aL,aM){var aK=aM.values;aD.text(aK[0]+"-"+aK[1]);aH.low=aK[0];aH.high=aK[1];ap.track.request_draw(true,true)},change:function(aK,aL){aH.control_element.slider("option","slide").call(aH.control_element,aK,aL)}});aH.slider=aH.control_element;aH.slider_label=aD;ak(aJ,aD,aH.control_element);$("<div style='clear: both;'/>").appendTo(aH.container)});if(this.filters.length!==0){var am=$("<div/>").addClass("param-row").appendTo(ax);var ao=$("<input type='submit'/>").attr("value","Run on complete dataset").appendTo(am);var ai=this;ao.click(function(){ai.run_on_dataset()})}var ar=$("<div/>").addClass("display-controls").appendTo(this.parent_div),au,an,aq,al={Transparency:function(aC){ap.alpha_filter=aC},Height:function(aC){ap.height_filter=aC}};$.each(al,function(aE,aD){au=$("<div/>").addClass("filter-row").appendTo(ar),an=$("<span/>").addClass("elt-label").text(aE+":").appendTo(au),aq=$("<select/>").attr("name",aE+"_dropdown").css("float","right").appendTo(au);$("<option/>").attr("value",-1).text("== None ==").appendTo(aq);for(var aC=0;aC<ap.filters.length;aC++){$("<option/>").attr("value",aC).text(ap.filters[aC].name).appendTo(aq)}aq.change(function(){$(this).children("option:selected").each(function(){var aF=parseInt($(this).val());al[aE]((aF>=0?ap.filters[aF]:null));ap.track.request_draw(true,true)})});$("<div style='clear: both;'/>").appendTo(au)});$("<div style='clear: both;'/>").appendTo(this.parent_div)};q(ac.prototype,{reset_filters:function(){for(var ah=0;ah<this.filters.length;ah++){filter=this.filters[ah];filter.slider.slider("option","values",[filter.min,filter.max])}this.alpha_filter=null;this.height_filter=null},run_on_dataset:function(){var ap=function(au,ar,at){if(!(ar in au)){au[ar]=at}return au[ar]};var aj={},ah,ai,ak;for(var al=0;al<this.filters.length;al++){ah=this.filters[al];if(ah.tool_id){if(ah.min!=ah.low){ai=ap(aj,ah.tool_id,[]);ai[ai.length]=ah.tool_exp_name+" >= "+ah.low}if(ah.max!=ah.high){ai=ap(aj,ah.tool_id,[]);ai[ai.length]=ah.tool_exp_name+" <= "+ah.high}}}var an=[];for(var aq in aj){an[an.length]=[aq,aj[aq]]}var ao=an.length;(function am(ay,av){var at=av[0],au=at[0],ax=at[1],aw="("+ax.join(") and (")+")",ar={cond:aw,input:ay,target_dataset_id:ay,tool_id:au},av=av.slice(1);$.getJSON(run_tool_url,ar,function(az){if(az.error){show_modal("Filter Dataset","Error running tool "+au,{Close:hide_modal})}else{if(av.length===0){show_modal("Filtering Dataset","Filter(s) are running on the complete dataset. Outputs are in dataset's history.",{Close:hide_modal})}else{am(az.dataset_id,av)}}})})(this.track.dataset_id,an)}});var E=function(ah,ai){N.Scaler.call(this,ai);this.filter=ah};E.prototype.gen_val=function(ah){if(this.filter.high===Number.MAX_VALUE||this.filter.low===-Number.MAX_VALUE||this.filter.low===this.filter.high){return this.default_val}return((parseFloat(ah[this.filter.index])-this.filter.low)/(this.filter.high-this.filter.low))};var H=function(ah){this.track=ah.track;this.params=ah.params;this.values={};this.restore_values((ah.saved_values?ah.saved_values:{}));this.onchange=ah.onchange};q(H.prototype,{restore_values:function(ah){var ai=this;$.each(this.params,function(aj,ak){if(ah[ak.key]!==undefined){ai.values[ak.key]=ah[ak.key]}else{ai.values[ak.key]=ak.default_value}})},build_form:function(){var ai=this;var ah=$("<div />");$.each(this.params,function(am,ak){if(!ak.hidden){var aj="param_"+am;var ao=ai.values[ak.key];var ar=$("<div class='form-row' />").appendTo(ah);ar.append($("<label />").attr("for",aj).text(ak.label+":"));if(ak.type==="bool"){ar.append($('<input type="checkbox" />').attr("id",aj).attr("name",aj).attr("checked",ao))}else{if(ak.type==="text"){ar.append($('<input type="text"/>').attr("id",aj).val(ao).click(function(){$(this).select()}))}else{if(ak.type==="color"){var an=$("<input />").attr("id",aj).attr("name",aj).val(ao);var ap=$("<div class='tipsy tipsy-north' style='position: absolute;' />").hide();var al=$("<div style='background-color: black; padding: 10px;'></div>").appendTo(ap);var aq=$("<div/>").appendTo(al).farbtastic({width:100,height:100,callback:an,color:ao});$("<div />").append(an).append(ap).appendTo(ar).bind("click",function(at){ap.css({left:$(this).position().left+($(an).width()/2)-60,top:$(this).position().top+$(this.height)}).show();$(document).bind("click.color-picker",function(){ap.hide();$(document).unbind("click.color-picker")});at.stopPropagation()})}else{ar.append($("<input />").attr("id",aj).attr("name",aj).val(ao))}}}}});return ah},update_from_form:function(ah){var aj=this;var ai=false;$.each(this.params,function(ak,am){if(!am.hidden){var an="param_"+ak;var al=ah.find("#"+an).val();if(am.type==="float"){al=parseFloat(al)}else{if(am.type==="int"){al=parseInt(al)}else{if(am.type==="bool"){al=ah.find("#"+an).is(":checked")}}}if(al!==aj.values[am.key]){aj.values[am.key]=al;ai=true}}});if(ai){this.onchange()}}});var b=function(ah,ak,aj,ai,al){this.track=ah;this.index=ak;this.low=ak*S*aj;this.high=(ak+1)*S*aj;this.resolution=aj;this.canvas=$("<div class='track-tile'/>").append(ai);this.data=al;this.stale=false};b.prototype.predisplay_actions=function(){};var l=function(ah,ak,aj,ai,al,am){b.call(this,ah,ak,aj,ai,al);this.max_val=am};q(l.prototype,b.prototype);var Q=function(ah,al,ak,aj,an,ao,am,ai){b.call(this,ah,al,ak,aj,an);this.mode=ao;this.message=am;this.feature_mapper=ai};q(Q.prototype,b.prototype);Q.prototype.predisplay_actions=function(){var ai=this,ah={};if(ai.mode!=="Pack"){return}$(this.canvas).mousemove(function(au){var ao=$(this).offset(),at=au.pageX-ao.left,ar=au.pageY-ao.top,ay=ai.feature_mapper.get_feature_data(at,ar),ap=(ay?ay[0]:null);$(this).siblings(".feature-popup").each(function(){if(!ap||$(this).attr("id")!==ap.toString()){$(this).remove()}});if(ay){var ak=ah[ap];if(!ak){var ap=ay[0],av={name:ay[3],start:ay[1],end:ay[2],strand:ay[4]},an=ai.track.filters_manager.filters,am;for(var aq=0;aq<an.length;aq++){am=an[aq];av[am.name]=ay[am.index]}var ak=$("<div/>").attr("id",ap).addClass("feature-popup"),ax,aw,az=$("<table/>").appendTo(ak),aA;for(ax in av){aw=av[ax];aA=$("<tr/>").appendTo(az);$("<th/>").appendTo(aA).text(ax);$("<td/>").attr("align","left").appendTo(aA).text(typeof(aw)=="number"?ab(aw,2):aw)}ah[ap]=ak}ak.appendTo($(ai.canvas).parent());var al=at+parseInt(ai.canvas.css("left"))+7,aj=ar+parseInt(ai.canvas.css("top"))+7;ak.css("left",al+"px").css("top",aj+"px")}else{if(!au.isPropagationStopped()){au.stopPropagation();$(this).siblings().each(function(){$(this).trigger(au)})}}}).mouseleave(function(){$(this).siblings(".feature-popup").remove()})};var j=function(ak,ai,ah,aj,al,am){r.call(this,ak,ai,ah,{},"draghandle");this.data_url=(al?al:default_data_url);this.data_url_extra_params={};this.data_query_wait=(am?am:M);this.dataset_check_url=converted_datasets_state_url;if(!j.id_counter){j.id_counter=0}this.container_div=$("<div />").addClass("track").attr("id","track_"+j.id_counter++).css("position","relative");if(!this.hidden){this.header_div=$("<div class='track-header' />").appendTo(this.container_div);if(this.view.editor){this.drag_div=$("<div/>").addClass(this.drag_handle_class).appendTo(this.header_div)}this.name_div=$("<div class='menubutton popup' />").appendTo(this.header_div);this.name_div.text(this.name);this.name_div.attr("id",this.name.replace(/\s+/g,"-").replace(/[^a-zA-Z0-9\-]/g,"").toLowerCase())}this.content_div=$("<div class='track-content'>").appendTo(this.container_div);this.container.content_div.append(this.container_div)};q(j.prototype,r.prototype,{get_type:function(){if(this instanceof ad){return"LabelTrack"}else{if(this instanceof B){return"ReferenceTrack"}else{if(this instanceof k){return"LineTrack"}else{if(this instanceof Y){return"ReadTrack"}else{if(this instanceof W){return"ToolDataFeatureTrack"}else{if(this instanceof V){return"VcfTrack"}else{if(this instanceof e){return"FeatureTrack"}}}}}}}return""},init:function(){var ah=this;ah.enabled=false;ah.tile_cache.clear();ah.data_manager.clear();ah.initial_canvas=undefined;ah.content_div.css("height","auto");ah.container_div.removeClass("nodata error pending");if(!ah.dataset_id){return}$.getJSON(converted_datasets_state_url,{hda_ldda:ah.hda_ldda,dataset_id:ah.dataset_id,chrom:ah.view.chrom},function(ai){if(!ai||ai==="error"||ai.kind==="error"){ah.container_div.addClass("error");ah.content_div.text(p);if(ai.message){var aj=$(" <a href='javascript:void(0);'></a>").text("View error").click(function(){show_modal("Trackster Error","<pre>"+ai.message+"</pre>",{Close:hide_modal})});ah.content_div.append(aj)}}else{if(ai==="no converter"){ah.container_div.addClass("error");ah.content_div.text(L)}else{if(ai==="no data"||(ai.data!==undefined&&(ai.data===null||ai.data.length===0))){ah.container_div.addClass("nodata");ah.content_div.text(G)}else{if(ai==="pending"){ah.container_div.addClass("pending");ah.content_div.text(u);setTimeout(function(){ah.init()},ah.data_query_wait)}else{if(ai.status==="data"){if(ai.valid_chroms){ah.valid_chroms=ai.valid_chroms;ah.make_name_popup_menu()}ah.content_div.text(aa);if(ah.view.chrom){ah.content_div.text("");ah.content_div.css("height",ah.height_px+"px");ah.enabled=true;$.when(ah.predraw_init()).done(function(){ah.container_div.removeClass("nodata error pending");ah.request_draw()})}}}}}}})},predraw_init:function(){},});var O=function(ao,am){var ai=this,ap=ai.view;n(ai.container_div,ai.drag_handle_class,".group",ai);this.filters_manager=new ac(this,(ao!==undefined?ao:{}));this.filters_available=false;this.filters_visible=false;this.tool=(am!==undefined&&obj_length(am)>0?new s(this,am):undefined);this.is_overview=false;if(ai.hidden){return}if(this.filters_manager){this.filters_div=this.filters_manager.parent_div;this.header_div.after(this.filters_div)}if(this.tool){this.dynamic_tool_div=this.tool.parent_div;this.header_div.after(this.dynamic_tool_div)}if(ai.display_modes!==undefined){if(ai.mode_div===undefined){ai.mode_div=$("<div class='right-float menubutton popup' />").appendTo(ai.header_div);var aj=(ai.config&&ai.config.values.mode?ai.config.values.mode:ai.display_modes[0]);ai.mode=aj;ai.mode_div.text(aj);var ah={};for(var ak=0,an=ai.display_modes.length;ak<an;ak++){var al=ai.display_modes[ak];ah[al]=function(aq){return function(){ai.change_mode(aq)}}(al)}make_popupmenu(ai.mode_div,ah)}else{ai.mode_div.hide()}}this.make_name_popup_menu()};q(O.prototype,r.prototype,j.prototype,{to_json:function(){return{track_type:this.get_type(),name:this.name,hda_ldda:this.hda_ldda,dataset_id:this.dataset_id,prefs:this.prefs,mode:this.mode,}},change_mode:function(ai){var ah=this;ah.mode_div.text(ai);ah.mode=ai;ah.config.values.mode=ai;ah.tile_cache.clear();ah.request_draw();return ah},make_name_popup_menu:function(){var ai=this;var ah={};ah[(this.is_overview?"Hide overview":"Set as overview")]=function(){if(ai.is_overview){ai.view.reset_overview()}else{ai.view.set_overview(ai)}};ah["Edit configuration"]=function(){var am=function(){hide_modal();$(window).unbind("keypress.check_enter_esc")},ak=function(){ai.config.update_from_form($(".dialog-box"));hide_modal();$(window).unbind("keypress.check_enter_esc")},al=function(an){if((an.keyCode||an.which)===27){am()}else{if((an.keyCode||an.which)===13){ak()}}};$(window).bind("keypress.check_enter_esc",al);show_modal("Configure Track",ai.config.build_form(),{Cancel:am,OK:ak})};if(ai.filters_available>0){var aj=(ai.filters_div.is(":visible")?"Hide filters":"Show filters");ah[aj]=function(){ai.filters_visible=(ai.filters_div.is(":visible"));if(ai.filters_visible){ai.filters_manager.reset_filters()}ai.filters_div.toggle();ai.make_name_popup_menu()}}if(ai.tool){var aj=(ai.dynamic_tool_div.is(":visible")?"Hide tool":"Show tool");ah[aj]=function(){if(!ai.dynamic_tool_div.is(":visible")){ai.set_name(ai.name+ai.tool_region_and_parameters_str())}else{menu_option_text="Show dynamic tool";ai.revert_name()}ai.dynamic_tool_div.toggle();ai.make_name_popup_menu()}}ah.Remove=function(){ai.remove()};make_popupmenu(ai.name_div,ah)},set_is_overview:function(ah){this.is_overview=ah;this.make_name_popup_menu()},get_overview_tile:function(){var ah=this;view=ah.view,resolution=Math.pow(D,Math.ceil(Math.log((view.max_high-view.max_low)/S)/Math.log(D))),view_width=view.container.width(),w_scale=view_width/(view.max_high-view.max_low),overview_tile=$.Deferred();$.when(ah.data_manager.get_data(view.max_low,view.max_high,"Auto",resolution,ah.data_url_extra_params)).then(function(ai){var ak=ah._gen_tile_cache_key(view_width,w_scale,0),am=ah.tile_cache.get(ak);if(!am){am=ah.draw_tile(ai,"Auto",resolution,0,w_scale);ah.tile_cache.set(ak,am)}var ap=$(am.canvas.find("canvas")),al=ap.clone(),ao=ap.get(0).getContext("2d"),aj=al.get(0).getContext("2d"),an=ao.getImageData(0,0,ao.canvas.width,ao.canvas.height);aj.putImageData(an,-ah.left_offset,(am.data.dataset_type==="summary_tree"?U:0));new_tile=new b(ah,-1,resolution,al);overview_tile.resolve(new_tile)});return overview_tile},_gen_tile_cache_key:function(ai,aj,ah){return ai+"_"+aj+"_"+ah},request_draw:function(ai,ah){this.view.request_redraw(false,ai,ah,this)},_draw:function(aj,ar){if(!this.enabled){return}if(!(this instanceof B)&&(!this.dataset_id)){return}var aq=this.view.low,an=this.view.high,ao=an-aq,ak=this.view.container.width(),av=ak/ao,am=this.view.resolution,au=$("<div style='position: relative;'></div>");if(!ar){this.content_div.children().remove()}this.content_div.append(au);this.max_height=0;var ai=Math.floor(aq/am/S);var ap=true;var at=[];var ah=0;while((ai*S*am)<an){tile=this.draw_helper(aj,ak,ai,am,au,av);if(tile){at.push(tile)}else{ap=false}ai+=1;ah++}var al=this;if(ap){al.postdraw_actions(at,ak,av,ar)}},postdraw_actions:function(al,am,an,ah){var aj=this;var ak=false;for(var ai=0;ai<al.length;ai++){if(al[ai].message){ak=true;break}}if(ak){for(var ai=0;ai<al.length;ai++){tile=al[ai];if(!tile.message){tile.canvas.css("padding-top",F)}}}},draw_helper:function(ai,aj,ak,an,au,ay,av,ao){var al=this,at=this._gen_tile_cache_key(aj,ay,ak),ap=ak*S*an,ax=ap+S*an;var aq=(ai?undefined:al.tile_cache.get(at));if(aq){al.show_tile(aq,au,ay);return aq}var ar=function(az){return("isResolved" in az)};var am=true;var ah=al.data_manager.get_data(ap,ax,al.mode,an,al.data_url_extra_params);if(ar(ah)){am=false}var aw;if(view.reference_track&&ay>view.canvas_manager.char_width_px){aw=view.reference_track.data_manager.get_data(ap,ax,al.mode,an,view.reference_track.data_url_extra_params);if(ar(aw)){am=false}}if(am){q(ah,ao);var aq=al.draw_tile(ah,al.mode,an,ak,ay,aw);if(aq!==undefined){al.tile_cache.set(at,aq);al.show_tile(aq,au,ay)}return aq}$.when(ah,aw).then(function(){view.request_redraw()});return null},show_tile:function(ao,aq,ar){var aj=this,ai=ao.canvas,an=ai;if(ao.message){var at=$("<div/>"),ap=$("<div/>").addClass("tile-message").text(ao.message).css({height:F-1,width:ao.canvas.width}).appendTo(at),al=$("<a href='javascript:void(0);'/>").addClass("icon more-down").appendTo(ap),ah=$("<a href='javascript:void(0);'/>").addClass("icon more-across").appendTo(ap);at.append(ai);an=at;al.click(function(){ao.stale=true;aj.data_manager.get_more_data(ao.low,ao.high,aj.mode,ao.resolution,{},aj.data_manager.DEEP_DATA_REQ);aj.request_draw()}).dblclick(function(au){au.stopPropagation()});ah.click(function(){ao.stale=true;aj.data_manager.get_more_data(ao.low,ao.high,aj.mode,ao.resolution,{},aj.data_manager.BROAD_DATA_REQ);aj.request_draw()}).dblclick(function(au){au.stopPropagation()})}ao.predisplay_actions();var am=this.view.high-this.view.low,ak=(ao.low-this.view.low)*ar;if(this.left_offset){ak-=this.left_offset}an.css({position:"absolute",top:0,left:ak,height:""});aq.append(an);aj.max_height=Math.max(aj.max_height,an.height());aj.content_div.css("height",aj.max_height+"px");aq.children().css("height",aj.max_height+"px")},_get_tile_bounds:function(ah,ai){var ak=ah*S*ai,al=S*ai,aj=(ak+al<=this.view.max_high?ak+al:this.view.max_high);return[ak,aj]},tool_region_and_parameters_str:function(aj,ah,ak){var ai=this,al=(aj!==undefined&&ah!==undefined&&ak!==undefined?aj+":"+ah+"-"+ak:"all");return" - region=["+al+"], parameters=["+ai.tool.get_param_values().join(", ")+"]"}});var ad=function(ai,ah){this.hidden=true;j.call(this,"label",ai,ah,{});this.container_div.addClass("label-track")};q(ad.prototype,j.prototype,{init:function(){this.enabled=true},_draw:function(){var aj=this.view,ak=aj.high-aj.low,an=Math.floor(Math.pow(10,Math.floor(Math.log(ak)/Math.log(10)))),ah=Math.floor(aj.low/an)*an,al=this.view.container.width(),ai=$("<div style='position: relative; height: 1.3em;'></div>");while(ah<aj.high){var am=(ah-aj.low)/ak*al;ai.append($("<div class='label'>"+commatize(ah)+"</div>").css({position:"absolute",left:am-1}));ah+=an}this.content_div.children(":first").remove();this.content_div.append(ai)}});var B=function(ah){this.hidden=true;j.call(this,"reference",ah,{content_div:ah.top_labeltrack},{});O.call(this);ah.reference_track=this;this.left_offset=200;this.height_px=12;this.container_div.addClass("reference-track");this.content_div.css("background","none");this.content_div.css("min-height","0px");this.content_div.css("border","none");this.data_url=reference_url;this.data_url_extra_params={dbkey:ah.dbkey};this.data_manager=new J(C,this,false);this.tile_cache=new c(v)};q(B.prototype,r.prototype,O.prototype,{init:function(){this.enabled=true},draw_tile:function(ar,an,am,ai,at){var al=this,aj=S*am;if(at>this.view.canvas_manager.char_width_px){if(ar===null){al.content_div.css("height","0px");return}var ak=this.view.canvas_manager.new_canvas();var aq=ak.getContext("2d");ak.width=Math.ceil(aj*at+al.left_offset);ak.height=al.height_px;aq.font=aq.canvas.manager.default_font;aq.textAlign="center";ar=ar.data;for(var ao=0,ap=ar.length;ao<ap;ao++){var ah=Math.round(ao*at);aq.fillText(ar[ao],ah+al.left_offset,10)}return new b(al,ai,am,ak,ar)}this.content_div.css("height","0px")}});var k=function(am,ak,aj,an,ah,al){var ai=this;this.display_modes=["Histogram","Line","Filled","Intensity"];this.mode="Histogram";j.call(this,am,ak,aj,al);O.call(this);this.min_height_px=16;this.max_height_px=400;this.height_px=80;this.hda_ldda=an;this.dataset_id=ah;this.original_dataset_id=ah;this.data_manager=new T(C,this);this.tile_cache=new c(v);this.left_offset=0;this.config=new H({track:this,params:[{key:"name",label:"Name",type:"text",default_value:am},{key:"color",label:"Color",type:"color",default_value:"black"},{key:"min_value",label:"Min Value",type:"float",default_value:undefined},{key:"max_value",label:"Max Value",type:"float",default_value:undefined},{key:"mode",type:"string",default_value:this.mode,hidden:true},{key:"height",type:"int",default_value:this.height_px,hidden:true}],saved_values:al,onchange:function(){ai.set_name(ai.prefs.name);ai.vertical_range=ai.prefs.max_value-ai.prefs.min_value;$("#linetrack_"+ai.dataset_id+"_minval").text(ai.prefs.min_value);$("#linetrack_"+ai.dataset_id+"_maxval").text(ai.prefs.max_value);ai.tile_cache.clear();ai.request_draw()}});this.prefs=this.config.values;this.height_px=this.config.values.height;this.vertical_range=this.config.values.max_value-this.config.values.min_value;this.add_resize_handle()};q(k.prototype,r.prototype,O.prototype,{add_resize_handle:function(){var ah=this;var ak=false;var aj=false;var ai=$("<div class='track-resize'>");$(ah.container_div).hover(function(){ak=true;ai.show()},function(){ak=false;if(!aj){ai.hide()}});ai.hide().bind("dragstart",function(al,am){aj=true;am.original_height=$(ah.content_div).height()}).bind("drag",function(am,an){var al=Math.min(Math.max(an.original_height+an.deltaY,ah.min_height_px),ah.max_height_px);$(ah.content_div).css("height",al);ah.height_px=al;ah.request_draw(true)}).bind("dragend",function(al,am){ah.tile_cache.clear();aj=false;if(!ak){ai.hide()}ah.config.values.height=ah.height_px}).appendTo(ah.container_div)},predraw_init:function(){var ah=this;ah.vertical_range=undefined;return $.getJSON(ah.data_url,{stats:true,chrom:ah.view.chrom,low:null,high:null,hda_ldda:ah.hda_ldda,dataset_id:ah.dataset_id},function(ai){ah.container_div.addClass("line-track");var ak=ai.data;if(isNaN(parseFloat(ah.prefs.min_value))||isNaN(parseFloat(ah.prefs.max_value))){ah.prefs.min_value=ak.min;ah.prefs.max_value=ak.max;$("#track_"+ah.dataset_id+"_minval").val(ah.prefs.min_value);$("#track_"+ah.dataset_id+"_maxval").val(ah.prefs.max_value)}ah.vertical_range=ah.prefs.max_value-ah.prefs.min_value;ah.total_frequency=ak.total_frequency;ah.container_div.find(".yaxislabel").remove();var al=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+ah.dataset_id+"_minval").text(ab(ah.prefs.min_value,3));var aj=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+ah.dataset_id+"_maxval").text(ab(ah.prefs.max_value,3));aj.css({position:"absolute",top:"24px",left:"10px"});aj.prependTo(ah.container_div);al.css({position:"absolute",bottom:"2px",left:"10px"});al.prependTo(ah.container_div)})},draw_tile:function(au,am,al,aj,at){if(this.vertical_range===undefined){return}var ah=this._get_tile_bounds(aj,al),an=ah[0],ar=ah[1],ai=Math.ceil((ar-an)*at),ap=this.height_px;var ak=this.view.canvas_manager.new_canvas();ak.width=ai,ak.height=ap;var aq=ak.getContext("2d");var ao=new N.LinePainter(au.data,an,ar,this.prefs,am);ao.draw(aq,ai,ap);return new b(this.track,aj,al,ak,au.data)}});var e=function(ah,an,ai,am,ap,ao,ak,al){var aj=this;this.display_modes=["Auto","Histogram","Dense","Squish","Pack"];j.call(this,ah,an,ai,ao);O.call(this,ak,al);this.config=new H({track:this,params:[{key:"name",label:"Name",type:"text",default_value:ah},{key:"block_color",label:"Block color",type:"color",default_value:"#444"},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:ao,onchange:function(){aj.set_name(aj.prefs.name);aj.tile_cache.clear();aj.request_draw()}});this.prefs=this.config.values;this.height_px=0;this.container_div.addClass("feature-track");this.hda_ldda=am;this.dataset_id=ap;this.original_dataset_id=ap;this.show_labels_scale=0.001;this.showing_details=false;this.summary_draw_height=30;this.inc_slots={};this.start_end_dct={};this.tile_cache=new c(d);this.data_manager=new T(20,this);this.left_offset=200;this.painter=N.LinkedFeaturePainter};q(e.prototype,r.prototype,O.prototype,{postdraw_actions:function(ax,ah,ay,aw){O.prototype.postdraw_actions.call(this,ax,aw);var ak=this;if(aw){var am=ak.content_div.children();var an=false;for(var al=am.length-1,ar=0;al>=ar;al--){var aj=$(am[al]);if(an){aj.remove()}else{if(aj.children().length!==0){an=true}}}}if(ak.mode=="Histogram"){var aq=-1;for(var al=0;al<ax.length;al++){var av=ax[al].max_val;if(av>aq){aq=av}}for(var al=0;al<ax.length;al++){var au=ax[al];if(au.max_val!==aq){au.canvas.remove();ak.draw_helper(true,ah,au.index,au.resolution,au.canvas.parent(),ay,[],{max:aq})}}}if(ak.filters_manager){var ai=ak.filters_manager.filters;for(var ap=0;ap<ai.length;ap++){ai[ap].update_ui_elt()}var ao=false,at;for(var al=0;al<ax.length;al++){if(ax[al].data.length){at=ax[al].data[0];for(var ap=0;ap<ai.length;ap++){if(ai[ap].applies_to(at)){ao=true;break}}}}if(ak.filters_available!==ao){ak.filters_available=ao;if(!ak.filters_available){ak.filters_div.hide()}ak.make_name_popup_menu()}}},update_auto_mode:function(ah){if(this.mode=="Auto"){if(ah=="no_detail"){ah="feature spans"}else{if(ah=="summary_tree"){ah="coverage histogram"}}this.mode_div.text("Auto ("+ah+")")}},incremental_slots:function(al,ai,ak){var aj=this.view.canvas_manager.dummy_context,ah=this.inc_slots[al];if(!ah||(ah.mode!==ak)){ah=new (t.FeatureSlotter)(al,ak==="Pack",A,function(am){return aj.measureText(am)});ah.mode=ak;this.inc_slots[al]=ah}return ah.slot_features(ai)},get_summary_tree_data:function(al,ao,aj,ax){if(ax>aj-ao){ax=aj-ao}var at=Math.floor((aj-ao)/ax),aw=[],ak=0;var am=0,an=0,ar,av=0,ap=[],au,aq;var ai=function(aA,az,aB,ay){aA[0]=az+aB*ay;aA[1]=az+(aB+1)*ay};while(av<ax&&am!==al.length){var ah=false;for(;av<ax&&!ah;av++){ai(ap,ao,av,at);for(an=am;an<al.length;an++){ar=al[an].slice(1,3);if(is_overlap(ar,ap)){ah=true;break}}if(ah){break}}data_start_index=an;aw[aw.length]=au=[ap[0],0];for(;an<al.length;an++){ar=al[an].slice(1,3);if(is_overlap(ar,ap)){au[1]++}else{break}}if(au[1]>ak){ak=au[1]}av++}return{max:ak,delta:at,data:aw}},draw_tile:function(aw,az,aD,aH,ar,ak){var aA=this,am=aA._get_tile_bounds(aH,aD),aK=am[0],ai=am[1],ay=ai-aK,aB=Math.ceil(ay*ar),aQ=25,al=this.left_offset,ax,an;if(az==="Auto"){if(aw.dataset_type==="summary_tree"){az=aw.dataset_type}else{if(aw.extra_info==="no_detail"){az="no_detail"}else{var aP=aw.data;if(this.view.high-this.view.low>K){az="Squish"}else{az="Pack"}}}this.update_auto_mode(az)}if(az==="summary_tree"||az==="Histogram"){an=this.summary_draw_height;this.container_div.find(".yaxislabel").remove();var ah=$("<div />").addClass("yaxislabel");ah.text(aw.max);ah.css({position:"absolute",top:"24px",left:"10px",color:this.prefs.label_color});ah.prependTo(this.container_div);var aj=this.view.canvas_manager.new_canvas();aj.width=aB+al;aj.height=an+U;if(aw.dataset_type!="summary_tree"){var at=this.get_summary_tree_data(aw.data,aK,ai,200);if(aw.max){at.max=aw.max}aw=at}var aM=new N.SummaryTreePainter(aw,aK,ai,this.prefs);var aC=aj.getContext("2d");aC.translate(al,U);aM.draw(aC,aB,an);return new l(aA,aH,aD,aj,aw.data,aw.max)}var ax,ap=1;if(az==="no_detail"||az==="Squish"||az==="Pack"){ap=this.incremental_slots(ar,aw.data,az);ax=this.inc_slots[ar].slots}var aq=[];if(aw.data){var au=this.filters_manager.filters;for(var aE=0,aG=aw.data.length;aE<aG;aE++){var ao=aw.data[aE];var aF=false;var av;for(var aJ=0,aO=au.length;aJ<aO;aJ++){av=au[aJ];av.update_attrs(ao);if(!av.keep(ao)){aF=true;break}}if(!aF){aq.push(ao)}}}var aN=(this.filters_manager.alpha_filter?new E(this.filters_manager.alpha_filter):null);var aL=(this.filters_manager.height_filter?new E(this.filters_manager.height_filter):null);var aM=new (this.painter)(aq,aK,ai,this.prefs,az,aN,aL,ak);var an=Math.max(af,aM.get_required_height(ap));var aj=this.view.canvas_manager.new_canvas();var aI=null;aj.width=aB+al;aj.height=an;var aC=aj.getContext("2d");aC.fillStyle=this.prefs.block_color;aC.font=aC.canvas.manager.default_font;aC.textAlign="right";this.container_div.find(".yaxislabel").remove();if(aw.data){aC.translate(al,0);aI=aM.draw(aC,aB,an,ax);aI.translation=-al}return new Q(aA,aH,aD,aj,aw.data,az,aw.message,aI)}});var V=function(al,aj,ai,an,ah,ak,am){e.call(this,al,aj,ai,an,ah,ak,am);this.painter=N.VariantPainter};q(V.prototype,r.prototype,O.prototype,e.prototype);var Y=function(al,aj,ai,an,ah,ak,am){e.call(this,al,aj,ai,an,ah,ak,am);this.config=new H({track:this,params:[{key:"name",label:"Name",type:"text",default_value:al},{key:"block_color",label:"Block color",type:"color",default_value:"#444"},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_insertions",label:"Show insertions",type:"bool",default_value:false},{key:"show_differences",label:"Show differences only",type:"bool",default_value:true},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:ak,onchange:function(){this.track.set_name(this.track.prefs.name);this.track.tile_cache.clear();this.track.request_draw()}});this.prefs=this.config.values;this.painter=N.ReadPainter;this.make_name_popup_menu()};q(Y.prototype,r.prototype,O.prototype,e.prototype);var W=function(al,aj,ai,an,ah,ak,am){e.call(this,al,aj,ai,an,ah,ak,am,{});this.data_url=raw_data_url;this.data_query_wait=1000;this.dataset_check_url=dataset_state_url};q(W.prototype,r.prototype,O.prototype,e.prototype,{predraw_init:function(){var ai=this;var ah=function(){if(ai.data_manager.size()===0){setTimeout(ah,300)}else{ai.data_url=default_data_url;ai.data_query_wait=M;ai.dataset_state_url=converted_datasets_state_url;$.getJSON(ai.dataset_state_url,{dataset_id:ai.dataset_id,hda_ldda:ai.hda_ldda},function(aj){})}};ah()}});Z.View=ae;Z.DrawableGroup=R;Z.LineTrack=k;Z.FeatureTrack=e;Z.ReadTrack=Y};var slotting_module=function(c,b){var e=c("class").extend;var d=2,a=5;b.FeatureSlotter=function(j,h,f,g){this.slots={};this.start_end_dct={};this.w_scale=j;this.include_label=h;this.max_rows=f;this.measureText=g};e(b.FeatureSlotter.prototype,{slot_features:function(m){var p=this.w_scale,s=this.slots,h=this.start_end_dct,y=[],A=[],n=0,z=this.max_rows;for(var w=0,x=m.length;w<x;w++){var l=m[w],o=l[0];if(s[o]!==undefined){n=Math.max(n,s[o]);A.push(s[o])}else{y.push(w)}}var q=function(G,H){for(var F=0;F<=z;F++){var D=false,I=h[F];if(I!==undefined){for(var C=0,E=I.length;C<E;C++){var B=I[C];if(H>B[0]&&G<B[1]){D=true;break}}}if(!D){return F}}return -1};for(var w=0,x=y.length;w<x;w++){var l=m[y[w]],o=l[0],u=l[1],f=l[2],r=l[3],g=Math.floor(u*p),k=Math.ceil(f*p),v=this.measureText(r).width,j;if(r!==undefined&&this.include_label){v+=(d+a);if(g-v>=0){g-=v;j="left"}else{k+=v;j="right"}}var t=q(g,k);if(t>=0){if(h[t]===undefined){h[t]=[]}h[t].push([g,k]);s[o]=t;n=Math.max(n,t)}else{}}return n+1}})};var painters_module=function(k,y){var v=k("class").extend;var q=function(J,B,H,A,G,E){if(E===undefined){E=4}var D=A-B;var C=G-H;var F=Math.floor(Math.sqrt(D*D+C*C)/E);var K=D/F;var I=C/F;var z;for(z=0;z<F;z++,B+=K,H+=I){if(z%2!==0){continue}J.fillRect(B,H,E,1)}};var r=function(B,A,z,E){var D=A-E/2,C=A+E/2,F=z-Math.sqrt(E*3/2);B.beginPath();B.moveTo(D,F);B.lineTo(C,F);B.lineTo(A,z);B.lineTo(D,F);B.strokeStyle=this.fillStyle;B.fill();B.stroke();B.closePath()};var e=function(z){this.default_val=(z?z:1)};e.prototype.gen_val=function(z){return this.default_val};var n=function(B,D,z,A,C){this.data=B;this.view_start=D;this.view_end=z;this.prefs=v({},this.default_prefs,A);this.mode=C};n.prototype.default_prefs={};var w=function(B,D,z,A,C){n.call(this,B,D,z,A,C)};w.prototype.default_prefs={show_counts:false};w.prototype.draw=function(M,z,L){var E=this.view_start,O=this.view_end-this.view_start,N=z/O;var J=this.data.data,I=this.data.delta,G=this.data.max,B=L;delta_x_px=Math.ceil(I*N);M.save();for(var C=0,D=J.length;C<D;C++){var H=Math.floor((J[C][0]-E)*N);var F=J[C][1];if(!F){continue}var K=F/G*L;if(F!==0&&K<1){K=1}M.fillStyle=this.prefs.block_color;M.fillRect(H,B-K,delta_x_px,K);var A=4;if(this.prefs.show_counts&&(M.measureText(F).width+A)<delta_x_px){M.fillStyle=this.prefs.label_color;M.textAlign="center";M.fillText(F,H+(delta_x_px/2),10)}}M.restore()};var c=function(z,D,F,G,B){n.call(this,z,D,F,G,B);if(this.prefs.min_value===undefined){var H=Infinity;for(var A=0,C=this.data.length;A<C;A++){H=Math.min(H,this.data[A][1])}this.prefs.min_value=H}if(this.prefs.max_value===undefined){var E=-Infinity;for(var A=0,C=this.data.length;A<C;A++){E=Math.max(E,this.data[A][1])}this.prefs.max_value=E}};c.prototype.default_prefs={min_value:undefined,max_value:undefined,mode:"Histogram",color:"#000",overflow_color:"#F66"};c.prototype.draw=function(N,M,K){var F=false,H=this.prefs.min_value,D=this.prefs.max_value,J=D-H,z=K,A=this.view_start,L=this.view_end-this.view_start,B=M/L,I=this.mode,T=this.data;N.save();var U=Math.round(K+H/J*K);if(I!=="Intensity"){N.fillStyle="#aaa";N.fillRect(0,U,M,1)}N.beginPath();var R,E,C;if(T.length>1){C=Math.ceil((T[1][0]-T[0][0])*B)}else{C=10}for(var O=0,P=T.length;O<P;O++){N.fillStyle=this.prefs.color;R=Math.round((T[O][0]-A)*B);E=T[O][1];var Q=false,G=false;if(E===null){if(F&&I==="Filled"){N.lineTo(R,z)}F=false;continue}if(E<H){G=true;E=H}else{if(E>D){Q=true;E=D}}if(I==="Histogram"){E=Math.round(E/J*z);N.fillRect(R,U,C,-E)}else{if(I==="Intensity"){E=255-Math.floor((E-H)/J*255);N.fillStyle="rgb("+E+","+E+","+E+")";N.fillRect(R,0,C,z)}else{E=Math.round(z-(E-H)/J*z);if(F){N.lineTo(R,E)}else{F=true;if(I==="Filled"){N.moveTo(R,z);N.lineTo(R,E)}else{N.moveTo(R,E)}}}}N.fillStyle=this.prefs.overflow_color;if(Q||G){var S;if(I==="Histogram"||I==="Intensity"){S=C}else{R-=2;S=4}if(Q){N.fillRect(R,0,S,3)}if(G){N.fillRect(R,z-3,S,3)}}N.fillStyle=this.prefs.color}if(I==="Filled"){if(F){N.lineTo(R,U);N.lineTo(0,U)}N.fill()}else{N.stroke()}N.restore()};var o=function(z){this.feature_positions={};this.slot_height=z;this.translation=0};o.prototype.map_feature_data=function(A,C,z,B){if(!this.feature_positions[C]){this.feature_positions[C]=[]}this.feature_positions[C].push({data:A,x_start:z,x_end:B})};o.prototype.get_feature_data=function(z,D){var C=Math.floor(D/this.slot_height),B;if(!this.feature_positions[C]){return null}z+=this.translation;for(var A=0;A<this.feature_positions[C].length;A++){B=this.feature_positions[C][A];if(z>=B.x_start&&z<=B.x_end){return B.data}}};var p=function(B,E,z,A,D,F,C){n.call(this,B,E,z,A,D);this.alpha_scaler=(F?F:new e());this.height_scaler=(C?C:new e())};p.prototype.default_prefs={block_color:"#FFF",connector_color:"#FFF"};v(p.prototype,{get_required_height:function(A){var z=y_scale=this.get_row_height(),B=this.mode;if(B==="no_detail"||B==="Squish"||B==="Pack"){z=A*y_scale}return z+Math.max(Math.round(y_scale/2),5)},draw:function(L,J,H,G){var R=this.data,E=this.view_start,N=this.view_end;L.save();L.fillStyle=this.prefs.block_color;L.textAlign="right";var I=this.view_end-this.view_start,F=J/I,M=this.get_row_height(),Q=new o(M),C;for(var O=0,P=R.length;O<P;O++){var B=R[O],D=B[0],K=B[1],z=B[2],A=(G&&G[D]!==undefined?G[D]:null);if((K<N&&z>E)&&(this.mode=="Dense"||A!==null)){C=this.draw_element(L,this.mode,B,A,E,N,F,M,J);Q.map_feature_data(B,A,C[0],C[1])}}L.restore();return Q},draw_element:function(F,B,H,D,C,E,G,A,z){console.log("WARNING: Unimplemented function.");return[0,0]}});var d=10,j=3,m=5,x=10,g=1,t=3,f=3,a=9,l=2,h="#ccc";var s=function(B,E,z,A,D,F,C){p.call(this,B,E,z,A,D,F,C)};v(s.prototype,p.prototype,{get_row_height:function(){var A=this.mode,z;if(A==="Dense"){z=d}else{if(A==="no_detail"){z=j}else{if(A==="Squish"){z=m}else{z=x}}}return z},draw_element:function(N,E,W,I,P,ah,al,an,z){var T=W[0],aj=W[1],ab=W[2],R=W[3],ac=Math.floor(Math.max(0,(aj-P)*al)),O=Math.ceil(Math.min(z,Math.max(0,(ab-P)*al))),aa=ac,am=O,Z=(E==="Dense"?0:(0+I))*an,M,af,S=null,ap=null,C=this.prefs.block_color,ae=this.prefs.label_color;N.globalAlpha=this.alpha_scaler.gen_val(W);if(E=="Dense"){I=1}if(E==="no_detail"){N.fillStyle=C;N.fillRect(ac,Z+5,O-ac,g)}else{var L=W[4],Y=W[5],ad=W[6],D=W[7];if(Y&&ad){S=Math.floor(Math.max(0,(Y-P)*al));ap=Math.ceil(Math.min(z,Math.max(0,(ad-P)*al)))}var ak,U;if(E==="Squish"||E==="Dense"){ak=1;U=f}else{ak=5;U=a}if(!D){if(W.strand){if(W.strand==="+"){N.fillStyle=N.canvas.manager.get_pattern("right_strand_inv")}else{if(W.strand==="-"){N.fillStyle=N.canvas.manager.get_pattern("left_strand_inv")}}}else{N.fillStyle=C}N.fillRect(ac,Z,O-ac,U)}else{var K,V;if(E==="Squish"||E==="Dense"){N.fillStyle=h;K=Z+Math.floor(f/2)+1;V=1}else{if(L){var K=Z;var V=U;if(L==="+"){N.fillStyle=N.canvas.manager.get_pattern("right_strand")}else{if(L==="-"){N.fillStyle=N.canvas.manager.get_pattern("left_strand")}}}else{N.fillStyle=h;K+=(f/2)+1;V=1}}N.fillRect(ac,K,O-ac,V);var F;for(var ai=0,B=D.length;ai<B;ai++){var G=D[ai],A=Math.floor(Math.max(0,(G[0]-P)*al)),X=Math.ceil(Math.min(z,Math.max((G[1]-P)*al)));if(A>X){continue}N.fillStyle=C;N.fillRect(A,Z+(U-ak)/2+1,X-A,ak);if(S!==undefined&&ad>Y&&!(A>ap||X<S)){var ag=Math.max(A,S),J=Math.min(X,ap);N.fillRect(ag,Z+1,J-ag,U);if(D.length==1&&E=="Pack"){if(L==="+"){N.fillStyle=N.canvas.manager.get_pattern("right_strand_inv")}else{if(L==="-"){N.fillStyle=N.canvas.manager.get_pattern("left_strand_inv")}}if(ag+14<J){ag+=2;J-=2}N.fillRect(ag,Z+1,J-ag,U)}}}if(E==="Pack"){N.globalAlpha=1;N.fillStyle="white";var H=this.height_scaler.gen_val(W),Q=Math.ceil(U*H),ao=Math.round((U-Q)/2);if(H!==1){N.fillRect(ac,K+1,O-ac,ao);N.fillRect(ac,K+U-ao+1,O-ac,ao)}}}N.globalAlpha=1;if(E==="Pack"&&aj>P){N.fillStyle=ae;if(P===0&&ac-N.measureText(R).width<0){N.textAlign="left";N.fillText(R,O+l,Z+8);am+=N.measureText(R).width+l}else{N.textAlign="right";N.fillText(R,ac-l,Z+8);aa-=N.measureText(R).width+l}}}N.globalAlpha=1;return[aa,am]}});var b=function(B,E,z,A,D,F,C){p.call(this,B,E,z,A,D,F,C)};v(b.prototype,p.prototype,{draw_element:function(S,N,H,D,V,B,K,T,Q){var H=data[i],J=H[0],R=H[1],C=H[2],M=H[3],F=Math.floor(Math.max(0,(R-V)*K)),I=Math.ceil(Math.min(Q,Math.max(0,(C-V)*K))),E=(N==="Dense"?0:(0+D))*T,z,W,A=null,L=null;if(no_label){S.fillStyle=block_color;S.fillRect(F+left_offset,E+5,I-F,1)}else{var U=H[4],P=H[5],G=H[6];z=9;W=1;S.fillRect(F+left_offset,E,I-F,z);if(N!=="Dense"&&M!==undefined&&R>V){S.fillStyle=label_color;if(V===0&&F-S.measureText(M).width<0){S.textAlign="left";S.fillText(M,I+2+left_offset,E+8)}else{S.textAlign="right";S.fillText(M,F-2+left_offset,E+8)}S.fillStyle=block_color}var O=U+" / "+P;if(R>V&&S.measureText(O).width<(I-F)){S.fillStyle="white";S.textAlign="center";S.fillText(O,left_offset+F+(I-F)/2,E+8);S.fillStyle=block_color}}return[F,I]}});var u=function(C,F,z,B,E,G,D,A){p.call(this,C,F,z,B,E,G,D);this.ref_seq=A};u.prototype.default_prefs=v({},p.prototype.default_prefs,{show_insertions:false});v(u.prototype,p.prototype,{get_row_height:function(){var z,A=this.mode;if(A==="Dense"){z=d}else{if(A==="Squish"){z=m}else{z=x;if(this.prefs.show_insertions){z*=2}}}return z},draw_read:function(V,Q,M,aa,B,U,J,G,F){V.textAlign="center";var T=this,A=[aa,B],P=0,W=0,S=0;ref_seq=this.ref_seq.data,char_width_px=V.canvas.manager.char_width_px;var af=[];if((Q==="Pack"||this.mode==="Auto")&&G!==undefined&&M>char_width_px){S=Math.round(M/2)}if(!J){J=[[0,G.length]]}for(var N=0,Y=J.length;N<Y;N++){var K=J[N],C="MIDNSHP=X"[K[0]],O=K[1];if(C==="H"||C==="S"){P-=O}var H=U+P,ae=Math.floor(Math.max(0,(H-aa)*M)),I=Math.floor(Math.max(0,(H+O-aa)*M));if(ae===I){I+=1}switch(C){case"H":break;case"S":case"M":case"=":if(is_overlap([H,H+O],A)){var R=G.slice(W,W+O);if(S>0){V.fillStyle=this.prefs.block_color;V.fillRect(ae-S,F+1,I-ae,9);V.fillStyle=h;for(var ac=0,z=R.length;ac<z;ac++){if(this.prefs.show_differences&&ref_seq){var L=ref_seq[H-aa+ac];if(!L||L.toLowerCase()===R[ac].toLowerCase()){continue}}if(H+ac>=aa&&H+ac<=B){var ad=Math.floor(Math.max(0,(H+ac-aa)*M));V.fillText(R[ac],ad,F+9)}}}else{V.fillStyle=this.prefs.block_color;V.fillRect(ae,F+4,I-ae,f)}}W+=O;P+=O;break;case"N":V.fillStyle=h;V.fillRect(ae-S,F+5,I-ae,1);P+=O;break;case"D":V.fillStyle="red";V.fillRect(ae-S,F+4,I-ae,3);P+=O;break;case"P":break;case"I":var Z=ae-S;if(is_overlap([H,H+O],A)){var R=G.slice(W,W+O);if(this.prefs.show_insertions){var E=ae-(I-ae)/2;if((Q==="Pack"||this.mode==="Auto")&&G!==undefined&&M>char_width_px){V.fillStyle="yellow";V.fillRect(E-S,F-9,I-ae,9);af[af.length]={type:"triangle",data:[Z,F+4,5]};V.fillStyle=h;switch(seq_tile_overlap){case (OVERLAP_START):R=R.slice(aa-H);break;case (OVERLAP_END):R=R.slice(0,H-B);break;case (CONTAINED_BY):break;case (CONTAINS):R=R.slice(aa-H,H-B);break}for(var ac=0,z=R.length;ac<z;ac++){var ad=Math.floor(Math.max(0,(H+ac-aa)*M));V.fillText(R[ac],ad-(I-ae)/2,F)}}else{V.fillStyle="yellow";V.fillRect(E,F+(this.mode!=="Dense"?2:5),I-ae,(Q!=="Dense"?f:t))}}else{if((Q==="Pack"||this.mode==="Auto")&&G!==undefined&&M>char_width_px){af[af.length]={type:"text",data:[R.length,Z,F+9]}}else{}}}W+=O;break;case"X":W+=O;break}}V.fillStyle="yellow";var ab,D,ag;for(var X=0;X<af.length;X++){ab=af[X];D=ab.type;ag=ab.data;if(D==="text"){V.save();V.font="bold "+V.font;V.fillText(ag[0],ag[1],ag[2]);V.restore()}else{if(D=="triangle"){r(V,ag[0],ag[1],ag[2])}}}},draw_element:function(S,N,F,C,V,A,J,T,Q){var I=F[0],R=F[1],B=F[2],K=F[3],E=Math.floor(Math.max(0,(R-V)*J)),G=Math.ceil(Math.min(Q,Math.max(0,(B-V)*J))),D=(N==="Dense"?0:(0+C))*T,W=this.prefs.block_color,H=this.prefs.label_color,P=0;if((N==="Pack"||this.mode==="Auto")&&J>S.canvas.manager.char_width_px){var P=Math.round(J/2)}S.fillStyle=W;if(F[5] instanceof Array){var O=Math.floor(Math.max(0,(F[4][0]-V)*J)),M=Math.ceil(Math.min(Q,Math.max(0,(F[4][1]-V)*J))),L=Math.floor(Math.max(0,(F[5][0]-V)*J)),z=Math.ceil(Math.min(Q,Math.max(0,(F[5][1]-V)*J)));if(F[4][1]>=V&&F[4][0]<=A&&F[4][2]){this.draw_read(S,N,J,V,A,F[4][0],F[4][2],F[4][3],D)}if(F[5][1]>=V&&F[5][0]<=A&&F[5][2]){this.draw_read(S,N,J,V,A,F[5][0],F[5][2],F[5][3],D)}if(L>M){S.fillStyle=h;q(S,M-P,D+5,L-P,D+5)}}else{S.fillStyle=W;this.draw_read(S,N,J,V,A,R,F[4],F[5],D)}if(N==="Pack"&&R>V){S.fillStyle=this.prefs.label_color;var U=1;if(U===0&&E-S.measureText(K).width<0){S.textAlign="left";S.fillText(K,G+l-P,D+8)}else{S.textAlign="right";S.fillText(K,E-l-P,D+8)}S.fillStyle=W}return[0,0]}});y.Scaler=e;y.SummaryTreePainter=w;y.LinePainter=c;y.LinkedFeaturePainter=s;y.ReadPainter=u;y.VariantPainter=b};(function(d){var c={};var b=function(e){return c[e]};var a=function(f,g){var e={};g(b,e);c[f]=e};a("class",class_module);a("slotting",slotting_module);a("painters",painters_module);a("trackster",trackster_module);for(key in c.trackster){d[key]=c.trackster[key]}})(window); \ No newline at end of file +var class_module=function(b,a){var c=function(){var f=arguments[0];for(var e=1;e<arguments.length;e++){var d=arguments[e];for(key in d){f[key]=d[key]}}return f};a.extend=c};var requestAnimationFrame=(function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(b,a){window.setTimeout(b,1000/60)}})();var BEFORE=1001,CONTAINS=1002,OVERLAP_START=1003,OVERLAP_END=1004,CONTAINED_BY=1005,AFTER=1006;var compute_overlap=function(e,b){var g=e[0],f=e[1],d=b[0],c=b[1],a;if(g<d){if(f<d){a=BEFORE}else{if(f<=c){a=OVERLAP_START}else{a=CONTAINS}}}else{if(g>c){a=AFTER}else{if(f<=c){a=CONTAINED_BY}else{a=OVERLAP_END}}}return a};var is_overlap=function(c,b){var a=compute_overlap(c,b);return(a!==BEFORE&&a!==AFTER)};var get_random_color=function(a){if(!a){a="#ffffff"}if(typeof(a)==="string"){a=[a]}for(var j=0;j<a.length;j++){a[j]=parseInt(a[j].slice(1),16)}var m=function(u,t,s){return((u*299)+(t*587)+(s*114))/1000};var e=function(v,u,w,s,r,t){return(Math.max(v,s)-Math.min(v,s))+(Math.max(u,r)-Math.min(u,r))+(Math.max(w,t)-Math.min(w,t))};var g,n,f,k,p,h,q,c,d,b,o,l=false;do{g=Math.random()*16777215;n=g|16711680;f=g|65280;k=g|255;d=m(n,f,k);l=true;for(var j=0;j<a.length;j++){p=a[j];h=p|16711680;q=p|65280;c=p|255;b=m(h,q,c);o=e(n,f,k,h,q,c);if((Math.abs(d-b)<125)||(o<500)){l=false;break}}}while(!l);return"#"+(16777216+g).toString(16).substr(1,6)};var trackster_module=function(f,Z){var q=f("class").extend,t=f("slotting"),N=f("painters");var ag=function(ah,ai){this.document=ah;this.default_font=ai!==undefined?ai:"9px Monaco, Lucida Console, monospace";this.dummy_canvas=this.new_canvas();this.dummy_context=this.dummy_canvas.getContext("2d");this.dummy_context.font=this.default_font;this.char_width_px=this.dummy_context.measureText("A").width;this.patterns={};this.load_pattern("right_strand","/visualization/strand_right.png");this.load_pattern("left_strand","/visualization/strand_left.png");this.load_pattern("right_strand_inv","/visualization/strand_right_inv.png");this.load_pattern("left_strand_inv","/visualization/strand_left_inv.png")};q(ag.prototype,{load_pattern:function(ah,al){var ai=this.patterns,aj=this.dummy_context,ak=new Image();ak.src=image_path+al;ak.onload=function(){ai[ah]=aj.createPattern(ak,"repeat")}},get_pattern:function(ah){return this.patterns[ah]},new_canvas:function(){var ah=this.document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(ah)}ah.manager=this;return ah}});var o={};var m=function(ah,ai){o[ah.attr("id")]=ai};var n=function(ah,aj,al,ak){al=".group";var ai={};o[ah.attr("id")]=ak;ah.bind("drag",{handle:"."+aj,relative:true},function(au,av){var at=$(this);var ay=$(this).parent(),ap=ay.children(),ar=o[$(this).attr("id")],ao,an,aw,am,aq;an=$(this).parents(al);if(an.length!==0){aw=an.position().top;am=aw+an.outerHeight();if(av.offsetY<aw){$(this).insertBefore(an);var ax=o[an.attr("id")];ax.remove_drawable(ar);ax.container.add_drawable_before(ar,ax);return}else{if(av.offsetY>am){$(this).insertAfter(an);var ax=o[an.attr("id")];ax.remove_drawable(ar);ax.container.add_drawable(ar);return}}}an=null;for(aq=0;aq<ap.length;aq++){ao=$(ap.get(aq));aw=ao.position().top;am=aw+ao.outerHeight();if(ao.is(al)&&this!==ao.get(0)&&av.offsetY>=aw&&av.offsetY<=am){if(av.offsetY-aw<am-av.offsetY){ao.find(".content-div").prepend(this)}else{ao.find(".content-div").append(this)}if(ar.container){ar.container.remove_drawable(ar)}o[ao.attr("id")].add_drawable(ar);return}}for(aq=0;aq<ap.length;aq++){if(av.offsetY<$(ap.get(aq)).position().top){break}}if(aq===ap.length){if(this!==ap.get(aq-1)){ay.append(this);o[ay.attr("id")].move_drawable(ar,aq)}}else{if(this!==ap.get(aq)){$(this).insertBefore(ap.get(aq));o[ay.attr("id")].move_drawable(ar,(av.deltaY>0?aq-1:aq))}}}).bind("dragstart",function(){ai["border-top"]=ah.css("border-top");ai["border-bottom"]=ah.css("border-bottom");$(this).css({"border-top":"1px solid blue","border-bottom":"1px solid blue"})}).bind("dragend",function(){$(this).css(ai)})};Z.moveable=n;var af=16,I=9,F=20,U=I+2,A=100,K=12000,S=200,D=5,w=10,M=5000,x=100,p="There was an error in indexing this dataset. ",L="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",G="No data for this chrom/contig.",u="Currently indexing... please wait",y="Tool cannot be rerun: ",a="Loading data...",aa="Ready for display",d=10,v=5,C=5;function ab(ai,ah){if(!ah){ah=0}var aj=Math.pow(10,ah);return Math.round(ai*aj)/aj}var c=function(ah){this.num_elements=ah;this.clear()};q(c.prototype,{get:function(ai){var ah=this.key_ary.indexOf(ai);if(ah!==-1){if(this.obj_cache[ai].stale){this.key_ary.splice(ah,1);delete this.obj_cache[ai]}else{this.move_key_to_end(ai,ah)}}return this.obj_cache[ai]},set:function(ai,aj){if(!this.obj_cache[ai]){if(this.key_ary.length>=this.num_elements){var ah=this.key_ary.shift();delete this.obj_cache[ah]}this.key_ary.push(ai)}this.obj_cache[ai]=aj;return aj},move_key_to_end:function(ai,ah){this.key_ary.splice(ah,1);this.key_ary.push(ai)},clear:function(){this.obj_cache={};this.key_ary=[]},size:function(){return this.key_ary.length}});var T=function(ai,ah,aj){c.call(this,ai);this.track=ah;this.subset=(aj!==undefined?aj:true)};q(T.prototype,c.prototype,{load_data:function(aq,al,ao,ai,an){var ap=this.track.view.chrom,ak={chrom:ap,low:aq,high:al,mode:ao,resolution:ai,dataset_id:this.track.dataset_id,hda_ldda:this.track.hda_ldda};$.extend(ak,an);if(this.track.filters_manager){var ar=[];var ah=this.track.filters_manager.filters;for(var am=0;am<ah.length;am++){ar[ar.length]=ah[am].name}ak.filter_cols=JSON.stringify(ar)}var aj=this;return $.getJSON(this.track.data_url,ak,function(at){aj.set_data(aq,al,ao,at)})},get_data:function(ah,al,am,ai,ak){var aj=this.get_data_from_cache(ah,al,am);if(aj){return aj}aj=this.load_data(ah,al,am,ai,ak);this.set_data(ah,al,am,aj);return aj},DEEP_DATA_REQ:"deep",BROAD_DATA_REQ:"breadth",get_more_data:function(ap,ak,ao,aj,an,al){var aq=this.get_data_from_cache(ap,ak,ao);if(!aq){console.log("ERROR: no current data for: ",this.track,ap,ak,ao,aj,an);return}aq.stale=true;var ai=ap;if(al===this.DEEP_DATA_REQ){$.extend(an,{start_val:aq.data.length+1})}else{if(al===this.BROAD_DATA_REQ){ai=(aq.max_high?aq.max_high:aq.data[aq.data.length-1][2])+1}}var ah=this,am=this.load_data(ai,ak,ao,aj,an);new_data_available=$.Deferred();this.set_data(ap,ak,ao,new_data_available);$.when(am).then(function(ar){if(ar.data){ar.data=aq.data.concat(ar.data);if(ar.max_low){ar.max_low=aq.max_low}if(ar.message){ar.message=ar.message.replace(/[0-9]+/,ar.data.length)}}ah.set_data(ap,ak,ao,ar);new_data_available.resolve(ar)});return new_data_available},get_data_from_cache:function(ah,ai,aj){return this.get(this.gen_key(ah,ai,aj))},set_data:function(ai,aj,ak,ah){return this.set(this.gen_key(ai,aj,ak),ah)},gen_key:function(ah,aj,ak){var ai=ah+"_"+aj+"_"+ak;return ai},split_key:function(ah){return ah.split("_")}});var J=function(ai,ah,aj){T.call(this,ai,ah,aj)};q(J.prototype,T.prototype,c.prototype,{load_data:function(ah,ak,al,ai,aj){if(ai>1){return{data:null}}return T.prototype.load_data.call(this,ah,ak,al,ai,aj)}});var r=function(ak,ai,ah,aj,al){this.name=ak;this.view=ai;this.container=ah;this.config=new H({track:this,params:[{key:"name",label:"Name",type:"text",default_value:ak}],saved_values:aj,onchange:function(){this.track.set_name(this.track.config.values.name)}});this.prefs=this.config.values;this.drag_handle_class=al;this.is_overview=false};q(r.prototype,{init:function(){},request_draw:function(){},_draw:function(){},to_json:function(){},update_track_icons:function(){},set_name:function(ah){this.old_name=this.name;this.name=ah;this.name_div.text(this.name)},revert_name:function(){this.name=this.old_name;this.name_div.text(this.name)},remove:function(){this.container.remove_drawable(this);this.container_div.fadeOut("slow",function(){$(this).remove();view.update_intro_div();view.has_changes=true})}});var z=function(al,ak,ai,ah,aj,am){r.call(this,ak,ai,ah,aj,am);this.obj_type=al;this.drawables=[]};q(z.prototype,r.prototype,{init:function(){for(var ah=0;ah<this.drawables.length;ah++){this.drawables[ah].init()}},_draw:function(){for(var ah=0;ah<this.drawables.length;ah++){this.drawables[ah]._draw()}},to_json:function(){var ai=[];for(var ah=0;ah<this.drawables.length;ah++){ai.push(this.drawables[ah].to_json())}return{name:this.name,prefs:this.prefs,obj_type:this.obj_type,drawables:ai}},add_drawable:function(ah){this.drawables.push(ah);ah.container=this},add_drawable_before:function(aj,ah){var ai=this.drawables.indexOf(ah);if(ai!=-1){this.drawables.splice(ai,0,aj);return true}return false},remove_drawable:function(ai){var ah=this.drawables.indexOf(ai);if(ah!=-1){this.drawables.splice(ah,1);ai.container=null;return true}return false},move_drawable:function(ai,aj){var ah=this.drawables.indexOf(ai);if(ah!=-1){this.drawables.splice(ah,1);this.drawables.splice(aj,0,ai);return true}return false}});var R=function(ak,ai,ah,aj){z.call(this,"DrawableGroup",ak,ai,ah,aj,"group-handle");if(!R.id_counter){R.id_counter=0}var al=R.id_counter++;this.container_div=$("<div/>").addClass("group").attr("id","group_"+al).appendTo(this.container.content_div);this.header_div=$("<div/>").addClass("track-header").appendTo(this.container_div);this.header_div.append($("<div/>").addClass(this.drag_handle_class));this.name_div=$("<div/>").addClass("group-name menubutton popup").text(this.name).appendTo(this.header_div);this.content_div=$("<div/>").addClass("content-div").attr("id","group_"+al+"_content_div").appendTo(this.container_div);m(this.container_div,this);m(this.content_div,this);n(this.container_div,this.drag_handle_class,".group",this);this.update_track_icons()};q(R.prototype,r.prototype,z.prototype,{update_track_icons:function(){var ai=this;var ah={};ah["Edit configuration"]=function(){var al=function(){hide_modal();$(window).unbind("keypress.check_enter_esc")},aj=function(){ai.config.update_from_form($(".dialog-box"));hide_modal();$(window).unbind("keypress.check_enter_esc")},ak=function(am){if((am.keyCode||am.which)===27){al()}else{if((am.keyCode||am.which)===13){aj()}}};$(window).bind("keypress.check_enter_esc",ak);show_modal("Configure Group",ai.config.build_form(),{Cancel:al,OK:aj})};ah.Remove=function(){ai.remove()};make_popupmenu(ai.name_div,ah)}});var ae=function(ah,ak,aj,ai){z.call(this,"View");this.container=ah;this.chrom=null;this.vis_id=aj;this.dbkey=ai;this.title=ak;this.label_tracks=[];this.tracks_to_be_redrawn=[];this.max_low=0;this.max_high=0;this.zoom_factor=3;this.min_separation=30;this.has_changes=false;this.load_chroms_deferred=null;this.init();this.canvas_manager=new ag(ah.get(0).ownerDocument);this.reset()};q(ae.prototype,z.prototype,{init:function(){var aj=this.container,ah=this;this.top_container=$("<div/>").addClass("top-container").appendTo(aj);this.browser_content_div=$("<div/>").addClass("content").css("position","relative").appendTo(aj);this.bottom_container=$("<div/>").addClass("bottom-container").appendTo(aj);this.top_labeltrack=$("<div/>").addClass("top-labeltrack").appendTo(this.top_container);this.viewport_container=$("<div/>").addClass("viewport-container").attr("id","viewport-container").appendTo(this.browser_content_div);this.content_div=this.viewport_container;m(this.viewport_container,ah);this.intro_div=$("<div/>").addClass("intro");var ak=$("<div/>").text("Add Datasets to Visualization").addClass("action-button").appendTo(this.intro_div).click(function(){add_tracks()});this.nav_labeltrack=$("<div/>").addClass("nav-labeltrack").appendTo(this.bottom_container);this.nav_container=$("<div/>").addClass("nav-container").prependTo(this.top_container);this.nav=$("<div/>").addClass("nav").appendTo(this.nav_container);this.overview=$("<div/>").addClass("overview").appendTo(this.bottom_container);this.overview_viewport=$("<div/>").addClass("overview-viewport").appendTo(this.overview);this.overview_close=$("<a/>").attr("href","javascript:void(0);").attr("title","Close overview").addClass("icon-button overview-close tooltip").hide().appendTo(this.overview_viewport);this.overview_highlight=$("<div/>").addClass("overview-highlight").hide().appendTo(this.overview_viewport);this.overview_box_background=$("<div/>").addClass("overview-boxback").appendTo(this.overview_viewport);this.overview_box=$("<div/>").addClass("overview-box").appendTo(this.overview_viewport);this.default_overview_height=this.overview_box.height();this.nav_controls=$("<div/>").addClass("nav-controls").appendTo(this.nav);this.chrom_select=$("<select/>").attr({name:"chrom"}).css("width","15em").addClass("no-autocomplete").append("<option value=''>Loading</option>").appendTo(this.nav_controls);var ai=function(al){if(al.type==="focusout"||(al.keyCode||al.which)===13||(al.keyCode||al.which)===27){if((al.keyCode||al.which)!==27){ah.go_to($(this).val())}$(this).hide();$(this).val("");ah.location_span.show();ah.chrom_select.show()}};this.nav_input=$("<input/>").addClass("nav-input").hide().bind("keyup focusout",ai).appendTo(this.nav_controls);this.location_span=$("<span/>").addClass("location").appendTo(this.nav_controls);this.location_span.click(function(){ah.location_span.hide();ah.chrom_select.hide();ah.nav_input.val(ah.chrom+":"+ah.low+"-"+ah.high);ah.nav_input.css("display","inline-block");ah.nav_input.select();ah.nav_input.focus()});if(this.vis_id!==undefined){this.hidden_input=$("<input/>").attr("type","hidden").val(this.vis_id).appendTo(this.nav_controls)}this.zo_link=$("<a id='zoom-out' />").click(function(){ah.zoom_out();ah.request_redraw()}).appendTo(this.nav_controls);this.zi_link=$("<a id='zoom-in' />").click(function(){ah.zoom_in();ah.request_redraw()}).appendTo(this.nav_controls);this.load_chroms_deferred=this.load_chroms({low:0});this.chrom_select.bind("change",function(){ah.change_chrom(ah.chrom_select.val())});this.browser_content_div.click(function(al){$(this).find("input").trigger("blur")});this.browser_content_div.bind("dblclick",function(al){ah.zoom_in(al.pageX,this.viewport_container)});this.overview_box.bind("dragstart",function(al,am){this.current_x=am.offsetX}).bind("drag",function(al,an){var ao=an.offsetX-this.current_x;this.current_x=an.offsetX;var am=Math.round(ao/ah.viewport_container.width()*(ah.max_high-ah.max_low));ah.move_delta(-am)});this.overview_close.click(function(){ah.reset_overview()});this.viewport_container.bind("draginit",function(al,am){if(al.clientX>ah.viewport_container.width()-16){return false}}).bind("dragstart",function(al,am){am.original_low=ah.low;am.current_height=al.clientY;am.current_x=am.offsetX}).bind("drag",function(an,ap){var al=$(this);var aq=ap.offsetX-ap.current_x;var am=al.scrollTop()-(an.clientY-ap.current_height);al.scrollTop(am);ap.current_height=an.clientY;ap.current_x=ap.offsetX;var ao=Math.round(aq/ah.viewport_container.width()*(ah.high-ah.low));ah.move_delta(ao)}).bind("mousewheel",function(an,ap,am,al){if(am){var ao=Math.round(-am/ah.viewport_container.width()*(ah.high-ah.low));ah.move_delta(ao)}});this.top_labeltrack.bind("dragstart",function(al,am){return $("<div />").css({height:ah.browser_content_div.height()+ah.top_labeltrack.height()+ah.nav_labeltrack.height()+1,top:"0px",position:"absolute","background-color":"#ccf",opacity:0.5,"z-index":1000}).appendTo($(this))}).bind("drag",function(ap,aq){$(aq.proxy).css({left:Math.min(ap.pageX,aq.startX),width:Math.abs(ap.pageX-aq.startX)});var am=Math.min(ap.pageX,aq.startX)-ah.container.offset().left,al=Math.max(ap.pageX,aq.startX)-ah.container.offset().left,ao=(ah.high-ah.low),an=ah.viewport_container.width();ah.update_location(Math.round(am/an*ao)+ah.low,Math.round(al/an*ao)+ah.low)}).bind("dragend",function(aq,ar){var am=Math.min(aq.pageX,ar.startX),al=Math.max(aq.pageX,ar.startX),ao=(ah.high-ah.low),an=ah.viewport_container.width(),ap=ah.low;ah.low=Math.round(am/an*ao)+ap;ah.high=Math.round(al/an*ao)+ap;$(ar.proxy).remove();ah.request_redraw()});this.add_label_track(new ad(this,{content_div:this.top_labeltrack}));this.add_label_track(new ad(this,{content_div:this.nav_labeltrack}));$(window).bind("resize",function(){ah.resize_window()});$(document).bind("redraw",function(){ah.redraw()});this.reset();$(window).trigger("resize");this.update_intro_div()},update_intro_div:function(){if(this.num_tracks===0){this.intro_div.appendTo(this.viewport_container)}else{this.intro_div.remove()}},update_location:function(ah,ai){this.location_span.text(commatize(ah)+" - "+commatize(ai));this.nav_input.val(this.chrom+":"+commatize(ah)+"-"+commatize(ai))},load_chroms:function(aj){aj.num=x;$.extend(aj,(this.vis_id!==undefined?{vis_id:this.vis_id}:{dbkey:this.dbkey}));var ah=this,ai=$.Deferred();$.ajax({url:chrom_url,data:aj,dataType:"json",success:function(al){if(al.chrom_info.length===0){alert("Invalid chromosome: "+aj.chrom);return}if(al.reference){ah.add_label_track(new B(ah))}ah.chrom_data=al.chrom_info;var ao='<option value="">Select Chrom/Contig</option>';for(var an=0,ak=ah.chrom_data.length;an<ak;an++){var am=ah.chrom_data[an].chrom;ao+='<option value="'+am+'">'+am+"</option>"}if(al.prev_chroms){ao+='<option value="previous">Previous '+x+"</option>"}if(al.next_chroms){ao+='<option value="next">Next '+x+"</option>"}ah.chrom_select.html(ao);ah.chrom_start_index=al.start_index;ai.resolve(al)},error:function(){alert("Could not load chroms for this dbkey:",ah.dbkey)}});return ai},change_chrom:function(am,ai,ao){if(!am||am==="None"){return}var aj=this;if(am==="previous"){aj.load_chroms({low:this.chrom_start_index-x});return}if(am==="next"){aj.load_chroms({low:this.chrom_start_index+x});return}var an=$.grep(aj.chrom_data,function(ap,aq){return ap.chrom===am})[0];if(an===undefined){aj.load_chroms({chrom:am},function(){aj.change_chrom(am,ai,ao)});return}else{if(am!==aj.chrom){aj.chrom=am;aj.chrom_select.val(aj.chrom);aj.max_high=an.len-1;aj.reset();aj.request_redraw(true);for(var al=0,ah=aj.drawables.length;al<ah;al++){var ak=aj.drawables[al];if(ak.init){ak.init()}}}if(ai!==undefined&&ao!==undefined){aj.low=Math.max(ai,0);aj.high=Math.min(ao,aj.max_high)}aj.reset_overview();aj.request_redraw()}},go_to:function(al){var ap=this,ah,ak,ai=al.split(":"),an=ai[0],ao=ai[1];if(ao!==undefined){try{var am=ao.split("-");ah=parseInt(am[0].replace(/,/g,""),10);ak=parseInt(am[1].replace(/,/g,""),10)}catch(aj){return false}}ap.change_chrom(an,ah,ak)},move_fraction:function(aj){var ah=this;var ai=ah.high-ah.low;this.move_delta(aj*ai)},move_delta:function(aj){var ah=this;var ai=ah.high-ah.low;if(ah.low-aj<ah.max_low){ah.low=ah.max_low;ah.high=ah.max_low+ai}else{if(ah.high-aj>ah.max_high){ah.high=ah.max_high;ah.low=ah.max_high-ai}else{ah.high-=aj;ah.low-=aj}}ah.request_redraw()},add_drawable:function(ah){z.prototype.add_drawable.call(this,ah);ah.init();this.has_changes=true;this.update_intro_div()},add_label_track:function(ah){ah.view=this;ah.init();this.label_tracks.push(ah)},remove_drawable:function(aj,ai){z.prototype.remove_drawable.call(this,aj);if(ai){var ah=this;aj.container_div.fadeOut("slow",function(){$(this).remove();ah.update_intro_div()});this.has_changes=true}},reset:function(){this.low=this.max_low;this.high=this.max_high;this.viewport_container.find(".yaxislabel").remove()},request_redraw:function(ap,ah,ao,ai){var an=this,al=(ai?[ai]:an.drawables),aj;var ai;for(var am=0;am<al.length;am++){ai=al[am];aj=-1;for(var ak=0;ak<an.tracks_to_be_redrawn.length;ak++){if(an.tracks_to_be_redrawn[ak][0]===ai){aj=ak;break}}if(aj<0){an.tracks_to_be_redrawn.push([ai,ah,ao])}else{an.tracks_to_be_redrawn[am][1]=ah;an.tracks_to_be_redrawn[am][2]=ao}}requestAnimationFrame(function(){an._redraw(ap)})},_redraw:function(ar){var ao=this.low,ak=this.high;if(ao<this.max_low){ao=this.max_low}if(ak>this.max_high){ak=this.max_high}var aq=this.high-this.low;if(this.high!==0&&aq<this.min_separation){ak=ao+this.min_separation}this.low=Math.floor(ao);this.high=Math.ceil(ak);this.resolution=Math.pow(D,Math.ceil(Math.log((this.high-this.low)/S)/Math.log(D)));this.zoom_res=Math.pow(w,Math.max(0,Math.ceil(Math.log(this.resolution,w)/Math.log(w))));var ah=(this.low/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var an=((this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var at=13;this.overview_box.css({left:ah,width:Math.max(at,an)}).show();if(an<at){this.overview_box.css("left",ah-(at-an)/2)}if(this.overview_highlight){this.overview_highlight.css({left:ah,width:an})}this.update_location(this.low,this.high);if(!ar){var aj,ai,ap;for(var al=0,am=this.tracks_to_be_redrawn.length;al<am;al++){aj=this.tracks_to_be_redrawn[al][0];ai=this.tracks_to_be_redrawn[al][1];ap=this.tracks_to_be_redrawn[al][2];if(aj){aj._draw(ai,ap)}}this.tracks_to_be_redrawn=[];for(al=0,am=this.label_tracks.length;al<am;al++){this.label_tracks[al]._draw()}}},zoom_in:function(ai,aj){if(this.max_high===0||this.high-this.low<this.min_separation){return}var ak=this.high-this.low,al=ak/2+this.low,ah=(ak/this.zoom_factor)/2;if(ai){al=ai/this.viewport_container.width()*(this.high-this.low)+this.low}this.low=Math.round(al-ah);this.high=Math.round(al+ah);this.request_redraw()},zoom_out:function(){if(this.max_high===0){return}var ai=this.high-this.low,aj=ai/2+this.low,ah=(ai*this.zoom_factor)/2;this.low=Math.round(aj-ah);this.high=Math.round(aj+ah);this.request_redraw()},resize_window:function(){this.viewport_container.height(this.container.height()-this.top_container.height()-this.bottom_container.height());this.nav_container.width(this.container.width());this.request_redraw()},set_overview:function(aj){if(this.overview_drawable){if(this.overview_drawable.dataset_id===aj.dataset_id){return}this.overview_viewport.find(".track").remove()}var ai=aj.copy({content_div:this.overview_viewport}),ah=this;ai.header_div.hide();ai.is_overview=true;ah.overview_drawable=ai;this.overview_drawable.postdraw_actions=function(){ah.overview_highlight.show().height(ah.overview_drawable.content_div.height());ah.overview_viewport.height(ah.overview_drawable.content_div.height()+ah.overview_box.outerHeight());ah.overview_close.show();ah.resize_window()};this.overview_drawable.init();ah.has_changes=true},reset_overview:function(){$(".tipsy").remove();this.overview_viewport.find(".track-tile").remove();this.overview_viewport.height(this.default_overview_height);this.overview_box.height(this.default_overview_height);this.overview_close.hide();this.overview_highlight.hide();view.resize_window();view.overview_drawable=null}});var s=function(aj,an){this.track=aj;this.name=an.name;this.params=[];var av=an.params;for(var ak=0;ak<av.length;ak++){var ap=av[ak],ai=ap.name,au=ap.label,al=unescape(ap.html),aw=ap.value,ar=ap.type;if(ar==="number"){this.params[this.params.length]=new g(ai,au,al,aw,ap.min,ap.max)}else{if(ar=="select"){this.params[this.params.length]=new P(ai,au,al,aw)}else{console.log("WARNING: unrecognized tool parameter type:",ai,ar)}}}this.parent_div=$("<div/>").addClass("dynamic-tool").hide();this.parent_div.bind("drag",function(ay){ay.stopPropagation()}).click(function(ay){ay.stopPropagation()}).bind("dblclick",function(ay){ay.stopPropagation()});var at=$("<div class='tool-name'>").appendTo(this.parent_div).text(this.name);var aq=this.params;var ao=this;$.each(this.params,function(az,aC){var aB=$("<div>").addClass("param-row").appendTo(ao.parent_div);var ay=$("<div>").addClass("param-label").text(aC.label).appendTo(aB);var aA=$("<div/>").addClass("slider").html(aC.html).appendTo(aB);aA.find(":input").val(aC.value);$("<div style='clear: both;'/>").appendTo(aB)});this.parent_div.find("input").click(function(){$(this).select()});var ax=$("<div>").addClass("param-row").appendTo(this.parent_div);var am=$("<input type='submit'>").attr("value","Run on complete dataset").appendTo(ax);var ah=$("<input type='submit'>").attr("value","Run on visible region").css("margin-left","3em").appendTo(ax);var ao=this;ah.click(function(){ao.run_on_region()});am.click(function(){ao.run_on_dataset()})};q(s.prototype,{get_param_values_dict:function(){var ah={};this.parent_div.find(":input").each(function(){var ai=$(this).attr("name"),aj=$(this).val();ah[ai]=JSON.stringify(aj)});return ah},get_param_values:function(){var ai=[];var ah={};this.parent_div.find(":input").each(function(){var aj=$(this).attr("name"),ak=$(this).val();if(aj){ai[ai.length]=ak}});return ai},run_on_dataset:function(){var ah=this;ah.run({dataset_id:this.track.original_dataset_id,tool_id:ah.name},null,function(ai){show_modal(ah.name+" is Running",ah.name+" is running on the complete dataset. Tool outputs are in dataset's history.",{Close:hide_modal})})},run_on_region:function(){var ai={dataset_id:this.track.original_dataset_id,chrom:this.track.view.chrom,low:this.track.view.low,high:this.track.view.high,tool_id:this.name},al=this.track,aj=ai.tool_id+al.tool_region_and_parameters_str(ai.chrom,ai.low,ai.high),ah,am;if(al.container===view){var ak=new R(this.name,this.track.view,this.track.container);al.container.add_drawable(ak);al.container.remove_drawable(al);ak.add_drawable(al);al.container_div.appendTo(ak.content_div);ah=ak}else{ah=al.container}if(al instanceof e){am=new W(aj,view,ah,"hda");am.change_mode(al.mode);ah.add_drawable(am)}am.content_div.text("Starting job.");this.run(ai,am,function(an){am.dataset_id=an.dataset_id;am.content_div.text("Running job.");am.init()})},run:function(ai,aj,ak){$.extend(ai,this.get_param_values_dict());var ah=function(){$.getJSON(rerun_tool_url,ai,function(al){if(al==="no converter"){aj.container_div.addClass("error");aj.content_div.text(L)}else{if(al.error){aj.container_div.addClass("error");aj.content_div.text(y+al.message)}else{if(al==="pending"){aj.container_div.addClass("pending");aj.content_div.text("Converting input data so that it can be used quickly with tool.");setTimeout(ah,2000)}else{ak(al)}}}})};ah()}});var P=function(ai,ah,aj,ak){this.name=ai;this.label=ah;this.html=aj;this.value=ak};var g=function(aj,ai,al,am,ak,ah){P.call(this,aj,ai,al,am);this.min=ak;this.max=ah};var h=function(ai,ah,aj,ak){this.name=ai;this.index=ah;this.tool_id=aj;this.tool_exp_name=ak};var X=function(ai,ah,aj,ak){h.call(this,ai,ah,aj,ak);this.low=-Number.MAX_VALUE;this.high=Number.MAX_VALUE;this.min=Number.MAX_VALUE;this.max=-Number.MAX_VALUE;this.container=null;this.slider=null;this.slider_label=null};q(X.prototype,{applies_to:function(ah){if(ah.length>this.index){return true}return false},keep:function(ah){if(!this.applies_to(ah)){return true}var ai=ah[this.index];return(isNaN(ai)||(ai>=this.low&&ai<=this.high))},update_attrs:function(ai){var ah=false;if(!this.applies_to(ai)){return ah}if(ai[this.index]<this.min){this.min=Math.floor(ai[this.index]);ah=true}if(ai[this.index]>this.max){this.max=Math.ceil(ai[this.index]);ah=true}return ah},update_ui_elt:function(){if(this.min!=this.max){this.container.show()}else{this.container.hide()}var aj=function(am,ak){var al=ak-am;return(al<=2?0.01:1)};var ai=this.slider.slider("option","min"),ah=this.slider.slider("option","max");if(this.min<ai||this.max>ah){this.slider.slider("option","min",this.min);this.slider.slider("option","max",this.max);this.slider.slider("option","step",aj(this.min,this.max));this.slider.slider("option","values",[this.min,this.max])}}});var ac=function(at,aA){this.track=at;this.filters=[];for(var av=0;av<aA.length;av++){var aw=aA[av],aB=aw.name,ah=aw.type,aj=aw.index,az=aw.tool_id,ay=aw.tool_exp_name;if(ah==="int"||ah==="float"){this.filters[av]=new X(aB,aj,az,ay)}else{console.log("ERROR: unsupported filter: ",aB,ah)}}var ak=function(aC,aD,aE){aC.click(function(){var aF=aD.text();max=parseFloat(aE.slider("option","max")),input_size=(max<=1?4:max<=1000000?max.toString().length:6),multi_value=false;if(aE.slider("option","values")){input_size=2*input_size+1;multi_value=true}aD.text("");$("<input type='text'/>").attr("size",input_size).attr("maxlength",input_size).attr("value",aF).appendTo(aD).focus().select().click(function(aG){aG.stopPropagation()}).blur(function(){$(this).remove();aD.text(aF)}).keyup(function(aK){if(aK.keyCode===27){$(this).trigger("blur")}else{if(aK.keyCode===13){var aI=aE.slider("option","min"),aG=aE.slider("option","max"),aJ=function(aL){return(isNaN(aL)||aL>aG||aL<aI)},aH=$(this).val();if(!multi_value){aH=parseFloat(aH);if(aJ(aH)){alert("Parameter value must be in the range ["+aI+"-"+aG+"]");return $(this)}}else{aH=aH.split("-");aH=[parseFloat(aH[0]),parseFloat(aH[1])];if(aJ(aH[0])||aJ(aH[1])){alert("Parameter value must be in the range ["+aI+"-"+aG+"]");return $(this)}}aE.slider((multi_value?"values":"value"),aH)}}})})};this.parent_div=$("<div/>").addClass("filters").hide();this.parent_div.bind("drag",function(aC){aC.stopPropagation()}).click(function(aC){aC.stopPropagation()}).bind("dblclick",function(aC){aC.stopPropagation()}).bind("keydown",function(aC){aC.stopPropagation()});var ax=$("<div/>").addClass("sliders").appendTo(this.parent_div);var ap=this;$.each(this.filters,function(aF,aH){aH.container=$("<div/>").addClass("filter-row slider-row").appendTo(ax);var aG=$("<div/>").addClass("elt-label").appendTo(aH.container);var aE=$("<span/>").addClass("slider-name").text(aH.name+" ").appendTo(aG);var aD=$("<span/>");var aJ=$("<span/>").addClass("slider-value").appendTo(aG).append("[").append(aD).append("]");var aC=$("<div/>").addClass("slider").appendTo(aH.container);aH.control_element=$("<div/>").attr("id",aH.name+"-filter-control").appendTo(aC);var aI=[0,0];aH.control_element.slider({range:true,min:Number.MAX_VALUE,max:-Number.MIN_VALUE,values:[0,0],slide:function(aL,aM){var aK=aM.values;aD.text(aK[0]+"-"+aK[1]);aH.low=aK[0];aH.high=aK[1];ap.track.request_draw(true,true)},change:function(aK,aL){aH.control_element.slider("option","slide").call(aH.control_element,aK,aL)}});aH.slider=aH.control_element;aH.slider_label=aD;ak(aJ,aD,aH.control_element);$("<div style='clear: both;'/>").appendTo(aH.container)});if(this.filters.length!==0){var am=$("<div/>").addClass("param-row").appendTo(ax);var ao=$("<input type='submit'/>").attr("value","Run on complete dataset").appendTo(am);var ai=this;ao.click(function(){ai.run_on_dataset()})}var ar=$("<div/>").addClass("display-controls").appendTo(this.parent_div),au,an,aq,al={Transparency:function(aC){ap.alpha_filter=aC},Height:function(aC){ap.height_filter=aC}};$.each(al,function(aE,aD){au=$("<div/>").addClass("filter-row").appendTo(ar),an=$("<span/>").addClass("elt-label").text(aE+":").appendTo(au),aq=$("<select/>").attr("name",aE+"_dropdown").css("float","right").appendTo(au);$("<option/>").attr("value",-1).text("== None ==").appendTo(aq);for(var aC=0;aC<ap.filters.length;aC++){$("<option/>").attr("value",aC).text(ap.filters[aC].name).appendTo(aq)}aq.change(function(){$(this).children("option:selected").each(function(){var aF=parseInt($(this).val());al[aE]((aF>=0?ap.filters[aF]:null));ap.track.request_draw(true,true)})});$("<div style='clear: both;'/>").appendTo(au)});$("<div style='clear: both;'/>").appendTo(this.parent_div)};q(ac.prototype,{reset_filters:function(){for(var ah=0;ah<this.filters.length;ah++){filter=this.filters[ah];filter.slider.slider("option","values",[filter.min,filter.max])}this.alpha_filter=null;this.height_filter=null},run_on_dataset:function(){var ap=function(au,ar,at){if(!(ar in au)){au[ar]=at}return au[ar]};var aj={},ah,ai,ak;for(var al=0;al<this.filters.length;al++){ah=this.filters[al];if(ah.tool_id){if(ah.min!=ah.low){ai=ap(aj,ah.tool_id,[]);ai[ai.length]=ah.tool_exp_name+" >= "+ah.low}if(ah.max!=ah.high){ai=ap(aj,ah.tool_id,[]);ai[ai.length]=ah.tool_exp_name+" <= "+ah.high}}}var an=[];for(var aq in aj){an[an.length]=[aq,aj[aq]]}var ao=an.length;(function am(ay,av){var at=av[0],au=at[0],ax=at[1],aw="("+ax.join(") and (")+")",ar={cond:aw,input:ay,target_dataset_id:ay,tool_id:au},av=av.slice(1);$.getJSON(run_tool_url,ar,function(az){if(az.error){show_modal("Filter Dataset","Error running tool "+au,{Close:hide_modal})}else{if(av.length===0){show_modal("Filtering Dataset","Filter(s) are running on the complete dataset. Outputs are in dataset's history.",{Close:hide_modal})}else{am(az.dataset_id,av)}}})})(this.track.dataset_id,an)}});var E=function(ah,ai){N.Scaler.call(this,ai);this.filter=ah};E.prototype.gen_val=function(ah){if(this.filter.high===Number.MAX_VALUE||this.filter.low===-Number.MAX_VALUE||this.filter.low===this.filter.high){return this.default_val}return((parseFloat(ah[this.filter.index])-this.filter.low)/(this.filter.high-this.filter.low))};var H=function(ah){this.track=ah.track;this.params=ah.params;this.values={};this.restore_values((ah.saved_values?ah.saved_values:{}));this.onchange=ah.onchange};q(H.prototype,{restore_values:function(ah){var ai=this;$.each(this.params,function(aj,ak){if(ah[ak.key]!==undefined){ai.values[ak.key]=ah[ak.key]}else{ai.values[ak.key]=ak.default_value}})},build_form:function(){var ai=this;var ah=$("<div />");$.each(this.params,function(am,ak){if(!ak.hidden){var aj="param_"+am;var ao=ai.values[ak.key];var ar=$("<div class='form-row' />").appendTo(ah);ar.append($("<label />").attr("for",aj).text(ak.label+":"));if(ak.type==="bool"){ar.append($('<input type="checkbox" />').attr("id",aj).attr("name",aj).attr("checked",ao))}else{if(ak.type==="text"){ar.append($('<input type="text"/>').attr("id",aj).val(ao).click(function(){$(this).select()}))}else{if(ak.type==="color"){var an=$("<input />").attr("id",aj).attr("name",aj).val(ao);var ap=$("<div class='tipsy tipsy-north' style='position: absolute;' />").hide();var al=$("<div style='background-color: black; padding: 10px;'></div>").appendTo(ap);var aq=$("<div/>").appendTo(al).farbtastic({width:100,height:100,callback:an,color:ao});$("<div />").append(an).append(ap).appendTo(ar).bind("click",function(at){ap.css({left:$(this).position().left+($(an).width()/2)-60,top:$(this).position().top+$(this.height)}).show();$(document).bind("click.color-picker",function(){ap.hide();$(document).unbind("click.color-picker")});at.stopPropagation()})}else{ar.append($("<input />").attr("id",aj).attr("name",aj).val(ao))}}}}});return ah},update_from_form:function(ah){var aj=this;var ai=false;$.each(this.params,function(ak,am){if(!am.hidden){var an="param_"+ak;var al=ah.find("#"+an).val();if(am.type==="float"){al=parseFloat(al)}else{if(am.type==="int"){al=parseInt(al)}else{if(am.type==="bool"){al=ah.find("#"+an).is(":checked")}}}if(al!==aj.values[am.key]){aj.values[am.key]=al;ai=true}}});if(ai){this.onchange()}}});var b=function(ah,ak,aj,ai,al){this.track=ah;this.index=ak;this.low=ak*S*aj;this.high=(ak+1)*S*aj;this.resolution=aj;this.canvas=$("<div class='track-tile'/>").append(ai);this.data=al;this.stale=false};b.prototype.predisplay_actions=function(){};var l=function(ah,ak,aj,ai,al,am){b.call(this,ah,ak,aj,ai,al);this.max_val=am};q(l.prototype,b.prototype);var Q=function(ah,al,ak,aj,an,ao,am,ai){b.call(this,ah,al,ak,aj,an);this.mode=ao;this.message=am;this.feature_mapper=ai};q(Q.prototype,b.prototype);Q.prototype.predisplay_actions=function(){var ai=this,ah={};if(ai.mode!=="Pack"){return}$(this.canvas).mousemove(function(au){var ao=$(this).offset(),at=au.pageX-ao.left,ar=au.pageY-ao.top,ay=ai.feature_mapper.get_feature_data(at,ar),ap=(ay?ay[0]:null);$(this).siblings(".feature-popup").each(function(){if(!ap||$(this).attr("id")!==ap.toString()){$(this).remove()}});if(ay){var ak=ah[ap];if(!ak){var ap=ay[0],av={name:ay[3],start:ay[1],end:ay[2],strand:ay[4]},an=ai.track.filters_manager.filters,am;for(var aq=0;aq<an.length;aq++){am=an[aq];av[am.name]=ay[am.index]}var ak=$("<div/>").attr("id",ap).addClass("feature-popup"),ax,aw,az=$("<table/>").appendTo(ak),aA;for(ax in av){aw=av[ax];aA=$("<tr/>").appendTo(az);$("<th/>").appendTo(aA).text(ax);$("<td/>").attr("align","left").appendTo(aA).text(typeof(aw)=="number"?ab(aw,2):aw)}ah[ap]=ak}ak.appendTo($(ai.canvas).parent());var al=at+parseInt(ai.canvas.css("left"))+7,aj=ar+parseInt(ai.canvas.css("top"))+7;ak.css("left",al+"px").css("top",aj+"px")}else{if(!au.isPropagationStopped()){au.stopPropagation();$(this).siblings().each(function(){$(this).trigger(au)})}}}).mouseleave(function(){$(this).siblings(".feature-popup").remove()})};var j=function(ak,at,al,ao,au,aj,ai){r.call(this,ak,at,al,{},"draghandle");this.data_url=(aj?aj:default_data_url);this.data_url_extra_params={};this.data_query_wait=(ai?ai:M);this.dataset_check_url=converted_datasets_state_url;if(!j.id_counter){j.id_counter=0}this.id=j.id_counter++;this.container_div=$("<div />").addClass("track").attr("id","track_"+this.id).css("position","relative");if(ao){this.header_div=$("<div class='track-header' />").appendTo(this.container_div);if(this.view.editor){this.drag_div=$("<div/>").addClass(this.drag_handle_class).appendTo(this.header_div)}this.name_div=$("<div/>").addClass("track-name").appendTo(this.header_div).text(this.name).attr("id",this.name.replace(/\s+/g,"-").replace(/[^a-zA-Z0-9\-]/g,"").toLowerCase());this.icons_div=$("<div/>").css("float","left").appendTo(this.header_div).hide();this.settings_icon=$("<a/>").attr("href","javascript:void(0);").attr("title","Edit settings").addClass("icon-button settings-icon").tipsy({gravity:"s"}).appendTo(this.icons_div);this.overview_icon=$("<a/>").attr("href","javascript:void(0);").attr("title","Set as overview").addClass("icon-button overview-icon").tipsy({gravity:"s"}).appendTo(this.icons_div);this.filters_icon=$("<a/>").attr("href","javascript:void(0);").attr("title","Filters").addClass("icon-button filters-icon").tipsy({gravity:"s"}).appendTo(this.icons_div).hide();this.tools_icon=$("<a/>").attr("href","javascript:void(0);").attr("title","Tools").addClass("icon-button tools-icon").tipsy({gravity:"s"}).appendTo(this.icons_div).hide();this.remove_icon=$("<a/>").attr("href","javascript:void(0);").attr("title","Remove").addClass("icon-button remove-icon").tipsy({gravity:"s"}).appendTo(this.icons_div);var am=this;this.header_div.dblclick(function(av){av.stopPropagation()});this.settings_icon.click(function(){var ax=function(){hide_modal();$(window).unbind("keypress.check_enter_esc")},av=function(){am.config.update_from_form($(".dialog-box"));hide_modal();$(window).unbind("keypress.check_enter_esc")},aw=function(ay){if((ay.keyCode||ay.which)===27){ax()}else{if((ay.keyCode||ay.which)===13){av()}}};$(window).bind("keypress.check_enter_esc",aw);show_modal("Configure Track",am.config.build_form(),{Cancel:ax,OK:av})});this.overview_icon.click(function(){am.view.set_overview(am)});this.filters_icon.click(function(){am.filters_div.toggle();am.filters_manager.reset_filters()});this.tools_icon.click(function(){am.dynamic_tool_div.toggle();if(am.dynamic_tool_div.is(":visible")){am.set_name(am.name+am.tool_region_and_parameters_str())}else{am.revert_name()}$(".tipsy").remove()});this.remove_icon.click(function(){$(".tipsy").remove();am.remove()});if(am.display_modes!==undefined){if(am.mode_div===undefined){am.mode_div=$("<div class='right-float menubutton popup' />").appendTo(am.header_div);var an=(am.config&&am.config.values.mode?am.config.values.mode:am.display_modes[0]);am.mode=an;am.mode_div.text(an);var ah={};for(var ap=0,ar=am.display_modes.length;ap<ar;ap++){var aq=am.display_modes[ap];ah[aq]=function(av){return function(){am.change_mode(av)}}(aq)}make_popupmenu(am.mode_div,ah)}else{am.mode_div.hide()}this.header_div.append($("<div/>").css("clear","both"));this.container_div.hover(function(){am.icons_div.show()},function(){am.icons_div.hide()})}}this.content_div=$("<div class='track-content'>").appendTo(this.container_div);this.container.content_div.append(this.container_div)};q(j.prototype,r.prototype,{get_type:function(){if(this instanceof ad){return"LabelTrack"}else{if(this instanceof B){return"ReferenceTrack"}else{if(this instanceof k){return"LineTrack"}else{if(this instanceof Y){return"ReadTrack"}else{if(this instanceof W){return"ToolDataFeatureTrack"}else{if(this instanceof V){return"VcfTrack"}else{if(this instanceof e){return"FeatureTrack"}}}}}}}return""},init:function(){var ah=this;ah.enabled=false;ah.tile_cache.clear();ah.data_manager.clear();ah.initial_canvas=undefined;ah.content_div.css("height","auto");ah.container_div.removeClass("nodata error pending");if(!ah.dataset_id){return}$.getJSON(converted_datasets_state_url,{hda_ldda:ah.hda_ldda,dataset_id:ah.dataset_id,chrom:ah.view.chrom},function(ai){if(!ai||ai==="error"||ai.kind==="error"){ah.container_div.addClass("error");ah.content_div.text(p);if(ai.message){var aj=$(" <a href='javascript:void(0);'></a>").text("View error").click(function(){show_modal("Trackster Error","<pre>"+ai.message+"</pre>",{Close:hide_modal})});ah.content_div.append(aj)}}else{if(ai==="no converter"){ah.container_div.addClass("error");ah.content_div.text(L)}else{if(ai==="no data"||(ai.data!==undefined&&(ai.data===null||ai.data.length===0))){ah.container_div.addClass("nodata");ah.content_div.text(G)}else{if(ai==="pending"){ah.container_div.addClass("pending");ah.content_div.text(u);setTimeout(function(){ah.init()},ah.data_query_wait)}else{if(ai.status==="data"){if(ai.valid_chroms){ah.valid_chroms=ai.valid_chroms;ah.update_track_icons()}ah.content_div.text(aa);if(ah.view.chrom){ah.content_div.text("");ah.content_div.css("height",ah.height_px+"px");ah.enabled=true;$.when(ah.predraw_init()).done(function(){ah.container_div.removeClass("nodata error pending");ah.request_draw()})}}}}}}});this.update_track_icons()},predraw_init:function(){}});var O=function(ak,aj){var ai=this,ah=ai.view;n(ai.container_div,ai.drag_handle_class,".group",ai);this.filters_manager=new ac(this,(ak!==undefined?ak:{}));this.filters_available=false;this.filters_visible=false;this.tool=(aj!==undefined&&obj_length(aj)>0?new s(this,aj):undefined);if(this.header_div){if(this.filters_manager){this.filters_div=this.filters_manager.parent_div;this.header_div.after(this.filters_div)}if(this.tool){this.dynamic_tool_div=this.tool.parent_div;this.header_div.after(this.dynamic_tool_div)}}};q(O.prototype,r.prototype,j.prototype,{copy:function(ah){return new this.constructor(this.name,this.view,ah,this.hda_ldda,this.dataset_id,this.prefs,this.filters,this.tool)},to_json:function(){return{track_type:this.get_type(),name:this.name,hda_ldda:this.hda_ldda,dataset_id:this.dataset_id,prefs:this.prefs,mode:this.mode,}},change_mode:function(ai){var ah=this;ah.mode_div.text(ai);ah.mode=ai;ah.config.values.mode=ai;ah.tile_cache.clear();ah.request_draw();return ah},update_track_icons:function(){var ah=this;if(ah.filters_available>0){ah.filters_icon.show()}else{ah.filters_icon.hide()}if(ah.tool){ah.tools_icon.show()}else{ah.tools_icon.hide()}},_gen_tile_cache_key:function(ai,aj,ah){return ai+"_"+aj+"_"+ah},request_draw:function(ai,ah){this.view.request_redraw(false,ai,ah,this)},_draw:function(aj,ar){if(!this.enabled){return}if(!(this instanceof B)&&(!this.dataset_id)){return}var aq=this.view.low,an=this.view.high,ao=an-aq,ak=this.view.container.width(),av=ak/ao,am=this.view.resolution,au=$("<div style='position: relative;'></div>");if(this.is_overview){aq=this.view.max_low;an=this.view.max_high;am=Math.pow(D,Math.ceil(Math.log((view.max_high-view.max_low)/S)/Math.log(D)));av=ak/(view.max_high-view.max_low)}if(!ar){this.content_div.children().remove()}this.content_div.append(au);this.max_height=0;var ai=Math.floor(aq/am/S);var ap=true;var at=[];var ah=0;while((ai*S*am)<an){tile=this.draw_helper(aj,ak,ai,am,au,av);if(tile){at.push(tile)}else{ap=false}ai+=1;ah++}var al=this;if(ap){al.postdraw_actions(at,ak,av,ar)}},postdraw_actions:function(al,am,an,ah){var aj=this;var ak=false;for(var ai=0;ai<al.length;ai++){if(al[ai].message){ak=true;break}}if(ak){for(var ai=0;ai<al.length;ai++){tile=al[ai];if(!tile.message){tile.canvas.css("padding-top",F)}}}},draw_helper:function(ai,aj,ak,an,au,ay,av,ao){var al=this,at=this._gen_tile_cache_key(aj,ay,ak),ap=ak*S*an,ax=ap+S*an;var aq=(ai?undefined:al.tile_cache.get(at));if(aq){al.show_tile(aq,au,ay);return aq}var ar=function(az){return("isResolved" in az)};var am=true;var ah=al.data_manager.get_data(ap,ax,al.mode,an,al.data_url_extra_params);if(ar(ah)){am=false}var aw;if(view.reference_track&&ay>view.canvas_manager.char_width_px){aw=view.reference_track.data_manager.get_data(ap,ax,al.mode,an,view.reference_track.data_url_extra_params);if(ar(aw)){am=false}}if(am){q(ah,ao);var aq=al.draw_tile(ah,al.mode,an,ak,ay,aw);if(aq!==undefined){al.tile_cache.set(at,aq);al.show_tile(aq,au,ay)}return aq}$.when(ah,aw).then(function(){view.request_redraw(false,false,false,al)});return null},show_tile:function(an,ap,aq){var aj=this,ai=an.canvas,am=ai;if(an.message){var ar=$("<div/>"),ao=$("<div/>").addClass("tile-message").text(an.message).css({height:F-1,width:an.canvas.width}).appendTo(ar),al=$("<a href='javascript:void(0);'/>").addClass("icon more-down").appendTo(ao),ah=$("<a href='javascript:void(0);'/>").addClass("icon more-across").appendTo(ao);ar.append(ai);am=ar;al.click(function(){an.stale=true;aj.data_manager.get_more_data(an.low,an.high,aj.mode,an.resolution,{},aj.data_manager.DEEP_DATA_REQ);aj.request_draw()}).dblclick(function(at){at.stopPropagation()});ah.click(function(){an.stale=true;aj.data_manager.get_more_data(an.low,an.high,aj.mode,an.resolution,{},aj.data_manager.BROAD_DATA_REQ);aj.request_draw()}).dblclick(function(at){at.stopPropagation()})}an.predisplay_actions();var ak=(an.low-(this.is_overview?this.view.max_low:this.view.low))*aq;if(this.left_offset){ak-=this.left_offset}am.css({position:"absolute",top:0,left:ak,height:""});ap.append(am);aj.max_height=Math.max(aj.max_height,am.height());aj.content_div.css("height",aj.max_height+"px");ap.children().css("height",aj.max_height+"px")},_get_tile_bounds:function(ah,ai){var ak=ah*S*ai,al=S*ai,aj=(ak+al<=this.view.max_high?ak+al:this.view.max_high);return[ak,aj]},tool_region_and_parameters_str:function(aj,ah,ak){var ai=this,al=(aj!==undefined&&ah!==undefined&&ak!==undefined?aj+":"+ah+"-"+ak:"all");return" - region=["+al+"], parameters=["+ai.tool.get_param_values().join(", ")+"]"}});var ad=function(ai,ah){j.call(this,"label",ai,ah,false,{});this.container_div.addClass("label-track")};q(ad.prototype,j.prototype,{init:function(){this.enabled=true},_draw:function(){var aj=this.view,ak=aj.high-aj.low,an=Math.floor(Math.pow(10,Math.floor(Math.log(ak)/Math.log(10)))),ah=Math.floor(aj.low/an)*an,al=this.view.container.width(),ai=$("<div style='position: relative; height: 1.3em;'></div>");while(ah<aj.high){var am=(ah-aj.low)/ak*al;ai.append($("<div class='label'>"+commatize(ah)+"</div>").css({position:"absolute",left:am-1}));ah+=an}this.content_div.children(":first").remove();this.content_div.append(ai)}});var B=function(ah){j.call(this,"reference",ah,{content_div:ah.top_labeltrack},false,{});O.call(this);ah.reference_track=this;this.left_offset=200;this.height_px=12;this.container_div.addClass("reference-track");this.content_div.css("background","none");this.content_div.css("min-height","0px");this.content_div.css("border","none");this.data_url=reference_url;this.data_url_extra_params={dbkey:ah.dbkey};this.data_manager=new J(C,this,false);this.tile_cache=new c(v)};q(B.prototype,r.prototype,O.prototype,{init:function(){this.enabled=true},draw_tile:function(ar,an,am,ai,at){var al=this,aj=S*am;if(at>this.view.canvas_manager.char_width_px){if(ar.data===null){al.content_div.css("height","0px");return}var ak=this.view.canvas_manager.new_canvas();var aq=ak.getContext("2d");ak.width=Math.ceil(aj*at+al.left_offset);ak.height=al.height_px;aq.font=aq.canvas.manager.default_font;aq.textAlign="center";ar=ar.data;for(var ao=0,ap=ar.length;ao<ap;ao++){var ah=Math.round(ao*at);aq.fillText(ar[ao],ah+al.left_offset,10)}return new b(al,ai,am,ak,ar)}this.content_div.css("height","0px")}});var k=function(am,ak,aj,an,ah,al){var ai=this;this.display_modes=["Histogram","Line","Filled","Intensity"];this.mode="Histogram";j.call(this,am,ak,aj,al);O.call(this);this.min_height_px=16;this.max_height_px=400;this.height_px=80;this.hda_ldda=an;this.dataset_id=ah;this.original_dataset_id=ah;this.data_manager=new T(C,this);this.tile_cache=new c(v);this.left_offset=0;this.config=new H({track:this,params:[{key:"name",label:"Name",type:"text",default_value:am},{key:"color",label:"Color",type:"color",default_value:get_random_color()},{key:"min_value",label:"Min Value",type:"float",default_value:undefined},{key:"max_value",label:"Max Value",type:"float",default_value:undefined},{key:"mode",type:"string",default_value:this.mode,hidden:true},{key:"height",type:"int",default_value:this.height_px,hidden:true}],saved_values:al,onchange:function(){ai.set_name(ai.prefs.name);ai.vertical_range=ai.prefs.max_value-ai.prefs.min_value;$("#linetrack_"+ai.dataset_id+"_minval").text(ai.prefs.min_value);$("#linetrack_"+ai.dataset_id+"_maxval").text(ai.prefs.max_value);ai.tile_cache.clear();ai.request_draw()}});this.prefs=this.config.values;this.height_px=this.config.values.height;this.vertical_range=this.config.values.max_value-this.config.values.min_value;this.add_resize_handle()};q(k.prototype,r.prototype,O.prototype,{add_resize_handle:function(){var ah=this;var ak=false;var aj=false;var ai=$("<div class='track-resize'>");$(ah.container_div).hover(function(){ak=true;ai.show()},function(){ak=false;if(!aj){ai.hide()}});ai.hide().bind("dragstart",function(al,am){aj=true;am.original_height=$(ah.content_div).height()}).bind("drag",function(am,an){var al=Math.min(Math.max(an.original_height+an.deltaY,ah.min_height_px),ah.max_height_px);$(ah.content_div).css("height",al);ah.height_px=al;ah.request_draw(true)}).bind("dragend",function(al,am){ah.tile_cache.clear();aj=false;if(!ak){ai.hide()}ah.config.values.height=ah.height_px}).appendTo(ah.container_div)},predraw_init:function(){var ah=this;ah.vertical_range=undefined;return $.getJSON(ah.data_url,{stats:true,chrom:ah.view.chrom,low:null,high:null,hda_ldda:ah.hda_ldda,dataset_id:ah.dataset_id},function(ai){ah.container_div.addClass("line-track");var ak=ai.data;if(isNaN(parseFloat(ah.prefs.min_value))||isNaN(parseFloat(ah.prefs.max_value))){ah.prefs.min_value=ak.min;ah.prefs.max_value=ak.max;$("#track_"+ah.dataset_id+"_minval").val(ah.prefs.min_value);$("#track_"+ah.dataset_id+"_maxval").val(ah.prefs.max_value)}ah.vertical_range=ah.prefs.max_value-ah.prefs.min_value;ah.total_frequency=ak.total_frequency;ah.container_div.find(".yaxislabel").remove();var al=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+ah.dataset_id+"_minval").text(ab(ah.prefs.min_value,3));var aj=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+ah.dataset_id+"_maxval").text(ab(ah.prefs.max_value,3));aj.css({position:"absolute",top:"24px",left:"10px"});aj.prependTo(ah.container_div);al.css({position:"absolute",bottom:"2px",left:"10px"});al.prependTo(ah.container_div)})},draw_tile:function(au,am,al,aj,at){if(this.vertical_range===undefined){return}var ah=this._get_tile_bounds(aj,al),an=ah[0],ar=ah[1],ai=Math.ceil((ar-an)*at),ap=this.height_px;var ak=this.view.canvas_manager.new_canvas();ak.width=ai,ak.height=ap;var aq=ak.getContext("2d");var ao=new N.LinePainter(au.data,an,ar,this.prefs,am);ao.draw(aq,ai,ap);return new b(this.track,aj,al,ak,au.data)}});var e=function(ah,an,ai,am,ap,ao,ak,al){var aj=this;this.display_modes=["Auto","Histogram","Dense","Squish","Pack"];j.call(this,ah,an,ai,true,ao);O.call(this,ak,al);this.config=new H({track:this,params:[{key:"name",label:"Name",type:"text",default_value:ah},{key:"block_color",label:"Block color",type:"color",default_value:get_random_color()},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:ao,onchange:function(){aj.set_name(aj.prefs.name);aj.tile_cache.clear();aj.request_draw()}});this.prefs=this.config.values;this.height_px=0;this.container_div.addClass("feature-track");this.hda_ldda=am;this.dataset_id=ap;this.original_dataset_id=ap;this.show_labels_scale=0.001;this.showing_details=false;this.summary_draw_height=30;this.inc_slots={};this.start_end_dct={};this.tile_cache=new c(d);this.data_manager=new T(20,this);this.left_offset=200;this.painter=N.LinkedFeaturePainter};q(e.prototype,r.prototype,O.prototype,{postdraw_actions:function(ax,ah,ay,aw){O.prototype.postdraw_actions.call(this,ax,aw);var ak=this;if(aw){var am=ak.content_div.children();var an=false;for(var al=am.length-1,ar=0;al>=ar;al--){var aj=$(am[al]);if(an){aj.remove()}else{if(aj.children().length!==0){an=true}}}}if(ak.mode=="Histogram"){var aq=-1;for(var al=0;al<ax.length;al++){var av=ax[al].max_val;if(av>aq){aq=av}}for(var al=0;al<ax.length;al++){var au=ax[al];if(au.max_val!==aq){au.canvas.remove();ak.draw_helper(true,ah,au.index,au.resolution,au.canvas.parent(),ay,[],{max:aq})}}}if(ak.filters_manager){var ai=ak.filters_manager.filters;for(var ap=0;ap<ai.length;ap++){ai[ap].update_ui_elt()}var ao=false,at;for(var al=0;al<ax.length;al++){if(ax[al].data.length){at=ax[al].data[0];for(var ap=0;ap<ai.length;ap++){if(ai[ap].applies_to(at)){ao=true;break}}}}if(ak.filters_available!==ao){ak.filters_available=ao;if(!ak.filters_available){ak.filters_div.hide()}ak.update_track_icons()}}},update_auto_mode:function(ah){if(this.mode=="Auto"){if(ah=="no_detail"){ah="feature spans"}else{if(ah=="summary_tree"){ah="coverage histogram"}}this.mode_div.text("Auto ("+ah+")")}},incremental_slots:function(al,ai,ak){var aj=this.view.canvas_manager.dummy_context,ah=this.inc_slots[al];if(!ah||(ah.mode!==ak)){ah=new (t.FeatureSlotter)(al,ak==="Pack",A,function(am){return aj.measureText(am)});ah.mode=ak;this.inc_slots[al]=ah}return ah.slot_features(ai)},get_summary_tree_data:function(al,ao,aj,ax){if(ax>aj-ao){ax=aj-ao}var at=Math.floor((aj-ao)/ax),aw=[],ak=0;var am=0,an=0,ar,av=0,ap=[],au,aq;var ai=function(aA,az,aB,ay){aA[0]=az+aB*ay;aA[1]=az+(aB+1)*ay};while(av<ax&&am!==al.length){var ah=false;for(;av<ax&&!ah;av++){ai(ap,ao,av,at);for(an=am;an<al.length;an++){ar=al[an].slice(1,3);if(is_overlap(ar,ap)){ah=true;break}}if(ah){break}}data_start_index=an;aw[aw.length]=au=[ap[0],0];for(;an<al.length;an++){ar=al[an].slice(1,3);if(is_overlap(ar,ap)){au[1]++}else{break}}if(au[1]>ak){ak=au[1]}av++}return{max:ak,delta:at,data:aw}},draw_tile:function(aw,az,aD,aH,ar,ak){var aA=this,am=aA._get_tile_bounds(aH,aD),aK=am[0],ai=am[1],ay=ai-aK,aB=Math.ceil(ay*ar),aQ=25,al=this.left_offset,ax,an;if(az==="Auto"){if(aw.dataset_type==="summary_tree"){az=aw.dataset_type}else{if(aw.extra_info==="no_detail"||aA.is_overview){az="no_detail"}else{var aP=aw.data;if(this.view.high-this.view.low>K){az="Squish"}else{az="Pack"}}}this.update_auto_mode(az)}if(az==="summary_tree"||az==="Histogram"){an=this.summary_draw_height;this.container_div.find(".yaxislabel").remove();var ah=$("<div />").addClass("yaxislabel");ah.text(aw.max);ah.css({position:"absolute",top:"24px",left:"10px",color:this.prefs.label_color});ah.prependTo(this.container_div);var aj=this.view.canvas_manager.new_canvas();aj.width=aB+al;aj.height=an+U;if(aw.dataset_type!="summary_tree"){var at=this.get_summary_tree_data(aw.data,aK,ai,200);if(aw.max){at.max=aw.max}aw=at}var aM=new N.SummaryTreePainter(aw,aK,ai,this.prefs);var aC=aj.getContext("2d");aC.translate(al,U);aM.draw(aC,aB,an);return new l(aA,aH,aD,aj,aw.data,aw.max)}var ax,ap=1;if(az==="no_detail"||az==="Squish"||az==="Pack"){ap=this.incremental_slots(ar,aw.data,az);ax=this.inc_slots[ar].slots}var aq=[];if(aw.data){var au=this.filters_manager.filters;for(var aE=0,aG=aw.data.length;aE<aG;aE++){var ao=aw.data[aE];var aF=false;var av;for(var aJ=0,aO=au.length;aJ<aO;aJ++){av=au[aJ];av.update_attrs(ao);if(!av.keep(ao)){aF=true;break}}if(!aF){aq.push(ao)}}}var aN=(this.filters_manager.alpha_filter?new E(this.filters_manager.alpha_filter):null);var aL=(this.filters_manager.height_filter?new E(this.filters_manager.height_filter):null);var aM=new (this.painter)(aq,aK,ai,this.prefs,az,aN,aL,ak);var an=Math.max(af,aM.get_required_height(ap));var aj=this.view.canvas_manager.new_canvas();var aI=null;aj.width=aB+al;aj.height=an;var aC=aj.getContext("2d");aC.fillStyle=this.prefs.block_color;aC.font=aC.canvas.manager.default_font;aC.textAlign="right";this.container_div.find(".yaxislabel").remove();if(aw.data){aC.translate(al,0);aI=aM.draw(aC,aB,an,ax);aI.translation=-al}return new Q(aA,aH,aD,aj,aw.data,az,aw.message,aI)}});var V=function(al,aj,ai,an,ah,ak,am){e.call(this,al,aj,ai,an,ah,ak,am);this.painter=N.VariantPainter};q(V.prototype,r.prototype,O.prototype,e.prototype);var Y=function(al,aj,ai,an,ah,ak,am){e.call(this,al,aj,ai,an,ah,ak,am);this.config=new H({track:this,params:[{key:"name",label:"Name",type:"text",default_value:al},{key:"block_color",label:"Block color",type:"color",default_value:get_random_color()},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_insertions",label:"Show insertions",type:"bool",default_value:false},{key:"show_differences",label:"Show differences only",type:"bool",default_value:true},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:ak,onchange:function(){this.track.set_name(this.track.prefs.name);this.track.tile_cache.clear();this.track.request_draw()}});this.prefs=this.config.values;this.painter=N.ReadPainter;this.update_track_icons()};q(Y.prototype,r.prototype,O.prototype,e.prototype);var W=function(al,aj,ai,an,ah,ak,am){e.call(this,al,aj,ai,an,ah,ak,am,{});this.data_url=raw_data_url;this.data_query_wait=1000;this.dataset_check_url=dataset_state_url};q(W.prototype,r.prototype,O.prototype,e.prototype,{predraw_init:function(){var ai=this;var ah=function(){if(ai.data_manager.size()===0){setTimeout(ah,300)}else{ai.data_url=default_data_url;ai.data_query_wait=M;ai.dataset_state_url=converted_datasets_state_url;$.getJSON(ai.dataset_state_url,{dataset_id:ai.dataset_id,hda_ldda:ai.hda_ldda},function(aj){})}};ah()}});Z.View=ae;Z.DrawableGroup=R;Z.LineTrack=k;Z.FeatureTrack=e;Z.ReadTrack=Y};var slotting_module=function(c,b){var e=c("class").extend;var d=2,a=5;b.FeatureSlotter=function(j,h,f,g){this.slots={};this.start_end_dct={};this.w_scale=j;this.include_label=h;this.max_rows=f;this.measureText=g};e(b.FeatureSlotter.prototype,{slot_features:function(m){var p=this.w_scale,s=this.slots,h=this.start_end_dct,y=[],A=[],n=0,z=this.max_rows;for(var w=0,x=m.length;w<x;w++){var l=m[w],o=l[0];if(s[o]!==undefined){n=Math.max(n,s[o]);A.push(s[o])}else{y.push(w)}}var q=function(G,H){for(var F=0;F<=z;F++){var D=false,I=h[F];if(I!==undefined){for(var C=0,E=I.length;C<E;C++){var B=I[C];if(H>B[0]&&G<B[1]){D=true;break}}}if(!D){return F}}return -1};for(var w=0,x=y.length;w<x;w++){var l=m[y[w]],o=l[0],u=l[1],f=l[2],r=l[3],g=Math.floor(u*p),k=Math.ceil(f*p),v=this.measureText(r).width,j;if(r!==undefined&&this.include_label){v+=(d+a);if(g-v>=0){g-=v;j="left"}else{k+=v;j="right"}}var t=q(g,k);if(t>=0){if(h[t]===undefined){h[t]=[]}h[t].push([g,k]);s[o]=t;n=Math.max(n,t)}else{}}return n+1}})};var painters_module=function(k,y){var v=k("class").extend;var q=function(J,B,H,A,G,E){if(E===undefined){E=4}var D=A-B;var C=G-H;var F=Math.floor(Math.sqrt(D*D+C*C)/E);var K=D/F;var I=C/F;var z;for(z=0;z<F;z++,B+=K,H+=I){if(z%2!==0){continue}J.fillRect(B,H,E,1)}};var r=function(B,A,z,E){var D=A-E/2,C=A+E/2,F=z-Math.sqrt(E*3/2);B.beginPath();B.moveTo(D,F);B.lineTo(C,F);B.lineTo(A,z);B.lineTo(D,F);B.strokeStyle=this.fillStyle;B.fill();B.stroke();B.closePath()};var e=function(z){this.default_val=(z?z:1)};e.prototype.gen_val=function(z){return this.default_val};var n=function(B,D,z,A,C){this.data=B;this.view_start=D;this.view_end=z;this.prefs=v({},this.default_prefs,A);this.mode=C};n.prototype.default_prefs={};var w=function(B,D,z,A,C){n.call(this,B,D,z,A,C)};w.prototype.default_prefs={show_counts:false};w.prototype.draw=function(M,z,L){var E=this.view_start,O=this.view_end-this.view_start,N=z/O;var J=this.data.data,I=this.data.delta,G=this.data.max,B=L;delta_x_px=Math.ceil(I*N);M.save();for(var C=0,D=J.length;C<D;C++){var H=Math.floor((J[C][0]-E)*N);var F=J[C][1];if(!F){continue}var K=F/G*L;if(F!==0&&K<1){K=1}M.fillStyle=this.prefs.block_color;M.fillRect(H,B-K,delta_x_px,K);var A=4;if(this.prefs.show_counts&&(M.measureText(F).width+A)<delta_x_px){M.fillStyle=this.prefs.label_color;M.textAlign="center";M.fillText(F,H+(delta_x_px/2),10)}}M.restore()};var c=function(z,D,F,G,B){n.call(this,z,D,F,G,B);if(this.prefs.min_value===undefined){var H=Infinity;for(var A=0,C=this.data.length;A<C;A++){H=Math.min(H,this.data[A][1])}this.prefs.min_value=H}if(this.prefs.max_value===undefined){var E=-Infinity;for(var A=0,C=this.data.length;A<C;A++){E=Math.max(E,this.data[A][1])}this.prefs.max_value=E}};c.prototype.default_prefs={min_value:undefined,max_value:undefined,mode:"Histogram",color:"#000",overflow_color:"#F66"};c.prototype.draw=function(N,M,K){var F=false,H=this.prefs.min_value,D=this.prefs.max_value,J=D-H,z=K,A=this.view_start,L=this.view_end-this.view_start,B=M/L,I=this.mode,T=this.data;N.save();var U=Math.round(K+H/J*K);if(I!=="Intensity"){N.fillStyle="#aaa";N.fillRect(0,U,M,1)}N.beginPath();var R,E,C;if(T.length>1){C=Math.ceil((T[1][0]-T[0][0])*B)}else{C=10}for(var O=0,P=T.length;O<P;O++){N.fillStyle=this.prefs.color;R=Math.round((T[O][0]-A)*B);E=T[O][1];var Q=false,G=false;if(E===null){if(F&&I==="Filled"){N.lineTo(R,z)}F=false;continue}if(E<H){G=true;E=H}else{if(E>D){Q=true;E=D}}if(I==="Histogram"){E=Math.round(E/J*z);N.fillRect(R,U,C,-E)}else{if(I==="Intensity"){E=255-Math.floor((E-H)/J*255);N.fillStyle="rgb("+E+","+E+","+E+")";N.fillRect(R,0,C,z)}else{E=Math.round(z-(E-H)/J*z);if(F){N.lineTo(R,E)}else{F=true;if(I==="Filled"){N.moveTo(R,z);N.lineTo(R,E)}else{N.moveTo(R,E)}}}}N.fillStyle=this.prefs.overflow_color;if(Q||G){var S;if(I==="Histogram"||I==="Intensity"){S=C}else{R-=2;S=4}if(Q){N.fillRect(R,0,S,3)}if(G){N.fillRect(R,z-3,S,3)}}N.fillStyle=this.prefs.color}if(I==="Filled"){if(F){N.lineTo(R,U);N.lineTo(0,U)}N.fill()}else{N.stroke()}N.restore()};var o=function(z){this.feature_positions={};this.slot_height=z;this.translation=0};o.prototype.map_feature_data=function(A,C,z,B){if(!this.feature_positions[C]){this.feature_positions[C]=[]}this.feature_positions[C].push({data:A,x_start:z,x_end:B})};o.prototype.get_feature_data=function(z,D){var C=Math.floor(D/this.slot_height),B;if(!this.feature_positions[C]){return null}z+=this.translation;for(var A=0;A<this.feature_positions[C].length;A++){B=this.feature_positions[C][A];if(z>=B.x_start&&z<=B.x_end){return B.data}}};var p=function(B,E,z,A,D,F,C){n.call(this,B,E,z,A,D);this.alpha_scaler=(F?F:new e());this.height_scaler=(C?C:new e())};p.prototype.default_prefs={block_color:"#FFF",connector_color:"#FFF"};v(p.prototype,{get_required_height:function(A){var z=y_scale=this.get_row_height(),B=this.mode;if(B==="no_detail"||B==="Squish"||B==="Pack"){z=A*y_scale}return z+Math.max(Math.round(y_scale/2),5)},draw:function(L,J,H,G){var R=this.data,E=this.view_start,N=this.view_end;L.save();L.fillStyle=this.prefs.block_color;L.textAlign="right";var I=this.view_end-this.view_start,F=J/I,M=this.get_row_height(),Q=new o(M),C;for(var O=0,P=R.length;O<P;O++){var B=R[O],D=B[0],K=B[1],z=B[2],A=(G&&G[D]!==undefined?G[D]:null);if((K<N&&z>E)&&(this.mode=="Dense"||A!==null)){C=this.draw_element(L,this.mode,B,A,E,N,F,M,J);Q.map_feature_data(B,A,C[0],C[1])}}L.restore();return Q},draw_element:function(F,B,H,D,C,E,G,A,z){console.log("WARNING: Unimplemented function.");return[0,0]}});var d=10,j=3,m=5,x=10,g=1,t=3,f=3,a=9,l=2,h="#ccc";var s=function(B,E,z,A,D,F,C){p.call(this,B,E,z,A,D,F,C)};v(s.prototype,p.prototype,{get_row_height:function(){var A=this.mode,z;if(A==="Dense"){z=d}else{if(A==="no_detail"){z=j}else{if(A==="Squish"){z=m}else{z=x}}}return z},draw_element:function(N,E,W,I,P,ah,al,an,z){var T=W[0],aj=W[1],ab=W[2],R=W[3],ac=Math.floor(Math.max(0,(aj-P)*al)),O=Math.ceil(Math.min(z,Math.max(0,(ab-P)*al))),aa=ac,am=O,Z=(E==="Dense"?0:(0+I))*an,M,af,S=null,ap=null,C=this.prefs.block_color,ae=this.prefs.label_color;N.globalAlpha=this.alpha_scaler.gen_val(W);if(E=="Dense"){I=1}if(E==="no_detail"){N.fillStyle=C;N.fillRect(ac,Z+5,O-ac,g)}else{var L=W[4],Y=W[5],ad=W[6],D=W[7];if(Y&&ad){S=Math.floor(Math.max(0,(Y-P)*al));ap=Math.ceil(Math.min(z,Math.max(0,(ad-P)*al)))}var ak,U;if(E==="Squish"||E==="Dense"){ak=1;U=f}else{ak=5;U=a}if(!D){if(W.strand){if(W.strand==="+"){N.fillStyle=N.canvas.manager.get_pattern("right_strand_inv")}else{if(W.strand==="-"){N.fillStyle=N.canvas.manager.get_pattern("left_strand_inv")}}}else{N.fillStyle=C}N.fillRect(ac,Z,O-ac,U)}else{var K,V;if(E==="Squish"||E==="Dense"){N.fillStyle=h;K=Z+Math.floor(f/2)+1;V=1}else{if(L){var K=Z;var V=U;if(L==="+"){N.fillStyle=N.canvas.manager.get_pattern("right_strand")}else{if(L==="-"){N.fillStyle=N.canvas.manager.get_pattern("left_strand")}}}else{N.fillStyle=h;K+=(f/2)+1;V=1}}N.fillRect(ac,K,O-ac,V);var F;for(var ai=0,B=D.length;ai<B;ai++){var G=D[ai],A=Math.floor(Math.max(0,(G[0]-P)*al)),X=Math.ceil(Math.min(z,Math.max((G[1]-P)*al)));if(A>X){continue}N.fillStyle=C;N.fillRect(A,Z+(U-ak)/2+1,X-A,ak);if(S!==undefined&&ad>Y&&!(A>ap||X<S)){var ag=Math.max(A,S),J=Math.min(X,ap);N.fillRect(ag,Z+1,J-ag,U);if(D.length==1&&E=="Pack"){if(L==="+"){N.fillStyle=N.canvas.manager.get_pattern("right_strand_inv")}else{if(L==="-"){N.fillStyle=N.canvas.manager.get_pattern("left_strand_inv")}}if(ag+14<J){ag+=2;J-=2}N.fillRect(ag,Z+1,J-ag,U)}}}if(E==="Pack"){N.globalAlpha=1;N.fillStyle="white";var H=this.height_scaler.gen_val(W),Q=Math.ceil(U*H),ao=Math.round((U-Q)/2);if(H!==1){N.fillRect(ac,K+1,O-ac,ao);N.fillRect(ac,K+U-ao+1,O-ac,ao)}}}N.globalAlpha=1;if(E==="Pack"&&aj>P){N.fillStyle=ae;if(P===0&&ac-N.measureText(R).width<0){N.textAlign="left";N.fillText(R,O+l,Z+8);am+=N.measureText(R).width+l}else{N.textAlign="right";N.fillText(R,ac-l,Z+8);aa-=N.measureText(R).width+l}}}N.globalAlpha=1;return[aa,am]}});var b=function(B,E,z,A,D,F,C){p.call(this,B,E,z,A,D,F,C)};v(b.prototype,p.prototype,{draw_element:function(S,N,H,D,V,B,K,T,Q){var H=data[i],J=H[0],R=H[1],C=H[2],M=H[3],F=Math.floor(Math.max(0,(R-V)*K)),I=Math.ceil(Math.min(Q,Math.max(0,(C-V)*K))),E=(N==="Dense"?0:(0+D))*T,z,W,A=null,L=null;if(no_label){S.fillStyle=block_color;S.fillRect(F+left_offset,E+5,I-F,1)}else{var U=H[4],P=H[5],G=H[6];z=9;W=1;S.fillRect(F+left_offset,E,I-F,z);if(N!=="Dense"&&M!==undefined&&R>V){S.fillStyle=label_color;if(V===0&&F-S.measureText(M).width<0){S.textAlign="left";S.fillText(M,I+2+left_offset,E+8)}else{S.textAlign="right";S.fillText(M,F-2+left_offset,E+8)}S.fillStyle=block_color}var O=U+" / "+P;if(R>V&&S.measureText(O).width<(I-F)){S.fillStyle="white";S.textAlign="center";S.fillText(O,left_offset+F+(I-F)/2,E+8);S.fillStyle=block_color}}return[F,I]}});var u=function(C,F,z,B,E,G,D,A){p.call(this,C,F,z,B,E,G,D);this.ref_seq=(A?A.data:null)};u.prototype.default_prefs=v({},p.prototype.default_prefs,{show_insertions:false});v(u.prototype,p.prototype,{get_row_height:function(){var z,A=this.mode;if(A==="Dense"){z=d}else{if(A==="Squish"){z=m}else{z=x;if(this.prefs.show_insertions){z*=2}}}return z},draw_read:function(W,R,N,ab,C,V,K,H,G){W.textAlign="center";var U=this,B=[ab,C],Q=0,X=0,T=0,z=W.canvas.manager.char_width_px;var ag=[];if((R==="Pack"||this.mode==="Auto")&&H!==undefined&&N>z){T=Math.round(N/2)}if(!K){K=[[0,H.length]]}for(var O=0,Z=K.length;O<Z;O++){var L=K[O],D="MIDNSHP=X"[L[0]],P=L[1];if(D==="H"||D==="S"){Q-=P}var I=V+Q,af=Math.floor(Math.max(0,(I-ab)*N)),J=Math.floor(Math.max(0,(I+P-ab)*N));if(af===J){J+=1}switch(D){case"H":break;case"S":case"M":case"=":if(is_overlap([I,I+P],B)){var S=H.slice(X,X+P);if(T>0){W.fillStyle=this.prefs.block_color;W.fillRect(af-T,G+1,J-af,9);W.fillStyle=h;for(var ad=0,A=S.length;ad<A;ad++){if(this.prefs.show_differences&&this.ref_seq){var M=this.ref_seq[I-ab+ad];if(!M||M.toLowerCase()===S[ad].toLowerCase()){continue}}if(I+ad>=ab&&I+ad<=C){var ae=Math.floor(Math.max(0,(I+ad-ab)*N));W.fillText(S[ad],ae,G+9)}}}else{W.fillStyle=this.prefs.block_color;W.fillRect(af,G+4,J-af,f)}}X+=P;Q+=P;break;case"N":W.fillStyle=h;W.fillRect(af-T,G+5,J-af,1);Q+=P;break;case"D":W.fillStyle="red";W.fillRect(af-T,G+4,J-af,3);Q+=P;break;case"P":break;case"I":var aa=af-T;if(is_overlap([I,I+P],B)){var S=H.slice(X,X+P);if(this.prefs.show_insertions){var F=af-(J-af)/2;if((R==="Pack"||this.mode==="Auto")&&H!==undefined&&N>z){W.fillStyle="yellow";W.fillRect(F-T,G-9,J-af,9);ag[ag.length]={type:"triangle",data:[aa,G+4,5]};W.fillStyle=h;switch(seq_tile_overlap){case (OVERLAP_START):S=S.slice(ab-I);break;case (OVERLAP_END):S=S.slice(0,I-C);break;case (CONTAINED_BY):break;case (CONTAINS):S=S.slice(ab-I,I-C);break}for(var ad=0,A=S.length;ad<A;ad++){var ae=Math.floor(Math.max(0,(I+ad-ab)*N));W.fillText(S[ad],ae-(J-af)/2,G)}}else{W.fillStyle="yellow";W.fillRect(F,G+(this.mode!=="Dense"?2:5),J-af,(R!=="Dense"?f:t))}}else{if((R==="Pack"||this.mode==="Auto")&&H!==undefined&&N>z){ag[ag.length]={type:"text",data:[S.length,aa,G+9]}}else{}}}X+=P;break;case"X":X+=P;break}}W.fillStyle="yellow";var ac,E,ah;for(var Y=0;Y<ag.length;Y++){ac=ag[Y];E=ac.type;ah=ac.data;if(E==="text"){W.save();W.font="bold "+W.font;W.fillText(ah[0],ah[1],ah[2]);W.restore()}else{if(E=="triangle"){r(W,ah[0],ah[1],ah[2])}}}},draw_element:function(S,N,F,C,V,A,J,T,Q){var I=F[0],R=F[1],B=F[2],K=F[3],E=Math.floor(Math.max(0,(R-V)*J)),G=Math.ceil(Math.min(Q,Math.max(0,(B-V)*J))),D=(N==="Dense"?0:(0+C))*T,W=this.prefs.block_color,H=this.prefs.label_color,P=0;if((N==="Pack"||this.mode==="Auto")&&J>S.canvas.manager.char_width_px){var P=Math.round(J/2)}S.fillStyle=W;if(F[5] instanceof Array){var O=Math.floor(Math.max(0,(F[4][0]-V)*J)),M=Math.ceil(Math.min(Q,Math.max(0,(F[4][1]-V)*J))),L=Math.floor(Math.max(0,(F[5][0]-V)*J)),z=Math.ceil(Math.min(Q,Math.max(0,(F[5][1]-V)*J)));if(F[4][1]>=V&&F[4][0]<=A&&F[4][2]){this.draw_read(S,N,J,V,A,F[4][0],F[4][2],F[4][3],D)}if(F[5][1]>=V&&F[5][0]<=A&&F[5][2]){this.draw_read(S,N,J,V,A,F[5][0],F[5][2],F[5][3],D)}if(L>M){S.fillStyle=h;q(S,M-P,D+5,L-P,D+5)}}else{S.fillStyle=W;this.draw_read(S,N,J,V,A,R,F[4],F[5],D)}if(N==="Pack"&&R>V){S.fillStyle=this.prefs.label_color;var U=1;if(U===0&&E-S.measureText(K).width<0){S.textAlign="left";S.fillText(K,G+l-P,D+8)}else{S.textAlign="right";S.fillText(K,E-l-P,D+8)}S.fillStyle=W}return[0,0]}});y.Scaler=e;y.SummaryTreePainter=w;y.LinePainter=c;y.LinkedFeaturePainter=s;y.ReadPainter=u;y.VariantPainter=b};(function(d){var c={};var b=function(e){return c[e]};var a=function(f,g){var e={};g(b,e);c[f]=e};a("class",class_module);a("slotting",slotting_module);a("painters",painters_module);a("trackster",trackster_module);for(key in c.trackster){d[key]=c.trackster[key]}})(window); \ No newline at end of file diff -r 603924d3abc3057def82337b53178ad48a71b1d1 -r 125d735c689ee60ad9bd9601c7a22738ba3523de static/scripts/packed/trackster_ui.js --- a/static/scripts/packed/trackster_ui.js +++ b/static/scripts/packed/trackster_ui.js @@ -1,1 +1,1 @@ -var add_bookmark=function(b,a){var g=$("#bookmarks-container"),d=$("<div/>").addClass("bookmark").appendTo(g),c=$("<div/>").addClass("delete-icon-container").appendTo(d).click(function(){d.slideUp("fast");d.remove();view.has_changes=true;return false}),e=$("<a href=''/>").addClass("icon-button delete").appendTo(c),f=$("<div/>").addClass("position").appendTo(d),h=$("<a href=''/>").text(b).appendTo(f).click(function(){view.go_to(b);return false});annotation_div=get_editable_text_elt(a,true).addClass("annotation").appendTo(d);view.has_changes=true;return d};var addable_objects={LineTrack:LineTrack,FeatureTrack:FeatureTrack,ReadTrack:ReadTrack,DrawableGroup:DrawableGroup};var track_from_dict=function(c,b){var a=new addable_objects[c.track_type](c.name,view,b,c.hda_ldda,c.dataset_id,c.prefs,c.filters,c.tool);if(c.mode){a.change_mode(c.mode)}return a};var drawable_collection_from_dict=function(f,a){var e=new addable_objects[f.obj_type](f.name,view,a,f.prefs,view.viewport_container,view);for(var d=0;d<f.drawables.length;d++){var b=f.drawables[d],c;if(b.track_type){c=track_from_dict(b,e)}else{c=drawable_collection_from_dict(b)}e.add_drawable(c);e.content_div.append(c.container_div)}return e};var drawable_from_dict=function(b,a){return(b.track_type?track_from_dict(b,a):drawable_collection_from_dict(b,a))};var create_visualization=function(b,e,g,c,a,d,f){view=new View(b,e,g,c);view.editor=true;$.when(view.load_chroms_deferred).then(function(){if(a){var k=a.chrom,p=a.start,h=a.end,m=a.overview;if(k&&(p!==undefined)&&h){view.change_chrom(k,p,h)}}if(d){var o;for(var j=0;j<d.length;j++){o=d[j];view.add_drawable(drawable_from_dict(o,view))}}var n;for(var j=0;j<view.drawables.length;j++){if(view.drawables[j].name==m){view.set_overview(view.drawables[j]);break}}if(f){var l;for(var j=0;j<f.length;j++){l=f[j];add_bookmark(l.position,l.annotation)}}view.has_changes=false});return view};var init_keyboard_nav=function(a){$(document).keydown(function(b){if($(b.srcElement).is(":input")){return}switch(b.which){case 37:a.move_fraction(0.25);break;case 38:var c=Math.round(a.viewport_container.height()/15);a.viewport_container.scrollTo("-="+c+"px");break;case 39:a.move_fraction(-0.25);break;case 40:var c=Math.round(a.viewport_container.height()/15);a.viewport_container.scrollTo("+="+c+"px");break}})}; \ No newline at end of file +var add_bookmark=function(b,a){var g=$("#bookmarks-container"),d=$("<div/>").addClass("bookmark").appendTo(g),c=$("<div/>").addClass("delete-icon-container").appendTo(d).click(function(){d.slideUp("fast");d.remove();view.has_changes=true;return false}),e=$("<a href=''/>").addClass("icon-button delete").appendTo(c),f=$("<div/>").addClass("position").appendTo(d),h=$("<a href=''/>").text(b).appendTo(f).click(function(){view.go_to(b);return false});annotation_div=get_editable_text_elt(a,true).addClass("annotation").appendTo(d);view.has_changes=true;return d};var addable_objects={LineTrack:LineTrack,FeatureTrack:FeatureTrack,ReadTrack:ReadTrack,DrawableGroup:DrawableGroup};var track_from_dict=function(c,b){var a=new addable_objects[c.track_type](c.name,view,b,c.hda_ldda,c.dataset_id,c.prefs,c.filters,c.tool);if(c.mode){a.change_mode(c.mode)}return a};var drawable_collection_from_dict=function(f,a){var e=new addable_objects[f.obj_type](f.name,view,a,f.prefs,view.viewport_container,view);for(var d=0;d<f.drawables.length;d++){var b=f.drawables[d],c;if(b.track_type){c=track_from_dict(b,e)}else{c=drawable_collection_from_dict(b)}e.add_drawable(c);e.content_div.append(c.container_div)}return e};var drawable_from_dict=function(b,a){return(b.track_type?track_from_dict(b,a):drawable_collection_from_dict(b,a))};var create_visualization=function(b,e,g,c,a,d,f){view=new View(b,e,g,c);view.editor=true;$.when(view.load_chroms_deferred).then(function(){if(a){var k=a.chrom,p=a.start,h=a.end,m=a.overview;if(k&&(p!==undefined)&&h){view.change_chrom(k,p,h)}}if(d){var o;for(var j=0;j<d.length;j++){o=d[j];view.add_drawable(drawable_from_dict(o,view))}}var n;for(var j=0;j<view.drawables.length;j++){if(view.drawables[j].name===m){view.set_overview(view.drawables[j]);break}}if(f){var l;for(var j=0;j<f.length;j++){l=f[j];add_bookmark(l.position,l.annotation)}}view.has_changes=false});return view};var init_keyboard_nav=function(a){$(document).keydown(function(b){if($(b.srcElement).is(":input")){return}switch(b.which){case 37:a.move_fraction(0.25);break;case 38:var c=Math.round(a.viewport_container.height()/15);a.viewport_container.scrollTo("-="+c+"px");break;case 39:a.move_fraction(-0.25);break;case 40:var c=Math.round(a.viewport_container.height()/15);a.viewport_container.scrollTo("+="+c+"px");break}})}; \ No newline at end of file diff -r 603924d3abc3057def82337b53178ad48a71b1d1 -r 125d735c689ee60ad9bd9601c7a22738ba3523de static/scripts/trackster.js --- a/static/scripts/trackster.js +++ b/static/scripts/trackster.js @@ -37,7 +37,6 @@ }; })(); - /** * Compute the type of overlap between two regions. They are assumed to be on the same chrom/contig. * The overlap is computed relative to the second region; hence, OVERLAP_START indicates that the first @@ -74,6 +73,7 @@ return overlap; }; + /** * Returns true if regions overlap. */ @@ -82,6 +82,74 @@ return (overlap !== BEFORE && overlap !== AFTER); }; +/** + * Returns a random color in hexadecimal format that is sufficiently different from a single color + * or set of colors. + * @param colors a color or list of colors in the format '#RRGGBB' + */ +var get_random_color = function(colors) { + // Default for colors is white. + if (!colors) { colors = "#ffffff" }; + + // If needed, create list of colors. + if ( typeof(colors) === "string" ) { + colors = [ colors ]; + } + + // Convert colors to numbers. + for (var i = 0; i < colors.length; i++) { + colors[i] = parseInt( colors[i].slice(1), 16 ); + } + + // -- Perceived brightness and difference formulas are from + // -- http://www.w3.org/WAI/ER/WD-AERT/#color-contrast + + // Compute perceived color brightness (based on RGB-YIQ transformation): + var brightness = function(r, g, b) { + return ( (r * 299) + (g * 587) + (b * 114) ) / 1000; + }; + + // Compute color difference: + var difference = function(r1, g1, b1, r2, g2, b2) { + return ( Math.max(r1, r2) - Math.min(r1, r2) ) + + ( Math.max(g1, g2) - Math.min(g1, g2) ) + + ( Math.max(b1, b2) - Math.min(b1, b2) ); + }; + + // Create new random color. + var new_color, nr, ng, nb, + other_color, or, og, ob, + n_brightness, o_brightness, + diff, ok = false; + do { + // New color is never white b/c random in [0,1) + new_color = Math.random() * 0xffffff; + nr = new_color | 0xff0000; + ng = new_color | 0x00ff00; + nb = new_color | 0x0000ff; + n_brightness = brightness(nr, ng, nb); + ok = true; + for (var i = 0; i < colors.length; i++) { + other_color = colors[i]; + or = other_color | 0xff0000; + og = other_color | 0x00ff00; + ob = other_color | 0x0000ff; + o_brightness = brightness(or, og, ob); + diff = difference(nr, ng, nb, or, og, ob); + // Thresholds for brightness difference and color difference + // are from W3C link above. + if ( ( Math.abs(n_brightness - o_brightness) < 125 ) || + ( diff < 500 ) ) { + ok = false; + break; + } + } + } while (!ok); + + // Add 0x1000000 to left pad number with 0s. + return '#' + ( 0x1000000 + new_color ).toString(16).substr(1,6); +}; + // Encapsulate -- anything to be availabe outside this block is added to exports var trackster_module = function(require, exports) { @@ -463,7 +531,7 @@ // data is ready, it then replaces itself with the actual data entry = this.load_data(low, high, mode, resolution, extra_params); this.set_data(low, high, mode, entry); - return entry + return entry; }, /** "Deep" data request; used as a parameter for DataManager.get_more_data() */ DEEP_DATA_REQ: "deep", @@ -589,7 +657,6 @@ this.name = name; this.view = view; this.container = container; - this.drag_handle_class = drag_handle_class; this.config = new DrawableConfig({ track: this, params: [ @@ -601,6 +668,8 @@ } }); this.prefs = this.config.values; + this.drag_handle_class = drag_handle_class; + this.is_overview = false; }; extend(Drawable.prototype, { @@ -608,7 +677,7 @@ request_draw: function() {}, _draw: function() {}, to_json: function() {}, - make_name_popup_menu: function() {}, + update_track_icons: function() {}, /** * Set drawable name. */ @@ -750,14 +819,14 @@ is_container(this.content_div, this); moveable(this.container_div, this.drag_handle_class, ".group", this); - this.make_name_popup_menu(); + this.update_track_icons(); }; extend(DrawableGroup.prototype, Drawable.prototype, DrawableCollection.prototype, { /** * Make popup menu for group. */ - make_name_popup_menu: function() { + update_track_icons: function() { var group = this; var group_dropdown = {}; @@ -852,7 +921,7 @@ // Overview (scrollbar and overview plot) at bottom this.overview = $("<div/>").addClass("overview").appendTo(this.bottom_container); this.overview_viewport = $("<div/>").addClass("overview-viewport").appendTo(this.overview); - this.overview_close = $("<a href='javascript:void(0);'>Close Overview</a>").addClass("overview-close").hide().appendTo(this.overview_viewport); + this.overview_close = $("<a/>").attr("href", "javascript:void(0);").attr("title", "Close overview").addClass("icon-button overview-close tooltip").hide().appendTo(this.overview_viewport); this.overview_highlight = $("<div/>").addClass("overview-highlight").hide().appendTo(this.overview_viewport); this.overview_box_background = $("<div/>").addClass("overview-boxback").appendTo(this.overview_viewport); this.overview_box = $("<div/>").addClass("overview-box").appendTo(this.overview_viewport); @@ -1195,13 +1264,14 @@ /** * Request that view redraw some or all tracks. If a track is not specificied, redraw all tracks. */ + // FIXME: change method call so that track is first and additional parameters are optional. request_redraw: function(nodraw, force, clear_after, track) { var view = this, - // Either redrawing a single track or all view's tracks. + // Either redrawing a single drawable or all view's drawables. track_list = (track ? [track] : view.drawables), track_index; - + // Add/update tracks in track list to redraw list. var track; for (var i = 0; i < track_list.length; i++) { @@ -1318,42 +1388,44 @@ this.nav_container.width( this.container.width() ); this.request_redraw(); }, - /** Show a track in the overview. */ - set_overview: function(track) { - // Get data and draw tile. - $.when(track.get_overview_tile()).then(function(tile) { - // Update UI. - view.overview_viewport.find(".track-tile").remove(); + /** Show a Drawable in the overview. */ + set_overview: function(drawable) { + if (this.overview_drawable) { + // If drawable to be set as overview is already in overview, do nothing. + // Otherwise, remove overview. + if (this.overview_drawable.dataset_id === drawable.dataset_id) { + return; + } + this.overview_viewport.find(".track").remove(); + } + + // Set new overview. + var + overview_drawable = drawable.copy( { content_div: this.overview_viewport } ), + view = this; + overview_drawable.header_div.hide(); + overview_drawable.is_overview = true; + view.overview_drawable = overview_drawable; + this.overview_drawable.postdraw_actions = function() { + view.overview_highlight.show().height(view.overview_drawable.content_div.height()); + view.overview_viewport.height(view.overview_drawable.content_div.height() + view.overview_box.outerHeight()); view.overview_close.show(); - view.overview_viewport.append(tile.canvas); - view.overview_highlight.show().height(tile.canvas.height()); - view.overview_viewport.height(tile.canvas.height() + view.overview_box.outerHeight()); view.resize_window(); - - // Update view, track states. - if (view.overview_track) { - view.overview_track.set_is_overview(false); - } - view.overview_track = track; - track.set_is_overview(true); - }); + }; + this.overview_drawable.init(); view.has_changes = true; }, /** Close and reset overview. */ reset_overview: function() { // Update UI. + $(".tipsy").remove(); this.overview_viewport.find(".track-tile").remove(); this.overview_viewport.height(this.default_overview_height); this.overview_box.height(this.default_overview_height); this.overview_close.hide(); this.overview_highlight.hide(); view.resize_window(); - - // Update view, track states. - if (view.overview_track) { - view.overview_track.set_is_overview(false); - } - view.overview_track = null; + view.overview_drawable = null; } }); @@ -2243,7 +2315,7 @@ * -------> ToolDataFeatureTrack * -------> VcfTrack */ -var Track = function(name, view, container, prefs, data_url, data_query_wait) { +var Track = function(name, view, container, show_header, prefs, data_url, data_query_wait) { // For now, track's container is always view. Drawable.call(this, name, view, container, {}, "draghandle"); @@ -2254,18 +2326,128 @@ this.data_url_extra_params = {} this.data_query_wait = (data_query_wait ? data_query_wait : DEFAULT_DATA_QUERY_WAIT); this.dataset_check_url = converted_datasets_state_url; + + if (!Track.id_counter) { Track.id_counter = 0; } + this.id = Track.id_counter++; // // Create HTML element structure for track. // - if (!Track.id_counter) { Track.id_counter = 0; } - this.container_div = $("<div />").addClass('track').attr("id", "track_" + Track.id_counter++).css("position", "relative"); - if (!this.hidden) { + this.container_div = $("<div />").addClass('track').attr("id", "track_" + this.id).css("position", "relative"); + + // Create and initialize track header and icons. + if (show_header) { this.header_div = $("<div class='track-header' />").appendTo(this.container_div); if (this.view.editor) { this.drag_div = $("<div/>").addClass(this.drag_handle_class).appendTo(this.header_div); } - this.name_div = $("<div class='menubutton popup' />").appendTo(this.header_div); - this.name_div.text(this.name); - this.name_div.attr( "id", this.name.replace(/\s+/g,'-').replace(/[^a-zA-Z0-9\-]/g,'').toLowerCase() ); + this.name_div = $("<div/>").addClass("track-name").appendTo(this.header_div).text(this.name) + .attr( "id", this.name.replace(/\s+/g,'-').replace(/[^a-zA-Z0-9\-]/g,'').toLowerCase() ); + this.icons_div = $("<div/>").css("float", "left").appendTo(this.header_div).hide(); + + // Track icons. + this.settings_icon = $("<a/>").attr("href", "javascript:void(0);").attr("title", "Edit settings") + .addClass("icon-button settings-icon").tipsy( {gravity: 's'} ) + .appendTo(this.icons_div); + this.overview_icon = $("<a/>").attr("href", "javascript:void(0);").attr("title", "Set as overview") + .addClass("icon-button overview-icon").tipsy( {gravity: 's'} ) + .appendTo(this.icons_div); + this.filters_icon = $("<a/>").attr("href", "javascript:void(0);").attr("title", "Filters") + .addClass("icon-button filters-icon").tipsy( {gravity: 's'} ) + .appendTo(this.icons_div).hide(); + this.tools_icon = $("<a/>").attr("href", "javascript:void(0);").attr("title", "Tools") + .addClass("icon-button tools-icon").tipsy( {gravity: 's'} ) + .appendTo(this.icons_div).hide(); + this.remove_icon = $("<a/>").attr("href", "javascript:void(0);").attr("title", "Remove") + .addClass("icon-button remove-icon").tipsy( {gravity: 's'} ) + .appendTo(this.icons_div); + var track = this; + + // Suppress double clicks in header so that they do not impact viz. + this.header_div.dblclick( function(e) { e.stopPropagation(); } ); + + // Clicking on settings icon opens track config. + this.settings_icon.click( function() { + var cancel_fn = function() { hide_modal(); $(window).unbind("keypress.check_enter_esc"); }, + ok_fn = function() { + track.config.update_from_form( $(".dialog-box") ); + hide_modal(); + $(window).unbind("keypress.check_enter_esc"); + }, + check_enter_esc = function(e) { + if ((e.keyCode || e.which) === 27) { // Escape key + cancel_fn(); + } else if ((e.keyCode || e.which) === 13) { // Enter key + ok_fn(); + } + }; + + $(window).bind("keypress.check_enter_esc", check_enter_esc); + show_modal("Configure Track", track.config.build_form(), { + "Cancel": cancel_fn, + "OK": ok_fn + }); + }); + + this.overview_icon.click( function() { + track.view.set_overview(track); + }); + + this.filters_icon.click( function() { + // TODO: update tipsy text. + track.filters_div.toggle(); + track.filters_manager.reset_filters(); + }); + + this.tools_icon.click( function() { + // TODO: update tipsy text. + + track.dynamic_tool_div.toggle(); + + // Update track name. + if (track.dynamic_tool_div.is(":visible")) { + track.set_name(track.name + track.tool_region_and_parameters_str()); + } + else { + track.revert_name(); + } + // HACK: name change modifies icon placement, which leaves tooltip incorrectly placed. + $(".tipsy").remove(); + }); + + // Clicking on remove icon removes track. + this.remove_icon.click( function() { + // Tipsy for remove icon must be deleted when track is deleted. + $(".tipsy").remove(); + track.remove(); + }); + + // Set up behavior for modes popup. + if (track.display_modes !== undefined) { + if (track.mode_div === undefined) { + track.mode_div = $("<div class='right-float menubutton popup' />").appendTo(track.header_div); + var init_mode = (track.config && track.config.values['mode'] ? + track.config.values['mode'] : track.display_modes[0]); + track.mode = init_mode; + track.mode_div.text(init_mode); + + var mode_mapping = {}; + for (var i = 0, len = track.display_modes.length; i < len; i++) { + var mode = track.display_modes[i]; + mode_mapping[mode] = function(mode) { + return function() { track.change_mode(mode); }; + }(mode); + } + make_popupmenu(track.mode_div, mode_mapping); + } else { + track.mode_div.hide(); + } + + this.header_div.append( $("<div/>").css("clear", "both") ); + + // Set up config icon. + + // Show icons when users is hovering over track. + this.container_div.hover( function() { track.icons_div.show(); }, function() { track.icons_div.hide(); } ); + } } // @@ -2352,7 +2534,7 @@ } else if (result['status'] === "data") { if (result['valid_chroms']) { track.valid_chroms = result['valid_chroms']; - track.make_name_popup_menu(); + track.update_track_icons(); } track.content_div.text(DATA_OK); if (track.view.chrom) { @@ -2367,14 +2549,18 @@ } } }); + + this.update_track_icons(); }, /** * Additional initialization required before drawing track for the first time. */ - predraw_init: function() {}, + predraw_init: function() {} }); -var TiledTrack = function(filters_list, tool_dict) { +var TiledTrack = function(name, view, container, show_header, prefs, filters_list, tool_dict, data_url, data_query_wait) { + Track.call(this, name, view, container, show_header, prefs, data_url, data_query_wait); + var track = this, view = track.view; @@ -2387,54 +2573,33 @@ this.filters_available = false; this.filters_visible = false; this.tool = (tool_dict !== undefined && obj_length(tool_dict) > 0 ? new Tool(this, tool_dict) : undefined); - this.is_overview = false; - if (track.hidden) { return; } + if (this.header_div) { + // + // Create filters div. + // + if (this.filters_manager) { + this.filters_div = this.filters_manager.parent_div + this.header_div.after(this.filters_div); + } - // - // Create filters div. - // - if (this.filters_manager) { - this.filters_div = this.filters_manager.parent_div - this.header_div.after(this.filters_div); - } - - // - // Create dynamic tool div. - // - if (this.tool) { - this.dynamic_tool_div = this.tool.parent_div; - this.header_div.after(this.dynamic_tool_div); - } - - // - // Create modes control. - // - if (track.display_modes !== undefined) { - if (track.mode_div === undefined) { - track.mode_div = $("<div class='right-float menubutton popup' />").appendTo(track.header_div); - var init_mode = (track.config && track.config.values['mode'] ? - track.config.values['mode'] : track.display_modes[0]); - track.mode = init_mode; - track.mode_div.text(init_mode); - - var mode_mapping = {}; - for (var i = 0, len = track.display_modes.length; i < len; i++) { - var mode = track.display_modes[i]; - mode_mapping[mode] = function(mode) { - return function() { track.change_mode(mode); }; - }(mode); - } - make_popupmenu(track.mode_div, mode_mapping); - } else { - track.mode_div.hide(); + // + // Create dynamic tool div. + // + if (this.tool) { + this.dynamic_tool_div = this.tool.parent_div; + this.header_div.after(this.dynamic_tool_div); } } - - this.make_name_popup_menu(); }; extend(TiledTrack.prototype, Drawable.prototype, Track.prototype, { /** + * Returns a copy of the track. + */ + copy: function(container) { + return new this.constructor(this.name, this.view, container, this.hda_ldda, this.dataset_id, this.prefs, this.filters, this.tool); + }, + /** * Convert track to JSON object. */ to_json: function() { @@ -2461,87 +2626,31 @@ return track; }, /** - * Make popup menu for track name. + * Update track's buttons. */ - make_name_popup_menu: function() { + update_track_icons: function() { var track = this; - var track_dropdown = {}; - // - // Make track overview option. - // - track_dropdown[(this.is_overview ? "Hide overview" : "Set as overview")] = function() { - if (track.is_overview) { - track.view.reset_overview(); - } - else { - track.view.set_overview(track); - } - }; - - // - // Edit config option. - // - track_dropdown["Edit configuration"] = function() { - var cancel_fn = function() { hide_modal(); $(window).unbind("keypress.check_enter_esc"); }, - ok_fn = function() { - track.config.update_from_form( $(".dialog-box") ); - hide_modal(); - $(window).unbind("keypress.check_enter_esc"); - }, - check_enter_esc = function(e) { - if ((e.keyCode || e.which) === 27) { // Escape key - cancel_fn(); - } else if ((e.keyCode || e.which) === 13) { // Enter key - ok_fn(); - } - }; - - $(window).bind("keypress.check_enter_esc", check_enter_esc); - show_modal("Configure Track", track.config.build_form(), { - "Cancel": cancel_fn, - "OK": ok_fn - }); - }; - - // - // Show/hide filters option. + // Show/hide filter icon. // if (track.filters_available > 0) { - // Show/hide filters menu item. - var text = (track.filters_div.is(":visible") ? "Hide filters" : "Show filters"); - track_dropdown[text] = function() { - // Toggle filtering div, reset filters, and remake menu. - track.filters_visible = (track.filters_div.is(":visible")); - if (track.filters_visible) { - track.filters_manager.reset_filters(); - } - track.filters_div.toggle(); - track.make_name_popup_menu(); - }; + track.filters_icon.show(); + } + else { + track.filters_icon.hide(); } // - // Show/hide tool option. + // Show/hide tool icon. // if (track.tool) { - // Show/hide dynamic tool menu item. - var text = (track.dynamic_tool_div.is(":visible") ? "Hide tool" : "Show tool"); - track_dropdown[text] = function() { - // Set track name, toggle tool div, and remake menu. - if (!track.dynamic_tool_div.is(":visible")) { - track.set_name(track.name + track.tool_region_and_parameters_str()); - } - else { - menu_option_text = "Show dynamic tool"; - track.revert_name(); - } - track.dynamic_tool_div.toggle(); - track.make_name_popup_menu(); - }; + track.tools_icon.show(); } - + else { + track.tools_icon.hide(); + } + // // List chrom/contigs with data option. // @@ -2552,61 +2661,6 @@ }; } */ - - // - // Remove option. - // - track_dropdown.Remove = function() { - track.remove(); - }; - - make_popupmenu(track.name_div, track_dropdown); - }, - /** - * Set track's overview status. - */ - set_is_overview: function(is_overview) { - this.is_overview = is_overview; - this.make_name_popup_menu(); - }, - /** - * Returns a jQuery Deferred object that resolves to a Tile with track's overview. - * TODO: this should be the approach used when drawing any tile so that tile drawing is not blocking. - */ - get_overview_tile: function() { - var - track = this; - view = track.view, - resolution = Math.pow(RESOLUTION, Math.ceil( Math.log( (view.max_high - view.max_low) / DENSITY ) / Math.log(RESOLUTION) )), - view_width = view.container.width(), - // w_scale units are pixels per base. - w_scale = view_width / (view.max_high - view.max_low), - overview_tile = $.Deferred(); - $.when(track.data_manager.get_data(view.max_low, view.max_high, "Auto", resolution, track.data_url_extra_params)).then(function(overview_data) { - var - key = track._gen_tile_cache_key(view_width, w_scale, 0), - tile = track.tile_cache.get(key); - - // Draw tile if necessary. - if (!tile) { - tile = track.draw_tile(overview_data, "Auto", resolution, 0, w_scale); - track.tile_cache.set(key, tile); - } - - // Always copy tile because it may need to be used in viz. - var - src_canvas = $(tile.canvas.find("canvas")), - new_canvas = src_canvas.clone(), - src_ctx = src_canvas.get(0).getContext("2d"), - tgt_ctx = new_canvas.get(0).getContext("2d"), - data = src_ctx.getImageData(0, 0, src_ctx.canvas.width, src_ctx.canvas.height); - // Need to undo offsets when placing image data. - tgt_ctx.putImageData(data, -track.left_offset, (tile.data.dataset_type === "summary_tree" ? SUMMARY_TREE_TOP_PADDING : 0)); - new_tile = new Tile(track, -1, resolution, new_canvas); - overview_tile.resolve(new_tile); - }); - - return overview_tile; }, /** * Generate a key for the tile cache. @@ -2641,6 +2695,14 @@ w_scale = width / range, resolution = this.view.resolution, parent_element = $("<div style='position: relative;'></div>"); + + // For overview, adjust high, low, resolution, and w_scale. + if (this.is_overview) { + low = this.view.max_low; + high = this.view.max_high; + resolution = Math.pow(RESOLUTION, Math.ceil( Math.log( (view.max_high - view.max_low) / DENSITY ) / Math.log(RESOLUTION) )); + w_scale = width / (view.max_high - view.max_low); + } if (!clear_after) { this.content_div.children().remove(); } this.content_div.append( parent_element ); @@ -2751,7 +2813,7 @@ // Can't draw now, so trigger another redraw when the data is ready $.when( tile_data, seq_data ).then( function() { - view.request_redraw(); + view.request_redraw(false, false, false, track); }); // Indicate to caller that this tile could not be drawn @@ -2811,8 +2873,7 @@ tile.predisplay_actions(); // Position tile element, recalculate left position at display time - var range = this.view.high - this.view.low, - left = (tile.low - this.view.low) * w_scale; + var left = ( tile.low - (this.is_overview? this.view.max_low : this.view.low) ) * w_scale; if (this.left_offset) { left -= this.left_offset; } @@ -2849,8 +2910,7 @@ }); var LabelTrack = function (view, container) { - this.hidden = true; - Track.call(this, "label", view, container, {} ); + Track.call(this, "label", view, container, false, {} ); this.container_div.addClass( "label-track" ); }; extend(LabelTrack.prototype, Track.prototype, { @@ -2880,9 +2940,7 @@ }); var ReferenceTrack = function (view) { - this.hidden = true; - Track.call(this, "reference", view, { content_div: view.top_labeltrack }, {}); - TiledTrack.call(this); + TiledTrack.call(this, "reference", view, { content_div: view.top_labeltrack }, false, {}); view.reference_track = this; this.left_offset = 200; @@ -2909,7 +2967,7 @@ tile_length = DENSITY * resolution; if (w_scale > this.view.canvas_manager.char_width_px) { - if (seq === null) { + if (seq.data === null) { track.content_div.css("height", "0px"); return; } @@ -2934,8 +2992,7 @@ var track = this; this.display_modes = ["Histogram", "Line", "Filled", "Intensity"]; this.mode = "Histogram"; - Track.call( this, name, view, container, prefs ); - TiledTrack.call( this ); + TiledTrack.call( this, name, view, container, true, prefs ); this.min_height_px = 16; this.max_height_px = 400; @@ -2952,7 +3009,7 @@ track: this, params: [ { key: 'name', label: 'Name', type: 'text', default_value: name }, - { key: 'color', label: 'Color', type: 'color', default_value: 'black' }, + { key: 'color', label: 'Color', type: 'color', default_value: get_random_color() }, { key: 'min_value', label: 'Min Value', type: 'float', default_value: undefined }, { key: 'max_value', label: 'Max Value', type: 'float', default_value: undefined }, { key: 'mode', type: 'string', default_value: this.mode, hidden: true }, @@ -3080,18 +3137,15 @@ // // Initialization. - // - - // FIXME: cleaner init needed; should just be able to call TiledTrack() - Track.call(this, name, view, container, prefs); - TiledTrack.call(this, filters, tool); + // + TiledTrack.call(this, name, view, container, true, prefs, filters, tool); // Define and restore track configuration. this.config = new DrawableConfig( { track: this, params: [ { key: 'name', label: 'Name', type: 'text', default_value: name }, - { key: 'block_color', label: 'Block color', type: 'color', default_value: '#444' }, + { key: 'block_color', label: 'Block color', type: 'color', default_value: get_random_color() }, { key: 'label_color', label: 'Label color', type: 'color', default_value: 'black' }, { key: 'show_counts', label: 'Show summary counts', type: 'bool', default_value: true }, { key: 'mode', type: 'string', default_value: this.mode, hidden: true }, @@ -3203,7 +3257,7 @@ if (!track.filters_available) { track.filters_div.hide(); } - track.make_name_popup_menu(); + track.update_track_icons(); } } }, @@ -3345,9 +3399,12 @@ if (mode === "Auto") { if (result.dataset_type === "summary_tree") { mode = result.dataset_type; - } else if (result.extra_info === "no_detail") { + } + // HACK: use no_detail mode track is in overview to prevent overview from being too large. + else if (result.extra_info === "no_detail" || track.is_overview) { mode = "no_detail"; - } else { + } + else { // Choose b/t Squish and Pack. // Proxy measures for using Squish: // (a) error message re: limiting number of features shown; @@ -3478,7 +3535,7 @@ track: this, params: [ { key: 'name', label: 'Name', type: 'text', default_value: name }, - { key: 'block_color', label: 'Block color', type: 'color', default_value: '#444' }, + { key: 'block_color', label: 'Block color', type: 'color', default_value: get_random_color() }, { key: 'label_color', label: 'Label color', type: 'color', default_value: 'black' }, { key: 'show_insertions', label: 'Show insertions', type: 'bool', default_value: false }, { key: 'show_differences', label: 'Show differences only', type: 'bool', default_value: true }, @@ -3495,7 +3552,7 @@ this.prefs = this.config.values; this.painter = painters.ReadPainter; - this.make_name_popup_menu(); + this.update_track_icons(); }; extend(ReadTrack.prototype, Drawable.prototype, TiledTrack.prototype, FeatureTrack.prototype); diff -r 603924d3abc3057def82337b53178ad48a71b1d1 -r 125d735c689ee60ad9bd9601c7a22738ba3523de static/scripts/trackster_ui.js --- a/static/scripts/trackster_ui.js +++ b/static/scripts/trackster_ui.js @@ -114,7 +114,7 @@ // Set overview. var overview_track; for (var i = 0; i < view.drawables.length; i++) { - if (view.drawables[i].name == overview_track_name) { + if (view.drawables[i].name === overview_track_name) { view.set_overview(view.drawables[i]); break; } diff -r 603924d3abc3057def82337b53178ad48a71b1d1 -r 125d735c689ee60ad9bd9601c7a22738ba3523de templates/tracks/browser.mako --- a/templates/tracks/browser.mako +++ b/templates/tracks/browser.mako @@ -42,10 +42,9 @@ <script type='text/javascript' src="${h.url_for('/static/scripts/excanvas.js')}"></script><![endif]--> -${h.js( "galaxy.base", "galaxy.panels", "json2", "jquery", "jstorage", "jquery.event.drag", "jquery.mousewheel", "jquery.autocomplete", "trackster", "trackster_ui", "jquery.ui.sortable.slider", "jquery.scrollTo", "farbtastic" )} +${h.js( "galaxy.base", "galaxy.panels", "json2", "jquery", "jstorage", "jquery.event.drag", "jquery.mousewheel", "jquery.autocomplete", "trackster", "trackster_ui", "jquery.ui.sortable.slider", "jquery.scrollTo", "farbtastic", "jquery.tipsy" )} <script type="text/javascript"> - // // Place URLs here so that url_for can be used to generate them. // @@ -113,6 +112,9 @@ }; $(function() { + // Manual tipsy config because default gravity is S and cannot be changed. + $(".menu-button").tipsy( {gravity: 'n'} ); + // Hide bookmarks by default right now. parent.force_right_panel("hide"); @@ -172,59 +174,62 @@ %endif // - // Make actions menu. + // Initialize icons. // - $("#viz-actions-button").css( "position", "relative" ); - make_popupmenu( $("#viz-actions-button"), { - "Add Tracks": add_tracks, - "Add Group": function() { - var group = new DrawableGroup("New Group", view, view); - view.add_drawable(group); - }, - "Save": function() { - // Show saving dialog box - show_modal("Saving...", "<img src='${h.url_for('/static/images/yui/rel_interstitial_loading.gif')}'/>"); - - // Save bookmarks. - var bookmarks = []; - $(".bookmark").each(function() { - bookmarks[bookmarks.length] = { - position: $(this).children(".position").text(), - annotation: $(this).children(".annotation").text() - }; - }); - - var overview_track_name = (view.overview_track ? view.overview_track.name : null); - var payload = { - 'view': view.to_json(), - 'viewport': { 'chrom': view.chrom, 'start': view.low , 'end': view.high, 'overview': overview_track_name }, - 'bookmarks': bookmarks - }; - - $.ajax({ - url: "${h.url_for( action='save' )}", - type: "POST", - data: { - 'vis_id': view.vis_id, - 'vis_title': view.title, - 'dbkey': view.dbkey, - 'payload': JSON.stringify(payload) - }, - success: function(vis_id) { - view.vis_id = vis_id; - view.has_changes = false; - hide_modal(); - }, - error: function() { alert("Could not save visualization"); } - }); - }, - "Bookmarks": function() { - // HACK -- use style to determine if panel is hidden and hide/show accordingly. - parent.force_right_panel(($("div#right").css("right") == "0px" ? "hide" : "show")); - }, - "Close": function() { window.location = "${h.url_for( controller='visualization', action='list' )}"; } + $("#add-tracks-icon").click( function() { add_tracks(); } ); + + $("#add-group-icon").click( function() { + view.add_drawable( new DrawableGroup("New Group", view, view) ); }); + $("#save-icon").click( function() { + // Show saving dialog box + show_modal("Saving...", "<img src='${h.url_for('/static/images/yui/rel_interstitial_loading.gif')}'/>"); + + // Save bookmarks. + var bookmarks = []; + $(".bookmark").each(function() { + bookmarks[bookmarks.length] = { + position: $(this).children(".position").text(), + annotation: $(this).children(".annotation").text() + }; + }); + + // FIXME: give unique IDs to Drawables and save overview as ID. + var overview_track_name = (view.overview_drawable ? view.overview_drawable.name : null); + var payload = { + 'view': view.to_json(), + 'viewport': { 'chrom': view.chrom, 'start': view.low , 'end': view.high, 'overview': overview_track_name }, + 'bookmarks': bookmarks + }; + + $.ajax({ + url: "${h.url_for( action='save' )}", + type: "POST", + data: { + 'vis_id': view.vis_id, + 'vis_title': view.title, + 'dbkey': view.dbkey, + 'payload': JSON.stringify(payload) + }, + success: function(vis_id) { + view.vis_id = vis_id; + view.has_changes = false; + hide_modal(); + }, + error: function() { alert("Could not save visualization"); } + }); + }); + + $("#bookmarks-icon").click( function() { + // HACK -- use style to determine if panel is hidden and hide/show accordingly. + parent.force_right_panel(($("div#right").css("right") == "0px" ? "hide" : "show")); + }); + + $("#close-icon").click( function() { + window.location = "${h.url_for( controller='visualization', action='list' )}"; + }); + $("#add-bookmark-button").click(function() { // Add new bookmark. var position = view.chrom + ":" + view.low + "-" + view.high, @@ -245,9 +250,14 @@ <div class="unified-panel-header-inner"><div style="float:left;" id="title"></div><div style="float: right"> - <a id="viz-actions-button" class='panel-header-button popup' href="javascript:void(0)" target="galaxy_main">${_('Actions')}</a> + <a id="add-tracks-icon" class='icon-button menu-button' href="javascript:void(0);" title="Add tracks"></a> + <a id="add-group-icon" class='icon-button menu-button' href="javascript:void(0);" title="Add new group"></a> + <a id="bookmarks-icon" class='icon-button menu-button' href="javascript:void(0);" title="Bookmarks"></a> + <a id="save-icon" class='icon-button menu-button' href="javascript:void(0);" title="Save"></a> + <a id="close-icon" class='icon-button menu-button' href="javascript:void(0);" title="Close"></a></div></div> + <div style="clear: both"></div></div><div id="browser-container" class="unified-panel-body"></div> diff -r 603924d3abc3057def82337b53178ad48a71b1d1 -r 125d735c689ee60ad9bd9601c7a22738ba3523de test-data/picard_fastq_to_sam_out1.bam Binary file test-data/picard_fastq_to_sam_out1.bam has changed diff -r 603924d3abc3057def82337b53178ad48a71b1d1 -r 125d735c689ee60ad9bd9601c7a22738ba3523de test-data/picard_fastq_to_sam_out2.bam Binary file test-data/picard_fastq_to_sam_out2.bam has changed diff -r 603924d3abc3057def82337b53178ad48a71b1d1 -r 125d735c689ee60ad9bd9601c7a22738ba3523de tool_conf.xml.sample --- a/tool_conf.xml.sample +++ b/tool_conf.xml.sample @@ -295,6 +295,9 @@ <tool file="fastx_toolkit/fastx_trimmer.xml" /></section><section name="NGS: Picard (beta)" id="picard_beta"> + <label text="Conversion" id="picard_conversion"/> + <tool file="picard/picard_FastqToSam.xml" /> + <tool file="picard/picard_SamToFastq.xml" /><label text="QC/Metrics for sam/bam" id="qcsambam"/><tool file="picard/picard_BamIndexStats.xml" /> @@ -390,7 +393,6 @@ <label text="Filtration" id="gatk_filtration" /><tool file="gatk/variant_filtration.xml" /> - <tool file="gatk/variant_filtration.xml" /><label text="Variant Quality Score Recalibration" id="gatk_variant_quality_score_recalibration" /><tool file="gatk/variant_recalibrator.xml" /> diff -r 603924d3abc3057def82337b53178ad48a71b1d1 -r 125d735c689ee60ad9bd9601c7a22738ba3523de tools/fastq/fastq_paired_end_deinterlacer.py --- a/tools/fastq/fastq_paired_end_deinterlacer.py +++ b/tools/fastq/fastq_paired_end_deinterlacer.py @@ -21,12 +21,14 @@ i = None skip_count = 0 found = {} - for i, mate1 in enumerate( fastqReader( open( input_filename, 'rb' ), format = type ) ): + for i, read in enumerate( fastqReader( open( input_filename, 'rb' ), format = type ) ): - if mate1.identifier in found: - del found[mate1.identifier] + if read.identifier in found: + del found[read.identifier] continue + mate1 = input.get( read.identifier ) + mate2 = input.get( joiner.get_paired_identifier( mate1 ) ) if mate2: diff -r 603924d3abc3057def82337b53178ad48a71b1d1 -r 125d735c689ee60ad9bd9601c7a22738ba3523de tools/gatk/variant_apply_recalibration.xml --- a/tools/gatk/variant_apply_recalibration.xml +++ b/tools/gatk/variant_apply_recalibration.xml @@ -102,9 +102,9 @@ <param name="input_recal" type="data" format="gatk_recal" label="Variant Recalibration file" /><param name="input_tranches" type="data" format="gatk_tranche" label="Variant Tranches file" /><param name="ref_file" type="select" label="Using reference genome"> - <!-- <options from_data_table="picard_indexes"> - <filter type="data_meta" key="dbkey" ref="variants[0].input_variants" column="dbkey"/> - </options> --> + <options from_data_table="picard_indexes"> + <!-- <filter type="data_meta" key="dbkey" ref="variants[0].input_variants" column="dbkey"/> --> + </options></param></when><when value="history"><!-- FIX ME!!!! --> diff -r 603924d3abc3057def82337b53178ad48a71b1d1 -r 125d735c689ee60ad9bd9601c7a22738ba3523de tools/gatk/variant_eval.xml --- a/tools/gatk/variant_eval.xml +++ b/tools/gatk/variant_eval.xml @@ -159,9 +159,9 @@ <param name="input_variant" type="data" format="vcf" label="Input variant file" /></repeat><param name="ref_file" type="select" label="Using reference genome"> - <!--<options from_data_table="picard_indexes"> - <filter type="data_meta" key="dbkey" ref="input_variant" column="dbkey"/> - </options>--> + <options from_data_table="picard_indexes"> + <!-- <filter type="data_meta" key="dbkey" ref="input_variant" column="dbkey"/> --> + </options></param></when><when value="history"><!-- FIX ME!!!! --> diff -r 603924d3abc3057def82337b53178ad48a71b1d1 -r 125d735c689ee60ad9bd9601c7a22738ba3523de tools/gatk/variant_recalibrator.xml --- a/tools/gatk/variant_recalibrator.xml +++ b/tools/gatk/variant_recalibrator.xml @@ -152,9 +152,9 @@ <param name="input_variants" type="data" format="vcf" label="Variant file to recalibrate" /></repeat><param name="ref_file" type="select" label="Using reference genome"> - <!-- <options from_data_table="picard_indexes"> - <filter type="data_meta" key="dbkey" ref="variants[0].input_variants" column="dbkey"/> - </options> --> + <options from_data_table="picard_indexes"> + <!-- <filter type="data_meta" key="dbkey" ref="variants[0].input_variants" column="dbkey"/> --> + </options></param></when><when value="history"><!-- FIX ME!!!! --> diff -r 603924d3abc3057def82337b53178ad48a71b1d1 -r 125d735c689ee60ad9bd9601c7a22738ba3523de tools/picard/picard_AddOrReplaceReadGroups.xml --- a/tools/picard/picard_AddOrReplaceReadGroups.xml +++ b/tools/picard/picard_AddOrReplaceReadGroups.xml @@ -1,4 +1,4 @@ -<tool name="Add or Replace Groups" id="picard_ARRG" version="0.2.0"> +<tool name="Add or Replace Groups" id="picard_ARRG" version="0.2.1"><requirements><requirement type="package">picard</requirement></requirements><command interpreter="python"> picard_wrapper.py @@ -15,7 +15,7 @@ #end if --output-format=$outputFormat --output=$outFile - -j "${GALAXY_DATA_INDEX_DIR}/shared/jars/AddOrReplaceReadGroups.jar" + -j "${GALAXY_DATA_INDEX_DIR}/shared/jars/picard/AddOrReplaceReadGroups.jar" </command><inputs><param format="bam,sam" name="inputFile" type="data" label="SAM/BAM dataset to add or replace read groups in" diff -r 603924d3abc3057def82337b53178ad48a71b1d1 -r 125d735c689ee60ad9bd9601c7a22738ba3523de tools/picard/picard_BamIndexStats.xml --- a/tools/picard/picard_BamIndexStats.xml +++ b/tools/picard/picard_BamIndexStats.xml @@ -1,4 +1,4 @@ -<tool name="BAM Index Statistics" id="picard_BamIndexStats" version="0.2.0"> +<tool name="BAM Index Statistics" id="picard_BamIndexStats" version="0.2.1"><requirements><requirement type="package">picard</requirement></requirements><command interpreter="python"> picard_wrapper.py @@ -6,7 +6,7 @@ --bai-file "$input_file.metadata.bam_index" -t "$htmlfile" -d "$htmlfile.files_path" - -j "${GALAXY_DATA_INDEX_DIR}/shared/jars/BamIndexStats.jar" + -j "${GALAXY_DATA_INDEX_DIR}/shared/jars/picard/BamIndexStats.jar" </command><inputs><param format="bam" name="input_file" type="data" label="BAM dataset to generate statistics for" diff -r 603924d3abc3057def82337b53178ad48a71b1d1 -r 125d735c689ee60ad9bd9601c7a22738ba3523de tools/picard/picard_FastqToSam.xml --- /dev/null +++ b/tools/picard/picard_FastqToSam.xml @@ -0,0 +1,144 @@ +<tool id="picard_FastqToSam" name="FASTQ to BAM" version="0.0.1"> + <description>creates an unaligned BAM file</description> + <requirements><requirement type="package">picard</requirement></requirements> + <command>java -XX:DefaultMaxRAMFraction=1 -XX:+UseParallelGC + -jar "${GALAXY_DATA_INDEX_DIR}/shared/jars/picard/FastqToSam.jar" + FASTQ="${input_fastq1}" + #if str( $input_fastq2) != "None": + FASTQ2="${input_fastq2}" + #end if + QUALITY_FORMAT="${ dict( fastqsanger='Standard', fastqcssanger='Standard', fastqillumina='Illumina', fastqsolexa='Solexa' )[ $input_fastq1.ext ] }" ##Solexa, Illumina, Standard + OUTPUT="${output_bam}" + READ_GROUP_NAME="${read_group_name}" + SAMPLE_NAME="${sample_name}" + #if $param_type.param_type_selector == "advanced": + #if str( $param_type.library_name ) != "": + LIBRARY_NAME="${param_type.library_name}" + #end if + #if str( $param_type.platform_unit ) != "": + PLATFORM_UNIT="${param_type.platform_unit}" + #end if + #if str( $param_type.platform ) != "": + PLATFORM="${param_type.platform}" + #end if + #if str( $param_type.sequencing_center ) != "": + SEQUENCING_CENTER="${param_type.sequencing_center}" + #end if + #if str( $param_type.predicted_insert_size ) != "": + PREDICTED_INSERT_SIZE="${param_type.predicted_insert_size}" + #end if + #if str( $param_type.description.value ) != "": + DESCRIPTION="${param_type.description}" + #end if + #if str( $param_type.run_date ) != "": + RUN_DATE="${param_type.run_date}" + #end if + #if str( $param_type.min_q ) != "": + MIN_Q="${param_type.min_q}" + #end if + #if str( $param_type.min_q ) != "": + MAX_Q="${param_type.max_q}" + #end if + SORT_ORDER="${param_type.sort_order}" + #else: + SORT_ORDER=coordinate ##unsorted, queryname, coordinate; always use coordinate + #end if + 2>&1 + || echo "Error running Picard FastqToSAM" >&2 + </command> + <inputs> + <param name="input_fastq1" type="data" format="fastqsanger,fastqillumina,fastqsolexa,fastqcssanger" label="FASTQ file" /><!-- confirm that fastqcssanger also works --> + <param name="input_fastq2" type="data" format="fastqsanger,fastqillumina,fastqsolexa,fastqcssanger" optional="True" label="Second FASTQ of paired end data" help="Only needed when using paired end data." > + <options options_filter_attribute="ext" from_parameter="tool.app.datatypes_registry.datatypes_by_extension" transform_lines="obj.keys()"> + <column name="name" index="0"/> + <column name="value" index="0"/> + <filter type="param_value" ref="input_fastq1" ref_attribute="ext" column="0"/> + </options> + </param> + <param name="read_group_name" type="text" value="A" label="Read Group Name" /> + <param name="sample_name" type="text" value="unknown sample" label="Sample Name" /> + <conditional name="param_type"> + <param name="param_type_selector" type="select" label="Basic or Advanced options"> + <option value="basic" selected="True">Basic</option> + <option value="advanced">Advanced</option> + </param> + <when value="basic"> + <!-- Do nothing here --> + </when> + <when value="advanced"> + <param name="library_name" type="text" value="" label="Library Name" /> + <param name="platform_unit" type="text" value="" label="Platform Unit" /> + <param name="platform" type="text" value="" label="Platform" /> + <param name="sequencing_center" type="text" value="" label="Sequencing Center" /> + <param name="predicted_insert_size" type="integer" value="" optional="True" label="Predicted Insert Size" /> + <param name="description" type="text" value="" label="Description" /> + <param name="run_date" type="text" value="" label="Run Date" /> + <param name="min_q" type="integer" optional="True" value="0" label="Min Q" /> + <param name="max_q" type="integer" optional="True" value="93" label="Max Q" /> + <param name="sort_order" type="select" label="Sort order"> + <option value="coordinate" selected="True">coordinate</option> + <option value="queryname">queryname</option> + <option value="unsorted">unsorted</option> + </param> + </when> + </conditional> + </inputs> + <outputs> + <data format="bam" name="output_bam" /> + </outputs> + <tests> + <test> + <param name="input_fastq1" value="bwa_wrapper_in2.fastqsanger" ftype="fastqsanger" /> + <param name="input_fastq2" /> + <param name="read_group_name" value="A" /> + <param name="sample_name" value="unknown sample" /> + <param name="param_type_selector" value="basic" /> + <output name="output_bam" file="picard_fastq_to_sam_out1.bam" ftype="bam"/> + </test> + <test> + <param name="input_fastq1" value="bwa_wrapper_in2.fastqsanger" ftype="fastqsanger" /> + <param name="input_fastq2" value="bwa_wrapper_in3.fastqsanger" ftype="fastqsanger" /> + <param name="read_group_name" value="A" /> + <param name="sample_name" value="unknown sample" /> + <param name="param_type_selector" value="basic" /> + <output name="output_bam" file="picard_fastq_to_sam_out2.bam" ftype="bam"/> + </test> + </tests> + <help> +**What it does** + +Picard: FastqToSam converts FASTQ files to unaligned BAM files. + +------ + +Please cite the website "http://picard.sourceforge.net". + +------ + + +**Input formats** + +FastqToSam accepts FASTQ input files. If using paired-end data, you should select two FASTQ files. + +------ + +**Outputs** + +The output is in BAM format, see http://samtools.sourceforge.net for more details. + +------- + +**FastqToSam settings** + +This is list of FastqToSam options:: + + READ_GROUP_NAME=String Read group name Default value: A. This option can be set to 'null' to clear the default value. + SAMPLE_NAME=String Sample name to insert into the read group header Required. + LIBRARY_NAME=String The library name to place into the LB attribute in the read group header Default value: null. + PLATFORM_UNIT=String The platform unit (often run_barcode.lane) to insert into the read group header Default value: null. + PLATFORM=String The platform type (e.g. illumina, solid) to insert into the read group header Default value: null. + SEQUENCING_CENTER=String The sequencing center from which the data originated Default value: null. + PREDICTED_INSERT_SIZE=Integer Predicted median insert size, to insert into the read group header Default value: null. + DESCRIPTION=String Inserted into the read group header Default value: null. + </help> +</tool> diff -r 603924d3abc3057def82337b53178ad48a71b1d1 -r 125d735c689ee60ad9bd9601c7a22738ba3523de tools/picard/picard_MarkDuplicates.xml --- a/tools/picard/picard_MarkDuplicates.xml +++ b/tools/picard/picard_MarkDuplicates.xml @@ -1,4 +1,4 @@ -<tool name="Mark Duplicates" id="picard_MarkDuplicates" version="0.01"> +<tool name="Mark Duplicates" id="picard_MarkDuplicates" version="0.01.1"><command interpreter="python"> picard_wrapper.py --input="$input_file" @@ -20,7 +20,7 @@ --output-sam=$outFileBamMarked #end if #end if - -j "${GALAXY_DATA_INDEX_DIR}/shared/jars/" + -j "${GALAXY_DATA_INDEX_DIR}/shared/jars/picard/" --picard-cmd="MarkDuplicates" </command><inputs> diff -r 603924d3abc3057def82337b53178ad48a71b1d1 -r 125d735c689ee60ad9bd9601c7a22738ba3523de tools/picard/picard_ReorderSam.xml --- a/tools/picard/picard_ReorderSam.xml +++ b/tools/picard/picard_ReorderSam.xml @@ -1,4 +1,4 @@ -<tool name="Reorder SAM/BAM" id="picard_ReorderSam" version="0.3.0"> +<tool name="Reorder SAM/BAM" id="picard_ReorderSam" version="0.3.1"><requirements><requirement type="package">picard</requirement></requirements><command interpreter="python"> picard_wrapper.py @@ -15,7 +15,7 @@ --allow-contig-len-discord=$allowContigLenDiscord --output-format=$outputFormat --output=$outFile - -j "${GALAXY_DATA_INDEX_DIR}/shared/jars/ReorderSam.jar" + -j "${GALAXY_DATA_INDEX_DIR}/shared/jars/picard/ReorderSam.jar" </command><inputs><param format="bam,sam" name="inputFile" type="data" label="SAM/BAM dataset to be reordered" diff -r 603924d3abc3057def82337b53178ad48a71b1d1 -r 125d735c689ee60ad9bd9601c7a22738ba3523de tools/picard/picard_ReplaceSamHeader.xml --- a/tools/picard/picard_ReplaceSamHeader.xml +++ b/tools/picard/picard_ReplaceSamHeader.xml @@ -1,4 +1,4 @@ -<tool name="Replace SAM/BAM Header" id="picard_ReplaceSamHeader" version="0.2.0"> +<tool name="Replace SAM/BAM Header" id="picard_ReplaceSamHeader" version="0.2.1"><requirements><requirement type="package">picard</requirement></requirements><command interpreter="python"> picard_wrapper.py @@ -6,7 +6,7 @@ -o $outFile --header-file $headerFile --output-format $outputFormat - -j "${GALAXY_DATA_INDEX_DIR}/shared/jars/ReplaceSamHeader.jar" + -j "${GALAXY_DATA_INDEX_DIR}/shared/jars/picard/ReplaceSamHeader.jar" --tmpdir "${__new_file_path__}" </command><inputs> diff -r 603924d3abc3057def82337b53178ad48a71b1d1 -r 125d735c689ee60ad9bd9601c7a22738ba3523de tools/picard/picard_SamToFastq.xml --- /dev/null +++ b/tools/picard/picard_SamToFastq.xml @@ -0,0 +1,157 @@ +<tool id="picard_SamToFastq" name="SAM to FASTQ" version="0.0.1"> + <description>creates a FASTQ file</description> + <requirements><requirement type="package">picard</requirement></requirements> + <command>java -XX:DefaultMaxRAMFraction=1 -XX:+UseParallelGC + -jar "${GALAXY_DATA_INDEX_DIR}/shared/jars/picard/SamToFastq.jar" + INPUT="${input_sam}" + RE_REVERSE=${re_reverse} + INCLUDE_NON_PF_READS=${include_non_pf_reads} + #if str( $clipping_attribute ): + CLIPPING_ATTRIBUTE="${clipping_attribute}" + #end if + #if str( $clipping_action ): + CLIPPING_ACTION="${clipping_action}" + #end if + #if str( $read1_trim ): + READ1_TRIM="${read1_trim}" + #end if + #if str( $read1_max_bases_to_write ): + READ1_MAX_BASES_TO_WRITE="${read1_max_bases_to_write}" + #end if + INCLUDE_NON_PRIMARY_ALIGNMENTS=${include_non_primary_alignments} + + #if str( $output_per_read_group_selector ) == 'per_sam_file': + ##OUTPUT_PER_RG=false + FASTQ="${output_fastq1}" + + #if str( $single_paired_end_type.single_paired_end_type_selector ) == 'paired': + SECOND_END_FASTQ="${output_fastq2}" + #if str( $single_paired_end_type.read2_trim ): + READ2_TRIM="${single_paired_end_type.read2_trim}" + #end if + #if str( $single_paired_end_type.read2_max_bases_to_write ): + READ2_MAX_BASES_TO_WRITE="${single_paired_end_type.read2_max_bases_to_write}" + #end if + #end if + #else: + #raise Exception( 'Per Read Group not yet supported.' ) + OUTPUT_PER_RG=true + OUTPUT_DIR="./picard_sam_to_fastq_tmp_dir/" + #end if + 2>&1 + || echo "Error running SamToFastq" >&2 + </command> + <inputs> + <param name="input_sam" type="data" format="sam" label="SAM file" /> + <param name="read1_trim" type="integer" value="" optional="True" label="The number of bases to trim from the beginning of read 1." /> + <param name="read1_max_bases_to_write" type="integer" optional="True" value="" label="The maximum number of bases to write from read 1 after trimming." /> + <param name="output_per_read_group_selector" type="select" label="Output per read group"> + <option value="per_sam_file" selected="True">Per SAM file</option> + <!-- <option value="per_read_group">Per Read Group</option> --> + <validator type="expression" message="Per Read Group selection is not yet implemented">value == 'per_sam_file'</validator> + </param> + <conditional name="single_paired_end_type"> + <param name="single_paired_end_type_selector" type="select" label="Single or Paired end"> + <option value="single" selected="True">Single</option> + <option value="paired">Paired end</option> + </param> + <when value="single"> + <!-- nothing yet --> + </when> + <when value="paired"> + <param name="read2_trim" type="integer" value="" optional="True" label="The number of bases to trim from the beginning of read 2." /> + <param name="read2_max_bases_to_write" type="integer" optional="True" value="" label="The maximum number of bases to write from read 2 after trimming." /> + </when> + </conditional> + <param name="re_reverse" type="boolean" truevalue="true" falsevalue="false" checked="True" label="Re-reverse bases and qualities of reads on negative strand"/> + <param name="include_non_pf_reads" type="boolean" truevalue="true" falsevalue="false" checked="False" label="Include non-PF reads from the SAM file into the output FASTQ files."/> + <param name="clipping_attribute" type="text" value="" label="The attribute that stores the position at which the SAM record should be clipped" help="Leave blank for null" /> + <param name="clipping_action" type="text" value="" label="The action that should be taken with clipped reads" help="'X' means the reads and qualities should be trimmed at the clipped position; 'N' means the bases should be changed to Ns in the clipped region; and any integer means that the base qualities should be set to that value in the clipped region. Leave blank for null" /> + <param name="include_non_primary_alignments" type="boolean" truevalue="true" falsevalue="false" checked="False" label="If true, include non-primary alignments in the output." help="Support of non-primary alignments in SamToFastq is not comprehensive, so there may be exceptions if this is set to true and there are paired reads with non-primary alignments."/> + + </inputs> + <outputs> + <data format="fastqsanger" name="output_fastq1" label="${tool.name} on ${on_string}: FASTQ 1" /> + <data format="fastqsanger" name="output_fastq2" label="${tool.name} on ${on_string}: FASTQ 2" > + <filter>single_paired_end_type['single_paired_end_type_selector'] == 'paired'</filter> + </data> + </outputs> + <tests> + <test> + <param name="input_sam" value="bfast_out1.sam" ftype="sam" /> + <param name="output_per_read_group_selector" value="per_sam_file" /> + <param name="single_paired_end_type_selector" value="single" /> + <param name="read1_trim" value="" /> + <param name="read1_max_bases_to_write" value="" /> + <param name="re_reverse" value="True" /> + <param name="include_non_pf_reads" value="False" /> + <param name="clipping_action" value="" /> + <param name="clipping_attribute" value="" /> + <param name="include_non_primary_alignments" value="False" /> + <output name="output_fastq1" file="random_phiX_1.fastqsanger"/> + </test> + <test> + <param name="input_sam" value="bwa_wrapper_out3.sam" ftype="sam" /> + <param name="output_per_read_group_selector" value="per_sam_file" /> + <param name="single_paired_end_type_selector" value="paired" /> + <param name="read1_trim" value="" /> + <param name="read1_max_bases_to_write" value="" /> + <param name="read2_trim" value="" /> + <param name="read2_max_bases_to_write" value="" /> + <param name="re_reverse" value="True" /> + <param name="include_non_pf_reads" value="False" /> + <param name="clipping_action" value="" /> + <param name="clipping_attribute" value="" /> + <param name="include_non_primary_alignments" value="False" /> + <output name="output_fastq1" file="bwa_wrapper_in2.fastqsanger" lines_diff="64"/><!-- 16 unaligned fastq blocks not present in original sam file --> + <output name="output_fastq2" file="bwa_wrapper_in3.fastqsanger" lines_diff="64"/><!-- 16 unaligned fastq blocks not present in original sam file --> + </test> + </tests> + <help> +**What it does** + +Picard: SamToFastq converts SAM files to FASTQ files. + +Extracts read sequences and qualities from the input SAM/BAM file and writes them into the output file in Sanger fastq format. In the RC mode (default is True), if the read is aligned and the alignment is to the reverse strand on the genome, the read's sequence from input SAM file will be reverse-complemented prior to writing it to fastq in order restore correctly the original read sequence as it was generated by the sequencer. + +------ + +Please cite the website "http://picard.sourceforge.net". + +------ + + +**Input formats** + +FastqToSam accepts SAM input files, see http://samtools.sourceforge.net for more details. + +------ + +**Outputs** + +The output is in FASTQ format. If using Paired end data, 2 fastq files are created. + +------- + +**FastqToSam settings** + +This is list of SamToFastq options:: + + INPUT=File Input SAM/BAM file to extract reads from Required. + FASTQ=File Output fastq file (single-end fastq or, if paired, first end of the pair fastq). Required. Cannot be used in conjuction with option(s) OUTPUT_PER_RG (OPRG) + SECOND_END_FASTQ=File Output fastq file (if paired, second end of the pair fastq). Default value: null. Cannot be used in conjuction with option(s) OUTPUT_PER_RG (OPRG) + OUTPUT_PER_RG=Boolean Output a fastq file per read group (two fastq files per read group if the group is paired). Default value: false. This option can be set to 'null' to clear the default value. Possible values: {true, false} Cannot be used in conjuction with option(s) SECOND_END_FASTQ (F2) FASTQ (F) + OUTPUT_DIR=File Directory in which to output the fastq file(s). Used only when OUTPUT_PER_RG is true. Default value: null. + RE_REVERSE=Boolean Re-reverse bases and qualities of reads with negative strand flag set before writing them to fastq Default value: true. This option can be set to 'null' to clear the default value. Possible values: {true, false} + INCLUDE_NON_PF_READS=Boolean Include non-PF reads from the SAM file into the output FASTQ files. Default value: false. This option can be set to 'null' to clear the default value. Possible values: {true, false} + CLIPPING_ATTRIBUTE=String The attribute that stores the position at which the SAM record should be clipped Default value: null. + CLIPPING_ACTION=String The action that should be taken with clipped reads: 'X' means the reads and qualities should be trimmed at the clipped position; 'N' means the bases should be changed to Ns in the clipped region; and any integer means that the base qualities should be set to that value in the clipped region. Default value: null. + READ1_TRIM=Integer The number of bases to trim from the beginning of read 1. Default value: 0. This option can be set to 'null' to clear the default value. + READ1_MAX_BASES_TO_WRITE=Integer The maximum number of bases to write from read 1 after trimming. If there are fewer than this many bases left after trimming, all will be written. If this value is null then all bases left after trimming will be written. Default value: null. + READ2_TRIM=Integer The number of bases to trim from the beginning of read 2. Default value: 0. This option can be set to 'null' to clear the default value. + READ2_MAX_BASES_TO_WRITE=Integer The maximum number of bases to write from read 2 after trimming. If there are fewer than this many bases left after trimming, all will be written. If this value is null then all bases left after trimming will be written. Default value: null. + INCLUDE_NON_PRIMARY_ALIGNMENTS=Boolean If true, include non-primary alignments in the output. Support of non-primary alignments in SamToFastq is not comprehensive, so there may be exceptions if this is set to true and there are paired reads with non-primary alignments. Default value: false. This option can be set to 'null' to clear the default value. Possible values: {true, false} + + + </help> +</tool> diff -r 603924d3abc3057def82337b53178ad48a71b1d1 -r 125d735c689ee60ad9bd9601c7a22738ba3523de tools/picard/rgPicardASMetrics.xml --- a/tools/picard/rgPicardASMetrics.xml +++ b/tools/picard/rgPicardASMetrics.xml @@ -1,8 +1,8 @@ -<tool name="SAM/BAM Alignment Summary Metrics" id="PicardASMetrics" version="0.03"> +<tool name="SAM/BAM Alignment Summary Metrics" id="PicardASMetrics" version="0.03.1"><command interpreter="python"> picard_wrapper.py -i "$input_file" -d "$html_file.files_path" -t "$html_file" --assumesorted "$sorted" -b "$bisulphite" --adaptors "$adaptors" --maxinsert "$maxinsert" -n "$out_prefix" - -j ${GALAXY_DATA_INDEX_DIR}/shared/jars/CollectAlignmentSummaryMetrics.jar + -j ${GALAXY_DATA_INDEX_DIR}/shared/jars/picard/CollectAlignmentSummaryMetrics.jar #if $genomeSource.refGenomeSource == "history": --ref-file "$genomeSource.ownFile" #else diff -r 603924d3abc3057def82337b53178ad48a71b1d1 -r 125d735c689ee60ad9bd9601c7a22738ba3523de tools/picard/rgPicardFixMate.xml --- a/tools/picard/rgPicardFixMate.xml +++ b/tools/picard/rgPicardFixMate.xml @@ -1,8 +1,8 @@ -<tool name="Paired Read Mate Fixer" id="rgPicFixMate" version="0.2.0"> +<tool name="Paired Read Mate Fixer" id="rgPicFixMate" version="0.2.1"><description>for paired data</description><command interpreter="python"> picard_wrapper.py -i "$input_file" -o "$out_file" --tmpdir "${__new_file_path__}" -n "$out_prefix" - --output-format "$outputFormat" -j "${GALAXY_DATA_INDEX_DIR}/shared/jars/FixMateInformation.jar" --sortorder "$sortOrder" + --output-format "$outputFormat" -j "${GALAXY_DATA_INDEX_DIR}/shared/jars/picard/FixMateInformation.jar" --sortorder "$sortOrder" </command><requirements><requirement type="package">picard</requirement></requirements><inputs> diff -r 603924d3abc3057def82337b53178ad48a71b1d1 -r 125d735c689ee60ad9bd9601c7a22738ba3523de tools/picard/rgPicardGCBiasMetrics.xml --- a/tools/picard/rgPicardGCBiasMetrics.xml +++ b/tools/picard/rgPicardGCBiasMetrics.xml @@ -1,8 +1,8 @@ -<tool name="SAM/BAM GC Bias Metrics" id="PicardGCBiasMetrics" version="0.02"> +<tool name="SAM/BAM GC Bias Metrics" id="PicardGCBiasMetrics" version="0.02.1"><command interpreter="python"> picard_wrapper.py -i "$input_file" -d "$html_file.files_path" -t "$html_file" --windowsize "$windowsize" --mingenomefrac "$mingenomefrac" -n "$out_prefix" --tmpdir "${__new_file_path__}" - -j ${GALAXY_DATA_INDEX_DIR}/shared/jars/CollectGcBiasMetrics.jar + -j ${GALAXY_DATA_INDEX_DIR}/shared/jars/picard/CollectGcBiasMetrics.jar #if $genomeSource.refGenomeSource == "history": --ref-file "$genomeSource.ownFile" #else: diff -r 603924d3abc3057def82337b53178ad48a71b1d1 -r 125d735c689ee60ad9bd9601c7a22738ba3523de tools/picard/rgPicardHsMetrics.xml --- a/tools/picard/rgPicardHsMetrics.xml +++ b/tools/picard/rgPicardHsMetrics.xml @@ -1,10 +1,10 @@ -<tool name="SAM/BAM Hybrid Selection Metrics" id="PicardHsMetrics" version="0.02"> +<tool name="SAM/BAM Hybrid Selection Metrics" id="PicardHsMetrics" version="0.02.1"><description>for targeted resequencing data</description><command interpreter="python"> picard_wrapper.py -i "$input_file" -d "$html_file.files_path" -t "$html_file" --datatype "$input_file.ext" --baitbed "$bait_bed" --targetbed "$target_bed" -n "$out_prefix" --tmpdir "${__new_file_path__}" - -j "${GALAXY_DATA_INDEX_DIR}/shared/jars/CalculateHsMetrics.jar" + -j "${GALAXY_DATA_INDEX_DIR}/shared/jars/picard/CalculateHsMetrics.jar" </command><requirements><requirement type="package">picard</requirement></requirements> diff -r 603924d3abc3057def82337b53178ad48a71b1d1 -r 125d735c689ee60ad9bd9601c7a22738ba3523de tools/picard/rgPicardInsertSize.xml --- a/tools/picard/rgPicardInsertSize.xml +++ b/tools/picard/rgPicardInsertSize.xml @@ -1,10 +1,10 @@ -<tool name="Insertion size metrics" id="PicardInsertSize" version="0.3.0"> +<tool name="Insertion size metrics" id="PicardInsertSize" version="0.3.1"><description>for PAIRED data</description><requirements><requirement type="package">picard</requirement></requirements><command interpreter="python"> picard_wrapper.py -i "$input_file" -n "$out_prefix" --tmpdir "${__new_file_path__}" --taillimit "$tailLimit" --histwidth "$histWidth" --minpct "$minPct" - -j "${GALAXY_DATA_INDEX_DIR}/shared/jars/CollectInsertSizeMetrics.jar" -d "$html_file.files_path" -t "$html_file" + -j "${GALAXY_DATA_INDEX_DIR}/shared/jars/picard/CollectInsertSizeMetrics.jar" -d "$html_file.files_path" -t "$html_file" </command><inputs><param format="bam,sam" name="input_file" type="data" label="SAM/BAM dataset to generate statistics for" diff -r 603924d3abc3057def82337b53178ad48a71b1d1 -r 125d735c689ee60ad9bd9601c7a22738ba3523de tools/picard/rgPicardLibComplexity.xml --- a/tools/picard/rgPicardLibComplexity.xml +++ b/tools/picard/rgPicardLibComplexity.xml @@ -1,8 +1,8 @@ -<tool name="Estimate Library Complexity" id="rgEstLibComp" version="0.01"> +<tool name="Estimate Library Complexity" id="rgEstLibComp" version="0.01.1"><command interpreter="python"> picard_wrapper.py -i "$input_file" -n "$out_prefix" --tmpdir "${__new_file_path__}" --minid "$minIDbases" --maxdiff "$maxDiff" --minmeanq "$minMeanQ" --readregex "$readRegex" --optdupdist "$optDupeDist" - -j "${GALAXY_DATA_INDEX_DIR}/shared/jars/EstimateLibraryComplexity.jar" -d "$html_file.files_path" -t "$html_file" + -j "${GALAXY_DATA_INDEX_DIR}/shared/jars/picard/EstimateLibraryComplexity.jar" -d "$html_file.files_path" -t "$html_file" </command><inputs><param format="bam,sam" name="input_file" type="data" label="SAM/BAM dataset" diff -r 603924d3abc3057def82337b53178ad48a71b1d1 -r 125d735c689ee60ad9bd9601c7a22738ba3523de tools/picard/rgPicardMarkDups.xml --- a/tools/picard/rgPicardMarkDups.xml +++ b/tools/picard/rgPicardMarkDups.xml @@ -1,8 +1,8 @@ -<tool name="Mark Duplicate reads" id="rgPicardMarkDups" version="0.01"> +<tool name="Mark Duplicate reads" id="rgPicardMarkDups" version="0.01.1"><command interpreter="python"> picard_wrapper.py -i "$input_file" -n "$out_prefix" --tmpdir "${__new_file_path__}" -o "$out_file" --remdups "$remDups" --assumesorted "$assumeSorted" --readregex "$readRegex" --optdupdist "$optDupeDist" - -j "${GALAXY_DATA_INDEX_DIR}/shared/jars/MarkDuplicates.jar" -d "$html_file.files_path" -t "$html_file" -e "$input_file.ext" + -j "${GALAXY_DATA_INDEX_DIR}/shared/jars/picard/MarkDuplicates.jar" -d "$html_file.files_path" -t "$html_file" -e "$input_file.ext" </command><requirements><requirement type="package">picard</requirement></requirements><inputs> https://bitbucket.org/galaxy/galaxy-central/changeset/ab8fb6d1f56d/ changeset: ab8fb6d1f56d user: natefoo date: 2011-10-27 19:51:28 summary: merge affected #: 37 files diff -r 125d735c689ee60ad9bd9601c7a22738ba3523de -r ab8fb6d1f56d6677ccd9dbfa137acf6efbc4d245 lib/galaxy/web/base/controller.py --- a/lib/galaxy/web/base/controller.py +++ b/lib/galaxy/web/base/controller.py @@ -1,10 +1,11 @@ """ Contains functionality needed in every web interface """ -import os, time, logging, re, string, sys, glob, shutil, tempfile, subprocess +import os, time, logging, re, string, sys, glob, shutil, tempfile, subprocess, binascii from datetime import date, datetime, timedelta from time import strftime from galaxy import config, tools, web, util +from galaxy.util.hash_util import * from galaxy.web import error, form, url_for from galaxy.model.orm import * from galaxy.workflow.modules import * @@ -2484,3 +2485,32 @@ message = "The required file named tool_data_table_conf.xml does not exist in the Galaxy install directory." error = True return error, message +def tool_shed_encode( val ): + if isinstance( val, dict ): + value = simplejson.dumps( val ) + else: + value = val + a = hmac_new( 'ToolShedAndGalaxyMustHaveThisSameKey', value ) + b = binascii.hexlify( value ) + return "%s:%s" % ( a, b ) +def tool_shed_decode( value ): + # Extract and verify hash + a, b = value.split( ":" ) + value = binascii.unhexlify( b ) + test = hmac_new( 'ToolShedAndGalaxyMustHaveThisSameKey', value ) + assert a == test + # Restore from string + values = None + try: + values = simplejson.loads( value ) + except Exception, e: + log.debug( "Decoding json value from tool shed threw exception: %s" % str( e ) ) + if values is not None: + try: + return json_fix( values ) + except Exception, e: + log.debug( "Fixing decoded json value from tool shed threw exception: %s" % str( e ) ) + fixed_values = values + if values is None: + values = value + return values diff -r 125d735c689ee60ad9bd9601c7a22738ba3523de -r ab8fb6d1f56d6677ccd9dbfa137acf6efbc4d245 lib/galaxy/web/controllers/admin.py --- a/lib/galaxy/web/controllers/admin.py +++ b/lib/galaxy/web/controllers/admin.py @@ -4,8 +4,7 @@ from galaxy.web.framework.helpers import time_ago, iff, grids from galaxy.tools.search import ToolBoxSearch from galaxy.tools import json_fix -from galaxy.util.hash_util import * -import simplejson, binascii, logging +import logging log = logging.getLogger( __name__ ) from galaxy.actions.admin import AdminActions @@ -705,6 +704,13 @@ return trans.response.send_redirect( url ) @web.expose @web.require_admin + def find_workflows_in_tool_shed( self, trans, **kwd ): + tool_shed_url = kwd[ 'tool_shed_url' ] + galaxy_url = trans.request.host + url = '%s/repository/find_workflows?galaxy_url=%s&webapp=galaxy' % ( tool_shed_url, galaxy_url ) + return trans.response.send_redirect( url ) + @web.expose + @web.require_admin def browse_tool_shed( self, trans, **kwd ): tool_shed_url = kwd[ 'tool_shed_url' ] galaxy_url = trans.request.host @@ -736,7 +742,7 @@ section_key = 'section_%s' % kwd[ 'tool_panel_section' ] tool_section = trans.app.toolbox.tool_panel[ section_key ] # Decode the encoded repo_info_dict param value. - repo_info_dict = self.__decode( repo_info_dict ) + repo_info_dict = tool_shed_decode( repo_info_dict ) # Clone the repository to the configured location. current_working_dir = os.getcwd() for name, repo_info_tuple in repo_info_dict.items(): @@ -1157,15 +1163,6 @@ section_str += ' </tool>\n' section_str += ' </section>\n' return section_str - def __decode( self, value ): - # Extract and verify hash - a, b = value.split( ":" ) - value = binascii.unhexlify( b ) - test = hmac_new( 'ToolShedAndGalaxyMustHaveThisSameKey', value ) - assert a == test - # Restore from string - values = json_fix( simplejson.loads( value ) ) - return values ## ---- Utility methods ------------------------------------------------------- diff -r 125d735c689ee60ad9bd9601c7a22738ba3523de -r ab8fb6d1f56d6677ccd9dbfa137acf6efbc4d245 lib/galaxy/web/controllers/tracks.py --- a/lib/galaxy/web/controllers/tracks.py +++ b/lib/galaxy/web/controllers/tracks.py @@ -663,7 +663,8 @@ vis.latest_revision = vis_rev session.add( vis_rev ) session.flush() - return trans.security.encode_id(vis.id) + encoded_id = trans.security.encode_id(vis.id) + return { "id": encoded_id, "url": url_for( action='browser', id=encoded_id ) } @web.expose @web.require_login( "see all available libraries" ) diff -r 125d735c689ee60ad9bd9601c7a22738ba3523de -r ab8fb6d1f56d6677ccd9dbfa137acf6efbc4d245 lib/galaxy/web/controllers/workflow.py --- a/lib/galaxy/web/controllers/workflow.py +++ b/lib/galaxy/web/controllers/workflow.py @@ -4,7 +4,7 @@ pkg_resources.require( "simplejson" ) pkg_resources.require( "SVGFig" ) import simplejson -import base64, httplib, urllib2, sgmllib, svgfig +import base64, httplib, urllib2, sgmllib, svgfig, urllib, urllib2 import math from galaxy.web.framework.helpers import time_ago, grids from galaxy.tools.parameters import * @@ -1092,13 +1092,35 @@ trans.response.headers["Content-Disposition"] = "attachment; filename=Galaxy-Workflow-%s.ga" % ( sname ) trans.response.set_content_type( 'application/galaxy-archive' ) return stored_dict - @web.expose def import_workflow( self, trans, **kwd ): + """ + Import a workflow by reading an url, uploading a file, or receiving the textual + representation of a workflow. + """ url = kwd.get( 'url', '' ) + workflow_text = kwd.get( 'workflow_text', '' ) + webapp = kwd.get( 'webapp', 'galaxy' ) message = kwd.get( 'message', '' ) status = kwd.get( 'status', 'done' ) - if kwd.get( 'import_button', False ): + import_button = kwd.get( 'import_button', False ) + tool_shed_url = kwd.get( 'tool_shed_url', '' ) + repository_metadata_id = kwd.get( 'repository_metadata_id', '' ) + # The workflow_name parameter is in the request only if the import originated + # from a Galaxy tool shed, in which case the value was encoded. + workflow_name = kwd.get( 'workflow_name', '' ) + if workflow_name: + workflow_name = tool_shed_decode( workflow_name ) + if tool_shed_url and not import_button: + # Use urllib (send another request to the tool shed) to retrieve the workflow. + workflow_url = 'http://%s/workflow/import_workflow?repository_metadata_id=%s&workflow_name=%s&webapp=%s&open_for_url=true' % \ + ( tool_shed_url, repository_metadata_id, tool_shed_encode( workflow_name ), webapp ) + response = urllib2.urlopen( workflow_url ) + workflow_text = response.read() + response.close() + workflow_text = workflow_text + import_button = True + if import_button: workflow_data = None if url: # Load workflow from external URL @@ -1108,6 +1130,8 @@ except Exception, e: message = "Failed to open URL: <b>%s</b><br>Exception: %s" % ( url, str( e ) ) status = 'error' + elif workflow_text: + workflow_data = workflow_text else: # Load workflow from browsed file. file_data = kwd.get( 'file_data', '' ) @@ -1175,6 +1199,13 @@ else: # TODO: Figure out what to do here... pass + if tool_shed_url: + # We've received the textual representation of a workflow from a Galaxy tool shed. + message = "This workflow has been successfully imported into your local Galaxy instance." + # TODO: support https in the following url. + url = 'http://%s/workflow/view_workflow?repository_metadata_id=%s&workflow_name=%s&webapp=%s&message=%s' % \ + ( tool_shed_url, repository_metadata_id, tool_shed_encode( workflow_name ), webapp, message ) + return trans.response.send_redirect( url ) return self.list( trans ) return trans.fill_template( "workflow/import.mako", url=url, diff -r 125d735c689ee60ad9bd9601c7a22738ba3523de -r ab8fb6d1f56d6677ccd9dbfa137acf6efbc4d245 lib/galaxy/webapps/community/app.py --- a/lib/galaxy/webapps/community/app.py +++ b/lib/galaxy/webapps/community/app.py @@ -35,6 +35,8 @@ self.tag_handler = CommunityTagHandler() # Tool data tables self.tool_data_tables = galaxy.tools.data.ToolDataTableManager( self.config.tool_data_table_config_path ) + # The tool shed has no toolbox, but this attribute is still required. + self.toolbox = None # Load security policy self.security_agent = self.model.security_agent self.quota_agent = galaxy.quota.NoQuotaAgent( self.model ) diff -r 125d735c689ee60ad9bd9601c7a22738ba3523de -r ab8fb6d1f56d6677ccd9dbfa137acf6efbc4d245 lib/galaxy/webapps/community/controllers/admin.py --- a/lib/galaxy/webapps/community/controllers/admin.py +++ b/lib/galaxy/webapps/community/controllers/admin.py @@ -332,13 +332,13 @@ if 'tools' in metadata: metadata_str += '<b>Tools:</b><br/>' for tool_metadata_dict in metadata[ 'tools' ]: - metadata_str += '%s <b>%s</b><br/>' % \ - ( tool_metadata_dict[ 'id' ], tool_metadata_dict[ 'version' ] ) + metadata_str += '%s <b>%s</b><br/>' % ( tool_metadata_dict[ 'id' ], + tool_metadata_dict[ 'version' ] ) if 'workflows' in metadata: metadata_str += '<b>Workflows:</b><br/>' for workflow_metadata_dict in metadata[ 'workflows' ]: - metadata_str += '%s <b>%s</b><br/>' % \ - ( workflow_metadata_dict[ 'name' ], workflow_metadata_dict[ 'format-version' ] ) + metadata_str += '%s <b>%s</b><br/>' % ( workflow_metadata_dict[ 'name' ], + workflow_metadata_dict[ 'format-version' ] ) return metadata_str class MaliciousColumn( grids.BooleanColumn ): def get_value( self, trans, grid, repository_metadata ): diff -r 125d735c689ee60ad9bd9601c7a22738ba3523de -r ab8fb6d1f56d6677ccd9dbfa137acf6efbc4d245 lib/galaxy/webapps/community/controllers/common.py --- a/lib/galaxy/webapps/community/controllers/common.py +++ b/lib/galaxy/webapps/community/controllers/common.py @@ -1,8 +1,9 @@ -import os, string, socket, logging +import os, string, socket, logging, simplejson, binascii from time import strftime from datetime import * from galaxy.tools import * from galaxy.util.json import from_json_string, to_json_string +from galaxy.util.hash_util import * from galaxy.web.base.controller import * from galaxy.webapps.community import model from galaxy.model.orm import * @@ -126,23 +127,18 @@ def generate_workflow_metadata( trans, id, changeset_revision, exported_workflow_dict, metadata_dict ): """ Update the received metadata_dict with changes that have been applied - to the received exported_workflow_dict. Store everything except the - workflow steps in the database. + to the received exported_workflow_dict. Store everything in the database. """ - workflow_dict = { 'a_galaxy_workflow' : exported_workflow_dict[ 'a_galaxy_workflow' ], - 'name' :exported_workflow_dict[ 'name' ], - 'annotation' : exported_workflow_dict[ 'annotation' ], - 'format-version' : exported_workflow_dict[ 'format-version' ] } if 'workflows' in metadata_dict: - metadata_dict[ 'workflows' ].append( workflow_dict ) + metadata_dict[ 'workflows' ].append( exported_workflow_dict ) else: - metadata_dict[ 'workflows' ] = [ workflow_dict ] + metadata_dict[ 'workflows' ] = [ exported_workflow_dict ] return metadata_dict def new_workflow_metadata_required( trans, id, metadata_dict ): """ - TODO: Currently everything about an exported workflow except the name is hard-coded, so - there's no real way to differentiate versions of exported workflows. If this changes at - some future time, this method should be enhanced accordingly... + Currently everything about an exported workflow except the name is hard-coded, so there's + no real way to differentiate versions of exported workflows. If this changes at some future + time, this method should be enhanced accordingly. """ if 'workflows' in metadata_dict: repository_metadata = get_latest_repository_metadata( trans, id ) @@ -425,18 +421,20 @@ trans.sa_session.add( repository_metadata ) trans.sa_session.flush() else: - message = "Change set revision '%s' includes no tools or exported workflows for which metadata can be set." % str( changeset_revision ) + message = "Revision '%s' includes no tools or exported workflows for which metadata can be defined " % str( changeset_revision ) + message += "so this revision cannot be automatically installed into a local Galaxy instance." status = "error" else: # change_set is None - message = "Repository does not include change set revision '%s'." % str( changeset_revision ) + message = "This repository does not include revision '%s'." % str( changeset_revision ) status = 'error' if invalid_files: if metadata_dict: - message = "Metadata was defined for some items in change set revision '%s'. " % str( changeset_revision ) + message = "Metadata was defined for some items in revision '%s'. " % str( changeset_revision ) message += "Correct the following problems if necessary and reset metadata.<br/>" else: - message = "Metadata cannot be defined for change set revision '%s'. Correct the following problems and reset metadata.<br/>" % str( changeset_revision ) + message = "Metadata cannot be defined for revision '%s' so this revision cannot be automatically " % str( changeset_revision ) + message += "installed into a local Galaxy instance. Correct the following problems and reset metadata.<br/>" for itc_tup in invalid_files: tool_file, exception_msg = itc_tup if exception_msg.find( 'No such file or directory' ) >= 0: @@ -619,3 +617,24 @@ selected = selected_value and option_tup[1] == selected_value select_field.add_option( option_tup[0], option_tup[1], selected=selected ) return select_field +def encode( val ): + if isinstance( val, dict ): + value = simplejson.dumps( val ) + else: + value = val + a = hmac_new( 'ToolShedAndGalaxyMustHaveThisSameKey', value ) + b = binascii.hexlify( value ) + return "%s:%s" % ( a, b ) +def decode( value ): + # Extract and verify hash + a, b = value.split( ":" ) + value = binascii.unhexlify( b ) + test = hmac_new( 'ToolShedAndGalaxyMustHaveThisSameKey', value ) + assert a == test + # Restore from string + try: + values = json_fix( simplejson.loads( value ) ) + except Exception, e: + # We do not have a json string + values = value + return values diff -r 125d735c689ee60ad9bd9601c7a22738ba3523de -r ab8fb6d1f56d6677ccd9dbfa137acf6efbc4d245 lib/galaxy/webapps/community/controllers/repository.py --- a/lib/galaxy/webapps/community/controllers/repository.py +++ b/lib/galaxy/webapps/community/controllers/repository.py @@ -9,7 +9,6 @@ from galaxy.webapps.community.model import directory_hash_id from galaxy.web.framework.helpers import time_ago, iff, grids from galaxy.util.json import from_json_string, to_json_string -from galaxy.util.hash_util import * from galaxy.model.orm import * from common import * from mercurial import hg, ui, patch, commands @@ -232,7 +231,7 @@ return repository_metadata.repository.user.username return 'no user' # Grid definition - title = "Repositories with matching tools" + title = "Matching repositories" model_class = model.RepositoryMetadata template='/webapps/community/repository/grid.mako' default_sort_key = "Repository.name" @@ -376,6 +375,83 @@ # Render the list view return self.valid_repository_list_grid( trans, **kwd ) @web.expose + def find_workflows( self, trans, **kwd ): + params = util.Params( kwd ) + message = util.restore_text( params.get( 'message', '' ) ) + status = params.get( 'status', 'done' ) + webapp = params.get( 'webapp', 'community' ) + galaxy_url = kwd.get( 'galaxy_url', None ) + if galaxy_url: + trans.set_cookie( galaxy_url, name='toolshedgalaxyurl' ) + if 'operation' in kwd: + item_id = kwd.get( 'id', '' ) + if item_id: + operation = kwd[ 'operation' ].lower() + is_admin = trans.user_is_admin() + if operation == "view_or_manage_repository": + # The received id is a RepositoryMetadata id, so we have to get the repository id. + repository_metadata = get_repository_metadata_by_id( trans, item_id ) + repository_id = trans.security.encode_id( repository_metadata.repository.id ) + repository = get_repository( trans, repository_id ) + kwd[ 'id' ] = repository_id + kwd[ 'changeset_revision' ] = repository_metadata.changeset_revision + if webapp == 'community' and ( is_admin or repository.user == trans.user ): + a = 'manage_repository' + else: + a = 'view_repository' + return trans.response.send_redirect( web.url_for( controller='repository', + action=a, + **kwd ) ) + if operation == "install": + galaxy_url = trans.get_cookie( name='toolshedgalaxyurl' ) + encoded_repo_info_dict = self.__encode_repo_info_dict( trans, webapp, util.listify( item_id ) ) + # TODO: support https in the following url. + url = 'http://%s/admin/install_tool_shed_repository?tool_shed_url=%s&webapp=%s&repo_info_dict=%s' % \ + ( galaxy_url, trans.request.host, webapp, encoded_repo_info_dict ) + return trans.response.send_redirect( url ) + else: + # This can only occur when there is a multi-select grid with check boxes and an operation, + # and the user clicked the operation button without checking any of the check boxes. + return trans.show_error_message( "No items were selected." ) + workflow_names = [ item.lower() for item in util.listify( kwd.get( 'workflow_name', '' ) ) ] + exact_matches = params.get( 'exact_matches', '' ) + exact_matches_checked = CheckboxField.is_checked( exact_matches ) + match_tuples = [] + ok = True + if workflow_names: + ok, match_tuples = self.__search_repository_metadata( trans, exact_matches_checked, workflow_names=workflow_names ) + if ok: + kwd[ 'match_tuples' ] = match_tuples + # Render the list view + if webapp == 'galaxy': + # Our initial request originated from a Galaxy instance. + global_actions = [ grids.GridAction( "Browse valid repositories", + dict( controller='repository', action='browse_valid_repositories', webapp=webapp ) ), + grids.GridAction( "Search for valid tools", + dict( controller='repository', action='find_tools', webapp=webapp ) ), + grids.GridAction( "Search for workflows", + dict( controller='repository', action='find_workflows', webapp=webapp ) ) ] + self.install_matched_repository_list_grid.global_actions = global_actions + install_url_args = dict( controller='repository', action='find_workflows', webapp=webapp ) + operations = [ grids.GridOperation( "Install", url_args=install_url_args, allow_multiple=True, async_compatible=False ) ] + self.install_matched_repository_list_grid.operations = operations + return self.install_matched_repository_list_grid( trans, **kwd ) + else: + kwd[ 'message' ] = "workflow name: <b>%s</b><br/>exact matches only: <b>%s</b>" % \ + ( self.__stringify( workflow_names ), str( exact_matches_checked ) ) + self.matched_repository_list_grid.title = "Repositories with matching workflows" + return self.matched_repository_list_grid( trans, **kwd ) + else: + message = "No search performed - each field must contain the same number of comma-separated items." + status = "error" + exact_matches_check_box = CheckboxField( 'exact_matches', checked=exact_matches_checked ) + return trans.fill_template( '/webapps/community/repository/find_workflows.mako', + webapp=webapp, + workflow_name=self.__stringify( workflow_names ), + exact_matches_check_box=exact_matches_check_box, + message=message, + status=status ) + @web.expose def find_tools( self, trans, **kwd ): params = util.Params( kwd ) message = util.restore_text( params.get( 'message', '' ) ) @@ -422,7 +498,7 @@ match_tuples = [] ok = True if tool_ids or tool_names or tool_versions: - ok, match_tuples = self.__search_repository_metadata( trans, tool_ids, tool_names, tool_versions, exact_matches_checked ) + ok, match_tuples = self.__search_repository_metadata( trans, exact_matches_checked, tool_ids=tool_ids, tool_names=tool_names, tool_versions=tool_versions ) if ok: kwd[ 'match_tuples' ] = match_tuples # Render the list view @@ -431,7 +507,9 @@ global_actions = [ grids.GridAction( "Browse valid repositories", dict( controller='repository', action='browse_valid_repositories', webapp=webapp ) ), grids.GridAction( "Search for valid tools", - dict( controller='repository', action='find_tools', webapp=webapp ) ) ] + dict( controller='repository', action='find_tools', webapp=webapp ) ), + grids.GridAction( "Search for workflows", + dict( controller='repository', action='find_workflows', webapp=webapp ) ) ] self.install_matched_repository_list_grid.global_actions = global_actions install_url_args = dict( controller='repository', action='find_tools', webapp=webapp ) operations = [ grids.GridOperation( "Install", url_args=install_url_args, allow_multiple=True, async_compatible=False ) ] @@ -440,6 +518,7 @@ else: kwd[ 'message' ] = "tool id: <b>%s</b><br/>tool name: <b>%s</b><br/>tool version: <b>%s</b><br/>exact matches only: <b>%s</b>" % \ ( self.__stringify( tool_ids ), self.__stringify( tool_names ), self.__stringify( tool_versions ), str( exact_matches_checked ) ) + self.matched_repository_list_grid.title = "Repositories with matching tools" return self.matched_repository_list_grid( trans, **kwd ) else: message = "No search performed - each field must contain the same number of comma-separated items." @@ -453,59 +532,76 @@ exact_matches_check_box=exact_matches_check_box, message=message, status=status ) - def __search_repository_metadata( self, trans, tool_ids, tool_names, tool_versions, exact_matches_checked ): + def __search_repository_metadata( self, trans, exact_matches_checked, tool_ids='', tool_names='', tool_versions='', workflow_names='' ): match_tuples = [] ok = True for repository_metadata in trans.sa_session.query( model.RepositoryMetadata ): metadata = repository_metadata.metadata - tools = metadata[ 'tools' ] - for tool_dict in tools: - if tool_ids and not tool_names and not tool_versions: - for tool_id in tool_ids: - if self.__in_tool_dict( tool_dict, exact_matches_checked, tool_id=tool_id ): + if tool_ids or tool_names or tool_versions: + if 'tools' in metadata: + tools = metadata[ 'tools' ] + else: + tools = [] + for tool_dict in tools: + if tool_ids and not tool_names and not tool_versions: + for tool_id in tool_ids: + if self.__in_tool_dict( tool_dict, exact_matches_checked, tool_id=tool_id ): + match_tuples.append( ( repository_metadata.repository_id, repository_metadata.changeset_revision ) ) + elif tool_names and not tool_ids and not tool_versions: + for tool_name in tool_names: + if self.__in_tool_dict( tool_dict, exact_matches_checked, tool_name=tool_name ): + match_tuples.append( ( repository_metadata.repository_id, repository_metadata.changeset_revision ) ) + elif tool_versions and not tool_ids and not tool_names: + for tool_version in tool_versions: + if self.__in_tool_dict( tool_dict, exact_matches_checked, tool_version=tool_version ): + match_tuples.append( ( repository_metadata.repository_id, repository_metadata.changeset_revision ) ) + elif tool_ids and tool_names and not tool_versions: + if len( tool_ids ) == len( tool_names ): + match_tuples = self.__search_ids_names( tool_dict, exact_matches_checked, match_tuples, repository_metadata, tool_ids, tool_names ) + elif len( tool_ids ) == 1 or len( tool_names ) == 1: + tool_ids, tool_names = self.__make_same_length( tool_ids, tool_names ) + match_tuples = self.__search_ids_names( tool_dict, exact_matches_checked, match_tuples, repository_metadata, tool_ids, tool_names ) + else: + ok = False + elif tool_ids and tool_versions and not tool_names: + if len( tool_ids ) == len( tool_versions ): + match_tuples = self.__search_ids_versions( tool_dict, exact_matches_checked, match_tuples, repository_metadata, tool_ids, tool_versions ) + elif len( tool_ids ) == 1 or len( tool_versions ) == 1: + tool_ids, tool_versions = self.__make_same_length( tool_ids, tool_versions ) + match_tuples = self.__search_ids_versions( tool_dict, exact_matches_checked, match_tuples, repository_metadata, tool_ids, tool_versions ) + else: + ok = False + elif tool_versions and tool_names and not tool_ids: + if len( tool_versions ) == len( tool_names ): + match_tuples = self.__search_names_versions( tool_dict, exact_matches_checked, match_tuples, repository_metadata, tool_names, tool_versions ) + elif len( tool_versions ) == 1 or len( tool_names ) == 1: + tool_versions, tool_names = self.__make_same_length( tool_versions, tool_names ) + match_tuples = self.__search_names_versions( tool_dict, exact_matches_checked, match_tuples, repository_metadata, tool_names, tool_versions ) + else: + ok = False + elif tool_versions and tool_names and tool_ids: + if len( tool_versions ) == len( tool_names ) and len( tool_names ) == len( tool_ids ): + for i, tool_version in enumerate( tool_versions ): + tool_name = tool_names[ i ] + tool_id = tool_ids[ i ] + if self.__in_tool_dict( tool_dict, exact_matches_checked, tool_id=tool_id, tool_name=tool_name, tool_version=tool_version ): + match_tuples.append( ( repository_metadata.repository_id, repository_metadata.changeset_revision ) ) + else: + ok = False + if workflow_names: + if 'workflows' in metadata: + workflows = metadata[ 'workflows' ] + else: + workflows = [] + for workflow_dict in workflows: + for workflow_name in workflow_names: + if self.__in_workflow_dict( workflow_dict, exact_matches_checked, workflow_name=workflow_name ): match_tuples.append( ( repository_metadata.repository_id, repository_metadata.changeset_revision ) ) - elif tool_names and not tool_ids and not tool_versions: - for tool_name in tool_names: - if self.__in_tool_dict( tool_dict, exact_matches_checked, tool_name=tool_name ): - match_tuples.append( ( repository_metadata.repository_id, repository_metadata.changeset_revision ) ) - elif tool_versions and not tool_ids and not tool_names: - for tool_version in tool_versions: - if self.__in_tool_dict( tool_dict, exact_matches_checked, tool_version=tool_version ): - match_tuples.append( ( repository_metadata.repository_id, repository_metadata.changeset_revision ) ) - elif tool_ids and tool_names and not tool_versions: - if len( tool_ids ) == len( tool_names ): - match_tuples = self.__search_ids_names( tool_dict, exact_matches_checked, match_tuples, repository_metadata, tool_ids, tool_names ) - elif len( tool_ids ) == 1 or len( tool_names ) == 1: - tool_ids, tool_names = self.__make_same_length( tool_ids, tool_names ) - match_tuples = self.__search_ids_names( tool_dict, exact_matches_checked, match_tuples, repository_metadata, tool_ids, tool_names ) - else: - ok = False - elif tool_ids and tool_versions and not tool_names: - if len( tool_ids ) == len( tool_versions ): - match_tuples = self.__search_ids_versions( tool_dict, exact_matches_checked, match_tuples, repository_metadata, tool_ids, tool_versions ) - elif len( tool_ids ) == 1 or len( tool_versions ) == 1: - tool_ids, tool_versions = self.__make_same_length( tool_ids, tool_versions ) - match_tuples = self.__search_ids_versions( tool_dict, exact_matches_checked, match_tuples, repository_metadata, tool_ids, tool_versions ) - else: - ok = False - elif tool_versions and tool_names and not tool_ids: - if len( tool_versions ) == len( tool_names ): - match_tuples = self.__search_names_versions( tool_dict, exact_matches_checked, match_tuples, repository_metadata, tool_names, tool_versions ) - elif len( tool_versions ) == 1 or len( tool_names ) == 1: - tool_versions, tool_names = self.__make_same_length( tool_versions, tool_names ) - match_tuples = self.__search_names_versions( tool_dict, exact_matches_checked, match_tuples, repository_metadata, tool_names, tool_versions ) - else: - ok = False - elif tool_versions and tool_names and tool_ids: - if len( tool_versions ) == len( tool_names ) and len( tool_names ) == len( tool_ids ): - for i, tool_version in enumerate( tool_versions ): - tool_name = tool_names[ i ] - tool_id = tool_ids[ i ] - if self.__in_tool_dict( tool_dict, exact_matches_checked, tool_id=tool_id, tool_name=tool_name, tool_version=tool_version ): - match_tuples.append( ( repository_metadata.repository_id, repository_metadata.changeset_revision ) ) - else: - ok = False return ok, match_tuples + def __in_workflow_dict( self, workflow_dict, exact_matches_checked, workflow_name=None ): + workflow_dict_workflow_name = workflow_dict[ 'name' ].lower() + return ( workflow_name == workflow_dict_workflow_name ) or \ + ( not exact_matches_checked and workflow_dict_workflow_name.find( workflow_name ) >= 0 ) def __in_tool_dict( self, tool_dict, exact_matches_checked, tool_id=None, tool_name=None, tool_version=None ): found = False if tool_id and not tool_name and not tool_version: @@ -588,15 +684,7 @@ changeset_revision = repository_metadata.changeset_revision repository_clone_url = generate_clone_url( trans, repository_id ) repo_info_dict[ repository.name ] = ( repository.description, repository_clone_url, changeset_revision ) - return self.__encode( repo_info_dict ) - def __encode( self, val ): - if isinstance( val, dict ): - value = simplejson.dumps( val ) - else: - value = val - a = hmac_new( 'ToolShedAndGalaxyMustHaveThisSameKey', value ) - b = binascii.hexlify( value ) - return "%s:%s" % ( a, b ) + return encode( repo_info_dict ) @web.expose def preview_tools_in_changeset( self, trans, repository_id, **kwd ): params = util.Params( kwd ) @@ -607,8 +695,10 @@ changeset_revision = util.restore_text( params.get( 'changeset_revision', repository.tip ) ) repository_metadata = get_repository_metadata_by_changeset_revision( trans, repository_id, changeset_revision ) if repository_metadata: + repository_metadata_id = trans.security.encode_id( repository_metadata.id ), metadata = repository_metadata.metadata else: + repository_metadata_id = None metadata = None revision_label = get_revision_label( trans, repository, changeset_revision ) changeset_revision_select_field = build_changeset_revision_select_field( trans, @@ -617,6 +707,7 @@ add_id_to_name=False ) return trans.fill_template( '/webapps/community/repository/preview_tools_in_changeset.mako', repository=repository, + repository_metadata_id=repository_metadata_id, changeset_revision=changeset_revision, revision_label=revision_label, changeset_revision_select_field=changeset_revision_select_field, @@ -636,7 +727,7 @@ changeset_revision = util.restore_text( params.get( 'changeset_revision', repository.tip ) ) repo_info_dict = {} repo_info_dict[ repository.name ] = ( repository.description, repository_clone_url, changeset_revision ) - encoded_repo_info_dict = self.__encode( repo_info_dict ) + encoded_repo_info_dict = encode( repo_info_dict ) # Redirect back to local Galaxy to perform install. # TODO: support https in the following url. url = 'http://%s/admin/install_tool_shed_repository?tool_shed_url=%s&repo_info_dict=%s' % \ @@ -1159,8 +1250,10 @@ revision_label = get_revision_label( trans, repository, changeset_revision ) repository_metadata = get_repository_metadata_by_changeset_revision( trans, id, changeset_revision ) if repository_metadata: + repository_metadata_id = trans.security.encode_id( repository_metadata.id ), metadata = repository_metadata.metadata else: + repository_metadata_id = None metadata = None is_malicious = change_set_is_malicious( trans, id, repository.tip ) if is_malicious: @@ -1172,6 +1265,7 @@ return trans.fill_template( '/webapps/community/repository/view_repository.mako', repo=repo, repository=repository, + repository_metadata_id=repository_metadata_id, metadata=metadata, avg_rating=avg_rating, display_reviews=display_reviews, @@ -1299,9 +1393,11 @@ revision_label = get_revision_label( trans, repository, changeset_revision ) repository_metadata = get_repository_metadata_by_changeset_revision( trans, id, changeset_revision ) if repository_metadata: + repository_metadata_id = trans.security.encode_id( repository_metadata.id ) metadata = repository_metadata.metadata is_malicious = repository_metadata.malicious else: + repository_metadata_id = None metadata = None is_malicious = False if is_malicious: @@ -1321,6 +1417,7 @@ allow_push_select_field=allow_push_select_field, repo=repo, repository=repository, + repository_metadata_id=repository_metadata_id, changeset_revision=changeset_revision, changeset_revision_select_field=changeset_revision_select_field, revision_label=revision_label, diff -r 125d735c689ee60ad9bd9601c7a22738ba3523de -r ab8fb6d1f56d6677ccd9dbfa137acf6efbc4d245 lib/galaxy/webapps/community/controllers/workflow.py --- /dev/null +++ b/lib/galaxy/webapps/community/controllers/workflow.py @@ -0,0 +1,395 @@ +import pkg_resources +pkg_resources.require( "simplejson" ) +pkg_resources.require( "SVGFig" ) +import os, logging, ConfigParser, tempfile, shutil, svgfig +from galaxy.webapps.community import model +from galaxy.web.framework.helpers import time_ago, iff, grids +from galaxy.util.json import from_json_string, to_json_string +from galaxy.workflow.modules import InputDataModule, ToolModule, WorkflowModuleFactory +from galaxy.tools import DefaultToolState +from galaxy.web.controllers.workflow import attach_ordered_steps +from galaxy.model.orm import * +from common import * + +class RepoInputDataModule( InputDataModule ): + + type = "data_input" + name = "Input dataset" + + @classmethod + def new( Class, trans, tools_metadata=None, tool_id=None ): + module = Class( trans ) + module.state = dict( name="Input Dataset" ) + return module + @classmethod + def from_dict( Class, trans, d, tools_metadata=None, secure=True ): + module = Class( trans ) + state = from_json_string( d[ "tool_state" ] ) + module.state = dict( name=state.get( "name", "Input Dataset" ) ) + return module + @classmethod + def from_workflow_step( Class, trans, tools_metadata, step ): + module = Class( trans ) + module.state = dict( name="Input Dataset" ) + if step.tool_inputs and "name" in step.tool_inputs: + module.state[ 'name' ] = step.tool_inputs[ 'name' ] + return module + +class RepoToolModule( ToolModule ): + + type = "tool" + + def __init__( self, trans, tools_metadata, tool_id ): + self.trans = trans + self.tools_metadata = tools_metadata + self.tool_id = tool_id + self.tool = None + for tool_dict in tools_metadata: + if self.tool_id in [ tool_dict[ 'id' ], tool_dict[ 'guid' ] ]: + self.tool = load_tool( trans, os.path.abspath( tool_dict[ 'tool_config' ] ) ) + self.post_job_actions = {} + self.workflow_outputs = [] + self.state = None + self.errors = None + @classmethod + def new( Class, trans, tools_metadata, tool_id=None ): + module = Class( trans, tools_metadata, tool_id ) + module.state = module.tool.new_state( trans, all_pages=True ) + return module + @classmethod + def from_dict( Class, trans, d, tools_metadata, secure=True ): + tool_id = d[ 'tool_id' ] + module = Class( trans, tools_metadata, tool_id ) + module.state = DefaultToolState() + if module.tool is not None: + module.state.decode( d[ "tool_state" ], module.tool, module.trans.app, secure=secure ) + module.errors = d.get( "tool_errors", None ) + return module + @classmethod + def from_workflow_step( Class, trans, tools_metadata, step ): + module = Class( trans, tools_metadata, step.tool_id ) + module.state = DefaultToolState() + if module.tool: + module.state.inputs = module.tool.params_from_strings( step.tool_inputs, trans.app, ignore_errors=True ) + else: + module.state.inputs = {} + module.errors = step.tool_errors + return module + def get_data_inputs( self ): + data_inputs = [] + def callback( input, value, prefixed_name, prefixed_label ): + if isinstance( input, DataToolParameter ): + data_inputs.append( dict( name=prefixed_name, + label=prefixed_label, + extensions=input.extensions ) ) + if self.tool: + visit_input_values( self.tool.inputs, self.state.inputs, callback ) + return data_inputs + def get_data_outputs( self ): + data_outputs = [] + if self.tool: + data_inputs = None + for name, tool_output in self.tool.outputs.iteritems(): + if tool_output.format_source != None: + # Default to special name "input" which remove restrictions on connections + formats = [ 'input' ] + if data_inputs == None: + data_inputs = self.get_data_inputs() + # Find the input parameter referenced by format_source + for di in data_inputs: + # Input names come prefixed with conditional and repeat names separated by '|', + # so remove prefixes when comparing with format_source. + if di[ 'name' ] != None and di[ 'name' ].split( '|' )[ -1 ] == tool_output.format_source: + formats = di[ 'extensions' ] + else: + formats = [ tool_output.format ] + for change_elem in tool_output.change_format: + for when_elem in change_elem.findall( 'when' ): + format = when_elem.get( 'format', None ) + if format and format not in formats: + formats.append( format ) + data_outputs.append( dict( name=name, extensions=formats ) ) + return data_outputs + +class RepoWorkflowModuleFactory( WorkflowModuleFactory ): + def __init__( self, module_types ): + self.module_types = module_types + def new( self, trans, type, tools_metadata=None, tool_id=None ): + """Return module for type and (optional) tool_id intialized with new / default state.""" + assert type in self.module_types + return self.module_types[type].new( trans, tool_id ) + def from_dict( self, trans, d, **kwargs ): + """Return module initialized from the data in dictionary `d`.""" + type = d[ 'type' ] + assert type in self.module_types + return self.module_types[ type ].from_dict( trans, d, **kwargs ) + def from_workflow_step( self, trans, tools_metadata, step ): + """Return module initialized from the WorkflowStep object `step`.""" + type = step.type + return self.module_types[ type ].from_workflow_step( trans, tools_metadata, step ) + +module_factory = RepoWorkflowModuleFactory( dict( data_input=RepoInputDataModule, tool=RepoToolModule ) ) + +class WorkflowController( BaseUIController ): + @web.expose + def view_workflow( self, trans, **kwd ): + repository_metadata_id = kwd.get( 'repository_metadata_id', '' ) + workflow_name = kwd.get( 'workflow_name', '' ) + if workflow_name: + workflow_name = decode( workflow_name ) + webapp = kwd.get( 'webapp', 'community' ) + message = kwd.get( 'message', '' ) + status = kwd.get( 'status', 'done' ) + repository_metadata = get_repository_metadata_by_id( trans, repository_metadata_id ) + repository = get_repository( trans, trans.security.encode_id( repository_metadata.repository_id ) ) + return trans.fill_template( "/webapps/community/repository/view_workflow.mako", + repository=repository, + changeset_revision=repository_metadata.changeset_revision, + repository_metadata_id=repository_metadata_id, + workflow_name=workflow_name, + webapp=webapp, + message=message, + status=status ) + @web.expose + def generate_workflow_image( self, trans, repository_metadata_id, workflow_name, webapp='community' ): + repository_metadata = get_repository_metadata_by_id( trans, repository_metadata_id ) + metadata = repository_metadata.metadata + workflow_name = decode( workflow_name ) + for workflow_dict in metadata[ 'workflows' ]: + if workflow_dict[ 'name' ] == workflow_name: + break + if 'tools' in metadata: + tools_metadata = metadata[ 'tools' ] + else: + tools_metadata = [] + workflow, missing_tool_tups = self.__workflow_from_dict( trans, workflow_dict, tools_metadata ) + data = [] + canvas = svgfig.canvas( style="stroke:black; fill:none; stroke-width:1px; stroke-linejoin:round; text-anchor:left" ) + text = svgfig.SVG( "g" ) + connectors = svgfig.SVG( "g" ) + boxes = svgfig.SVG( "g" ) + svgfig.Text.defaults[ "font-size" ] = "10px" + in_pos = {} + out_pos = {} + margin = 5 + # Spacing between input/outputs. + line_px = 16 + # Store px width for boxes of each step. + widths = {} + max_width, max_x, max_y = 0, 0, 0 + for step in workflow.steps: + step.upgrade_messages = {} + module = module_factory.from_workflow_step( trans, tools_metadata, step ) + tool_errors = module.type == 'tool' and not module.tool + module_data_inputs = self.__get_data_inputs( step, module ) + module_data_outputs = self.__get_data_outputs( step, module, workflow.steps ) + step_dict = { + 'id' : step.order_index, + 'data_inputs' : module_data_inputs, + 'data_outputs' : module_data_outputs, + 'position' : step.position, + 'tool_errors' : tool_errors + } + input_conn_dict = {} + for conn in step.input_connections: + input_conn_dict[ conn.input_name ] = dict( id=conn.output_step.order_index, output_name=conn.output_name ) + step_dict[ 'input_connections' ] = input_conn_dict + data.append( step_dict ) + x, y = step.position[ 'left' ], step.position[ 'top' ] + count = 0 + module_name = self.__get_name( module, missing_tool_tups ) + max_len = len( module_name ) * 1.5 + text.append( svgfig.Text( x, y + 20, module_name, **{ "font-size": "14px" } ).SVG() ) + y += 45 + for di in module_data_inputs: + cur_y = y + count * line_px + if step.order_index not in in_pos: + in_pos[ step.order_index ] = {} + in_pos[ step.order_index ][ di[ 'name' ] ] = ( x, cur_y ) + text.append( svgfig.Text( x, cur_y, di[ 'label' ] ).SVG() ) + count += 1 + max_len = max( max_len, len( di[ 'label' ] ) ) + if len( module.get_data_inputs() ) > 0: + y += 15 + for do in module_data_outputs: + cur_y = y + count * line_px + if step.order_index not in out_pos: + out_pos[ step.order_index ] = {} + out_pos[ step.order_index ][ do[ 'name' ] ] = ( x, cur_y ) + text.append( svgfig.Text( x, cur_y, do[ 'name' ] ).SVG() ) + count += 1 + max_len = max( max_len, len( do['name' ] ) ) + widths[ step.order_index ] = max_len * 5.5 + max_x = max( max_x, step.position[ 'left' ] ) + max_y = max( max_y, step.position[ 'top' ] ) + max_width = max( max_width, widths[ step.order_index ] ) + for step_dict in data: + tool_unavailable = step_dict[ 'tool_errors' ] + width = widths[ step_dict[ 'id' ] ] + x, y = step_dict[ 'position' ][ 'left' ], step_dict[ 'position' ][ 'top' ] + if tool_unavailable: + fill = "#EBBCB2" + else: + fill = "#EBD9B2" + boxes.append( svgfig.Rect( x - margin, y, x + width - margin, y + 30, fill=fill ).SVG() ) + box_height = ( len( step_dict[ 'data_inputs' ] ) + len( step_dict[ 'data_outputs' ] ) ) * line_px + margin + # Draw separator line. + if len( step_dict[ 'data_inputs' ] ) > 0: + box_height += 15 + sep_y = y + len( step_dict[ 'data_inputs' ] ) * line_px + 40 + text.append( svgfig.Line( x - margin, sep_y, x + width - margin, sep_y ).SVG() ) + # Define an input/output box. + boxes.append( svgfig.Rect( x - margin, y + 30, x + width - margin, y + 30 + box_height, fill="#ffffff" ).SVG() ) + for conn, output_dict in step_dict[ 'input_connections' ].iteritems(): + in_coords = in_pos[ step_dict[ 'id' ] ][ conn ] + out_conn_pos = out_pos[ output_dict[ 'id' ] ][ output_dict[ 'output_name' ] ] + adjusted = ( out_conn_pos[ 0 ] + widths[ output_dict[ 'id' ] ], out_conn_pos[ 1 ] ) + text.append( svgfig.SVG( "circle", + cx=out_conn_pos[ 0 ] + widths[ output_dict[ 'id' ] ] - margin, + cy=out_conn_pos[ 1 ] - margin, + r = 5, + fill="#ffffff" ) ) + connectors.append( svgfig.Line( adjusted[ 0 ], + adjusted[ 1 ] - margin, + in_coords[ 0 ] - 10, + in_coords[ 1 ], + arrow_end = "true" ).SVG() ) + canvas.append( connectors ) + canvas.append( boxes ) + canvas.append( text ) + width, height = ( max_x + max_width + 50 ), max_y + 300 + canvas[ 'width' ] = "%s px" % width + canvas[ 'height' ] = "%s px" % height + canvas[ 'viewBox' ] = "0 0 %s %s" % ( width, height ) + trans.response.set_content_type( "image/svg+xml" ) + return canvas.standalone_xml() + def __get_name( self, module, missing_tool_tups ): + module_name = module.get_name() + if module.type == 'tool' and module_name == 'unavailable': + for missing_tool_tup in missing_tool_tups: + missing_tool_id, missing_tool_name, missing_tool_version = missing_tool_tup + if missing_tool_id == module.tool_id: + module_name = '%s' % missing_tool_name + return module_name + def __get_data_inputs( self, step, module ): + if module.type == 'tool': + if module.tool: + return module.get_data_inputs() + else: + data_inputs = [] + for wfsc in step.input_connections: + data_inputs_dict = {} + data_inputs_dict[ 'extensions' ] = [ '' ] + data_inputs_dict[ 'name' ] = wfsc.input_name + data_inputs_dict[ 'label' ] = 'Unknown' + data_inputs.append( data_inputs_dict ) + return data_inputs + return module.get_data_inputs() + def __get_data_outputs( self, step, module, steps ): + if module.type == 'tool': + if module.tool: + return module.get_data_outputs() + else: + data_outputs = [] + data_outputs_dict = {} + data_outputs_dict[ 'extensions' ] = [ 'input' ] + found = False + for workflow_step in steps: + for wfsc in workflow_step.input_connections: + if step.name == wfsc.output_step.name: + data_outputs_dict[ 'name' ] = wfsc.output_name + found = True + break + if found: + break + if not found: + # We're at the last step of the workflow. + data_outputs_dict[ 'name' ] = 'output' + data_outputs.append( data_outputs_dict ) + return data_outputs + return module.get_data_outputs() + def __workflow_from_dict( self, trans, data, tools_metadata ): + """Creates and returns workflow object from a dictionary.""" + trans.workflow_building_mode = True + workflow = model.Workflow() + workflow.name = data[ 'name' ] + workflow.has_errors = False + steps = [] + # Keep ids for each step that we need to use to make connections. + steps_by_external_id = {} + # Keep track of tools required by the workflow that are not available in + # the tool shed repository. Each tuple in the list of missing_tool_tups + # will be ( tool_id, tool_name, tool_version ). + missing_tool_tups = [] + # First pass to build step objects and populate basic values + for key, step_dict in data[ 'steps' ].iteritems(): + # Create the model class for the step + step = model.WorkflowStep() + step.name = step_dict[ 'name' ] + step.position = step_dict[ 'position' ] + module = module_factory.from_dict( trans, step_dict, tools_metadata=tools_metadata, secure=False ) + if module.type == 'tool' and module.tool is None: + # A required tool is not available in the current repository. + step.tool_errors = 'unavailable' + missing_tool_tup = ( step_dict[ 'tool_id' ], step_dict[ 'name' ], step_dict[ 'tool_version' ] ) + if missing_tool_tup not in missing_tool_tups: + missing_tool_tups.append( missing_tool_tup ) + module.save_to_step( step ) + if step.tool_errors: + workflow.has_errors = True + # Stick this in the step temporarily. + step.temp_input_connections = step_dict[ 'input_connections' ] + # Unpack and add post-job actions. + post_job_actions = step_dict.get( 'post_job_actions', {} ) + for name, pja_dict in post_job_actions.items(): + pja = PostJobAction( pja_dict[ 'action_type' ], + step, pja_dict[ 'output_name' ], + pja_dict[ 'action_arguments' ] ) + steps.append( step ) + steps_by_external_id[ step_dict[ 'id' ] ] = step + # Second pass to deal with connections between steps. + for step in steps: + # Input connections. + for input_name, conn_dict in step.temp_input_connections.iteritems(): + if conn_dict: + output_step = steps_by_external_id[ conn_dict[ 'id' ] ] + conn = model.WorkflowStepConnection() + conn.input_step = step + conn.input_name = input_name + conn.output_step = output_step + conn.output_name = conn_dict[ 'output_name' ] + step.input_connections.append( conn ) + del step.temp_input_connections + # Order the steps if possible. + attach_ordered_steps( workflow, steps ) + return workflow, missing_tool_tups + @web.expose + def import_workflow( self, trans, **kwd ): + repository_metadata_id = kwd.get( 'repository_metadata_id', '' ) + workflow_name = kwd.get( 'workflow_name', '' ) + if workflow_name: + workflow_name = decode( workflow_name ) + webapp = kwd.get( 'webapp', 'community' ) + message = kwd.get( 'message', '' ) + status = kwd.get( 'status', 'done' ) + repository_metadata = get_repository_metadata_by_id( trans, repository_metadata_id ) + workflows = repository_metadata.metadata[ 'workflows' ] + workflow_data = None + for workflow_data in workflows: + if workflow_data[ 'name' ] == workflow_name: + break + if workflow_data: + if kwd.get( 'open_for_url', False ): + tmp_fd, tmp_fname = tempfile.mkstemp() + to_file = open( tmp_fname, 'wb' ) + to_file.write( to_json_string( workflow_data ) ) + return open( tmp_fname ) + galaxy_url = trans.get_cookie( name='toolshedgalaxyurl' ) + # TODO: support https in the following url. + url = 'http://%s/workflow/import_workflow?tool_shed_url=%s&repository_metadata_id=%s&workflow_name=%s&webapp=%s' % \ + ( galaxy_url, trans.request.host, repository_metadata_id, encode( workflow_name ), webapp ) + return trans.response.send_redirect( url ) + return trans.response.send_redirect( web.url_for( controller='workflow', + action='view_workflow', + message=message, + status=status ) ) diff -r 125d735c689ee60ad9bd9601c7a22738ba3523de -r ab8fb6d1f56d6677ccd9dbfa137acf6efbc4d245 lib/galaxy/webapps/community/model/__init__.py --- a/lib/galaxy/webapps/community/model/__init__.py +++ b/lib/galaxy/webapps/community/model/__init__.py @@ -204,6 +204,34 @@ self.value = None self.user_value = None +class Workflow( object ): + def __init__( self ): + self.user = None + self.name = None + self.has_cycles = None + self.has_errors = None + self.steps = [] + +class WorkflowStep( object ): + def __init__( self ): + self.id = None + self.type = None + self.name = None + self.tool_id = None + self.tool_inputs = None + self.tool_errors = None + self.position = None + self.input_connections = [] + #self.output_connections = [] + self.config = None + +class WorkflowStepConnection( object ): + def __init__( self ): + self.output_step = None + self.output_name = None + self.input_step = None + self.input_name = None + ## ---- Utility methods ------------------------------------------------------- def sort_by_attr( seq, attr ): """ diff -r 125d735c689ee60ad9bd9601c7a22738ba3523de -r ab8fb6d1f56d6677ccd9dbfa137acf6efbc4d245 lib/galaxy/workflow/modules.py --- a/lib/galaxy/workflow/modules.py +++ b/lib/galaxy/workflow/modules.py @@ -205,14 +205,14 @@ def from_workflow_step( Class, trans, step ): tool_id = step.tool_id install_tool_id = None - if tool_id not in trans.app.toolbox.tools_by_id: + if trans.app.toolbox and tool_id not in trans.app.toolbox.tools_by_id: # The id value of tools installed from a Galaxy tool shed is a guid, but # these tool's old_id attribute should contain what we're looking for. for available_tool_id, available_tool in trans.app.toolbox.tools_by_id.items(): if tool_id == available_tool.old_id: install_tool_id = available_tool_id break - if tool_id in trans.app.toolbox.tools_by_id or install_tool_id: + if ( trans.app.toolbox and tool_id in trans.app.toolbox.tools_by_id ) or install_tool_id: module = Class( trans, tool_id ) module.state = DefaultToolState() module.state.inputs = module.tool.params_from_strings( step.tool_inputs, trans.app, ignore_errors=True ) @@ -247,7 +247,9 @@ action_arguments = None n_p = PostJobAction(v['action_type'], step, output_name, action_arguments) def get_name( self ): - return self.tool.name + if self.tool: + return self.tool.name + return 'unavailable' def get_tool_id( self ): return self.tool_id def get_tool_version( self ): diff -r 125d735c689ee60ad9bd9601c7a22738ba3523de -r ab8fb6d1f56d6677ccd9dbfa137acf6efbc4d245 static/scripts/trackster.js --- a/static/scripts/trackster.js +++ b/static/scripts/trackster.js @@ -1189,6 +1189,10 @@ } }, go_to: function(str) { + // Preprocess str to remove spaces and commas. + str = str.replace(/ |,/g, ""); + + // Go to new location. var view = this, new_low, new_high, @@ -1199,8 +1203,8 @@ if (pos !== undefined) { try { var pos_split = pos.split("-"); - new_low = parseInt(pos_split[0].replace(/,/g, ""), 10); - new_high = parseInt(pos_split[1].replace(/,/g, ""), 10); + new_low = parseInt(pos_split[0], 10); + new_high = parseInt(pos_split[1], 10); } catch (e) { return false; } diff -r 125d735c689ee60ad9bd9601c7a22738ba3523de -r ab8fb6d1f56d6677ccd9dbfa137acf6efbc4d245 templates/grid_base.mako --- a/templates/grid_base.mako +++ b/templates/grid_base.mako @@ -744,7 +744,7 @@ %if grid.global_actions: <ul class="manage-table-actions"> - %if len( grid.global_actions ) < 4: + %if len( grid.global_actions ) < 3: %for action in grid.global_actions: <li><a class="action-button" href="${h.url_for( **action.url_args )}">${action.label}</a></li> %endfor diff -r 125d735c689ee60ad9bd9601c7a22738ba3523de -r ab8fb6d1f56d6677ccd9dbfa137acf6efbc4d245 templates/root/history_common.mako --- a/templates/root/history_common.mako +++ b/templates/root/history_common.mako @@ -96,7 +96,7 @@ display_url = h.url_for( controller='dataset', action='display', dataset_id=dataset_id, preview=True, filename='' ) %> %if data.purged: - <span class="icon-button display_disabled tooltip" title="Cannoy display datasets removed from disk"></span> + <span class="icon-button display_disabled tooltip" title="Cannot display datasets removed from disk"></span> %else: <a class="icon-button display tooltip" title="Display data in browser" href="${display_url}" %if for_editing: @@ -150,6 +150,9 @@ %endif </div> %elif data_state == "error": + %if not data.purged: + <div>${data.get_size( nice_size=True )}</div> + %endif <div> An error occurred running this job: <i>${data.display_info().strip()}</i></div> diff -r 125d735c689ee60ad9bd9601c7a22738ba3523de -r ab8fb6d1f56d6677ccd9dbfa137acf6efbc4d245 templates/tracks/browser.mako --- a/templates/tracks/browser.mako +++ b/templates/tracks/browser.mako @@ -212,10 +212,14 @@ 'dbkey': view.dbkey, 'payload': JSON.stringify(payload) }, - success: function(vis_id) { - view.vis_id = vis_id; + dataType: "json", + success: function(vis_info) { + hide_modal(); + view.vis_id = vis_info.vis_id; view.has_changes = false; - hide_modal(); + + // Needed to set URL when first saving a visualization. + window.history.pushState({}, "", vis_info.url); }, error: function() { alert("Could not save visualization"); } }); diff -r 125d735c689ee60ad9bd9601c7a22738ba3523de -r ab8fb6d1f56d6677ccd9dbfa137acf6efbc4d245 templates/webapps/community/index.mako --- a/templates/webapps/community/index.mako +++ b/templates/webapps/community/index.mako @@ -44,6 +44,20 @@ <div class="page-container" style="padding: 10px;"><div class="toolMenu"><div class="toolSectionList"> + %if repository_metadata: + <div class="toolSectionPad"></div> + <div class="toolSectionTitle"> + Search + </div> + <div class="toolSectionBody"> + <div class="toolTitle"> + <a target="galaxy_main" href="${h.url_for( controller='repository', action='find_tools', webapp='community' )}">Search for valid tools</a> + </div> + <div class="toolTitle"> + <a target="galaxy_main" href="${h.url_for( controller='repository', action='find_workflows', webapp='community' )}">Search for workflows</a> + </div> + </div> + %endif <div class="toolSectionPad"></div><div class="toolSectionTitle"> Repositories @@ -61,11 +75,6 @@ <a target="galaxy_main" href="${h.url_for( controller='repository', action='browse_repositories', operation='my_repositories', webapp='community' )}">Browse my repositories</a></div> %endif - %if repository_metadata: - <div class="toolTitle"> - <a target="galaxy_main" href="${h.url_for( controller='repository', action='find_tools', webapp='community' )}">Search for valid tools</a> - </div> - %endif </div></div><div class="toolSectionBody"> diff -r 125d735c689ee60ad9bd9601c7a22738ba3523de -r ab8fb6d1f56d6677ccd9dbfa137acf6efbc4d245 templates/webapps/community/repository/common.mako --- a/templates/webapps/community/repository/common.mako +++ b/templates/webapps/community/repository/common.mako @@ -83,7 +83,8 @@ hg clone <a href="${clone_str}">${clone_str}</a></%def> -<%def name="render_repository_tools_and_workflows( metadata, can_set_metadata=False, webapp='community' )"> +<%def name="render_repository_tools_and_workflows( repository_metadata_id, metadata, can_set_metadata=False, webapp='community' )"> + <% from galaxy.webapps.community.controllers.common import encode, decode %> %if metadata or can_set_metadata: <p/><div class="toolForm"> @@ -160,14 +161,34 @@ <table class="grid"><tr><td><b>name</b></td> + <td><b>steps</b></td><td><b>format-version</b></td><td><b>annotation</b></td></tr> %for workflow_dict in workflow_dicts: + <% + workflow_name = workflow_dict[ 'name' ] + if 'steps' in workflow_dict: + ## Initially steps were not stored in the metadata record. + steps = workflow_dict[ 'steps' ] + else: + steps = [] + format_version = workflow_dict[ 'format-version' ] + annotation = workflow_dict[ 'annotation' ] + %><tr> - <td>${workflow_dict[ 'name' ]}</td> - <td>${workflow_dict[ 'format-version' ]}</td> - <td>${workflow_dict[ 'annotation' ]}</td> + <td> + <a href="${h.url_for( controller='workflow', action='view_workflow', repository_metadata_id=repository_metadata_id, workflow_name=encode( workflow_name ), webapp=webapp )}">${workflow_name}</a> + </td> + <td> + %if 'steps' in workflow_dict: + ${len( steps )} + %else: + unknown + %endif + </td> + <td>${format_version}</td> + <td>${annotation}</td></tr> %endfor </table> diff -r 125d735c689ee60ad9bd9601c7a22738ba3523de -r ab8fb6d1f56d6677ccd9dbfa137acf6efbc4d245 templates/webapps/community/repository/find_tools.mako --- a/templates/webapps/community/repository/find_tools.mako +++ b/templates/webapps/community/repository/find_tools.mako @@ -14,6 +14,7 @@ <br/><br/><ul class="manage-table-actions"><li><a class="action-button" href="${h.url_for( controller='repository', action='browse_valid_repositories', webapp=webapp )}">Browse valid repositories</a></li> + <li><a class="action-button" href="${h.url_for( controller='repository', action='find_workflows', webapp=webapp )}">Search for workflows</a></li></ul> %endif diff -r 125d735c689ee60ad9bd9601c7a22738ba3523de -r ab8fb6d1f56d6677ccd9dbfa137acf6efbc4d245 templates/webapps/community/repository/find_workflows.mako --- /dev/null +++ b/templates/webapps/community/repository/find_workflows.mako @@ -0,0 +1,53 @@ +<%inherit file="/base.mako"/> +<%namespace file="/message.mako" import="render_msg" /> + +<%! + def inherit(context): + if context.get('use_panels'): + return '/webapps/community/base_panels.mako' + else: + return '/base.mako' +%> +<%inherit file="${inherit(context)}"/> + +%if webapp == 'galaxy': + <br/><br/> + <ul class="manage-table-actions"> + <li><a class="action-button" href="${h.url_for( controller='repository', action='browse_valid_repositories', webapp=webapp )}">Browse valid repositories</a></li> + <a class="action-button" href="${h.url_for( controller='repository', action='find_tools', webapp=webapp )}">Search for valid tools</a> + </ul> +%endif + +%if message: + ${render_msg( message, status )} +%endif + +<div class="toolForm"> + <div class="toolFormTitle">Search repositories for workflows</div> + <div class="toolFormBody"> + <div class="form-row"> + Enter a workflow name to find repositories that contain workflows matching the search criteria.<br/><br/> + Comma-separated strings may be entered to expand search criteria. + </div> + <div style="clear: both"></div> + <form name="find_workflows" id="find_workflows" action="${h.url_for( controller='repository', action='find_workflows', webapp=webapp )}" method="post" > + <div style="clear: both"></div> + <div class="form-row"> + <label>Workflow name:</label> + <input name="workflow_name" type="textfield" value="${workflow_name}" size="40"/> + </div> + <div style="clear: both"></div> + <div class="form-row"> + <label>Exact matches only:</label> + ${exact_matches_check_box.get_html()} + <div class="toolParamHelp" style="clear: both;"> + Check the box to match text exactly (text case doesn't matter as all strings are forced to lower case). + </div> + </div> + <div style="clear: both"></div> + <div class="form-row"> + <input type="submit" value="Search repositories"/> + </div> + </form> + </div> +</div> diff -r 125d735c689ee60ad9bd9601c7a22738ba3523de -r ab8fb6d1f56d6677ccd9dbfa137acf6efbc4d245 templates/webapps/community/repository/manage_repository.mako --- a/templates/webapps/community/repository/manage_repository.mako +++ b/templates/webapps/community/repository/manage_repository.mako @@ -184,7 +184,7 @@ </form></div></div> -${render_repository_tools_and_workflows( metadata, can_set_metadata=True )} +${render_repository_tools_and_workflows( repository_metadata_id, metadata, can_set_metadata=True )} <p/><div class="toolForm"><div class="toolFormTitle">Manage categories</div> diff -r 125d735c689ee60ad9bd9601c7a22738ba3523de -r ab8fb6d1f56d6677ccd9dbfa137acf6efbc4d245 templates/webapps/community/repository/preview_tools_in_changeset.mako --- a/templates/webapps/community/repository/preview_tools_in_changeset.mako +++ b/templates/webapps/community/repository/preview_tools_in_changeset.mako @@ -69,6 +69,7 @@ <div popupmenu="repository-${repository.id}-popup"><a class="action-button" href="${h.url_for( controller='repository', action='browse_valid_repositories', webapp=webapp )}">Browse valid repositories</a><a class="action-button" href="${h.url_for( controller='repository', action='find_tools', webapp=webapp )}">Search for valid tools</a> + <a class="action-button" href="${h.url_for( controller='repository', action='find_workflows', webapp=webapp )}">Search for workflows</a></div></ul> @@ -103,4 +104,4 @@ </div></div><p/> -${render_repository_tools_and_workflows( metadata, webapp=webapp )} +${render_repository_tools_and_workflows( repository_metadata_id, metadata, webapp=webapp )} diff -r 125d735c689ee60ad9bd9601c7a22738ba3523de -r ab8fb6d1f56d6677ccd9dbfa137acf6efbc4d245 templates/webapps/community/repository/tool_form.mako --- a/templates/webapps/community/repository/tool_form.mako +++ b/templates/webapps/community/repository/tool_form.mako @@ -116,6 +116,7 @@ <div popupmenu="repository-${repository.id}-popup"><a class="action-button" href="${h.url_for( controller='repository', action='browse_valid_repositories', webapp=webapp )}">Browse valid repositories</a><a class="action-button" href="${h.url_for( controller='repository', action='find_tools', webapp=webapp )}">Search for valid tools</a> + <a class="action-button" href="${h.url_for( controller='repository', action='find_workflows', webapp=webapp )}">Search for workflows</a></div> %else: %if is_new: diff -r 125d735c689ee60ad9bd9601c7a22738ba3523de -r ab8fb6d1f56d6677ccd9dbfa137acf6efbc4d245 templates/webapps/community/repository/view_repository.mako --- a/templates/webapps/community/repository/view_repository.mako +++ b/templates/webapps/community/repository/view_repository.mako @@ -99,6 +99,7 @@ <div popupmenu="repository-${repository.id}-popup"><a class="action-button" href="${h.url_for( controller='repository', action='browse_valid_repositories', webapp=webapp )}">Browse valid repositories</a><a class="action-button" href="${h.url_for( controller='repository', action='find_tools', webapp=webapp )}">Search for valid tools</a> + <a class="action-button" href="${h.url_for( controller='repository', action='find_workflows', webapp=webapp )}">Search for workflows</a></div> %endif </ul> @@ -185,7 +186,7 @@ %endif </div></div> -${render_repository_tools_and_workflows( metadata, webapp=webapp )} +${render_repository_tools_and_workflows( repository_metadata_id, metadata, webapp=webapp )} %if repository.categories: <p/><div class="toolForm"> diff -r 125d735c689ee60ad9bd9601c7a22738ba3523de -r ab8fb6d1f56d6677ccd9dbfa137acf6efbc4d245 templates/webapps/community/repository/view_tool_metadata.mako --- a/templates/webapps/community/repository/view_tool_metadata.mako +++ b/templates/webapps/community/repository/view_tool_metadata.mako @@ -39,6 +39,7 @@ <div popupmenu="repository-${repository.id}-popup"><a class="action-button" href="${h.url_for( controller='repository', action='browse_valid_repositories', webapp=webapp )}">Browse valid repositories</a><a class="action-button" href="${h.url_for( controller='repository', action='find_tools', webapp=webapp )}">Search for valid tools</a> + <a class="action-button" href="${h.url_for( controller='repository', action='find_workflows', webapp=webapp )}">Search for workflows</a></div> %else: %if is_new: diff -r 125d735c689ee60ad9bd9601c7a22738ba3523de -r ab8fb6d1f56d6677ccd9dbfa137acf6efbc4d245 templates/webapps/community/repository/view_workflow.mako --- /dev/null +++ b/templates/webapps/community/repository/view_workflow.mako @@ -0,0 +1,105 @@ +<%inherit file="/base.mako"/> +<%namespace file="/message.mako" import="render_msg" /> +<%namespace file="/webapps/community/common/common.mako" import="*" /> +<%namespace file="/webapps/community/repository/common.mako" import="*" /> + +<% + from galaxy.web.framework.helpers import time_ago + from galaxy.webapps.community.controllers.common import encode + + in_tool_shed = webapp == 'community' + is_admin = trans.user_is_admin() + is_new = repository.is_new + can_manage = is_admin or trans.user == repository.user + can_contact_owner = in_tool_shed and trans.user and trans.user != repository.user + can_push = in_tool_shed and trans.app.security_agent.can_push( trans.user, repository ) + can_upload = can_push + can_download = in_tool_shed and not is_new and ( not is_malicious or can_push ) + can_browse_contents = in_tool_shed and not is_new + can_set_metadata = in_tool_shed and not is_new + can_rate = in_tool_shed and not is_new and trans.user and repository.user != trans.user + can_view_change_log = in_tool_shed and not is_new + if can_push: + browse_label = 'Browse or delete repository files' + else: + browse_label = 'Browse repository files' +%> + +<%! + def inherit(context): + if context.get('use_panels'): + return '/webapps/community/base_panels.mako' + else: + return '/base.mako' +%> +<%inherit file="${inherit(context)}"/> + +<%def name="render_workflow( repository_metadata_id, workflow_name, webapp )"> + <% center_url = h.url_for( controller='workflow', action='generate_workflow_image', repository_metadata_id=repository_metadata_id, workflow_name=encode( workflow_name ), webapp=webapp ) %> + <iframe name="galaxy_main" id="galaxy_main" frameborder="0" style="position: absolute; width: 100%; height: 100%;" src="${center_url}"></iframe> +</%def> + +<br/><br/> +<ul class="manage-table-actions"> + %if in_tool_shed: + %if is_new and can_upload: + <a class="action-button" href="${h.url_for( controller='upload', action='upload', repository_id=trans.security.encode_id( repository.id ), webapp='community' )}">Upload files to repository</a> + %else: + <li><a class="action-button" id="repository-${repository.id}-popup" class="menubutton">Repository Actions</a></li> + <div popupmenu="repository-${repository.id}-popup"> + %if can_upload: + <a class="action-button" href="${h.url_for( controller='upload', action='upload', repository_id=trans.security.encode_id( repository.id ), webapp='community' )}">Upload files to repository</a> + %endif + %if can_manage: + <a class="action-button" href="${h.url_for( controller='repository', action='manage_repository', id=trans.app.security.encode_id( repository.id ), changeset_revision=repository.tip )}">Manage repository</a> + %else: + <a class="action-button" href="${h.url_for( controller='repository', action='view_repository', id=trans.app.security.encode_id( repository.id ), changeset_revision=repository.tip, webapp='community' )}">View repository</a> + %endif + %if can_view_change_log: + <a class="action-button" href="${h.url_for( controller='repository', action='view_changelog', id=trans.app.security.encode_id( repository.id ), webapp='community' )}">View change log</a> + %endif + %if can_rate: + <a class="action-button" href="${h.url_for( controller='repository', action='rate_repository', id=trans.app.security.encode_id( repository.id ) )}">Rate repository</a> + %endif + %if can_browse_contents: + <a class="action-button" href="${h.url_for( controller='repository', action='browse_repository', id=trans.app.security.encode_id( repository.id ), webapp='community' )}">${browse_label}</a> + %endif + %if can_contact_owner: + <a class="action-button" href="${h.url_for( controller='repository', action='contact_owner', id=trans.security.encode_id( repository.id ), webapp='community' )}">Contact repository owner</a> + %endif + %if can_download: + <a class="action-button" href="${h.url_for( controller='repository', action='download', repository_id=trans.app.security.encode_id( repository.id ), changeset_revision=changeset_revision, file_type='gz' )}">Download as a .tar.gz file</a> + <a class="action-button" href="${h.url_for( controller='repository', action='download', repository_id=trans.app.security.encode_id( repository.id ), changeset_revision=changeset_revision, file_type='bz2' )}">Download as a .tar.bz2 file</a> + <a class="action-button" href="${h.url_for( controller='repository', action='download', repository_id=trans.app.security.encode_id( repository.id ), changeset_revision=changeset_revision, file_type='zip' )}">Download as a zip file</a> + %endif + </div> + %endif + %else: + <li><a class="action-button" id="repository-${repository.id}-popup" class="menubutton">Repository Actions</a></li> + <div popupmenu="repository-${repository.id}-popup"> + <li><a class="action-button" href="${h.url_for( controller='workflow', action='import_workflow', repository_metadata_id=repository_metadata_id, workflow_name=encode( workflow_name ), webapp=webapp )}">Import workflow to local Galaxy</a></li> + <li><a class="action-button" href="${h.url_for( controller='repository', action='install_repository_revision', repository_id=trans.security.encode_id( repository.id ), webapp=webapp, changeset_revision=changeset_revision )}">Install repository to local Galaxy</a></li> + </div> + <li><a class="action-button" id="toolshed-${repository.id}-popup" class="menubutton">Tool Shed Actions</a></li> + <div popupmenu="toolshed-${repository.id}-popup"> + <a class="action-button" href="${h.url_for( controller='repository', action='browse_valid_repositories', webapp=webapp )}">Browse valid repositories</a> + <a class="action-button" href="${h.url_for( controller='repository', action='find_tools', webapp=webapp )}">Search for valid tools</a> + <a class="action-button" href="${h.url_for( controller='repository', action='find_workflows', webapp=webapp )}">Search for workflows</a> + </div> + %endif +</ul> + +%if message: + ${render_msg( message, status )} +%endif + +<div class="toolFormTitle">${workflow_name}</div> +<div class="form-row"> + <b>Boxes are red when tools are not available in this repository</b> + <div class="toolParamHelp" style="clear: both;"> + (this page displays SVG graphics) + </div> +</div> +<br clear="left"/> + +${render_workflow( repository_metadata_id, workflow_name, webapp )} diff -r 125d735c689ee60ad9bd9601c7a22738ba3523de -r ab8fb6d1f56d6677ccd9dbfa137acf6efbc4d245 templates/webapps/galaxy/admin/index.mako --- a/templates/webapps/galaxy/admin/index.mako +++ b/templates/webapps/galaxy/admin/index.mako @@ -73,7 +73,7 @@ <div class="toolSectionTitle">Tool sheds</div><div class="toolSectionBody"><div class="toolSectionBg"> - <div class="toolTitle"><a href="${h.url_for( controller='admin', action='browse_tool_sheds' )}" target="galaxy_main">Browse tool sheds</a></div> + <div class="toolTitle"><a href="${h.url_for( controller='admin', action='browse_tool_sheds' )}" target="galaxy_main">Search and browse tool sheds</a></div></div></div> %endif diff -r 125d735c689ee60ad9bd9601c7a22738ba3523de -r ab8fb6d1f56d6677ccd9dbfa137acf6efbc4d245 templates/webapps/galaxy/admin/tool_sheds.mako --- a/templates/webapps/galaxy/admin/tool_sheds.mako +++ b/templates/webapps/galaxy/admin/tool_sheds.mako @@ -27,6 +27,7 @@ <div popupmenu="dataset-${shed_id}-popup"><a class="action-button" href="${h.url_for( controller='admin', action='browse_tool_shed', tool_shed_url=url )}">Browse valid repositories</a><a class="action-button" href="${h.url_for( controller='admin', action='find_tools_in_tool_shed', tool_shed_url=url )}">Search for valid tools</a> + <a class="action-button" href="${h.url_for( controller='admin', action='find_workflows_in_tool_shed', tool_shed_url=url )}">Search for workflows</a></div></td></tr> diff -r 125d735c689ee60ad9bd9601c7a22738ba3523de -r ab8fb6d1f56d6677ccd9dbfa137acf6efbc4d245 templates/workflow/display.mako --- a/templates/workflow/display.mako +++ b/templates/workflow/display.mako @@ -1,7 +1,7 @@ <%inherit file="/display_base.mako"/><%namespace file="/display_common.mako" import="render_message" /> -<%! +<% from galaxy.tools.parameters import DataToolParameter, RuntimeValue from galaxy.web import form_builder %> @@ -82,7 +82,17 @@ %for i, step in enumerate( steps ): <tr><td> %if step.type == 'tool' or step.type is None: - <% tool = app.toolbox.tools_by_id[step.tool_id] %> + <% + try: + tool = trans.app.toolbox.tools_by_id[ step.tool_id ] + except KeyError, e: + # The id value of tools installed from a Galaxy tool shed is a guid, but + # these tool's old_id attribute should contain what we're looking for. + for available_tool_id, available_tool in trans.app.toolbox.tools_by_id.items(): + if step.tool_id == available_tool.old_id: + tool = available_tool + break + %><div class="toolForm"><div class="toolFormTitle">Step ${int(step.order_index)+1}: ${tool.name}</div><div class="toolFormBody"> diff -r 125d735c689ee60ad9bd9601c7a22738ba3523de -r ab8fb6d1f56d6677ccd9dbfa137acf6efbc4d245 templates/workflow/run.mako --- a/templates/workflow/run.mako +++ b/templates/workflow/run.mako @@ -363,7 +363,17 @@ %endif %for i, step in enumerate( steps ): %if step.type == 'tool' or step.type is None: - <% tool = app.toolbox.tools_by_id[step.tool_id] %> + <% + try: + tool = trans.app.toolbox.tools_by_id[ step.tool_id ] + except KeyError, e: + # The id value of tools installed from a Galaxy tool shed is a guid, but + # these tool's old_id attribute should contain what we're looking for. + for available_tool_id, available_tool in trans.app.toolbox.tools_by_id.items(): + if step.tool_id == available_tool.old_id: + tool = available_tool + break + %><input type="hidden" name="${step.id}|tool_state" value="${step.state.encode( tool, app )}"><div class="toolForm"><div class="toolFormTitle"> diff -r 125d735c689ee60ad9bd9601c7a22738ba3523de -r ab8fb6d1f56d6677ccd9dbfa137acf6efbc4d245 tools/gatk/count_covariates.xml --- a/tools/gatk/count_covariates.xml +++ b/tools/gatk/count_covariates.xml @@ -138,6 +138,7 @@ <when value="cached"><param name="input_bam" type="data" format="bam" label="BAM file"><validator type="unspecified_build" /> + <validator type="metadata" check="bam_index" message="Metadata missing, click the pencil icon in the history item and use the auto-detect feature to correct this issue."/><validator type="dataset_metadata_in_file" filename="picard_index.loc" metadata_name="dbkey" metadata_column="1" message="Sequences are not currently available for the specified build." /><!-- fixme!!! this needs to be a select --></param><param name="ref_file" type="select" label="Using reference genome"> @@ -147,7 +148,9 @@ </param></when><when value="history"><!-- FIX ME!!!! --> - <param name="input_bam" type="data" format="bam" label="BAM file" /> + <param name="input_bam" type="data" format="bam" label="BAM file" > + <validator type="metadata" check="bam_index" message="Metadata missing, click the pencil icon in the history item and use the auto-detect feature to correct this issue."/> + </param><param name="ref_file" type="data" format="fasta" label="Using reference file" /></when></conditional> diff -r 125d735c689ee60ad9bd9601c7a22738ba3523de -r ab8fb6d1f56d6677ccd9dbfa137acf6efbc4d245 tools/gatk/indel_realigner.xml --- a/tools/gatk/indel_realigner.xml +++ b/tools/gatk/indel_realigner.xml @@ -107,6 +107,7 @@ <when value="cached"><param name="input_bam" type="data" format="bam" label="BAM file"><validator type="unspecified_build" /> + <validator type="metadata" check="bam_index" message="Metadata missing, click the pencil icon in the history item and use the auto-detect feature to correct this issue."/><validator type="dataset_metadata_in_data_table" table_name="picard_indexes" metadata_name="dbkey" metadata_column="dbkey" message="Sequences are not currently available for the specified build." /><!-- fixme!!! this needs to be a select --></param><param name="ref_file" type="select" label="Using reference genome"> @@ -116,7 +117,9 @@ </param></when><when value="history"><!-- FIX ME!!!! --> - <param name="input_bam" type="data" format="bam" label="BAM file" /> + <param name="input_bam" type="data" format="bam" label="BAM file" > + <validator type="metadata" check="bam_index" message="Metadata missing, click the pencil icon in the history item and use the auto-detect feature to correct this issue."/> + </param><param name="ref_file" type="data" format="fasta" label="Using reference file"><options><filter type="data_meta" key="dbkey" ref="input_bam" /><!-- FIX ME!!!! --> diff -r 125d735c689ee60ad9bd9601c7a22738ba3523de -r ab8fb6d1f56d6677ccd9dbfa137acf6efbc4d245 tools/gatk/realigner_target_creator.xml --- a/tools/gatk/realigner_target_creator.xml +++ b/tools/gatk/realigner_target_creator.xml @@ -103,6 +103,7 @@ <when value="cached"><param name="input_bam" type="data" format="bam" label="BAM file"><validator type="unspecified_build" /> + <validator type="metadata" check="bam_index" message="Metadata missing, click the pencil icon in the history item and use the auto-detect feature to correct this issue."/><validator type="dataset_metadata_in_data_table" table_name="picard_indexes" metadata_name="dbkey" metadata_column="dbkey" message="Sequences are not currently available for the specified build." /><!-- fixme!!! this needs to be a select --></param><param name="ref_file" type="select" label="Using reference genome"> @@ -112,7 +113,9 @@ </param></when><when value="history"> - <param name="input_bam" type="data" format="bam" label="BAM file" /> + <param name="input_bam" type="data" format="bam" label="BAM file" > + <validator type="metadata" check="bam_index" message="Metadata missing, click the pencil icon in the history item and use the auto-detect feature to correct this issue."/> + </param><param name="ref_file" type="data" format="fasta" label="Using reference file"><options><filter type="data_meta" key="dbkey" ref="input_bam" /><!-- FIX ME!!!! --> diff -r 125d735c689ee60ad9bd9601c7a22738ba3523de -r ab8fb6d1f56d6677ccd9dbfa137acf6efbc4d245 tools/gatk/table_recalibration.xml --- a/tools/gatk/table_recalibration.xml +++ b/tools/gatk/table_recalibration.xml @@ -117,6 +117,7 @@ <when value="cached"><param name="input_bam" type="data" format="bam" label="BAM file"><validator type="unspecified_build" /> + <validator type="metadata" check="bam_index" message="Metadata missing, click the pencil icon in the history item and use the auto-detect feature to correct this issue."/><validator type="dataset_metadata_in_data_table" table_name="picard_indexes" metadata_name="dbkey" metadata_column="dbkey" message="Sequences are not currently available for the specified build." /><!-- fixme!!! this needs to be a select --></param><param name="ref_file" type="select" label="Using reference genome"> @@ -126,7 +127,9 @@ </param></when><when value="history"><!-- FIX ME!!!! --> - <param name="input_bam" type="data" format="bam" label="BAM file" /> + <param name="input_bam" type="data" format="bam" label="BAM file" > + <validator type="metadata" check="bam_index" message="Metadata missing, click the pencil icon in the history item and use the auto-detect feature to correct this issue."/> + </param><param name="ref_file" type="data" format="fasta" label="Using reference file" /></when></conditional> diff -r 125d735c689ee60ad9bd9601c7a22738ba3523de -r ab8fb6d1f56d6677ccd9dbfa137acf6efbc4d245 tools/gatk/unified_genotyper.xml --- a/tools/gatk/unified_genotyper.xml +++ b/tools/gatk/unified_genotyper.xml @@ -7,8 +7,6 @@ --max_jvm_heap_fraction "1" --stdout "${output_log}" #for $i, $input_bam in enumerate( $reference_source.input_bams ): - ${dir( $input_bam.input_bam )} - ${dir( $input_bam.input_bam.dataset )} -d "-I" "${input_bam.input_bam}" "${input_bam.input_bam.ext}" "gatk_input_${i}" -d "" "${input_bam.input_bam.metadata.bam_index}" "bam_index" "gatk_input_${i}" ##hardcode galaxy ext type as bam_index #end for @@ -137,6 +135,7 @@ <repeat name="input_bams" title="Sample BAM file" min="1"><param name="input_bam" type="data" format="bam" label="BAM file"><validator type="unspecified_build" /> + <validator type="metadata" check="bam_index" message="Metadata missing, click the pencil icon in the history item and use the auto-detect feature to correct this issue."/><validator type="dataset_metadata_in_data_table" table_name="picard_indexes" metadata_name="dbkey" metadata_column="dbkey" message="Sequences are not currently available for the specified build." /><!-- fixme!!! this needs to be a select --></param></repeat> @@ -148,7 +147,9 @@ </when><when value="history"><!-- FIX ME!!!! --><repeat name="input_bams" title="Sample BAM file" min="1"> - <param name="input_bam" type="data" format="bam" label="BAM file" /> + <param name="input_bam" type="data" format="bam" label="BAM file" > + <validator type="metadata" check="bam_index" message="Metadata missing, click the pencil icon in the history item and use the auto-detect feature to correct this issue."/> + </param></repeat><param name="ref_file" type="data" format="fasta" label="Using reference file" /></when> diff -r 125d735c689ee60ad9bd9601c7a22738ba3523de -r ab8fb6d1f56d6677ccd9dbfa137acf6efbc4d245 tools/gatk/variant_annotator.xml --- a/tools/gatk/variant_annotator.xml +++ b/tools/gatk/variant_annotator.xml @@ -145,6 +145,7 @@ <param name="input_variant_bti" type="boolean" truevalue="-BTI variant" falsevalue="" label="Increase efficiency for small variant files." /><param name="input_bam" type="data" format="bam" label="BAM file" optional="True" help="Not needed for all annotations." ><validator type="unspecified_build" /> + <validator type="metadata" check="bam_index" message="Metadata missing, click the pencil icon in the history item and use the auto-detect feature to correct this issue."/><validator type="dataset_metadata_in_data_table" table_name="picard_indexes" metadata_name="dbkey" metadata_column="dbkey" message="Sequences are not currently available for the specified build." /><!-- fixme!!! this needs to be a select --></param><param name="ref_file" type="select" label="Using reference genome"> @@ -156,7 +157,9 @@ <when value="history"><!-- FIX ME!!!! --><param name="input_variant" type="data" format="vcf" label="Variant file to annotate" /><param name="input_variant_bti" type="boolean" truevalue="-BTI variant" falsevalue="" label="Increase efficiency for small variant files." /> - <param name="input_bam" type="data" format="bam" label="BAM file" optional="True" /> + <param name="input_bam" type="data" format="bam" label="BAM file" optional="True" > + <validator type="metadata" check="bam_index" message="Metadata missing, click the pencil icon in the history item and use the auto-detect feature to correct this issue."/> + </param><param name="ref_file" type="data" format="fasta" label="Using reference file" /></when></conditional> diff -r 125d735c689ee60ad9bd9601c7a22738ba3523de -r ab8fb6d1f56d6677ccd9dbfa137acf6efbc4d245 tools/picard/picard_SamToFastq.xml --- a/tools/picard/picard_SamToFastq.xml +++ b/tools/picard/picard_SamToFastq.xml @@ -42,11 +42,11 @@ || echo "Error running SamToFastq" >&2 </command><inputs> - <param name="input_sam" type="data" format="sam" label="SAM file" /> + <param name="input_sam" type="data" format="sam,bam" label="BAM/SAM file" /><param name="read1_trim" type="integer" value="" optional="True" label="The number of bases to trim from the beginning of read 1." /><param name="read1_max_bases_to_write" type="integer" optional="True" value="" label="The maximum number of bases to write from read 1 after trimming." /><param name="output_per_read_group_selector" type="select" label="Output per read group"> - <option value="per_sam_file" selected="True">Per SAM file</option> + <option value="per_sam_file" selected="True">Per BAM/SAM file</option><!-- <option value="per_read_group">Per Read Group</option> --><validator type="expression" message="Per Read Group selection is not yet implemented">value == 'per_sam_file'</validator></param> diff -r 125d735c689ee60ad9bd9601c7a22738ba3523de -r ab8fb6d1f56d6677ccd9dbfa137acf6efbc4d245 tools/samtools/sam_merge.xml --- a/tools/samtools/sam_merge.xml +++ b/tools/samtools/sam_merge.xml @@ -4,11 +4,12 @@ <requirement type="package">picard</requirement></requirements><command> -java -Xmx2G -jar ${GALAXY_DATA_INDEX_DIR}/shared/jars/MergeSamFiles.jar MSD=$mergeSD VALIDATION_STRINGENCY=LENIENT O=$output1 I=$input1 I=$input2 +java -Xmx2G -jar ${GALAXY_DATA_INDEX_DIR}/shared/jars/picard/MergeSamFiles.jar MSD=$mergeSD VALIDATION_STRINGENCY=LENIENT O=$output1 I=$input1 I=$input2 #for $i in $inputs I=${i.input} #end for 2> $outlog + || echo "Error running Picard MergeSamFiles" >&2 </command><inputs><param name="title" label="Name for the output merged bam file" type="text" default="Merged.bam" @@ -16,10 +17,10 @@ <param name="mergeSD" value="true" type="boolean" label="Merge all component bam file headers into the merged bam file" truevalue="true" falsevalue="false" checked="yes" help="Control the MERGE_SEQUENCE_DICTIONARIES flag for Picard MergeSamFiles. Default (true) correctly propagates read groups and other important metadata" /> - <param name="input1" label="First file" type="data" format="bam" /> - <param name="input2" label="with file" type="data" format="bam" help="Need to add more files? Use controls below." /> + <param name="input1" label="First file" type="data" format="bam,sam" /> + <param name="input2" label="with file" type="data" format="bam,sam" help="Need to add more files? Use controls below." /><repeat name="inputs" title="Input Files"> - <param name="input" label="Add file" type="data" format="bam" /> + <param name="input" label="Add file" type="data" format="bam,sam" /></repeat></inputs><outputs> @@ -36,7 +37,7 @@ <param name="input1" value="sam_merge_in1.bam" ftype="bam" /><param name="input2" value="sam_merge_in2.bam" ftype="bam" /><output name="output1" file="sam_merge_out1.bam" ftype="bam" /> - <output name="outlog" file="sam_merge_out1.log" ftype="txt" lines_diff="10"/> + <output name="outlog" file="sam_merge_out1.log" ftype="txt" lines_diff="11"/></test><test><param name="title" value="test2" /> @@ -45,7 +46,7 @@ <param name="input2" value="sam_merge_in2.bam" ftype="bam" /><param name="input" value="sam_merge_in3.bam" ftype="bam" /><output name="output1" file="sam_merge_out2.bam" ftype="bam" /> - <output name="outlog" file="sam_merge_out2.log" ftype="txt" lines_diff="10"/> + <output name="outlog" file="sam_merge_out2.log" ftype="txt" lines_diff="11"/></test></tests><help> https://bitbucket.org/galaxy/galaxy-central/changeset/89893520cb6d/ changeset: 89893520cb6d user: natefoo date: 2011-10-27 20:04:57 summary: Fixes for stuff lost in a merge somewhere. affected #: 1 file diff -r ab8fb6d1f56d6677ccd9dbfa137acf6efbc4d245 -r 89893520cb6d18d1371d2dbf816a83b1d7ae2631 lib/galaxy/tools/__init__.py --- a/lib/galaxy/tools/__init__.py +++ b/lib/galaxy/tools/__init__.py @@ -107,6 +107,14 @@ try: path = elem.get( "file" ) tool = self.load_tool( os.path.join( tool_path, path ), guid=guid ) + if guid is not None: + # Tool was installed from a Galaxy tool shed. + tool.tool_shed = elem.find( "tool_shed" ).text + tool.repository_name = elem.find( "repository_name" ).text + tool.repository_owner = elem.find( "repository_owner" ).text + tool.changeset_revision = elem.find( "changeset_revision" ).text + tool.old_id = elem.find( "id" ).text + tool.version = elem.find( "version" ).text if self.app.config.get_bool( 'enable_tool_tags', False ): tag_names = elem.get( "tags", "" ).split( "," ) for tag_name in tag_names: @@ -367,9 +375,7 @@ # legacy basic mode - provide compatible defaults self.attributes['split_size'] = 20 self.attributes['split_mode'] = 'number_of_parts' - - - + class Tool: """ Represents a computational tool that can be executed through Galaxy. @@ -390,6 +396,13 @@ # easily ensure that parameter dependencies like index files or # tool_data_table_conf.xml entries exist. self.input_params = [] + # Attributes of tools installed from Galaxy tool sheds. + self.tool_shed = None + self.repository_name = None + self.repository_owner = None + self.changeset_revision = None + self.old_id = None + self.version = None # Parse XML element containing configuration self.parse( root, guid=guid ) self.external_runJob_script = app.config.drmaa_external_runjob_script @@ -411,14 +424,15 @@ raise Exception, "Missing tool 'name'" # Get the UNIQUE id for the tool # TODO: can this be generated automatically? - if guid is not None: + if guid is None: + self.id = root.get( "id" ) + self.version = root.get( "version" ) + else: self.id = guid - else: - self.id = root.get( "id" ) if not self.id: - raise Exception, "Missing tool 'id'" + raise Exception, "Missing tool 'id'" self.version = root.get( "version" ) - if not self.version: + if not self.version: # For backward compatibility, some tools may not have versions yet. self.version = "1.0.0" # Support multi-byte tools @@ -806,6 +820,7 @@ group = Repeat() group.name = elem.get( "name" ) group.title = elem.get( "title" ) + group.help = elem.get( "help", None ) group.inputs = self.parse_input_elem( elem, enctypes, context ) group.default = int( elem.get( "default", 0 ) ) group.min = int( elem.get( "min", 0 ) ) @@ -1571,7 +1586,7 @@ name = conversion_name, config_info = self.app.config ) # Wrap actual input dataset input_values[ input.name ] = \ - DatasetFilenameWrapper( input_values[ input.name ], + DatasetFilenameWrapper( input_values[ input.name ], datatypes_registry = self.app.datatypes_registry, tool = self, name = input.name, config_info = self.app.config ) https://bitbucket.org/galaxy/galaxy-central/changeset/638d994c4cc7/ changeset: 638d994c4cc7 user: natefoo date: 2011-10-27 20:14:27 summary: Revert changes to cufflinks/tophat, these can be integrated in a seperate commit. affected #: 2 files diff -r 89893520cb6d18d1371d2dbf816a83b1d7ae2631 -r 638d994c4cc7783248357b3cf7403b00924d0016 tools/ngs_rna/cufflinks_wrapper.xml --- a/tools/ngs_rna/cufflinks_wrapper.xml +++ b/tools/ngs_rna/cufflinks_wrapper.xml @@ -1,4 +1,5 @@ -<tool id="cufflinks" name="Cufflinks" version="0.9.1"> +<tool id="cufflinks" name="Cufflinks" version="0.0.5"> + <!-- Wrapper supports Cufflinks versions v1.0.0-v1.0.3 --><description>transcript assembly and FPKM (RPKM) estimates for RNA-Seq data</description><requirements><requirement type="package">cufflinks</requirement> @@ -14,27 +15,10 @@ ## Include reference annotation? #if $reference_annotation.use_ref == "Use reference annotation": - #if $reference_annotation.annotationSource.reference_annotation_file == "indexed": - -G "${ filter( lambda x: str( x[0] ) == str( $reference_annotation.annotationSource.indices ), $__app__.tool_data_tables[ 'gtf_index' ].get_fields() )[0][-1] }" - #else: - #if $reference_annotation.annotationSource.reference_annotation_file == "attribute": - -G "${ filter( lambda x: str( x[0] ) == str( $input.metadata.dbkey ), $__app__.tool_data_tables[ 'gtf_index' ].get_fields() )[0][-1] }" - #else: - -G "${reference_annotation.annotationSource.ownFile}" - #end if - #end if + -G $reference_annotation.reference_annotation_file #end if - #if $reference_annotation.use_ref == "Use reference annotation guide": - #if $reference_annotation.annotationSource.reference_annotation_file == "indexed": - -g "${ filter( lambda x: str( x[0] ) == str( $reference_annotation.annotationSource.indices ), $__app__.tool_data_tables[ 'gtf_index' ].get_fields() )[0][-1] }" - #else: - #if $reference_annotation.annotationSource.reference_annotation_file == "attribute": - -g "${ filter( lambda x: str( x[0] ) == str( $input.metadata.dbkey ), $__app__.tool_data_tables[ 'gtf_index' ].get_fields() )[0][-1] }" - #else: - -g "${reference_annotation.annotationSource.ownFile}" - #end if - #end if + -g $reference_annotation.reference_annotation_guide_file #end if ## Set paired-end parameters? @@ -77,44 +61,10 @@ </param><when value="No"></when><when value="Use reference annotation"> - <conditional name="annotationSource"> - <param name="reference_annotation_file" type="select" label="Please select a reference Aonnotation"> - <option value="indexed">Use a built-in index</option> - <option value="history">Use one from the history</option> - <option value="attribute">Use input bam metadata.dbkey attribute</option> - </param> - <when value="indexed"> - <param name="indices" type="select" label="Select genome for gtf annotation"> - <options from_data_table="gtf_index"> - <filter type="sort_by" column="3" /> - <validator type="no_options" message="No indexes are available for the selected input dataset" /> - </options> - </param> - </when> - <when value="history"> - <param name="ownFile" type="data" format="gff3, gtf" label="Select a reference annotation file" /> - </when> - </conditional> - </when> + <param format="gff3,gtf" name="reference_annotation_file" type="data" label="Reference Annotation" help="Make sure your annotation file is in GTF format and that Galaxy knows that your file is GTF--not GFF."/> + </when><when value="Use reference annotation guide"> - <conditional name="annotationSource"> - <param name="reference_annotation_file" type="select" label="Please select a reference Aonnotation"> - <option value="indexed">Use a built-in index</option> - <option value="history">Use one from the history</option> - <option value="attribute">Use input bam metadata.dbkey attribute</option> - </param> - <when value="indexed"> - <param name="indices" type="select" label="Select genome for gtf annotation"> - <options from_data_table="gtf_index"> - <filter type="sort_by" column="3" /> - <validator type="no_options" message="No indexes are available for the selected input dataset" /> - </options> - </param> - </when> - <when value="history"> - <param name="ownFile" type="data" format="gff3, gtf" label="Select a reference annotation file" /> - </when> - </conditional> + <param format="gff3,gtf" name="reference_annotation_guide_file" type="data" label="Reference Annotation" help="Make sure your annotation file is in GTF format and that Galaxy knows that your file is GTF--not GFF."/></when></conditional><conditional name="bias_correction"> diff -r 89893520cb6d18d1371d2dbf816a83b1d7ae2631 -r 638d994c4cc7783248357b3cf7403b00924d0016 tools/ngs_rna/tophat_wrapper.xml --- a/tools/ngs_rna/tophat_wrapper.xml +++ b/tools/ngs_rna/tophat_wrapper.xml @@ -1,8 +1,7 @@ -<tool id="tophat" name="Tophat" version="1.2.1"> +<tool id="tophat" name="Tophat for Illumina" version="1.5.0"><description>Find splice junctions using RNA-seq data</description> + <version_command>tophat --version</version_command><requirements> - <requirement type="package">samtools</requirement> - <requirement type="package">bowtie</requirement><requirement type="package">tophat</requirement></requirements><command interpreter="python"> @@ -18,18 +17,14 @@ #if $refGenomeSource.genomeSource == "history": --own-file=$refGenomeSource.ownFile #else: - #if $refGenomeSource.genomeSource == "indexed": - --indexes-path="${ filter( lambda x: str( x[0] ) == str( $refGenomeSource.index ), $__app__.tool_data_tables[ 'tophat_indexes' ].get_fields() )[0][-1] }" - #else: - --indexes-path="${ filter( lambda x: str( x[0] ) == str( $singlePaired.input1.metadata.dbkey ), $__app__.tool_data_tables[ 'tophat_indexes' ].get_fields() )[0][-1] }" - #end if + --indexes-path="${ filter( lambda x: str( x[0] ) == str( $refGenomeSource.index ), $__app__.tool_data_tables[ 'tophat_indexes' ].get_fields() )[0][-1] }" #end if ## Are reads single-end or paired? --single-paired=$singlePaired.sPaired ## First input file always required. - --input1=$singlePaired.input1 + --input1=$input1 ## Set params based on whether reads are single-end or paired. #if $singlePaired.sPaired == "single": @@ -57,15 +52,7 @@ ## Supplying junctions parameters. #if $singlePaired.sParams.own_junctions.use_junctions == "Yes": #if $singlePaired.sParams.own_junctions.gene_model_ann.use_annotations == "Yes": - #if $singlePaired.sParams.own_junctions.gene_model_ann.annotationSource.reference_annotation_file == "indexed": - -G "${ filter( lambda x: str( x[0] ) == str( $refGenomeSource.index ), $__app__.tool_data_tables[ 'gtf_index' ].get_fields() )[0][-1] }" - #else: - #if $singlePaired.sParams.own_junctions.gene_model_ann.annotationSource.reference_annotation_file == "attribute": - -G "${ filter( lambda x: str( x[0] ) == str( $singlePaired.input1.metadata.dbkey ), $__app__.tool_data_tables[ 'gtf_index' ].get_fields() )[0][-1] }" - #else - -G "${singlePaired.sParams.own_junctions.gene_model_ann.annotationSource.owngtfFile}" - #end if - #end if + -G $singlePaired.sParams.own_junctions.gene_model_ann.gene_annotation_model #end if #if $singlePaired.sParams.own_junctions.raw_juncs.use_juncs == "Yes": -j $singlePaired.sParams.own_junctions.raw_juncs.raw_juncs @@ -124,15 +111,7 @@ ## Supplying junctions parameters. #if $singlePaired.pParams.own_junctions.use_junctions == "Yes": #if $singlePaired.pParams.own_junctions.gene_model_ann.use_annotations == "Yes": - #if $singlePaired.pParams.own_junctions.gene_model_ann.annotationSource.reference_annotation_file == "indexed": - -G "${ filter( lambda x: str( x[0] ) == str( $refGenomeSource.index ), $__app__.tool_data_tables[ 'gtf_index' ].get_fields() )[0][-1] }" - #else: - #if $singlePaired.pParams.own_junctions.gene_model_ann.annotationSource.reference_annotation_file == "attribute": - -G "${ filter( lambda x: str( x[0] ) == str( $singlePaired.input1.metadata.dbkey ), $__app__.tool_data_tables[ 'gtf_index' ].get_fields() )[0][-1] }" - #else - -G "${singlePaired.sParams.own_junctions.gene_model_ann.annotationSource.owngtfFile}" - #end if - #end if + -G $singlePaired.pParams.own_junctions.gene_model_ann.gene_annotation_model #end if #if $singlePaired.pParams.own_junctions.raw_juncs.use_juncs == "Yes": -j $singlePaired.pParams.own_junctions.raw_juncs.raw_juncs @@ -166,15 +145,18 @@ #end if </command><inputs> + <param format="fastqsanger" name="input1" type="data" label="RNA-Seq FASTQ file" help="Nucleotide-space: Must have Sanger-scaled quality values with ASCII offset 33" /><conditional name="refGenomeSource"><param name="genomeSource" type="select" label="Will you select a reference genome from your history or use a built-in index?" help="Built-ins were indexed using default options"><option value="indexed">Use a built-in index</option><option value="history">Use one from the history</option> - <option value="attribute">Use input fastq metadata.dbkey attribute</option></param><when value="indexed"><param name="index" type="select" label="Select a reference genome" help="If your genome of interest is not listed, contact the Galaxy team"> - <options from_data_table="tophat_indexes" /> + <options from_data_table="tophat_indexes"> + <filter type="sort_by" column="2"/> + <validator type="no_options" message="No indexes are available for the selected input dataset"/> + </options></param></when><when value="history"> @@ -187,7 +169,6 @@ <option value="paired">Paired-end</option></param><when value="single"> - <param format="fastqsanger" name="input1" type="data" label="RNA-Seq FASTQ file" help="Must have Sanger-scaled quality values with ASCII offset 33"/><conditional name="sParams"><param name="sSettingsType" type="select" label="TopHat settings to use" help="You can use the default settings or set custom values for any of Tophat's parameters."><option value="preSet">Use Defaults</option> @@ -237,16 +218,7 @@ </param><when value="No" /><when value="Yes"> - <conditional name="annotationSource"> - <param name="reference_annotation_file" type="select" label="Please select a reference Aonnotation"> - <option value="indexed">Use a built-in index</option> - <option value="history">Use one from the history</option> - <option value="attribute">Use metadata.bkey attribute from input fastq file</option> - </param> - <when value="history"> - <param name="owngtfFile" type="data" format="gff3, gtf" label="Select a reference annotation file" /> - </when> - </conditional> + <param format="gtf" name="gene_annotation_model" type="data" label="Gene Model Annotations" help="TopHat will use the exon records in this file to build a set of known splice junctions for each gene, and will attempt to align reads to these junctions even if they would not normally be covered by the initial mapping."/></when></conditional><conditional name="raw_juncs"> @@ -291,7 +263,7 @@ <param name="max_coverage_intron" type="integer" value="20000" label="Maximum intron length that may be found during coverage search" /></when><when value="No" /> - </conditional> + </conditional><param name="microexon_search" type="select" label="Use Microexon Search" help="With this option, the pipeline will attempt to find alignments incident to microexons. Works only for reads 50bp or longer."><option value="No">No</option><option value="Yes">Yes</option> @@ -300,8 +272,7 @@ </conditional><!-- sParams --></when><!-- single --><when value="paired"> - <param format="fastqsanger" name="input1" type="data" label="RNA-Seq FASTQ file" help="Must have Sanger-scaled quality values with ASCII offset 33"/> - <param format="fastqsanger" name="input2" type="data" label="RNA-Seq FASTQ file" help="Must have Sanger-scaled quality values with ASCII offset 33"/> + <param format="fastqsanger" name="input2" type="data" label="RNA-Seq FASTQ file" help="Nucleotide-space: Must have Sanger-scaled quality values with ASCII offset 33" /><param name="mate_inner_distance" type="integer" value="20" label="Mean Inner Distance between Mate Pairs" /><conditional name="pParams"><param name="pSettingsType" type="select" label="TopHat settings to use" help="For most mapping needs use Commonly used settings. If you want full control use Full parameter list"> @@ -352,16 +323,7 @@ </param><when value="No" /><when value="Yes"> - <conditional name="annotationSource"> - <param name="reference_annotation_file" type="select" label="Please select a reference Aonnotation"> - <option value="indexed">Use a built-in index</option> - <option value="history">Use one from the history</option> - <option value="attribute">Use metadata.bkey attribute from input fastq files</option> - </param> - <when value="history"> - <param name="owngtfFile" type="data" format="gff3, gtf" label="Select a reference annotation file" /> - </when> - </conditional> + <param format="gtf" name="gene_annotation_model" type="data" label="Gene Model Annotations" help="TopHat will use the exon records in this file to build a set of known splice junctions for each gene, and will attempt to align reads to these junctions even if they would not normally be covered by the initial mapping."/></when></conditional><conditional name="raw_juncs"> @@ -425,7 +387,7 @@ ( singlePaired['sParams']['indel_search']['allow_indel_search'] == 'Yes' ) ) or ( ( 'pParams' in singlePaired ) and ( 'indel_search' in singlePaired['pParams'] ) and ( singlePaired['pParams']['indel_search']['allow_indel_search'] == 'Yes' ) ) - ) + ) </filter><actions><conditional name="refGenomeSource.genomeSource"> @@ -513,46 +475,49 @@ </outputs><tests> - <!-- Test single-end reads with pre-built index and preset parameters --> + <!-- Test base-space single-end reads with pre-built index and preset parameters --><test><!-- TopHat commands: - tophat -o tmp_dir -p 1 /afs/bx.psu.edu/depot/data/genome/test/tophat/tophat_in1 test-data/tophat_in2.fastqsanger + tophat -o tmp_dir -p 1 tophat_in1 test-data/tophat_in2.fastqsanger + Rename the files in tmp_dir appropriately --> + <param name="input1" ftype="fastqsanger" value="tophat_in2.fastqsanger" /><param name="genomeSource" value="indexed" /><param name="index" value="tophat_test" /><param name="sPaired" value="single" /> - <param name="input1" ftype="fastqsanger" value="tophat_in2.fastqsanger" /><param name="sSettingsType" value="preSet" /><output name="junctions" file="tophat_out1j.bed" /><output name="accepted_hits" file="tophat_out1h.bam" compare="sim_size" /></test> - <!-- Test using test data: paired-end reads, index from history. --> + <!-- Test using base-space test data: paired-end reads, index from history. --><test><!-- TopHat commands: bowtie-build -f test-data/tophat_in1.fasta tophat_in1 tophat -o tmp_dir -p 1 -r 20 tophat_in1 test-data/tophat_in2.fastqsanger test-data/tophat_in3.fastqsanger + Rename the files in tmp_dir appropriately --> + <param name="input1" ftype="fastqsanger" value="tophat_in2.fastqsanger" /><param name="genomeSource" value="history" /><param name="ownFile" ftype="fasta" value="tophat_in1.fasta" /><param name="sPaired" value="paired" /> - <param name="input1" ftype="fastqsanger" value="tophat_in2.fastqsanger" /><param name="input2" ftype="fastqsanger" value="tophat_in3.fastqsanger" /><param name="mate_inner_distance" value="20" /><param name="pSettingsType" value="preSet" /><output name="junctions" file="tophat_out2j.bed" /><output name="accepted_hits" file="tophat_out2h.bam" compare="sim_size" /></test> - <!-- Test single-end reads with user-supplied reference fasta and full parameters --> + <!-- Test base-space single-end reads with user-supplied reference fasta and full parameters --><test><!-- Tophat commands: bowtie-build -f test-data/tophat_in1.fasta tophat_in1 tophat -o tmp_dir -p 1 -a 8 -m 0 -i 70 -I 500000 -F 0.15 -g 40 +allow-indels +coverage-search +min-coverage-intron 50 +max-coverage-intro 20000 +segment-mismatches 2 +segment-length 25 +closure-search +min-closure-exon 50 +min-closure-intron 50 +max-closure-intro 5000 +microexon-search tophat_in1 test-data/tophat_in2.fastqsanger Replace the + with double-dash + Rename the files in tmp_dir appropriately --> + <param name="input1" ftype="fastqsanger" value="tophat_in2.fastqsanger"/><param name="genomeSource" value="history"/><param name="ownFile" value="tophat_in1.fasta"/><param name="sPaired" value="single"/> - <param name="input1" ftype="fastqsanger" value="tophat_in2.fastqsanger"/><param name="sSettingsType" value="full"/><param name="library_type" value="FR Unstranded"/><param name="anchor_length" value="8"/> @@ -585,16 +550,17 @@ <output name="junctions" file="tophat_out3j.bed" /><output name="accepted_hits" file="tophat_out3h.bam" compare="sim_size" /></test> - <!-- Test paired-end reads with user-supplied reference fasta and full parameters --> + <!-- Test base-space paired-end reads with user-supplied reference fasta and full parameters --><test><!-- TopHat commands: - tophat -o tmp_dir -r 20 -p 1 -a 8 -m 0 -i 70 -I 500000 -F 0.15 -g 40 +coverage-search +min-coverage-intron 50 +max-coverage-intro 20000 +segment-mismatches 2 +segment-length 25 +closure-search +min-closure-exon 50 +min-closure-intron 50 +max-closure-intron 5000 +microexon-search /afs/bx.psu.edu/depot/data/genome/test/tophat/tophat_in1 test-data/tophat_in2.fastqsanger test-data/tophat_in3.fastqsanger + tophat -o tmp_dir -r 20 -p 1 -a 8 -m 0 -i 70 -I 500000 -F 0.15 -g 40 +coverage-search +min-coverage-intron 50 +max-coverage-intro 20000 +segment-mismatches 2 +segment-length 25 +closure-search +min-closure-exon 50 +min-closure-intron 50 +max-closure-intron 5000 +microexon-search tophat_in1 test-data/tophat_in2.fastqsanger test-data/tophat_in3.fastqsanger Replace the + with double-dash + Rename the files in tmp_dir appropriately --> + <param name="input1" ftype="fastqsanger" value="tophat_in2.fastqsanger"/><param name="genomeSource" value="indexed"/><param name="index" value="tophat_test"/><param name="sPaired" value="paired"/> - <param name="input1" ftype="fastqsanger" value="tophat_in2.fastqsanger"/><param name="input2" ftype="fastqsanger" value="tophat_in3.fastqsanger"/><param name="mate_inner_distance" value="20"/><param name="pSettingsType" value="full"/> @@ -662,7 +628,9 @@ .. _BED: http://genome.ucsc.edu/FAQ/FAQformat.html#format1 .. _BAM: http://samtools.sourceforge.net/ - + +Two other possible outputs, depending on the options you choose, are insertions and deletions, both of which are in BED format. + ------- **Tophat settings** @@ -681,7 +649,7 @@ --mate-std-dev INT The standard deviation for the distribution on inner distances between mate pairs. The default is 20bp. -a/--min-anchor-length INT The "anchor length". TopHat will report junctions spanned by reads with at least this many bases on each side of the junction. Note that individual spliced alignments may span a junction with fewer than this many bases on one side. However, every junction involved in spliced alignments is supported by at least one - read with this many bases on each side. This must be at least 3 and the default is 8. + read with this many bases on each side. This must be at least 3 and the default is 8. -m/--splice-mismatches INT The maximum number of mismatches that may appear in the "anchor" region of a spliced alignment. The default is 0. -i/--min-intron-length INT The minimum intron length. TopHat will ignore donor/acceptor pairs closer than this many bases apart. The default is 70. -I/--max-intron-length INT The maximum intron length. When searching for junctions ab initio, TopHat will ignore donor/acceptor pairs farther than this many bases apart, except when such a pair is supported by a split segment alignment of a long read. The default is 500000. https://bitbucket.org/galaxy/galaxy-central/changeset/3f0872314937/ changeset: 3f0872314937 user: natefoo date: 2011-10-27 22:36:46 summary: A couple more fixes. affected #: 4 files diff -r 638d994c4cc7783248357b3cf7403b00924d0016 -r 3f08723149377d3f10b53909f97f90edd4babf6e lib/galaxy/jobs/__init__.py --- a/lib/galaxy/jobs/__init__.py +++ b/lib/galaxy/jobs/__init__.py @@ -778,7 +778,7 @@ jeha_false_path = None if self.app.config.outputs_to_working_directory: self.output_paths = [] - output_dataset_paths = {} + self.output_dataset_paths = {} for name, data in [ ( da.name, da.dataset.dataset ) for da in job.output_datasets + job.output_library_datasets ]: false_path = os.path.abspath( os.path.join( self.working_directory, "galaxy_dataset_%d.dat" % data.id ) ) dsp = DatasetPath( data.id, data.file_name, false_path ) @@ -908,7 +908,7 @@ else: self.prepare_input_files_cmds = None self.status = task.states.NEW - + def get_job( self ): if self.job_id: return self.sa_session.query( model.Job ).get( self.job_id ) diff -r 638d994c4cc7783248357b3cf7403b00924d0016 -r 3f08723149377d3f10b53909f97f90edd4babf6e lib/galaxy/model/__init__.py --- a/lib/galaxy/model/__init__.py +++ b/lib/galaxy/model/__init__.py @@ -649,7 +649,7 @@ permitted_actions = get_permitted_actions( filter='DATASET' ) file_path = "/tmp/" engine = None - def __init__( self, id=None, state=None, external_filename=None, extra_files_path=None, file_size=None, purgable=True): + def __init__( self, id=None, state=None, external_filename=None, extra_files_path=None, file_size=None, purgable=True ): self.id = id self.state = state self.deleted = False diff -r 638d994c4cc7783248357b3cf7403b00924d0016 -r 3f08723149377d3f10b53909f97f90edd4babf6e lib/galaxy/tools/__init__.py --- a/lib/galaxy/tools/__init__.py +++ b/lib/galaxy/tools/__init__.py @@ -819,7 +819,7 @@ if elem.tag == "repeat": group = Repeat() group.name = elem.get( "name" ) - group.title = elem.get( "title" ) + group.title = elem.get( "title" ) group.help = elem.get( "help", None ) group.inputs = self.parse_input_elem( elem, enctypes, context ) group.default = int( elem.get( "default", 0 ) ) diff -r 638d994c4cc7783248357b3cf7403b00924d0016 -r 3f08723149377d3f10b53909f97f90edd4babf6e universe_wsgi.ini.sample --- a/universe_wsgi.ini.sample +++ b/universe_wsgi.ini.sample @@ -586,9 +586,6 @@ # run with the runner defined with default_cluster_job_runner. [galaxy:tool_runners] -binsort = drmaa://-cwd -V -pe threaded 4/ -bwa_wrapper = drmaa://-cwd -V -pe threaded 4/ -unified_genotyper = drmaa://-cwd -V -pe threaded 2/ biomart = local:/// encode_db1 = local:/// hbvar = local:/// https://bitbucket.org/galaxy/galaxy-central/changeset/0dbc8f529441/ changeset: 0dbc8f529441 user: natefoo date: 2011-10-31 21:15:00 summary: Some fixes to actual user code to negate the need for world-writable directories and write external metadata and job stdout/stderr to the job working directory. affected #: 6 files diff -r 3f08723149377d3f10b53909f97f90edd4babf6e -r 0dbc8f529441cb79585c520a062ea01940714814 lib/galaxy/config.py --- a/lib/galaxy/config.py +++ b/lib/galaxy/config.py @@ -81,6 +81,7 @@ self.job_working_directory = resolve_path( kwargs.get( "job_working_directory", "database/job_working_directory" ), self.root ) self.outputs_to_working_directory = string_as_bool( kwargs.get( 'outputs_to_working_directory', False ) ) self.output_size_limit = int( kwargs.get( 'output_size_limit', 0 ) ) + self.retry_job_output_collection = int( kwargs.get( 'retry_job_output_collection', 0 ) ) self.job_walltime = kwargs.get( 'job_walltime', None ) self.admin_users = kwargs.get( "admin_users", "" ) self.mailing_join_addr = kwargs.get('mailing_join_addr',"galaxy-user-join@bx.psu.edu") @@ -219,14 +220,6 @@ os.makedirs( path ) except Exception, e: raise ConfigurationError( "Unable to create missing directory: %s\n%s" % ( path, e ) ) - if self.drmaa_external_runjob_script: - os.chmod(self.new_file_path, 0777) - os.chmod(self.job_working_directory, 0777) - os.chmod(self.cluster_files_directory, 0777) - else: - os.chmod(self.new_file_path, 0755) - os.chmod(self.job_working_directory, 0755) - os.chmod(self.cluster_files_directory, 0755) # Check that required files exist for path in self.tool_configs: diff -r 3f08723149377d3f10b53909f97f90edd4babf6e -r 0dbc8f529441cb79585c520a062ea01940714814 lib/galaxy/jobs/__init__.py --- a/lib/galaxy/jobs/__init__.py +++ b/lib/galaxy/jobs/__init__.py @@ -332,6 +332,9 @@ # Wrapper holding the info required to restore and clean up from files used for setting metadata externally self.external_output_metadata = metadata.JobExternalOutputMetadataWrapper( job ) + self.__user_system_pwent = None + self.__galaxy_system_pwent = None + def get_job_runner( self ): return self.tool.job_runner @@ -360,15 +363,15 @@ config files. """ self.sa_session.expunge_all() #this prevents the metadata reverting that has been seen in conjunction with the PBS job runner + if not os.path.exists( self.working_directory ): os.mkdir( self.working_directory ) - if self.app.config.drmaa_external_runjob_script: - os.chmod(self.working_directory , 0777) # Restore parameters from the database job = self.get_job() if job.user is None and job.galaxy_session is None: raise Exception( 'Job %s has no user and no session.' % job.id ) + incoming = dict( [ ( p.name, p.value ) for p in job.parameters ] ) incoming = self.tool.params_from_strings( incoming, self.app ) # Do any validation that could not be done at job creation @@ -526,6 +529,21 @@ # default post job setup self.sa_session.expunge_all() job = self.get_job() + + if self.app.config.drmaa_external_runjob_script and job.user is not None: + try: + # FIXME: hardcoded path + cmd = [ '/usr/bin/sudo', '-E', self.app.config.external_chown_script, self.working_directory, self.galaxy_system_pwent[0], str( self.galaxy_system_pwent[3] ) ] + log.debug( '(%s) Changing ownership of working directory with: %s' % ( job.id, ' '.join( cmd ) ) ) + p = subprocess.Popen( cmd, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) + stdout, stderr = p.communicate() + assert p.returncode == 0 + except: + # TODO: log stdout/stderr + log.exception( '(%s) Failed to change ownership of %s, failing' % ( job.id, self.working_directory ) ) + self.fail( job.info ) + return + # if the job was deleted, don't finish it if job.state == job.states.DELETED: self.cleanup() @@ -698,16 +716,6 @@ # fix permissions for path in [ dp.real_path for dp in self.get_output_fnames() ]: - #change the ownership of the files in file_path directory back to galaxy user - if self.app.config.drmaa_external_runjob_script and self.app.config.external_chown_script: - galaxy_user_name = pwd.getpwuid(os.getuid())[0] - galaxy_group_id = str(pwd.getpwuid(os.getuid())[3]) - p = subprocess.Popen([ '/usr/bin/sudo', '-E', self.app.config.external_chown_script, path,galaxy_user_name,galaxy_group_id], shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - (stdoutdata, stderrdata) = p.communicate() - exitcode = p.returncode - if exitcode != 0: - ## There was an error in the child process - raise RuntimeError("External_chown_script failed (exit code %s) with error %s" % (str(exitcode), stderrdata)) util.umask_fix_perms( path, self.app.config.umask, 0666, self.app.config.gid ) self.sa_session.flush() log.debug( 'job %d ended' % self.job_id ) @@ -718,10 +726,10 @@ try: for fname in self.extra_filenames: os.remove( fname ) + if self.app.config.set_metadata_externally: + self.external_output_metadata.cleanup_external_metadata( self.sa_session ) if self.working_directory is not None and os.path.isdir( self.working_directory ): shutil.rmtree( self.working_directory ) - if self.app.config.set_metadata_externally: - self.external_output_metadata.cleanup_external_metadata( self.sa_session ) galaxy.tools.imp_exp.JobExportHistoryArchiveWrapper( self.job_id ).cleanup_after_job( self.sa_session ) galaxy.tools.imp_exp.JobImportHistoryArchiveWrapper( self.job_id ).cleanup_after_job( self.sa_session ) except: @@ -892,6 +900,33 @@ else: return 'anonymous@unknown' + def change_ownership_for_run( self ): + job = self.get_job() + if self.app.config.external_chown_script and job.user is not None: + try: + # FIXME: hardcoded path + cmd = [ '/usr/bin/sudo', '-E', self.app.config.external_chown_script, self.working_directory, self.user_system_pwent[0], str( self.user_system_pwent[3] ) ] + log.debug( '(%s) Changing ownership of working directory with: %s' % ( job.id, ' '.join( cmd ) ) ) + p = subprocess.Popen( cmd, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) + stdout, stderr = p.communicate() + assert p.returncode == 0 + except: + log.exception( '(%s) Failed to change ownership of %s, making world-writable instead' % ( job.id, self.working_directory ) ) + os.chmod( self.working_directory, 0777 ) + + @property + def user_system_pwent( self ): + if self.__user_system_pwent is None: + job = self.get_job() + self.__user_system_pwent = pwd.getpwnam( job.user.email.split('@')[0] ) + return self.__user_system_pwent + + @property + def galaxy_system_pwent( self ): + if self.__galaxy_system_pwent is None: + self.__galaxy_system_pwent = pwd.getpwuid(os.getuid()) + return self.__galaxy_system_pwent + class TaskWrapper(JobWrapper): """ Extension of JobWrapper intended for running tasks. diff -r 3f08723149377d3f10b53909f97f90edd4babf6e -r 0dbc8f529441cb79585c520a062ea01940714814 lib/galaxy/jobs/runners/__init__.py --- a/lib/galaxy/jobs/runners/__init__.py +++ b/lib/galaxy/jobs/runners/__init__.py @@ -31,7 +31,7 @@ commands += "; cd %s; " % os.path.abspath( os.getcwd() ) commands += job_wrapper.setup_external_metadata( exec_dir = os.path.abspath( os.getcwd() ), - tmp_dir = self.app.config.new_file_path, + tmp_dir = job_wrapper.working_directory, dataset_files_path = self.app.model.Dataset.file_path, output_fnames = job_wrapper.get_output_fnames(), set_extension = False, diff -r 3f08723149377d3f10b53909f97f90edd4babf6e -r 0dbc8f529441cb79585c520a062ea01940714814 lib/galaxy/jobs/runners/drmaa.py --- a/lib/galaxy/jobs/runners/drmaa.py +++ b/lib/galaxy/jobs/runners/drmaa.py @@ -53,8 +53,6 @@ cd %s %s %s -%s -%s """ def __lineno__(): """Returns the current line number in our program.""" @@ -168,8 +166,8 @@ job_wrapper.change_state( model.Job.states.QUEUED ) # define job attributes - ofile = "%s/%s.o" % (self.app.config.cluster_files_directory, job_wrapper.get_id_tag()) - efile = "%s/%s.e" % (self.app.config.cluster_files_directory, job_wrapper.get_id_tag()) + ofile = "%s.drmout" % os.path.join(os.getcwd(), job_wrapper.working_directory, job_wrapper.get_id_tag()) + efile = "%s.drmerr" % os.path.join(os.getcwd(), job_wrapper.working_directory, job_wrapper.get_id_tag()) jt = self.ds.createJobTemplate() jt.remoteCommand = "%s/database/pbs/galaxy_%s.sh" % (os.getcwd(), job_wrapper.get_id_tag()) jt.outputPath = ":%s" % ofile @@ -191,12 +189,7 @@ else: export_tmp = '' - if self.external_runJob_script == None: - script = drm_template % (job_wrapper.galaxy_lib_dir, export_path, os.path.abspath( job_wrapper.working_directory ),export_tmp, command_line,'','') - else: - touchcmd = 'touch ' + os.path.abspath( job_wrapper.working_directory ) + '/just_in_cases.txt' - chmodcmd = 'chmod -Rf a+rwx ' + os.path.abspath( job_wrapper.working_directory ) + '/*' - script = drm_template % (job_wrapper.galaxy_lib_dir, export_path, os.path.abspath( job_wrapper.working_directory ), export_tmp, command_line, touchcmd,chmodcmd) + script = drm_template % ( job_wrapper.galaxy_lib_dir, export_path, os.path.abspath( job_wrapper.working_directory ), export_tmp, command_line ) fh = file( jt.remoteCommand, "w" ) fh.write( script ) @@ -219,9 +212,10 @@ if self.external_runJob_script is None: job_id = self.ds.runJob(jt) else: - userid = self.get_qsub_user(job_wrapper) + job_wrapper.change_ownership_for_run() + log.debug( '(%s) submitting with credentials: %s [uid: %s]' % ( galaxy_id_tag, job_wrapper.user_system_pwent[0], job_wrapper.user_system_pwent[2] ) ) filename = self.store_jobtemplate(job_wrapper, jt) - job_id = self.external_runjob(filename, userid) + job_id = self.external_runjob(filename, job_wrapper.user_system_pwent[2]).strip() log.info("(%s) queued as %s" % ( galaxy_id_tag, job_id ) ) # store runner information for tracking if Galaxy restarts @@ -315,23 +309,23 @@ efile = drm_job_state.efile job_file = drm_job_state.job_file # collect the output - # JED - HACK to wait for the files to appear + # wait for the files to appear which_try = 0 - while which_try < 60: + while which_try < (self.app.config.retry_job_output_collection + 1): try: ofh = file(ofile, "r") efh = file(efile, "r") stdout = ofh.read( 32768 ) stderr = efh.read( 32768 ) - which_try = 60 + which_try = (self.app.config.retry_job_output_collection + 1) except: - if which_try == 60: + if which_try == self.app.config.retry_job_output_collection: stdout = '' stderr = 'Job output not returned from cluster' - log.debug(stderr) + log.debug( stderr ) else: - which_try += 1 time.sleep(1) + which_try += 1 try: drm_job_state.job_wrapper.finish( stdout, stderr ) @@ -389,9 +383,9 @@ def recover( self, job, job_wrapper ): """Recovers jobs stuck in the queued/running state when Galaxy started""" drm_job_state = DRMAAJobState() - drm_job_state.ofile = "%s/database/pbs/%s.o" % (os.getcwd(), job.id) - drm_job_state.efile = "%s/database/pbs/%s.e" % (os.getcwd(), job.id) - drm_job_state.job_file = "%s/database/pbs/galaxy_%s.sh" % (os.getcwd(), job.id) + drm_job_state.ofile = "%s.drmout" % os.path.join(os.getcwd(), job_wrapper.working_directory, job_wrapper.get_id_tag()) + drm_job_state.efile = "%s.drmerr" % os.path.join(os.getcwd(), job_wrapper.working_directory, job_wrapper.get_id_tag()) + drm_job_state.job_file = "%s/galaxy_%s.sh" % (self.app.config.cluster_files_directory, job.id) drm_job_state.job_id = str( job.job_runner_external_id ) drm_job_state.runner_url = job_wrapper.get_job_runner() job_wrapper.command_line = job.command_line @@ -407,30 +401,22 @@ drm_job_state.running = False self.monitor_queue.put( drm_job_state ) - def get_qsub_user(self, job_wrapper): - """ Returns the UserID (or Username) that should be used to execute the job. """ - #TODO: - #add some logic to decide on an SGE user for the given job. - job_user_name = job_wrapper.user.split('@') - self.job_user_uid = getpwnam(job_user_name[0]) - log.debug (" (%s) is the uid being passed to the DRM queu\n" % ( self.job_user_uid[2]) ) - return self.job_user_uid[2] - def store_jobtemplate(self, job_wrapper, jt): """ Stores the content of a DRMAA JobTemplate object in a file as a JSON string. Path is hard-coded, but it's no worse than other path in this module. Uses Galaxy's JobID, so file is expected to be unique.""" - filename = "%s/database/pbs/%s.jt_json" % (os.getcwd(), job_wrapper.get_id_tag()) + filename = "%s/%s.jt_json" % (self.app.config.cluster_files_directory, job_wrapper.get_id_tag()) data = {} for attr in DRMAA_jobTemplate_attributes: try: data[attr] = getattr(jt, attr) except: pass - s = json.dumps(data); + s = json.dumps(data) f = open(filename,'w') f.write(s) f.close() + log.debug( '(%s) Job script for external submission is: %s' % ( job_wrapper.job_id, filename ) ) return filename def external_runjob(self, jobtemplate_filename, username): diff -r 3f08723149377d3f10b53909f97f90edd4babf6e -r 0dbc8f529441cb79585c520a062ea01940714814 scripts/external_chown_script.py --- a/scripts/external_chown_script.py +++ b/scripts/external_chown_script.py @@ -15,8 +15,6 @@ pkg_resources.require("drmaa") import drmaa - - def validate_paramters(): if len(sys.argv)<4: sys.stderr.write("usage: %s path user_name gid\n" % sys.argv[0]) @@ -26,16 +24,12 @@ galaxy_user_name = sys.argv[2] gid = sys.argv[3] - - return path, galaxy_user_name, gid def main(): path, galaxy_user_name, gid = validate_paramters() - os.system('chown %s %s' %(galaxy_user_name, path)) - os.system('chgrp %s %s' %(gid, path)) - - + os.system('chown -Rh %s %s' %(galaxy_user_name, path)) + os.system('chgrp -Rh %s %s' %(gid, path)) if __name__ == "__main__": main() diff -r 3f08723149377d3f10b53909f97f90edd4babf6e -r 0dbc8f529441cb79585c520a062ea01940714814 universe_wsgi.ini.sample --- a/universe_wsgi.ini.sample +++ b/universe_wsgi.ini.sample @@ -519,6 +519,13 @@ # Galaxy server after the job completes. #outputs_to_working_directory = False +# If your network filesystem's caching prevents the Galaxy server from seeing +# the job's stdout and stderr files when it completes, you can retry reading +# these files. The job runner will retry the number of times specified below, +# waiting 1 second between tries. For NFS, you may want to try the -noac mount +# option (Linux) or -actimeo=0 (Solaris). +#retry_job_output_collection = 0 + # Number of concurrent jobs to run (local job runner) #local_job_queue_workers = 5 @@ -556,9 +563,9 @@ # Also the # Defaults requiretty # in /etc/sudoers must be commented out -#drmaa_external_runjob_script = /opt/galaxy/scripts/drmaa_external_runner.py -#drmaa_external_killjob_script = /opt/galaxy/scripts/drmaa_external_killer.py -#external_chown_script = /opt/galaxy/scripts/external_chown_script.py +#drmaa_external_runjob_script = scripts/drmaa_external_runner.py +#drmaa_external_killjob_script = scripts/drmaa_external_killer.py +#external_chown_script = scripts/external_chown_script.py #important if running as actual user since enviromental variables are not passed #will supercede an other definition of TMPDIR if using drmaa https://bitbucket.org/galaxy/galaxy-central/changeset/ce2673f8f212/ changeset: ce2673f8f212 user: natefoo date: 2011-11-02 14:18:47 summary: Run as user: Don't overwrite stdout/stderr on finish. affected #: 1 file diff -r 0dbc8f529441cb79585c520a062ea01940714814 -r ce2673f8f2122c4d2cf455f35b9bdc42b540a373 lib/galaxy/jobs/__init__.py --- a/lib/galaxy/jobs/__init__.py +++ b/lib/galaxy/jobs/__init__.py @@ -536,7 +536,7 @@ cmd = [ '/usr/bin/sudo', '-E', self.app.config.external_chown_script, self.working_directory, self.galaxy_system_pwent[0], str( self.galaxy_system_pwent[3] ) ] log.debug( '(%s) Changing ownership of working directory with: %s' % ( job.id, ' '.join( cmd ) ) ) p = subprocess.Popen( cmd, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) - stdout, stderr = p.communicate() + p.wait() assert p.returncode == 0 except: # TODO: log stdout/stderr https://bitbucket.org/galaxy/galaxy-central/changeset/574db4e4ea45/ changeset: 574db4e4ea45 user: natefoo date: 2011-11-02 15:49:17 summary: Fix a merge error in model/__init__.py affected #: 1 file diff -r ce2673f8f2122c4d2cf455f35b9bdc42b540a373 -r 574db4e4ea45c90d02c89110879ace47085a1ac4 lib/galaxy/model/__init__.py --- a/lib/galaxy/model/__init__.py +++ b/lib/galaxy/model/__init__.py @@ -480,23 +480,6 @@ rval = galaxy.datatypes.data.nice_size( rval ) return rval - def get_api_value( self, view='collection', value_mapper = None ): - if value_mapper is None: - value_mapper = {} - rval = {} - try: - visible_keys = self.__getattribute__( 'api_' + view + '_visible_keys' ) - except AttributeError: - raise Exception( 'Unknown API view: %s' % view ) - for key in visible_keys: - try: - rval[key] = self.__getattribute__( key ) - if key in value_mapper: - rval[key] = value_mapper.get( key )( rval[key] ) - except AttributeError: - rval[key] = None - return rval - class HistoryUserShareAssociation( object ): def __init__( self ): self.history = None @@ -1149,28 +1132,6 @@ return hda_name def get_access_roles( self, trans ): return self.dataset.get_access_roles( trans ) - def get_api_value( self, view='collection' ): - # Since this class is a proxy to rather complex attributes we want to - # display in other objects, we can't use the simpler method used by - # other model classes. - hda = self - rval = dict( name = hda.name, - extension = hda.extension, - deleted = hda.deleted, - visible = hda.visible, - state = hda.state, - file_size = int( hda.get_size() ), - genome_build = hda.dbkey, - misc_info = hda.info, - misc_blurb = hda.blurb ) - for name, spec in hda.metadata.spec.items(): - val = hda.metadata.get( name ) - if isinstance( val, MetadataFile ): - val = val.file_name - elif isinstance( val, list ): - val = ', '.join( [str(v) for v in val] ) - rval['metadata_' + name] = val - return rval def quota_amount( self, user ): """ If the user has multiple instances of this dataset, it will not affect their disk usage statistic. https://bitbucket.org/galaxy/galaxy-central/changeset/9ec467c9268d/ changeset: 9ec467c9268d user: natefoo date: 2011-11-02 17:08:40 summary: Run as user: Removed a few more chmods that shouldn't be necessary with everything happening in the job working directory. affected #: 4 files diff -r 574db4e4ea45c90d02c89110879ace47085a1ac4 -r 9ec467c9268d58d995b81cec3499804d572d5430 lib/galaxy/jobs/runners/drmaa.py --- a/lib/galaxy/jobs/runners/drmaa.py +++ b/lib/galaxy/jobs/runners/drmaa.py @@ -365,20 +365,17 @@ def stop_job( self, job ): """Attempts to delete a job from the DRM queue""" - if self.external_killJob_script is None: - try: - self.ds.control( job.job_runner_external_id, drmaa.JobControlAction.TERMINATE ) - log.debug( "(%s/%s) Removed from DRM queue at user's request" % ( job.id, job.job_runner_external_id ) ) - except drmaa.InvalidJobException: - log.debug( "(%s/%s) User killed running job, but it was already dead" % ( job.id, job.job_runner_external_id ) ) - except Exception, e: - log.debug( "(%s/%s) User killed running job, but error encountered removing from DRM queue: %s" % ( job.id, job.job_runner_external_id, e ) ) - else: - try: - subprocess.Popen(['/usr/bin/sudo','-E', self.external_killJob_script, str(job.job_runner_external_id), str(self.job_user_uid[2])],shell=False) - log.debug( "(%s/%s) Removed from DRM queue at user's request" % ( job.id, job.job_runner_external_id ) ) - except Exception, e: - log.debug( "(%s/%s) User killed running job, but error encountered removing from DRM queue: %s" % ( job.id, job.job_runner_external_id, e ) ) + try: + if self.external_killJob_script is None: + self.ds.control( job.job_runner_external_id, drmaa.JobControlAction.TERMINATE ) + else: + # FIXME: hardcoded path + subprocess.Popen( [ '/usr/bin/sudo', '-E', self.external_killJob_script, str( job.job_runner_external_id ), str( self.job_user_uid[2] ) ], shell=False ) + log.debug( "(%s/%s) Removed from DRM queue at user's request" % ( job.id, job.job_runner_external_id ) ) + except drmaa.InvalidJobException: + log.debug( "(%s/%s) User killed running job, but it was already dead" % ( job.id, job.job_runner_external_id ) ) + except Exception, e: + log.debug( "(%s/%s) User killed running job, but error encountered removing from DRM queue: %s" % ( job.id, job.job_runner_external_id, e ) ) def recover( self, job, job_wrapper ): """Recovers jobs stuck in the queued/running state when Galaxy started""" diff -r 574db4e4ea45c90d02c89110879ace47085a1ac4 -r 9ec467c9268d58d995b81cec3499804d572d5430 lib/galaxy/model/__init__.py --- a/lib/galaxy/model/__init__.py +++ b/lib/galaxy/model/__init__.py @@ -653,7 +653,6 @@ # Create directory if it does not exist if not os.path.exists( dir ): os.makedirs( dir ) - os.chmod(dir, 0777) # Return filename inside hashed directory return os.path.abspath( os.path.join( dir, "dataset_%d.dat" % self.id ) ) else: @@ -1795,8 +1794,6 @@ # File Exists is okay, otherwise reraise if e.errno != errno.EEXIST: raise - - os.chmod(path, 0777) # Return filename inside hashed directory return os.path.abspath( os.path.join( path, "metadata_%d.dat" % self.id ) ) diff -r 574db4e4ea45c90d02c89110879ace47085a1ac4 -r 9ec467c9268d58d995b81cec3499804d572d5430 lib/galaxy/tools/__init__.py --- a/lib/galaxy/tools/__init__.py +++ b/lib/galaxy/tools/__init__.py @@ -1707,10 +1707,10 @@ fd, config_filename = tempfile.mkstemp( dir=directory ) os.close( fd ) f = open( config_filename, "wt" ) - os.chmod(config_filename, 0777) f.write( fill_template( template_text, context=param_dict ) ) f.close() - os.chmod(config_filename, 0777) + # For running jobs as the actual user, ensure the config file is globally readable + os.chmod( config_filename, 0644 ) param_dict[name] = config_filename config_filenames.append( config_filename ) return config_filenames @@ -1843,25 +1843,23 @@ """ for name, hda in output.items(): temp_file_path = os.path.join( job_working_directory, "dataset_%s_files" % ( hda.dataset.id ) ) - #try: - if os.path.exists(temp_file_path) and len( os.listdir( temp_file_path ) ) > 0: - store_file_path = os.path.join( - os.path.join( self.app.config.file_path, *directory_hash_id( hda.dataset.id ) ), + try: + if len( os.listdir( temp_file_path ) ) > 0: + store_file_path = os.path.join( + os.path.join( self.app.config.file_path, *directory_hash_id( hda.dataset.id ) ), "dataset_%d_files" % hda.dataset.id ) - os.mkdir(store_file_path) - os.system('mv %s/* %s/' %(temp_file_path ,store_file_path)) - # Fix permissions - if self.external_runJob_script == None: + shutil.move( temp_file_path, store_file_path ) + # Fix permissions for basedir, dirs, files in os.walk( store_file_path ): util.umask_fix_perms( basedir, self.app.config.umask, 0777, self.app.config.gid ) for file in files: path = os.path.join( basedir, file ) # Ignore symlinks if os.path.islink( path ): - continue + continue util.umask_fix_perms( path, self.app.config.umask, 0666, self.app.config.gid ) - #except: - #continue + except: + continue def collect_child_datasets( self, output): """ diff -r 574db4e4ea45c90d02c89110879ace47085a1ac4 -r 9ec467c9268d58d995b81cec3499804d572d5430 lib/galaxy/tools/actions/__init__.py --- a/lib/galaxy/tools/actions/__init__.py +++ b/lib/galaxy/tools/actions/__init__.py @@ -282,12 +282,9 @@ trans.sa_session.flush() trans.app.security_agent.set_all_dataset_permissions( data.dataset, output_permissions ) # Create an empty file immediately - self.external_runJob_script = trans.app.config.drmaa_external_runjob_script - if self.external_runJob_script == None: - open( data.file_name, "w" ).close() - # Fix permissions - util.umask_fix_perms( data.file_name, trans.app.config.umask, 0666) - log.debug('.DAT file name = %s\n' %(data.file_name)) + open( data.file_name, "w" ).close() + # Fix permissions + util.umask_fix_perms( data.file_name, trans.app.config.umask, 0666) # This may not be neccesary with the new parent/child associations data.designation = name # Copy metadata from one of the inputs if requested. https://bitbucket.org/galaxy/galaxy-central/changeset/f701f2805fff/ changeset: f701f2805fff user: natefoo date: 2011-11-04 00:03:55 summary: Fix for splitting with outputs_to_working_directory = True, also rename a dict and method in jobs to refer to hda instead of dataset to avoid (my own) confusion. affected #: 4 files diff -r 9ec467c9268d58d995b81cec3499804d572d5430 -r f701f2805fff88e6ad94d40b00dd8dc72f0ef48f lib/galaxy/jobs/__init__.py --- a/lib/galaxy/jobs/__init__.py +++ b/lib/galaxy/jobs/__init__.py @@ -327,7 +327,7 @@ self.working_directory = \ os.path.join( self.app.config.job_working_directory, str( self.job_id ) ) self.output_paths = None - self.output_dataset_paths = None + self.output_hdas_and_paths = None self.tool_provided_job_metadata = None # Wrapper holding the info required to restore and clean up from files used for setting metadata externally self.external_output_metadata = metadata.JobExternalOutputMetadataWrapper( job ) @@ -764,10 +764,10 @@ self.compute_outputs() return self.output_paths - def get_output_datasets_and_fnames( self ): - if self.output_dataset_paths is None: + def get_output_hdas_and_fnames( self ): + if self.output_hdas_and_paths is None: self.compute_outputs() - return self.output_dataset_paths + return self.output_hdas_and_paths def compute_outputs( self ) : class DatasetPath( object ): @@ -786,18 +786,18 @@ jeha_false_path = None if self.app.config.outputs_to_working_directory: self.output_paths = [] - self.output_dataset_paths = {} - for name, data in [ ( da.name, da.dataset.dataset ) for da in job.output_datasets + job.output_library_datasets ]: - false_path = os.path.abspath( os.path.join( self.working_directory, "galaxy_dataset_%d.dat" % data.id ) ) - dsp = DatasetPath( data.id, data.file_name, false_path ) + self.output_hdas_and_paths = {} + for name, hda in [ ( da.name, da.dataset ) for da in job.output_datasets + job.output_library_datasets ]: + false_path = os.path.abspath( os.path.join( self.working_directory, "galaxy_dataset_%d.dat" % hda.dataset.id ) ) + dsp = DatasetPath( hda.dataset.id, hda.dataset.file_name, false_path ) self.output_paths.append( dsp ) - self.output_dataset_paths[name] = data, dsp + self.output_hdas_and_paths[name] = hda, dsp if jeha: jeha_false_path = os.path.abspath( os.path.join( self.working_directory, "galaxy_dataset_%d.dat" % jeha.dataset.id ) ) else: - results = [ (da.name, da.dataset, DatasetPath( da.dataset.dataset.id, da.dataset.file_name )) for da in job.output_datasets + job.output_library_datasets ] + results = [ ( da.name, da.dataset, DatasetPath( da.dataset.dataset.id, da.dataset.file_name ) ) for da in job.output_datasets + job.output_library_datasets ] self.output_paths = [t[2] for t in results] - self.output_dataset_paths = dict([(t[0], t[1:]) for t in results]) + self.output_hdas_and_paths = dict([(t[0], t[1:]) for t in results]) if jeha: dsp = DatasetPath( jeha.dataset.id, jeha.dataset.file_name, jeha_false_path ) self.output_paths.append( dsp ) diff -r 9ec467c9268d58d995b81cec3499804d572d5430 -r f701f2805fff88e6ad94d40b00dd8dc72f0ef48f lib/galaxy/jobs/splitters/basic.py --- a/lib/galaxy/jobs/splitters/basic.py +++ b/lib/galaxy/jobs/splitters/basic.py @@ -6,7 +6,7 @@ def set_basic_defaults(job_wrapper): parent_job = job_wrapper.get_job() job_wrapper.tool.parallelism.attributes['split_inputs'] = parent_job.input_datasets[0].name - job_wrapper.tool.parallelism.attributes['merge_outputs'] = job_wrapper.get_output_datasets_and_fnames().keys()[0] + job_wrapper.tool.parallelism.attributes['merge_outputs'] = job_wrapper.get_output_hdas_and_fnames().keys()[0] def do_split (job_wrapper): if len(job_wrapper.get_input_fnames()) > 1 or len(job_wrapper.get_output_fnames()) > 1: diff -r 9ec467c9268d58d995b81cec3499804d572d5430 -r f701f2805fff88e6ad94d40b00dd8dc72f0ef48f lib/galaxy/jobs/splitters/multi.py --- a/lib/galaxy/jobs/splitters/multi.py +++ b/lib/galaxy/jobs/splitters/multi.py @@ -33,7 +33,6 @@ subdir_index[0] = subdir_index[0] + 1 if not os.path.exists(dir): os.makedirs(dir) - os.chmod(dir,0777) task_dirs.append(dir) return dir @@ -118,7 +117,7 @@ working_directory = job_wrapper.working_directory task_dirs = [os.path.join(working_directory, x) for x in os.listdir(working_directory) if x.startswith('task_')] # TODO: Output datasets can be very complex. This doesn't handle metadata files - outputs = job_wrapper.get_output_datasets_and_fnames() + outputs = job_wrapper.get_output_hdas_and_fnames() pickone_done = [] task_dirs = [os.path.join(working_directory, x) for x in os.listdir(working_directory) if x.startswith('task_')] for output in outputs: @@ -143,6 +142,7 @@ raise Exception(log_error) except Exception, e: stdout = 'Error merging files'; + log.exception( stdout ) stderr = str(e) https://bitbucket.org/galaxy/galaxy-central/changeset/89ade2dfb20a/ changeset: 89ade2dfb20a user: ichorny date: 2011-11-04 18:47:40 summary: Fix for killing jobs using external jobKillin script affected #: 1 file diff -r f701f2805fff88e6ad94d40b00dd8dc72f0ef48f -r 89ade2dfb20a1167305df832c6d5eaabf671c2a0 lib/galaxy/jobs/runners/drmaa.py --- a/lib/galaxy/jobs/runners/drmaa.py +++ b/lib/galaxy/jobs/runners/drmaa.py @@ -113,6 +113,7 @@ self.external_runJob_script = app.config.drmaa_external_runjob_script self.external_killJob_script = app.config.drmaa_external_killjob_script self.TMPDIR = app.config.TMPDIR + self.userid = [] def get_native_spec( self, url ): """Get any native DRM arguments specified by the site configuration""" @@ -215,6 +216,7 @@ job_wrapper.change_ownership_for_run() log.debug( '(%s) submitting with credentials: %s [uid: %s]' % ( galaxy_id_tag, job_wrapper.user_system_pwent[0], job_wrapper.user_system_pwent[2] ) ) filename = self.store_jobtemplate(job_wrapper, jt) + self.userid = job_wrapper.user_system_pwent[2] job_id = self.external_runjob(filename, job_wrapper.user_system_pwent[2]).strip() log.info("(%s) queued as %s" % ( galaxy_id_tag, job_id ) ) @@ -370,7 +372,7 @@ self.ds.control( job.job_runner_external_id, drmaa.JobControlAction.TERMINATE ) else: # FIXME: hardcoded path - subprocess.Popen( [ '/usr/bin/sudo', '-E', self.external_killJob_script, str( job.job_runner_external_id ), str( self.job_user_uid[2] ) ], shell=False ) + subprocess.Popen( [ '/usr/bin/sudo', '-E', self.external_killJob_script, str( job.job_runner_external_id ), str( self.userid ) ], shell=False ) log.debug( "(%s/%s) Removed from DRM queue at user's request" % ( job.id, job.job_runner_external_id ) ) except drmaa.InvalidJobException: log.debug( "(%s/%s) User killed running job, but it was already dead" % ( job.id, job.job_runner_external_id ) ) https://bitbucket.org/galaxy/galaxy-central/changeset/42c8a6cfaa5b/ changeset: 42c8a6cfaa5b user: ichorny date: 2011-11-05 00:59:30 summary: made a change to sniff.py to copyfile instead of move. Move fails when running as actual user affected #: 1 file diff -r 89ade2dfb20a1167305df832c6d5eaabf671c2a0 -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 lib/galaxy/datatypes/sniff.py --- a/lib/galaxy/datatypes/sniff.py +++ b/lib/galaxy/datatypes/sniff.py @@ -95,7 +95,7 @@ fp.write( "%s\n" % line.rstrip( "\r\n" ) ) fp.close() if in_place: - shutil.move( temp_name, fname ) + shutil.copyfile( temp_name, fname ) # Return number of lines in file. return ( i + 1, None ) else: https://bitbucket.org/galaxy/galaxy-central/changeset/f05722e66a8a/ changeset: f05722e66a8a user: natefoo date: 2011-11-07 20:17:43 summary: merge. affected #: 64 files diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 lib/galaxy/config.py --- a/lib/galaxy/config.py +++ b/lib/galaxy/config.py @@ -71,6 +71,7 @@ self.allow_user_creation = string_as_bool( kwargs.get( "allow_user_creation", "True" ) ) self.allow_user_deletion = string_as_bool( kwargs.get( "allow_user_deletion", "False" ) ) self.allow_user_dataset_purge = string_as_bool( kwargs.get( "allow_user_dataset_purge", "False" ) ) + self.allow_user_impersonation = string_as_bool( kwargs.get( "allow_user_impersonation", "False" ) ) self.new_user_dataset_access_role_default_private = string_as_bool( kwargs.get( "new_user_dataset_access_role_default_private", "False" ) ) self.template_path = resolve_path( kwargs.get( "template_path", "templates" ), self.root ) self.template_cache = resolve_path( kwargs.get( "template_cache_path", "database/compiled_templates" ), self.root ) diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 lib/galaxy/datatypes/data.py --- a/lib/galaxy/datatypes/data.py +++ b/lib/galaxy/datatypes/data.py @@ -462,15 +462,16 @@ dataset.peek = 'file does not exist' dataset.blurb = 'file purged from disk' - def split( input_files, subdir_generator_function, split_params): + def split( cls, input_datasets, subdir_generator_function, split_params): """ Split the input files by line. """ if split_params is None: return - if len(input_files) > 1: + if len(input_datasets) > 1: raise Exception("Text file splitting does not support multiple files") + input_files = [ds.file_name for ds in input_datasets] lines_per_file = None chunk_size = None @@ -534,7 +535,7 @@ part_file.close() raise f.close() - split = staticmethod(split) + split = classmethod(split) class LineCount( Text ): """ diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 lib/galaxy/datatypes/display_applications/parameters.py --- a/lib/galaxy/datatypes/display_applications/parameters.py +++ b/lib/galaxy/datatypes/display_applications/parameters.py @@ -94,13 +94,11 @@ if target_ext and not converted_dataset: if isinstance( data, DisplayDataValueWrapper ): data = data.value - assoc = trans.app.model.ImplicitlyConvertedDatasetAssociation( parent = data, file_type = target_ext, metadata_safe = False ) new_data = data.datatype.convert_dataset( trans, data, target_ext, return_output = True, visible = False ).values()[0] new_data.hid = data.hid new_data.name = data.name trans.sa_session.add( new_data ) - trans.sa_session.flush() - assoc.dataset = new_data + assoc = trans.app.model.ImplicitlyConvertedDatasetAssociation( parent = data, file_type = target_ext, dataset = new_data, metadata_safe = False ) trans.sa_session.add( assoc ) trans.sa_session.flush() elif converted_dataset and converted_dataset.state == converted_dataset.states.ERROR: diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 lib/galaxy/datatypes/genetics.py --- a/lib/galaxy/datatypes/genetics.py +++ b/lib/galaxy/datatypes/genetics.py @@ -192,27 +192,9 @@ Tabular.__init__( self, **kwd ) self.column_names = [] - def make_html_table( self, dataset, skipchars=[] ): - """ - Create HTML table, used for displaying peek - """ - out = ['<table cellspacing="0" cellpadding="3">'] - comments = [] - try: - # Generate column header - out.append( '<tr>' ) - for i, name in enumerate( self.column_names ): - out.append( '<th>%s.%s</th>' % ( str( i+1 ), name ) ) - if dataset.metadata.columns - len( self.column_names ) > 0: - for i in range( len( self.column_names ), dataset.metadata.columns ): - out.append( '<th>%s</th>' % str( i+1 ) ) - out.append( '</tr>' ) - out.append( self.make_html_peek_rows( dataset, skipchars=skipchars ) ) - out.append( '</table>' ) - out = "".join( out ) - except Exception, exc: - out = "Can't create peek %s" % exc - return out + def display_peek( self, dataset ): + """Returns formated html of peek""" + return Tabular.make_html_table( self, dataset, column_names=self.column_names ) def get_mime(self): """Returns the mime type of the datatype""" diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 lib/galaxy/datatypes/interval.py --- a/lib/galaxy/datatypes/interval.py +++ b/lib/galaxy/datatypes/interval.py @@ -219,33 +219,9 @@ os.write(fd, '%s\n' % '\t'.join(tmp) ) os.close(fd) return open(temp_name) - def make_html_table( self, dataset, skipchars=[] ): - """Create HTML table, used for displaying peek""" - out = ['<table cellspacing="0" cellpadding="3">'] - comments = [] - try: - # Generate column header - out.append('<tr>') - for i in range( 1, dataset.metadata.columns+1 ): - if i == dataset.metadata.chromCol: - out.append( '<th>%s.Chrom</th>' % i ) - elif i == dataset.metadata.startCol: - out.append( '<th>%s.Start</th>' % i ) - elif i == dataset.metadata.endCol: - out.append( '<th>%s.End</th>' % i ) - elif dataset.metadata.strandCol and i == dataset.metadata.strandCol: - out.append( '<th>%s.Strand</th>' % i ) - elif dataset.metadata.nameCol and i == dataset.metadata.nameCol: - out.append( '<th>%s.Name</th>' % i ) - else: - out.append( '<th>%s</th>' % i ) - out.append('</tr>') - out.append( self.make_html_peek_rows( dataset, skipchars=skipchars ) ) - out.append( '</table>' ) - out = "".join( out ) - except Exception, exc: - out = "Can't create peek %s" % str( exc ) - return out + def display_peek( self, dataset ): + """Returns formated html of peek""" + return Tabular.make_html_table( self, dataset, column_parameter_alias={'chromCol':'Chrom', 'startCol':'Start', 'endCol':'End', 'strandCol':'Strand', 'nameCol':'Name'} ) def ucsc_links( self, dataset, type, app, base_url ): """ Generate links to UCSC genome browser sites based on the dbkey @@ -617,21 +593,9 @@ except: pass Tabular.set_meta( self, dataset, overwrite = overwrite, skip = i ) - def make_html_table( self, dataset, skipchars=[] ): - """Create HTML table, used for displaying peek""" - out = ['<table cellspacing="0" cellpadding="3">'] - comments = [] - try: - # Generate column header - out.append( '<tr>' ) - for i, name in enumerate( self.column_names ): - out.append( '<th>%s.%s</th>' % ( str( i+1 ), name ) ) - out.append( self.make_html_peek_rows( dataset, skipchars=skipchars ) ) - out.append( '</table>' ) - out = "".join( out ) - except Exception, exc: - out = "Can't create peek %s" % exc - return out + def display_peek( self, dataset ): + """Returns formated html of peek""" + return Tabular.make_html_table( self, dataset, column_names=self.column_names ) def get_estimated_display_viewport( self, dataset ): """ Return a chrom, start, stop tuple for viewing a file. There are slight differences between gff 2 and gff 3 @@ -1081,7 +1045,8 @@ link = self._get_remote_call_url( redirect_url, site_name, dataset, type, app, base_url ) ret_val.append( ( site_name, link ) ) return ret_val - def make_html_table( self, dataset ): + def display_peek( self, dataset ): + """Returns formated html of peek""" return Tabular.make_html_table( self, dataset, skipchars=['track', '#'] ) def set_meta( self, dataset, overwrite = True, **kwd ): max_data_lines = None diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 lib/galaxy/datatypes/tabular.py --- a/lib/galaxy/datatypes/tabular.py +++ b/lib/galaxy/datatypes/tabular.py @@ -164,64 +164,69 @@ dataset.metadata.comment_lines = comment_lines dataset.metadata.column_types = column_types dataset.metadata.columns = len( column_types ) - def make_html_table( self, dataset, skipchars=[] ): + def make_html_table( self, dataset, **kwargs ): """Create HTML table, used for displaying peek""" out = ['<table cellspacing="0" cellpadding="3">'] try: - out.append( '<tr>' ) - # Generate column header - for i in range( 1, dataset.metadata.columns+1 ): - out.append( '<th>%s</th>' % str( i ) ) - out.append( '</tr>' ) - out.append( self.make_html_peek_rows( dataset, skipchars=skipchars ) ) + out.append( self.make_html_peek_header( dataset, **kwargs ) ) + out.append( self.make_html_peek_rows( dataset, **kwargs ) ) out.append( '</table>' ) out = "".join( out ) except Exception, exc: out = "Can't create peek %s" % str( exc ) return out - def make_html_peek_rows( self, dataset, skipchars=[] ): - out = [""] - comments = [] - if not dataset.peek: - dataset.set_peek() - data = dataset.peek - lines = data.splitlines() - for line in lines: - line = line.rstrip( '\r\n' ) - if not line: - continue - comment = False - for skipchar in skipchars: - if line.startswith( skipchar ): - comments.append( line ) - comment = True - break - if comment: - continue - elems = line.split( '\t' ) - if len( elems ) != dataset.metadata.columns: - # We may have an invalid comment line or invalid data - comments.append( line ) - comment = True - continue - while len( comments ) > 0: # Keep comments - try: - out.append( '<tr><td colspan="100%">' ) - except: - out.append( '<tr><td>' ) - out.append( '%s</td></tr>' % escape( comments.pop(0) ) ) + def make_html_peek_header( self, dataset, skipchars=[], column_names=[], column_number_format='%s', column_parameter_alias={}, **kwargs ): + out = [] + try: + column_headers = [None] * dataset.metadata.columns + + # fill in empty headers with data from column_names + for i in range( min( dataset.metadata.columns, len( column_names ) ) ): + if column_headers[i] is None and column_names[i] is not None: + column_headers[i] = column_names[i] + + # fill in empty headers from ColumnParameters set in the metadata + for name, spec in dataset.metadata.spec.items(): + if isinstance( spec.param, metadata.ColumnParameter ): + try: + i = int( getattr( dataset.metadata, name ) ) - 1 + except: + i = -1 + if 0 <= i < dataset.metadata.columns and column_headers[i] is None: + column_headers[i] = column_parameter_alias.get(name, name) + out.append( '<tr>' ) - for elem in elems: # valid data - elem = escape( elem ) - out.append( '<td>%s</td>' % elem ) + for i, header in enumerate( column_headers ): + out.append( '<th>' ) + if header is None: + out.append( column_number_format % str( i + 1 ) ) + else: + out.append( '%s.%s' % ( str( i + 1 ), escape( header ) ) ) + out.append( '</th>' ) out.append( '</tr>' ) - # Peek may consist only of comments - while len( comments ) > 0: - try: - out.append( '<tr><td colspan="100%">' ) - except: - out.append( '<tr><td>' ) - out.append( '%s</td></tr>' % escape( comments.pop(0) ) ) + except Exception, exc: + raise Exception, "Can't create peek header %s" % str( exc ) + return "".join( out ) + def make_html_peek_rows( self, dataset, skipchars=[], **kwargs ): + out = [] + try: + if not dataset.peek: + dataset.set_peek() + for line in dataset.peek.splitlines(): + if line.startswith( tuple( skipchars ) ): + out.append( '<tr><td colspan="100%%">%s</td></tr>' % escape( line ) ) + elif line: + elems = line.split( '\t' ) + # we may have an invalid comment line or invalid data + if len( elems ) != dataset.metadata.columns: + out.append( '<tr><td colspan="100%%">%s</td></tr>' % escape( line ) ) + else: + out.append( '<tr>' ) + for elem in elems: + out.append( '<td>%s</td>' % escape( elem ) ) + out.append( '</tr>' ) + except Exception, exc: + raise Exception, "Can't create peek rows %s" % str( exc ) return "".join( out ) def set_peek( self, dataset, line_count=None, is_multi_byte=False): super(Tabular, self).set_peek( dataset, line_count=line_count, is_multi_byte=is_multi_byte) @@ -252,26 +257,9 @@ 'Superorder', 'Order', 'Suborder', 'Superfamily', 'Family', 'Subfamily', 'Tribe', 'Subtribe', 'Genus', 'Subgenus', 'Species', 'Subspecies' ] - def make_html_table( self, dataset, skipchars=[] ): - """Create HTML table, used for displaying peek""" - out = ['<table cellspacing="0" cellpadding="3">'] - comments = [] - try: - # Generate column header - out.append( '<tr>' ) - for i, name in enumerate( self.column_names ): - out.append( '<th>%s.%s</th>' % ( str( i+1 ), name ) ) - # This data type requires at least 24 columns in the data - if dataset.metadata.columns - len( self.column_names ) > 0: - for i in range( len( self.column_names ), dataset.metadata.columns ): - out.append( '<th>%s</th>' % str( i+1 ) ) - out.append( '</tr>' ) - out.append( self.make_html_peek_rows( dataset, skipchars=skipchars ) ) - out.append( '</table>' ) - out = "".join( out ) - except Exception, exc: - out = "Can't create peek %s" % exc - return out + def display_peek( self, dataset ): + """Returns formated html of peek""" + return Tabular.make_html_table( self, dataset, column_names=self.column_names ) class Sam( Tabular ): file_ext = 'sam' @@ -281,25 +269,10 @@ self.column_names = ['QNAME', 'FLAG', 'RNAME', 'POS', 'MAPQ', 'CIGAR', 'MRNM', 'MPOS', 'ISIZE', 'SEQ', 'QUAL', 'OPT' ] - def make_html_table( self, dataset, skipchars=[] ): - """Create HTML table, used for displaying peek""" - out = ['<table cellspacing="0" cellpadding="3">'] - try: - # Generate column header - out.append( '<tr>' ) - for i, name in enumerate( self.column_names ): - out.append( '<th>%s.%s</th>' % ( str( i+1 ), name ) ) - # This data type requires at least 11 columns in the data - if dataset.metadata.columns - len( self.column_names ) > 0: - for i in range( len( self.column_names ), dataset.metadata.columns ): - out.append( '<th>%s</th>' % str( i+1 ) ) - out.append( '</tr>' ) - out.append( self.make_html_peek_rows( dataset, skipchars=skipchars ) ) - out.append( '</table>' ) - out = "".join( out ) - except Exception, exc: - out = "Can't create peek %s" % exc - return out + def display_peek( self, dataset ): + """Returns formated html of peek""" + return Tabular.make_html_table( self, dataset, column_names=self.column_names ) + def sniff( self, filename ): """ Determines whether the file is in SAM format @@ -393,29 +366,9 @@ def init_meta( self, dataset, copy_from=None ): Tabular.init_meta( self, dataset, copy_from=copy_from ) - def make_html_table( self, dataset, skipchars=[] ): - """Create HTML table, used for displaying peek""" - out = ['<table cellspacing="0" cellpadding="3">'] - comments = [] - try: - # Generate column header - out.append('<tr>') - for i in range( 1, dataset.metadata.columns+1 ): - if i == dataset.metadata.chromCol: - out.append( '<th>%s.Chrom</th>' % i ) - elif i == dataset.metadata.startCol: - out.append( '<th>%s.Start</th>' % i ) - elif i == dataset.metadata.baseCol: - out.append( '<th>%s.Base</th>' % i ) - else: - out.append( '<th>%s</th>' % i ) - out.append('</tr>') - out.append( self.make_html_peek_rows( dataset, skipchars=skipchars ) ) - out.append( '</table>' ) - out = "".join( out ) - except Exception, exc: - out = "Can't create peek %s" % str( exc ) - return out + def display_peek( self, dataset ): + """Returns formated html of peek""" + return Tabular.make_html_table( self, dataset, column_parameter_alias={'chromCol':'Chrom', 'startCol':'Start', 'baseCol':'Base'} ) def repair_methods( self, dataset ): """Return options for removing errors along with a description""" @@ -481,21 +434,9 @@ def sniff( self, filename ): headers = get_headers( filename, '\n', count=1 ) return headers[0][0].startswith("##fileformat=VCF") + def display_peek( self, dataset ): + """Returns formated html of peek""" + return Tabular.make_html_table( self, dataset, column_names=self.column_names ) - def make_html_table( self, dataset, skipchars=[] ): - """Create HTML table, used for displaying peek""" - out = ['<table cellspacing="0" cellpadding="3">'] - try: - # Generate column header - out.append( '<tr>' ) - for i, name in enumerate( self.column_names ): - out.append( '<th>%s.%s</th>' % ( str( i+1 ), name ) ) - out.append( self.make_html_peek_rows( dataset, skipchars=skipchars ) ) - out.append( '</table>' ) - out = "".join( out ) - except Exception, exc: - out = "Can't create peek %s" % exc - return out - def get_track_type( self ): - return "FeatureTrack", {"data": "tabix", "index": "summary_tree"} + return "VcfTrack", {"data": "tabix", "index": "summary_tree"} diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 lib/galaxy/tools/actions/__init__.py --- a/lib/galaxy/tools/actions/__init__.py +++ b/lib/galaxy/tools/actions/__init__.py @@ -43,13 +43,11 @@ data = converted_dataset else: #run converter here - assoc = trans.app.model.ImplicitlyConvertedDatasetAssociation( parent = data, file_type = target_ext, metadata_safe = False ) new_data = data.datatype.convert_dataset( trans, data, target_ext, return_output = True, visible = False ).values()[0] new_data.hid = data.hid new_data.name = data.name trans.sa_session.add( new_data ) - trans.sa_session.flush() - assoc.dataset = new_data + assoc = trans.app.model.ImplicitlyConvertedDatasetAssociation( parent = data, file_type = target_ext, dataset = new_data, metadata_safe = False ) trans.sa_session.add( assoc ) trans.sa_session.flush() data = new_data diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 lib/galaxy/visualization/tracks/data_providers.py --- a/lib/galaxy/visualization/tracks/data_providers.py +++ b/lib/galaxy/visualization/tracks/data_providers.py @@ -135,10 +135,137 @@ { 'name' : attrs[ 'name' ], 'type' : column_types[viz_col_index], \ 'index' : attrs[ 'index' ] } ) return filters + +# +# -- Base mixins and providers -- +# + +class FilterableMixin: + def get_filters( self ): + """ Returns a dataset's filters. """ + + # is_ functions taken from Tabular.set_meta + def is_int( column_text ): + try: + int( column_text ) + return True + except: + return False + def is_float( column_text ): + try: + float( column_text ) + return True + except: + if column_text.strip().lower() == 'na': + return True #na is special cased to be a float + return False + + # + # Get filters. + # TODOs: + # (a) might be useful to move this into each datatype's set_meta method; + # (b) could look at first N lines to ensure GTF attribute types are consistent. + # + filters = [] + # HACK: first 8 fields are for drawing, so start filter column index at 9. + filter_col = 8 + if isinstance( self.original_dataset.datatype, Gff ): + # Can filter by score and GTF attributes. + filters = [ { 'name': 'Score', + 'type': 'int', + 'index': filter_col, + 'tool_id': 'Filter1', + 'tool_exp_name': 'c6' } ] + filter_col += 1 + if isinstance( self.original_dataset.datatype, Gtf ): + # Create filters based on dataset metadata. + for name, a_type in self.original_dataset.metadata.attribute_types.items(): + if a_type in [ 'int', 'float' ]: + filters.append( + { 'name': name, + 'type': a_type, + 'index': filter_col, + 'tool_id': 'gff_filter_by_attribute', + 'tool_exp_name': name } ) + filter_col += 1 + + ''' + # Old code: use first line in dataset to find attributes. + for i, line in enumerate( open(self.original_dataset.file_name) ): + if not line.startswith('#'): + # Look at first line for attributes and types. + attributes = parse_gff_attributes( line.split('\t')[8] ) + for attr, value in attributes.items(): + # Get attribute type. + if is_int( value ): + attr_type = 'int' + elif is_float( value ): + attr_type = 'float' + else: + attr_type = 'str' + # Add to filters. + if attr_type is not 'str': + filters.append( { 'name': attr, 'type': attr_type, 'index': filter_col } ) + filter_col += 1 + break + ''' + elif isinstance( self.original_dataset.datatype, Bed ): + # Can filter by score column only. + filters = [ { 'name': 'Score', + 'type': 'int', + 'index': filter_col, + 'tool_id': 'Filter1', + 'tool_exp_name': 'c5' + } ] + + return filters + + +class TabixDataProvider( FilterableMixin, TracksDataProvider ): + """ + Tabix index data provider for the Galaxy track browser. + """ + + col_name_data_attr_mapping = { 4 : { 'index': 4 , 'name' : 'Score' } } + + def get_iterator( self, chrom, start, end ): + start, end = int(start), int(end) + if end >= (2<<29): + end = (2<<29 - 1) # Tabix-enforced maximum + + bgzip_fname = self.dependencies['bgzip'].file_name + + # if os.path.getsize(self.converted_dataset.file_name) == 0: + # return { 'kind': messages.ERROR, 'message': "Tabix converted size was 0, meaning the input file had invalid values." } + tabix = ctabix.Tabixfile(bgzip_fname, index_filename=self.converted_dataset.file_name) + + # If chrom is not found in indexes, try removing the first three + # characters (e.g. 'chr') and see if that works. This enables the + # provider to handle chrome names defined as chrXXX and as XXX. + chrom = str(chrom) + if chrom not in tabix.contigs and chrom.startswith("chr") and (chrom[3:] in tabix.contigs): + chrom = chrom[3:] + + return tabix.fetch(reference=chrom, start=start, end=end) + + def get_data( self, chrom, start, end, start_val=0, max_vals=None, **kwargs ): + iterator = self.get_iterator( chrom, start, end ) + return self.process_data( iterator, start_val, max_vals, **kwargs ) + + def write_data_to_file( self, chrom, start, end, filename ): + iterator = self.get_iterator( chrom, start, end ) + out = open( filename, "w" ) + for line in iterator: + out.write( "%s\n" % line ) + out.close() + +# +# -- BED data providers -- +# class BedDataProvider( TracksDataProvider ): """ - Abstract class that processes BED data from text format to payload format. + Abstract class that processes BED data from native format to payload format. Payload format: [ uid (offset), start, end, name, strand, thick_start, thick_end, blocks ] """ @@ -220,7 +347,168 @@ for line in iterator: out.write( "%s\n" % line ) out.close() - + +class BedTabixDataProvider( TabixDataProvider, BedDataProvider ): + """ + Provides data from a BED file indexed via tabix. + """ + pass + +class RawBedDataProvider( BedDataProvider ): + """ + Provide data from BED file. + + NOTE: this data provider does not use indices, and hence will be very slow + for large datasets. + """ + + def get_iterator( self, chrom, start, end ): + def line_filter_iter(): + for line in open( self.original_dataset.file_name ): + feature = line.split() + feature_chrom = feature[0] + feature_start = int( feature[1] ) + feature_end = int( feature[2] ) + if feature_chrom != chrom or feature_start > int( end ) or feature_end < int( start ): + continue + yield line + return line_filter_iter() + +# +# -- VCF data providers -- +# + +class VcfDataProvider( TracksDataProvider ): + """ + Abstract class that processes VCF data from native format to payload format. + + Payload format: TODO + """ + + col_name_data_attr_mapping = { 'Qual' : { 'index': 6 , 'name' : 'Qual' } } + + + def get_iterator( self, chrom, start, end ): + raise "Unimplemented Method" + + def get_data( self, chrom, start, end, start_val=0, max_vals=None, **kwargs ): + iterator = self.get_iterator( chrom, start, end ) + return self.process_data( iterator, start_val, max_vals, **kwargs ) + + def process_data( self, iterator, start_val=0, max_vals=None, **kwargs ): + """ + Returns a dict with the following attributes: + data - a list of variants with the format + [<guid>, <start>, <end>, <name>, cigar, seq] + + message - error/informative message + """ + rval = [] + message = None + + def get_mapping( ref, alt ): + """ + Returns ( offset, new_seq, cigar ) tuple that defines mapping of + alt to ref. Cigar format is an array of [ op_index, length ] pairs + where op_index is the 0-based index into the string "MIDNSHP=X" + """ + + cig_ops = "MIDNSHP=X" + + ref_len = len( ref ) + alt_len = len( alt ) + + # Substitutions? + if ref_len == alt_len: + return 0, alt, [ [ cig_ops.find( "M" ), ref_len ] ] + + # Deletions? + alt_in_ref_index = ref.find( alt ) + if alt_in_ref_index != -1: + return alt_in_ref_index, ref[ alt_in_ref_index + 1: ], [ [ cig_ops.find( "D" ), ref_len - alt_len ] ] + + # Insertions? + ref_in_alt_index = alt.find( ref ) + if ref_in_alt_index != -1: + return ref_in_alt_index, alt[ ref_in_alt_index + 1: ], [ [ cig_ops.find( "I" ), alt_len - ref_len ] ] + + # Pack data. + for count, line in enumerate( iterator ): + if count < start_val: + continue + if max_vals and count-start_val >= max_vals: + message = ERROR_MAX_VALS % ( max_vals, "features" ) + break + + feature = line.split() + start = int( feature[1] ) - 1 + ref = feature[3] + alts = feature[4] + + # HACK? alts == '.' --> monomorphism. + if alts == '.': + alts = ref + + # Pack variants. + for alt in alts.split(","): + offset, new_seq, cigar = get_mapping( ref, alt ) + start += offset + end = start + len( new_seq ) + + # Pack line. + payload = [ hash( line ), + start, + end, + # ID: + feature[2], + cigar, + # TODO? VCF does not have strand, so default to positive. + "+", + new_seq, + float( feature[5] ) ] + rval.append(payload) + + return { 'data': rval, 'message': message } + + def write_data_to_file( self, chrom, start, end, filename ): + iterator = self.get_iterator( chrom, start, end ) + out = open( filename, "w" ) + for line in iterator: + out.write( "%s\n" % line ) + out.close() + +class VcfTabixDataProvider( TabixDataProvider, VcfDataProvider ): + """ + Provides data from a VCF file indexed via tabix. + """ + pass + +class RawVcfDataProvider( VcfDataProvider ): + """ + Provide data from VCF file. + + NOTE: this data provider does not use indices, and hence will be very slow + for large datasets. + """ + + def get_iterator( self, chrom, start, end ): + def line_filter_iter(): + for line in open( self.original_dataset.file_name ): + if line.startswith("#"): + continue + variant = line.split() + variant_chrom, variant_start, id, ref, alts = variant[ 0:5 ] + variant_start = int( variant_start ) + longest_alt = -1 + for alt in alts: + if len( alt ) > longest_alt: + longest_alt = len( alt ) + variant_end = variant_start + abs( len( ref ) - longest_alt ) + if variant_chrom != chrom or variant_start > int( end ) or variant_end < int( start ): + continue + yield line + return line_filter_iter() + class SummaryTreeDataProvider( TracksDataProvider ): """ Summary tree data provider for the Galaxy track browser. @@ -323,11 +611,11 @@ data - a list of reads with the format [<guid>, <start>, <end>, <name>, <read_1>, <read_2>] where <read_1> has the format - [<start>, <end>, <cigar>, ?<read_seq>?] + [<start>, <end>, <cigar>, <strand>, ?<read_seq>?] and <read_2> has the format - [<start>, <end>, <cigar>, ?<read_seq>?] + [<start>, <end>, <cigar>, <strand>, ?<read_seq>?] For single-end reads, read has format: - [<guid>, <start>, <end>, <name>, cigar, seq] + [<guid>, <start>, <end>, <name>, <cigar>, <strand>, <seq>] NOTE: read end and sequence data are not valid for reads outside of requested region and should not be used. @@ -355,17 +643,34 @@ else: return None + # Decode strand from read flag. + def decode_strand( read_flag, mask ): + strand_flag = ( read_flag & mask == 0 ) + if strand_flag: + return "+" + else: + return "-" + # Encode reads as list of lists. results = [] paired_pending = {} + unmapped = 0 for count, read in enumerate( data ): if count < start_val: continue - if count-start_val >= max_vals: + if ( count - start_val - unmapped ) >= max_vals: message = ERROR_MAX_VALS % ( max_vals, "reads" ) break + + # If not mapped, skip read. + is_mapped = ( read.flag & 0x0004 == 0 ) + if not is_mapped: + unmapped += 1 + continue + qname = read.qname seq = read.seq + strand = decode_strand( read.flag, 0x0010 ) if read.cigar is not None: read_len = sum( [cig[1] for cig in read.cigar] ) # Use cigar to determine length else: @@ -378,14 +683,15 @@ pair['start'], read.pos + read_len, qname, - [ pair['start'], pair['end'], pair['cigar'], pair['seq'] ], - [ read.pos, read.pos + read_len, read.cigar, seq ] + [ pair['start'], pair['end'], pair['cigar'], pair['strand'], pair['seq'] ], + [ read.pos, read.pos + read_len, read.cigar, strand, seq ] ] ) del paired_pending[qname] else: - paired_pending[qname] = { 'start': read.pos, 'end': read.pos + read_len, 'seq': seq, 'mate_start': read.mpos, 'rlen': read_len, 'cigar': read.cigar } + paired_pending[qname] = { 'start': read.pos, 'end': read.pos + read_len, 'seq': seq, 'mate_start': read.mpos, + 'rlen': read_len, 'strand': strand, 'cigar': read.cigar } else: - results.append( [ "%i_%s" % ( read.pos, qname ), read.pos, read.pos + read_len, qname, read.cigar, read.seq] ) + results.append( [ "%i_%s" % ( read.pos, qname ), read.pos, read.pos + read_len, qname, read.cigar, strand, read.seq] ) # Take care of reads whose mates are out of range. # TODO: count paired reads when adhering to max_vals? @@ -397,14 +703,14 @@ # Make read_1 start=end so that length is 0 b/c we don't know # read length. r1 = [ read['mate_start'], read['mate_start'] ] - r2 = [ read['start'], read['end'], read['cigar'], read['seq'] ] + r2 = [ read['start'], read['end'], read['cigar'], read['strand'], read['seq'] ] else: # Mate is after read. read_start = read['start'] # Make read_2 start=end so that length is 0 b/c we don't know # read length. Hence, end of read is start of read_2. read_end = read['mate_start'] - r1 = [ read['start'], read['end'], read['cigar'], read['seq'] ] + r1 = [ read['start'], read['end'], read['cigar'], read['strand'], read['seq'] ] r2 = [ read['mate_start'], read['mate_start'] ] results.append( [ "%i_%s" % ( read_start, qname ), read_start, read_end, qname, r1, r2 ] ) @@ -485,118 +791,7 @@ else: f = open( self.original_dataset.file_name ) return f, BigWigFile(file=f) - -class FilterableMixin: - def get_filters( self ): - """ Returns a dataset's filters. """ - - # is_ functions taken from Tabular.set_meta - def is_int( column_text ): - try: - int( column_text ) - return True - except: - return False - def is_float( column_text ): - try: - float( column_text ) - return True - except: - if column_text.strip().lower() == 'na': - return True #na is special cased to be a float - return False - - # - # Get filters. - # TODOs: - # (a) might be useful to move this into each datatype's set_meta method; - # (b) could look at first N lines to ensure GTF attribute types are consistent. - # - filters = [] - # HACK: first 8 fields are for drawing, so start filter column index at 9. - filter_col = 8 - if isinstance( self.original_dataset.datatype, Gff ): - # Can filter by score and GTF attributes. - filters = [ { 'name': 'Score', - 'type': 'int', - 'index': filter_col, - 'tool_id': 'Filter1', - 'tool_exp_name': 'c6' } ] - filter_col += 1 - if isinstance( self.original_dataset.datatype, Gtf ): - # Create filters based on dataset metadata. - for name, a_type in self.original_dataset.metadata.attribute_types.items(): - if a_type in [ 'int', 'float' ]: - filters.append( - { 'name': name, - 'type': a_type, - 'index': filter_col, - 'tool_id': 'gff_filter_by_attribute', - 'tool_exp_name': name } ) - filter_col += 1 - - ''' - # Old code: use first line in dataset to find attributes. - for i, line in enumerate( open(self.original_dataset.file_name) ): - if not line.startswith('#'): - # Look at first line for attributes and types. - attributes = parse_gff_attributes( line.split('\t')[8] ) - for attr, value in attributes.items(): - # Get attribute type. - if is_int( value ): - attr_type = 'int' - elif is_float( value ): - attr_type = 'float' - else: - attr_type = 'str' - # Add to filters. - if attr_type is not 'str': - filters.append( { 'name': attr, 'type': attr_type, 'index': filter_col } ) - filter_col += 1 - break - ''' - elif isinstance( self.original_dataset.datatype, Bed ): - # Can filter by score column only. - filters = [ { 'name': 'Score', - 'type': 'int', - 'index': filter_col, - 'tool_id': 'Filter1', - 'tool_exp_name': 'c5' - } ] - - return filters - -class TabixDataProvider( FilterableMixin, TracksDataProvider ): - """ - Tabix index data provider for the Galaxy track browser. - """ - - col_name_data_attr_mapping = { 4 : { 'index': 4 , 'name' : 'Score' } } - - def get_iterator( self, chrom, start, end ): - start, end = int(start), int(end) - if end >= (2<<29): - end = (2<<29 - 1) # Tabix-enforced maximum - - bgzip_fname = self.dependencies['bgzip'].file_name - - # if os.path.getsize(self.converted_dataset.file_name) == 0: - # return { 'kind': messages.ERROR, 'message': "Tabix converted size was 0, meaning the input file had invalid values." } - tabix = ctabix.Tabixfile(bgzip_fname, index_filename=self.converted_dataset.file_name) - - # If chrom is not found in indexes, try removing the first three - # characters (e.g. 'chr') and see if that works. This enables the - # provider to handle chrome names defined as chrXXX and as XXX. - chrom = str(chrom) - if chrom not in tabix.contigs and chrom.startswith("chr") and (chrom[3:] in tabix.contigs): - chrom = chrom[3:] - - return tabix.fetch(reference=chrom, start=start, end=end) - - def get_data( self, chrom, start, end, start_val=0, max_vals=None, **kwargs ): - iterator = self.get_iterator( chrom, start, end ) - return self.process_data( iterator, start_val, max_vals, **kwargs ) - + class IntervalIndexDataProvider( FilterableMixin, TracksDataProvider ): """ Interval index files used only for GFF files. @@ -658,41 +853,6 @@ results.append( payload ) return { 'data': results, 'message': message } - -class VcfDataProvider( TabixDataProvider ): - """ - VCF data provider for the Galaxy track browser. - - Payload format: - [ uid (offset), start, end, ID, reference base(s), alternate base(s), quality score ] - """ - - col_name_data_attr_mapping = { 'Qual' : { 'index': 6 , 'name' : 'Qual' } } - - def process_data( self, iterator, start_val=0, max_vals=sys.maxint, **kwargs ): - rval = [] - message = None - - for count, line in enumerate( iterator ): - if count < start_val: - continue - if count-start_val >= max_vals: - message = ERROR_MAX_VALS % ( "max_vals", "features" ) - break - - feature = line.split() - payload = [ hash(line), int(feature[1])-1, int(feature[1]), - # ID: - feature[2], - # reference base(s): - feature[3], - # alternative base(s) - feature[4], - # phred quality score - float( feature[5] )] - rval.append(payload) - - return { 'data': rval, 'message': message } class GFFDataProvider( TracksDataProvider ): """ @@ -724,40 +884,16 @@ offset += feature.raw_size return { 'data': results, 'message': message } - -class BedTabixDataProvider( TabixDataProvider, BedDataProvider ): - """ - Provides data from a BED file indexed via tabix. - """ - pass - -class RawBedDataProvider( BedDataProvider ): - """ - Provide data from BED file. - - NOTE: this data provider does not use indices, and hence will be very slow - for large datasets. - """ - - def get_iterator( self, chrom, start, end ): - def line_filter_iter(): - for line in open( self.original_dataset.file_name ): - feature = line.split() - feature_chrom, feature_start, feature_end = feature[ 0:3 ] - if feature_chrom != chrom or feature_start > end or feature_end < start: - continue - yield line - return line_filter_iter() - + # -# Helper methods. +# -- Helper methods. -- # # Mapping from dataset type name to a class that can fetch data from a file of that # type. First key is converted dataset type; if result is another dict, second key # is original dataset type. TODO: This needs to be more flexible. dataset_type_name_to_data_provider = { - "tabix": { Vcf: VcfDataProvider, Bed: BedTabixDataProvider, "default" : TabixDataProvider }, + "tabix": { Vcf: VcfTabixDataProvider, Bed: BedTabixDataProvider, "default" : TabixDataProvider }, "interval_index": IntervalIndexDataProvider, "bai": BamDataProvider, "summary_tree": SummaryTreeDataProvider, diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 lib/galaxy/web/controllers/admin.py --- a/lib/galaxy/web/controllers/admin.py +++ b/lib/galaxy/web/controllers/admin.py @@ -410,7 +410,8 @@ columns = [ NameColumn( "Name", key="name", - attach_popup=True ), + link=( lambda item: dict( operation="manage_repository", id=item.id, webapp="galaxy" ) ), + attach_popup=False ), DescriptionColumn( "Description" ), OwnerColumn( "Owner" ), RevisionColumn( "Revision" ), @@ -426,17 +427,14 @@ key="free-text-search", visible=False, filterable="standard" ) ) - operations = [ grids.GridOperation( "Get updates", - allow_multiple=False, - condition=( lambda item: not item.deleted ), - async_compatible=False ) ] standard_filters = [] default_filter = dict( deleted="False" ) num_rows_per_page = 50 preserve_state = False use_paging = True def build_initial_query( self, trans, **kwd ): - return trans.sa_session.query( self.model_class ) + return trans.sa_session.query( self.model_class ) \ + .filter( self.model_class.table.c.deleted == False ) class AdminGalaxy( BaseUIController, Admin, AdminActions, UsesQuota, QuotaParamParser ): @@ -678,11 +676,88 @@ return quota, params @web.expose @web.require_admin - def browse_repositories( self, trans, **kwd ): + def browse_tool_shed_repository( self, trans, **kwd ): + params = util.Params( kwd ) + message = util.restore_text( params.get( 'message', '' ) ) + status = params.get( 'status', 'done' ) + repository = get_repository( trans, kwd[ 'id' ] ) + relative_install_dir = self.__get_relative_install_dir( trans, repository ) + repo_files_dir = os.path.abspath( os.path.join( relative_install_dir, repository.name ) ) + tool_dicts = [] + workflow_dicts = [] + for root, dirs, files in os.walk( repo_files_dir ): + if not root.find( '.hg' ) >= 0 and not root.find( 'hgrc' ) >= 0: + if '.hg' in dirs: + # Don't visit .hg directories. + dirs.remove( '.hg' ) + if 'hgrc' in files: + # Don't include hgrc files. + files.remove( 'hgrc' ) + for name in files: + # Find all tool configs. + if name.endswith( '.xml' ): + try: + full_path = os.path.abspath( os.path.join( root, name ) ) + tool = trans.app.toolbox.load_tool( full_path ) + if tool is not None: + tool_config = os.path.join( root, name ) + # Handle tool.requirements. + tool_requirements = [] + for tr in tool.requirements: + name=tr.name + type=tr.type + if type == 'fabfile': + version = None + fabfile = tr.fabfile + method = tr.method + else: + version = tr.version + fabfile = None + method = None + requirement_dict = dict( name=name, + type=type, + version=version, + fabfile=fabfile, + method=method ) + tool_requirements.append( requirement_dict ) + tool_dict = dict( id=tool.id, + old_id=tool.old_id, + name=tool.name, + version=tool.version, + description=tool.description, + requirements=tool_requirements, + tool_config=tool_config ) + tool_dicts.append( tool_dict ) + except Exception, e: + # The file is not a Galaxy tool config. + pass + # Find all exported workflows + elif name.endswith( '.ga' ): + try: + full_path = os.path.abspath( os.path.join( root, name ) ) + # Convert workflow data from json + fp = open( full_path, 'rb' ) + workflow_text = fp.read() + fp.close() + workflow_dict = from_json_string( workflow_text ) + if workflow_dict[ 'a_galaxy_workflow' ] == 'true': + workflow_dicts.append( dict( full_path=full_path, workflow_dict=workflow_dict ) ) + except Exception, e: + # The file is not a Galaxy workflow. + pass + return trans.fill_template( '/admin/tool_shed_repository/browse_repository.mako', + repository=repository, + tool_dicts=tool_dicts, + workflow_dicts=workflow_dicts, + message=message, + status=status ) + @web.expose + @web.require_admin + def browse_tool_shed_repositories( self, trans, **kwd ): if 'operation' in kwd: - operation = kwd.pop('operation').lower() - if operation == "get updates": - return self.check_for_updates( trans, **kwd ) + operation = kwd.pop( 'operation' ).lower() + if operation == "manage_repository": + return self.manage_tool_shed_repository( trans, **kwd ) # Render the list view return self.repository_list_grid( trans, **kwd ) @web.expose @@ -725,7 +800,7 @@ message += 'directory in order to automatically install tools from a Galaxy tool shed (e.g., the file name <b>shed_tool_conf.xml</b> whose ' message += '<b><toolbox></b> tag is <b><toolbox tool_path="../shed_tools"></b>).<p/>See the ' message += '<a href="http://wiki.g2.bx.psu.edu/Tool%20Shed#Automatic_installation_of_Galaxy_tool_..." ' - message += 'target=_blank">Automatic installation of Galaxy tool shed repository tools into a local Galaxy instance</a> section of the ' + message += 'target="_blank">Automatic installation of Galaxy tool shed repository tools into a local Galaxy instance</a> section of the ' message += '<a href="http://wiki.g2.bx.psu.edu/Tool%20Shed" target="_blank">Galaxy tool shed wiki</a> for all of the details.' return trans.show_error_message( message ) message = kwd.get( 'message', '' ) @@ -766,12 +841,9 @@ os.chdir( current_working_dir ) tmp_stderr.close() if returncode == 0: - # Add a new record to the tool_shed_repository table. - tool_shed_repository = self.__create_tool_shed_repository( trans, - name, - description, - changeset_revision, - repository_clone_url ) + # Add a new record to the tool_shed_repository table if one doesn't + # already exist. If one exists but is marked deleted, undelete it. + self.__create_or_undelete_tool_shed_repository( trans, name, description, changeset_revision, repository_clone_url ) # Update the cloned repository to changeset_revision. repo_files_dir = os.path.join( clone_dir, name ) log.debug( 'Updating cloned repository to revision "%s"...' % changeset_revision ) @@ -853,10 +925,35 @@ status=status ) @web.expose @web.require_admin + def manage_tool_shed_repository( self, trans, **kwd ): + params = util.Params( kwd ) + message = util.restore_text( params.get( 'message', '' ) ) + status = params.get( 'status', 'done' ) + repository_id = params.get( 'id', None ) + repository = get_repository( trans, repository_id ) + description = util.restore_text( params.get( 'description', repository.description ) ) + if params.get( 'edit_repository_button', False ): + if description != repository.description: + repository.description = description + trans.sa_session.add( repository ) + trans.sa_session.flush() + message = "The repository information has been updated." + relative_install_dir = self.__get_relative_install_dir( trans, repository ) + if relative_install_dir: + repo_files_dir = os.path.abspath( os.path.join( relative_install_dir, repository.name ) ) + else: + repo_files_dir = 'unknown' + return trans.fill_template( '/admin/tool_shed_repository/manage_repository.mako', + repository=repository, + description=description, + repo_files_dir=repo_files_dir, + message=message, + status=status ) + @web.expose + @web.require_admin def check_for_updates( self, trans, **kwd ): params = util.Params( kwd ) - repository_id = params.get( 'id', None ) - repository = get_repository( trans, repository_id ) + repository = get_repository( trans, kwd[ 'id' ] ) galaxy_url = trans.request.host # Send a request to the relevant tool shed to see if there are any updates. # TODO: support https in the following url. @@ -875,26 +972,16 @@ owner = params.get( 'owner', None ) changeset_revision = params.get( 'changeset_revision', None ) latest_changeset_revision = params.get( 'latest_changeset_revision', None ) + repository = get_repository_by_shed_name_owner_changeset_revision( trans, tool_shed_url, name, owner, changeset_revision ) if changeset_revision and latest_changeset_revision: if changeset_revision == latest_changeset_revision: message = "The cloned tool shed repository named '%s' is current (there are no updates available)." % name else: - repository = get_repository_by_name_owner_changeset_revision( trans, name, owner, changeset_revision ) current_working_dir = os.getcwd() - # Get the directory where the repository is cloned. - cleaned_tool_shed_url = self.__clean_tool_shed_url( tool_shed_url ) - partial_cloned_dir = '%s/repos/%s/%s/%s' % ( cleaned_tool_shed_url, owner, name, changeset_revision ) - # Get the relative tool installation paths from each of the shed tool configs. - shed_tool_confs = trans.app.toolbox.shed_tool_confs - relative_cloned_dir = None - # The shed_tool_confs dictionary contains shed_conf_filename : tool_path pairs. - for shed_conf_filename, tool_path in shed_tool_confs.items(): - relative_cloned_dir = os.path.join( tool_path, partial_cloned_dir ) - if os.path.isdir( relative_cloned_dir ): - break - if relative_cloned_dir: + relative_install_dir = self.__get_relative_install_dir( trans, repository ) + if relative_install_dir: # Update the cloned repository to changeset_revision. - repo_files_dir = os.path.join( relative_cloned_dir, name ) + repo_files_dir = os.path.join( relative_install_dir, name ) log.debug( "Updating cloned repository named '%s' from revision '%s' to revision '%s'..." % \ ( name, changeset_revision, latest_changeset_revision ) ) cmd = 'hg pull' @@ -938,9 +1025,44 @@ message = "The latest changeset revision could not be retrieved for the repository named '%s'." % name status = 'error' return trans.response.send_redirect( web.url_for( controller='admin', - action='browse_repositories', + action='manage_tool_shed_repository', + id=trans.security.encode_id( repository.id ), message=message, status=status ) ) + @web.expose + @web.require_admin + def impersonate( self, trans, email=None, **kwd ): + if not trans.app.config.allow_user_impersonation: + return trans.show_error_message( "User impersonation is not enabled in this instance of Galaxy." ) + message = '' + status = 'done' + emails = None + if email is not None: + user = trans.sa_session.query( trans.app.model.User ).filter_by( email=email ).first() + if user: + trans.set_user( user ) + message = 'You are now logged in as %s, <a target="_top" href="%s">return to the home page</a>' % ( email, url_for( controller='root' ) ) + emails = [] + else: + message = 'Invalid user selected' + status = 'error' + if emails is None: + emails = [ u.email for u in trans.sa_session.query( trans.app.model.User ).enable_eagerloads( False ).all() ] + return trans.fill_template( 'admin/impersonate.mako', emails=emails, message=message, status=status ) + + def __get_relative_install_dir( self, trans, repository ): + # Get the directory where the repository is install. + tool_shed = self.__clean_tool_shed_url( repository.tool_shed ) + partial_install_dir = '%s/repos/%s/%s/%s' % ( tool_shed, repository.owner, repository.name, repository.changeset_revision ) + # Get the relative tool installation paths from each of the shed tool configs. + shed_tool_confs = trans.app.toolbox.shed_tool_confs + relative_install_dir = None + # The shed_tool_confs dictionary contains { shed_conf_filename : tool_path } pairs. + for shed_conf_filename, tool_path in shed_tool_confs.items(): + relative_install_dir = os.path.join( tool_path, partial_install_dir ) + if os.path.isdir( relative_install_dir ): + break + return relative_install_dir def __handle_missing_data_table_entry( self, trans, tool_path, sample_files, repository_tools_tups ): # Inspect each tool to see if any have input parameters that are dynamically # generated select lists that require entries in the tool_data_table_conf.xml file. @@ -1055,17 +1177,26 @@ # We have an invalid .xml file, so not a tool config. log.debug( "Ignoring invalid tool config (%s). Error: %s" % ( str( relative_path ), str( e ) ) ) return sample_files, repository_tools_tups - def __create_tool_shed_repository( self, trans, name, description, changeset_revision, repository_clone_url ): + def __create_or_undelete_tool_shed_repository( self, trans, name, description, changeset_revision, repository_clone_url ): tmp_url = self.__clean_repository_clone_url( repository_clone_url ) tool_shed = tmp_url.split( 'repos' )[ 0 ].rstrip( '/' ) owner = self.__get_repository_owner( tmp_url ) - tool_shed_repository = trans.model.ToolShedRepository( tool_shed=tool_shed, - name=name, - description=description, - owner=owner, - changeset_revision=changeset_revision ) - trans.sa_session.add( tool_shed_repository ) - trans.sa_session.flush() + flush_needed = False + tool_shed_repository = get_repository_by_shed_name_owner_changeset_revision( trans, tool_shed, name, owner, changeset_revision ) + if tool_shed_repository: + if tool_shed_repository.deleted: + tool_shed_repository.deleted = False + flush_needed = True + else: + tool_shed_repository = trans.model.ToolShedRepository( tool_shed=tool_shed, + name=name, + description=description, + owner=owner, + changeset_revision=changeset_revision ) + flush_needed = True + if flush_needed: + trans.sa_session.add( tool_shed_repository ) + trans.sa_session.flush() def __add_shed_tool_conf_entry( self, trans, shed_tool_conf, new_tool_section ): # Add an entry in the shed_tool_conf file. An entry looks something like: # <section name="Filter and Sort" id="filter"> @@ -1194,3 +1325,11 @@ trans.model.ToolShedRepository.table.c.owner == owner, trans.model.ToolShedRepository.table.c.changeset_revision == changeset_revision ) ) \ .first() +def get_repository_by_shed_name_owner_changeset_revision( trans, tool_shed, name, owner, changeset_revision ): + return trans.sa_session.query( trans.model.ToolShedRepository ) \ + .filter( and_( trans.model.ToolShedRepository.table.c.tool_shed == tool_shed, + trans.model.ToolShedRepository.table.c.name == name, + trans.model.ToolShedRepository.table.c.owner == owner, + trans.model.ToolShedRepository.table.c.changeset_revision == changeset_revision ) ) \ + .first() + diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 lib/galaxy/web/controllers/tracks.py --- a/lib/galaxy/web/controllers/tracks.py +++ b/lib/galaxy/web/controllers/tracks.py @@ -465,10 +465,14 @@ data = GFFDataProvider( original_dataset=dataset ).get_data( chrom, low, high, **kwargs ) data[ 'dataset_type' ] = 'interval_index' data[ 'extra_info' ] = None - if isinstance( dataset.datatype, Bed ): + elif isinstance( dataset.datatype, Bed ): data = RawBedDataProvider( original_dataset=dataset ).get_data( chrom, low, high, **kwargs ) data[ 'dataset_type' ] = 'interval_index' data[ 'extra_info' ] = None + elif isinstance( dataset.datatype, Vcf ): + data = RawVcfDataProvider( original_dataset=dataset ).get_data( chrom, low, high, **kwargs ) + data[ 'dataset_type' ] = 'tabix' + data[ 'extra_info' ] = None return data @web.json @@ -586,7 +590,7 @@ data_provider = data_provider_class( converted_dataset=converted_dataset, original_dataset=dataset, dependencies=deps ) # Get and return data from data_provider. - result = data_provider.get_data( chrom, low, high, int(start_val), int(max_vals), **kwargs ) + result = data_provider.get_data( chrom, low, high, int( start_val ), int( max_vals ), **kwargs ) result.update( { 'dataset_type': tracks_dataset_type, 'extra_info': extra_info } ) return result @@ -840,6 +844,43 @@ # Set input datasets for tool. If running on region, extract and use subset # when possible. # + + def set_param_value( param_dict, param_name, param_value ): + """ + Set new parameter value in a parameter dictionary. + """ + + # Recursive function to set param value. + def set_value( param_dict, group_name, group_index, param_name, param_value ): + if group_name in param_dict: + param_dict[ group_name ][ group_index ][ param_name ] = param_value + return True + elif param_name in param_dict: + param_dict[ param_name ] = param_value + return True + else: + # Recursive search. + return_val = False + for name, value in param_dict.items(): + if isinstance( value, dict ): + return_val = set_value( value, group_name, group_index, param_name, param_value) + if return_val: + return return_val + return False + + # Parse parameter name if necessary. + if param_name.find( "|" ) == -1: + # Non-grouping parameter. + group_name = group_index = None + else: + # Grouping parameter. + group, param_name = param_name.split( "|" ) + index = group.rfind( "_" ) + group_name = group[ :index ] + group_index = int( group[ index + 1: ] ) + + return set_value( param_dict, group_name, group_index, param_name, param_value ) + for jida in original_job.input_datasets: input_dataset = jida.dataset if input_dataset is None: #optional dataset and dataset wasn't selected @@ -875,10 +916,20 @@ new_dataset.set_size() new_dataset.info = "Data subset for trackster" new_dataset.set_dataset_state( trans.app.model.Dataset.states.OK ) + + # Set metadata. + if trans.app.config.set_metadata_externally: + trans.app.datatypes_registry.set_external_metadata_tool.tool_action.execute( trans.app.datatypes_registry.set_external_metadata_tool, trans, incoming = { 'input1':new_dataset } ) + else: + message = 'Attributes updated' + new_dataset.set_meta() + new_dataset.datatype.after_setting_metadata( new_dataset ) + trans.sa_session.flush() - + # Add dataset to tool's parameters. - tool_params[ jida.name ] = new_dataset + if not set_param_value( tool_params, jida.name, new_dataset ): + return to_json_string( { "error" : True, "message" : "error setting parameter %s" % jida.name } ) # # Execute tool and handle outputs. diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 lib/galaxy/web/controllers/workflow.py --- a/lib/galaxy/web/controllers/workflow.py +++ b/lib/galaxy/web/controllers/workflow.py @@ -1095,8 +1095,8 @@ @web.expose def import_workflow( self, trans, **kwd ): """ - Import a workflow by reading an url, uploading a file, or receiving the textual - representation of a workflow. + Import a workflow by reading an url, uploading a file, opening and reading the contents + of a local file, or receiving the textual representation of a workflow via http. """ url = kwd.get( 'url', '' ) workflow_text = kwd.get( 'workflow_text', '' ) @@ -1104,6 +1104,8 @@ message = kwd.get( 'message', '' ) status = kwd.get( 'status', 'done' ) import_button = kwd.get( 'import_button', False ) + # The following parameters will have values only if the workflow + # id being imported from a Galaxy tool shed repository. tool_shed_url = kwd.get( 'tool_shed_url', '' ) repository_metadata_id = kwd.get( 'repository_metadata_id', '' ) # The workflow_name parameter is in the request only if the import originated @@ -1111,6 +1113,15 @@ workflow_name = kwd.get( 'workflow_name', '' ) if workflow_name: workflow_name = tool_shed_decode( workflow_name ) + # The following parameters will have a value only if the import originated + # from a tool shed repository installed locally. + local_file = kwd.get( 'local_file', '' ) + repository_id = kwd.get( 'repository_id', '' ) + if local_file and not import_button: + workflow_file = open( local_file, 'rb' ) + workflow_text = workflow_file.read() + workflow_file.close() + import_button = True if tool_shed_url and not import_button: # Use urllib (send another request to the tool shed) to retrieve the workflow. workflow_url = 'http://%s/workflow/import_workflow?repository_metadata_id=%s&workflow_name=%s&webapp=%s&open_for_url=true' % \ @@ -1118,7 +1129,6 @@ response = urllib2.urlopen( workflow_url ) workflow_text = response.read() response.close() - workflow_text = workflow_text import_button = True if import_button: workflow_data = None @@ -1131,6 +1141,7 @@ message = "Failed to open URL: <b>%s</b><br>Exception: %s" % ( url, str( e ) ) status = 'error' elif workflow_text: + # This case occurs when the workflow_text was sent via http from the tool shed. workflow_data = workflow_text else: # Load workflow from browsed file. @@ -1170,7 +1181,7 @@ message += "Imported, but this workflow contains cycles. " status = "error" else: - message += "Workflow '%s' imported successfully. " % workflow.name + message += "Workflow <b>%s</b> imported successfully. " % workflow.name if missing_tool_tups: if trans.user_is_admin(): # A required tool is not available in the local Galaxy instance. @@ -1182,30 +1193,49 @@ # the Galaxy panels displayed whenever in Galaxy. message += "The workflow requires the following tools that are not available in this Galaxy instance." message += "You can likely install the required tools from one of the Galaxy tool sheds listed below.<br/><br/>" - for tool_shed_name, tool_shed_url in trans.app.tool_shed_registry.tool_sheds.items(): - if tool_shed_url.endswith( '/' ): - tool_shed_url = tool_shed_url.rstrip( '/' ) - url = '%s/repository/find_tools?galaxy_url=%s&webapp=galaxy' % ( tool_shed_url, trans.request.host ) + for shed_name, shed_url in trans.app.tool_shed_registry.tool_sheds.items(): + if shed_url.endswith( '/' ): + shed_url = shed_url.rstrip( '/' ) + url = '%s/repository/find_tools?galaxy_url=%s&webapp=%s' % ( shed_url, trans.request.host, webapp ) for missing_tool_tup in missing_tool_tups: missing_tool_id = missing_tool_tup[0] url += '&tool_id=%s' % missing_tool_id - message += '<a href="%s">%s</a><br/>' % ( url, tool_shed_name ) + message += '<a href="%s">%s</a><br/>' % ( url, shed_name ) status = 'error' - return trans.response.send_redirect( web.url_for( controller='admin', - action='index', - webapp='galaxy', - message=message, - status=status ) ) + if local_file or tool_shed_url: + # Another Galaxy panels Hack: The request did not originate from the Galaxy + # workflow view, so we don't need to render the Galaxy panels. + return trans.response.send_redirect( web.url_for( controller='admin', + action='center', + webapp='galaxy', + message=message, + status=status ) ) + else: + # Another Galaxy panels hack: The request originated from the Galaxy + # workflow view, so we need to render the Galaxy panels. + return trans.response.send_redirect( web.url_for( controller='admin', + action='index', + webapp='galaxy', + message=message, + status=status ) ) else: # TODO: Figure out what to do here... pass if tool_shed_url: # We've received the textual representation of a workflow from a Galaxy tool shed. - message = "This workflow has been successfully imported into your local Galaxy instance." + message = "Workflow <b>%s</b> imported successfully." % workflow.name # TODO: support https in the following url. url = 'http://%s/workflow/view_workflow?repository_metadata_id=%s&workflow_name=%s&webapp=%s&message=%s' % \ ( tool_shed_url, repository_metadata_id, tool_shed_encode( workflow_name ), webapp, message ) return trans.response.send_redirect( url ) + elif local_file: + # The workflow was read from a file included with an installed tool shed repository. + message = "Workflow <b>%s</b> imported successfully." % workflow.name + return trans.response.send_redirect( web.url_for( controller='admin', + action='browse_tool_shed_repository', + id=repository_id, + message=message, + status=status ) ) return self.list( trans ) return trans.fill_template( "workflow/import.mako", url=url, @@ -1277,7 +1307,16 @@ for job_id in job_ids: assert job_id in jobs_by_id, "Attempt to create workflow with job not connected to current history" job = jobs_by_id[ job_id ] - tool = trans.app.toolbox.tools_by_id[ job.tool_id ] + try: + tool = trans.app.toolbox.tools_by_id[ job.tool_id ] + except KeyError, e: + # Handle the case where the workflow requires a tool not available in the local Galaxy instance. + # The id value of tools installed from a Galaxy tool shed is a guid, but these tool's old_id + # attribute should contain what we're looking for. + for available_tool_id, available_tool in trans.app.toolbox.tools_by_id.items(): + if job.tool_id == available_tool.old_id: + tool = available_tool + break param_values = job.get_param_values( trans.app ) associations = cleanup_param_values( tool.inputs, param_values ) # Doing it this way breaks dynamic parameters, backed out temporarily. @@ -1444,7 +1483,16 @@ # Execute module job = None if step.type == 'tool' or step.type is None: - tool = trans.app.toolbox.tools_by_id[ step.tool_id ] + try: + tool = trans.app.toolbox.tools_by_id[ step.tool_id ] + except KeyError, e: + # Handle the case where the workflow requires a tool not available in the local Galaxy instance. + # The id value of tools installed from a Galaxy tool shed is a guid, but these tool's old_id + # attribute should contain what we're looking for. + for available_tool_id, available_tool in trans.app.toolbox.tools_by_id.items(): + if step.tool_id == available_tool.old_id: + tool = available_tool + break input_values = step.state.inputs # Connect up def callback( input, value, prefixed_name, prefixed_label ): @@ -1480,10 +1528,10 @@ trans.sa_session.add( workflow_invocation ) invocations.append({'outputs': outputs, 'new_history': new_history}) - trans.sa_session.flush() - return trans.fill_template( "workflow/run_complete.mako", - workflow=stored, - invocations=invocations ) + trans.sa_session.flush() + return trans.fill_template( "workflow/run_complete.mako", + workflow=stored, + invocations=invocations ) else: # Prepare each step missing_tools = [] diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 lib/galaxy/webapps/community/controllers/common.py --- a/lib/galaxy/webapps/community/controllers/common.py +++ b/lib/galaxy/webapps/community/controllers/common.py @@ -361,8 +361,9 @@ workflow_text = fp.read() fp.close() exported_workflow_dict = from_json_string( workflow_text ) - # Update the list of metadata dictionaries for workflows in metadata_dict. - metadata_dict = generate_workflow_metadata( trans, id, changeset_revision, exported_workflow_dict, metadata_dict ) + if exported_workflow_dict[ 'a_galaxy_workflow' ] == 'true': + # Update the list of metadata dictionaries for workflows in metadata_dict. + metadata_dict = generate_workflow_metadata( trans, id, changeset_revision, exported_workflow_dict, metadata_dict ) except Exception, e: invalid_files.append( ( name, str( e ) ) ) else: diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 lib/galaxy/webapps/community/controllers/workflow.py --- a/lib/galaxy/webapps/community/controllers/workflow.py +++ b/lib/galaxy/webapps/community/controllers/workflow.py @@ -339,12 +339,6 @@ workflow.has_errors = True # Stick this in the step temporarily. step.temp_input_connections = step_dict[ 'input_connections' ] - # Unpack and add post-job actions. - post_job_actions = step_dict.get( 'post_job_actions', {} ) - for name, pja_dict in post_job_actions.items(): - pja = PostJobAction( pja_dict[ 'action_type' ], - step, pja_dict[ 'output_name' ], - pja_dict[ 'action_arguments' ] ) steps.append( step ) steps_by_external_id[ step_dict[ 'id' ] ] = step # Second pass to deal with connections between steps. diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 static/scripts/jquery.scrollTo.js --- a/static/scripts/jquery.scrollTo.js +++ /dev/null @@ -1,215 +0,0 @@ -/** - * jQuery.ScrollTo - * Copyright (c) 2007-2009 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com - * Dual licensed under MIT and GPL. - * Date: 5/25/2009 - * - * @projectDescription Easy element scrolling using jQuery. - * http://flesler.blogspot.com/2007/10/jqueryscrollto.html - * Works with jQuery +1.2.6. Tested on FF 2/3, IE 6/7/8, Opera 9.5/6, Safari 3, Chrome 1 on WinXP. - * - * @author Ariel Flesler - * @version 1.4.2 - * - * @id jQuery.scrollTo - * @id jQuery.fn.scrollTo - * @param {String, Number, DOMElement, jQuery, Object} target Where to scroll the matched elements. - * The different options for target are: - * - A number position (will be applied to all axes). - * - A string position ('44', '100px', '+=90', etc ) will be applied to all axes - * - A jQuery/DOM element ( logically, child of the element to scroll ) - * - A string selector, that will be relative to the element to scroll ( 'li:eq(2)', etc ) - * - A hash { top:x, left:y }, x and y can be any kind of number/string like above. -* - A percentage of the container's dimension/s, for example: 50% to go to the middle. - * - The string 'max' for go-to-end. - * @param {Number} duration The OVERALL length of the animation, this argument can be the settings object instead. - * @param {Object,Function} settings Optional set of settings or the onAfter callback. - * @option {String} axis Which axis must be scrolled, use 'x', 'y', 'xy' or 'yx'. - * @option {Number} duration The OVERALL length of the animation. - * @option {String} easing The easing method for the animation. - * @option {Boolean} margin If true, the margin of the target element will be deducted from the final position. - * @option {Object, Number} offset Add/deduct from the end position. One number for both axes or { top:x, left:y }. - * @option {Object, Number} over Add/deduct the height/width multiplied by 'over', can be { top:x, left:y } when using both axes. - * @option {Boolean} queue If true, and both axis are given, the 2nd axis will only be animated after the first one ends. - * @option {Function} onAfter Function to be called after the scrolling ends. - * @option {Function} onAfterFirst If queuing is activated, this function will be called after the first scrolling ends. - * @return {jQuery} Returns the same jQuery object, for chaining. - * - * @desc Scroll to a fixed position - * @example $('div').scrollTo( 340 ); - * - * @desc Scroll relatively to the actual position - * @example $('div').scrollTo( '+=340px', { axis:'y' } ); - * - * @dec Scroll using a selector (relative to the scrolled element) - * @example $('div').scrollTo( 'p.paragraph:eq(2)', 500, { easing:'swing', queue:true, axis:'xy' } ); - * - * @ Scroll to a DOM element (same for jQuery object) - * @example var second_child = document.getElementById('container').firstChild.nextSibling; - * $('#container').scrollTo( second_child, { duration:500, axis:'x', onAfter:function(){ - * alert('scrolled!!'); - * }}); - * - * @desc Scroll on both axes, to different values - * @example $('div').scrollTo( { top: 300, left:'+=200' }, { axis:'xy', offset:-20 } ); - */ -;(function( $ ){ - - var $scrollTo = $.scrollTo = function( target, duration, settings ){ - $(window).scrollTo( target, duration, settings ); - }; - - $scrollTo.defaults = { - axis:'xy', - duration: parseFloat($.fn.jquery) >= 1.3 ? 0 : 1 - }; - - // Returns the element that needs to be animated to scroll the window. - // Kept for backwards compatibility (specially for localScroll & serialScroll) - $scrollTo.window = function( scope ){ - return $(window)._scrollable(); - }; - - // Hack, hack, hack :) - // Returns the real elements to scroll (supports window/iframes, documents and regular nodes) - $.fn._scrollable = function(){ - return this.map(function(){ - var elem = this, - isWin = !elem.nodeName || $.inArray( elem.nodeName.toLowerCase(), ['iframe','#document','html','body'] ) != -1; - - if( !isWin ) - return elem; - - var doc = (elem.contentWindow || elem).document || elem.ownerDocument || elem; - - return $.browser.safari || doc.compatMode == 'BackCompat' ? - doc.body : - doc.documentElement; - }); - }; - - $.fn.scrollTo = function( target, duration, settings ){ - if( typeof duration == 'object' ){ - settings = duration; - duration = 0; - } - if( typeof settings == 'function' ) - settings = { onAfter:settings }; - - if( target == 'max' ) - target = 9e9; - - settings = $.extend( {}, $scrollTo.defaults, settings ); - // Speed is still recognized for backwards compatibility - duration = duration || settings.speed || settings.duration; - // Make sure the settings are given right - settings.queue = settings.queue && settings.axis.length > 1; - - if( settings.queue ) - // Let's keep the overall duration - duration /= 2; - settings.offset = both( settings.offset ); - settings.over = both( settings.over ); - - return this._scrollable().each(function(){ - var elem = this, - $elem = $(elem), - targ = target, toff, attr = {}, - win = $elem.is('html,body'); - - switch( typeof targ ){ - // A number will pass the regex - case 'number': - case 'string': - if( /^([+-]=)?\d+(\.\d+)?(px|%)?$/.test(targ) ){ - targ = both( targ ); - // We are done - break; - } - // Relative selector, no break! - targ = $(targ,this); - case 'object': - // DOMElement / jQuery - if( targ.is || targ.style ) - // Get the real position of the target - toff = (targ = $(targ)).offset(); - } - $.each( settings.axis.split(''), function( i, axis ){ - var Pos = axis == 'x' ? 'Left' : 'Top', - pos = Pos.toLowerCase(), - key = 'scroll' + Pos, - old = elem[key], - max = $scrollTo.max(elem, axis); - - if( toff ){// jQuery / DOMElement - attr[key] = toff[pos] + ( win ? 0 : old - $elem.offset()[pos] ); - - // If it's a dom element, reduce the margin - if( settings.margin ){ - attr[key] -= parseInt(targ.css('margin'+Pos)) || 0; - attr[key] -= parseInt(targ.css('border'+Pos+'Width')) || 0; - } - - attr[key] += settings.offset[pos] || 0; - - if( settings.over[pos] ) - // Scroll to a fraction of its width/height - attr[key] += targ[axis=='x'?'width':'height']() * settings.over[pos]; - }else{ - var val = targ[pos]; - // Handle percentage values - attr[key] = val.slice && val.slice(-1) == '%' ? - parseFloat(val) / 100 * max - : val; - } - - // Number or 'number' - if( /^\d+$/.test(attr[key]) ) - // Check the limits - attr[key] = attr[key] <= 0 ? 0 : Math.min( attr[key], max ); - - // Queueing axes - if( !i && settings.queue ){ - // Don't waste time animating, if there's no need. - if( old != attr[key] ) - // Intermediate animation - animate( settings.onAfterFirst ); - // Don't animate this axis again in the next iteration. - delete attr[key]; - } - }); - - animate( settings.onAfter ); - - function animate( callback ){ - $elem.animate( attr, duration, settings.easing, callback && function(){ - callback.call(this, target, settings); - }); - }; - - }).end(); - }; - - // Max scrolling position, works on quirks mode - // It only fails (not too badly) on IE, quirks mode. - $scrollTo.max = function( elem, axis ){ - var Dim = axis == 'x' ? 'Width' : 'Height', - scroll = 'scroll'+Dim; - - if( !$(elem).is('html,body') ) - return elem[scroll] - $(elem)[Dim.toLowerCase()](); - - var size = 'client' + Dim, - html = elem.ownerDocument.documentElement, - body = elem.ownerDocument.body; - - return Math.max( html[scroll], body[scroll] ) - - Math.min( html[size] , body[size] ); - - }; - - function both( val ){ - return typeof val == 'object' ? val : { top:val, left:val }; - }; - -})( jQuery ); \ No newline at end of file diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 static/scripts/packed/jquery.scrollTo.js --- a/static/scripts/packed/jquery.scrollTo.js +++ /dev/null @@ -1,1 +0,0 @@ -(function(c){var a=c.scrollTo=function(f,e,d){c(window).scrollTo(f,e,d)};a.defaults={axis:"xy",duration:parseFloat(c.fn.jquery)>=1.3?0:1};a.window=function(d){return c(window)._scrollable()};c.fn._scrollable=function(){return this.map(function(){var e=this,d=!e.nodeName||c.inArray(e.nodeName.toLowerCase(),["iframe","#document","html","body"])!=-1;if(!d){return e}var f=(e.contentWindow||e).document||e.ownerDocument||e;return c.browser.safari||f.compatMode=="BackCompat"?f.body:f.documentElement})};c.fn.scrollTo=function(f,e,d){if(typeof e=="object"){d=e;e=0}if(typeof d=="function"){d={onAfter:d}}if(f=="max"){f=9000000000}d=c.extend({},a.defaults,d);e=e||d.speed||d.duration;d.queue=d.queue&&d.axis.length>1;if(d.queue){e/=2}d.offset=b(d.offset);d.over=b(d.over);return this._scrollable().each(function(){var l=this,j=c(l),k=f,i,g={},m=j.is("html,body");switch(typeof k){case"number":case"string":if(/^([+-]=)?\d+(\.\d+)?(px|%)?$/.test(k)){k=b(k);break}k=c(k,this);case"object":if(k.is||k.style){i=(k=c(k)).offset()}}c.each(d.axis.split(""),function(q,r){var s=r=="x"?"Left":"Top",u=s.toLowerCase(),p="scroll"+s,o=l[p],n=a.max(l,r);if(i){g[p]=i[u]+(m?0:o-j.offset()[u]);if(d.margin){g[p]-=parseInt(k.css("margin"+s))||0;g[p]-=parseInt(k.css("border"+s+"Width"))||0}g[p]+=d.offset[u]||0;if(d.over[u]){g[p]+=k[r=="x"?"width":"height"]()*d.over[u]}}else{var t=k[u];g[p]=t.slice&&t.slice(-1)=="%"?parseFloat(t)/100*n:t}if(/^\d+$/.test(g[p])){g[p]=g[p]<=0?0:Math.min(g[p],n)}if(!q&&d.queue){if(o!=g[p]){h(d.onAfterFirst)}delete g[p]}});h(d.onAfter);function h(n){j.animate(g,e,d.easing,n&&function(){n.call(this,f,d)})}}).end()};a.max=function(j,i){var h=i=="x"?"Width":"Height",e="scroll"+h;if(!c(j).is("html,body")){return j[e]-c(j)[h.toLowerCase()]()}var g="client"+h,f=j.ownerDocument.documentElement,d=j.ownerDocument.body;return Math.max(f[e],d[e])-Math.min(f[g],d[g])};function b(d){return typeof d=="object"?d:{top:d,left:d}}})(jQuery); \ No newline at end of file diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 static/scripts/packed/trackster.js --- a/static/scripts/packed/trackster.js +++ b/static/scripts/packed/trackster.js @@ -1,1 +1,1 @@ -var class_module=function(b,a){var c=function(){var f=arguments[0];for(var e=1;e<arguments.length;e++){var d=arguments[e];for(key in d){f[key]=d[key]}}return f};a.extend=c};var requestAnimationFrame=(function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(b,a){window.setTimeout(b,1000/60)}})();var BEFORE=1001,CONTAINS=1002,OVERLAP_START=1003,OVERLAP_END=1004,CONTAINED_BY=1005,AFTER=1006;var compute_overlap=function(e,b){var g=e[0],f=e[1],d=b[0],c=b[1],a;if(g<d){if(f<d){a=BEFORE}else{if(f<=c){a=OVERLAP_START}else{a=CONTAINS}}}else{if(g>c){a=AFTER}else{if(f<=c){a=CONTAINED_BY}else{a=OVERLAP_END}}}return a};var is_overlap=function(c,b){var a=compute_overlap(c,b);return(a!==BEFORE&&a!==AFTER)};var get_random_color=function(a){if(!a){a="#ffffff"}if(typeof(a)==="string"){a=[a]}for(var j=0;j<a.length;j++){a[j]=parseInt(a[j].slice(1),16)}var m=function(u,t,s){return((u*299)+(t*587)+(s*114))/1000};var e=function(v,u,w,s,r,t){return(Math.max(v,s)-Math.min(v,s))+(Math.max(u,r)-Math.min(u,r))+(Math.max(w,t)-Math.min(w,t))};var g,n,f,k,p,h,q,c,d,b,o,l=false;do{g=Math.random()*16777215;n=g|16711680;f=g|65280;k=g|255;d=m(n,f,k);l=true;for(var j=0;j<a.length;j++){p=a[j];h=p|16711680;q=p|65280;c=p|255;b=m(h,q,c);o=e(n,f,k,h,q,c);if((Math.abs(d-b)<125)||(o<500)){l=false;break}}}while(!l);return"#"+(16777216+g).toString(16).substr(1,6)};var trackster_module=function(f,Z){var q=f("class").extend,t=f("slotting"),N=f("painters");var ag=function(ah,ai){this.document=ah;this.default_font=ai!==undefined?ai:"9px Monaco, Lucida Console, monospace";this.dummy_canvas=this.new_canvas();this.dummy_context=this.dummy_canvas.getContext("2d");this.dummy_context.font=this.default_font;this.char_width_px=this.dummy_context.measureText("A").width;this.patterns={};this.load_pattern("right_strand","/visualization/strand_right.png");this.load_pattern("left_strand","/visualization/strand_left.png");this.load_pattern("right_strand_inv","/visualization/strand_right_inv.png");this.load_pattern("left_strand_inv","/visualization/strand_left_inv.png")};q(ag.prototype,{load_pattern:function(ah,al){var ai=this.patterns,aj=this.dummy_context,ak=new Image();ak.src=image_path+al;ak.onload=function(){ai[ah]=aj.createPattern(ak,"repeat")}},get_pattern:function(ah){return this.patterns[ah]},new_canvas:function(){var ah=this.document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(ah)}ah.manager=this;return ah}});var o={};var m=function(ah,ai){o[ah.attr("id")]=ai};var n=function(ah,aj,al,ak){al=".group";var ai={};o[ah.attr("id")]=ak;ah.bind("drag",{handle:"."+aj,relative:true},function(au,av){var at=$(this);var ay=$(this).parent(),ap=ay.children(),ar=o[$(this).attr("id")],ao,an,aw,am,aq;an=$(this).parents(al);if(an.length!==0){aw=an.position().top;am=aw+an.outerHeight();if(av.offsetY<aw){$(this).insertBefore(an);var ax=o[an.attr("id")];ax.remove_drawable(ar);ax.container.add_drawable_before(ar,ax);return}else{if(av.offsetY>am){$(this).insertAfter(an);var ax=o[an.attr("id")];ax.remove_drawable(ar);ax.container.add_drawable(ar);return}}}an=null;for(aq=0;aq<ap.length;aq++){ao=$(ap.get(aq));aw=ao.position().top;am=aw+ao.outerHeight();if(ao.is(al)&&this!==ao.get(0)&&av.offsetY>=aw&&av.offsetY<=am){if(av.offsetY-aw<am-av.offsetY){ao.find(".content-div").prepend(this)}else{ao.find(".content-div").append(this)}if(ar.container){ar.container.remove_drawable(ar)}o[ao.attr("id")].add_drawable(ar);return}}for(aq=0;aq<ap.length;aq++){if(av.offsetY<$(ap.get(aq)).position().top){break}}if(aq===ap.length){if(this!==ap.get(aq-1)){ay.append(this);o[ay.attr("id")].move_drawable(ar,aq)}}else{if(this!==ap.get(aq)){$(this).insertBefore(ap.get(aq));o[ay.attr("id")].move_drawable(ar,(av.deltaY>0?aq-1:aq))}}}).bind("dragstart",function(){ai["border-top"]=ah.css("border-top");ai["border-bottom"]=ah.css("border-bottom");$(this).css({"border-top":"1px solid blue","border-bottom":"1px solid blue"})}).bind("dragend",function(){$(this).css(ai)})};Z.moveable=n;var af=16,I=9,F=20,U=I+2,A=100,K=12000,S=200,D=5,w=10,M=5000,x=100,p="There was an error in indexing this dataset. ",L="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",G="No data for this chrom/contig.",u="Currently indexing... please wait",y="Tool cannot be rerun: ",a="Loading data...",aa="Ready for display",d=10,v=5,C=5;function ab(ai,ah){if(!ah){ah=0}var aj=Math.pow(10,ah);return Math.round(ai*aj)/aj}var c=function(ah){this.num_elements=ah;this.clear()};q(c.prototype,{get:function(ai){var ah=this.key_ary.indexOf(ai);if(ah!==-1){if(this.obj_cache[ai].stale){this.key_ary.splice(ah,1);delete this.obj_cache[ai]}else{this.move_key_to_end(ai,ah)}}return this.obj_cache[ai]},set:function(ai,aj){if(!this.obj_cache[ai]){if(this.key_ary.length>=this.num_elements){var ah=this.key_ary.shift();delete this.obj_cache[ah]}this.key_ary.push(ai)}this.obj_cache[ai]=aj;return aj},move_key_to_end:function(ai,ah){this.key_ary.splice(ah,1);this.key_ary.push(ai)},clear:function(){this.obj_cache={};this.key_ary=[]},size:function(){return this.key_ary.length}});var T=function(ai,ah,aj){c.call(this,ai);this.track=ah;this.subset=(aj!==undefined?aj:true)};q(T.prototype,c.prototype,{load_data:function(aq,al,ao,ai,an){var ap=this.track.view.chrom,ak={chrom:ap,low:aq,high:al,mode:ao,resolution:ai,dataset_id:this.track.dataset_id,hda_ldda:this.track.hda_ldda};$.extend(ak,an);if(this.track.filters_manager){var ar=[];var ah=this.track.filters_manager.filters;for(var am=0;am<ah.length;am++){ar[ar.length]=ah[am].name}ak.filter_cols=JSON.stringify(ar)}var aj=this;return $.getJSON(this.track.data_url,ak,function(at){aj.set_data(aq,al,ao,at)})},get_data:function(ah,al,am,ai,ak){var aj=this.get_data_from_cache(ah,al,am);if(aj){return aj}aj=this.load_data(ah,al,am,ai,ak);this.set_data(ah,al,am,aj);return aj},DEEP_DATA_REQ:"deep",BROAD_DATA_REQ:"breadth",get_more_data:function(ap,ak,ao,aj,an,al){var aq=this.get_data_from_cache(ap,ak,ao);if(!aq){console.log("ERROR: no current data for: ",this.track,ap,ak,ao,aj,an);return}aq.stale=true;var ai=ap;if(al===this.DEEP_DATA_REQ){$.extend(an,{start_val:aq.data.length+1})}else{if(al===this.BROAD_DATA_REQ){ai=(aq.max_high?aq.max_high:aq.data[aq.data.length-1][2])+1}}var ah=this,am=this.load_data(ai,ak,ao,aj,an);new_data_available=$.Deferred();this.set_data(ap,ak,ao,new_data_available);$.when(am).then(function(ar){if(ar.data){ar.data=aq.data.concat(ar.data);if(ar.max_low){ar.max_low=aq.max_low}if(ar.message){ar.message=ar.message.replace(/[0-9]+/,ar.data.length)}}ah.set_data(ap,ak,ao,ar);new_data_available.resolve(ar)});return new_data_available},get_data_from_cache:function(ah,ai,aj){return this.get(this.gen_key(ah,ai,aj))},set_data:function(ai,aj,ak,ah){return this.set(this.gen_key(ai,aj,ak),ah)},gen_key:function(ah,aj,ak){var ai=ah+"_"+aj+"_"+ak;return ai},split_key:function(ah){return ah.split("_")}});var J=function(ai,ah,aj){T.call(this,ai,ah,aj)};q(J.prototype,T.prototype,c.prototype,{load_data:function(ah,ak,al,ai,aj){if(ai>1){return{data:null}}return T.prototype.load_data.call(this,ah,ak,al,ai,aj)}});var r=function(ak,ai,ah,aj,al){this.name=ak;this.view=ai;this.container=ah;this.config=new H({track:this,params:[{key:"name",label:"Name",type:"text",default_value:ak}],saved_values:aj,onchange:function(){this.track.set_name(this.track.config.values.name)}});this.prefs=this.config.values;this.drag_handle_class=al;this.is_overview=false};q(r.prototype,{init:function(){},request_draw:function(){},_draw:function(){},to_json:function(){},update_track_icons:function(){},set_name:function(ah){this.old_name=this.name;this.name=ah;this.name_div.text(this.name)},revert_name:function(){this.name=this.old_name;this.name_div.text(this.name)},remove:function(){this.container.remove_drawable(this);this.container_div.fadeOut("slow",function(){$(this).remove();view.update_intro_div();view.has_changes=true})}});var z=function(al,ak,ai,ah,aj,am){r.call(this,ak,ai,ah,aj,am);this.obj_type=al;this.drawables=[]};q(z.prototype,r.prototype,{init:function(){for(var ah=0;ah<this.drawables.length;ah++){this.drawables[ah].init()}},_draw:function(){for(var ah=0;ah<this.drawables.length;ah++){this.drawables[ah]._draw()}},to_json:function(){var ai=[];for(var ah=0;ah<this.drawables.length;ah++){ai.push(this.drawables[ah].to_json())}return{name:this.name,prefs:this.prefs,obj_type:this.obj_type,drawables:ai}},add_drawable:function(ah){this.drawables.push(ah);ah.container=this},add_drawable_before:function(aj,ah){var ai=this.drawables.indexOf(ah);if(ai!=-1){this.drawables.splice(ai,0,aj);return true}return false},remove_drawable:function(ai){var ah=this.drawables.indexOf(ai);if(ah!=-1){this.drawables.splice(ah,1);ai.container=null;return true}return false},move_drawable:function(ai,aj){var ah=this.drawables.indexOf(ai);if(ah!=-1){this.drawables.splice(ah,1);this.drawables.splice(aj,0,ai);return true}return false}});var R=function(ak,ai,ah,aj){z.call(this,"DrawableGroup",ak,ai,ah,aj,"group-handle");if(!R.id_counter){R.id_counter=0}var al=R.id_counter++;this.container_div=$("<div/>").addClass("group").attr("id","group_"+al).appendTo(this.container.content_div);this.header_div=$("<div/>").addClass("track-header").appendTo(this.container_div);this.header_div.append($("<div/>").addClass(this.drag_handle_class));this.name_div=$("<div/>").addClass("group-name menubutton popup").text(this.name).appendTo(this.header_div);this.content_div=$("<div/>").addClass("content-div").attr("id","group_"+al+"_content_div").appendTo(this.container_div);m(this.container_div,this);m(this.content_div,this);n(this.container_div,this.drag_handle_class,".group",this);this.update_track_icons()};q(R.prototype,r.prototype,z.prototype,{update_track_icons:function(){var ai=this;var ah={};ah["Edit configuration"]=function(){var al=function(){hide_modal();$(window).unbind("keypress.check_enter_esc")},aj=function(){ai.config.update_from_form($(".dialog-box"));hide_modal();$(window).unbind("keypress.check_enter_esc")},ak=function(am){if((am.keyCode||am.which)===27){al()}else{if((am.keyCode||am.which)===13){aj()}}};$(window).bind("keypress.check_enter_esc",ak);show_modal("Configure Group",ai.config.build_form(),{Cancel:al,OK:aj})};ah.Remove=function(){ai.remove()};make_popupmenu(ai.name_div,ah)}});var ae=function(ah,ak,aj,ai){z.call(this,"View");this.container=ah;this.chrom=null;this.vis_id=aj;this.dbkey=ai;this.title=ak;this.label_tracks=[];this.tracks_to_be_redrawn=[];this.max_low=0;this.max_high=0;this.zoom_factor=3;this.min_separation=30;this.has_changes=false;this.load_chroms_deferred=null;this.init();this.canvas_manager=new ag(ah.get(0).ownerDocument);this.reset()};q(ae.prototype,z.prototype,{init:function(){var aj=this.container,ah=this;this.top_container=$("<div/>").addClass("top-container").appendTo(aj);this.browser_content_div=$("<div/>").addClass("content").css("position","relative").appendTo(aj);this.bottom_container=$("<div/>").addClass("bottom-container").appendTo(aj);this.top_labeltrack=$("<div/>").addClass("top-labeltrack").appendTo(this.top_container);this.viewport_container=$("<div/>").addClass("viewport-container").attr("id","viewport-container").appendTo(this.browser_content_div);this.content_div=this.viewport_container;m(this.viewport_container,ah);this.intro_div=$("<div/>").addClass("intro");var ak=$("<div/>").text("Add Datasets to Visualization").addClass("action-button").appendTo(this.intro_div).click(function(){add_tracks()});this.nav_labeltrack=$("<div/>").addClass("nav-labeltrack").appendTo(this.bottom_container);this.nav_container=$("<div/>").addClass("nav-container").prependTo(this.top_container);this.nav=$("<div/>").addClass("nav").appendTo(this.nav_container);this.overview=$("<div/>").addClass("overview").appendTo(this.bottom_container);this.overview_viewport=$("<div/>").addClass("overview-viewport").appendTo(this.overview);this.overview_close=$("<a/>").attr("href","javascript:void(0);").attr("title","Close overview").addClass("icon-button overview-close tooltip").hide().appendTo(this.overview_viewport);this.overview_highlight=$("<div/>").addClass("overview-highlight").hide().appendTo(this.overview_viewport);this.overview_box_background=$("<div/>").addClass("overview-boxback").appendTo(this.overview_viewport);this.overview_box=$("<div/>").addClass("overview-box").appendTo(this.overview_viewport);this.default_overview_height=this.overview_box.height();this.nav_controls=$("<div/>").addClass("nav-controls").appendTo(this.nav);this.chrom_select=$("<select/>").attr({name:"chrom"}).css("width","15em").addClass("no-autocomplete").append("<option value=''>Loading</option>").appendTo(this.nav_controls);var ai=function(al){if(al.type==="focusout"||(al.keyCode||al.which)===13||(al.keyCode||al.which)===27){if((al.keyCode||al.which)!==27){ah.go_to($(this).val())}$(this).hide();$(this).val("");ah.location_span.show();ah.chrom_select.show()}};this.nav_input=$("<input/>").addClass("nav-input").hide().bind("keyup focusout",ai).appendTo(this.nav_controls);this.location_span=$("<span/>").addClass("location").appendTo(this.nav_controls);this.location_span.click(function(){ah.location_span.hide();ah.chrom_select.hide();ah.nav_input.val(ah.chrom+":"+ah.low+"-"+ah.high);ah.nav_input.css("display","inline-block");ah.nav_input.select();ah.nav_input.focus()});if(this.vis_id!==undefined){this.hidden_input=$("<input/>").attr("type","hidden").val(this.vis_id).appendTo(this.nav_controls)}this.zo_link=$("<a id='zoom-out' />").click(function(){ah.zoom_out();ah.request_redraw()}).appendTo(this.nav_controls);this.zi_link=$("<a id='zoom-in' />").click(function(){ah.zoom_in();ah.request_redraw()}).appendTo(this.nav_controls);this.load_chroms_deferred=this.load_chroms({low:0});this.chrom_select.bind("change",function(){ah.change_chrom(ah.chrom_select.val())});this.browser_content_div.click(function(al){$(this).find("input").trigger("blur")});this.browser_content_div.bind("dblclick",function(al){ah.zoom_in(al.pageX,this.viewport_container)});this.overview_box.bind("dragstart",function(al,am){this.current_x=am.offsetX}).bind("drag",function(al,an){var ao=an.offsetX-this.current_x;this.current_x=an.offsetX;var am=Math.round(ao/ah.viewport_container.width()*(ah.max_high-ah.max_low));ah.move_delta(-am)});this.overview_close.click(function(){ah.reset_overview()});this.viewport_container.bind("draginit",function(al,am){if(al.clientX>ah.viewport_container.width()-16){return false}}).bind("dragstart",function(al,am){am.original_low=ah.low;am.current_height=al.clientY;am.current_x=am.offsetX}).bind("drag",function(an,ap){var al=$(this);var aq=ap.offsetX-ap.current_x;var am=al.scrollTop()-(an.clientY-ap.current_height);al.scrollTop(am);ap.current_height=an.clientY;ap.current_x=ap.offsetX;var ao=Math.round(aq/ah.viewport_container.width()*(ah.high-ah.low));ah.move_delta(ao)}).bind("mousewheel",function(an,ap,am,al){if(am){var ao=Math.round(-am/ah.viewport_container.width()*(ah.high-ah.low));ah.move_delta(ao)}});this.top_labeltrack.bind("dragstart",function(al,am){return $("<div />").css({height:ah.browser_content_div.height()+ah.top_labeltrack.height()+ah.nav_labeltrack.height()+1,top:"0px",position:"absolute","background-color":"#ccf",opacity:0.5,"z-index":1000}).appendTo($(this))}).bind("drag",function(ap,aq){$(aq.proxy).css({left:Math.min(ap.pageX,aq.startX),width:Math.abs(ap.pageX-aq.startX)});var am=Math.min(ap.pageX,aq.startX)-ah.container.offset().left,al=Math.max(ap.pageX,aq.startX)-ah.container.offset().left,ao=(ah.high-ah.low),an=ah.viewport_container.width();ah.update_location(Math.round(am/an*ao)+ah.low,Math.round(al/an*ao)+ah.low)}).bind("dragend",function(aq,ar){var am=Math.min(aq.pageX,ar.startX),al=Math.max(aq.pageX,ar.startX),ao=(ah.high-ah.low),an=ah.viewport_container.width(),ap=ah.low;ah.low=Math.round(am/an*ao)+ap;ah.high=Math.round(al/an*ao)+ap;$(ar.proxy).remove();ah.request_redraw()});this.add_label_track(new ad(this,{content_div:this.top_labeltrack}));this.add_label_track(new ad(this,{content_div:this.nav_labeltrack}));$(window).bind("resize",function(){ah.resize_window()});$(document).bind("redraw",function(){ah.redraw()});this.reset();$(window).trigger("resize");this.update_intro_div()},update_intro_div:function(){if(this.num_tracks===0){this.intro_div.appendTo(this.viewport_container)}else{this.intro_div.remove()}},update_location:function(ah,ai){this.location_span.text(commatize(ah)+" - "+commatize(ai));this.nav_input.val(this.chrom+":"+commatize(ah)+"-"+commatize(ai))},load_chroms:function(aj){aj.num=x;$.extend(aj,(this.vis_id!==undefined?{vis_id:this.vis_id}:{dbkey:this.dbkey}));var ah=this,ai=$.Deferred();$.ajax({url:chrom_url,data:aj,dataType:"json",success:function(al){if(al.chrom_info.length===0){alert("Invalid chromosome: "+aj.chrom);return}if(al.reference){ah.add_label_track(new B(ah))}ah.chrom_data=al.chrom_info;var ao='<option value="">Select Chrom/Contig</option>';for(var an=0,ak=ah.chrom_data.length;an<ak;an++){var am=ah.chrom_data[an].chrom;ao+='<option value="'+am+'">'+am+"</option>"}if(al.prev_chroms){ao+='<option value="previous">Previous '+x+"</option>"}if(al.next_chroms){ao+='<option value="next">Next '+x+"</option>"}ah.chrom_select.html(ao);ah.chrom_start_index=al.start_index;ai.resolve(al)},error:function(){alert("Could not load chroms for this dbkey:",ah.dbkey)}});return ai},change_chrom:function(am,ai,ao){if(!am||am==="None"){return}var aj=this;if(am==="previous"){aj.load_chroms({low:this.chrom_start_index-x});return}if(am==="next"){aj.load_chroms({low:this.chrom_start_index+x});return}var an=$.grep(aj.chrom_data,function(ap,aq){return ap.chrom===am})[0];if(an===undefined){aj.load_chroms({chrom:am},function(){aj.change_chrom(am,ai,ao)});return}else{if(am!==aj.chrom){aj.chrom=am;aj.chrom_select.val(aj.chrom);aj.max_high=an.len-1;aj.reset();aj.request_redraw(true);for(var al=0,ah=aj.drawables.length;al<ah;al++){var ak=aj.drawables[al];if(ak.init){ak.init()}}}if(ai!==undefined&&ao!==undefined){aj.low=Math.max(ai,0);aj.high=Math.min(ao,aj.max_high)}aj.reset_overview();aj.request_redraw()}},go_to:function(al){var ap=this,ah,ak,ai=al.split(":"),an=ai[0],ao=ai[1];if(ao!==undefined){try{var am=ao.split("-");ah=parseInt(am[0].replace(/,/g,""),10);ak=parseInt(am[1].replace(/,/g,""),10)}catch(aj){return false}}ap.change_chrom(an,ah,ak)},move_fraction:function(aj){var ah=this;var ai=ah.high-ah.low;this.move_delta(aj*ai)},move_delta:function(aj){var ah=this;var ai=ah.high-ah.low;if(ah.low-aj<ah.max_low){ah.low=ah.max_low;ah.high=ah.max_low+ai}else{if(ah.high-aj>ah.max_high){ah.high=ah.max_high;ah.low=ah.max_high-ai}else{ah.high-=aj;ah.low-=aj}}ah.request_redraw()},add_drawable:function(ah){z.prototype.add_drawable.call(this,ah);ah.init();this.has_changes=true;this.update_intro_div()},add_label_track:function(ah){ah.view=this;ah.init();this.label_tracks.push(ah)},remove_drawable:function(aj,ai){z.prototype.remove_drawable.call(this,aj);if(ai){var ah=this;aj.container_div.fadeOut("slow",function(){$(this).remove();ah.update_intro_div()});this.has_changes=true}},reset:function(){this.low=this.max_low;this.high=this.max_high;this.viewport_container.find(".yaxislabel").remove()},request_redraw:function(ap,ah,ao,ai){var an=this,al=(ai?[ai]:an.drawables),aj;var ai;for(var am=0;am<al.length;am++){ai=al[am];aj=-1;for(var ak=0;ak<an.tracks_to_be_redrawn.length;ak++){if(an.tracks_to_be_redrawn[ak][0]===ai){aj=ak;break}}if(aj<0){an.tracks_to_be_redrawn.push([ai,ah,ao])}else{an.tracks_to_be_redrawn[am][1]=ah;an.tracks_to_be_redrawn[am][2]=ao}}requestAnimationFrame(function(){an._redraw(ap)})},_redraw:function(ar){var ao=this.low,ak=this.high;if(ao<this.max_low){ao=this.max_low}if(ak>this.max_high){ak=this.max_high}var aq=this.high-this.low;if(this.high!==0&&aq<this.min_separation){ak=ao+this.min_separation}this.low=Math.floor(ao);this.high=Math.ceil(ak);this.resolution=Math.pow(D,Math.ceil(Math.log((this.high-this.low)/S)/Math.log(D)));this.zoom_res=Math.pow(w,Math.max(0,Math.ceil(Math.log(this.resolution,w)/Math.log(w))));var ah=(this.low/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var an=((this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var at=13;this.overview_box.css({left:ah,width:Math.max(at,an)}).show();if(an<at){this.overview_box.css("left",ah-(at-an)/2)}if(this.overview_highlight){this.overview_highlight.css({left:ah,width:an})}this.update_location(this.low,this.high);if(!ar){var aj,ai,ap;for(var al=0,am=this.tracks_to_be_redrawn.length;al<am;al++){aj=this.tracks_to_be_redrawn[al][0];ai=this.tracks_to_be_redrawn[al][1];ap=this.tracks_to_be_redrawn[al][2];if(aj){aj._draw(ai,ap)}}this.tracks_to_be_redrawn=[];for(al=0,am=this.label_tracks.length;al<am;al++){this.label_tracks[al]._draw()}}},zoom_in:function(ai,aj){if(this.max_high===0||this.high-this.low<this.min_separation){return}var ak=this.high-this.low,al=ak/2+this.low,ah=(ak/this.zoom_factor)/2;if(ai){al=ai/this.viewport_container.width()*(this.high-this.low)+this.low}this.low=Math.round(al-ah);this.high=Math.round(al+ah);this.request_redraw()},zoom_out:function(){if(this.max_high===0){return}var ai=this.high-this.low,aj=ai/2+this.low,ah=(ai*this.zoom_factor)/2;this.low=Math.round(aj-ah);this.high=Math.round(aj+ah);this.request_redraw()},resize_window:function(){this.viewport_container.height(this.container.height()-this.top_container.height()-this.bottom_container.height());this.nav_container.width(this.container.width());this.request_redraw()},set_overview:function(aj){if(this.overview_drawable){if(this.overview_drawable.dataset_id===aj.dataset_id){return}this.overview_viewport.find(".track").remove()}var ai=aj.copy({content_div:this.overview_viewport}),ah=this;ai.header_div.hide();ai.is_overview=true;ah.overview_drawable=ai;this.overview_drawable.postdraw_actions=function(){ah.overview_highlight.show().height(ah.overview_drawable.content_div.height());ah.overview_viewport.height(ah.overview_drawable.content_div.height()+ah.overview_box.outerHeight());ah.overview_close.show();ah.resize_window()};this.overview_drawable.init();ah.has_changes=true},reset_overview:function(){$(".tipsy").remove();this.overview_viewport.find(".track-tile").remove();this.overview_viewport.height(this.default_overview_height);this.overview_box.height(this.default_overview_height);this.overview_close.hide();this.overview_highlight.hide();view.resize_window();view.overview_drawable=null}});var s=function(aj,an){this.track=aj;this.name=an.name;this.params=[];var av=an.params;for(var ak=0;ak<av.length;ak++){var ap=av[ak],ai=ap.name,au=ap.label,al=unescape(ap.html),aw=ap.value,ar=ap.type;if(ar==="number"){this.params[this.params.length]=new g(ai,au,al,aw,ap.min,ap.max)}else{if(ar=="select"){this.params[this.params.length]=new P(ai,au,al,aw)}else{console.log("WARNING: unrecognized tool parameter type:",ai,ar)}}}this.parent_div=$("<div/>").addClass("dynamic-tool").hide();this.parent_div.bind("drag",function(ay){ay.stopPropagation()}).click(function(ay){ay.stopPropagation()}).bind("dblclick",function(ay){ay.stopPropagation()});var at=$("<div class='tool-name'>").appendTo(this.parent_div).text(this.name);var aq=this.params;var ao=this;$.each(this.params,function(az,aC){var aB=$("<div>").addClass("param-row").appendTo(ao.parent_div);var ay=$("<div>").addClass("param-label").text(aC.label).appendTo(aB);var aA=$("<div/>").addClass("slider").html(aC.html).appendTo(aB);aA.find(":input").val(aC.value);$("<div style='clear: both;'/>").appendTo(aB)});this.parent_div.find("input").click(function(){$(this).select()});var ax=$("<div>").addClass("param-row").appendTo(this.parent_div);var am=$("<input type='submit'>").attr("value","Run on complete dataset").appendTo(ax);var ah=$("<input type='submit'>").attr("value","Run on visible region").css("margin-left","3em").appendTo(ax);var ao=this;ah.click(function(){ao.run_on_region()});am.click(function(){ao.run_on_dataset()})};q(s.prototype,{get_param_values_dict:function(){var ah={};this.parent_div.find(":input").each(function(){var ai=$(this).attr("name"),aj=$(this).val();ah[ai]=JSON.stringify(aj)});return ah},get_param_values:function(){var ai=[];var ah={};this.parent_div.find(":input").each(function(){var aj=$(this).attr("name"),ak=$(this).val();if(aj){ai[ai.length]=ak}});return ai},run_on_dataset:function(){var ah=this;ah.run({dataset_id:this.track.original_dataset_id,tool_id:ah.name},null,function(ai){show_modal(ah.name+" is Running",ah.name+" is running on the complete dataset. Tool outputs are in dataset's history.",{Close:hide_modal})})},run_on_region:function(){var ai={dataset_id:this.track.original_dataset_id,chrom:this.track.view.chrom,low:this.track.view.low,high:this.track.view.high,tool_id:this.name},al=this.track,aj=ai.tool_id+al.tool_region_and_parameters_str(ai.chrom,ai.low,ai.high),ah,am;if(al.container===view){var ak=new R(this.name,this.track.view,this.track.container);al.container.add_drawable(ak);al.container.remove_drawable(al);ak.add_drawable(al);al.container_div.appendTo(ak.content_div);ah=ak}else{ah=al.container}if(al instanceof e){am=new W(aj,view,ah,"hda");am.change_mode(al.mode);ah.add_drawable(am)}am.content_div.text("Starting job.");this.run(ai,am,function(an){am.dataset_id=an.dataset_id;am.content_div.text("Running job.");am.init()})},run:function(ai,aj,ak){$.extend(ai,this.get_param_values_dict());var ah=function(){$.getJSON(rerun_tool_url,ai,function(al){if(al==="no converter"){aj.container_div.addClass("error");aj.content_div.text(L)}else{if(al.error){aj.container_div.addClass("error");aj.content_div.text(y+al.message)}else{if(al==="pending"){aj.container_div.addClass("pending");aj.content_div.text("Converting input data so that it can be used quickly with tool.");setTimeout(ah,2000)}else{ak(al)}}}})};ah()}});var P=function(ai,ah,aj,ak){this.name=ai;this.label=ah;this.html=aj;this.value=ak};var g=function(aj,ai,al,am,ak,ah){P.call(this,aj,ai,al,am);this.min=ak;this.max=ah};var h=function(ai,ah,aj,ak){this.name=ai;this.index=ah;this.tool_id=aj;this.tool_exp_name=ak};var X=function(ai,ah,aj,ak){h.call(this,ai,ah,aj,ak);this.low=-Number.MAX_VALUE;this.high=Number.MAX_VALUE;this.min=Number.MAX_VALUE;this.max=-Number.MAX_VALUE;this.container=null;this.slider=null;this.slider_label=null};q(X.prototype,{applies_to:function(ah){if(ah.length>this.index){return true}return false},keep:function(ah){if(!this.applies_to(ah)){return true}var ai=ah[this.index];return(isNaN(ai)||(ai>=this.low&&ai<=this.high))},update_attrs:function(ai){var ah=false;if(!this.applies_to(ai)){return ah}if(ai[this.index]<this.min){this.min=Math.floor(ai[this.index]);ah=true}if(ai[this.index]>this.max){this.max=Math.ceil(ai[this.index]);ah=true}return ah},update_ui_elt:function(){if(this.min!=this.max){this.container.show()}else{this.container.hide()}var aj=function(am,ak){var al=ak-am;return(al<=2?0.01:1)};var ai=this.slider.slider("option","min"),ah=this.slider.slider("option","max");if(this.min<ai||this.max>ah){this.slider.slider("option","min",this.min);this.slider.slider("option","max",this.max);this.slider.slider("option","step",aj(this.min,this.max));this.slider.slider("option","values",[this.min,this.max])}}});var ac=function(at,aA){this.track=at;this.filters=[];for(var av=0;av<aA.length;av++){var aw=aA[av],aB=aw.name,ah=aw.type,aj=aw.index,az=aw.tool_id,ay=aw.tool_exp_name;if(ah==="int"||ah==="float"){this.filters[av]=new X(aB,aj,az,ay)}else{console.log("ERROR: unsupported filter: ",aB,ah)}}var ak=function(aC,aD,aE){aC.click(function(){var aF=aD.text();max=parseFloat(aE.slider("option","max")),input_size=(max<=1?4:max<=1000000?max.toString().length:6),multi_value=false;if(aE.slider("option","values")){input_size=2*input_size+1;multi_value=true}aD.text("");$("<input type='text'/>").attr("size",input_size).attr("maxlength",input_size).attr("value",aF).appendTo(aD).focus().select().click(function(aG){aG.stopPropagation()}).blur(function(){$(this).remove();aD.text(aF)}).keyup(function(aK){if(aK.keyCode===27){$(this).trigger("blur")}else{if(aK.keyCode===13){var aI=aE.slider("option","min"),aG=aE.slider("option","max"),aJ=function(aL){return(isNaN(aL)||aL>aG||aL<aI)},aH=$(this).val();if(!multi_value){aH=parseFloat(aH);if(aJ(aH)){alert("Parameter value must be in the range ["+aI+"-"+aG+"]");return $(this)}}else{aH=aH.split("-");aH=[parseFloat(aH[0]),parseFloat(aH[1])];if(aJ(aH[0])||aJ(aH[1])){alert("Parameter value must be in the range ["+aI+"-"+aG+"]");return $(this)}}aE.slider((multi_value?"values":"value"),aH)}}})})};this.parent_div=$("<div/>").addClass("filters").hide();this.parent_div.bind("drag",function(aC){aC.stopPropagation()}).click(function(aC){aC.stopPropagation()}).bind("dblclick",function(aC){aC.stopPropagation()}).bind("keydown",function(aC){aC.stopPropagation()});var ax=$("<div/>").addClass("sliders").appendTo(this.parent_div);var ap=this;$.each(this.filters,function(aF,aH){aH.container=$("<div/>").addClass("filter-row slider-row").appendTo(ax);var aG=$("<div/>").addClass("elt-label").appendTo(aH.container);var aE=$("<span/>").addClass("slider-name").text(aH.name+" ").appendTo(aG);var aD=$("<span/>");var aJ=$("<span/>").addClass("slider-value").appendTo(aG).append("[").append(aD).append("]");var aC=$("<div/>").addClass("slider").appendTo(aH.container);aH.control_element=$("<div/>").attr("id",aH.name+"-filter-control").appendTo(aC);var aI=[0,0];aH.control_element.slider({range:true,min:Number.MAX_VALUE,max:-Number.MIN_VALUE,values:[0,0],slide:function(aL,aM){var aK=aM.values;aD.text(aK[0]+"-"+aK[1]);aH.low=aK[0];aH.high=aK[1];ap.track.request_draw(true,true)},change:function(aK,aL){aH.control_element.slider("option","slide").call(aH.control_element,aK,aL)}});aH.slider=aH.control_element;aH.slider_label=aD;ak(aJ,aD,aH.control_element);$("<div style='clear: both;'/>").appendTo(aH.container)});if(this.filters.length!==0){var am=$("<div/>").addClass("param-row").appendTo(ax);var ao=$("<input type='submit'/>").attr("value","Run on complete dataset").appendTo(am);var ai=this;ao.click(function(){ai.run_on_dataset()})}var ar=$("<div/>").addClass("display-controls").appendTo(this.parent_div),au,an,aq,al={Transparency:function(aC){ap.alpha_filter=aC},Height:function(aC){ap.height_filter=aC}};$.each(al,function(aE,aD){au=$("<div/>").addClass("filter-row").appendTo(ar),an=$("<span/>").addClass("elt-label").text(aE+":").appendTo(au),aq=$("<select/>").attr("name",aE+"_dropdown").css("float","right").appendTo(au);$("<option/>").attr("value",-1).text("== None ==").appendTo(aq);for(var aC=0;aC<ap.filters.length;aC++){$("<option/>").attr("value",aC).text(ap.filters[aC].name).appendTo(aq)}aq.change(function(){$(this).children("option:selected").each(function(){var aF=parseInt($(this).val());al[aE]((aF>=0?ap.filters[aF]:null));ap.track.request_draw(true,true)})});$("<div style='clear: both;'/>").appendTo(au)});$("<div style='clear: both;'/>").appendTo(this.parent_div)};q(ac.prototype,{reset_filters:function(){for(var ah=0;ah<this.filters.length;ah++){filter=this.filters[ah];filter.slider.slider("option","values",[filter.min,filter.max])}this.alpha_filter=null;this.height_filter=null},run_on_dataset:function(){var ap=function(au,ar,at){if(!(ar in au)){au[ar]=at}return au[ar]};var aj={},ah,ai,ak;for(var al=0;al<this.filters.length;al++){ah=this.filters[al];if(ah.tool_id){if(ah.min!=ah.low){ai=ap(aj,ah.tool_id,[]);ai[ai.length]=ah.tool_exp_name+" >= "+ah.low}if(ah.max!=ah.high){ai=ap(aj,ah.tool_id,[]);ai[ai.length]=ah.tool_exp_name+" <= "+ah.high}}}var an=[];for(var aq in aj){an[an.length]=[aq,aj[aq]]}var ao=an.length;(function am(ay,av){var at=av[0],au=at[0],ax=at[1],aw="("+ax.join(") and (")+")",ar={cond:aw,input:ay,target_dataset_id:ay,tool_id:au},av=av.slice(1);$.getJSON(run_tool_url,ar,function(az){if(az.error){show_modal("Filter Dataset","Error running tool "+au,{Close:hide_modal})}else{if(av.length===0){show_modal("Filtering Dataset","Filter(s) are running on the complete dataset. Outputs are in dataset's history.",{Close:hide_modal})}else{am(az.dataset_id,av)}}})})(this.track.dataset_id,an)}});var E=function(ah,ai){N.Scaler.call(this,ai);this.filter=ah};E.prototype.gen_val=function(ah){if(this.filter.high===Number.MAX_VALUE||this.filter.low===-Number.MAX_VALUE||this.filter.low===this.filter.high){return this.default_val}return((parseFloat(ah[this.filter.index])-this.filter.low)/(this.filter.high-this.filter.low))};var H=function(ah){this.track=ah.track;this.params=ah.params;this.values={};this.restore_values((ah.saved_values?ah.saved_values:{}));this.onchange=ah.onchange};q(H.prototype,{restore_values:function(ah){var ai=this;$.each(this.params,function(aj,ak){if(ah[ak.key]!==undefined){ai.values[ak.key]=ah[ak.key]}else{ai.values[ak.key]=ak.default_value}})},build_form:function(){var ai=this;var ah=$("<div />");$.each(this.params,function(am,ak){if(!ak.hidden){var aj="param_"+am;var ao=ai.values[ak.key];var ar=$("<div class='form-row' />").appendTo(ah);ar.append($("<label />").attr("for",aj).text(ak.label+":"));if(ak.type==="bool"){ar.append($('<input type="checkbox" />').attr("id",aj).attr("name",aj).attr("checked",ao))}else{if(ak.type==="text"){ar.append($('<input type="text"/>').attr("id",aj).val(ao).click(function(){$(this).select()}))}else{if(ak.type==="color"){var an=$("<input />").attr("id",aj).attr("name",aj).val(ao);var ap=$("<div class='tipsy tipsy-north' style='position: absolute;' />").hide();var al=$("<div style='background-color: black; padding: 10px;'></div>").appendTo(ap);var aq=$("<div/>").appendTo(al).farbtastic({width:100,height:100,callback:an,color:ao});$("<div />").append(an).append(ap).appendTo(ar).bind("click",function(at){ap.css({left:$(this).position().left+($(an).width()/2)-60,top:$(this).position().top+$(this.height)}).show();$(document).bind("click.color-picker",function(){ap.hide();$(document).unbind("click.color-picker")});at.stopPropagation()})}else{ar.append($("<input />").attr("id",aj).attr("name",aj).val(ao))}}}}});return ah},update_from_form:function(ah){var aj=this;var ai=false;$.each(this.params,function(ak,am){if(!am.hidden){var an="param_"+ak;var al=ah.find("#"+an).val();if(am.type==="float"){al=parseFloat(al)}else{if(am.type==="int"){al=parseInt(al)}else{if(am.type==="bool"){al=ah.find("#"+an).is(":checked")}}}if(al!==aj.values[am.key]){aj.values[am.key]=al;ai=true}}});if(ai){this.onchange()}}});var b=function(ah,ak,aj,ai,al){this.track=ah;this.index=ak;this.low=ak*S*aj;this.high=(ak+1)*S*aj;this.resolution=aj;this.canvas=$("<div class='track-tile'/>").append(ai);this.data=al;this.stale=false};b.prototype.predisplay_actions=function(){};var l=function(ah,ak,aj,ai,al,am){b.call(this,ah,ak,aj,ai,al);this.max_val=am};q(l.prototype,b.prototype);var Q=function(ah,al,ak,aj,an,ao,am,ai){b.call(this,ah,al,ak,aj,an);this.mode=ao;this.message=am;this.feature_mapper=ai};q(Q.prototype,b.prototype);Q.prototype.predisplay_actions=function(){var ai=this,ah={};if(ai.mode!=="Pack"){return}$(this.canvas).mousemove(function(au){var ao=$(this).offset(),at=au.pageX-ao.left,ar=au.pageY-ao.top,ay=ai.feature_mapper.get_feature_data(at,ar),ap=(ay?ay[0]:null);$(this).siblings(".feature-popup").each(function(){if(!ap||$(this).attr("id")!==ap.toString()){$(this).remove()}});if(ay){var ak=ah[ap];if(!ak){var ap=ay[0],av={name:ay[3],start:ay[1],end:ay[2],strand:ay[4]},an=ai.track.filters_manager.filters,am;for(var aq=0;aq<an.length;aq++){am=an[aq];av[am.name]=ay[am.index]}var ak=$("<div/>").attr("id",ap).addClass("feature-popup"),ax,aw,az=$("<table/>").appendTo(ak),aA;for(ax in av){aw=av[ax];aA=$("<tr/>").appendTo(az);$("<th/>").appendTo(aA).text(ax);$("<td/>").attr("align","left").appendTo(aA).text(typeof(aw)=="number"?ab(aw,2):aw)}ah[ap]=ak}ak.appendTo($(ai.canvas).parent());var al=at+parseInt(ai.canvas.css("left"))+7,aj=ar+parseInt(ai.canvas.css("top"))+7;ak.css("left",al+"px").css("top",aj+"px")}else{if(!au.isPropagationStopped()){au.stopPropagation();$(this).siblings().each(function(){$(this).trigger(au)})}}}).mouseleave(function(){$(this).siblings(".feature-popup").remove()})};var j=function(ak,at,al,ao,au,aj,ai){r.call(this,ak,at,al,{},"draghandle");this.data_url=(aj?aj:default_data_url);this.data_url_extra_params={};this.data_query_wait=(ai?ai:M);this.dataset_check_url=converted_datasets_state_url;if(!j.id_counter){j.id_counter=0}this.id=j.id_counter++;this.container_div=$("<div />").addClass("track").attr("id","track_"+this.id).css("position","relative");if(ao){this.header_div=$("<div class='track-header' />").appendTo(this.container_div);if(this.view.editor){this.drag_div=$("<div/>").addClass(this.drag_handle_class).appendTo(this.header_div)}this.name_div=$("<div/>").addClass("track-name").appendTo(this.header_div).text(this.name).attr("id",this.name.replace(/\s+/g,"-").replace(/[^a-zA-Z0-9\-]/g,"").toLowerCase());this.icons_div=$("<div/>").css("float","left").appendTo(this.header_div).hide();this.settings_icon=$("<a/>").attr("href","javascript:void(0);").attr("title","Edit settings").addClass("icon-button settings-icon").tipsy({gravity:"s"}).appendTo(this.icons_div);this.overview_icon=$("<a/>").attr("href","javascript:void(0);").attr("title","Set as overview").addClass("icon-button overview-icon").tipsy({gravity:"s"}).appendTo(this.icons_div);this.filters_icon=$("<a/>").attr("href","javascript:void(0);").attr("title","Filters").addClass("icon-button filters-icon").tipsy({gravity:"s"}).appendTo(this.icons_div).hide();this.tools_icon=$("<a/>").attr("href","javascript:void(0);").attr("title","Tools").addClass("icon-button tools-icon").tipsy({gravity:"s"}).appendTo(this.icons_div).hide();this.remove_icon=$("<a/>").attr("href","javascript:void(0);").attr("title","Remove").addClass("icon-button remove-icon").tipsy({gravity:"s"}).appendTo(this.icons_div);var am=this;this.header_div.dblclick(function(av){av.stopPropagation()});this.settings_icon.click(function(){var ax=function(){hide_modal();$(window).unbind("keypress.check_enter_esc")},av=function(){am.config.update_from_form($(".dialog-box"));hide_modal();$(window).unbind("keypress.check_enter_esc")},aw=function(ay){if((ay.keyCode||ay.which)===27){ax()}else{if((ay.keyCode||ay.which)===13){av()}}};$(window).bind("keypress.check_enter_esc",aw);show_modal("Configure Track",am.config.build_form(),{Cancel:ax,OK:av})});this.overview_icon.click(function(){am.view.set_overview(am)});this.filters_icon.click(function(){am.filters_div.toggle();am.filters_manager.reset_filters()});this.tools_icon.click(function(){am.dynamic_tool_div.toggle();if(am.dynamic_tool_div.is(":visible")){am.set_name(am.name+am.tool_region_and_parameters_str())}else{am.revert_name()}$(".tipsy").remove()});this.remove_icon.click(function(){$(".tipsy").remove();am.remove()});if(am.display_modes!==undefined){if(am.mode_div===undefined){am.mode_div=$("<div class='right-float menubutton popup' />").appendTo(am.header_div);var an=(am.config&&am.config.values.mode?am.config.values.mode:am.display_modes[0]);am.mode=an;am.mode_div.text(an);var ah={};for(var ap=0,ar=am.display_modes.length;ap<ar;ap++){var aq=am.display_modes[ap];ah[aq]=function(av){return function(){am.change_mode(av)}}(aq)}make_popupmenu(am.mode_div,ah)}else{am.mode_div.hide()}this.header_div.append($("<div/>").css("clear","both"));this.container_div.hover(function(){am.icons_div.show()},function(){am.icons_div.hide()})}}this.content_div=$("<div class='track-content'>").appendTo(this.container_div);this.container.content_div.append(this.container_div)};q(j.prototype,r.prototype,{get_type:function(){if(this instanceof ad){return"LabelTrack"}else{if(this instanceof B){return"ReferenceTrack"}else{if(this instanceof k){return"LineTrack"}else{if(this instanceof Y){return"ReadTrack"}else{if(this instanceof W){return"ToolDataFeatureTrack"}else{if(this instanceof V){return"VcfTrack"}else{if(this instanceof e){return"FeatureTrack"}}}}}}}return""},init:function(){var ah=this;ah.enabled=false;ah.tile_cache.clear();ah.data_manager.clear();ah.initial_canvas=undefined;ah.content_div.css("height","auto");ah.container_div.removeClass("nodata error pending");if(!ah.dataset_id){return}$.getJSON(converted_datasets_state_url,{hda_ldda:ah.hda_ldda,dataset_id:ah.dataset_id,chrom:ah.view.chrom},function(ai){if(!ai||ai==="error"||ai.kind==="error"){ah.container_div.addClass("error");ah.content_div.text(p);if(ai.message){var aj=$(" <a href='javascript:void(0);'></a>").text("View error").click(function(){show_modal("Trackster Error","<pre>"+ai.message+"</pre>",{Close:hide_modal})});ah.content_div.append(aj)}}else{if(ai==="no converter"){ah.container_div.addClass("error");ah.content_div.text(L)}else{if(ai==="no data"||(ai.data!==undefined&&(ai.data===null||ai.data.length===0))){ah.container_div.addClass("nodata");ah.content_div.text(G)}else{if(ai==="pending"){ah.container_div.addClass("pending");ah.content_div.text(u);setTimeout(function(){ah.init()},ah.data_query_wait)}else{if(ai.status==="data"){if(ai.valid_chroms){ah.valid_chroms=ai.valid_chroms;ah.update_track_icons()}ah.content_div.text(aa);if(ah.view.chrom){ah.content_div.text("");ah.content_div.css("height",ah.height_px+"px");ah.enabled=true;$.when(ah.predraw_init()).done(function(){ah.container_div.removeClass("nodata error pending");ah.request_draw()})}}}}}}});this.update_track_icons()},predraw_init:function(){}});var O=function(ak,aj){var ai=this,ah=ai.view;n(ai.container_div,ai.drag_handle_class,".group",ai);this.filters_manager=new ac(this,(ak!==undefined?ak:{}));this.filters_available=false;this.filters_visible=false;this.tool=(aj!==undefined&&obj_length(aj)>0?new s(this,aj):undefined);if(this.header_div){if(this.filters_manager){this.filters_div=this.filters_manager.parent_div;this.header_div.after(this.filters_div)}if(this.tool){this.dynamic_tool_div=this.tool.parent_div;this.header_div.after(this.dynamic_tool_div)}}};q(O.prototype,r.prototype,j.prototype,{copy:function(ah){return new this.constructor(this.name,this.view,ah,this.hda_ldda,this.dataset_id,this.prefs,this.filters,this.tool)},to_json:function(){return{track_type:this.get_type(),name:this.name,hda_ldda:this.hda_ldda,dataset_id:this.dataset_id,prefs:this.prefs,mode:this.mode,}},change_mode:function(ai){var ah=this;ah.mode_div.text(ai);ah.mode=ai;ah.config.values.mode=ai;ah.tile_cache.clear();ah.request_draw();return ah},update_track_icons:function(){var ah=this;if(ah.filters_available>0){ah.filters_icon.show()}else{ah.filters_icon.hide()}if(ah.tool){ah.tools_icon.show()}else{ah.tools_icon.hide()}},_gen_tile_cache_key:function(ai,aj,ah){return ai+"_"+aj+"_"+ah},request_draw:function(ai,ah){this.view.request_redraw(false,ai,ah,this)},_draw:function(aj,ar){if(!this.enabled){return}if(!(this instanceof B)&&(!this.dataset_id)){return}var aq=this.view.low,an=this.view.high,ao=an-aq,ak=this.view.container.width(),av=ak/ao,am=this.view.resolution,au=$("<div style='position: relative;'></div>");if(this.is_overview){aq=this.view.max_low;an=this.view.max_high;am=Math.pow(D,Math.ceil(Math.log((view.max_high-view.max_low)/S)/Math.log(D)));av=ak/(view.max_high-view.max_low)}if(!ar){this.content_div.children().remove()}this.content_div.append(au);this.max_height=0;var ai=Math.floor(aq/am/S);var ap=true;var at=[];var ah=0;while((ai*S*am)<an){tile=this.draw_helper(aj,ak,ai,am,au,av);if(tile){at.push(tile)}else{ap=false}ai+=1;ah++}var al=this;if(ap){al.postdraw_actions(at,ak,av,ar)}},postdraw_actions:function(al,am,an,ah){var aj=this;var ak=false;for(var ai=0;ai<al.length;ai++){if(al[ai].message){ak=true;break}}if(ak){for(var ai=0;ai<al.length;ai++){tile=al[ai];if(!tile.message){tile.canvas.css("padding-top",F)}}}},draw_helper:function(ai,aj,ak,an,au,ay,av,ao){var al=this,at=this._gen_tile_cache_key(aj,ay,ak),ap=ak*S*an,ax=ap+S*an;var aq=(ai?undefined:al.tile_cache.get(at));if(aq){al.show_tile(aq,au,ay);return aq}var ar=function(az){return("isResolved" in az)};var am=true;var ah=al.data_manager.get_data(ap,ax,al.mode,an,al.data_url_extra_params);if(ar(ah)){am=false}var aw;if(view.reference_track&&ay>view.canvas_manager.char_width_px){aw=view.reference_track.data_manager.get_data(ap,ax,al.mode,an,view.reference_track.data_url_extra_params);if(ar(aw)){am=false}}if(am){q(ah,ao);var aq=al.draw_tile(ah,al.mode,an,ak,ay,aw);if(aq!==undefined){al.tile_cache.set(at,aq);al.show_tile(aq,au,ay)}return aq}$.when(ah,aw).then(function(){view.request_redraw(false,false,false,al)});return null},show_tile:function(an,ap,aq){var aj=this,ai=an.canvas,am=ai;if(an.message){var ar=$("<div/>"),ao=$("<div/>").addClass("tile-message").text(an.message).css({height:F-1,width:an.canvas.width}).appendTo(ar),al=$("<a href='javascript:void(0);'/>").addClass("icon more-down").appendTo(ao),ah=$("<a href='javascript:void(0);'/>").addClass("icon more-across").appendTo(ao);ar.append(ai);am=ar;al.click(function(){an.stale=true;aj.data_manager.get_more_data(an.low,an.high,aj.mode,an.resolution,{},aj.data_manager.DEEP_DATA_REQ);aj.request_draw()}).dblclick(function(at){at.stopPropagation()});ah.click(function(){an.stale=true;aj.data_manager.get_more_data(an.low,an.high,aj.mode,an.resolution,{},aj.data_manager.BROAD_DATA_REQ);aj.request_draw()}).dblclick(function(at){at.stopPropagation()})}an.predisplay_actions();var ak=(an.low-(this.is_overview?this.view.max_low:this.view.low))*aq;if(this.left_offset){ak-=this.left_offset}am.css({position:"absolute",top:0,left:ak,height:""});ap.append(am);aj.max_height=Math.max(aj.max_height,am.height());aj.content_div.css("height",aj.max_height+"px");ap.children().css("height",aj.max_height+"px")},_get_tile_bounds:function(ah,ai){var ak=ah*S*ai,al=S*ai,aj=(ak+al<=this.view.max_high?ak+al:this.view.max_high);return[ak,aj]},tool_region_and_parameters_str:function(aj,ah,ak){var ai=this,al=(aj!==undefined&&ah!==undefined&&ak!==undefined?aj+":"+ah+"-"+ak:"all");return" - region=["+al+"], parameters=["+ai.tool.get_param_values().join(", ")+"]"}});var ad=function(ai,ah){j.call(this,"label",ai,ah,false,{});this.container_div.addClass("label-track")};q(ad.prototype,j.prototype,{init:function(){this.enabled=true},_draw:function(){var aj=this.view,ak=aj.high-aj.low,an=Math.floor(Math.pow(10,Math.floor(Math.log(ak)/Math.log(10)))),ah=Math.floor(aj.low/an)*an,al=this.view.container.width(),ai=$("<div style='position: relative; height: 1.3em;'></div>");while(ah<aj.high){var am=(ah-aj.low)/ak*al;ai.append($("<div class='label'>"+commatize(ah)+"</div>").css({position:"absolute",left:am-1}));ah+=an}this.content_div.children(":first").remove();this.content_div.append(ai)}});var B=function(ah){j.call(this,"reference",ah,{content_div:ah.top_labeltrack},false,{});O.call(this);ah.reference_track=this;this.left_offset=200;this.height_px=12;this.container_div.addClass("reference-track");this.content_div.css("background","none");this.content_div.css("min-height","0px");this.content_div.css("border","none");this.data_url=reference_url;this.data_url_extra_params={dbkey:ah.dbkey};this.data_manager=new J(C,this,false);this.tile_cache=new c(v)};q(B.prototype,r.prototype,O.prototype,{init:function(){this.enabled=true},draw_tile:function(ar,an,am,ai,at){var al=this,aj=S*am;if(at>this.view.canvas_manager.char_width_px){if(ar.data===null){al.content_div.css("height","0px");return}var ak=this.view.canvas_manager.new_canvas();var aq=ak.getContext("2d");ak.width=Math.ceil(aj*at+al.left_offset);ak.height=al.height_px;aq.font=aq.canvas.manager.default_font;aq.textAlign="center";ar=ar.data;for(var ao=0,ap=ar.length;ao<ap;ao++){var ah=Math.round(ao*at);aq.fillText(ar[ao],ah+al.left_offset,10)}return new b(al,ai,am,ak,ar)}this.content_div.css("height","0px")}});var k=function(am,ak,aj,an,ah,al){var ai=this;this.display_modes=["Histogram","Line","Filled","Intensity"];this.mode="Histogram";j.call(this,am,ak,aj,al);O.call(this);this.min_height_px=16;this.max_height_px=400;this.height_px=80;this.hda_ldda=an;this.dataset_id=ah;this.original_dataset_id=ah;this.data_manager=new T(C,this);this.tile_cache=new c(v);this.left_offset=0;this.config=new H({track:this,params:[{key:"name",label:"Name",type:"text",default_value:am},{key:"color",label:"Color",type:"color",default_value:get_random_color()},{key:"min_value",label:"Min Value",type:"float",default_value:undefined},{key:"max_value",label:"Max Value",type:"float",default_value:undefined},{key:"mode",type:"string",default_value:this.mode,hidden:true},{key:"height",type:"int",default_value:this.height_px,hidden:true}],saved_values:al,onchange:function(){ai.set_name(ai.prefs.name);ai.vertical_range=ai.prefs.max_value-ai.prefs.min_value;$("#linetrack_"+ai.dataset_id+"_minval").text(ai.prefs.min_value);$("#linetrack_"+ai.dataset_id+"_maxval").text(ai.prefs.max_value);ai.tile_cache.clear();ai.request_draw()}});this.prefs=this.config.values;this.height_px=this.config.values.height;this.vertical_range=this.config.values.max_value-this.config.values.min_value;this.add_resize_handle()};q(k.prototype,r.prototype,O.prototype,{add_resize_handle:function(){var ah=this;var ak=false;var aj=false;var ai=$("<div class='track-resize'>");$(ah.container_div).hover(function(){ak=true;ai.show()},function(){ak=false;if(!aj){ai.hide()}});ai.hide().bind("dragstart",function(al,am){aj=true;am.original_height=$(ah.content_div).height()}).bind("drag",function(am,an){var al=Math.min(Math.max(an.original_height+an.deltaY,ah.min_height_px),ah.max_height_px);$(ah.content_div).css("height",al);ah.height_px=al;ah.request_draw(true)}).bind("dragend",function(al,am){ah.tile_cache.clear();aj=false;if(!ak){ai.hide()}ah.config.values.height=ah.height_px}).appendTo(ah.container_div)},predraw_init:function(){var ah=this;ah.vertical_range=undefined;return $.getJSON(ah.data_url,{stats:true,chrom:ah.view.chrom,low:null,high:null,hda_ldda:ah.hda_ldda,dataset_id:ah.dataset_id},function(ai){ah.container_div.addClass("line-track");var ak=ai.data;if(isNaN(parseFloat(ah.prefs.min_value))||isNaN(parseFloat(ah.prefs.max_value))){ah.prefs.min_value=ak.min;ah.prefs.max_value=ak.max;$("#track_"+ah.dataset_id+"_minval").val(ah.prefs.min_value);$("#track_"+ah.dataset_id+"_maxval").val(ah.prefs.max_value)}ah.vertical_range=ah.prefs.max_value-ah.prefs.min_value;ah.total_frequency=ak.total_frequency;ah.container_div.find(".yaxislabel").remove();var al=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+ah.dataset_id+"_minval").text(ab(ah.prefs.min_value,3));var aj=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+ah.dataset_id+"_maxval").text(ab(ah.prefs.max_value,3));aj.css({position:"absolute",top:"24px",left:"10px"});aj.prependTo(ah.container_div);al.css({position:"absolute",bottom:"2px",left:"10px"});al.prependTo(ah.container_div)})},draw_tile:function(au,am,al,aj,at){if(this.vertical_range===undefined){return}var ah=this._get_tile_bounds(aj,al),an=ah[0],ar=ah[1],ai=Math.ceil((ar-an)*at),ap=this.height_px;var ak=this.view.canvas_manager.new_canvas();ak.width=ai,ak.height=ap;var aq=ak.getContext("2d");var ao=new N.LinePainter(au.data,an,ar,this.prefs,am);ao.draw(aq,ai,ap);return new b(this.track,aj,al,ak,au.data)}});var e=function(ah,an,ai,am,ap,ao,ak,al){var aj=this;this.display_modes=["Auto","Histogram","Dense","Squish","Pack"];j.call(this,ah,an,ai,true,ao);O.call(this,ak,al);this.config=new H({track:this,params:[{key:"name",label:"Name",type:"text",default_value:ah},{key:"block_color",label:"Block color",type:"color",default_value:get_random_color()},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:ao,onchange:function(){aj.set_name(aj.prefs.name);aj.tile_cache.clear();aj.request_draw()}});this.prefs=this.config.values;this.height_px=0;this.container_div.addClass("feature-track");this.hda_ldda=am;this.dataset_id=ap;this.original_dataset_id=ap;this.show_labels_scale=0.001;this.showing_details=false;this.summary_draw_height=30;this.inc_slots={};this.start_end_dct={};this.tile_cache=new c(d);this.data_manager=new T(20,this);this.left_offset=200;this.painter=N.LinkedFeaturePainter};q(e.prototype,r.prototype,O.prototype,{postdraw_actions:function(ax,ah,ay,aw){O.prototype.postdraw_actions.call(this,ax,aw);var ak=this;if(aw){var am=ak.content_div.children();var an=false;for(var al=am.length-1,ar=0;al>=ar;al--){var aj=$(am[al]);if(an){aj.remove()}else{if(aj.children().length!==0){an=true}}}}if(ak.mode=="Histogram"){var aq=-1;for(var al=0;al<ax.length;al++){var av=ax[al].max_val;if(av>aq){aq=av}}for(var al=0;al<ax.length;al++){var au=ax[al];if(au.max_val!==aq){au.canvas.remove();ak.draw_helper(true,ah,au.index,au.resolution,au.canvas.parent(),ay,[],{max:aq})}}}if(ak.filters_manager){var ai=ak.filters_manager.filters;for(var ap=0;ap<ai.length;ap++){ai[ap].update_ui_elt()}var ao=false,at;for(var al=0;al<ax.length;al++){if(ax[al].data.length){at=ax[al].data[0];for(var ap=0;ap<ai.length;ap++){if(ai[ap].applies_to(at)){ao=true;break}}}}if(ak.filters_available!==ao){ak.filters_available=ao;if(!ak.filters_available){ak.filters_div.hide()}ak.update_track_icons()}}},update_auto_mode:function(ah){if(this.mode=="Auto"){if(ah=="no_detail"){ah="feature spans"}else{if(ah=="summary_tree"){ah="coverage histogram"}}this.mode_div.text("Auto ("+ah+")")}},incremental_slots:function(al,ai,ak){var aj=this.view.canvas_manager.dummy_context,ah=this.inc_slots[al];if(!ah||(ah.mode!==ak)){ah=new (t.FeatureSlotter)(al,ak==="Pack",A,function(am){return aj.measureText(am)});ah.mode=ak;this.inc_slots[al]=ah}return ah.slot_features(ai)},get_summary_tree_data:function(al,ao,aj,ax){if(ax>aj-ao){ax=aj-ao}var at=Math.floor((aj-ao)/ax),aw=[],ak=0;var am=0,an=0,ar,av=0,ap=[],au,aq;var ai=function(aA,az,aB,ay){aA[0]=az+aB*ay;aA[1]=az+(aB+1)*ay};while(av<ax&&am!==al.length){var ah=false;for(;av<ax&&!ah;av++){ai(ap,ao,av,at);for(an=am;an<al.length;an++){ar=al[an].slice(1,3);if(is_overlap(ar,ap)){ah=true;break}}if(ah){break}}data_start_index=an;aw[aw.length]=au=[ap[0],0];for(;an<al.length;an++){ar=al[an].slice(1,3);if(is_overlap(ar,ap)){au[1]++}else{break}}if(au[1]>ak){ak=au[1]}av++}return{max:ak,delta:at,data:aw}},draw_tile:function(aw,az,aD,aH,ar,ak){var aA=this,am=aA._get_tile_bounds(aH,aD),aK=am[0],ai=am[1],ay=ai-aK,aB=Math.ceil(ay*ar),aQ=25,al=this.left_offset,ax,an;if(az==="Auto"){if(aw.dataset_type==="summary_tree"){az=aw.dataset_type}else{if(aw.extra_info==="no_detail"||aA.is_overview){az="no_detail"}else{var aP=aw.data;if(this.view.high-this.view.low>K){az="Squish"}else{az="Pack"}}}this.update_auto_mode(az)}if(az==="summary_tree"||az==="Histogram"){an=this.summary_draw_height;this.container_div.find(".yaxislabel").remove();var ah=$("<div />").addClass("yaxislabel");ah.text(aw.max);ah.css({position:"absolute",top:"24px",left:"10px",color:this.prefs.label_color});ah.prependTo(this.container_div);var aj=this.view.canvas_manager.new_canvas();aj.width=aB+al;aj.height=an+U;if(aw.dataset_type!="summary_tree"){var at=this.get_summary_tree_data(aw.data,aK,ai,200);if(aw.max){at.max=aw.max}aw=at}var aM=new N.SummaryTreePainter(aw,aK,ai,this.prefs);var aC=aj.getContext("2d");aC.translate(al,U);aM.draw(aC,aB,an);return new l(aA,aH,aD,aj,aw.data,aw.max)}var ax,ap=1;if(az==="no_detail"||az==="Squish"||az==="Pack"){ap=this.incremental_slots(ar,aw.data,az);ax=this.inc_slots[ar].slots}var aq=[];if(aw.data){var au=this.filters_manager.filters;for(var aE=0,aG=aw.data.length;aE<aG;aE++){var ao=aw.data[aE];var aF=false;var av;for(var aJ=0,aO=au.length;aJ<aO;aJ++){av=au[aJ];av.update_attrs(ao);if(!av.keep(ao)){aF=true;break}}if(!aF){aq.push(ao)}}}var aN=(this.filters_manager.alpha_filter?new E(this.filters_manager.alpha_filter):null);var aL=(this.filters_manager.height_filter?new E(this.filters_manager.height_filter):null);var aM=new (this.painter)(aq,aK,ai,this.prefs,az,aN,aL,ak);var an=Math.max(af,aM.get_required_height(ap));var aj=this.view.canvas_manager.new_canvas();var aI=null;aj.width=aB+al;aj.height=an;var aC=aj.getContext("2d");aC.fillStyle=this.prefs.block_color;aC.font=aC.canvas.manager.default_font;aC.textAlign="right";this.container_div.find(".yaxislabel").remove();if(aw.data){aC.translate(al,0);aI=aM.draw(aC,aB,an,ax);aI.translation=-al}return new Q(aA,aH,aD,aj,aw.data,az,aw.message,aI)}});var V=function(al,aj,ai,an,ah,ak,am){e.call(this,al,aj,ai,an,ah,ak,am);this.painter=N.VariantPainter};q(V.prototype,r.prototype,O.prototype,e.prototype);var Y=function(al,aj,ai,an,ah,ak,am){e.call(this,al,aj,ai,an,ah,ak,am);this.config=new H({track:this,params:[{key:"name",label:"Name",type:"text",default_value:al},{key:"block_color",label:"Block color",type:"color",default_value:get_random_color()},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_insertions",label:"Show insertions",type:"bool",default_value:false},{key:"show_differences",label:"Show differences only",type:"bool",default_value:true},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:ak,onchange:function(){this.track.set_name(this.track.prefs.name);this.track.tile_cache.clear();this.track.request_draw()}});this.prefs=this.config.values;this.painter=N.ReadPainter;this.update_track_icons()};q(Y.prototype,r.prototype,O.prototype,e.prototype);var W=function(al,aj,ai,an,ah,ak,am){e.call(this,al,aj,ai,an,ah,ak,am,{});this.data_url=raw_data_url;this.data_query_wait=1000;this.dataset_check_url=dataset_state_url};q(W.prototype,r.prototype,O.prototype,e.prototype,{predraw_init:function(){var ai=this;var ah=function(){if(ai.data_manager.size()===0){setTimeout(ah,300)}else{ai.data_url=default_data_url;ai.data_query_wait=M;ai.dataset_state_url=converted_datasets_state_url;$.getJSON(ai.dataset_state_url,{dataset_id:ai.dataset_id,hda_ldda:ai.hda_ldda},function(aj){})}};ah()}});Z.View=ae;Z.DrawableGroup=R;Z.LineTrack=k;Z.FeatureTrack=e;Z.ReadTrack=Y};var slotting_module=function(c,b){var e=c("class").extend;var d=2,a=5;b.FeatureSlotter=function(j,h,f,g){this.slots={};this.start_end_dct={};this.w_scale=j;this.include_label=h;this.max_rows=f;this.measureText=g};e(b.FeatureSlotter.prototype,{slot_features:function(m){var p=this.w_scale,s=this.slots,h=this.start_end_dct,y=[],A=[],n=0,z=this.max_rows;for(var w=0,x=m.length;w<x;w++){var l=m[w],o=l[0];if(s[o]!==undefined){n=Math.max(n,s[o]);A.push(s[o])}else{y.push(w)}}var q=function(G,H){for(var F=0;F<=z;F++){var D=false,I=h[F];if(I!==undefined){for(var C=0,E=I.length;C<E;C++){var B=I[C];if(H>B[0]&&G<B[1]){D=true;break}}}if(!D){return F}}return -1};for(var w=0,x=y.length;w<x;w++){var l=m[y[w]],o=l[0],u=l[1],f=l[2],r=l[3],g=Math.floor(u*p),k=Math.ceil(f*p),v=this.measureText(r).width,j;if(r!==undefined&&this.include_label){v+=(d+a);if(g-v>=0){g-=v;j="left"}else{k+=v;j="right"}}var t=q(g,k);if(t>=0){if(h[t]===undefined){h[t]=[]}h[t].push([g,k]);s[o]=t;n=Math.max(n,t)}else{}}return n+1}})};var painters_module=function(k,y){var v=k("class").extend;var q=function(J,B,H,A,G,E){if(E===undefined){E=4}var D=A-B;var C=G-H;var F=Math.floor(Math.sqrt(D*D+C*C)/E);var K=D/F;var I=C/F;var z;for(z=0;z<F;z++,B+=K,H+=I){if(z%2!==0){continue}J.fillRect(B,H,E,1)}};var r=function(B,A,z,E){var D=A-E/2,C=A+E/2,F=z-Math.sqrt(E*3/2);B.beginPath();B.moveTo(D,F);B.lineTo(C,F);B.lineTo(A,z);B.lineTo(D,F);B.strokeStyle=this.fillStyle;B.fill();B.stroke();B.closePath()};var e=function(z){this.default_val=(z?z:1)};e.prototype.gen_val=function(z){return this.default_val};var n=function(B,D,z,A,C){this.data=B;this.view_start=D;this.view_end=z;this.prefs=v({},this.default_prefs,A);this.mode=C};n.prototype.default_prefs={};var w=function(B,D,z,A,C){n.call(this,B,D,z,A,C)};w.prototype.default_prefs={show_counts:false};w.prototype.draw=function(M,z,L){var E=this.view_start,O=this.view_end-this.view_start,N=z/O;var J=this.data.data,I=this.data.delta,G=this.data.max,B=L;delta_x_px=Math.ceil(I*N);M.save();for(var C=0,D=J.length;C<D;C++){var H=Math.floor((J[C][0]-E)*N);var F=J[C][1];if(!F){continue}var K=F/G*L;if(F!==0&&K<1){K=1}M.fillStyle=this.prefs.block_color;M.fillRect(H,B-K,delta_x_px,K);var A=4;if(this.prefs.show_counts&&(M.measureText(F).width+A)<delta_x_px){M.fillStyle=this.prefs.label_color;M.textAlign="center";M.fillText(F,H+(delta_x_px/2),10)}}M.restore()};var c=function(z,D,F,G,B){n.call(this,z,D,F,G,B);if(this.prefs.min_value===undefined){var H=Infinity;for(var A=0,C=this.data.length;A<C;A++){H=Math.min(H,this.data[A][1])}this.prefs.min_value=H}if(this.prefs.max_value===undefined){var E=-Infinity;for(var A=0,C=this.data.length;A<C;A++){E=Math.max(E,this.data[A][1])}this.prefs.max_value=E}};c.prototype.default_prefs={min_value:undefined,max_value:undefined,mode:"Histogram",color:"#000",overflow_color:"#F66"};c.prototype.draw=function(N,M,K){var F=false,H=this.prefs.min_value,D=this.prefs.max_value,J=D-H,z=K,A=this.view_start,L=this.view_end-this.view_start,B=M/L,I=this.mode,T=this.data;N.save();var U=Math.round(K+H/J*K);if(I!=="Intensity"){N.fillStyle="#aaa";N.fillRect(0,U,M,1)}N.beginPath();var R,E,C;if(T.length>1){C=Math.ceil((T[1][0]-T[0][0])*B)}else{C=10}for(var O=0,P=T.length;O<P;O++){N.fillStyle=this.prefs.color;R=Math.round((T[O][0]-A)*B);E=T[O][1];var Q=false,G=false;if(E===null){if(F&&I==="Filled"){N.lineTo(R,z)}F=false;continue}if(E<H){G=true;E=H}else{if(E>D){Q=true;E=D}}if(I==="Histogram"){E=Math.round(E/J*z);N.fillRect(R,U,C,-E)}else{if(I==="Intensity"){E=255-Math.floor((E-H)/J*255);N.fillStyle="rgb("+E+","+E+","+E+")";N.fillRect(R,0,C,z)}else{E=Math.round(z-(E-H)/J*z);if(F){N.lineTo(R,E)}else{F=true;if(I==="Filled"){N.moveTo(R,z);N.lineTo(R,E)}else{N.moveTo(R,E)}}}}N.fillStyle=this.prefs.overflow_color;if(Q||G){var S;if(I==="Histogram"||I==="Intensity"){S=C}else{R-=2;S=4}if(Q){N.fillRect(R,0,S,3)}if(G){N.fillRect(R,z-3,S,3)}}N.fillStyle=this.prefs.color}if(I==="Filled"){if(F){N.lineTo(R,U);N.lineTo(0,U)}N.fill()}else{N.stroke()}N.restore()};var o=function(z){this.feature_positions={};this.slot_height=z;this.translation=0};o.prototype.map_feature_data=function(A,C,z,B){if(!this.feature_positions[C]){this.feature_positions[C]=[]}this.feature_positions[C].push({data:A,x_start:z,x_end:B})};o.prototype.get_feature_data=function(z,D){var C=Math.floor(D/this.slot_height),B;if(!this.feature_positions[C]){return null}z+=this.translation;for(var A=0;A<this.feature_positions[C].length;A++){B=this.feature_positions[C][A];if(z>=B.x_start&&z<=B.x_end){return B.data}}};var p=function(B,E,z,A,D,F,C){n.call(this,B,E,z,A,D);this.alpha_scaler=(F?F:new e());this.height_scaler=(C?C:new e())};p.prototype.default_prefs={block_color:"#FFF",connector_color:"#FFF"};v(p.prototype,{get_required_height:function(A){var z=y_scale=this.get_row_height(),B=this.mode;if(B==="no_detail"||B==="Squish"||B==="Pack"){z=A*y_scale}return z+Math.max(Math.round(y_scale/2),5)},draw:function(L,J,H,G){var R=this.data,E=this.view_start,N=this.view_end;L.save();L.fillStyle=this.prefs.block_color;L.textAlign="right";var I=this.view_end-this.view_start,F=J/I,M=this.get_row_height(),Q=new o(M),C;for(var O=0,P=R.length;O<P;O++){var B=R[O],D=B[0],K=B[1],z=B[2],A=(G&&G[D]!==undefined?G[D]:null);if((K<N&&z>E)&&(this.mode=="Dense"||A!==null)){C=this.draw_element(L,this.mode,B,A,E,N,F,M,J);Q.map_feature_data(B,A,C[0],C[1])}}L.restore();return Q},draw_element:function(F,B,H,D,C,E,G,A,z){console.log("WARNING: Unimplemented function.");return[0,0]}});var d=10,j=3,m=5,x=10,g=1,t=3,f=3,a=9,l=2,h="#ccc";var s=function(B,E,z,A,D,F,C){p.call(this,B,E,z,A,D,F,C)};v(s.prototype,p.prototype,{get_row_height:function(){var A=this.mode,z;if(A==="Dense"){z=d}else{if(A==="no_detail"){z=j}else{if(A==="Squish"){z=m}else{z=x}}}return z},draw_element:function(N,E,W,I,P,ah,al,an,z){var T=W[0],aj=W[1],ab=W[2],R=W[3],ac=Math.floor(Math.max(0,(aj-P)*al)),O=Math.ceil(Math.min(z,Math.max(0,(ab-P)*al))),aa=ac,am=O,Z=(E==="Dense"?0:(0+I))*an,M,af,S=null,ap=null,C=this.prefs.block_color,ae=this.prefs.label_color;N.globalAlpha=this.alpha_scaler.gen_val(W);if(E=="Dense"){I=1}if(E==="no_detail"){N.fillStyle=C;N.fillRect(ac,Z+5,O-ac,g)}else{var L=W[4],Y=W[5],ad=W[6],D=W[7];if(Y&&ad){S=Math.floor(Math.max(0,(Y-P)*al));ap=Math.ceil(Math.min(z,Math.max(0,(ad-P)*al)))}var ak,U;if(E==="Squish"||E==="Dense"){ak=1;U=f}else{ak=5;U=a}if(!D){if(W.strand){if(W.strand==="+"){N.fillStyle=N.canvas.manager.get_pattern("right_strand_inv")}else{if(W.strand==="-"){N.fillStyle=N.canvas.manager.get_pattern("left_strand_inv")}}}else{N.fillStyle=C}N.fillRect(ac,Z,O-ac,U)}else{var K,V;if(E==="Squish"||E==="Dense"){N.fillStyle=h;K=Z+Math.floor(f/2)+1;V=1}else{if(L){var K=Z;var V=U;if(L==="+"){N.fillStyle=N.canvas.manager.get_pattern("right_strand")}else{if(L==="-"){N.fillStyle=N.canvas.manager.get_pattern("left_strand")}}}else{N.fillStyle=h;K+=(f/2)+1;V=1}}N.fillRect(ac,K,O-ac,V);var F;for(var ai=0,B=D.length;ai<B;ai++){var G=D[ai],A=Math.floor(Math.max(0,(G[0]-P)*al)),X=Math.ceil(Math.min(z,Math.max((G[1]-P)*al)));if(A>X){continue}N.fillStyle=C;N.fillRect(A,Z+(U-ak)/2+1,X-A,ak);if(S!==undefined&&ad>Y&&!(A>ap||X<S)){var ag=Math.max(A,S),J=Math.min(X,ap);N.fillRect(ag,Z+1,J-ag,U);if(D.length==1&&E=="Pack"){if(L==="+"){N.fillStyle=N.canvas.manager.get_pattern("right_strand_inv")}else{if(L==="-"){N.fillStyle=N.canvas.manager.get_pattern("left_strand_inv")}}if(ag+14<J){ag+=2;J-=2}N.fillRect(ag,Z+1,J-ag,U)}}}if(E==="Pack"){N.globalAlpha=1;N.fillStyle="white";var H=this.height_scaler.gen_val(W),Q=Math.ceil(U*H),ao=Math.round((U-Q)/2);if(H!==1){N.fillRect(ac,K+1,O-ac,ao);N.fillRect(ac,K+U-ao+1,O-ac,ao)}}}N.globalAlpha=1;if(E==="Pack"&&aj>P){N.fillStyle=ae;if(P===0&&ac-N.measureText(R).width<0){N.textAlign="left";N.fillText(R,O+l,Z+8);am+=N.measureText(R).width+l}else{N.textAlign="right";N.fillText(R,ac-l,Z+8);aa-=N.measureText(R).width+l}}}N.globalAlpha=1;return[aa,am]}});var b=function(B,E,z,A,D,F,C){p.call(this,B,E,z,A,D,F,C)};v(b.prototype,p.prototype,{draw_element:function(S,N,H,D,V,B,K,T,Q){var H=data[i],J=H[0],R=H[1],C=H[2],M=H[3],F=Math.floor(Math.max(0,(R-V)*K)),I=Math.ceil(Math.min(Q,Math.max(0,(C-V)*K))),E=(N==="Dense"?0:(0+D))*T,z,W,A=null,L=null;if(no_label){S.fillStyle=block_color;S.fillRect(F+left_offset,E+5,I-F,1)}else{var U=H[4],P=H[5],G=H[6];z=9;W=1;S.fillRect(F+left_offset,E,I-F,z);if(N!=="Dense"&&M!==undefined&&R>V){S.fillStyle=label_color;if(V===0&&F-S.measureText(M).width<0){S.textAlign="left";S.fillText(M,I+2+left_offset,E+8)}else{S.textAlign="right";S.fillText(M,F-2+left_offset,E+8)}S.fillStyle=block_color}var O=U+" / "+P;if(R>V&&S.measureText(O).width<(I-F)){S.fillStyle="white";S.textAlign="center";S.fillText(O,left_offset+F+(I-F)/2,E+8);S.fillStyle=block_color}}return[F,I]}});var u=function(C,F,z,B,E,G,D,A){p.call(this,C,F,z,B,E,G,D);this.ref_seq=(A?A.data:null)};u.prototype.default_prefs=v({},p.prototype.default_prefs,{show_insertions:false});v(u.prototype,p.prototype,{get_row_height:function(){var z,A=this.mode;if(A==="Dense"){z=d}else{if(A==="Squish"){z=m}else{z=x;if(this.prefs.show_insertions){z*=2}}}return z},draw_read:function(W,R,N,ab,C,V,K,H,G){W.textAlign="center";var U=this,B=[ab,C],Q=0,X=0,T=0,z=W.canvas.manager.char_width_px;var ag=[];if((R==="Pack"||this.mode==="Auto")&&H!==undefined&&N>z){T=Math.round(N/2)}if(!K){K=[[0,H.length]]}for(var O=0,Z=K.length;O<Z;O++){var L=K[O],D="MIDNSHP=X"[L[0]],P=L[1];if(D==="H"||D==="S"){Q-=P}var I=V+Q,af=Math.floor(Math.max(0,(I-ab)*N)),J=Math.floor(Math.max(0,(I+P-ab)*N));if(af===J){J+=1}switch(D){case"H":break;case"S":case"M":case"=":if(is_overlap([I,I+P],B)){var S=H.slice(X,X+P);if(T>0){W.fillStyle=this.prefs.block_color;W.fillRect(af-T,G+1,J-af,9);W.fillStyle=h;for(var ad=0,A=S.length;ad<A;ad++){if(this.prefs.show_differences&&this.ref_seq){var M=this.ref_seq[I-ab+ad];if(!M||M.toLowerCase()===S[ad].toLowerCase()){continue}}if(I+ad>=ab&&I+ad<=C){var ae=Math.floor(Math.max(0,(I+ad-ab)*N));W.fillText(S[ad],ae,G+9)}}}else{W.fillStyle=this.prefs.block_color;W.fillRect(af,G+4,J-af,f)}}X+=P;Q+=P;break;case"N":W.fillStyle=h;W.fillRect(af-T,G+5,J-af,1);Q+=P;break;case"D":W.fillStyle="red";W.fillRect(af-T,G+4,J-af,3);Q+=P;break;case"P":break;case"I":var aa=af-T;if(is_overlap([I,I+P],B)){var S=H.slice(X,X+P);if(this.prefs.show_insertions){var F=af-(J-af)/2;if((R==="Pack"||this.mode==="Auto")&&H!==undefined&&N>z){W.fillStyle="yellow";W.fillRect(F-T,G-9,J-af,9);ag[ag.length]={type:"triangle",data:[aa,G+4,5]};W.fillStyle=h;switch(seq_tile_overlap){case (OVERLAP_START):S=S.slice(ab-I);break;case (OVERLAP_END):S=S.slice(0,I-C);break;case (CONTAINED_BY):break;case (CONTAINS):S=S.slice(ab-I,I-C);break}for(var ad=0,A=S.length;ad<A;ad++){var ae=Math.floor(Math.max(0,(I+ad-ab)*N));W.fillText(S[ad],ae-(J-af)/2,G)}}else{W.fillStyle="yellow";W.fillRect(F,G+(this.mode!=="Dense"?2:5),J-af,(R!=="Dense"?f:t))}}else{if((R==="Pack"||this.mode==="Auto")&&H!==undefined&&N>z){ag[ag.length]={type:"text",data:[S.length,aa,G+9]}}else{}}}X+=P;break;case"X":X+=P;break}}W.fillStyle="yellow";var ac,E,ah;for(var Y=0;Y<ag.length;Y++){ac=ag[Y];E=ac.type;ah=ac.data;if(E==="text"){W.save();W.font="bold "+W.font;W.fillText(ah[0],ah[1],ah[2]);W.restore()}else{if(E=="triangle"){r(W,ah[0],ah[1],ah[2])}}}},draw_element:function(S,N,F,C,V,A,J,T,Q){var I=F[0],R=F[1],B=F[2],K=F[3],E=Math.floor(Math.max(0,(R-V)*J)),G=Math.ceil(Math.min(Q,Math.max(0,(B-V)*J))),D=(N==="Dense"?0:(0+C))*T,W=this.prefs.block_color,H=this.prefs.label_color,P=0;if((N==="Pack"||this.mode==="Auto")&&J>S.canvas.manager.char_width_px){var P=Math.round(J/2)}S.fillStyle=W;if(F[5] instanceof Array){var O=Math.floor(Math.max(0,(F[4][0]-V)*J)),M=Math.ceil(Math.min(Q,Math.max(0,(F[4][1]-V)*J))),L=Math.floor(Math.max(0,(F[5][0]-V)*J)),z=Math.ceil(Math.min(Q,Math.max(0,(F[5][1]-V)*J)));if(F[4][1]>=V&&F[4][0]<=A&&F[4][2]){this.draw_read(S,N,J,V,A,F[4][0],F[4][2],F[4][3],D)}if(F[5][1]>=V&&F[5][0]<=A&&F[5][2]){this.draw_read(S,N,J,V,A,F[5][0],F[5][2],F[5][3],D)}if(L>M){S.fillStyle=h;q(S,M-P,D+5,L-P,D+5)}}else{S.fillStyle=W;this.draw_read(S,N,J,V,A,R,F[4],F[5],D)}if(N==="Pack"&&R>V){S.fillStyle=this.prefs.label_color;var U=1;if(U===0&&E-S.measureText(K).width<0){S.textAlign="left";S.fillText(K,G+l-P,D+8)}else{S.textAlign="right";S.fillText(K,E-l-P,D+8)}S.fillStyle=W}return[0,0]}});y.Scaler=e;y.SummaryTreePainter=w;y.LinePainter=c;y.LinkedFeaturePainter=s;y.ReadPainter=u;y.VariantPainter=b};(function(d){var c={};var b=function(e){return c[e]};var a=function(f,g){var e={};g(b,e);c[f]=e};a("class",class_module);a("slotting",slotting_module);a("painters",painters_module);a("trackster",trackster_module);for(key in c.trackster){d[key]=c.trackster[key]}})(window); \ No newline at end of file +var class_module=function(b,a){var c=function(){var f=arguments[0];for(var e=1;e<arguments.length;e++){var d=arguments[e];for(key in d){f[key]=d[key]}}return f};a.extend=c};var requestAnimationFrame=(function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(b,a){window.setTimeout(b,1000/60)}})();var BEFORE=1001,CONTAINS=1002,OVERLAP_START=1003,OVERLAP_END=1004,CONTAINED_BY=1005,AFTER=1006;var compute_overlap=function(e,b){var g=e[0],f=e[1],d=b[0],c=b[1],a;if(g<d){if(f<d){a=BEFORE}else{if(f<=c){a=OVERLAP_START}else{a=CONTAINS}}}else{if(g>c){a=AFTER}else{if(f<=c){a=CONTAINED_BY}else{a=OVERLAP_END}}}return a};var is_overlap=function(c,b){var a=compute_overlap(c,b);return(a!==BEFORE&&a!==AFTER)};var get_random_color=function(a){if(!a){a="#ffffff"}if(typeof(a)==="string"){a=[a]}for(var j=0;j<a.length;j++){a[j]=parseInt(a[j].slice(1),16)}var m=function(t,s,i){return((t*299)+(s*587)+(i*114))/1000};var e=function(u,t,v,r,i,s){return(Math.max(u,r)-Math.min(u,r))+(Math.max(t,i)-Math.min(t,i))+(Math.max(v,s)-Math.min(v,s))};var g,n,f,k,p,h,q,c,d,b,o,l=false;do{g=Math.random()*16777215;n=g|16711680;f=g|65280;k=g|255;d=m(n,f,k);l=true;for(var j=0;j<a.length;j++){p=a[j];h=p|16711680;q=p|65280;c=p|255;b=m(h,q,c);o=e(n,f,k,h,q,c);if((Math.abs(d-b)<125)||(o<500)){l=false;break}}}while(!l);return"#"+(16777216+g).toString(16).substr(1,6)};var trackster_module=function(f,X){var p=f("class").extend,s=f("slotting"),M=f("painters");var ae=function(af,ag){this.document=af;this.default_font=ag!==undefined?ag:"9px Monaco, Lucida Console, monospace";this.dummy_canvas=this.new_canvas();this.dummy_context=this.dummy_canvas.getContext("2d");this.dummy_context.font=this.default_font;this.char_width_px=this.dummy_context.measureText("A").width;this.patterns={};this.load_pattern("right_strand","/visualization/strand_right.png");this.load_pattern("left_strand","/visualization/strand_left.png");this.load_pattern("right_strand_inv","/visualization/strand_right_inv.png");this.load_pattern("left_strand_inv","/visualization/strand_left_inv.png")};p(ae.prototype,{load_pattern:function(af,aj){var ag=this.patterns,ah=this.dummy_context,ai=new Image();ai.src=image_path+aj;ai.onload=function(){ag[af]=ah.createPattern(ai,"repeat")}},get_pattern:function(af){return this.patterns[af]},new_canvas:function(){var af=this.document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(af)}af.manager=this;return af}});var n={};var l=function(af,ag){n[af.attr("id")]=ag};var m=function(af,ah,aj,ai){aj=".group";var ag={};n[af.attr("id")]=ai;af.bind("drag",{handle:"."+ah,relative:true},function(ar,at){var aq=$(this);var aw=$(this).parent(),an=aw.children(),ap=n[$(this).attr("id")],am,al,au,ak,ao;al=$(this).parents(aj);if(al.length!==0){au=al.position().top;ak=au+al.outerHeight();if(at.offsetY<au){$(this).insertBefore(al);var av=n[al.attr("id")];av.remove_drawable(ap);av.container.add_drawable_before(ap,av);return}else{if(at.offsetY>ak){$(this).insertAfter(al);var av=n[al.attr("id")];av.remove_drawable(ap);av.container.add_drawable(ap);return}}}al=null;for(ao=0;ao<an.length;ao++){am=$(an.get(ao));au=am.position().top;ak=au+am.outerHeight();if(am.is(aj)&&this!==am.get(0)&&at.offsetY>=au&&at.offsetY<=ak){if(at.offsetY-au<ak-at.offsetY){am.find(".content-div").prepend(this)}else{am.find(".content-div").append(this)}if(ap.container){ap.container.remove_drawable(ap)}n[am.attr("id")].add_drawable(ap);return}}for(ao=0;ao<an.length;ao++){if(at.offsetY<$(an.get(ao)).position().top){break}}if(ao===an.length){if(this!==an.get(ao-1)){aw.append(this);n[aw.attr("id")].move_drawable(ap,ao)}}else{if(this!==an.get(ao)){$(this).insertBefore(an.get(ao));n[aw.attr("id")].move_drawable(ap,(at.deltaY>0?ao-1:ao))}}}).bind("dragstart",function(){ag["border-top"]=af.css("border-top");ag["border-bottom"]=af.css("border-bottom");$(this).css({"border-top":"1px solid blue","border-bottom":"1px solid blue"})}).bind("dragend",function(){$(this).css(ag)})};X.moveable=m;var ad=16,H=9,E=20,T=H+2,z=100,J=12000,R=200,C=5,v=10,L=5000,w=100,o="There was an error in indexing this dataset. ",K="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",F="No data for this chrom/contig.",t="Currently indexing... please wait",x="Tool cannot be rerun: ",a="Loading data...",Y="Ready for display",d=10,u=5,B=5;function Z(ag,af){if(!af){af=0}var ah=Math.pow(10,af);return Math.round(ag*ah)/ah}var c=function(af){this.num_elements=af;this.clear()};p(c.prototype,{get:function(ag){var af=this.key_ary.indexOf(ag);if(af!==-1){if(this.obj_cache[ag].stale){this.key_ary.splice(af,1);delete this.obj_cache[ag]}else{this.move_key_to_end(ag,af)}}return this.obj_cache[ag]},set:function(ag,ah){if(!this.obj_cache[ag]){if(this.key_ary.length>=this.num_elements){var af=this.key_ary.shift();delete this.obj_cache[af]}this.key_ary.push(ag)}this.obj_cache[ag]=ah;return ah},move_key_to_end:function(ag,af){this.key_ary.splice(af,1);this.key_ary.push(ag)},clear:function(){this.obj_cache={};this.key_ary=[]},size:function(){return this.key_ary.length}});var S=function(ag,af,ah){c.call(this,ag);this.track=af;this.subset=(ah!==undefined?ah:true)};p(S.prototype,c.prototype,{load_data:function(ao,aj,am,ag,al){var an=this.track.view.chrom,ai={chrom:an,low:ao,high:aj,mode:am,resolution:ag,dataset_id:this.track.dataset_id,hda_ldda:this.track.hda_ldda};$.extend(ai,al);if(this.track.filters_manager){var ap=[];var af=this.track.filters_manager.filters;for(var ak=0;ak<af.length;ak++){ap[ap.length]=af[ak].name}ai.filter_cols=JSON.stringify(ap)}var ah=this;return $.getJSON(this.track.data_url,ai,function(aq){ah.set_data(ao,aj,am,aq)})},get_data:function(af,aj,ak,ag,ai){var ah=this.get_data_from_cache(af,aj,ak);if(ah){return ah}ah=this.load_data(af,aj,ak,ag,ai);this.set_data(af,aj,ak,ah);return ah},DEEP_DATA_REQ:"deep",BROAD_DATA_REQ:"breadth",get_more_data:function(an,ai,am,ah,al,aj){var ao=this.get_data_from_cache(an,ai,am);if(!ao){console.log("ERROR: no current data for: ",this.track,an,ai,am,ah,al);return}ao.stale=true;var ag=an;if(aj===this.DEEP_DATA_REQ){$.extend(al,{start_val:ao.data.length+1})}else{if(aj===this.BROAD_DATA_REQ){ag=(ao.max_high?ao.max_high:ao.data[ao.data.length-1][2])+1}}var af=this,ak=this.load_data(ag,ai,am,ah,al);new_data_available=$.Deferred();this.set_data(an,ai,am,new_data_available);$.when(ak).then(function(ap){if(ap.data){ap.data=ao.data.concat(ap.data);if(ap.max_low){ap.max_low=ao.max_low}if(ap.message){ap.message=ap.message.replace(/[0-9]+/,ap.data.length)}}af.set_data(an,ai,am,ap);new_data_available.resolve(ap)});return new_data_available},get_data_from_cache:function(af,ag,ah){return this.get(this.gen_key(af,ag,ah))},set_data:function(ag,ah,ai,af){return this.set(this.gen_key(ag,ah,ai),af)},gen_key:function(af,ah,ai){var ag=af+"_"+ah+"_"+ai;return ag},split_key:function(af){return af.split("_")}});var I=function(ag,af,ah){S.call(this,ag,af,ah)};p(I.prototype,S.prototype,c.prototype,{load_data:function(af,ai,aj,ag,ah){if(ag>1){return{data:null}}return S.prototype.load_data.call(this,af,ai,aj,ag,ah)}});var q=function(ai,ag,af,ah,aj){this.name=ai;this.view=ag;this.container=af;this.config=new G({track:this,params:[{key:"name",label:"Name",type:"text",default_value:ai}],saved_values:ah,onchange:function(){this.track.set_name(this.track.config.values.name)}});this.prefs=this.config.values;this.drag_handle_class=aj;this.is_overview=false};p(q.prototype,{init:function(){},request_draw:function(){},_draw:function(){},to_json:function(){},update_track_icons:function(){},set_name:function(af){this.old_name=this.name;this.name=af;this.name_div.text(this.name)},revert_name:function(){this.name=this.old_name;this.name_div.text(this.name)},remove:function(){this.container.remove_drawable(this);this.container_div.fadeOut("slow",function(){$(this).remove();view.update_intro_div();view.has_changes=true})}});var y=function(aj,ai,ag,af,ah,ak){q.call(this,ai,ag,af,ah,ak);this.obj_type=aj;this.drawables=[]};p(y.prototype,q.prototype,{init:function(){for(var af=0;af<this.drawables.length;af++){this.drawables[af].init()}},_draw:function(){for(var af=0;af<this.drawables.length;af++){this.drawables[af]._draw()}},to_json:function(){var ag=[];for(var af=0;af<this.drawables.length;af++){ag.push(this.drawables[af].to_json())}return{name:this.name,prefs:this.prefs,obj_type:this.obj_type,drawables:ag}},add_drawable:function(af){this.drawables.push(af);af.container=this},add_drawable_before:function(ah,af){var ag=this.drawables.indexOf(af);if(ag!=-1){this.drawables.splice(ag,0,ah);return true}return false},remove_drawable:function(ag){var af=this.drawables.indexOf(ag);if(af!=-1){this.drawables.splice(af,1);ag.container=null;return true}return false},move_drawable:function(ag,ah){var af=this.drawables.indexOf(ag);if(af!=-1){this.drawables.splice(af,1);this.drawables.splice(ah,0,ag);return true}return false}});var Q=function(ai,ag,af,ah){y.call(this,"DrawableGroup",ai,ag,af,ah,"group-handle");if(!Q.id_counter){Q.id_counter=0}var aj=Q.id_counter++;this.container_div=$("<div/>").addClass("group").attr("id","group_"+aj).appendTo(this.container.content_div);this.header_div=$("<div/>").addClass("track-header").appendTo(this.container_div);this.header_div.append($("<div/>").addClass(this.drag_handle_class));this.name_div=$("<div/>").addClass("group-name menubutton popup").text(this.name).appendTo(this.header_div);this.content_div=$("<div/>").addClass("content-div").attr("id","group_"+aj+"_content_div").appendTo(this.container_div);l(this.container_div,this);l(this.content_div,this);m(this.container_div,this.drag_handle_class,".group",this);this.update_track_icons()};p(Q.prototype,q.prototype,y.prototype,{update_track_icons:function(){var ag=this;var af={};af["Edit configuration"]=function(){var aj=function(){hide_modal();$(window).unbind("keypress.check_enter_esc")},ah=function(){ag.config.update_from_form($(".dialog-box"));hide_modal();$(window).unbind("keypress.check_enter_esc")},ai=function(ak){if((ak.keyCode||ak.which)===27){aj()}else{if((ak.keyCode||ak.which)===13){ah()}}};$(window).bind("keypress.check_enter_esc",ai);show_modal("Configure Group",ag.config.build_form(),{Cancel:aj,OK:ah})};af.Remove=function(){ag.remove()};make_popupmenu(ag.name_div,af)}});var ac=function(af,ai,ah,ag){y.call(this,"View");this.container=af;this.chrom=null;this.vis_id=ah;this.dbkey=ag;this.title=ai;this.label_tracks=[];this.tracks_to_be_redrawn=[];this.max_low=0;this.max_high=0;this.zoom_factor=3;this.min_separation=30;this.has_changes=false;this.load_chroms_deferred=null;this.init();this.canvas_manager=new ae(af.get(0).ownerDocument);this.reset()};p(ac.prototype,y.prototype,{init:function(){var ah=this.container,af=this;this.top_container=$("<div/>").addClass("top-container").appendTo(ah);this.browser_content_div=$("<div/>").addClass("content").css("position","relative").appendTo(ah);this.bottom_container=$("<div/>").addClass("bottom-container").appendTo(ah);this.top_labeltrack=$("<div/>").addClass("top-labeltrack").appendTo(this.top_container);this.viewport_container=$("<div/>").addClass("viewport-container").attr("id","viewport-container").appendTo(this.browser_content_div);this.content_div=this.viewport_container;l(this.viewport_container,af);this.intro_div=$("<div/>").addClass("intro");var ai=$("<div/>").text("Add Datasets to Visualization").addClass("action-button").appendTo(this.intro_div).click(function(){add_tracks()});this.nav_labeltrack=$("<div/>").addClass("nav-labeltrack").appendTo(this.bottom_container);this.nav_container=$("<div/>").addClass("nav-container").prependTo(this.top_container);this.nav=$("<div/>").addClass("nav").appendTo(this.nav_container);this.overview=$("<div/>").addClass("overview").appendTo(this.bottom_container);this.overview_viewport=$("<div/>").addClass("overview-viewport").appendTo(this.overview);this.overview_close=$("<a/>").attr("href","javascript:void(0);").attr("title","Close overview").addClass("icon-button overview-close tooltip").hide().appendTo(this.overview_viewport);this.overview_highlight=$("<div/>").addClass("overview-highlight").hide().appendTo(this.overview_viewport);this.overview_box_background=$("<div/>").addClass("overview-boxback").appendTo(this.overview_viewport);this.overview_box=$("<div/>").addClass("overview-box").appendTo(this.overview_viewport);this.default_overview_height=this.overview_box.height();this.nav_controls=$("<div/>").addClass("nav-controls").appendTo(this.nav);this.chrom_select=$("<select/>").attr({name:"chrom"}).css("width","15em").addClass("no-autocomplete").append("<option value=''>Loading</option>").appendTo(this.nav_controls);var ag=function(aj){if(aj.type==="focusout"||(aj.keyCode||aj.which)===13||(aj.keyCode||aj.which)===27){if((aj.keyCode||aj.which)!==27){af.go_to($(this).val())}$(this).hide();$(this).val("");af.location_span.show();af.chrom_select.show()}};this.nav_input=$("<input/>").addClass("nav-input").hide().bind("keyup focusout",ag).appendTo(this.nav_controls);this.location_span=$("<span/>").addClass("location").appendTo(this.nav_controls);this.location_span.click(function(){af.location_span.hide();af.chrom_select.hide();af.nav_input.val(af.chrom+":"+af.low+"-"+af.high);af.nav_input.css("display","inline-block");af.nav_input.select();af.nav_input.focus()});if(this.vis_id!==undefined){this.hidden_input=$("<input/>").attr("type","hidden").val(this.vis_id).appendTo(this.nav_controls)}this.zo_link=$("<a id='zoom-out' />").click(function(){af.zoom_out();af.request_redraw()}).appendTo(this.nav_controls);this.zi_link=$("<a id='zoom-in' />").click(function(){af.zoom_in();af.request_redraw()}).appendTo(this.nav_controls);this.load_chroms_deferred=this.load_chroms({low:0});this.chrom_select.bind("change",function(){af.change_chrom(af.chrom_select.val())});this.browser_content_div.click(function(aj){$(this).find("input").trigger("blur")});this.browser_content_div.bind("dblclick",function(aj){af.zoom_in(aj.pageX,this.viewport_container)});this.overview_box.bind("dragstart",function(aj,ak){this.current_x=ak.offsetX}).bind("drag",function(aj,al){var am=al.offsetX-this.current_x;this.current_x=al.offsetX;var ak=Math.round(am/af.viewport_container.width()*(af.max_high-af.max_low));af.move_delta(-ak)});this.overview_close.click(function(){af.reset_overview()});this.viewport_container.bind("draginit",function(aj,ak){if(aj.clientX>af.viewport_container.width()-16){return false}}).bind("dragstart",function(aj,ak){ak.original_low=af.low;ak.current_height=aj.clientY;ak.current_x=ak.offsetX}).bind("drag",function(al,an){var aj=$(this);var ao=an.offsetX-an.current_x;var ak=aj.scrollTop()-(al.clientY-an.current_height);aj.scrollTop(ak);an.current_height=al.clientY;an.current_x=an.offsetX;var am=Math.round(ao/af.viewport_container.width()*(af.high-af.low));af.move_delta(am)}).bind("mousewheel",function(al,an,ak,aj){if(ak){var am=Math.round(-ak/af.viewport_container.width()*(af.high-af.low));af.move_delta(am)}});this.top_labeltrack.bind("dragstart",function(aj,ak){return $("<div />").css({height:af.browser_content_div.height()+af.top_labeltrack.height()+af.nav_labeltrack.height()+1,top:"0px",position:"absolute","background-color":"#ccf",opacity:0.5,"z-index":1000}).appendTo($(this))}).bind("drag",function(an,ao){$(ao.proxy).css({left:Math.min(an.pageX,ao.startX),width:Math.abs(an.pageX-ao.startX)});var ak=Math.min(an.pageX,ao.startX)-af.container.offset().left,aj=Math.max(an.pageX,ao.startX)-af.container.offset().left,am=(af.high-af.low),al=af.viewport_container.width();af.update_location(Math.round(ak/al*am)+af.low,Math.round(aj/al*am)+af.low)}).bind("dragend",function(ao,ap){var ak=Math.min(ao.pageX,ap.startX),aj=Math.max(ao.pageX,ap.startX),am=(af.high-af.low),al=af.viewport_container.width(),an=af.low;af.low=Math.round(ak/al*am)+an;af.high=Math.round(aj/al*am)+an;$(ap.proxy).remove();af.request_redraw()});this.add_label_track(new ab(this,{content_div:this.top_labeltrack}));this.add_label_track(new ab(this,{content_div:this.nav_labeltrack}));$(window).bind("resize",function(){af.resize_window()});$(document).bind("redraw",function(){af.redraw()});this.reset();$(window).trigger("resize");this.update_intro_div()},update_intro_div:function(){if(this.num_tracks===0){this.intro_div.appendTo(this.viewport_container)}else{this.intro_div.remove()}},update_location:function(af,ag){this.location_span.text(commatize(af)+" - "+commatize(ag));this.nav_input.val(this.chrom+":"+commatize(af)+"-"+commatize(ag))},load_chroms:function(ah){ah.num=w;$.extend(ah,(this.vis_id!==undefined?{vis_id:this.vis_id}:{dbkey:this.dbkey}));var af=this,ag=$.Deferred();$.ajax({url:chrom_url,data:ah,dataType:"json",success:function(aj){if(aj.chrom_info.length===0){alert("Invalid chromosome: "+ah.chrom);return}if(aj.reference){af.add_label_track(new A(af))}af.chrom_data=aj.chrom_info;var am='<option value="">Select Chrom/Contig</option>';for(var al=0,ai=af.chrom_data.length;al<ai;al++){var ak=af.chrom_data[al].chrom;am+='<option value="'+ak+'">'+ak+"</option>"}if(aj.prev_chroms){am+='<option value="previous">Previous '+w+"</option>"}if(aj.next_chroms){am+='<option value="next">Next '+w+"</option>"}af.chrom_select.html(am);af.chrom_start_index=aj.start_index;ag.resolve(aj)},error:function(){alert("Could not load chroms for this dbkey:",af.dbkey)}});return ag},change_chrom:function(ak,ag,am){if(!ak||ak==="None"){return}var ah=this;if(ak==="previous"){ah.load_chroms({low:this.chrom_start_index-w});return}if(ak==="next"){ah.load_chroms({low:this.chrom_start_index+w});return}var al=$.grep(ah.chrom_data,function(an,ao){return an.chrom===ak})[0];if(al===undefined){ah.load_chroms({chrom:ak},function(){ah.change_chrom(ak,ag,am)});return}else{if(ak!==ah.chrom){ah.chrom=ak;ah.chrom_select.val(ah.chrom);ah.max_high=al.len-1;ah.reset();ah.request_redraw(true);for(var aj=0,af=ah.drawables.length;aj<af;aj++){var ai=ah.drawables[aj];if(ai.init){ai.init()}}}if(ag!==undefined&&am!==undefined){ah.low=Math.max(ag,0);ah.high=Math.min(am,ah.max_high)}ah.reset_overview();ah.request_redraw()}},go_to:function(aj){aj=aj.replace(/ |,/g,"");var an=this,af,ai,ag=aj.split(":"),al=ag[0],am=ag[1];if(am!==undefined){try{var ak=am.split("-");af=parseInt(ak[0],10);ai=parseInt(ak[1],10)}catch(ah){return false}}an.change_chrom(al,af,ai)},move_fraction:function(ah){var af=this;var ag=af.high-af.low;this.move_delta(ah*ag)},move_delta:function(ah){var af=this;var ag=af.high-af.low;if(af.low-ah<af.max_low){af.low=af.max_low;af.high=af.max_low+ag}else{if(af.high-ah>af.max_high){af.high=af.max_high;af.low=af.max_high-ag}else{af.high-=ah;af.low-=ah}}af.request_redraw()},add_drawable:function(af){y.prototype.add_drawable.call(this,af);af.init();this.has_changes=true;this.update_intro_div()},add_label_track:function(af){af.view=this;af.init();this.label_tracks.push(af)},remove_drawable:function(ah,ag){y.prototype.remove_drawable.call(this,ah);if(ag){var af=this;ah.container_div.fadeOut("slow",function(){$(this).remove();af.update_intro_div()});this.has_changes=true}},reset:function(){this.low=this.max_low;this.high=this.max_high;this.viewport_container.find(".yaxislabel").remove()},request_redraw:function(an,af,am,ag){var al=this,aj=(ag?[ag]:al.drawables),ah;var ag;for(var ak=0;ak<aj.length;ak++){ag=aj[ak];ah=-1;for(var ai=0;ai<al.tracks_to_be_redrawn.length;ai++){if(al.tracks_to_be_redrawn[ai][0]===ag){ah=ai;break}}if(ah<0){al.tracks_to_be_redrawn.push([ag,af,am])}else{al.tracks_to_be_redrawn[ak][1]=af;al.tracks_to_be_redrawn[ak][2]=am}}requestAnimationFrame(function(){al._redraw(an)})},_redraw:function(ap){var am=this.low,ai=this.high;if(am<this.max_low){am=this.max_low}if(ai>this.max_high){ai=this.max_high}var ao=this.high-this.low;if(this.high!==0&&ao<this.min_separation){ai=am+this.min_separation}this.low=Math.floor(am);this.high=Math.ceil(ai);this.resolution=Math.pow(C,Math.ceil(Math.log((this.high-this.low)/R)/Math.log(C)));this.zoom_res=Math.pow(v,Math.max(0,Math.ceil(Math.log(this.resolution,v)/Math.log(v))));var af=(this.low/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var al=((this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var aq=13;this.overview_box.css({left:af,width:Math.max(aq,al)}).show();if(al<aq){this.overview_box.css("left",af-(aq-al)/2)}if(this.overview_highlight){this.overview_highlight.css({left:af,width:al})}this.update_location(this.low,this.high);if(!ap){var ah,ag,an;for(var aj=0,ak=this.tracks_to_be_redrawn.length;aj<ak;aj++){ah=this.tracks_to_be_redrawn[aj][0];ag=this.tracks_to_be_redrawn[aj][1];an=this.tracks_to_be_redrawn[aj][2];if(ah){ah._draw(ag,an)}}this.tracks_to_be_redrawn=[];for(aj=0,ak=this.label_tracks.length;aj<ak;aj++){this.label_tracks[aj]._draw()}}},zoom_in:function(ag,ah){if(this.max_high===0||this.high-this.low<this.min_separation){return}var ai=this.high-this.low,aj=ai/2+this.low,af=(ai/this.zoom_factor)/2;if(ag){aj=ag/this.viewport_container.width()*(this.high-this.low)+this.low}this.low=Math.round(aj-af);this.high=Math.round(aj+af);this.request_redraw()},zoom_out:function(){if(this.max_high===0){return}var ag=this.high-this.low,ah=ag/2+this.low,af=(ag*this.zoom_factor)/2;this.low=Math.round(ah-af);this.high=Math.round(ah+af);this.request_redraw()},resize_window:function(){this.viewport_container.height(this.container.height()-this.top_container.height()-this.bottom_container.height());this.nav_container.width(this.container.width());this.request_redraw()},set_overview:function(ah){if(this.overview_drawable){if(this.overview_drawable.dataset_id===ah.dataset_id){return}this.overview_viewport.find(".track").remove()}var ag=ah.copy({content_div:this.overview_viewport}),af=this;ag.header_div.hide();ag.is_overview=true;af.overview_drawable=ag;this.overview_drawable.postdraw_actions=function(){af.overview_highlight.show().height(af.overview_drawable.content_div.height());af.overview_viewport.height(af.overview_drawable.content_div.height()+af.overview_box.outerHeight());af.overview_close.show();af.resize_window()};this.overview_drawable.init();af.has_changes=true},reset_overview:function(){$(".tipsy").remove();this.overview_viewport.find(".track-tile").remove();this.overview_viewport.height(this.default_overview_height);this.overview_box.height(this.default_overview_height);this.overview_close.hide();this.overview_highlight.hide();view.resize_window();view.overview_drawable=null}});var r=function(ah,al){this.track=ah;this.name=al.name;this.params=[];var at=al.params;for(var ai=0;ai<at.length;ai++){var an=at[ai],ag=an.name,ar=an.label,aj=unescape(an.html),au=an.value,ap=an.type;if(ap==="number"){this.params[this.params.length]=new g(ag,ar,aj,au,an.min,an.max)}else{if(ap=="select"){this.params[this.params.length]=new O(ag,ar,aj,au)}else{console.log("WARNING: unrecognized tool parameter type:",ag,ap)}}}this.parent_div=$("<div/>").addClass("dynamic-tool").hide();this.parent_div.bind("drag",function(aw){aw.stopPropagation()}).click(function(aw){aw.stopPropagation()}).bind("dblclick",function(aw){aw.stopPropagation()});var aq=$("<div class='tool-name'>").appendTo(this.parent_div).text(this.name);var ao=this.params;var am=this;$.each(this.params,function(ax,aA){var az=$("<div>").addClass("param-row").appendTo(am.parent_div);var aw=$("<div>").addClass("param-label").text(aA.label).appendTo(az);var ay=$("<div/>").addClass("slider").html(aA.html).appendTo(az);ay.find(":input").val(aA.value);$("<div style='clear: both;'/>").appendTo(az)});this.parent_div.find("input").click(function(){$(this).select()});var av=$("<div>").addClass("param-row").appendTo(this.parent_div);var ak=$("<input type='submit'>").attr("value","Run on complete dataset").appendTo(av);var af=$("<input type='submit'>").attr("value","Run on visible region").css("margin-left","3em").appendTo(av);var am=this;af.click(function(){am.run_on_region()});ak.click(function(){am.run_on_dataset()})};p(r.prototype,{get_param_values_dict:function(){var af={};this.parent_div.find(":input").each(function(){var ag=$(this).attr("name"),ah=$(this).val();af[ag]=JSON.stringify(ah)});return af},get_param_values:function(){var ag=[];var af={};this.parent_div.find(":input").each(function(){var ah=$(this).attr("name"),ai=$(this).val();if(ah){ag[ag.length]=ai}});return ag},run_on_dataset:function(){var af=this;af.run({dataset_id:this.track.original_dataset_id,tool_id:af.name},null,function(ag){show_modal(af.name+" is Running",af.name+" is running on the complete dataset. Tool outputs are in dataset's history.",{Close:hide_modal})})},run_on_region:function(){var ag={dataset_id:this.track.original_dataset_id,chrom:this.track.view.chrom,low:this.track.view.low,high:this.track.view.high,tool_id:this.name},aj=this.track,ah=ag.tool_id+aj.tool_region_and_parameters_str(ag.chrom,ag.low,ag.high),af;if(aj.container===view){var ai=new Q(this.name,this.track.view,this.track.container);aj.container.add_drawable(ai);aj.container.remove_drawable(aj);ai.add_drawable(aj);aj.container_div.appendTo(ai.content_div);af=ai}else{af=aj.container}var ak=new aj.constructor(ah,view,af,"hda");ak.init_for_tool_data();ak.change_mode(aj.mode);af.add_drawable(ak);ak.content_div.text("Starting job.");this.run(ag,ak,function(al){ak.dataset_id=al.dataset_id;ak.content_div.text("Running job.");ak.init()})},run:function(ag,ah,ai){$.extend(ag,this.get_param_values_dict());var af=function(){$.getJSON(rerun_tool_url,ag,function(aj){if(aj==="no converter"){ah.container_div.addClass("error");ah.content_div.text(K)}else{if(aj.error){ah.container_div.addClass("error");ah.content_div.text(x+aj.message)}else{if(aj==="pending"){ah.container_div.addClass("pending");ah.content_div.text("Converting input data so that it can be used quickly with tool.");setTimeout(af,2000)}else{ai(aj)}}}})};af()}});var O=function(ag,af,ah,ai){this.name=ag;this.label=af;this.html=ah;this.value=ai};var g=function(ah,ag,aj,ak,ai,af){O.call(this,ah,ag,aj,ak);this.min=ai;this.max=af};var h=function(ag,af,ah,ai){this.name=ag;this.index=af;this.tool_id=ah;this.tool_exp_name=ai};var V=function(ag,af,ah,ai){h.call(this,ag,af,ah,ai);this.low=-Number.MAX_VALUE;this.high=Number.MAX_VALUE;this.min=Number.MAX_VALUE;this.max=-Number.MAX_VALUE;this.container=null;this.slider=null;this.slider_label=null};p(V.prototype,{applies_to:function(af){if(af.length>this.index){return true}return false},keep:function(af){if(!this.applies_to(af)){return true}var ag=af[this.index];return(isNaN(ag)||(ag>=this.low&&ag<=this.high))},update_attrs:function(ag){var af=false;if(!this.applies_to(ag)){return af}if(ag[this.index]<this.min){this.min=Math.floor(ag[this.index]);af=true}if(ag[this.index]>this.max){this.max=Math.ceil(ag[this.index]);af=true}return af},update_ui_elt:function(){if(this.min!=this.max){this.container.show()}else{this.container.hide()}var ah=function(ak,ai){var aj=ai-ak;return(aj<=2?0.01:1)};var ag=this.slider.slider("option","min"),af=this.slider.slider("option","max");if(this.min<ag||this.max>af){this.slider.slider("option","min",this.min);this.slider.slider("option","max",this.max);this.slider.slider("option","step",ah(this.min,this.max));this.slider.slider("option","values",[this.min,this.max])}}});var aa=function(aq,ay){this.track=aq;this.filters=[];for(var at=0;at<ay.length;at++){var au=ay[at],az=au.name,af=au.type,ah=au.index,ax=au.tool_id,aw=au.tool_exp_name;if(af==="int"||af==="float"){this.filters[at]=new V(az,ah,ax,aw)}else{console.log("ERROR: unsupported filter: ",az,af)}}var ai=function(aA,aB,aC){aA.click(function(){var aD=aB.text();max=parseFloat(aC.slider("option","max")),input_size=(max<=1?4:max<=1000000?max.toString().length:6),multi_value=false;if(aC.slider("option","values")){input_size=2*input_size+1;multi_value=true}aB.text("");$("<input type='text'/>").attr("size",input_size).attr("maxlength",input_size).attr("value",aD).appendTo(aB).focus().select().click(function(aE){aE.stopPropagation()}).blur(function(){$(this).remove();aB.text(aD)}).keyup(function(aI){if(aI.keyCode===27){$(this).trigger("blur")}else{if(aI.keyCode===13){var aG=aC.slider("option","min"),aE=aC.slider("option","max"),aH=function(aJ){return(isNaN(aJ)||aJ>aE||aJ<aG)},aF=$(this).val();if(!multi_value){aF=parseFloat(aF);if(aH(aF)){alert("Parameter value must be in the range ["+aG+"-"+aE+"]");return $(this)}}else{aF=aF.split("-");aF=[parseFloat(aF[0]),parseFloat(aF[1])];if(aH(aF[0])||aH(aF[1])){alert("Parameter value must be in the range ["+aG+"-"+aE+"]");return $(this)}}aC.slider((multi_value?"values":"value"),aF)}}})})};this.parent_div=$("<div/>").addClass("filters").hide();this.parent_div.bind("drag",function(aA){aA.stopPropagation()}).click(function(aA){aA.stopPropagation()}).bind("dblclick",function(aA){aA.stopPropagation()}).bind("keydown",function(aA){aA.stopPropagation()});var av=$("<div/>").addClass("sliders").appendTo(this.parent_div);var an=this;$.each(this.filters,function(aD,aF){aF.container=$("<div/>").addClass("filter-row slider-row").appendTo(av);var aE=$("<div/>").addClass("elt-label").appendTo(aF.container);var aC=$("<span/>").addClass("slider-name").text(aF.name+" ").appendTo(aE);var aB=$("<span/>");var aH=$("<span/>").addClass("slider-value").appendTo(aE).append("[").append(aB).append("]");var aA=$("<div/>").addClass("slider").appendTo(aF.container);aF.control_element=$("<div/>").attr("id",aF.name+"-filter-control").appendTo(aA);var aG=[0,0];aF.control_element.slider({range:true,min:Number.MAX_VALUE,max:-Number.MIN_VALUE,values:[0,0],slide:function(aJ,aK){var aI=aK.values;aB.text(aI[0]+"-"+aI[1]);aF.low=aI[0];aF.high=aI[1];an.track.request_draw(true,true)},change:function(aI,aJ){aF.control_element.slider("option","slide").call(aF.control_element,aI,aJ)}});aF.slider=aF.control_element;aF.slider_label=aB;ai(aH,aB,aF.control_element);$("<div style='clear: both;'/>").appendTo(aF.container)});if(this.filters.length!==0){var ak=$("<div/>").addClass("param-row").appendTo(av);var am=$("<input type='submit'/>").attr("value","Run on complete dataset").appendTo(ak);var ag=this;am.click(function(){ag.run_on_dataset()})}var ap=$("<div/>").addClass("display-controls").appendTo(this.parent_div),ar,al,ao,aj={Transparency:function(aA){an.alpha_filter=aA},Height:function(aA){an.height_filter=aA}};$.each(aj,function(aC,aB){ar=$("<div/>").addClass("filter-row").appendTo(ap),al=$("<span/>").addClass("elt-label").text(aC+":").appendTo(ar),ao=$("<select/>").attr("name",aC+"_dropdown").css("float","right").appendTo(ar);$("<option/>").attr("value",-1).text("== None ==").appendTo(ao);for(var aA=0;aA<an.filters.length;aA++){$("<option/>").attr("value",aA).text(an.filters[aA].name).appendTo(ao)}ao.change(function(){$(this).children("option:selected").each(function(){var aD=parseInt($(this).val());aj[aC]((aD>=0?an.filters[aD]:null));an.track.request_draw(true,true)})});$("<div style='clear: both;'/>").appendTo(ar)});$("<div style='clear: both;'/>").appendTo(this.parent_div)};p(aa.prototype,{reset_filters:function(){for(var af=0;af<this.filters.length;af++){filter=this.filters[af];filter.slider.slider("option","values",[filter.min,filter.max])}this.alpha_filter=null;this.height_filter=null},run_on_dataset:function(){var an=function(ar,ap,aq){if(!(ap in ar)){ar[ap]=aq}return ar[ap]};var ah={},af,ag,ai;for(var aj=0;aj<this.filters.length;aj++){af=this.filters[aj];if(af.tool_id){if(af.min!=af.low){ag=an(ah,af.tool_id,[]);ag[ag.length]=af.tool_exp_name+" >= "+af.low}if(af.max!=af.high){ag=an(ah,af.tool_id,[]);ag[ag.length]=af.tool_exp_name+" <= "+af.high}}}var al=[];for(var ao in ah){al[al.length]=[ao,ah[ao]]}var am=al.length;(function ak(aw,at){var aq=at[0],ar=aq[0],av=aq[1],au="("+av.join(") and (")+")",ap={cond:au,input:aw,target_dataset_id:aw,tool_id:ar},at=at.slice(1);$.getJSON(run_tool_url,ap,function(ax){if(ax.error){show_modal("Filter Dataset","Error running tool "+ar,{Close:hide_modal})}else{if(at.length===0){show_modal("Filtering Dataset","Filter(s) are running on the complete dataset. Outputs are in dataset's history.",{Close:hide_modal})}else{ak(ax.dataset_id,at)}}})})(this.track.dataset_id,al)}});var D=function(af,ag){M.Scaler.call(this,ag);this.filter=af};D.prototype.gen_val=function(af){if(this.filter.high===Number.MAX_VALUE||this.filter.low===-Number.MAX_VALUE||this.filter.low===this.filter.high){return this.default_val}return((parseFloat(af[this.filter.index])-this.filter.low)/(this.filter.high-this.filter.low))};var G=function(af){this.track=af.track;this.params=af.params;this.values={};this.restore_values((af.saved_values?af.saved_values:{}));this.onchange=af.onchange};p(G.prototype,{restore_values:function(af){var ag=this;$.each(this.params,function(ah,ai){if(af[ai.key]!==undefined){ag.values[ai.key]=af[ai.key]}else{ag.values[ai.key]=ai.default_value}})},build_form:function(){var ag=this;var af=$("<div />");$.each(this.params,function(ak,ai){if(!ai.hidden){var ah="param_"+ak;var am=ag.values[ai.key];var ap=$("<div class='form-row' />").appendTo(af);ap.append($("<label />").attr("for",ah).text(ai.label+":"));if(ai.type==="bool"){ap.append($('<input type="checkbox" />').attr("id",ah).attr("name",ah).attr("checked",am))}else{if(ai.type==="text"){ap.append($('<input type="text"/>').attr("id",ah).val(am).click(function(){$(this).select()}))}else{if(ai.type==="color"){var al=$("<input />").attr("id",ah).attr("name",ah).val(am);var an=$("<div class='tipsy tipsy-north' style='position: absolute;' />").hide();var aj=$("<div style='background-color: black; padding: 10px;'></div>").appendTo(an);var ao=$("<div/>").appendTo(aj).farbtastic({width:100,height:100,callback:al,color:am});$("<div />").append(al).append(an).appendTo(ap).bind("click",function(aq){an.css({left:$(this).position().left+($(al).width()/2)-60,top:$(this).position().top+$(this.height)}).show();$(document).bind("click.color-picker",function(){an.hide();$(document).unbind("click.color-picker")});aq.stopPropagation()})}else{ap.append($("<input />").attr("id",ah).attr("name",ah).val(am))}}}}});return af},update_from_form:function(af){var ah=this;var ag=false;$.each(this.params,function(ai,ak){if(!ak.hidden){var al="param_"+ai;var aj=af.find("#"+al).val();if(ak.type==="float"){aj=parseFloat(aj)}else{if(ak.type==="int"){aj=parseInt(aj)}else{if(ak.type==="bool"){aj=af.find("#"+al).is(":checked")}}}if(aj!==ah.values[ak.key]){ah.values[ak.key]=aj;ag=true}}});if(ag){this.onchange()}}});var b=function(af,ai,ah,ag,aj){this.track=af;this.index=ai;this.low=ai*R*ah;this.high=(ai+1)*R*ah;this.resolution=ah;this.canvas=$("<div class='track-tile'/>").append(ag);this.data=aj;this.stale=false};b.prototype.predisplay_actions=function(){};var k=function(af,ai,ah,ag,aj,ak){b.call(this,af,ai,ah,ag,aj);this.max_val=ak};p(k.prototype,b.prototype);var P=function(af,aj,ai,ah,al,am,ak,ag){b.call(this,af,aj,ai,ah,al);this.mode=am;this.message=ak;this.feature_mapper=ag};p(P.prototype,b.prototype);P.prototype.predisplay_actions=function(){var ag=this,af={};if(ag.mode!=="Pack"){return}$(this.canvas).mousemove(function(ar){var am=$(this).offset(),aq=ar.pageX-am.left,ap=ar.pageY-am.top,aw=ag.feature_mapper.get_feature_data(aq,ap),an=(aw?aw[0]:null);$(this).siblings(".feature-popup").each(function(){if(!an||$(this).attr("id")!==an.toString()){$(this).remove()}});if(aw){var ai=af[an];if(!ai){var an=aw[0],at={name:aw[3],start:aw[1],end:aw[2],strand:aw[4]},al=ag.track.filters_manager.filters,ak;for(var ao=0;ao<al.length;ao++){ak=al[ao];at[ak.name]=aw[ak.index]}var ai=$("<div/>").attr("id",an).addClass("feature-popup"),av,au,ax=$("<table/>").appendTo(ai),ay;for(av in at){au=at[av];ay=$("<tr/>").appendTo(ax);$("<th/>").appendTo(ay).text(av);$("<td/>").attr("align","left").appendTo(ay).text(typeof(au)=="number"?Z(au,2):au)}af[an]=ai}ai.appendTo($(ag.canvas).parent());var aj=aq+parseInt(ag.canvas.css("left"))+7,ah=ap+parseInt(ag.canvas.css("top"))+7;ai.css("left",aj+"px").css("top",ah+"px")}else{if(!ar.isPropagationStopped()){ar.stopPropagation();$(this).siblings().each(function(){$(this).trigger(ar)})}}}).mouseleave(function(){$(this).siblings(".feature-popup").remove()})};var i=function(ai,aq,aj,am,ar,ah,ag){q.call(this,ai,aq,aj,{},"draghandle");this.data_url=(ah?ah:default_data_url);this.data_url_extra_params={};this.data_query_wait=(ag?ag:L);this.dataset_check_url=converted_datasets_state_url;if(!i.id_counter){i.id_counter=0}this.id=i.id_counter++;this.container_div=$("<div />").addClass("track").attr("id","track_"+this.id).css("position","relative");if(am){this.header_div=$("<div class='track-header' />").appendTo(this.container_div);if(this.view.editor){this.drag_div=$("<div/>").addClass(this.drag_handle_class).appendTo(this.header_div)}this.name_div=$("<div/>").addClass("track-name").appendTo(this.header_div).text(this.name).attr("id",this.name.replace(/\s+/g,"-").replace(/[^a-zA-Z0-9\-]/g,"").toLowerCase());this.icons_div=$("<div/>").css("float","left").appendTo(this.header_div).hide();this.settings_icon=$("<a/>").attr("href","javascript:void(0);").attr("title","Edit settings").addClass("icon-button settings-icon").tipsy({gravity:"s"}).appendTo(this.icons_div);this.overview_icon=$("<a/>").attr("href","javascript:void(0);").attr("title","Set as overview").addClass("icon-button overview-icon").tipsy({gravity:"s"}).appendTo(this.icons_div);this.filters_icon=$("<a/>").attr("href","javascript:void(0);").attr("title","Filters").addClass("icon-button filters-icon").tipsy({gravity:"s"}).appendTo(this.icons_div).hide();this.tools_icon=$("<a/>").attr("href","javascript:void(0);").attr("title","Tools").addClass("icon-button tools-icon").tipsy({gravity:"s"}).appendTo(this.icons_div).hide();this.remove_icon=$("<a/>").attr("href","javascript:void(0);").attr("title","Remove").addClass("icon-button remove-icon").tipsy({gravity:"s"}).appendTo(this.icons_div);var ak=this;this.header_div.dblclick(function(at){at.stopPropagation()});this.settings_icon.click(function(){var av=function(){hide_modal();$(window).unbind("keypress.check_enter_esc")},at=function(){ak.config.update_from_form($(".dialog-box"));hide_modal();$(window).unbind("keypress.check_enter_esc")},au=function(aw){if((aw.keyCode||aw.which)===27){av()}else{if((aw.keyCode||aw.which)===13){at()}}};$(window).bind("keypress.check_enter_esc",au);show_modal("Configure Track",ak.config.build_form(),{Cancel:av,OK:at})});this.overview_icon.click(function(){ak.view.set_overview(ak)});this.filters_icon.click(function(){ak.filters_div.toggle();ak.filters_manager.reset_filters()});this.tools_icon.click(function(){ak.dynamic_tool_div.toggle();if(ak.dynamic_tool_div.is(":visible")){ak.set_name(ak.name+ak.tool_region_and_parameters_str())}else{ak.revert_name()}$(".tipsy").remove()});this.remove_icon.click(function(){$(".tipsy").remove();ak.remove()});if(ak.display_modes!==undefined){if(ak.mode_div===undefined){ak.mode_div=$("<div class='right-float menubutton popup' />").appendTo(ak.header_div);var al=(ak.config&&ak.config.values.mode?ak.config.values.mode:ak.display_modes[0]);ak.mode=al;ak.mode_div.text(al);var af={};for(var an=0,ap=ak.display_modes.length;an<ap;an++){var ao=ak.display_modes[an];af[ao]=function(at){return function(){ak.change_mode(at)}}(ao)}make_popupmenu(ak.mode_div,af)}else{ak.mode_div.hide()}this.header_div.append($("<div/>").css("clear","both"));this.container_div.hover(function(){ak.icons_div.show()},function(){ak.icons_div.hide()})}}this.content_div=$("<div class='track-content'>").appendTo(this.container_div);this.container.content_div.append(this.container_div)};p(i.prototype,q.prototype,{get_type:function(){if(this instanceof ab){return"LabelTrack"}else{if(this instanceof A){return"ReferenceTrack"}else{if(this instanceof j){return"LineTrack"}else{if(this instanceof W){return"ReadTrack"}else{if(this instanceof U){return"VcfTrack"}else{if(this instanceof e){return"FeatureTrack"}}}}}}return""},init:function(){var af=this;af.enabled=false;af.tile_cache.clear();af.data_manager.clear();af.initial_canvas=undefined;af.content_div.css("height","auto");af.container_div.removeClass("nodata error pending");if(!af.dataset_id){return}$.getJSON(converted_datasets_state_url,{hda_ldda:af.hda_ldda,dataset_id:af.dataset_id,chrom:af.view.chrom},function(ag){if(!ag||ag==="error"||ag.kind==="error"){af.container_div.addClass("error");af.content_div.text(o);if(ag.message){var ah=$(" <a href='javascript:void(0);'></a>").text("View error").click(function(){show_modal("Trackster Error","<pre>"+ag.message+"</pre>",{Close:hide_modal})});af.content_div.append(ah)}}else{if(ag==="no converter"){af.container_div.addClass("error");af.content_div.text(K)}else{if(ag==="no data"||(ag.data!==undefined&&(ag.data===null||ag.data.length===0))){af.container_div.addClass("nodata");af.content_div.text(F)}else{if(ag==="pending"){af.container_div.addClass("pending");af.content_div.text(t);setTimeout(function(){af.init()},af.data_query_wait)}else{if(ag.status==="data"){if(ag.valid_chroms){af.valid_chroms=ag.valid_chroms;af.update_track_icons()}af.content_div.text(Y);if(af.view.chrom){af.content_div.text("");af.content_div.css("height",af.height_px+"px");af.enabled=true;$.when(af.predraw_init()).done(function(){af.container_div.removeClass("nodata error pending");af.request_draw()})}}}}}}});this.update_track_icons()},predraw_init:function(){}});var N=function(aj,ah,ag,am,ai,al,ak){i.call(this,aj,ah,ag,am,ai);var af=this,ah=af.view;m(af.container_div,af.drag_handle_class,".group",af);this.filters_manager=new aa(this,(al!==undefined?al:{}));this.filters_available=false;this.filters_visible=false;this.tool=(ak!==undefined&&obj_length(ak)>0?new r(this,ak):undefined);if(this.header_div){if(this.filters_manager){this.filters_div=this.filters_manager.parent_div;this.header_div.after(this.filters_div)}if(this.tool){this.dynamic_tool_div=this.tool.parent_div;this.header_div.after(this.dynamic_tool_div)}}};p(N.prototype,q.prototype,i.prototype,{copy:function(af){return new this.constructor(this.name,this.view,af,this.hda_ldda,this.dataset_id,this.prefs,this.filters,this.tool)},to_json:function(){return{track_type:this.get_type(),name:this.name,hda_ldda:this.hda_ldda,dataset_id:this.dataset_id,prefs:this.prefs,mode:this.mode,}},change_mode:function(ag){var af=this;af.mode_div.text(ag);af.mode=ag;af.config.values.mode=ag;af.tile_cache.clear();af.request_draw();return af},update_track_icons:function(){var af=this;if(af.filters_available>0){af.filters_icon.show()}else{af.filters_icon.hide()}if(af.tool){af.tools_icon.show()}else{af.tools_icon.hide()}},_gen_tile_cache_key:function(ag,ah,af){return ag+"_"+ah+"_"+af},request_draw:function(ag,af){this.view.request_redraw(false,ag,af,this)},_draw:function(ah,ap){if(!this.enabled){return}if(!(this instanceof A)&&(!this.dataset_id)){return}var ao=this.view.low,al=this.view.high,am=al-ao,ai=this.view.container.width(),at=ai/am,ak=this.view.resolution,ar=$("<div style='position: relative;'></div>");if(this.is_overview){ao=this.view.max_low;al=this.view.max_high;ak=Math.pow(C,Math.ceil(Math.log((view.max_high-view.max_low)/R)/Math.log(C)));at=ai/(view.max_high-view.max_low)}if(!ap){this.content_div.children().remove()}this.content_div.append(ar);this.max_height=0;var ag=Math.floor(ao/ak/R);var an=true;var aq=[];var af=0;while((ag*R*ak)<al){tile=this.draw_helper(ah,ai,ag,ak,ar,at);if(tile){aq.push(tile)}else{an=false}ag+=1;af++}var aj=this;if(an){aj.postdraw_actions(aq,ai,at,ap)}},postdraw_actions:function(aj,ak,al,af){var ah=this;var ai=false;for(var ag=0;ag<aj.length;ag++){if(aj[ag].message){ai=true;break}}if(ai){for(var ag=0;ag<aj.length;ag++){tile=aj[ag];if(!tile.message){tile.canvas.css("padding-top",E)}}}},draw_helper:function(ag,ah,ai,al,ar,aw,at,am){var aj=this,aq=this._gen_tile_cache_key(ah,aw,ai),an=ai*R*al,av=an+R*al;var ao=(ag?undefined:aj.tile_cache.get(aq));if(ao){aj.show_tile(ao,ar,aw);return ao}var ap=function(ax){return("isResolved" in ax)};var ak=true;var af=aj.data_manager.get_data(an,av,aj.mode,al,aj.data_url_extra_params);if(ap(af)){ak=false}var au;if(view.reference_track&&aw>view.canvas_manager.char_width_px){au=view.reference_track.data_manager.get_data(an,av,aj.mode,al,view.reference_track.data_url_extra_params);if(ap(au)){ak=false}}if(ak){p(af,am);var ao=aj.draw_tile(af,aj.mode,al,ai,aw,au);if(ao!==undefined){aj.tile_cache.set(aq,ao);aj.show_tile(ao,ar,aw)}return ao}$.when(af,au).then(function(){view.request_redraw(false,false,false,aj)});return null},show_tile:function(al,an,ao){var ah=this,ag=al.canvas,ak=ag;if(al.message){var ap=$("<div/>"),am=$("<div/>").addClass("tile-message").text(al.message).css({height:E-1,width:al.canvas.width}).appendTo(ap),aj=$("<a href='javascript:void(0);'/>").addClass("icon more-down").appendTo(am),af=$("<a href='javascript:void(0);'/>").addClass("icon more-across").appendTo(am);ap.append(ag);ak=ap;aj.click(function(){al.stale=true;ah.data_manager.get_more_data(al.low,al.high,ah.mode,al.resolution,{},ah.data_manager.DEEP_DATA_REQ);ah.request_draw()}).dblclick(function(aq){aq.stopPropagation()});af.click(function(){al.stale=true;ah.data_manager.get_more_data(al.low,al.high,ah.mode,al.resolution,{},ah.data_manager.BROAD_DATA_REQ);ah.request_draw()}).dblclick(function(aq){aq.stopPropagation()})}al.predisplay_actions();var ai=(al.low-(this.is_overview?this.view.max_low:this.view.low))*ao;if(this.left_offset){ai-=this.left_offset}ak.css({position:"absolute",top:0,left:ai,height:""});an.append(ak);ah.max_height=Math.max(ah.max_height,ak.height());ah.content_div.css("height",ah.max_height+"px");an.children().css("height",ah.max_height+"px")},_get_tile_bounds:function(af,ag){var ai=af*R*ag,aj=R*ag,ah=(ai+aj<=this.view.max_high?ai+aj:this.view.max_high);return[ai,ah]},tool_region_and_parameters_str:function(ah,af,ai){var ag=this,aj=(ah!==undefined&&af!==undefined&&ai!==undefined?ah+":"+af+"-"+ai:"all");return" - region=["+aj+"], parameters=["+ag.tool.get_param_values().join(", ")+"]"},init_for_tool_data:function(){this.data_url=raw_data_url;this.data_query_wait=1000;this.dataset_check_url=dataset_state_url;this.predraw_init=function(){var ag=this;var af=function(){if(ag.data_manager.size()===0){setTimeout(af,300)}else{ag.data_url=default_data_url;ag.data_query_wait=L;ag.dataset_state_url=converted_datasets_state_url;$.getJSON(ag.dataset_state_url,{dataset_id:ag.dataset_id,hda_ldda:ag.hda_ldda},function(ah){})}};af()}}});var ab=function(ag,af){i.call(this,"label",ag,af,false,{});this.container_div.addClass("label-track")};p(ab.prototype,i.prototype,{init:function(){this.enabled=true},_draw:function(){var ah=this.view,ai=ah.high-ah.low,al=Math.floor(Math.pow(10,Math.floor(Math.log(ai)/Math.log(10)))),af=Math.floor(ah.low/al)*al,aj=this.view.container.width(),ag=$("<div style='position: relative; height: 1.3em;'></div>");while(af<ah.high){var ak=(af-ah.low)/ai*aj;ag.append($("<div class='label'>"+commatize(af)+"</div>").css({position:"absolute",left:ak-1}));af+=al}this.content_div.children(":first").remove();this.content_div.append(ag)}});var A=function(af){N.call(this,"reference",af,{content_div:af.top_labeltrack},false,{});af.reference_track=this;this.left_offset=200;this.height_px=12;this.container_div.addClass("reference-track");this.content_div.css("background","none");this.content_div.css("min-height","0px");this.content_div.css("border","none");this.data_url=reference_url;this.data_url_extra_params={dbkey:af.dbkey};this.data_manager=new I(B,this,false);this.tile_cache=new c(u)};p(A.prototype,q.prototype,N.prototype,{init:function(){this.enabled=true},draw_tile:function(ap,al,ak,ag,aq){var aj=this,ah=R*ak;if(aq>this.view.canvas_manager.char_width_px){if(ap.data===null){aj.content_div.css("height","0px");return}var ai=this.view.canvas_manager.new_canvas();var ao=ai.getContext("2d");ai.width=Math.ceil(ah*aq+aj.left_offset);ai.height=aj.height_px;ao.font=ao.canvas.manager.default_font;ao.textAlign="center";ap=ap.data;for(var am=0,an=ap.length;am<an;am++){var af=Math.round(am*aq);ao.fillText(ap[am],af+aj.left_offset,10)}return new b(aj,ag,ak,ai,ap)}this.content_div.css("height","0px")}});var j=function(ak,ai,ah,al,af,aj){var ag=this;this.display_modes=["Histogram","Line","Filled","Intensity"];this.mode="Histogram";N.call(this,ak,ai,ah,true,aj);this.min_height_px=16;this.max_height_px=400;this.height_px=80;this.hda_ldda=al;this.dataset_id=af;this.original_dataset_id=af;this.data_manager=new S(B,this);this.tile_cache=new c(u);this.left_offset=0;this.config=new G({track:this,params:[{key:"name",label:"Name",type:"text",default_value:ak},{key:"color",label:"Color",type:"color",default_value:get_random_color()},{key:"min_value",label:"Min Value",type:"float",default_value:undefined},{key:"max_value",label:"Max Value",type:"float",default_value:undefined},{key:"mode",type:"string",default_value:this.mode,hidden:true},{key:"height",type:"int",default_value:this.height_px,hidden:true}],saved_values:aj,onchange:function(){ag.set_name(ag.prefs.name);ag.vertical_range=ag.prefs.max_value-ag.prefs.min_value;$("#linetrack_"+ag.dataset_id+"_minval").text(ag.prefs.min_value);$("#linetrack_"+ag.dataset_id+"_maxval").text(ag.prefs.max_value);ag.tile_cache.clear();ag.request_draw()}});this.prefs=this.config.values;this.height_px=this.config.values.height;this.vertical_range=this.config.values.max_value-this.config.values.min_value;this.add_resize_handle()};p(j.prototype,q.prototype,N.prototype,{add_resize_handle:function(){var af=this;var ai=false;var ah=false;var ag=$("<div class='track-resize'>");$(af.container_div).hover(function(){ai=true;ag.show()},function(){ai=false;if(!ah){ag.hide()}});ag.hide().bind("dragstart",function(aj,ak){ah=true;ak.original_height=$(af.content_div).height()}).bind("drag",function(ak,al){var aj=Math.min(Math.max(al.original_height+al.deltaY,af.min_height_px),af.max_height_px);$(af.content_div).css("height",aj);af.height_px=aj;af.request_draw(true)}).bind("dragend",function(aj,ak){af.tile_cache.clear();ah=false;if(!ai){ag.hide()}af.config.values.height=af.height_px}).appendTo(af.container_div)},predraw_init:function(){var af=this;af.vertical_range=undefined;return $.getJSON(af.data_url,{stats:true,chrom:af.view.chrom,low:null,high:null,hda_ldda:af.hda_ldda,dataset_id:af.dataset_id},function(ag){af.container_div.addClass("line-track");var ai=ag.data;if(isNaN(parseFloat(af.prefs.min_value))||isNaN(parseFloat(af.prefs.max_value))){af.prefs.min_value=ai.min;af.prefs.max_value=ai.max;$("#track_"+af.dataset_id+"_minval").val(af.prefs.min_value);$("#track_"+af.dataset_id+"_maxval").val(af.prefs.max_value)}af.vertical_range=af.prefs.max_value-af.prefs.min_value;af.total_frequency=ai.total_frequency;af.container_div.find(".yaxislabel").remove();var aj=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+af.dataset_id+"_minval").text(Z(af.prefs.min_value,3));var ah=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+af.dataset_id+"_maxval").text(Z(af.prefs.max_value,3));ah.css({position:"absolute",top:"24px",left:"10px"});ah.prependTo(af.container_div);aj.css({position:"absolute",bottom:"2px",left:"10px"});aj.prependTo(af.container_div)})},draw_tile:function(ar,ak,aj,ah,aq){if(this.vertical_range===undefined){return}var af=this._get_tile_bounds(ah,aj),al=af[0],ap=af[1],ag=Math.ceil((ap-al)*aq),an=this.height_px;var ai=this.view.canvas_manager.new_canvas();ai.width=ag,ai.height=an;var ao=ai.getContext("2d");var am=new M.LinePainter(ar.data,al,ap,this.prefs,ak);am.draw(ao,ag,an);return new b(this.track,ah,aj,ai,ar.data)}});var e=function(af,al,ag,ak,an,am,ai,aj){var ah=this;this.display_modes=["Auto","Histogram","Dense","Squish","Pack"];N.call(this,af,al,ag,true,am,ai,aj);this.config=new G({track:this,params:[{key:"name",label:"Name",type:"text",default_value:af},{key:"block_color",label:"Block color",type:"color",default_value:get_random_color()},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:am,onchange:function(){ah.set_name(ah.prefs.name);ah.tile_cache.clear();ah.request_draw()}});this.prefs=this.config.values;this.height_px=0;this.container_div.addClass("feature-track");this.hda_ldda=ak;this.dataset_id=an;this.original_dataset_id=an;this.show_labels_scale=0.001;this.showing_details=false;this.summary_draw_height=30;this.inc_slots={};this.start_end_dct={};this.tile_cache=new c(d);this.data_manager=new S(20,this);this.left_offset=200;this.painter=M.LinkedFeaturePainter};p(e.prototype,q.prototype,N.prototype,{postdraw_actions:function(av,af,aw,au){N.prototype.postdraw_actions.call(this,av,au);var ai=this;if(au){var ak=ai.content_div.children();var al=false;for(var aj=ak.length-1,ap=0;aj>=ap;aj--){var ah=$(ak[aj]);if(al){ah.remove()}else{if(ah.children().length!==0){al=true}}}}if(ai.mode=="Histogram"){var ao=-1;for(var aj=0;aj<av.length;aj++){var at=av[aj].max_val;if(at>ao){ao=at}}for(var aj=0;aj<av.length;aj++){var ar=av[aj];if(ar.max_val!==ao){ar.canvas.remove();ai.draw_helper(true,af,ar.index,ar.resolution,ar.canvas.parent(),aw,[],{max:ao})}}}if(ai.filters_manager){var ag=ai.filters_manager.filters;for(var an=0;an<ag.length;an++){ag[an].update_ui_elt()}var am=false,aq;for(var aj=0;aj<av.length;aj++){if(av[aj].data.length){aq=av[aj].data[0];for(var an=0;an<ag.length;an++){if(ag[an].applies_to(aq)){am=true;break}}}}if(ai.filters_available!==am){ai.filters_available=am;if(!ai.filters_available){ai.filters_div.hide()}ai.update_track_icons()}}},update_auto_mode:function(af){if(this.mode=="Auto"){if(af=="no_detail"){af="feature spans"}else{if(af=="summary_tree"){af="coverage histogram"}}this.mode_div.text("Auto ("+af+")")}},incremental_slots:function(aj,ag,ai){var ah=this.view.canvas_manager.dummy_context,af=this.inc_slots[aj];if(!af||(af.mode!==ai)){af=new (s.FeatureSlotter)(aj,ai==="Pack",z,function(ak){return ah.measureText(ak)});af.mode=ai;this.inc_slots[aj]=af}return af.slot_features(ag)},get_summary_tree_data:function(aj,am,ah,av){if(av>ah-am){av=ah-am}var aq=Math.floor((ah-am)/av),au=[],ai=0;var ak=0,al=0,ap,at=0,an=[],ar,ao;var ag=function(ay,ax,az,aw){ay[0]=ax+az*aw;ay[1]=ax+(az+1)*aw};while(at<av&&ak!==aj.length){var af=false;for(;at<av&&!af;at++){ag(an,am,at,aq);for(al=ak;al<aj.length;al++){ap=aj[al].slice(1,3);if(is_overlap(ap,an)){af=true;break}}if(af){break}}data_start_index=al;au[au.length]=ar=[an[0],0];for(;al<aj.length;al++){ap=aj[al].slice(1,3);if(is_overlap(ap,an)){ar[1]++}else{break}}if(ar[1]>ai){ai=ar[1]}at++}return{max:ai,delta:aq,data:au}},draw_tile:function(au,ax,aB,aF,ap,ai){var ay=this,ak=ay._get_tile_bounds(aF,aB),aI=ak[0],ag=ak[1],aw=ag-aI,az=Math.ceil(aw*ap),aO=25,aj=this.left_offset,av,al;if(ax==="Auto"){if(au.dataset_type==="summary_tree"){ax=au.dataset_type}else{if(au.extra_info==="no_detail"||ay.is_overview){ax="no_detail"}else{var aN=au.data;if(this.view.high-this.view.low>J){ax="Squish"}else{ax="Pack"}}}this.update_auto_mode(ax)}if(ax==="summary_tree"||ax==="Histogram"){al=this.summary_draw_height;this.container_div.find(".yaxislabel").remove();var af=$("<div />").addClass("yaxislabel");af.text(au.max);af.css({position:"absolute",top:"24px",left:"10px",color:this.prefs.label_color});af.prependTo(this.container_div);var ah=this.view.canvas_manager.new_canvas();ah.width=az+aj;ah.height=al+T;if(au.dataset_type!="summary_tree"){var aq=this.get_summary_tree_data(au.data,aI,ag,200);if(au.max){aq.max=au.max}au=aq}var aK=new M.SummaryTreePainter(au,aI,ag,this.prefs);var aA=ah.getContext("2d");aA.translate(aj,T);aK.draw(aA,az,al);return new k(ay,aF,aB,ah,au.data,au.max)}var av,an=1;if(ax==="no_detail"||ax==="Squish"||ax==="Pack"){an=this.incremental_slots(ap,au.data,ax);av=this.inc_slots[ap].slots}var ao=[];if(au.data){var ar=this.filters_manager.filters;for(var aC=0,aE=au.data.length;aC<aE;aC++){var am=au.data[aC];var aD=false;var at;for(var aH=0,aM=ar.length;aH<aM;aH++){at=ar[aH];at.update_attrs(am);if(!at.keep(am)){aD=true;break}}if(!aD){ao.push(am)}}}var aL=(this.filters_manager.alpha_filter?new D(this.filters_manager.alpha_filter):null);var aJ=(this.filters_manager.height_filter?new D(this.filters_manager.height_filter):null);var aK=new (this.painter)(ao,aI,ag,this.prefs,ax,aL,aJ,ai);var al=Math.max(ad,aK.get_required_height(an));var ah=this.view.canvas_manager.new_canvas();var aG=null;ah.width=az+aj;ah.height=al;var aA=ah.getContext("2d");aA.fillStyle=this.prefs.block_color;aA.font=aA.canvas.manager.default_font;aA.textAlign="right";this.container_div.find(".yaxislabel").remove();if(au.data){aA.translate(aj,0);aG=aK.draw(aA,az,al,av);aG.translation=-aj}return new P(ay,aF,aB,ah,au.data,ax,au.message,aG)}});var U=function(ak,ah,ag,am,af,aj,al,ai){e.call(this,ak,ah,ag,am,af,aj,al,ai);this.config=new G({track:this,params:[{key:"name",label:"Name",type:"text",default_value:ak},{key:"block_color",label:"Block color",type:"color",default_value:get_random_color()},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_insertions",label:"Show insertions",type:"bool",default_value:false},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:aj,onchange:function(){this.track.set_name(this.track.prefs.name);this.track.tile_cache.clear();this.track.request_draw()}});this.prefs=this.config.values;this.painter=M.ReadPainter};p(U.prototype,q.prototype,N.prototype,e.prototype);var W=function(aj,ah,ag,al,af,ai,ak){e.call(this,aj,ah,ag,al,af,ai,ak);this.config=new G({track:this,params:[{key:"name",label:"Name",type:"text",default_value:aj},{key:"block_color",label:"Block color",type:"color",default_value:get_random_color()},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_insertions",label:"Show insertions",type:"bool",default_value:false},{key:"show_differences",label:"Show differences only",type:"bool",default_value:true},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:ai,onchange:function(){this.track.set_name(this.track.prefs.name);this.track.tile_cache.clear();this.track.request_draw()}});this.prefs=this.config.values;this.painter=M.ReadPainter;this.update_track_icons()};p(W.prototype,q.prototype,N.prototype,e.prototype);X.View=ac;X.DrawableGroup=Q;X.LineTrack=j;X.FeatureTrack=e;X.ReadTrack=W;X.VcfTrack=U};var slotting_module=function(c,b){var e=c("class").extend;var d=2,a=5;b.FeatureSlotter=function(i,h,f,g){this.slots={};this.start_end_dct={};this.w_scale=i;this.include_label=h;this.max_rows=f;this.measureText=g};e(b.FeatureSlotter.prototype,{slot_features:function(m){var p=this.w_scale,s=this.slots,h=this.start_end_dct,y=[],A=[],n=0,z=this.max_rows;for(var w=0,x=m.length;w<x;w++){var l=m[w],o=l[0];if(s[o]!==undefined){n=Math.max(n,s[o]);A.push(s[o])}else{y.push(w)}}var q=function(F,G){for(var E=0;E<=z;E++){var C=false,H=h[E];if(H!==undefined){for(var B=0,D=H.length;B<D;B++){var i=H[B];if(G>i[0]&&F<i[1]){C=true;break}}}if(!C){return E}}return -1};for(var w=0,x=y.length;w<x;w++){var l=m[y[w]],o=l[0],u=l[1],f=l[2],r=l[3],g=Math.floor(u*p),k=Math.ceil(f*p),v=this.measureText(r).width,j;if(r!==undefined&&this.include_label){v+=(d+a);if(g-v>=0){g-=v;j="left"}else{k+=v;j="right"}}var t=q(g,k);if(t>=0){if(h[t]===undefined){h[t]=[]}h[t].push([g,k]);s[o]=t;n=Math.max(n,t)}else{}}return n+1}})};var painters_module=function(i,w){var t=i("class").extend;var o=function(H,z,F,y,E,C){if(C===undefined){C=4}var B=y-z;var A=E-F;var D=Math.floor(Math.sqrt(B*B+A*A)/C);var I=B/D;var G=A/D;var x;for(x=0;x<D;x++,z+=I,F+=G){if(x%2!==0){continue}H.fillRect(z,F,C,1)}};var p=function(A,z,x,D){var C=z-D/2,B=z+D/2,E=x-Math.sqrt(D*3/2);A.beginPath();A.moveTo(C,E);A.lineTo(B,E);A.lineTo(z,x);A.lineTo(C,E);A.strokeStyle=this.fillStyle;A.fill();A.stroke();A.closePath()};var d=function(x){this.default_val=(x?x:1)};d.prototype.gen_val=function(x){return this.default_val};var l=function(z,B,x,y,A){this.data=z;this.view_start=B;this.view_end=x;this.prefs=t({},this.default_prefs,y);this.mode=A};l.prototype.default_prefs={};var u=function(z,B,x,y,A){l.call(this,z,B,x,y,A)};u.prototype.default_prefs={show_counts:false};u.prototype.draw=function(M,z,L){var E=this.view_start,O=this.view_end-this.view_start,N=z/O;var J=this.data.data,I=this.data.delta,G=this.data.max,B=L;delta_x_px=Math.ceil(I*N);M.save();for(var C=0,D=J.length;C<D;C++){var H=Math.floor((J[C][0]-E)*N);var F=J[C][1];if(!F){continue}var K=F/G*L;if(F!==0&&K<1){K=1}M.fillStyle=this.prefs.block_color;M.fillRect(H,B-K,delta_x_px,K);var A=4;if(this.prefs.show_counts&&(M.measureText(F).width+A)<delta_x_px){M.fillStyle=this.prefs.label_color;M.textAlign="center";M.fillText(F,H+(delta_x_px/2),10)}}M.restore()};var b=function(x,B,D,E,z){l.call(this,x,B,D,E,z);if(this.prefs.min_value===undefined){var F=Infinity;for(var y=0,A=this.data.length;y<A;y++){F=Math.min(F,this.data[y][1])}this.prefs.min_value=F}if(this.prefs.max_value===undefined){var C=-Infinity;for(var y=0,A=this.data.length;y<A;y++){C=Math.max(C,this.data[y][1])}this.prefs.max_value=C}};b.prototype.default_prefs={min_value:undefined,max_value:undefined,mode:"Histogram",color:"#000",overflow_color:"#F66"};b.prototype.draw=function(M,L,J){var E=false,G=this.prefs.min_value,C=this.prefs.max_value,I=C-G,x=J,z=this.view_start,K=this.view_end-this.view_start,A=L/K,H=this.mode,S=this.data;M.save();var T=Math.round(J+G/I*J);if(H!=="Intensity"){M.fillStyle="#aaa";M.fillRect(0,T,L,1)}M.beginPath();var Q,D,B;if(S.length>1){B=Math.ceil((S[1][0]-S[0][0])*A)}else{B=10}for(var N=0,O=S.length;N<O;N++){M.fillStyle=this.prefs.color;Q=Math.round((S[N][0]-z)*A);D=S[N][1];var P=false,F=false;if(D===null){if(E&&H==="Filled"){M.lineTo(Q,x)}E=false;continue}if(D<G){F=true;D=G}else{if(D>C){P=true;D=C}}if(H==="Histogram"){D=Math.round(D/I*x);M.fillRect(Q,T,B,-D)}else{if(H==="Intensity"){D=255-Math.floor((D-G)/I*255);M.fillStyle="rgb("+D+","+D+","+D+")";M.fillRect(Q,0,B,x)}else{D=Math.round(x-(D-G)/I*x);if(E){M.lineTo(Q,D)}else{E=true;if(H==="Filled"){M.moveTo(Q,x);M.lineTo(Q,D)}else{M.moveTo(Q,D)}}}}M.fillStyle=this.prefs.overflow_color;if(P||F){var R;if(H==="Histogram"||H==="Intensity"){R=B}else{Q-=2;R=4}if(P){M.fillRect(Q,0,R,3)}if(F){M.fillRect(Q,x-3,R,3)}}M.fillStyle=this.prefs.color}if(H==="Filled"){if(E){M.lineTo(Q,T);M.lineTo(0,T)}M.fill()}else{M.stroke()}M.restore()};var m=function(x){this.feature_positions={};this.slot_height=x;this.translation=0};m.prototype.map_feature_data=function(y,A,x,z){if(!this.feature_positions[A]){this.feature_positions[A]=[]}this.feature_positions[A].push({data:y,x_start:x,x_end:z})};m.prototype.get_feature_data=function(z,D){var C=Math.floor(D/this.slot_height),B;if(!this.feature_positions[C]){return null}z+=this.translation;for(var A=0;A<this.feature_positions[C].length;A++){B=this.feature_positions[C][A];if(z>=B.x_start&&z<=B.x_end){return B.data}}};var n=function(z,C,x,y,B,D,A){l.call(this,z,C,x,y,B);this.alpha_scaler=(D?D:new d());this.height_scaler=(A?A:new d())};n.prototype.default_prefs={block_color:"#FFF",connector_color:"#FFF"};t(n.prototype,{get_required_height:function(y){var x=y_scale=this.get_row_height(),z=this.mode;if(z==="no_detail"||z==="Squish"||z==="Pack"){x=y*y_scale}return x+Math.max(Math.round(y_scale/2),5)},draw:function(J,H,F,E){var P=this.data,C=this.view_start,L=this.view_end;J.save();J.fillStyle=this.prefs.block_color;J.textAlign="right";var G=this.view_end-this.view_start,D=H/G,K=this.get_row_height(),O=new m(K),A;for(var M=0,N=P.length;M<N;M++){var z=P[M],B=z[0],I=z[1],x=z[2],y=(E&&E[B]!==undefined?E[B]:null);if((I<L&&x>C)&&(this.mode=="Dense"||y!==null)){A=this.draw_element(J,this.mode,z,y,C,L,D,K,H);O.map_feature_data(z,y,A[0],A[1])}}J.restore();return O},draw_element:function(D,z,F,B,A,C,E,y,x){console.log("WARNING: Unimplemented function.");return[0,0]}});var c=10,h=3,k=5,v=10,f=1,r=3,e=3,a=9,j=2,g="#ccc";var q=function(z,C,x,y,B,D,A){n.call(this,z,C,x,y,B,D,A)};t(q.prototype,n.prototype,{get_row_height:function(){var y=this.mode,x;if(y==="Dense"){x=c}else{if(y==="no_detail"){x=h}else{if(y==="Squish"){x=k}else{x=v}}}return x},draw_element:function(L,C,U,G,N,af,aj,al,x){var R=U[0],ah=U[1],Z=U[2],P=U[3],aa=Math.floor(Math.max(0,(ah-N)*aj)),M=Math.ceil(Math.min(x,Math.max(0,(Z-N)*aj))),Y=aa,ak=M,X=(C==="Dense"?0:(0+G))*al,K,ad,Q=null,an=null,A=this.prefs.block_color,ac=this.prefs.label_color;L.globalAlpha=this.alpha_scaler.gen_val(U);if(C==="Dense"){G=1}if(C==="no_detail"){L.fillStyle=A;L.fillRect(aa,X+5,M-aa,f)}else{var J=U[4],W=U[5],ab=U[6],B=U[7];if(W&&ab){Q=Math.floor(Math.max(0,(W-N)*aj));an=Math.ceil(Math.min(x,Math.max(0,(ab-N)*aj)))}var ai,S;if(C==="Squish"||C==="Dense"){ai=1;S=e}else{ai=5;S=a}if(!B){if(U.strand){if(U.strand==="+"){L.fillStyle=L.canvas.manager.get_pattern("right_strand_inv")}else{if(U.strand==="-"){L.fillStyle=L.canvas.manager.get_pattern("left_strand_inv")}}}else{L.fillStyle=A}L.fillRect(aa,X,M-aa,S)}else{var I,T;if(C==="Squish"||C==="Dense"){L.fillStyle=g;I=X+Math.floor(e/2)+1;T=1}else{if(J){var I=X;var T=S;if(J==="+"){L.fillStyle=L.canvas.manager.get_pattern("right_strand")}else{if(J==="-"){L.fillStyle=L.canvas.manager.get_pattern("left_strand")}}}else{L.fillStyle=g;I+=(e/2)+1;T=1}}L.fillRect(aa,I,M-aa,T);var D;for(var ag=0,z=B.length;ag<z;ag++){var E=B[ag],y=Math.floor(Math.max(0,(E[0]-N)*aj)),V=Math.ceil(Math.min(x,Math.max((E[1]-N)*aj)));if(y>V){continue}L.fillStyle=A;L.fillRect(y,X+(S-ai)/2+1,V-y,ai);if(Q!==undefined&&ab>W&&!(y>an||V<Q)){var ae=Math.max(y,Q),H=Math.min(V,an);L.fillRect(ae,X+1,H-ae,S);if(B.length==1&&C=="Pack"){if(J==="+"){L.fillStyle=L.canvas.manager.get_pattern("right_strand_inv")}else{if(J==="-"){L.fillStyle=L.canvas.manager.get_pattern("left_strand_inv")}}if(ae+14<H){ae+=2;H-=2}L.fillRect(ae,X+1,H-ae,S)}}}if(C==="Pack"){L.globalAlpha=1;L.fillStyle="white";var F=this.height_scaler.gen_val(U),O=Math.ceil(S*F),am=Math.round((S-O)/2);if(F!==1){L.fillRect(aa,I+1,M-aa,am);L.fillRect(aa,I+S-am+1,M-aa,am)}}}L.globalAlpha=1;if(C==="Pack"&&ah>N){L.fillStyle=ac;if(N===0&&aa-L.measureText(P).width<0){L.textAlign="left";L.fillText(P,M+j,X+8);ak+=L.measureText(P).width+j}else{L.textAlign="right";L.fillText(P,aa-j,X+8);Y-=L.measureText(P).width+j}}}L.globalAlpha=1;return[Y,ak]}});var s=function(A,D,x,z,C,E,B,y){n.call(this,A,D,x,z,C,E,B);this.ref_seq=(y?y.data:null)};s.prototype.default_prefs=t({},n.prototype.default_prefs,{show_insertions:false});t(s.prototype,n.prototype,{get_row_height:function(){var x,y=this.mode;if(y==="Dense"){x=c}else{if(y==="Squish"){x=k}else{x=v;if(this.prefs.show_insertions){x*=2}}}return x},draw_read:function(U,P,L,Z,A,T,I,F,E){U.textAlign="center";var S=this,z=[Z,A],O=0,V=0,R=0,x=U.canvas.manager.char_width_px;var ae=[];if((P==="Pack"||this.mode==="Auto")&&F!==undefined&&L>x){R=Math.round(L/2)}if(!I){I=[[0,F.length]]}for(var M=0,X=I.length;M<X;M++){var J=I[M],B="MIDNSHP=X"[J[0]],N=J[1];if(B==="H"||B==="S"){O-=N}var G=T+O,ad=Math.floor(Math.max(0,(G-Z)*L)),H=Math.floor(Math.max(0,(G+N-Z)*L));if(ad===H){H+=1}switch(B){case"H":break;case"S":case"M":case"=":if(is_overlap([G,G+N],z)){var Q=F.slice(V,V+N);if(R>0){U.fillStyle=this.prefs.block_color;U.fillRect(ad-R,E+1,H-ad,9);U.fillStyle=g;for(var ab=0,y=Q.length;ab<y;ab++){if(this.prefs.show_differences&&this.ref_seq){var K=this.ref_seq[G-Z+ab];if(!K||K.toLowerCase()===Q[ab].toLowerCase()){continue}}if(G+ab>=Z&&G+ab<=A){var ac=Math.floor(Math.max(0,(G+ab-Z)*L));U.fillText(Q[ab],ac,E+9)}}}else{U.fillStyle=this.prefs.block_color;U.fillRect(ad,E+4,H-ad,e)}}V+=N;O+=N;break;case"N":U.fillStyle=g;U.fillRect(ad-R,E+5,H-ad,1);O+=N;break;case"D":U.fillStyle="red";U.fillRect(ad-R,E+4,H-ad,3);O+=N;break;case"P":break;case"I":var Y=ad-R;if(is_overlap([G,G+N],z)){var Q=F.slice(V,V+N);if(this.prefs.show_insertions){var D=ad-(H-ad)/2;if((P==="Pack"||this.mode==="Auto")&&F!==undefined&&L>x){U.fillStyle="yellow";U.fillRect(D-R,E-9,H-ad,9);ae[ae.length]={type:"triangle",data:[Y,E+4,5]};U.fillStyle=g;switch(compute_overlap([G,G+N],z)){case (OVERLAP_START):Q=Q.slice(Z-G);break;case (OVERLAP_END):Q=Q.slice(0,G-A);break;case (CONTAINED_BY):break;case (CONTAINS):Q=Q.slice(Z-G,G-A);break}for(var ab=0,y=Q.length;ab<y;ab++){var ac=Math.floor(Math.max(0,(G+ab-Z)*L));U.fillText(Q[ab],ac-(H-ad)/2,E)}}else{U.fillStyle="yellow";U.fillRect(D,E+(this.mode!=="Dense"?2:5),H-ad,(P!=="Dense"?e:r))}}else{if((P==="Pack"||this.mode==="Auto")&&F!==undefined&&L>x){ae.push({type:"text",data:[Q.length,Y,E+9]})}else{}}}V+=N;break;case"X":V+=N;break}}U.fillStyle="yellow";var aa,C,af;for(var W=0;W<ae.length;W++){aa=ae[W];C=aa.type;af=aa.data;if(C==="text"){U.save();U.font="bold "+U.font;U.fillText(af[0],af[1],af[2]);U.restore()}else{if(C=="triangle"){p(U,af[0],af[1],af[2])}}}},draw_element:function(Q,L,D,A,T,y,H,R,O){var G=D[0],P=D[1],z=D[2],I=D[3],C=Math.floor(Math.max(0,(P-T)*H)),E=Math.ceil(Math.min(O,Math.max(0,(z-T)*H))),B=(L==="Dense"?0:(0+A))*R,U=this.prefs.block_color,F=this.prefs.label_color,N=0;if((L==="Pack"||this.mode==="Auto")&&H>Q.canvas.manager.char_width_px){var N=Math.round(H/2)}Q.fillStyle=U;if(D[5] instanceof Array){var M=Math.floor(Math.max(0,(D[4][0]-T)*H)),K=Math.ceil(Math.min(O,Math.max(0,(D[4][1]-T)*H))),J=Math.floor(Math.max(0,(D[5][0]-T)*H)),x=Math.ceil(Math.min(O,Math.max(0,(D[5][1]-T)*H)));if(D[4][1]>=T&&D[4][0]<=y&&D[4][2]){this.draw_read(Q,L,H,T,y,D[4][0],D[4][2],D[4][3],B)}if(D[5][1]>=T&&D[5][0]<=y&&D[5][2]){this.draw_read(Q,L,H,T,y,D[5][0],D[5][2],D[5][3],B)}if(J>K){Q.fillStyle=g;o(Q,K-N,B+5,J-N,B+5)}}else{Q.fillStyle=U;this.draw_read(Q,L,H,T,y,P,D[4],D[5],B)}if(L==="Pack"&&P>T&&I!=="."){Q.fillStyle=this.prefs.label_color;var S=1;if(S===0&&C-Q.measureText(I).width<0){Q.textAlign="left";Q.fillText(I,E+j-N,B+8)}else{Q.textAlign="right";Q.fillText(I,C-j-N,B+8)}Q.fillStyle=U}return[0,0]}});w.Scaler=d;w.SummaryTreePainter=u;w.LinePainter=b;w.LinkedFeaturePainter=q;w.ReadPainter=s};(function(d){var c={};var b=function(e){return c[e]};var a=function(f,g){var e={};g(b,e);c[f]=e};a("class",class_module);a("slotting",slotting_module);a("painters",painters_module);a("trackster",trackster_module);for(key in c.trackster){d[key]=c.trackster[key]}})(window); \ No newline at end of file diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 static/scripts/packed/trackster_ui.js --- a/static/scripts/packed/trackster_ui.js +++ b/static/scripts/packed/trackster_ui.js @@ -1,1 +1,1 @@ -var add_bookmark=function(b,a){var g=$("#bookmarks-container"),d=$("<div/>").addClass("bookmark").appendTo(g),c=$("<div/>").addClass("delete-icon-container").appendTo(d).click(function(){d.slideUp("fast");d.remove();view.has_changes=true;return false}),e=$("<a href=''/>").addClass("icon-button delete").appendTo(c),f=$("<div/>").addClass("position").appendTo(d),h=$("<a href=''/>").text(b).appendTo(f).click(function(){view.go_to(b);return false});annotation_div=get_editable_text_elt(a,true).addClass("annotation").appendTo(d);view.has_changes=true;return d};var addable_objects={LineTrack:LineTrack,FeatureTrack:FeatureTrack,ReadTrack:ReadTrack,DrawableGroup:DrawableGroup};var track_from_dict=function(c,b){var a=new addable_objects[c.track_type](c.name,view,b,c.hda_ldda,c.dataset_id,c.prefs,c.filters,c.tool);if(c.mode){a.change_mode(c.mode)}return a};var drawable_collection_from_dict=function(f,a){var e=new addable_objects[f.obj_type](f.name,view,a,f.prefs,view.viewport_container,view);for(var d=0;d<f.drawables.length;d++){var b=f.drawables[d],c;if(b.track_type){c=track_from_dict(b,e)}else{c=drawable_collection_from_dict(b)}e.add_drawable(c);e.content_div.append(c.container_div)}return e};var drawable_from_dict=function(b,a){return(b.track_type?track_from_dict(b,a):drawable_collection_from_dict(b,a))};var create_visualization=function(b,e,g,c,a,d,f){view=new View(b,e,g,c);view.editor=true;$.when(view.load_chroms_deferred).then(function(){if(a){var k=a.chrom,p=a.start,h=a.end,m=a.overview;if(k&&(p!==undefined)&&h){view.change_chrom(k,p,h)}}if(d){var o;for(var j=0;j<d.length;j++){o=d[j];view.add_drawable(drawable_from_dict(o,view))}}var n;for(var j=0;j<view.drawables.length;j++){if(view.drawables[j].name===m){view.set_overview(view.drawables[j]);break}}if(f){var l;for(var j=0;j<f.length;j++){l=f[j];add_bookmark(l.position,l.annotation)}}view.has_changes=false});return view};var init_keyboard_nav=function(a){$(document).keydown(function(b){if($(b.srcElement).is(":input")){return}switch(b.which){case 37:a.move_fraction(0.25);break;case 38:var c=Math.round(a.viewport_container.height()/15);a.viewport_container.scrollTo("-="+c+"px");break;case 39:a.move_fraction(-0.25);break;case 40:var c=Math.round(a.viewport_container.height()/15);a.viewport_container.scrollTo("+="+c+"px");break}})}; \ No newline at end of file +var add_bookmark=function(b,a){var g=$("#bookmarks-container"),d=$("<div/>").addClass("bookmark").appendTo(g),c=$("<div/>").addClass("delete-icon-container").appendTo(d).click(function(){d.slideUp("fast");d.remove();view.has_changes=true;return false}),e=$("<a href=''/>").addClass("icon-button delete").appendTo(c),f=$("<div/>").addClass("position").appendTo(d),h=$("<a href=''/>").text(b).appendTo(f).click(function(){view.go_to(b);return false});annotation_div=get_editable_text_elt(a,true).addClass("annotation").appendTo(d);view.has_changes=true;return d};var addable_objects={LineTrack:LineTrack,FeatureTrack:FeatureTrack,VcfTrack:VcfTrack,ReadTrack:ReadTrack,DrawableGroup:DrawableGroup};var track_from_dict=function(c,b){var a=new addable_objects[c.track_type](c.name,view,b,c.hda_ldda,c.dataset_id,c.prefs,c.filters,c.tool);if(c.mode){a.change_mode(c.mode)}return a};var drawable_collection_from_dict=function(f,a){var e=new addable_objects[f.obj_type](f.name,view,a,f.prefs,view.viewport_container,view);for(var d=0;d<f.drawables.length;d++){var b=f.drawables[d],c;if(b.track_type){c=track_from_dict(b,e)}else{c=drawable_collection_from_dict(b)}e.add_drawable(c);e.content_div.append(c.container_div)}return e};var drawable_from_dict=function(b,a){return(b.track_type?track_from_dict(b,a):drawable_collection_from_dict(b,a))};var create_visualization=function(b,e,g,c,a,d,f){view=new View(b,e,g,c);view.editor=true;$.when(view.load_chroms_deferred).then(function(){if(a){var k=a.chrom,p=a.start,h=a.end,m=a.overview;if(k&&(p!==undefined)&&h){view.change_chrom(k,p,h)}}if(d){var o;for(var j=0;j<d.length;j++){o=d[j];view.add_drawable(drawable_from_dict(o,view))}}var n;for(var j=0;j<view.drawables.length;j++){if(view.drawables[j].name===m){view.set_overview(view.drawables[j]);break}}if(f){var l;for(var j=0;j<f.length;j++){l=f[j];add_bookmark(l.position,l.annotation)}}view.has_changes=false});return view};var init_keyboard_nav=function(a){$(document).keydown(function(b){if($(b.srcElement).is(":input")){return}switch(b.which){case 37:a.move_fraction(0.25);break;case 38:var c=Math.round(a.viewport_container.height()/15);a.viewport_container.scrollTo("-="+c+"px");break;case 39:a.move_fraction(-0.25);break;case 40:var c=Math.round(a.viewport_container.height()/15);a.viewport_container.scrollTo("+="+c+"px");break}})}; \ No newline at end of file diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 static/scripts/trackster.js --- a/static/scripts/trackster.js +++ b/static/scripts/trackster.js @@ -654,6 +654,8 @@ * associated with a view and container. They optionally have a drag handle class. */ var Drawable = function(name, view, container, prefs, drag_handle_class) { + if (!Drawable.id_counter) { Drawable.id_counter = 0; } + this.id = Drawable.id_counter++; this.name = name; this.view = view; this.container = container; @@ -677,7 +679,7 @@ request_draw: function() {}, _draw: function() {}, to_json: function() {}, - update_track_icons: function() {}, + update_icons: function() {}, /** * Set drawable name. */ @@ -804,13 +806,11 @@ DrawableCollection.call(this, "DrawableGroup", name, view, container, prefs, "group-handle"); // HTML elements. - if (!DrawableGroup.id_counter) { DrawableGroup.id_counter = 0; } - var group_id = DrawableGroup.id_counter++ - this.container_div = $("<div/>").addClass("group").attr("id", "group_" + group_id).appendTo(this.container.content_div); + this.container_div = $("<div/>").addClass("group").attr("id", "group_" + this.id).appendTo(this.container.content_div); this.header_div = $("<div/>").addClass("track-header").appendTo(this.container_div); this.header_div.append($("<div/>").addClass(this.drag_handle_class)); this.name_div = $("<div/>").addClass("group-name menubutton popup").text(this.name).appendTo(this.header_div); - this.content_div = $("<div/>").addClass("content-div").attr("id", "group_" + group_id + "_content_div").appendTo(this.container_div); + this.content_div = $("<div/>").addClass("content-div").attr("id", "group_" + this.id + "_content_div").appendTo(this.container_div); // Set up containers/moving for group: register both container_div and content div as container // because both are used as containers (container div to recognize container, content_div to @@ -819,14 +819,14 @@ is_container(this.content_div, this); moveable(this.container_div, this.drag_handle_class, ".group", this); - this.update_track_icons(); + this.update_icons(); }; extend(DrawableGroup.prototype, Drawable.prototype, DrawableCollection.prototype, { /** * Make popup menu for group. */ - update_track_icons: function() { + update_icons: function() { var group = this; var group_dropdown = {}; @@ -941,7 +941,7 @@ } }; this.nav_input = $("<input/>").addClass("nav-input").hide().bind("keyup focusout", submit_nav).appendTo(this.nav_controls); - this.location_span = $("<span/>").addClass("location").appendTo(this.nav_controls); + this.location_span = $("<span/>").addClass("location").attr('original-title', 'Click to change location').tipsy( { gravity: 'n' } ).appendTo(this.nav_controls); this.location_span.click(function() { view.location_span.hide(); view.chrom_select.hide(); @@ -953,8 +953,11 @@ if (this.vis_id !== undefined) { this.hidden_input = $("<input/>").attr("type", "hidden").val(this.vis_id).appendTo(this.nav_controls); } - this.zo_link = $("<a id='zoom-out' />").click(function() { view.zoom_out(); view.request_redraw(); }).appendTo(this.nav_controls); - this.zi_link = $("<a id='zoom-in' />").click(function() { view.zoom_in(); view.request_redraw(); }).appendTo(this.nav_controls); + + this.zo_link = $("<a/>").attr("id", "zoom-out").attr("title", "Zoom out").tipsy( {gravity: 'n'} ) + .click(function() { view.zoom_out(); view.request_redraw(); }).appendTo(this.nav_controls); + this.zi_link = $("<a/>").attr("id", "zoom-in").attr("title", "Zoom in").tipsy( {gravity: 'n'} ) + .click(function() { view.zoom_in(); view.request_redraw(); }).appendTo(this.nav_controls); // Get initial set of chroms. this.load_chroms_deferred = this.load_chroms({low: 0}); @@ -1069,11 +1072,10 @@ this.reset(); $(window).trigger("resize"); - this.update_intro_div(); }, /** Add or remove intro div depending on view state. */ update_intro_div: function() { - if (this.num_tracks === 0) { + if (this.drawables.length === 0) { this.intro_div.appendTo(this.viewport_container); } else { @@ -1577,8 +1579,7 @@ // Set name of track to include tool name, parameters, and region used. track_name = url_params.tool_id + current_track.tool_region_and_parameters_str(url_params.chrom, url_params.low, url_params.high), - container, - new_track; + container; // If track not in a group, create a group for it and add new track to group. If track // already in group, add track to group. @@ -1595,11 +1596,12 @@ else { container = current_track.container; } - if (current_track instanceof FeatureTrack) { - new_track = new ToolDataFeatureTrack(track_name, view, container, "hda"); - new_track.change_mode(current_track.mode); - container.add_drawable(new_track); - } + + // Create and init new track. + var new_track = new current_track.constructor(track_name, view, container, "hda"); + new_track.init_for_tool_data(); + new_track.change_mode(current_track.mode); + container.add_drawable(new_track); new_track.content_div.text("Starting job."); // Run tool. @@ -2316,7 +2318,6 @@ * ----> ReferenceTrack * ----> FeatureTrack * -------> ReadTrack - * -------> ToolDataFeatureTrack * -------> VcfTrack */ var Track = function(name, view, container, show_header, prefs, data_url, data_query_wait) { @@ -2330,9 +2331,6 @@ this.data_url_extra_params = {} this.data_query_wait = (data_query_wait ? data_query_wait : DEFAULT_DATA_QUERY_WAIT); this.dataset_check_url = converted_datasets_state_url; - - if (!Track.id_counter) { Track.id_counter = 0; } - this.id = Track.id_counter++; // // Create HTML element structure for track. @@ -2476,9 +2474,6 @@ else if (this instanceof ReadTrack) { return "ReadTrack"; } - else if (this instanceof ToolDataFeatureTrack) { - return "ToolDataFeatureTrack"; - } else if (this instanceof VcfTrack) { return "VcfTrack"; } @@ -2538,7 +2533,7 @@ } else if (result['status'] === "data") { if (result['valid_chroms']) { track.valid_chroms = result['valid_chroms']; - track.update_track_icons(); + track.update_icons(); } track.content_div.text(DATA_OK); if (track.view.chrom) { @@ -2554,7 +2549,7 @@ } }); - this.update_track_icons(); + this.update_icons(); }, /** * Additional initialization required before drawing track for the first time. @@ -2562,8 +2557,8 @@ predraw_init: function() {} }); -var TiledTrack = function(name, view, container, show_header, prefs, filters_list, tool_dict, data_url, data_query_wait) { - Track.call(this, name, view, container, show_header, prefs, data_url, data_query_wait); +var TiledTrack = function(name, view, container, show_header, prefs, filters_list, tool_dict) { + Track.call(this, name, view, container, show_header, prefs); var track = this, view = track.view; @@ -2632,7 +2627,7 @@ /** * Update track's buttons. */ - update_track_icons: function() { + update_icons: function() { var track = this; // @@ -2910,6 +2905,39 @@ region = (chrom !== undefined && low !== undefined && high !== undefined ? chrom + ":" + low + "-" + high : "all"); return " - region=[" + region + "], parameters=[" + track.tool.get_param_values().join(", ") + "]"; + }, + /** + * Set up track to receive tool data. + */ + init_for_tool_data: function() { + // Set up track to fetch initial data from raw data URL when the dataset--not the converted datasets-- + // is ready. + this.data_url = raw_data_url; + this.data_query_wait = 1000; + this.dataset_check_url = dataset_state_url; + + /** + * Predraw init sets up postdraw init. + */ + this.predraw_init = function() { + // Postdraw init: once data has been fetched, reset data url, wait time and start indexing. + var track = this; + var post_init = function() { + if (track.data_manager.size() === 0) { + // Track still drawing initial data, so do nothing. + setTimeout(post_init, 300); + } + else { + // Track drawing done: reset dataset check, data URL, wait time and get dataset state to start + // indexing. + track.data_url = default_data_url; + track.data_query_wait = DEFAULT_DATA_QUERY_WAIT; + track.dataset_state_url = converted_datasets_state_url; + $.getJSON(track.dataset_state_url, {dataset_id : track.dataset_id, hda_ldda: track.hda_ldda}, function(track_data) {}); + } + }; + post_init(); + } } }); @@ -3261,7 +3289,7 @@ if (!track.filters_available) { track.filters_div.hide(); } - track.update_track_icons(); + track.update_icons(); } } }, @@ -3524,16 +3552,8 @@ } }); -var VcfTrack = function(name, view, container, hda_ldda, dataset_id, prefs, filters) { - FeatureTrack.call(this, name, view, container, hda_ldda, dataset_id, prefs, filters); - this.painter = painters.VariantPainter; -}; - -extend(VcfTrack.prototype, Drawable.prototype, TiledTrack.prototype, FeatureTrack.prototype); - - -var ReadTrack = function (name, view, container, hda_ldda, dataset_id, prefs, filters) { - FeatureTrack.call(this, name, view, container, hda_ldda, dataset_id, prefs, filters); +var VcfTrack = function(name, view, container, hda_ldda, dataset_id, prefs, filters, tool) { + FeatureTrack.call(this, name, view, container, hda_ldda, dataset_id, prefs, filters, tool); this.config = new DrawableConfig( { track: this, @@ -3542,6 +3562,37 @@ { key: 'block_color', label: 'Block color', type: 'color', default_value: get_random_color() }, { key: 'label_color', label: 'Label color', type: 'color', default_value: 'black' }, { key: 'show_insertions', label: 'Show insertions', type: 'bool', default_value: false }, + { key: 'show_counts', label: 'Show summary counts', type: 'bool', default_value: true }, + { key: 'mode', type: 'string', default_value: this.mode, hidden: true }, + ], + saved_values: prefs, + onchange: function() { + this.track.set_name(this.track.prefs.name); + this.track.tile_cache.clear(); + this.track.request_draw(); + } + }); + this.prefs = this.config.values; + + this.painter = painters.ReadPainter; +}; + +extend(VcfTrack.prototype, Drawable.prototype, TiledTrack.prototype, FeatureTrack.prototype); + +var ReadTrack = function (name, view, container, hda_ldda, dataset_id, prefs, filters) { + FeatureTrack.call(this, name, view, container, hda_ldda, dataset_id, prefs, filters); + + var + block_color = get_random_color(), + reverse_strand_color = get_random_color( [ block_color, "#ffffff" ] ); + this.config = new DrawableConfig( { + track: this, + params: [ + { key: 'name', label: 'Name', type: 'text', default_value: name }, + { key: 'block_color', label: 'Block and sense strand color', type: 'color', default_value: block_color }, + { key: 'reverse_strand_color', label: 'Antisense strand color', type: 'color', default_value: reverse_strand_color }, + { key: 'label_color', label: 'Label color', type: 'color', default_value: 'black' }, + { key: 'show_insertions', label: 'Show insertions', type: 'bool', default_value: false }, { key: 'show_differences', label: 'Show differences only', type: 'bool', default_value: true }, { key: 'show_counts', label: 'Show summary counts', type: 'bool', default_value: true }, { key: 'mode', type: 'string', default_value: this.mode, hidden: true }, @@ -3556,48 +3607,10 @@ this.prefs = this.config.values; this.painter = painters.ReadPainter; - this.update_track_icons(); + this.update_icons(); }; extend(ReadTrack.prototype, Drawable.prototype, TiledTrack.prototype, FeatureTrack.prototype); -/** - * Feature track that displays data generated from tool. - */ -var ToolDataFeatureTrack = function(name, view, container, hda_ldda, dataset_id, prefs, filters) { - FeatureTrack.call(this, name, view, container, hda_ldda, dataset_id, prefs, filters, {}); - - // Set up track to fetch initial data from raw data URL when the dataset--not the converted datasets-- - // is ready. - this.data_url = raw_data_url; - this.data_query_wait = 1000; - this.dataset_check_url = dataset_state_url; -}; - -extend(ToolDataFeatureTrack.prototype, Drawable.prototype, TiledTrack.prototype, FeatureTrack.prototype, { - /** - * For this track type, the predraw init sets up postdraw init. - */ - predraw_init: function() { - // Postdraw init: once data has been fetched, reset data url, wait time and start indexing. - var track = this; - var post_init = function() { - if (track.data_manager.size() === 0) { - // Track still drawing initial data, so do nothing. - setTimeout(post_init, 300); - } - else { - // Track drawing done: reset dataset check, data URL, wait time and get dataset state to start - // indexing. - track.data_url = default_data_url; - track.data_query_wait = DEFAULT_DATA_QUERY_WAIT; - track.dataset_state_url = converted_datasets_state_url; - $.getJSON(track.dataset_state_url, {dataset_id : track.dataset_id, hda_ldda: track.hda_ldda}, function(track_data) {}); - } - }; - post_init(); - } -}); - // Exports exports.View = View; @@ -3605,6 +3618,7 @@ exports.LineTrack = LineTrack; exports.FeatureTrack = FeatureTrack; exports.ReadTrack = ReadTrack; +exports.VcfTrack = VcfTrack; // End trackster_module encapsulation }; @@ -4173,20 +4187,20 @@ * Height of a single row, depends on mode */ get_row_height: function() { - var mode = this.mode, y_scale; + var mode = this.mode, height; if (mode === "Dense") { - y_scale = DENSE_TRACK_HEIGHT; + height = DENSE_TRACK_HEIGHT; } else if (mode === "no_detail") { - y_scale = NO_DETAIL_TRACK_HEIGHT; + height = NO_DETAIL_TRACK_HEIGHT; } else if (mode === "Squish") { - y_scale = SQUISH_TRACK_HEIGHT; + height = SQUISH_TRACK_HEIGHT; } else { // mode === "Pack" - y_scale = PACK_TRACK_HEIGHT; + height = PACK_TRACK_HEIGHT; } - return y_scale; + return height; }, /** @@ -4212,7 +4226,7 @@ ctx.globalAlpha = this.alpha_scaler.gen_val(feature); // In dense mode, put all data in top slot. - if (mode == "Dense") { + if (mode === "Dense") { slot = 1; } @@ -4375,104 +4389,44 @@ } }); - -var VariantPainter = function(data, view_start, view_end, prefs, mode, alpha_scaler, height_scaler) { - FeaturePainter.call(this, data, view_start, view_end, prefs, mode, alpha_scaler, height_scaler); -} - -extend(VariantPainter.prototype, FeaturePainter.prototype, { - draw_element: function(ctx, mode, feature, slot, tile_low, tile_high, w_scale, y_scale, width) { - var feature = data[i], - feature_uid = feature[0], - feature_start = feature[1], - feature_end = feature[2], - feature_name = feature[3], - // All features need a start, end, and vertical center. - f_start = Math.floor( Math.max(0, (feature_start - tile_low) * w_scale) ), - f_end = Math.ceil( Math.min(width, Math.max(0, (feature_end - tile_low) * w_scale)) ), - y_center = (mode === "Dense" ? 0 : (0 + slot)) * y_scale, - thickness, y_start, thick_start = null, thick_end = null; - - if (no_label) { - ctx.fillStyle = block_color; - ctx.fillRect(f_start + left_offset, y_center + 5, f_end - f_start, 1); - } - else { // Show blocks, labels, etc. - // Unpack. - var ref_base = feature[4], alt_base = feature[5], qual = feature[6]; - - // Draw block for entry. - thickness = 9; - y_start = 1; - ctx.fillRect(f_start + left_offset, y_center, f_end - f_start, thickness); - - // Add label for entry. - if (mode !== "Dense" && feature_name !== undefined && feature_start > tile_low) { - // Draw label - ctx.fillStyle = label_color; - if (tile_low === 0 && f_start - ctx.measureText(feature_name).width < 0) { - ctx.textAlign = "left"; - ctx.fillText(feature_name, f_end + 2 + left_offset, y_center + 8); - } else { - ctx.textAlign = "right"; - ctx.fillText(feature_name, f_start - 2 + left_offset, y_center + 8); - } - ctx.fillStyle = block_color; - } - - // Show additional data on block. - var vcf_label = ref_base + " / " + alt_base; - if (feature_start > tile_low && ctx.measureText(vcf_label).width < (f_end - f_start)) { - ctx.fillStyle = "white"; - ctx.textAlign = "center"; - ctx.fillText(vcf_label, left_offset + f_start + (f_end-f_start)/2, y_center + 8); - ctx.fillStyle = block_color; - } - } - - return [f_start, f_end]; - } -}); - var ReadPainter = function(data, view_start, view_end, prefs, mode, alpha_scaler, height_scaler, ref_seq) { FeaturePainter.call(this, data, view_start, view_end, prefs, mode, alpha_scaler, height_scaler); this.ref_seq = (ref_seq ? ref_seq.data : null); }; -ReadPainter.prototype.default_prefs = extend({}, FeaturePainter.prototype.default_prefs, { show_insertions: false }); - extend(ReadPainter.prototype, FeaturePainter.prototype, { /** - * Returns y_scale based on mode. + * Returns height based on mode. */ get_row_height: function() { - var y_scale, mode = this.mode; + var height, mode = this.mode; if (mode === "Dense") { - y_scale = DENSE_TRACK_HEIGHT; + height = DENSE_TRACK_HEIGHT; } else if (mode === "Squish") { - y_scale = SQUISH_TRACK_HEIGHT; + height = SQUISH_TRACK_HEIGHT; } else { // mode === "Pack" - y_scale = PACK_TRACK_HEIGHT; + height = PACK_TRACK_HEIGHT; if (this.prefs.show_insertions) { - y_scale *= 2; + height *= 2; } } - return y_scale; + return height; }, /** * Draw a single read. */ - draw_read: function(ctx, mode, w_scale, tile_low, tile_high, feature_start, cigar, orig_seq, y_center) { + draw_read: function(ctx, mode, w_scale, y_center, tile_low, tile_high, feature_start, cigar, strand, orig_seq) { ctx.textAlign = "center"; var track = this, tile_region = [tile_low, tile_high], base_offset = 0, seq_offset = 0, gap = 0, - char_width_px = ctx.canvas.manager.char_width_px; + char_width_px = ctx.canvas.manager.char_width_px, + block_color = (strand === "+" ? this.prefs.block_color : this.prefs.reverse_strand_color); // Keep list of items that need to be drawn on top of initial drawing layer. var draw_last = []; @@ -4519,7 +4473,7 @@ // Draw. var seq = orig_seq.slice(seq_offset, seq_offset + cig_len); if (gap > 0) { - ctx.fillStyle = this.prefs.block_color; + ctx.fillStyle = block_color; ctx.fillRect(s_start - gap, y_center + 1, s_end - s_start, 9); ctx.fillStyle = CONNECTOR_COLOR; // TODO: this can be made much more efficient by computing the complete sequence @@ -4537,7 +4491,7 @@ } } } else { - ctx.fillStyle = this.prefs.block_color; + ctx.fillStyle = block_color; // TODO: This is a pretty hack-ish way to fill rectangle based on mode. ctx.fillRect(s_start, y_center + 4, s_end - s_start, SQUISH_FEATURE_HEIGHT); } @@ -4585,7 +4539,7 @@ draw_last[draw_last.length] = {type: "triangle", data: [insert_x_coord, y_center + 4, 5]}; ctx.fillStyle = CONNECTOR_COLOR; // Based on overlap b/t sequence and tile, get sequence to be drawn. - switch(seq_tile_overlap) { + switch( compute_overlap( [seq_start, seq_start + cig_len], tile_region ) ) { case(OVERLAP_START): seq = seq.slice(tile_low-seq_start); break; @@ -4616,7 +4570,7 @@ else { if ( (mode === "Pack" || this.mode === "Auto") && orig_seq !== undefined && w_scale > char_width_px) { // Show insertions with a single number at the insertion point. - draw_last[draw_last.length] = {type: "text", data: [seq.length, insert_x_coord, y_center + 9]}; + draw_last.push( { type: "text", data: [seq.length, insert_x_coord, y_center + 9] } ); } else { // TODO: probably can merge this case with code above. @@ -4666,7 +4620,6 @@ f_start = Math.floor( Math.max(0, (feature_start - tile_low) * w_scale) ), f_end = Math.ceil( Math.min(width, Math.max(0, (feature_end - tile_low) * w_scale)) ), y_center = (mode === "Dense" ? 0 : (0 + slot)) * y_scale, - block_color = this.prefs.block_color, label_color = this.prefs.label_color, // Left-gap for label text since we align chrom text to the position tick. gap = 0; @@ -4677,7 +4630,6 @@ } // Draw read. - ctx.fillStyle = block_color; if (feature[5] instanceof Array) { // Read is paired. var b1_start = Math.floor( Math.max(0, (feature[4][0] - tile_low) * w_scale) ), @@ -4686,12 +4638,12 @@ b2_end = Math.ceil( Math.min(width, Math.max(0, (feature[5][1] - tile_low) * w_scale)) ); // Draw left/forward read. - if (feature[4][1] >= tile_low && feature[4][0] <= tile_high && feature[4][2]) { - this.draw_read(ctx, mode, w_scale, tile_low, tile_high, feature[4][0], feature[4][2], feature[4][3], y_center); + if (feature[4][1] >= tile_low && feature[4][0] <= tile_high && feature[4][2]) { + this.draw_read(ctx, mode, w_scale, y_center, tile_low, tile_high, feature[4][0], feature[4][2], feature[4][3], feature[4][4]); } // Draw right/reverse read. if (feature[5][1] >= tile_low && feature[5][0] <= tile_high && feature[5][2]) { - this.draw_read(ctx, mode, w_scale, tile_low, tile_high, feature[5][0], feature[5][2], feature[5][3], y_center); + this.draw_read(ctx, mode, w_scale, y_center, tile_low, tile_high, feature[5][0], feature[5][2], feature[5][3], feature[5][4]); } // Draw connector. if (b2_start > b1_end) { @@ -4700,10 +4652,9 @@ } } else { // Read is single. - ctx.fillStyle = block_color; - this.draw_read(ctx, mode, w_scale, tile_low, tile_high, feature_start, feature[4], feature[5], y_center); + this.draw_read(ctx, mode, w_scale, y_center, tile_low, tile_high, feature_start, feature[4], feature[5], feature[6]); } - if (mode === "Pack" && feature_start > tile_low) { + if (mode === "Pack" && feature_start > tile_low && feature_name !== ".") { // Draw label. ctx.fillStyle = this.prefs.label_color; // FIXME: eliminate tile_index @@ -4715,7 +4666,6 @@ ctx.textAlign = "right"; ctx.fillText(feature_name, f_start - LABEL_SPACING - gap, y_center + 8); } - ctx.fillStyle = block_color; } // FIXME: provide actual coordinates for drawn read. @@ -4728,7 +4678,6 @@ exports.LinePainter = LinePainter; exports.LinkedFeaturePainter = LinkedFeaturePainter; exports.ReadPainter = ReadPainter; -exports.VariantPainter = VariantPainter; // End painters_module encapsulation }; diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 static/scripts/trackster_ui.js --- a/static/scripts/trackster_ui.js +++ b/static/scripts/trackster_ui.js @@ -31,7 +31,7 @@ /** * Objects that can be added to a view. */ -var addable_objects = { "LineTrack": LineTrack, "FeatureTrack": FeatureTrack, "ReadTrack": ReadTrack, "DrawableGroup": DrawableGroup }; +var addable_objects = { "LineTrack": LineTrack, "FeatureTrack": FeatureTrack, "VcfTrack": VcfTrack, "ReadTrack": ReadTrack, "DrawableGroup": DrawableGroup }; /** * Decode a track from a dictionary. @@ -111,6 +111,9 @@ } } + // Need to update intro div after drawables have been added. + view.update_intro_div(); + // Set overview. var overview_track; for (var i = 0; i < view.drawables.length; i++) { @@ -154,14 +157,14 @@ break case 38: var change = Math.round(view.viewport_container.height()/15.0); - view.viewport_container.scrollTo('-=' + change + 'px'); + view.viewport_container.scrollTop( view.viewport_container.scrollTop() - 20); break; case 39: view.move_fraction(-0.25); break; case 40: var change = Math.round(view.viewport_container.height()/15.0); - view.viewport_container.scrollTo('+=' + change + 'px'); + view.viewport_container.scrollTop( view.viewport_container.scrollTop() + 20); break; } }); diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 templates/admin/tool_shed_repository/browse_repository.mako --- /dev/null +++ b/templates/admin/tool_shed_repository/browse_repository.mako @@ -0,0 +1,127 @@ +<%inherit file="/base.mako"/> +<%namespace file="/message.mako" import="render_msg" /> + +<% from galaxy.web.base.controller import tool_shed_encode, tool_shed_decode %> + +<br/><br/> +<ul class="manage-table-actions"> + <li><a class="action-button" id="repository-${repository.id}-popup" class="menubutton">Repository Actions</a></li> + <div popupmenu="repository-${repository.id}-popup"> + <a class="action-button" href="${h.url_for( controller='admin', action='manage_tool_shed_repository', id=trans.security.encode_id( repository.id ) )}">Manage repository</a> + <a class="action-button" href="${h.url_for( controller='admin', action='check_for_updates', id=trans.security.encode_id( repository.id ) )}">Get updates</a> + </div> +</ul> + +%if message: + ${render_msg( message, status )} +%endif + +<div class="toolForm"> + <div class="toolFormTitle">Installed tool shed repository '${repository.name}'</div> + <div class="toolFormBody"> + + %if tool_dicts: + <div class="form-row"> + <table width="100%"> + <tr bgcolor="#D8D8D8" width="100%"> + <td><b>Tools</b></td> + </tr> + </table> + </div> + <div class="form-row"> + <table class="grid"> + <tr> + <td><b>name</b></td> + <td><b>description</b></td> + <td><b>version</b></td> + <td><b>requirements</b></td> + </tr> + %for tool_dict in tool_dicts: + <tr> + <td>${tool_dict[ 'name' ]}</div> + </td> + <td>${tool_dict[ 'description' ]}</td> + <td>${tool_dict[ 'version' ]}</td> + <td> + <% + if 'requirements' in tool_dict: + requirements = tool_dict[ 'requirements' ] + else: + requirements = None + %> + %if requirements: + <% + requirements_str = '' + for requirement_dict in tool_dict[ 'requirements' ]: + requirements_str += '%s (%s), ' % ( requirement_dict[ 'name' ], requirement_dict[ 'type' ] ) + requirements_str = requirements_str.rstrip( ', ' ) + %> + ${requirements_str} + %else: + none + %endif + </td> + </tr> + %endfor + </table> + </div> + <div style="clear: both"></div> + %endif + %if workflow_dicts: + <div class="form-row"> + <table width="100%"> + <tr bgcolor="#D8D8D8" width="100%"> + <td><b>Workflows</b></td> + </tr> + </table> + </div> + <div style="clear: both"></div> + <div class="form-row"> + <table class="grid"> + <tr> + <td><b>name</b></td> + <td><b>steps</b></td> + <td><b>format-version</b></td> + <td><b>annotation</b></td> + </tr> + <% index = 0 %> + %for wf_dict in workflow_dicts: + <% + full_path = wf_dict[ 'full_path' ] + workflow_dict = wf_dict[ 'workflow_dict' ] + workflow_name = workflow_dict[ 'name' ] + if 'steps' in workflow_dict: + ## Initially steps were not stored in the metadata record. + steps = workflow_dict[ 'steps' ] + else: + steps = [] + format_version = workflow_dict[ 'format-version' ] + annotation = workflow_dict[ 'annotation' ] + %> + <tr> + <td> + <div class="menubutton" style="float: left;" id="workflow-${index}-popup"> + ${workflow_name} + <div popupmenu="workflow-${index}-popup"> + <a class="action-button" href="${h.url_for( controller='workflow', action='import_workflow', local_file=full_path, repository_id=trans.security.encode_id( repository.id ) )}">Import to Galaxy</a> + </div> + </div> + </td> + <td> + %if 'steps' in workflow_dict: + ${len( steps )} + %else: + unknown + %endif + </td> + <td>${format_version}</td> + <td>${annotation}</td> + </tr> + <% index += 1 %> + %endfor + </table> + </div> + <div style="clear: both"></div> + %endif + </div> +</div> diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 templates/admin/tool_shed_repository/manage_repository.mako --- /dev/null +++ b/templates/admin/tool_shed_repository/manage_repository.mako @@ -0,0 +1,57 @@ +<%inherit file="/base.mako"/> +<%namespace file="/message.mako" import="render_msg" /> + +<br/><br/> +<ul class="manage-table-actions"> + <li><a class="action-button" id="repository-${repository.id}-popup" class="menubutton">Repository Actions</a></li> + <div popupmenu="repository-${repository.id}-popup"> + <a class="action-button" href="${h.url_for( controller='admin', action='browse_tool_shed_repository', id=trans.security.encode_id( repository.id ) )}">Browse repository</a> + <a class="action-button" href="${h.url_for( controller='admin', action='check_for_updates', id=trans.security.encode_id( repository.id ) )}">Get updates</a> + </div> +</ul> + +%if message: + ${render_msg( message, status )} +%endif + +<div class="toolForm"> + <div class="toolFormTitle">${repository.name}</div> + <div class="toolFormBody"> + <form name="edit_repository" id="edit_repository" action="${h.url_for( controller='admin', action='manage_tool_shed_repository', id=trans.security.encode_id( repository.id ) )}" method="post" > + <div class="form-row"> + <label>Tool shed:</label> + ${repository.tool_shed} + <div style="clear: both"></div> + </div> + <div class="form-row"> + <label>Name:</label> + ${repository.name} + <div style="clear: both"></div> + </div> + <div class="form-row"> + <label>Description:</label> + <input name="description" type="textfield" value="${description}" size="80"/> + <div style="clear: both"></div> + </div> + <div class="form-row"> + <label>Revision:</label> + ${repository.changeset_revision} + </div> + <div class="form-row"> + <label>Owner:</label> + ${repository.owner} + </div> + <div class="form-row"> + <label>Location:</label> + ${repo_files_dir} + </div> + <div class="form-row"> + <label>Deleted:</label> + ${repository.deleted} + </div> + <div class="form-row"> + <input type="submit" name="edit_repository_button" value="Save"/> + </div> + </form> + </div> +</div> diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 templates/tracks/browser.mako --- a/templates/tracks/browser.mako +++ b/templates/tracks/browser.mako @@ -42,7 +42,7 @@ <script type='text/javascript' src="${h.url_for('/static/scripts/excanvas.js')}"></script><![endif]--> -${h.js( "galaxy.base", "galaxy.panels", "json2", "jquery", "jstorage", "jquery.event.drag", "jquery.mousewheel", "jquery.autocomplete", "trackster", "trackster_ui", "jquery.ui.sortable.slider", "jquery.scrollTo", "farbtastic", "jquery.tipsy" )} +${h.js( "galaxy.base", "galaxy.panels", "json2", "jquery", "jstorage", "jquery.event.drag", "jquery.mousewheel", "jquery.autocomplete", "trackster", "trackster_ui", "jquery.ui.sortable.slider", "farbtastic", "jquery.tipsy" )} <script type="text/javascript"> // @@ -125,7 +125,7 @@ view = create_visualization( $("#browser-container"), "${config.get('title') | h}", "${config.get('vis_id')}", "${config.get('dbkey')}", JSON.parse('${ h.to_json_string( config.get( 'viewport', dict() ) ) }'), - JSON.parse('${ h.to_json_string( config['tracks'] ) }'), + JSON.parse('${ h.to_json_string( config['tracks'] ).replace("'", "\\'") }'), JSON.parse('${ h.to_json_string( config['bookmarks'] ) }') ); init_editor(); diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 templates/tracks/new_browser.mako --- a/templates/tracks/new_browser.mako +++ b/templates/tracks/new_browser.mako @@ -19,7 +19,7 @@ </div><div class="form-row"> Is the build not listed here? - <a href="${h.url_for( controller='user', action='dbkeys', panels=True )}">Add a Custom Build</a> + <a href="${h.url_for( controller='user', action='dbkeys', use_panels=True )}">Add a Custom Build</a></div> %if default_dbkey is not None: <script type="text/javascript"> diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 templates/user/register.mako --- a/templates/user/register.mako +++ b/templates/user/register.mako @@ -65,7 +65,7 @@ ${subscribe_check_box.get_html()} </div> %endif - %if user_type_fd_id_select_field: + %if user_type_fd_id_select_field and len( user_type_fd_id_select_field.options ) > 1: <div class="form-row"><label>User type</label> ${user_type_fd_id_select_field.get_html()} diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 templates/webapps/community/repository/tool_form.mako --- a/templates/webapps/community/repository/tool_form.mako +++ b/templates/webapps/community/repository/tool_form.mako @@ -111,9 +111,13 @@ <br/><br/><ul class="manage-table-actions"> %if webapp == 'galaxy': - <li><a class="action-button" href="${h.url_for( controller='repository', action='install_repository_revision', repository_id=trans.security.encode_id( repository.id ), webapp=webapp, changeset_revision=changeset_revision )}">Install to local Galaxy</a></li> - <li><a class="action-button" id="repository-${repository.id}-popup" class="menubutton">Tool Shed Actions</a></li> + <li><a class="action-button" id="repository-${repository.id}-popup" class="menubutton">Repository Actions</a></li><div popupmenu="repository-${repository.id}-popup"> + <li><a class="action-button" href="${h.url_for( controller='repository', action='install_repository_revision', repository_id=trans.security.encode_id( repository.id ), webapp=webapp, changeset_revision=changeset_revision )}">Install to local Galaxy</a></li> + <li><a class="action-button" href="${h.url_for( controller='repository', action='preview_tools_in_changeset', repository_id=trans.security.encode_id( repository.id ), webapp=webapp, changeset_revision=changeset_revision )}">Browse repository</a></li> + </div> + <li><a class="action-button" id="tool_shed-${repository.id}-popup" class="menubutton">Tool Shed Actions</a></li> + <div popupmenu="tool_shed-${repository.id}-popup"><a class="action-button" href="${h.url_for( controller='repository', action='browse_valid_repositories', webapp=webapp )}">Browse valid repositories</a><a class="action-button" href="${h.url_for( controller='repository', action='find_tools', webapp=webapp )}">Search for valid tools</a><a class="action-button" href="${h.url_for( controller='repository', action='find_workflows', webapp=webapp )}">Search for workflows</a> diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 templates/webapps/community/repository/view_tool_metadata.mako --- a/templates/webapps/community/repository/view_tool_metadata.mako +++ b/templates/webapps/community/repository/view_tool_metadata.mako @@ -34,9 +34,13 @@ <br/><br/><ul class="manage-table-actions"> %if webapp == 'galaxy': - <li><a class="action-button" href="${h.url_for( controller='repository', action='install_repository_revision', repository_id=trans.security.encode_id( repository.id ), webapp=webapp, changeset_revision=changeset_revision )}">Install to local Galaxy</a></li> - <li><a class="action-button" id="repository-${repository.id}-popup" class="menubutton">Tool Shed Actions</a></li> + <li><a class="action-button" id="repository-${repository.id}-popup" class="menubutton">Repository Actions</a></li><div popupmenu="repository-${repository.id}-popup"> + <li><a class="action-button" href="${h.url_for( controller='repository', action='install_repository_revision', repository_id=trans.security.encode_id( repository.id ), webapp=webapp, changeset_revision=changeset_revision )}">Install to local Galaxy</a></li> + <li><a class="action-button" href="${h.url_for( controller='repository', action='preview_tools_in_changeset', repository_id=trans.security.encode_id( repository.id ), webapp=webapp, changeset_revision=changeset_revision )}">Browse repository</a></li> + </div> + <li><a class="action-button" id="tool_shed-${repository.id}-popup" class="menubutton">Tool Shed Actions</a></li> + <div popupmenu="tool_shed-${repository.id}-popup"><a class="action-button" href="${h.url_for( controller='repository', action='browse_valid_repositories', webapp=webapp )}">Browse valid repositories</a><a class="action-button" href="${h.url_for( controller='repository', action='find_tools', webapp=webapp )}">Search for valid tools</a><a class="action-button" href="${h.url_for( controller='repository', action='find_workflows', webapp=webapp )}">Search for workflows</a> diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 templates/webapps/galaxy/admin/index.mako --- a/templates/webapps/galaxy/admin/index.mako +++ b/templates/webapps/galaxy/admin/index.mako @@ -46,6 +46,9 @@ <div class="toolTitle"><a href="${h.url_for( controller='admin', action='users', webapp=webapp )}" target="galaxy_main">Manage users</a></div><div class="toolTitle"><a href="${h.url_for( controller='admin', action='groups', webapp=webapp )}" target="galaxy_main">Manage groups</a></div><div class="toolTitle"><a href="${h.url_for( controller='admin', action='roles', webapp=webapp )}" target="galaxy_main">Manage roles</a></div> + %if trans.app.config.allow_user_impersonation: + <div class="toolTitle"><a href="${h.url_for( controller='admin', action='impersonate', webapp=webapp )}" target="galaxy_main">Impersonate a user</a></div> + %endif </div></div><div class="toolSectionPad"></div> @@ -64,7 +67,7 @@ <div class="toolTitle"><a href="${h.url_for( controller='admin', action='memdump' )}" target="galaxy_main">Profile memory usage</a></div><div class="toolTitle"><a href="${h.url_for( controller='admin', action='jobs' )}" target="galaxy_main">Manage jobs</a></div> %if cloned_repositories: - <div class="toolTitle"><a href="${h.url_for( controller='admin', action='browse_repositories' )}" target="galaxy_main">Manage installed tool shed repositories</a></div> + <div class="toolTitle"><a href="${h.url_for( controller='admin', action='browse_tool_shed_repositories' )}" target="galaxy_main">Manage installed tool shed repositories</a></div> %endif </div></div> diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 templates/webapps/galaxy/base_panels.mako --- a/templates/webapps/galaxy/base_panels.mako +++ b/templates/webapps/galaxy/base_panels.mako @@ -114,7 +114,7 @@ ['Support', app.config.get( "support_url", "http://wiki.g2.bx.psu.edu/Support" ), "_blank" ], ['Galaxy Wiki', app.config.get( "wiki_url", "http://wiki.g2.bx.psu.edu/" ), "_blank" ], ['Video tutorials (screencasts)', app.config.get( "screencasts_url", "http://galaxycast.org" ), "_blank" ], - ['How to Cite Galaxy', app.config.get( "screencasts_url", "http://wiki.g2.bx.psu.edu/Citing%20Galaxy" ), "_blank" ] + ['How to Cite Galaxy', app.config.get( "citation_url", "http://wiki.g2.bx.psu.edu/Citing%20Galaxy" ), "_blank" ] ] tab( "help", "Help", None, menu_options=menu_options) %> diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 templates/webapps/galaxy/user/info.mako --- a/templates/webapps/galaxy/user/info.mako +++ b/templates/webapps/galaxy/user/info.mako @@ -13,7 +13,7 @@ <div class="toolForm"><form name="user_info" id="user_info" action="${h.url_for( controller='user', action='edit_info', cntrller=cntrller, user_id=trans.security.encode_id( user.id ) )}" method="post" ><div class="toolFormTitle">User information</div> - %if user_type_fd_id_select_field: + %if user_type_fd_id_select_field and len( user_type_fd_id_select_field.options ) > 1: <div class="form-row"><label>User type:</label> ${user_type_fd_id_select_field.get_html()} diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 templates/workflow/display.mako --- a/templates/workflow/display.mako +++ b/templates/workflow/display.mako @@ -1,8 +1,8 @@ <%inherit file="/display_base.mako"/><%namespace file="/display_common.mako" import="render_message" /> -<% - from galaxy.tools.parameters import DataToolParameter, RuntimeValue +<%! + from galaxy.tools.parameters import DataToolParameter, RuntimeValue from galaxy.web import form_builder %> @@ -118,4 +118,4 @@ </tr> %endfor </table> -</%def> \ No newline at end of file +</%def> diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 test-data/interpolate_result.bed --- /dev/null +++ b/test-data/interpolate_result.bed @@ -0,0 +1,219 @@ +chr1 27800000 29750669 6600000 0 1.7386 +chr1 29800669 34400000 6600000 0 1.7920 +chr1 46500000 51300000 4800000 0 1.4004 +chr1 102000000 103636494 5000000 0 1.2007 +chr1 103686494 103843838 5000000 0 NA +chr1 103893838 107000000 5000000 0 1.1883 +chr1 117600000 120498679 3100000 0 1.4007 +chr1 120548679 120700000 3100000 0 NA +chr1 153300000 154800000 1500000 0 1.9511 +chr1 163800000 171200000 7400000 0 1.4719 +chr1 174300000 184000000 9700000 0 1.5022 +chr10 6700000 12300000 5600000 0 1.5533 +chr10 42100000 45746970 11200000 0 1.4905 +chr10 45896970 46849175 11200000 0 NA +chr10 46999175 47262482 11200000 0 1.4600 +chr10 47412482 47575713 11200000 0 NA +chr10 47725713 48715542 11200000 0 1.3900 +chr10 48865542 50807416 11200000 0 1.7448 +chr10 50857416 51068851 11200000 0 NA +chr10 51118851 53300000 11200000 0 1.3877 +chr10 74600000 81231464 15000000 0 1.4494 +chr10 81241464 89600000 15000000 0 1.4475 +chr10 98000000 99400000 1400000 0 1.7700 +chr10 102000000 111800000 9800000 0 1.4549 +chr10 114900000 119100000 4200000 0 1.3184 +chr10 127400000 128606059 7974737 0 1.2600 +chr10 128656059 133271394 7974737 0 1.3583 +chr10 133281394 133527517 7974737 0 NA +chr10 133577517 135374737 7974737 0 1.4720 +chr11 50000 1152759 2800000 0 1.5200 +chr11 1169335 2800000 2800000 0 1.6101 +chr11 12600000 16100000 3500000 0 1.2212 +chr11 21600000 26000000 4400000 0 1.3320 +chr11 27200000 31000000 3800000 0 1.2483 +chr11 48800000 50740429 2600000 0 1.3100 +chr11 50947429 51400000 2600000 0 NA +chr11 56400000 68846377 12800000 0 1.7959 +chr11 68848982 69200000 12800000 0 1.6400 +chr11 70700000 85300000 14600000 0 1.5591 +chr11 87900000 92300000 4400000 0 1.2134 +chr11 110000000 115400000 5400000 0 1.4715 +chr11 120700000 134452384 13752384 0 1.4668 +chr12 36500000 44600000 8100000 0 1.3403 +chr12 53100000 56300000 3200000 0 1.6808 +chr12 69800000 74791940 8900000 0 1.2548 +chr12 75041940 78700000 8900000 0 1.2656 +chr12 91200000 94800000 3600000 0 1.6655 +chr12 100000000 107500000 7500000 0 1.6243 +chr13 18400000 32900000 14500000 0 1.5346 +chr13 34700000 39500000 4800000 0 1.1758 +chr13 52200000 57600000 5400000 0 1.2506 +chr13 60500000 72100000 11600000 0 1.2112 +chr13 100500000 109100000 8600000 0 1.3144 +chr14 23600000 31800000 8200000 0 1.3057 +chr14 36900000 41000000 4100000 0 1.2309 +chr14 43200000 48300000 5100000 0 1.2680 +chr14 69300000 72900000 3600000 0 1.6758 +chr14 78400000 88900000 10500000 0 1.2495 +chr15 23300000 24687593 2400000 0 1.2379 +chr15 24731593 25169606 2400000 0 1.2200 +chr15 25270606 25700000 2400000 0 NA +chr15 31400000 37900000 6500000 0 1.4543 +chr15 65300000 70400000 5100000 0 1.6950 +chr16 0 8576922 14700000 0 1.5411 +chr16 8594422 14700000 14700000 0 1.5935 +chr16 16700000 21700000 5000000 0 1.6366 +chr16 69400000 78200000 8800000 0 1.4012 +chr16 80500000 82700000 2200000 0 1.5200 +chr17 0 296854 11200000 0 NA +chr17 343376 11200000 11200000 0 1.7399 +chr17 28800000 31699961 6600000 0 1.4123 +chr17 31799961 33429230 6600000 0 1.7100 +chr17 33529230 35400000 6600000 0 1.8415 +chr17 47600000 54900000 7300000 0 1.4561 +chr17 55600000 59900000 4300000 0 1.5958 +chr18 17300000 31000000 13700000 0 1.3855 +chr18 35500000 50313134 16500000 0 1.3679 +chr18 50360134 52000000 16500000 0 1.3600 +chr19 11000 7297004 12600000 0 1.8232 +chr19 7302004 8593198 12600000 0 2.1300 +chr19 8598198 12600000 12600000 0 1.7010 +chr2 12800000 16171403 4200000 0 1.2641 +chr2 16221403 17000000 4200000 0 1.2505 +chr2 19100000 21012571 4800000 0 1.2500 +chr2 21037571 23900000 4800000 0 1.4405 +chr2 47600000 52700000 5100000 0 1.2384 +chr2 54800000 61100000 6300000 0 1.4715 +chr2 75400000 83700000 8300000 0 1.1639 +chr2 102100000 108600000 6500000 0 1.3381 +chr2 113800000 118600000 4800000 0 1.1949 +chr2 129600000 134800000 5200000 0 1.3332 +chr2 136600000 144700000 8100000 0 1.3447 +chr2 189100000 197100000 8000000 0 1.4590 +chr2 209100000 215100000 6000000 0 1.3963 +chr2 221300000 233711985 15700000 0 1.3701 +chr2 233731985 237000000 15700000 0 1.4560 +chr20 5000000 9000000 4000000 0 1.3515 +chr20 11900000 17800000 5900000 0 1.3648 +chr20 21200000 25700000 4500000 0 1.4588 +chr20 37100000 41100000 4000000 0 1.3980 +chr20 49200000 54400000 5200000 0 1.5272 +chr21 38600000 41877429 8344323 0 1.6542 +chr21 41878628 43505733 8344323 0 1.9800 +chr21 43507092 46944323 8344323 0 1.6567 +chr22 16300000 18889431 11600000 0 NA +chr22 18939431 27900000 11600000 0 1.6362 +chr22 30500000 39300000 8800000 0 1.7639 +chr22 42600000 43057958 7091432 0 1.5600 +chr22 43107958 47356150 7091432 0 1.5400 +chr22 47366250 48750436 7091432 0 1.4700 +chr22 48767136 49087576 7091432 0 NA +chr22 49089176 49107103 7091432 0 NA +chr22 49126803 49591432 7091432 0 NA +chr3 14700000 23800000 9100000 0 1.3438 +chr3 26400000 32100000 5700000 0 1.2751 +chr3 54400000 58500000 4100000 0 1.4670 +chr3 63700000 66115833 8100000 0 1.1571 +chr3 66375833 71800000 8100000 0 1.4022 +chr3 74200000 87200000 13000000 0 1.2224 +chr3 104400000 123400000 19000000 0 1.4382 +chr3 144400000 150400000 6000000 0 1.2844 +chr4 0 1413146 5200000 0 NA +chr4 1464146 3883456 5200000 0 1.8696 +chr4 3963456 5200000 5200000 0 1.4193 +chr4 40900000 45600000 4700000 0 1.3101 +chr4 59200000 59429326 17300000 0 NA +chr4 59479326 69275441 17300000 0 1.1989 +chr4 69375441 71536854 17300000 0 1.4800 +chr4 71711854 75641303 17300000 0 1.3813 +chr4 75671303 76500000 17300000 0 NA +chr4 102500000 120600000 18100000 0 1.2796 +chr4 124000000 151000000 27000000 0 1.3180 +chr5 42400000 45800000 3400000 0 1.6600 +chr5 135400000 138812257 11800000 0 1.6903 +chr5 138817257 147200000 11800000 0 1.4559 +chr6 5000 4100000 4100000 0 1.4960 +chr6 7000000 9199728 6500000 0 1.3742 +chr6 9249728 13500000 6500000 0 1.5531 +chr6 15500000 23500000 8000000 0 1.3678 +chr6 26100000 40600000 14500000 0 1.5998 +chr6 45200000 57200000 12000000 0 1.3561 +chr6 63500000 70000000 6500000 0 1.2305 +chr6 75900000 87500000 11600000 0 1.3037 +chr6 92100000 95737264 7800000 0 1.1620 +chr6 95937264 99900000 7800000 0 1.2897 +chr6 139100000 149100000 10000000 0 1.4172 +chr6 164400000 167766922 6499992 0 1.2400 +chr6 167784922 170021897 6499992 0 1.5383 +chr6 170171897 170896992 6499992 0 1.4900 +chr7 19500000 35600000 16100000 0 1.5139 +chr7 37500000 43300000 5800000 0 1.4283 +chr7 46600000 48167949 7300000 0 1.3900 +chr7 48207949 50338125 7300000 0 1.4468 +chr7 50378125 53900000 7300000 0 1.3027 +chr7 61100000 61314455 36800000 0 NA +chr7 61364455 61554592 36800000 0 NA +chr7 61604592 74353660 36800000 0 1.4805 +chr7 74603660 97900000 36800000 0 1.3240 +chr7 117200000 130100000 12900000 0 1.3323 +chr7 132400000 137300000 4900000 0 1.4019 +chr7 142800000 147500000 4700000 0 1.1759 +chr8 12700000 19100000 6400000 0 1.1690 +chr8 29700000 29732668 8800000 0 NA +chr8 29798768 38500000 8800000 0 1.4250 +chr8 55600000 66100000 10500000 0 1.5225 +chr8 74000000 86069241 13200000 0 1.3023 +chr8 86193341 86763703 13200000 0 NA +chr8 86851003 87200000 13200000 0 NA +chr8 99100000 101600000 2500000 0 1.6452 +chr8 106100000 117700000 11600000 0 1.2240 +chr8 127300000 140000000 12700000 0 1.4038 +chr9 9000000 14100000 5100000 0 1.2167 +chr9 40200000 40223029 6500000 0 NA +chr9 40273029 40415834 6500000 0 NA +chr9 40465834 40930341 6500000 0 NA +chr9 40980341 41133214 6500000 0 NA +chr9 41183214 41355793 6500000 0 NA +chr9 41405793 42603951 6500000 0 NA +chr9 42653951 43203694 6500000 0 NA +chr9 43253694 43886565 6500000 0 NA +chr9 43936565 44616642 6500000 0 NA +chr9 44666642 44848289 6500000 0 NA +chr9 44898289 45190199 6500000 0 NA +chr9 45240199 45705517 6500000 0 NA +chr9 45755517 46106426 6500000 0 NA +chr9 46156426 46351035 6500000 0 NA +chr9 46401035 46700000 6500000 0 NA +chr9 91000000 91533236 10600000 0 NA +chr9 91583236 91668616 10600000 0 NA +chr9 91718616 101600000 10600000 0 1.5580 +chrX 0 34821 6000000 0 NA +chrX 84821 171384 6000000 0 NA +chrX 201384 967557 6000000 0 NA +chrX 1017557 1054113 6000000 0 NA +chrX 1104113 1184234 6000000 0 NA +chrX 1274234 2028238 6000000 0 NA +chrX 2128238 6000000 6000000 0 1.4520 +chrX 9500000 37008177 37800000 0 1.4047 +chrX 37033177 47300000 37800000 0 1.4817 +chrX 65000000 67700000 2700000 0 1.2658 +chrX 76000000 76570348 22200000 0 NA +chrX 76590348 98200000 22200000 0 1.2642 +chrX 102500000 113403924 18200000 0 1.3809 +chrX 113473924 115596318 18200000 0 1.3900 +chrX 115616318 120700000 18200000 0 1.4886 +chrX 137800000 140100000 2300000 0 1.2054 +chrX 141900000 143335010 5000000 0 1.2700 +chrX 143365010 146900000 5000000 0 1.2517 +chrY 0 34821 11200000 0 NA +chrY 84821 171384 11200000 0 NA +chrY 201384 967557 11200000 0 NA +chrY 1017557 1054113 11200000 0 NA +chrY 1104113 1184234 11200000 0 NA +chrY 1274234 2028238 11200000 0 NA +chrY 2128238 8974955 11200000 0 1.3987 +chrY 9024955 9301322 11200000 0 NA +chrY 9901322 10714553 11200000 0 1.2200 +chrY 12500000 22310816 14700000 0 1.3632 +chrY 22360816 27200000 14700000 0 1.2357 \ No newline at end of file diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 test-data/interval_interpolate.bed --- /dev/null +++ b/test-data/interval_interpolate.bed @@ -0,0 +1,219 @@ +chr1 27800000 29750669 6600000 0 +chr1 29800669 34400000 6600000 0 +chr1 46500000 51300000 4800000 0 +chr1 102000000 103636494 5000000 0 +chr1 103686494 103843838 5000000 0 +chr1 103893838 107000000 5000000 0 +chr1 117600000 120498679 3100000 0 +chr1 120548679 120700000 3100000 0 +chr1 153300000 154800000 1500000 0 +chr1 163800000 171200000 7400000 0 +chr1 174300000 184000000 9700000 0 +chr10 6700000 12300000 5600000 0 +chr10 42100000 45746970 11200000 0 +chr10 45896970 46849175 11200000 0 +chr10 46999175 47262482 11200000 0 +chr10 47412482 47575713 11200000 0 +chr10 47725713 48715542 11200000 0 +chr10 48865542 50807416 11200000 0 +chr10 50857416 51068851 11200000 0 +chr10 51118851 53300000 11200000 0 +chr10 74600000 81231464 15000000 0 +chr10 81241464 89600000 15000000 0 +chr10 98000000 99400000 1400000 0 +chr10 102000000 111800000 9800000 0 +chr10 114900000 119100000 4200000 0 +chr10 127400000 128606059 7974737 0 +chr10 128656059 133271394 7974737 0 +chr10 133281394 133527517 7974737 0 +chr10 133577517 135374737 7974737 0 +chr11 50000 1152759 2800000 0 +chr11 1169335 2800000 2800000 0 +chr11 12600000 16100000 3500000 0 +chr11 21600000 26000000 4400000 0 +chr11 27200000 31000000 3800000 0 +chr11 48800000 50740429 2600000 0 +chr11 50947429 51400000 2600000 0 +chr11 56400000 68846377 12800000 0 +chr11 68848982 69200000 12800000 0 +chr11 70700000 85300000 14600000 0 +chr11 87900000 92300000 4400000 0 +chr11 110000000 115400000 5400000 0 +chr11 120700000 134452384 13752384 0 +chr12 36500000 44600000 8100000 0 +chr12 53100000 56300000 3200000 0 +chr12 69800000 74791940 8900000 0 +chr12 75041940 78700000 8900000 0 +chr12 91200000 94800000 3600000 0 +chr12 100000000 107500000 7500000 0 +chr13 18400000 32900000 14500000 0 +chr13 34700000 39500000 4800000 0 +chr13 52200000 57600000 5400000 0 +chr13 60500000 72100000 11600000 0 +chr13 100500000 109100000 8600000 0 +chr14 23600000 31800000 8200000 0 +chr14 36900000 41000000 4100000 0 +chr14 43200000 48300000 5100000 0 +chr14 69300000 72900000 3600000 0 +chr14 78400000 88900000 10500000 0 +chr15 23300000 24687593 2400000 0 +chr15 24731593 25169606 2400000 0 +chr15 25270606 25700000 2400000 0 +chr15 31400000 37900000 6500000 0 +chr15 65300000 70400000 5100000 0 +chr16 0 8576922 14700000 0 +chr16 8594422 14700000 14700000 0 +chr16 16700000 21700000 5000000 0 +chr16 69400000 78200000 8800000 0 +chr16 80500000 82700000 2200000 0 +chr17 0 296854 11200000 0 +chr17 343376 11200000 11200000 0 +chr17 28800000 31699961 6600000 0 +chr17 31799961 33429230 6600000 0 +chr17 33529230 35400000 6600000 0 +chr17 47600000 54900000 7300000 0 +chr17 55600000 59900000 4300000 0 +chr18 17300000 31000000 13700000 0 +chr18 35500000 50313134 16500000 0 +chr18 50360134 52000000 16500000 0 +chr19 11000 7297004 12600000 0 +chr19 7302004 8593198 12600000 0 +chr19 8598198 12600000 12600000 0 +chr2 12800000 16171403 4200000 0 +chr2 16221403 17000000 4200000 0 +chr2 19100000 21012571 4800000 0 +chr2 21037571 23900000 4800000 0 +chr2 47600000 52700000 5100000 0 +chr2 54800000 61100000 6300000 0 +chr2 75400000 83700000 8300000 0 +chr2 102100000 108600000 6500000 0 +chr2 113800000 118600000 4800000 0 +chr2 129600000 134800000 5200000 0 +chr2 136600000 144700000 8100000 0 +chr2 189100000 197100000 8000000 0 +chr2 209100000 215100000 6000000 0 +chr2 221300000 233711985 15700000 0 +chr2 233731985 237000000 15700000 0 +chr20 5000000 9000000 4000000 0 +chr20 11900000 17800000 5900000 0 +chr20 21200000 25700000 4500000 0 +chr20 37100000 41100000 4000000 0 +chr20 49200000 54400000 5200000 0 +chr21 38600000 41877429 8344323 0 +chr21 41878628 43505733 8344323 0 +chr21 43507092 46944323 8344323 0 +chr22 16300000 18889431 11600000 0 +chr22 18939431 27900000 11600000 0 +chr22 30500000 39300000 8800000 0 +chr22 42600000 43057958 7091432 0 +chr22 43107958 47356150 7091432 0 +chr22 47366250 48750436 7091432 0 +chr22 48767136 49087576 7091432 0 +chr22 49089176 49107103 7091432 0 +chr22 49126803 49591432 7091432 0 +chr3 14700000 23800000 9100000 0 +chr3 26400000 32100000 5700000 0 +chr3 54400000 58500000 4100000 0 +chr3 63700000 66115833 8100000 0 +chr3 66375833 71800000 8100000 0 +chr3 74200000 87200000 13000000 0 +chr3 104400000 123400000 19000000 0 +chr3 144400000 150400000 6000000 0 +chr4 0 1413146 5200000 0 +chr4 1464146 3883456 5200000 0 +chr4 3963456 5200000 5200000 0 +chr4 40900000 45600000 4700000 0 +chr4 59200000 59429326 17300000 0 +chr4 59479326 69275441 17300000 0 +chr4 69375441 71536854 17300000 0 +chr4 71711854 75641303 17300000 0 +chr4 75671303 76500000 17300000 0 +chr4 102500000 120600000 18100000 0 +chr4 124000000 151000000 27000000 0 +chr5 42400000 45800000 3400000 0 +chr5 135400000 138812257 11800000 0 +chr5 138817257 147200000 11800000 0 +chr6 5000 4100000 4100000 0 +chr6 7000000 9199728 6500000 0 +chr6 9249728 13500000 6500000 0 +chr6 15500000 23500000 8000000 0 +chr6 26100000 40600000 14500000 0 +chr6 45200000 57200000 12000000 0 +chr6 63500000 70000000 6500000 0 +chr6 75900000 87500000 11600000 0 +chr6 92100000 95737264 7800000 0 +chr6 95937264 99900000 7800000 0 +chr6 139100000 149100000 10000000 0 +chr6 164400000 167766922 6499992 0 +chr6 167784922 170021897 6499992 0 +chr6 170171897 170896992 6499992 0 +chr7 19500000 35600000 16100000 0 +chr7 37500000 43300000 5800000 0 +chr7 46600000 48167949 7300000 0 +chr7 48207949 50338125 7300000 0 +chr7 50378125 53900000 7300000 0 +chr7 61100000 61314455 36800000 0 +chr7 61364455 61554592 36800000 0 +chr7 61604592 74353660 36800000 0 +chr7 74603660 97900000 36800000 0 +chr7 117200000 130100000 12900000 0 +chr7 132400000 137300000 4900000 0 +chr7 142800000 147500000 4700000 0 +chr8 12700000 19100000 6400000 0 +chr8 29700000 29732668 8800000 0 +chr8 29798768 38500000 8800000 0 +chr8 55600000 66100000 10500000 0 +chr8 74000000 86069241 13200000 0 +chr8 86193341 86763703 13200000 0 +chr8 86851003 87200000 13200000 0 +chr8 99100000 101600000 2500000 0 +chr8 106100000 117700000 11600000 0 +chr8 127300000 140000000 12700000 0 +chr9 9000000 14100000 5100000 0 +chr9 40200000 40223029 6500000 0 +chr9 40273029 40415834 6500000 0 +chr9 40465834 40930341 6500000 0 +chr9 40980341 41133214 6500000 0 +chr9 41183214 41355793 6500000 0 +chr9 41405793 42603951 6500000 0 +chr9 42653951 43203694 6500000 0 +chr9 43253694 43886565 6500000 0 +chr9 43936565 44616642 6500000 0 +chr9 44666642 44848289 6500000 0 +chr9 44898289 45190199 6500000 0 +chr9 45240199 45705517 6500000 0 +chr9 45755517 46106426 6500000 0 +chr9 46156426 46351035 6500000 0 +chr9 46401035 46700000 6500000 0 +chr9 91000000 91533236 10600000 0 +chr9 91583236 91668616 10600000 0 +chr9 91718616 101600000 10600000 0 +chrX 0 34821 6000000 0 +chrX 84821 171384 6000000 0 +chrX 201384 967557 6000000 0 +chrX 1017557 1054113 6000000 0 +chrX 1104113 1184234 6000000 0 +chrX 1274234 2028238 6000000 0 +chrX 2128238 6000000 6000000 0 +chrX 9500000 37008177 37800000 0 +chrX 37033177 47300000 37800000 0 +chrX 65000000 67700000 2700000 0 +chrX 76000000 76570348 22200000 0 +chrX 76590348 98200000 22200000 0 +chrX 102500000 113403924 18200000 0 +chrX 113473924 115596318 18200000 0 +chrX 115616318 120700000 18200000 0 +chrX 137800000 140100000 2300000 0 +chrX 141900000 143335010 5000000 0 +chrX 143365010 146900000 5000000 0 +chrY 0 34821 11200000 0 +chrY 84821 171384 11200000 0 +chrY 201384 967557 11200000 0 +chrY 1017557 1054113 11200000 0 +chrY 1104113 1184234 11200000 0 +chrY 1274234 2028238 11200000 0 +chrY 2128238 8974955 11200000 0 +chrY 9024955 9301322 11200000 0 +chrY 9901322 10714553 11200000 0 +chrY 12500000 22310816 14700000 0 +chrY 22360816 27200000 14700000 0 \ No newline at end of file diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 test-data/logreg_inp.tabular --- /dev/null +++ b/test-data/logreg_inp.tabular @@ -0,0 +1,100 @@ +2.04 2.01 1070 1 +2.56 3.4 1254 1 +3.75 3.68 1466 1 +1.1 1.54 706 1 +3 3.32 1160 1 +0.05 0.33 756 1 +1.38 0.36 1058 1 +1.5 1.97 1008 0 +1.38 2.03 1104 1 +4.01 2.05 1200 1 +1.5 2.13 896 1 +1.29 1.34 848 1 +1.9 1.51 958 1 +3.11 3.12 1246 0 +1.92 2.14 1106 1 +0.81 2.6 790 1 +1.01 1.9 954 1 +3.66 3.06 1500 0 +2 1.6 1046 0 +2.05 1.96 1054 1 +2.6 1.96 1198 0 +2.55 1.56 940 1 +0.38 1.6 456 0 +2.48 1.92 1150 1 +2.74 3.09 636 0 +1.77 0.78 744 1 +1.61 2.12 644 0 +0.99 1.85 842 1 +1.62 1.78 852 1 +2.03 1.03 1170 0 +3.5 3.44 1034 1 +3.18 2.42 1202 1 +2.39 1.74 1018 1 +1.48 1.89 1180 1 +1.54 1.43 952 0 +1.57 1.64 1038 1 +2.46 2.69 1090 0 +2.42 1.79 694 0 +2.11 2.72 1096 0 +2.04 2.15 1114 0 +1.68 2.22 1256 1 +1.64 1.55 1208 0 +2.41 2.34 820 0 +2.1 2.92 1222 0 +1.4 2.1 1120 0 +2.03 1.64 886 0 +1.99 2.83 1126 0 +2.24 1.76 1158 0 +0.45 1.81 676 0 +2.31 2.68 1214 0 +2.41 2.55 1136 1 +2.56 2.7 1264 0 +2.5 1.66 1116 1 +2.92 2.23 1292 1 +2.35 2.01 604 1 +2.82 1.24 854 1 +1.8 1.95 814 0 +1.29 1.73 778 1 +1.68 1.08 800 0 +3.44 3.46 1424 0 +1.9 3.01 950 0 +2.06 0.54 1056 1 +3.3 3.2 956 1 +1.8 1.5 1352 1 +2 1.71 852 1 +1.68 1.99 1168 0 +1.94 2.76 970 1 +0.97 1.56 776 1 +1.12 1.78 854 1 +1.31 1.32 1232 0 +1.68 0.87 1140 0 +3.09 1.75 1084 0 +1.87 1.41 954 0 +2 2.77 1000 0 +2.39 1.78 1084 0 +1.5 1.34 1058 0 +1.82 1.52 816 0 +1.8 2.97 1146 0 +2.01 1.75 1000 1 +1.88 1.64 856 1 +1.64 1.8 798 1 +2.42 3.37 1324 1 +0.22 1.15 704 1 +2.31 1.72 1222 1 +0.95 2.27 948 0 +1.99 2.85 1182 0 +1.86 2.21 1000 1 +1.79 1.94 910 0 +3.02 4.25 1374 1 +1.85 1.83 1014 0 +1.98 2.75 1420 0 +2.15 1.71 400 0 +1.46 2.2 998 1 +2.29 2.13 776 1 +2.39 2.38 1134 0 +1.8 1.64 772 0 +2.64 1.87 1304 0 +2.08 2.53 1212 0 +0.7 1.78 818 1 +0.89 1.2 864 1 \ No newline at end of file diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 test-data/logreg_out2.tabular --- /dev/null +++ b/test-data/logreg_out2.tabular @@ -0,0 +1,19 @@ +response column c4 +predictor column(s) c1,c2,c3 +Y-intercept 0.9111624714 +p-value (Y-intercept) 0.3571052008 +Slope (c1) 0.057995684 +p-value (c1) 0.8677866885 +Slope (c2) -0.2319990287 +p-value (c2) 0.4986584837 +Slope (c3) -0.0004633556 +p-value (c3) 0.6785709433 +Null deviance 138.46939 +Residual deviance 137.44023 +pseudo R-squared 0.00743 + + +vif +c1 1.65649272465 +c2 1.47696547452 +c3 1.4307725027 diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 test-data/partialR_result.tabular --- /dev/null +++ b/test-data/partialR_result.tabular @@ -0,0 +1,4 @@ +#Model R-sq partial_R_Terms partial_R_Value +1 2 0.9388 - - +2 0.7280 1 0.7750 +1 0.9104 2 0.3167 \ No newline at end of file diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 test-data/value_interpolate.bed --- /dev/null +++ b/test-data/value_interpolate.bed @@ -0,0 +1,2794 @@ +chr9 138121811 138276705 0 +chr10 80472830 80642405 0 +chr10 112350437 112499683 0 +chr18 44397436 44552893 0 +chr19 40876527 41059171 0 +chr19 47423994 47633625 0 +chr4 189654626 189851415 0.98 +chr14 41341385 41500259 0.99 +chr10 68138624 68290770 1.02 +chr1 194486128 194637476 1.03 +chr2 79730231 79730948 1.04 +chr8 77233600 77394640 1.04 +chr3 164366661 164516629 1.05 +chr4 182025739 182177673 1.05 +chr7 78310705 78485567 1.05 +chr8 34287764 34455012 1.05 +chr9 28840514 28840768 1.05 +chr16 62921688 63071731 1.05 +chr18 47940868 48119474 1.05 +chr1 215306203 215473376 1.06 +chr3 77584830 77738883 1.06 +chr5 165677723 165841050 1.06 +chr7 79539152 79645155 1.06 +chr8 4596118 4755769 1.06 +chr9 105583839 105754361 1.06 +chr10 56709834 56882157 1.06 +chr14 25538290 25757198 1.06 +chr1 213686097 213890738 1.07 +chr4 93630873 93775737 1.07 +chr11 37673721 37838885 1.07 +chr13 34909940 35080870 1.07 +chrX 66474376 66475056 1.07 +chr2 116313042 116516750 1.08 +chr5 28750780 28917994 1.08 +chr7 83471581 83635351 1.08 +chr9 24090721 24243438 1.08 +chr13 66420966 66421707 1.08 +chr14 83853577 84001147 1.08 +chr18 67890358 68041609 1.08 +chr4 45608190 45780635 1.09 +chr6 93072999 93225231 1.09 +chr8 16444047 16618550 1.09 +chr8 16444054 16618572 1.09 +chr8 89218072 89400932 1.09 +chr13 86846880 86847238 1.09 +chr13 88476238 88642707 1.09 +chr21 21123964 21277726 1.09 +chr1 162445439 162629394 1.1 +chr3 19336535 19494336 1.1 +chr3 20636022 20828571 1.1 +chr4 28748334 28909642 1.1 +chr4 65766258 65968108 1.1 +chr5 25187412 25333169 1.1 +chr13 82592804 82779046 1.1 +chr1 72790142 72983871 1.11 +chr1 193197934 193377693 1.11 +chr2 165238485 165239216 1.11 +chr3 65182404 65361116 1.11 +chr4 31129762 31286231 1.11 +chr4 160913220 161055170 1.11 +chr6 68213170 68355088 1.11 +chr6 121373179 121565240 1.11 +chr7 14108578 14279180 1.11 +chr7 83230804 83414012 1.11 +chr7 145959694 146102483 1.11 +chr8 85136758 85319037 1.11 +chr9 121031753 121032407 1.11 +chr12 80260958 80413762 1.11 +chr13 84781269 84965380 1.11 +chr13 93229523 93403152 1.11 +chr18 56874822 57034619 1.11 +chr2 78739654 78929106 1.12 +chr4 28258977 28448528 1.12 +chr6 81474419 81671778 1.12 +chr8 5106183 5256062 1.12 +chr8 15557561 15699688 1.12 +chr9 120913556 121095236 1.12 +chr11 41835501 42018028 1.12 +chr11 54839338 55007563 1.12 +chr13 82035437 82201311 1.12 +chr14 29256331 29403102 1.12 +chr14 79340662 79520755 1.12 +chr15 52652616 52815257 1.12 +chrX 139430017 139573923 1.12 +chr2 22411649 22627999 1.13 +chr2 146591634 146775911 1.13 +chr2 165687734 165861526 1.13 +chr3 21574294 21742228 1.13 +chr3 84623846 84624672 1.13 +chr4 118641782 118817785 1.13 +chr4 121715867 121905993 1.13 +chr4 171952201 171952789 1.13 +chr5 113199522 113366010 1.13 +chr5 121061430 121226477 1.13 +chr6 19131250 19131847 1.13 +chr6 62586405 62725287 1.13 +chr6 96322030 96503179 1.13 +chr7 10359917 10517208 1.13 +chr8 88145759 88302638 1.13 +chr9 119255125 119430632 1.13 +chr12 72112997 72312988 1.13 +chr14 28380477 28530538 1.13 +chr14 43288620 43453116 1.13 +chr14 84168823 84169632 1.13 +chr15 45134914 45309877 1.13 +chr16 60359424 60359773 1.13 +chr1 73625862 73764288 1.14 +chr1 73625895 73764288 1.14 +chr1 103893882 104012508 1.14 +chr1 215209972 215373859 1.14 +chr2 50386937 50387456 1.14 +chr2 81618970 81763529 1.14 +chr3 74234096 74391234 1.14 +chr3 80133749 80297117 1.14 +chr3 95519627 95706411 1.14 +chr3 98524261 98714848 1.14 +chr4 117579710 117743718 1.14 +chr4 171958495 172124798 1.14 +chr6 153105001 153217269 1.14 +chr7 52666632 52867234 1.14 +chr7 151558264 151732070 1.14 +chr8 112515727 112683952 1.14 +chr9 120076427 120271081 1.14 +chr11 90725899 90902355 1.14 +chr12 33170553 33333489 1.14 +chr13 106527433 106708235 1.14 +chr14 82169838 82169979 1.14 +chr18 26696101 26878287 1.14 +chr21 20389919 20390568 1.14 +chrX 92132730 92310405 1.14 +chrX 127763208 127921922 1.14 +chrX 137822409 137909028 1.14 +chr1 185443401 185614023 1.15 +chr2 49302567 49513831 1.15 +chr2 66394115 66576561 1.15 +chr2 83447798 83650748 1.15 +chr2 83447850 83650731 1.15 +chr2 115793564 115936236 1.15 +chr3 1347065 1517440 1.15 +chr3 119242817 119243578 1.15 +chr4 19599685 19772537 1.15 +chr4 112315831 112504400 1.15 +chr5 4351733 4533614 1.15 +chr5 52909243 53065314 1.15 +chr5 119668835 119831950 1.15 +chr5 120133844 120134605 1.15 +chr6 58610235 58788598 1.15 +chr6 65092079 65280053 1.15 +chr6 127363622 127546913 1.15 +chr7 84729683 84904466 1.15 +chr8 112100512 112266163 1.15 +chr8 132628905 132799581 1.15 +chr11 29071526 29253144 1.15 +chr11 90903367 91076093 1.15 +chr12 76524989 76660180 1.15 +chr12 83887475 84059958 1.15 +chr13 37217921 37218551 1.15 +chr13 70296348 70477659 1.15 +chr13 71078490 71256801 1.15 +chr13 89314358 89462845 1.15 +chr16 63462907 63616441 1.15 +chr18 37305512 37482566 1.15 +chr1 61044529 61191204 1.16 +chr1 74413167 74572629 1.16 +chr1 175137086 175272030 1.16 +chr1 188252333 188442427 1.16 +chr1 195614240 195777468 1.16 +chr2 52903987 53101240 1.16 +chr2 122950238 123095058 1.16 +chr2 193770382 193940783 1.16 +chr3 145885187 146013616 1.16 +chr4 60813762 60999837 1.16 +chr4 67050357 67201898 1.16 +chr4 91753784 91923803 1.16 +chr4 93320220 93531288 1.16 +chr4 107736688 107943788 1.16 +chr4 179406134 179587711 1.16 +chr5 16193697 16358412 1.16 +chr6 8464242 8664833 1.16 +chr6 22580422 22736310 1.16 +chr6 100781592 100953408 1.16 +chr7 51595765 51731468 1.16 +chr7 121314792 121472652 1.16 +chr7 123711877 123721155 1.16 +chr8 40501073 40649244 1.16 +chr8 94214334 94424255 1.16 +chr9 1340595 1488472 1.16 +chr9 82142727 82324329 1.16 +chr9 84622895 84783002 1.16 +chr11 91893716 92071858 1.16 +chr13 52804333 52973849 1.16 +chr13 90342056 90524017 1.16 +chr14 32378912 32540754 1.16 +chr14 37010397 37213971 1.16 +chr14 86077200 86077996 1.16 +chr15 95508740 95699545 1.16 +chr17 13211602 13416771 1.16 +chr17 48565062 48664511 1.16 +chr17 49013829 49212688 1.16 +chr21 13462479 13626951 1.16 +chrX 82482413 82601150 1.16 +chrX 84848634 85055360 1.16 +chrX 143420958 143549753 1.16 +chrY 4917122 4917768 1.16 +chrY 22545464 22688210 1.16 +chr1 71927607 72094826 1.17 +chr1 188974250 189126140 1.17 +chr2 50398943 50560714 1.17 +chr2 153550169 153751686 1.17 +chr3 167343076 167517669 1.17 +chr3 189731929 189918719 1.17 +chr4 12410352 12586679 1.17 +chr4 18028014 18213766 1.17 +chr4 22911964 23061775 1.17 +chr4 44529019 44675676 1.17 +chr4 59533297 59706381 1.17 +chr4 63770893 63973350 1.17 +chr4 101813229 101963326 1.17 +chr4 126354725 126519739 1.17 +chr4 135464067 135640784 1.17 +chr4 188522259 188676888 1.17 +chr5 135915628 135916057 1.17 +chr6 78821469 78822201 1.17 +chr6 113213629 113374404 1.17 +chr7 10241793 10242601 1.17 +chr7 108884723 109038822 1.17 +chr8 113491855 113659908 1.17 +chr10 67500726 67674349 1.17 +chr11 97102811 97328868 1.17 +chr11 100145397 100299538 1.17 +chr11 126420648 126568009 1.17 +chr11 132215897 132391418 1.17 +chr13 35921756 36083776 1.17 +chr13 37797297 37951253 1.17 +chr13 60719187 60882412 1.17 +chr13 65294071 65461528 1.17 +chr16 61098268 61286985 1.17 +chr17 66194639 66343264 1.17 +chr18 35489814 35657078 1.17 +chrX 66577693 66716608 1.17 +chrX 140211864 140377242 1.17 +chr1 75234702 75388843 1.18 +chr1 102366355 102506882 1.18 +chr1 106102412 106261344 1.18 +chr1 118630891 118728136 1.18 +chr1 192296623 192424789 1.18 +chr2 2210217 2390008 1.18 +chr2 58959370 59141335 1.18 +chr2 72247356 72428550 1.18 +chr2 82554305 82716433 1.18 +chr2 164085637 164247934 1.18 +chr2 199939521 200121814 1.18 +chr3 29867269 30018470 1.18 +chr3 73854905 74025974 1.18 +chr3 80611850 80795918 1.18 +chr4 67263328 67431970 1.18 +chr5 20414933 20415717 1.18 +chr5 26353486 26539834 1.18 +chr5 109349873 109506373 1.18 +chr5 144610138 144777056 1.18 +chr5 165737022 165925395 1.18 +chr6 50775747 50907356 1.18 +chr6 77624011 77788328 1.18 +chr7 81437179 81635132 1.18 +chr7 114921735 115101378 1.18 +chr7 144927075 145051342 1.18 +chr8 3899657 4066797 1.18 +chr8 16323134 16472679 1.18 +chr8 18447618 18644291 1.18 +chr8 36363082 36516620 1.18 +chr8 78915842 79062005 1.18 +chr8 92382762 92553372 1.18 +chr8 117283875 117484166 1.18 +chr9 12225005 12396287 1.18 +chr9 13729630 13912935 1.18 +chr9 23376562 23557443 1.18 +chr11 15778995 15940672 1.18 +chr11 26201318 26402942 1.18 +chr12 58234674 58235464 1.18 +chr12 60211160 60370325 1.18 +chr13 58618179 58784565 1.18 +chr14 41996958 42171562 1.18 +chr16 61943900 62080675 1.18 +chr18 25599572 25763880 1.18 +chr18 33450045 33623547 1.18 +chr20 12493232 12650585 1.18 +chrX 98334220 98501957 1.18 +chr1 98681325 98839806 1.19 +chr1 106759920 106884446 1.19 +chr1 188892773 189058601 1.19 +chr2 14523373 14693180 1.19 +chr2 40346711 40526003 1.19 +chr2 52193265 52373212 1.19 +chr2 167445852 167644200 1.19 +chr2 192914919 193076744 1.19 +chr2 211871510 212039574 1.19 +chr2 221335235 221512023 1.19 +chr3 2181314 2367266 1.19 +chr3 26718031 26882772 1.19 +chr3 149511877 149686925 1.19 +chr3 166908960 167080203 1.19 +chr3 169544516 169732146 1.19 +chr4 73321382 73500901 1.19 +chr4 103999791 104161865 1.19 +chr4 121155218 121304760 1.19 +chr4 132769467 132770056 1.19 +chr5 12130086 12282083 1.19 +chr5 163117739 163118288 1.19 +chr6 93629580 93823810 1.19 +chr7 12919070 13079613 1.19 +chr8 15279388 15445713 1.19 +chr8 118297084 118467725 1.19 +chr8 136470371 136653380 1.19 +chr8 137773461 137919469 1.19 +chr9 8398615 8557610 1.19 +chr9 12819715 13004078 1.19 +chr10 106748194 106912778 1.19 +chr11 80418056 80571094 1.19 +chr12 43511484 43650184 1.19 +chr12 76975277 77145211 1.19 +chr12 81988506 82172342 1.19 +chr14 26561378 26744993 1.19 +chr14 32835734 32999496 1.19 +chr14 40363695 40563204 1.19 +chr14 61886249 62046831 1.19 +chr16 6165969 6339847 1.19 +chr18 1551143 1734122 1.19 +chr18 47274877 47443274 1.19 +chrX 28257745 28427558 1.19 +chrX 50147722 50314773 1.19 +chrX 83845334 83846061 1.19 +chrX 141360475 141476781 1.19 +chr1 76640828 76740449 1.2 +chr1 95507969 95685941 1.2 +chr2 5764246 5956172 1.2 +chr2 63195188 63358079 1.2 +chr2 76357535 76358153 1.2 +chr2 77030009 77195797 1.2 +chr2 103816337 103983810 1.2 +chr2 150592885 150779567 1.2 +chr2 185140095 185334504 1.2 +chr2 224018074 224018802 1.2 +chr3 35590216 35766097 1.2 +chr3 105180963 105347887 1.2 +chr3 116940533 117110558 1.2 +chr4 60219574 60371862 1.2 +chr4 64867965 65032881 1.2 +chr4 179834815 180006495 1.2 +chr5 98954115 99111442 1.2 +chr5 100991121 101181889 1.2 +chr5 102992405 103190088 1.2 +chr6 69438735 69596850 1.2 +chr6 72157311 72342266 1.2 +chr6 102119094 102294630 1.2 +chr7 136263965 136416914 1.2 +chr8 4187855 4386741 1.2 +chr8 24278979 24469357 1.2 +chr8 75850345 76026015 1.2 +chr9 28027075 28204449 1.2 +chr9 75584378 75757095 1.2 +chr9 80495074 80676552 1.2 +chr9 103481717 103640785 1.2 +chr9 118368426 118523858 1.2 +chr10 10034833 10202423 1.2 +chr10 16038936 16196794 1.2 +chr10 57554233 57708605 1.2 +chr11 79636827 79817896 1.2 +chr12 18499860 18558864 1.2 +chr12 71742532 71963509 1.2 +chr12 86171722 86361997 1.2 +chr13 61999015 62167070 1.2 +chr13 86241575 86431660 1.2 +chr13 87858551 88035241 1.2 +chr15 24370637 24550028 1.2 +chr18 14843504 14998636 1.2 +chr18 40044271 40244003 1.2 +chr18 73605047 73776512 1.2 +chr21 24509084 24509572 1.2 +chrX 27748283 27942635 1.2 +chrX 140718912 140719477 1.2 +chrY 24157833 24324267 1.2 +chrY 26443321 26640420 1.2 +chrY 26443368 26443796 1.2 +chr1 81828369 81949209 1.21 +chr2 4779724 4937997 1.21 +chr2 141388838 141564023 1.21 +chr2 229316646 229475755 1.21 +chr2 235485097 235485527 1.21 +chr3 22372670 22514731 1.21 +chr3 34981231 35131137 1.21 +chr3 64198721 64357750 1.21 +chr3 86088438 86268550 1.21 +chr4 29381036 29558458 1.21 +chr4 96994009 97153613 1.21 +chr4 96994043 97153591 1.21 +chr4 98832394 98983885 1.21 +chr4 149764955 149967710 1.21 +chr4 158576067 158755508 1.21 +chr4 189957368 190151886 1.21 +chr5 166550028 166647640 1.21 +chr6 23499391 23684090 1.21 +chr6 66876814 67021555 1.21 +chr6 85028192 85201298 1.21 +chr6 94783870 94898446 1.21 +chr7 85371156 85485924 1.21 +chr7 118629320 118806601 1.21 +chr8 122743719 122893632 1.21 +chr9 11170428 11341967 1.21 +chr9 17839221 18013839 1.21 +chr9 82951747 83098620 1.21 +chr9 105214273 105379246 1.21 +chr9 117911982 118081322 1.21 +chr10 24159166 24341427 1.21 +chr10 36972913 37144238 1.21 +chr10 53912343 54101552 1.21 +chr11 104950107 105093266 1.21 +chr12 28228135 28228812 1.21 +chr12 58917391 59098004 1.21 +chr12 65509085 65693926 1.21 +chr12 87561517 87715880 1.21 +chr12 113937914 114127188 1.21 +chr13 56523630 56717407 1.21 +chr13 64727675 64900032 1.21 +chr13 77789426 77997374 1.21 +chr13 91284445 91452121 1.21 +chr13 92499797 92681312 1.21 +chr13 95333180 95498792 1.21 +chr13 100313432 100480730 1.21 +chr13 105286223 105459675 1.21 +chr14 33897190 34061283 1.21 +chr14 37337239 37487767 1.21 +chr15 41409166 41591912 1.21 +chr17 47844680 48028972 1.21 +chr18 61594910 61752944 1.21 +chr18 68809466 69000766 1.21 +chr20 9197717 9340955 1.21 +chr20 26006126 26220344 1.21 +chr21 40630421 40630982 1.21 +chrX 28029871 28187101 1.21 +chrX 81388806 81389596 1.21 +chrX 143983780 144162387 1.21 +chrX 145778720 145884794 1.21 +chrY 23612040 23794544 1.21 +chr1 102758472 102908844 1.22 +chr1 175974940 176155256 1.22 +chr2 77934103 78088722 1.22 +chr2 155527554 155706737 1.22 +chr2 188855759 189025686 1.22 +chr3 82655862 82799401 1.22 +chr3 87569879 87730255 1.22 +chr3 111576135 111740734 1.22 +chr3 159590747 159779789 1.22 +chr3 168566872 168739931 1.22 +chr3 182297993 182470707 1.22 +chr3 183174949 183353241 1.22 +chr4 11429778 11591553 1.22 +chr4 34462310 34632915 1.22 +chr4 58185990 58349753 1.22 +chr4 96348969 96517904 1.22 +chr4 116748182 116937051 1.22 +chr4 128468219 128623706 1.22 +chr4 142401195 142587354 1.22 +chr4 157665396 157840215 1.22 +chr4 182510849 182656131 1.22 +chr5 13218128 13374982 1.22 +chr5 56921507 57065064 1.22 +chr5 59340905 59341702 1.22 +chr6 48824625 48993352 1.22 +chr6 122952226 123105805 1.22 +chr7 11772911 11940697 1.22 +chr7 110006153 110166536 1.22 +chr7 110006194 110166524 1.22 +chr7 114005319 114175715 1.22 +chr8 31908045 32086561 1.22 +chr8 50882181 51087101 1.22 +chr9 77399680 77400521 1.22 +chr9 117248721 117432842 1.22 +chr10 52898354 53069428 1.22 +chr10 66811696 66961629 1.22 +chr10 107683471 107864697 1.22 +chr10 109290751 109488706 1.22 +chr10 128798554 128968853 1.22 +chr11 20206660 20372501 1.22 +chr11 40928715 41089514 1.22 +chr13 55372320 55544178 1.22 +chr13 57629383 57794495 1.22 +chr13 69138664 69317439 1.22 +chr13 83766576 83924559 1.22 +chr14 27534095 27695886 1.22 +chr15 22736034 22894833 1.22 +chr15 24960345 25130043 1.22 +chr16 6846409 7019846 1.22 +chr16 72300075 72453658 1.22 +chr18 28808364 28955525 1.22 +chr18 63881662 63997076 1.22 +chr21 17336806 17489108 1.22 +chr21 22151924 22333707 1.22 +chr21 30673984 30855176 1.22 +chrX 76640611 76788971 1.22 +chrX 80307294 80471254 1.22 +chrX 90182126 90332983 1.22 +chrX 137286220 137458601 1.22 +chrY 10088705 10250875 1.22 +chr1 56595685 56724303 1.23 +chr1 57456434 57628847 1.23 +chr1 69215584 69364440 1.23 +chr1 105468369 105631855 1.23 +chr1 187292331 187459950 1.23 +chr1 213048945 213231437 1.23 +chr2 56202097 56396479 1.23 +chr2 108502515 108667821 1.23 +chr2 150865067 151039803 1.23 +chr3 27349643 27531253 1.23 +chr3 118153905 118326520 1.23 +chr4 15981564 16185166 1.23 +chr4 18737375 18858211 1.23 +chr4 32138117 32292373 1.23 +chr4 101510584 101672095 1.23 +chr4 109877070 110039180 1.23 +chr4 172208306 172379167 1.23 +chr5 8413255 8600646 1.23 +chr5 90806344 90964362 1.23 +chr5 152539684 152728888 1.23 +chr6 19833231 20018547 1.23 +chr6 57292519 57451664 1.23 +chr6 104541641 104626173 1.23 +chr6 142222399 142361416 1.23 +chr7 67546085 67703913 1.23 +chr7 124677379 124865352 1.23 +chr8 64465972 64651147 1.23 +chr8 69451201 69616969 1.23 +chr8 93160371 93308372 1.23 +chr8 118573281 118737738 1.23 +chr8 139307409 139453227 1.23 +chr9 25690187 25853227 1.23 +chr9 29493271 29639053 1.23 +chr9 108208167 108395870 1.23 +chr10 65699664 65700044 1.23 +chr10 84424513 84577760 1.23 +chr10 130997310 130997876 1.23 +chr11 42864060 43020941 1.23 +chr12 39661185 39833116 1.23 +chr12 126779004 126932042 1.23 +chr13 22108664 22109399 1.23 +chr13 108167626 108341331 1.23 +chr16 58177854 58178675 1.23 +chr16 58776587 58993431 1.23 +chr16 76343711 76539056 1.23 +chr21 23491444 23651727 1.23 +chrX 29011746 29143750 1.23 +chrX 36335465 36531290 1.23 +chrX 45140586 45320235 1.23 +chrX 95213828 95348733 1.23 +chrX 97508539 97716150 1.23 +chrX 128151204 128272268 1.23 +chr1 237591432 237780877 1.24 +chr2 52045737 52233820 1.24 +chr2 129638238 129801244 1.24 +chr2 142692260 142876374 1.24 +chr2 175978460 176145301 1.24 +chr2 186280439 186426350 1.24 +chr3 7560443 7760313 1.24 +chr3 112056227 112057022 1.24 +chr3 191651334 191835494 1.24 +chr4 33712127 33712843 1.24 +chr4 61650910 61798492 1.24 +chr4 150581367 150736943 1.24 +chr5 15191420 15315309 1.24 +chr5 146975536 147089688 1.24 +chr5 174474436 174643725 1.24 +chr6 165061379 165244688 1.24 +chr7 62325611 62464970 1.24 +chr7 62908796 63102874 1.24 +chr7 122549071 122716095 1.24 +chr7 122549101 122549448 1.24 +chr8 14278141 14461142 1.24 +chr8 18249326 18450010 1.24 +chr8 47816618 47982164 1.24 +chr8 51483937 51664779 1.24 +chr8 70223686 70378901 1.24 +chr8 106002673 106200542 1.24 +chr9 9657611 9823754 1.24 +chr9 9932073 10130653 1.24 +chr9 83969058 84168612 1.24 +chr9 110239919 110428437 1.24 +chr10 20561285 20741009 1.24 +chr10 54769832 54938912 1.24 +chr11 21566376 21747063 1.24 +chr11 40185000 40379506 1.24 +chr11 106083757 106252007 1.24 +chr11 132451658 132626345 1.24 +chr12 16742828 16908591 1.24 +chr12 82133389 82134182 1.24 +chr13 96143661 96297462 1.24 +chr15 22736020 22894833 1.24 +chr16 50431379 50432028 1.24 +chr18 7827406 7985296 1.24 +chrX 62268206 62462742 1.24 +chrX 92989831 93172474 1.24 +chrX 104392277 104584586 1.24 +chr1 48917318 49102938 1.25 +chr1 85868659 85959828 1.25 +chr1 184949732 185093551 1.25 +chr2 16245984 16435838 1.25 +chr2 19328431 19511727 1.25 +chr2 19328462 19511695 1.25 +chr2 115568405 115730309 1.25 +chr2 117162771 117350524 1.25 +chr2 166510124 166700135 1.25 +chr2 185796056 186001245 1.25 +chr3 30704315 30705070 1.25 +chr3 68472813 68645976 1.25 +chr3 149208193 149208677 1.25 +chr4 13490350 13655289 1.25 +chr4 20347912 20531936 1.25 +chr4 105288371 105449318 1.25 +chr4 127250479 127434554 1.25 +chr4 127434114 127434494 1.25 +chr5 155562586 155563351 1.25 +chr6 9606972 9733133 1.25 +chr6 82503161 82690511 1.25 +chr6 83405526 83590455 1.25 +chr7 94315045 94480285 1.25 +chr7 95121078 95310527 1.25 +chr8 84378331 84550071 1.25 +chr9 26681234 26681720 1.25 +chr9 81315514 81316298 1.25 +chr10 118689986 118853807 1.25 +chr11 24362912 24551940 1.25 +chr11 86920498 87069201 1.25 +chr11 99613168 99757459 1.25 +chr12 23609734 23784529 1.25 +chr12 30395911 30548839 1.25 +chr13 43148302 43305457 1.25 +chr13 55715887 55883767 1.25 +chr17 12920204 13085706 1.25 +chr18 33631807 33798667 1.25 +chr18 60284571 60448778 1.25 +chr19 23555073 23732302 1.25 +chrX 63351109 63519991 1.25 +chrX 124726353 124825239 1.25 +chrY 8634089 8808181 1.25 +chr1 68609865 68712960 1.26 +chr1 95756281 95929212 1.26 +chr1 115660513 115837500 1.26 +chr1 118390909 118391668 1.26 +chr1 206612616 206789340 1.26 +chr2 18490095 18666766 1.26 +chr2 106847377 107037217 1.26 +chr2 115568405 115730304 1.26 +chr2 130418007 130583404 1.26 +chr2 138069597 138255840 1.26 +chr2 150165935 150366790 1.26 +chr2 198816122 199013992 1.26 +chr3 30275518 30447552 1.26 +chr3 62016738 62182587 1.26 +chr3 107635524 107671459 1.26 +chr3 119676303 119822832 1.26 +chr3 147011398 147184818 1.26 +chr4 116321048 116472386 1.26 +chr4 138014454 138176309 1.26 +chr4 179303625 179403709 1.26 +chr5 38200579 38306406 1.26 +chr5 100711511 100906817 1.26 +chr7 34143563 34292666 1.26 +chr7 77710865 77899863 1.26 +chr7 110835679 110975058 1.26 +chr8 57918204 58101868 1.26 +chr8 140285430 140443678 1.26 +chr9 24877888 25069382 1.26 +chr9 29089125 29250390 1.26 +chr9 117088639 117257661 1.26 +chr10 37693680 37822602 1.26 +chr10 59005947 59241663 1.26 +chr10 128180787 128326333 1.26 +chr11 14830578 14997910 1.26 +chr11 27223566 27388824 1.26 +chr11 88739639 88927964 1.26 +chr12 28623872 28774457 1.26 +chr12 78967748 79140491 1.26 +chr12 82690981 82845109 1.26 +chr12 96065359 96245190 1.26 +chr13 68180810 68334608 1.26 +chr16 7933143 8120601 1.26 +chr16 77599573 77781796 1.26 +chr17 49753469 49922957 1.26 +chr17 67169020 67327134 1.26 +chr18 6752920 6933631 1.26 +chr18 22740630 22930994 1.26 +chr18 23968045 23968797 1.26 +chr18 64985278 65144962 1.26 +chr18 66753077 66929602 1.26 +chr21 26643246 26798261 1.26 +chrX 25247627 25248382 1.26 +chrX 94578207 94717584 1.26 +chrX 116471060 116589009 1.26 +chrY 6163949 6386452 1.26 +chr1 174297595 174457323 1.27 +chr1 236568362 236755350 1.27 +chr2 14744438 14891566 1.27 +chr2 89772211 89772694 1.27 +chr2 156410442 156580098 1.27 +chr4 108638904 108797073 1.27 +chr4 184232930 184404421 1.27 +chr5 49907782 50093906 1.27 +chr5 63325516 63499151 1.27 +chr5 98073104 98073634 1.27 +chr5 110059851 110181740 1.27 +chr5 125160995 125355179 1.27 +chr6 51267587 51472545 1.27 +chr6 80800588 80953422 1.27 +chr6 152324233 152411820 1.27 +chr7 80388111 80528144 1.27 +chr7 112279599 112435186 1.27 +chr7 112279641 112435146 1.27 +chr7 136606310 136780129 1.27 +chr8 20700584 20890068 1.27 +chr8 49937832 50097992 1.27 +chr8 77869835 78033428 1.27 +chr8 97773109 97944343 1.27 +chr8 108980084 109137354 1.27 +chr8 110436818 110612510 1.27 +chr8 111740331 111910034 1.27 +chr8 132474524 132638132 1.27 +chr9 11389658 11588107 1.27 +chr9 102748915 102917912 1.27 +chr11 38512156 38673888 1.27 +chr11 56238253 56397616 1.27 +chr11 78641711 78791818 1.27 +chr11 103803623 103964960 1.27 +chr12 74178839 74333757 1.27 +chr12 80827000 80973942 1.27 +chr13 25122500 25300811 1.27 +chr13 77954930 78112209 1.27 +chr17 22465099 22465647 1.27 +chr18 32884985 32885636 1.27 +chr18 62491384 62645196 1.27 +chr20 40680814 40792351 1.27 +chrX 67342298 67474154 1.27 +chrX 68455961 68651311 1.27 +chrX 87708952 87799321 1.27 +chrX 110343521 110498830 1.27 +chrX 120476674 120618187 1.27 +chrX 130385383 130512118 1.27 +chrX 142121643 142239873 1.27 +chrX 144849234 145030848 1.27 +chrX 150493632 150654782 1.27 +chr1 96868133 97055430 1.28 +chr1 97892548 98068736 1.28 +chr1 216532635 216718346 1.28 +chr1 238957519 239131143 1.28 +chr2 13501029 13665382 1.28 +chr2 94782159 94983765 1.28 +chr2 184329536 184509986 1.28 +chr2 209951701 210150189 1.28 +chr2 210167648 210331732 1.28 +chr3 3134172 3304965 1.28 +chr3 54612454 54778896 1.28 +chr4 62331997 62507133 1.28 +chr4 83182488 83348944 1.28 +chr4 110057781 110225193 1.28 +chr4 130001146 130195432 1.28 +chr4 134372150 134551414 1.28 +chr5 87524422 87715075 1.28 +chr5 152817276 152985131 1.28 +chr6 54720745 54910224 1.28 +chr6 91251335 91352253 1.28 +chr6 115381841 115506680 1.28 +chr6 128448619 128633208 1.28 +chr7 48821083 48911960 1.28 +chr7 67228859 67229276 1.28 +chr8 33027897 33028624 1.28 +chr8 73498872 73677480 1.28 +chr9 71447572 71636838 1.28 +chr9 79930264 79930787 1.28 +chr10 92100790 92284115 1.28 +chr11 81301979 81443218 1.28 +chr11 84737833 84908431 1.28 +chr12 37327276 37489074 1.28 +chr12 53730294 53914923 1.28 +chr12 69745683 69884764 1.28 +chr12 83409425 83566599 1.28 +chr13 80871787 81079018 1.28 +chr13 101318694 101507371 1.28 +chr14 46624364 46819048 1.28 +chr15 19791367 19970461 1.28 +chr15 23661899 23823333 1.28 +chr20 22476800 22597585 1.28 +chr20 53411918 53537915 1.28 +chr21 24478239 24645814 1.28 +chrX 72656424 72823653 1.28 +chrX 75925804 75926596 1.28 +chrX 123854281 123854885 1.28 +chr1 82426194 82603316 1.29 +chr1 217478892 217657878 1.29 +chr1 235542207 235725718 1.29 +chr2 17006354 17177187 1.29 +chr2 50950354 50950648 1.29 +chr2 139529650 139697746 1.29 +chr2 227039805 227205229 1.29 +chr3 28645912 28824317 1.29 +chr3 41172087 41354700 1.29 +chr4 5094075 5290909 1.29 +chr4 22163792 22309218 1.29 +chr4 68644475 68645263 1.29 +chr4 94662902 94838368 1.29 +chr4 94995921 94996745 1.29 +chr4 163467846 163611458 1.29 +chr5 7426758 7530112 1.29 +chr5 50061472 50168170 1.29 +chr5 117322499 117464139 1.29 +chr6 27422168 27563699 1.29 +chr6 103441042 103538793 1.29 +chr6 125389199 125541230 1.29 +chr6 141124549 141227062 1.29 +chr6 152125036 152333573 1.29 +chr7 54607124 54784717 1.29 +chr7 153721042 153901560 1.29 +chr8 73722232 73910787 1.29 +chr8 75573453 75722946 1.29 +chr8 122721235 122875986 1.29 +chr9 88883454 89058511 1.29 +chr10 20025423 20189475 1.29 +chr10 77812080 78010375 1.29 +chr10 117796864 117962944 1.29 +chr11 36670298 36852531 1.29 +chr12 85522910 85686077 1.29 +chr12 124939576 125073994 1.29 +chr13 53669880 53839191 1.29 +chr13 103214616 103420259 1.29 +chr14 38348741 38528993 1.29 +chr14 78800500 78957629 1.29 +chr15 44046046 44246628 1.29 +chr16 26107505 26268718 1.29 +chr16 32190271 32345186 1.29 +chr16 74775686 74929189 1.29 +chr17 11938351 12108967 1.29 +chr18 73908671 74017409 1.29 +chr20 58880457 58881237 1.29 +chrX 96349949 96509334 1.29 +chrY 16111429 16274219 1.29 +chr1 14511126 14690862 1.3 +chr1 55647414 55828567 1.3 +chr1 64206725 64303907 1.3 +chr1 161212962 161388982 1.3 +chr1 169324707 169484782 1.3 +chr1 230006922 230007507 1.3 +chr2 104867082 105049417 1.3 +chr2 132886154 133065879 1.3 +chr2 159108864 159300999 1.3 +chr2 179945358 180117962 1.3 +chr2 180322044 180501048 1.3 +chr2 188197236 188359167 1.3 +chr3 25551992 25552787 1.3 +chr3 28813297 28966841 1.3 +chr3 156642078 156810052 1.3 +chr3 191495503 191657007 1.3 +chr4 54822133 54996008 1.3 +chr4 125513760 125670332 1.3 +chr4 141603576 141774273 1.3 +chr4 177405907 177623780 1.3 +chr5 89564662 89728632 1.3 +chr5 154429161 154604443 1.3 +chr6 29321047 29495843 1.3 +chr6 49686804 49805309 1.3 +chr7 142857956 142929771 1.3 +chr8 2898662 3068843 1.3 +chr8 17782600 17783052 1.3 +chr9 2521111 2521805 1.3 +chr10 61902228 62069013 1.3 +chr10 110235647 110401173 1.3 +chr11 133984028 134156487 1.3 +chr12 66077114 66250763 1.3 +chr13 38450249 38608557 1.3 +chr13 46981034 46981776 1.3 +chr13 62944467 63099883 1.3 +chr13 67325775 67493542 1.3 +chr13 80711182 80918589 1.3 +chr14 86833840 86986583 1.3 +chr15 25800263 25980037 1.3 +chr15 35738732 35906861 1.3 +chr17 65314673 65421406 1.3 +chr18 5260008 5444854 1.3 +chr18 29304152 29472016 1.3 +chr20 16588770 16671907 1.3 +chrX 32142361 32277808 1.3 +chrX 86196923 86368724 1.3 +chrX 101574713 101575302 1.3 +chrX 138587336 138777284 1.3 +chr1 98681360 98839775 1.31 +chr2 15932536 16131069 1.31 +chr2 99955231 100127792 1.31 +chr2 206054394 206242414 1.31 +chr3 3156042 3326580 1.31 +chr3 110118090 110272403 1.31 +chr3 141263358 141264123 1.31 +chr3 149312730 149313543 1.31 +chr3 193387515 193550113 1.31 +chr4 80383883 80547099 1.31 +chr4 90923945 90924643 1.31 +chr4 103067218 103220633 1.31 +chr4 138445756 138622735 1.31 +chr4 166740143 166917702 1.31 +chr4 190520037 190668407 1.31 +chr5 3172060 3340431 1.31 +chr5 5500139 5686966 1.31 +chr5 40113144 40281744 1.31 +chr5 60735468 60897700 1.31 +chr6 96958620 97139258 1.31 +chr6 139955534 140131757 1.31 +chr7 46123519 46124125 1.31 +chr8 2303640 2411205 1.31 +chr8 2303675 2304133 1.31 +chr8 55504844 55667413 1.31 +chr9 16987010 17148443 1.31 +chr9 72488794 72637606 1.31 +chr9 78821714 78991548 1.31 +chr9 90604332 90759707 1.31 +chr10 33721598 33912463 1.31 +chr10 60813496 60976631 1.31 +chr11 50013045 50013630 1.31 +chr11 50013069 50182216 1.31 +chr12 22465615 22628113 1.31 +chr12 29550028 29733366 1.31 +chr12 29550028 29733343 1.31 +chr12 41495108 41495904 1.31 +chr12 99369399 99527535 1.31 +chr13 33995112 34159357 1.31 +chr13 111638158 111785816 1.31 +chr19 33293142 33399234 1.31 +chr20 7012254 7110690 1.31 +chr20 11812380 11979405 1.31 +chr20 15512841 15602650 1.31 +chr20 37522311 37666045 1.31 +chr20 50717376 50828721 1.31 +chrX 32347186 32479426 1.31 +chrX 111819716 111820515 1.31 +chrY 17166593 17345966 1.31 +chrY 20066103 20221627 1.31 +chr1 69875752 69876541 1.32 +chr1 75818828 76000027 1.32 +chr1 77147556 77248155 1.32 +chr1 197774987 197913697 1.32 +chr2 1612842 1783287 1.32 +chr2 1612887 1785220 1.32 +chr2 88939391 89105046 1.32 +chr2 131896303 132072566 1.32 +chr2 200012080 200209072 1.32 +chr3 104052002 104208021 1.32 +chr3 122378972 122541183 1.32 +chr3 138893130 139048105 1.32 +chr3 163463027 163648089 1.32 +chr4 36674866 36838139 1.32 +chr4 173240668 173410133 1.32 +chr4 181215989 181422694 1.32 +chr5 2570762 2724892 1.32 +chr5 39226026 39422569 1.32 +chr5 136365521 136366234 1.32 +chr6 101399800 101541206 1.32 +chr7 19402555 19587422 1.32 +chr7 26748780 26749335 1.32 +chr9 74808583 74977612 1.32 +chr9 89208558 89375340 1.32 +chr9 116920527 117122848 1.32 +chr9 116941815 117122920 1.32 +chr10 25969731 26132531 1.32 +chr10 87190070 87373214 1.32 +chr10 132635061 132635351 1.32 +chr12 73066799 73273410 1.32 +chr14 39369030 39537972 1.32 +chr17 50112691 50268063 1.32 +chr21 18224008 18383964 1.32 +chrX 5403668 5566016 1.32 +chrX 35271454 35446803 1.32 +chrX 43352640 43449221 1.32 +chrX 51220237 51394261 1.32 +chrX 56977002 57134049 1.32 +chrY 21140424 21306286 1.32 +chr1 91067460 91175162 1.33 +chr1 99670834 99835759 1.33 +chr1 170113616 170285659 1.33 +chr2 7661942 7829976 1.33 +chr2 22998605 23182948 1.33 +chr2 39502082 39691390 1.33 +chr2 48938583 49093125 1.33 +chr2 131163481 131364402 1.33 +chr2 137366984 137538813 1.33 +chr3 81809988 81810796 1.33 +chr3 96093190 96250469 1.33 +chr3 105815245 105971443 1.33 +chr3 198339454 198340252 1.33 +chr4 26746608 26747433 1.33 +chr4 75136723 75305982 1.33 +chr4 167845359 168019133 1.33 +chr5 66695993 66888015 1.33 +chr5 92986024 93173416 1.33 +chr5 107339380 107503471 1.33 +chr5 122463059 122626530 1.33 +chr5 146313344 146482537 1.33 +chr6 114513327 114699492 1.33 +chr6 122617580 122660549 1.33 +chr6 152094531 152188434 1.33 +chr6 154042939 154223658 1.33 +chr7 45903670 46077198 1.33 +chr7 89321351 89474116 1.33 +chr8 32530048 32715279 1.33 +chr8 104875758 105015139 1.33 +chr9 18579957 18743091 1.33 +chr9 112915772 113092453 1.33 +chr10 122467471 122467966 1.33 +chr11 112570898 112764095 1.33 +chr12 13505608 13642782 1.33 +chr12 114694711 114865871 1.33 +chr13 72606913 72777348 1.33 +chr13 74355387 74530080 1.33 +chr16 53823781 53975887 1.33 +chr18 6041920 6213636 1.33 +chr20 59426926 59538706 1.33 +chrX 74701380 74866100 1.33 +chrX 131183827 131343176 1.33 +chrX 136272151 136409212 1.33 +chrX 146504015 146682434 1.33 +chr1 50343064 50459755 1.34 +chr1 107386318 107478559 1.34 +chr1 119360541 119480610 1.34 +chr2 99112041 99262127 1.34 +chr2 148009604 148187956 1.34 +chr4 68459613 68647327 1.34 +chr4 187292822 187293270 1.34 +chr5 14496184 14655227 1.34 +chr6 44987777 45164728 1.34 +chr6 54092161 54254813 1.34 +chr7 8950609 9102382 1.34 +chr7 42647643 42810331 1.34 +chr7 70687274 70842877 1.34 +chr7 90960627 91079688 1.34 +chr7 115640211 115832430 1.34 +chr8 119798302 119961178 1.34 +chr9 16141186 16325481 1.34 +chr9 88787420 88940656 1.34 +chr9 116878175 117053374 1.34 +chr10 60095385 60270663 1.34 +chr10 81634066 81634692 1.34 +chr10 115833961 115994342 1.34 +chr10 116774295 116971212 1.34 +chr11 4745892 4948056 1.34 +chr11 27884866 28058344 1.34 +chr11 102869304 103066049 1.34 +chr11 133514734 133706144 1.34 +chr12 19280723 19281492 1.34 +chr12 78580511 78745903 1.34 +chr14 81191238 81376380 1.34 +chr15 71270959 71440808 1.34 +chr16 52428121 52626454 1.34 +chr16 52428138 52626428 1.34 +chr17 61192768 61362729 1.34 +chr19 6351112 6519252 1.34 +chr20 23543240 23638382 1.34 +chr20 40040735 40041178 1.34 +chrX 27025629 27210559 1.34 +chrY 18135971 18136728 1.34 +chr1 4476758 4608070 1.35 +chr1 83494525 83678458 1.35 +chr1 145434722 145622003 1.35 +chr1 157083023 157241521 1.35 +chr1 208589372 208727000 1.35 +chr1 230738768 230922038 1.35 +chr2 100117165 100292273 1.35 +chr2 147927761 148088945 1.35 +chr2 222493356 222674220 1.35 +chr3 158817691 158979197 1.35 +chr3 170366524 170543975 1.35 +chr3 187914183 187914670 1.35 +chr4 35206819 35400282 1.35 +chr4 52354879 52532792 1.35 +chr5 5879140 6020331 1.35 +chr5 36988555 37177051 1.35 +chr5 41662376 41829385 1.35 +chr5 93540085 93709247 1.35 +chr5 114441173 114603245 1.35 +chr5 178243610 178415257 1.35 +chr6 20630798 20759036 1.35 +chr6 46918436 47035989 1.35 +chr6 97824224 97971094 1.35 +chr6 164265539 164265787 1.35 +chr8 115760314 115915271 1.35 +chr9 7904520 8056890 1.35 +chr10 124083545 124268622 1.35 +chr11 55176672 55351006 1.35 +chr11 87911050 88091465 1.35 +chr11 102613735 102771566 1.35 +chr13 109210635 109357541 1.35 +chr14 31443192 31601773 1.35 +chr14 58323469 58470270 1.35 +chr14 60206359 60397740 1.35 +chr17 29512898 29667899 1.35 +chr18 6752916 6933612 1.35 +chr18 34297490 34473929 1.35 +chrX 65362816 65515922 1.35 +chr1 99670780 99835817 1.36 +chr1 142642787 142787183 1.36 +chr1 163383027 163567283 1.36 +chr1 218698700 218866017 1.36 +chr2 16384031 16384829 1.36 +chr2 21280646 21452847 1.36 +chr2 31383815 31583388 1.36 +chr2 204715244 204915179 1.36 +chr3 5501957 5696842 1.36 +chr3 6475280 6636703 1.36 +chr3 73463994 73612035 1.36 +chr3 100492740 100545594 1.36 +chr3 162044681 162207578 1.36 +chr3 174372436 174549467 1.36 +chr3 181855132 181855955 1.36 +chr4 4919317 5078151 1.36 +chr4 53060094 53207986 1.36 +chr4 82199002 82332981 1.36 +chr5 35388213 35513588 1.36 +chr6 20101886 20272058 1.36 +chr6 20101922 20272069 1.36 +chr6 79531824 79716854 1.36 +chr6 104973586 104973967 1.36 +chr7 41208853 41345448 1.36 +chr8 30945721 30946131 1.36 +chr8 68363210 68363812 1.36 +chr8 79633094 79802906 1.36 +chr8 133156783 133317994 1.36 +chr9 14419816 14586697 1.36 +chr10 27935308 28141733 1.36 +chr10 113860111 114056751 1.36 +chr11 35657471 35810959 1.36 +chr11 83021047 83205297 1.36 +chr11 101247718 101405229 1.36 +chr12 40716223 40716974 1.36 +chr13 20982693 21161824 1.36 +chr14 53557920 53721815 1.36 +chr14 80497781 80658071 1.36 +chr18 21431339 21583434 1.36 +chr18 21431373 21583433 1.36 +chr18 28257154 28415030 1.36 +chr18 50538203 50702047 1.36 +chr18 51445587 51648079 1.36 +chr18 74707626 74870951 1.36 +chr18 74707640 74870925 1.36 +chr19 22133724 22288871 1.36 +chr19 32891236 33099546 1.36 +chr19 36894580 36979850 1.36 +chr20 8156614 8328068 1.36 +chr20 19157422 19322167 1.36 +chrX 73387054 73556231 1.36 +chrX 103498150 103656697 1.36 +chrX 108414862 108517413 1.36 +chrX 146471609 146530342 1.36 +chrX 154334471 154482330 1.36 +chr1 18255166 18394021 1.37 +chr1 62131262 62274416 1.37 +chr1 94564158 94767971 1.37 +chr1 108330015 108512967 1.37 +chr1 225649911 225807728 1.37 +chr2 122827843 122978689 1.37 +chr3 34495510 34655794 1.37 +chr3 97022228 97176817 1.37 +chr3 108464746 108465227 1.37 +chr3 154955764 155113460 1.37 +chr3 177684955 177849617 1.37 +chr4 24079171 24250252 1.37 +chr4 89621629 89807633 1.37 +chr4 98622889 98832379 1.37 +chr4 98622912 98833448 1.37 +chr4 104276780 104433230 1.37 +chr4 175341179 175488565 1.37 +chr6 28599637 28767189 1.37 +chr6 65839991 65840775 1.37 +chr6 117915464 118016129 1.37 +chr8 49685131 49685914 1.37 +chr8 123525975 123697977 1.37 +chr9 106528618 106714989 1.37 +chr9 121736192 121918440 1.37 +chr10 17758041 17921747 1.37 +chr10 62853055 63041017 1.37 +chr10 82479195 82648679 1.37 +chr10 114874404 115058195 1.37 +chr11 96155681 96302306 1.37 +chr11 113740438 113878585 1.37 +chr12 129082307 129082773 1.37 +chr14 55649062 55827391 1.37 +chr14 97065728 97234127 1.37 +chr15 98650852 98814162 1.37 +chr16 33544449 33715230 1.37 +chr16 54425522 54559952 1.37 +chr18 11065439 11231074 1.37 +chr19 22570613 22729077 1.37 +chr20 6209827 6351381 1.37 +chr20 14556853 14704918 1.37 +chr20 57583626 57734574 1.37 +chr22 27103294 27317685 1.37 +chrX 42106039 42272650 1.37 +chrY 14466905 14467721 1.37 +chr1 59939363 60081655 1.38 +chr2 110173028 110348650 1.38 +chr2 119406291 119582870 1.38 +chr2 133513096 133688729 1.38 +chr2 169206769 169397061 1.38 +chr2 183145945 183311858 1.38 +chr2 228366700 228542036 1.38 +chr3 768376 958261 1.38 +chr3 66860333 67018889 1.38 +chr3 131457257 131616297 1.38 +chr3 137175189 137175931 1.38 +chr3 144846185 145031570 1.38 +chr3 193748164 193916444 1.38 +chr4 129322994 129526144 1.38 +chr4 143908621 143909369 1.38 +chr4 151531332 151532020 1.38 +chr5 173800904 173985872 1.38 +chr6 1241036 1397672 1.38 +chr6 75301349 75301837 1.38 +chr6 118676249 118787894 1.38 +chr6 131311502 131529403 1.38 +chr6 132102708 132208085 1.38 +chr6 132876727 132877160 1.38 +chr7 127107831 127266861 1.38 +chr8 58226066 58378511 1.38 +chr8 72600219 72767625 1.38 +chr8 90077495 90220312 1.38 +chr8 90077559 90220260 1.38 +chr8 119189820 119373386 1.38 +chr10 18842318 19038215 1.38 +chr12 37199957 37369589 1.38 +chr13 59662163 59888923 1.38 +chr13 107304438 107482925 1.38 +chr14 44775871 44957642 1.38 +chr15 93038000 93169754 1.38 +chr18 43069131 43274185 1.38 +chr20 21493032 21584641 1.38 +chr20 52655199 52655545 1.38 +chrX 7455566 7633822 1.38 +chrX 7633160 7633819 1.38 +chrX 44687783 44688510 1.38 +chrX 126290650 126444827 1.38 +chrY 12581761 12759800 1.38 +chr1 65371370 65460371 1.39 +chr1 143613581 143614341 1.39 +chr1 190142199 190319491 1.39 +chr1 207338657 207512534 1.39 +chr1 221352963 221534370 1.39 +chr1 241339986 241495285 1.39 +chr2 596981 744912 1.39 +chr2 41617751 41618169 1.39 +chr2 133791584 133959364 1.39 +chr2 135632580 135813995 1.39 +chr2 162682911 162846571 1.39 +chr2 240559993 240731366 1.39 +chr3 55606124 55797550 1.39 +chr3 68008697 68146379 1.39 +chr3 78395760 78564986 1.39 +chr3 99133076 99288212 1.39 +chr3 132613105 132784639 1.39 +chr3 170729328 170729895 1.39 +chr3 188693502 188694253 1.39 +chr4 31500911 31663999 1.39 +chr4 88909482 89097085 1.39 +chr4 101150836 101325274 1.39 +chr4 156373857 156552012 1.39 +chr5 27487185 27641956 1.39 +chr5 36275837 36380871 1.39 +chr5 102291745 102448736 1.39 +chr6 69938032 70037252 1.39 +chr6 146065393 146266178 1.39 +chr6 148426072 148609952 1.39 +chr7 16861638 17055792 1.39 +chr7 33718683 33897261 1.39 +chr7 46553602 46734204 1.39 +chr8 105218041 105402499 1.39 +chr9 78050479 78213759 1.39 +chr9 82003000 82148095 1.39 +chr10 47897443 48101918 1.39 +chr10 95774178 95924122 1.39 +chr10 123214100 123388480 1.39 +chr11 107487025 107646360 1.39 +chr11 107721404 107722054 1.39 +chr12 15977584 16171208 1.39 +chr12 20887518 20888220 1.39 +chr12 42413160 42579564 1.39 +chr12 64348953 64349751 1.39 +chr12 70624458 70765581 1.39 +chr12 88092437 88268617 1.39 +chr12 118059529 118238008 1.39 +chr13 52183624 52356899 1.39 +chr14 19570817 19730543 1.39 +chr14 24548302 24715386 1.39 +chr15 27464579 27613829 1.39 +chr20 28069297 28267569 1.39 +chrX 114736950 114737643 1.39 +chrY 6752267 6919657 1.39 +chr1 88594032 88769698 1.4 +chr1 176713719 176849348 1.4 +chr2 11122011 11294825 1.4 +chr2 190415420 190576094 1.4 +chr2 195231804 195390886 1.4 +chr2 205174891 205347264 1.4 +chr2 206824790 207023290 1.4 +chr2 217797626 218009975 1.4 +chr3 57370504 57371093 1.4 +chr3 137706751 137888006 1.4 +chr4 72239164 72405633 1.4 +chr4 81316240 81510343 1.4 +chr4 119888533 120067924 1.4 +chr4 164527243 164688085 1.4 +chr5 80045485 80216158 1.4 +chr5 82570102 82742889 1.4 +chr5 127603123 127759109 1.4 +chr6 71065292 71255915 1.4 +chr7 102949624 103109840 1.4 +chr7 107917096 108107231 1.4 +chr8 53938368 54105592 1.4 +chr8 120711400 120863829 1.4 +chr9 27417088 27590261 1.4 +chr9 102010405 102158130 1.4 +chr9 109317590 109318247 1.4 +chr10 21321389 21321781 1.4 +chr10 86226512 86390131 1.4 +chr10 119495422 119675862 1.4 +chr10 123333219 123506448 1.4 +chr10 129933095 130095088 1.4 +chr11 12368586 12369363 1.4 +chr11 114823737 114993848 1.4 +chr11 115161463 115257393 1.4 +chr12 25552960 25763321 1.4 +chr13 25898602 26065333 1.4 +chr13 26088616 26258539 1.4 +chr13 46548919 46699279 1.4 +chr13 50328528 50471832 1.4 +chr13 73124080 73302606 1.4 +chr15 85186245 85362775 1.4 +chr19 35629568 35766588 1.4 +chr19 42010298 42199663 1.4 +chr20 38174633 38311073 1.4 +chrX 2939526 3122894 1.4 +chrX 21448265 21601094 1.4 +chrX 56037806 56203576 1.4 +chrY 26625199 26798428 1.4 +chr1 34152124 34253960 1.41 +chr1 151011893 151012531 1.41 +chr1 191477741 191478202 1.41 +chr1 217542815 217743251 1.41 +chr1 246013826 246181016 1.41 +chr2 97472556 97702878 1.41 +chr3 24167259 24311442 1.41 +chr3 57297437 57406984 1.41 +chr3 127314118 127484692 1.41 +chr4 47264023 47432177 1.41 +chr4 54523234 54684548 1.41 +chr4 57434444 57434922 1.41 +chr4 74651758 74866776 1.41 +chr4 86385323 86558911 1.41 +chr4 111660518 111862003 1.41 +chr4 152766850 152907961 1.41 +chr6 7898162 8078796 1.41 +chr7 68251011 68418471 1.41 +chr7 119703966 119865943 1.41 +chr7 129658047 129658708 1.41 +chr8 9788890 9958420 1.41 +chr8 52776792 52920522 1.41 +chr8 81904402 82095683 1.41 +chr8 142612553 142790550 1.41 +chr10 4322070 4497152 1.41 +chr10 34543824 34750571 1.41 +chr11 11681667 11828279 1.41 +chr11 92720473 92905772 1.41 +chr12 76525022 76660149 1.41 +chr12 106096640 106265232 1.41 +chr15 74499839 74647142 1.41 +chr16 76434234 76606517 1.41 +chr18 168428 340445 1.41 +chr18 3863274 4046678 1.41 +chr18 66000802 66001509 1.41 +chrX 31427078 31590251 1.41 +chrX 132222083 132364969 1.41 +chr1 83633989 83797164 1.42 +chr1 175450745 175559022 1.42 +chr1 228957731 229156894 1.42 +chr2 6618691 6796407 1.42 +chr2 169796806 169937266 1.42 +chr2 169796837 169937261 1.42 +chr3 138231890 138416930 1.42 +chr3 190563330 190731931 1.42 +chr4 41340107 41527091 1.42 +chr4 88731532 88903393 1.42 +chr4 124508498 124677424 1.42 +chr6 28140043 28246315 1.42 +chr6 63764613 63922893 1.42 +chr6 152520069 152520603 1.42 +chr7 29450068 29624460 1.42 +chr7 69104887 69250742 1.42 +chr7 80906040 81083807 1.42 +chr7 102514284 102705988 1.42 +chr9 89829931 90026396 1.42 +chr10 42660894 42830194 1.42 +chr10 55596032 55596257 1.42 +chr11 5753721 5927294 1.42 +chr11 16626965 16801594 1.42 +chr11 93743479 93936234 1.42 +chr11 130972996 131149195 1.42 +chr12 64532787 64711495 1.42 +chr14 35613641 35778687 1.42 +chrY 15267652 15268179 1.42 +chr2 102713202 102893869 1.43 +chr2 210628113 210819973 1.43 +chr2 225556163 225739791 1.43 +chr2 235987180 236177484 1.43 +chr3 59701342 59875950 1.43 +chr3 81904890 82066186 1.43 +chr3 121651205 121651894 1.43 +chr3 125236945 125434205 1.43 +chr3 181453963 181647155 1.43 +chr4 77680481 77681311 1.43 +chr4 77782579 77943381 1.43 +chr4 139829369 139830163 1.43 +chr4 146558596 146724447 1.43 +chr4 166240548 166418926 1.43 +chr4 174136216 174137023 1.43 +chr5 69917500 70040712 1.43 +chr5 178243610 178455510 1.43 +chr6 24254617 24421543 1.43 +chr6 47870455 48002399 1.43 +chr6 116166727 116304219 1.43 +chr7 7176442 7292335 1.43 +chr7 56264968 56265717 1.43 +chr9 87247884 87248580 1.43 +chr9 87920679 88054773 1.43 +chr10 22399419 22575894 1.43 +chr11 123265105 123449312 1.43 +chr12 5163995 5164563 1.43 +chr12 97941659 98092858 1.43 +chr13 112025897 112208253 1.43 +chr14 50856299 51017418 1.43 +chr14 97835615 98011599 1.43 +chr15 79566763 79756514 1.43 +chr15 81302303 81488639 1.43 +chr15 99831524 100036168 1.43 +chr16 70783699 70973594 1.43 +chr17 28664934 28816067 1.43 +chr19 21345165 21504289 1.43 +chrX 6957788 7136832 1.43 +chr1 48002310 48202605 1.44 +chr1 182747653 182876763 1.44 +chr2 32483627 32649925 1.44 +chr2 173168767 173332941 1.44 +chr2 182686311 182851083 1.44 +chr2 198253860 198438524 1.44 +chr2 220237135 220431654 1.44 +chr4 55856185 55987940 1.44 +chr4 90029296 90200476 1.44 +chr4 131096084 131265054 1.44 +chr5 3426805 3559003 1.44 +chr5 79936331 80082792 1.44 +chr5 99850207 100001668 1.44 +chr6 40860381 41038343 1.44 +chr7 86933537 87062340 1.44 +chr7 131132439 131308575 1.44 +chr8 53078890 53252047 1.44 +chr8 82622728 82768419 1.44 +chr8 127563630 127764314 1.44 +chr9 97173317 97362893 1.44 +chr10 28985024 29145346 1.44 +chr10 33174826 33372767 1.44 +chr10 35838794 36004759 1.44 +chr10 108400155 108574810 1.44 +chr11 94849670 95025482 1.44 +chrX 102547184 102663453 1.44 +chr1 7059934 7186706 1.45 +chr1 181306539 181493746 1.45 +chr2 53784663 53945814 1.45 +chr2 119282256 119432338 1.45 +chr2 144588986 144779859 1.45 +chr3 115459232 115611158 1.45 +chr3 120110945 120111694 1.45 +chr3 140271723 140451428 1.45 +chr3 157113250 157286182 1.45 +chr4 176481822 176566236 1.45 +chr4 186650182 186822363 1.45 +chr5 60203778 60204237 1.45 +chr6 99896150 100068707 1.45 +chr6 119595033 119707570 1.45 +chr6 155961870 156122661 1.45 +chr7 64729936 64924073 1.45 +chr7 156044144 156202337 1.45 +chr8 65377850 65551264 1.45 +chr8 134871608 135047479 1.45 +chr9 85290912 85485840 1.45 +chr9 85859428 85948488 1.45 +chr9 89286203 89446273 1.45 +chr10 29841338 30014928 1.45 +chr10 92924800 93134214 1.45 +chr11 7401245 7402032 1.45 +chr11 111797499 111973902 1.45 +chr11 125962061 126160026 1.45 +chr12 75292746 75293210 1.45 +chr12 90372960 90550230 1.45 +chr14 56456968 56623373 1.45 +chr16 9634606 9827687 1.45 +chr17 61687769 61864883 1.45 +chr18 4926284 5083817 1.45 +chr18 10865355 11045527 1.45 +chr18 18072986 18222633 1.45 +chr19 20458451 20637715 1.45 +chr21 44672693 44846917 1.45 +chrX 47651895 47861422 1.45 +chrX 153861611 153862276 1.45 +chrY 2845480 3017508 1.45 +chr1 190332681 190333427 1.46 +chr2 134654316 134837314 1.46 +chr2 169789426 169953565 1.46 +chr3 31634839 31812066 1.46 +chr3 193863511 194023814 1.46 +chr4 99887462 100074907 1.46 +chr4 156624370 156778344 1.46 +chr5 73126031 73314954 1.46 +chr5 143298228 143480824 1.46 +chr5 145152023 145152440 1.46 +chr5 154417750 154418252 1.46 +chr6 73094225 73275800 1.46 +chr6 76566432 76685186 1.46 +chr6 97092117 97184863 1.46 +chr7 140977724 141092826 1.46 +chr8 5805153 6001336 1.46 +chr8 62411200 62572729 1.46 +chr9 73274833 73425564 1.46 +chr9 89446315 89614800 1.46 +chr10 38601694 38812575 1.46 +chr10 46999181 47159666 1.46 +chr10 131816154 131982049 1.46 +chr12 10845028 11018640 1.46 +chr12 62854244 62854997 1.46 +chr14 48879652 49050953 1.46 +chr14 100856556 101045895 1.46 +chr15 55906011 56096416 1.46 +chr16 8777563 8958332 1.46 +chr16 8957713 8958371 1.46 +chr18 17277421 17277775 1.46 +chr18 30699517 30859564 1.46 +chr20 10398757 10582167 1.46 +chrX 49444589 49644597 1.46 +chrY 7639125 7808753 1.46 +chr1 50594589 50802780 1.47 +chr1 63195526 63374556 1.47 +chr2 198360294 198526020 1.47 +chr3 32650193 32650799 1.47 +chr3 69383525 69541168 1.47 +chr3 170830820 170980842 1.47 +chr4 48524316 48683528 1.47 +chr6 126458972 126630444 1.47 +chr6 145034633 145199352 1.47 +chr6 168034078 168121846 1.47 +chr7 55009903 55010206 1.47 +chr7 103922036 104084401 1.47 +chr8 477653 658324 1.47 +chr9 86180561 86337441 1.47 +chr9 98020525 98190144 1.47 +chr10 8219578 8346526 1.47 +chr10 45156434 45157151 1.47 +chr10 100941261 101161313 1.47 +chr10 133629580 133778451 1.47 +chr11 14098699 14099413 1.47 +chr12 106899831 107062271 1.47 +chr12 117108431 117263859 1.47 +chr13 75289525 75439997 1.47 +chr13 94506903 94507480 1.47 +chr15 46837058 47011154 1.47 +chr15 53411855 53412638 1.47 +chr17 30523581 30685925 1.47 +chr18 9999822 10203371 1.47 +chr22 47740384 47838754 1.47 +chrX 64514128 64626801 1.47 +chr1 7641550 7843532 1.48 +chr1 46884600 47041895 1.48 +chr1 240002379 240203522 1.48 +chr2 70877489 70877986 1.48 +chr2 105850251 106014094 1.48 +chr2 151825968 151986544 1.48 +chr2 207687330 207861345 1.48 +chr3 8869825 9037105 1.48 +chr3 39667080 39836464 1.48 +chr3 115539059 115697740 1.48 +chr4 69694804 69912758 1.48 +chr4 78196278 78342827 1.48 +chr4 144367999 144533208 1.48 +chr4 144368003 144533204 1.48 +chr5 17110139 17284381 1.48 +chr5 70179512 70309338 1.48 +chr6 21512035 21698557 1.48 +chr6 56747408 56926686 1.48 +chr7 56639458 56803076 1.48 +chr7 97314295 97314786 1.48 +chr7 157549662 157756716 1.48 +chr9 93170720 93341568 1.48 +chr10 78781413 78996385 1.48 +chr10 85567652 85747565 1.48 +chr10 93738544 93911873 1.48 +chr12 45862358 46054280 1.48 +chr13 97268163 97467144 1.48 +chr15 46296351 46451066 1.48 +chr16 5440772 5644276 1.48 +chr18 46732299 46888453 1.48 +chr19 51083971 51239073 1.48 +chr21 32849426 33019513 1.48 +chrX 14761611 14921290 1.48 +chrX 37553903 37716432 1.48 +chrX 57816335 57960019 1.48 +chrX 100689549 100819590 1.48 +chrX 122218340 122344745 1.48 +chr1 87448603 87550379 1.49 +chr1 90457836 90458553 1.49 +chr1 173088739 173150600 1.49 +chr1 211480446 211481236 1.49 +chr1 219213887 219395917 1.49 +chr2 33026997 33209840 1.49 +chr2 78607472 78608236 1.49 +chr2 158164777 158343977 1.49 +chr2 234552685 234701715 1.49 +chr3 51558739 51559061 1.49 +chr3 112743047 112939558 1.49 +chr3 134620114 134771759 1.49 +chr4 106334083 106509296 1.49 +chr5 9436026 9606181 1.49 +chr5 10925654 10926306 1.49 +chr5 54562705 54764085 1.49 +chr6 170373241 170509779 1.49 +chr7 32275005 32459557 1.49 +chr7 107472400 107473057 1.49 +chr7 116327910 116481783 1.49 +chr9 4911574 5121406 1.49 +chr9 92185916 92362290 1.49 +chr9 107184004 107356920 1.49 +chr9 116607379 116766078 1.49 +chr11 22391987 22575753 1.49 +chr11 58901935 59116427 1.49 +chr11 93041021 93189057 1.49 +chr11 115593861 115757272 1.49 +chr12 9026914 9190867 1.49 +chr12 66740902 66931728 1.49 +chr13 31067305 31240545 1.49 +chr14 65027747 65175760 1.49 +chr14 65655482 65825533 1.49 +chr15 54901274 55123176 1.49 +chr16 26595131 26757807 1.49 +chr16 45067244 45231075 1.49 +chr17 5165932 5166614 1.49 +chr17 6065412 6217707 1.49 +chr17 20112029 20230301 1.49 +chr17 57872126 58038015 1.49 +chr18 8795684 8973445 1.49 +chr19 60914385 61088444 1.49 +chrX 18274436 18453317 1.49 +chr1 84728063 84892898 1.5 +chr1 163762157 163969574 1.5 +chr1 173739041 173886092 1.5 +chr2 44273710 44442507 1.5 +chr2 68007238 68163121 1.5 +chr2 195826912 195994198 1.5 +chr3 72455321 72633462 1.5 +chr3 106787070 106966498 1.5 +chr3 121148320 121326513 1.5 +chr5 62010355 62191843 1.5 +chr5 64142336 64300795 1.5 +chr5 73817311 73818090 1.5 +chr5 74847814 74970806 1.5 +chr5 79084142 79219538 1.5 +chr5 106747796 106920923 1.5 +chr5 108016191 108180023 1.5 +chr6 38990350 39129181 1.5 +chr6 86034671 86222195 1.5 +chr6 117034043 117169404 1.5 +chr7 157306039 157518326 1.5 +chr8 26206462 26412209 1.5 +chr9 3533199 3696631 1.5 +chr10 10830787 11020034 1.5 +chr10 97612977 97780354 1.5 +chr11 78034362 78206791 1.5 +chr12 49019643 49198741 1.5 +chr12 116586716 116748345 1.5 +chr12 129169567 129337248 1.5 +chr13 44121309 44301217 1.5 +chr15 32893109 33055196 1.5 +chr15 58181440 58324747 1.5 +chr17 69446939 69639765 1.5 +chr18 957589 958333 1.5 +chr18 41216566 41408713 1.5 +chr19 57561867 57749886 1.5 +chrX 106921602 107049634 1.5 +chrX 134430199 134632455 1.5 +chr1 146151766 146342686 1.51 +chr1 211426248 211601419 1.51 +chr2 39007277 39187672 1.51 +chr2 101278789 101279455 1.51 +chr2 127089207 127253875 1.51 +chr2 170471119 170690250 1.51 +chr2 200708454 200708868 1.51 +chr2 208715036 208876525 1.51 +chr2 222855303 223012639 1.51 +chr3 4492889 4493650 1.51 +chr3 154238282 154238738 1.51 +chr4 106900834 107064924 1.51 +chr4 184365850 184561840 1.51 +chr5 137785372 137785868 1.51 +chr5 159195225 159278790 1.51 +chr6 2316533 2413083 1.51 +chr6 15432597 15630682 1.51 +chr6 27152460 27241417 1.51 +chr6 45777376 45778135 1.51 +chr7 17756921 17931177 1.51 +chr7 55196125 55347935 1.51 +chr7 86906212 87054355 1.51 +chr7 133858782 134022392 1.51 +chr8 48686840 48844731 1.51 +chr8 59452746 59619686 1.51 +chr8 81493448 81648841 1.51 +chr8 104441333 104600167 1.51 +chr10 45425501 45633310 1.51 +chr11 2061361 2140325 1.51 +chr11 6747383 6920916 1.51 +chr11 95569628 95712661 1.51 +chr12 32552977 32729939 1.51 +chr13 23922512 24103118 1.51 +chr13 42155420 42301191 1.51 +chr15 31802458 31975417 1.51 +chr15 34700420 34860371 1.51 +chr16 22715683 22893642 1.51 +chr16 49618230 49794206 1.51 +chr18 45025819 45187979 1.51 +chr19 58164197 58336597 1.51 +chr20 47383084 47538301 1.51 +chrX 129672438 129773610 1.51 +chr1 77776731 77944517 1.52 +chr2 143499679 143667001 1.52 +chr2 143499703 143666971 1.52 +chr2 213160973 213347177 1.52 +chr2 216268805 216402525 1.52 +chr3 71622997 71816463 1.52 +chr3 121091572 121205097 1.52 +chr3 127928374 128108559 1.52 +chr3 135843691 136012579 1.52 +chr3 153771209 153915208 1.52 +chr5 34929543 35043272 1.52 +chr5 73872906 73873453 1.52 +chr5 86340653 86503917 1.52 +chr5 94527791 94663165 1.52 +chr5 124179322 124350943 1.52 +chr5 175139770 175266330 1.52 +chr6 110784447 110785221 1.52 +chr6 111684690 111819918 1.52 +chr6 137133725 137301607 1.52 +chr7 38185293 38185927 1.52 +chr7 45250029 45415202 1.52 +chr7 140911725 140979677 1.52 +chr8 124550520 124718428 1.52 +chr8 134125496 134255043 1.52 +chr9 5993718 6146499 1.52 +chr9 95248571 95419405 1.52 +chr10 14321741 14514319 1.52 +chr10 17006984 17194159 1.52 +chr10 25141002 25306820 1.52 +chr10 75725495 75896292 1.52 +chr11 531283 635941 1.52 +chr12 44739504 44903816 1.52 +chr13 27414257 27414749 1.52 +chr13 110508381 110681700 1.52 +chr14 30158279 30325251 1.52 +chr14 51766997 51964741 1.52 +chr14 66697392 66870415 1.52 +chr15 91550020 91714417 1.52 +chr16 17137869 17316758 1.52 +chr16 51466052 51670097 1.52 +chr16 81121446 81279554 1.52 +chr17 9466335 9611536 1.52 +chr17 15321328 15510169 1.52 +chr17 54149948 54280512 1.52 +chr19 42852412 43004473 1.52 +chrX 16028655 16242639 1.52 +chr1 34876929 35068982 1.53 +chr1 45348865 45523040 1.53 +chr1 92289815 92432460 1.53 +chr1 112311574 112481086 1.53 +chr1 117224641 117407078 1.53 +chr1 245125396 245280368 1.53 +chr2 157052263 157250015 1.53 +chr2 217224033 217224816 1.53 +chr3 133822599 133959231 1.53 +chr3 147710163 147710635 1.53 +chr4 76536770 76733068 1.53 +chr6 17735600 17880829 1.53 +chr6 112484860 112485640 1.53 +chr6 129664388 129861059 1.53 +chr6 150539782 150646794 1.53 +chr7 21588275 21784320 1.53 +chr7 23647193 23835807 1.53 +chr7 24489649 24659178 1.53 +chr8 39836613 39985589 1.53 +chr10 79687959 79844996 1.53 +chr10 120359649 120558865 1.53 +chr11 32892553 33037781 1.53 +chr12 101677282 101678070 1.53 +chr15 20363717 20542365 1.53 +chr18 70753437 70931323 1.53 +chr19 49045897 49206630 1.53 +chrX 45526480 45690299 1.53 +chr1 70717489 70814713 1.54 +chr1 87045853 87046483 1.54 +chr1 119501411 119708536 1.54 +chr1 165358469 165523632 1.54 +chr1 242491517 242647813 1.54 +chr2 36843825 37027743 1.54 +chr3 178148594 178149349 1.54 +chr4 4175379 4366937 1.54 +chr4 54045893 54204756 1.54 +chr5 95842138 96007440 1.54 +chr6 134784559 134979508 1.54 +chr6 143442949 143622404 1.54 +chr7 49785150 49947692 1.54 +chr8 95335790 95508534 1.54 +chr9 2136364 2296360 1.54 +chr10 31849338 32041147 1.54 +chr10 43864787 44024290 1.54 +chr10 63211719 63382032 1.54 +chr10 121490551 121670090 1.54 +chr11 18095206 18291271 1.54 +chr12 30740646 30939600 1.54 +chr14 93946930 93947549 1.54 +chr16 13833316 13983107 1.54 +chr17 2312031 2492162 1.54 +chr18 22104629 22273853 1.54 +chr18 32335236 32502050 1.54 +chr18 55962809 56151527 1.54 +chr20 61511174 61703926 1.54 +chr21 38078283 38078909 1.54 +chr22 26497322 26722737 1.54 +chr22 44414990 44543853 1.54 +chrX 71369082 71564002 1.54 +chrX 109597530 109598132 1.54 +chr1 66677291 66805722 1.55 +chr1 101075385 101207106 1.55 +chr1 116580533 116707521 1.55 +chr2 45253782 45449719 1.55 +chr2 68860263 69024185 1.55 +chr2 68860398 69024204 1.55 +chr2 152428325 152613810 1.55 +chr2 173995308 174174745 1.55 +chr2 190280619 190450126 1.55 +chr2 202418564 202419200 1.55 +chr3 99856407 100037503 1.55 +chr3 184141428 184305417 1.55 +chr5 170996378 171159953 1.55 +chr5 170996460 171159864 1.55 +chr8 48736329 48914366 1.55 +chr8 66009709 66192073 1.55 +chr9 74281674 74441354 1.55 +chr9 123651685 123824659 1.55 +chr10 48967298 49121505 1.55 +chr10 52151517 52328336 1.55 +chr10 103281369 103282021 1.55 +chr10 126605954 126760588 1.55 +chr11 2261639 2430734 1.55 +chr11 44879168 45046134 1.55 +chr11 68072319 68278585 1.55 +chr11 122124382 122299430 1.55 +chr12 14521944 14697706 1.55 +chr13 32790732 32947408 1.55 +chr15 70693934 70907539 1.55 +chr15 92324496 92491964 1.55 +chr17 43957711 44125703 1.55 +chr18 17227954 17228530 1.55 +chr18 52656262 52867700 1.55 +chr19 12006544 12159478 1.55 +chr20 36675397 36843266 1.55 +chrX 10267319 10437613 1.55 +chr1 42987601 43152105 1.56 +chr1 44062032 44062761 1.56 +chr1 196605835 196750596 1.56 +chr2 8025181 8218125 1.56 +chr2 24702643 24890535 1.56 +chr2 108344392 108345037 1.56 +chr3 42599838 42784967 1.56 +chr3 153502270 153697655 1.56 +chr3 153502331 153697658 1.56 +chr4 37192091 37353152 1.56 +chr4 146929902 147089763 1.56 +chr5 112488884 112695479 1.56 +chr5 157384965 157573351 1.56 +chr6 75947919 76073439 1.56 +chr7 21173940 21341345 1.56 +chr7 130078078 130270796 1.56 +chr8 8029024 8179923 1.56 +chr8 30816370 30990446 1.56 +chr8 90947388 91066955 1.56 +chr8 130562466 130702085 1.56 +chr9 15219945 15401987 1.56 +chr9 94281900 94449618 1.56 +chr9 124769226 124954691 1.56 +chr9 137112108 137333436 1.56 +chr10 13058510 13254677 1.56 +chr10 23123798 23319758 1.56 +chr10 126007431 126190348 1.56 +chr11 70596609 70789798 1.56 +chr12 3099629 3265088 1.56 +chr12 7918143 7919008 1.56 +chr12 7918177 7918979 1.56 +chr12 10122402 10291075 1.56 +chr13 22887527 23065746 1.56 +chr13 47897121 47897916 1.56 +chr14 53262095 53262810 1.56 +chr14 75653348 75833248 1.56 +chr14 75653368 75833225 1.56 +chr15 43413012 43613760 1.56 +chr15 48942176 49085328 1.56 +chr17 25071274 25261602 1.56 +chr18 9449205 9633157 1.56 +chr18 27366553 27569454 1.56 +chr22 42473589 42651043 1.56 +chrX 100064566 100164684 1.56 +chrY 13952205 14124161 1.56 +chr2 43518282 43698576 1.57 +chr2 71104398 71285149 1.57 +chr2 161596505 161786674 1.57 +chr2 239981214 240142437 1.57 +chr3 23574974 23575716 1.57 +chr3 151508467 151678827 1.57 +chr3 184802897 185002162 1.57 +chr6 52995970 53088442 1.57 +chr6 167790712 167979638 1.57 +chr7 137919306 138093868 1.57 +chr9 20172465 20351121 1.57 +chr10 94734535 94907303 1.57 +chr10 112963144 113136917 1.57 +chr11 94000385 94161720 1.57 +chr11 110352104 110510107 1.57 +chr11 129326505 129514541 1.57 +chr11 129513858 129514567 1.57 +chr12 38991144 39141476 1.57 +chr12 129648137 129839417 1.57 +chr13 31703968 31870598 1.57 +chr13 32842471 33025319 1.57 +chr13 44939386 45124346 1.57 +chr14 96318570 96319342 1.57 +chr14 100296015 100460986 1.57 +chr15 49615114 49801299 1.57 +chr16 46446494 46605357 1.57 +chr17 56657760 56847011 1.57 +chr18 11684280 11857259 1.57 +chr18 42350383 42350954 1.57 +chr18 46462730 46633371 1.57 +chr19 9041365 9197603 1.57 +chr20 1128792 1320966 1.57 +chr20 13564713 13774030 1.57 +chr1 37166110 37304834 1.58 +chr1 85106641 85107391 1.58 +chr1 113304939 113473675 1.58 +chr1 167621290 167722803 1.58 +chr2 27426604 27622433 1.58 +chr2 52630527 52788518 1.58 +chr2 109111217 109319695 1.58 +chr2 203317371 203318141 1.58 +chr3 9054010 9236123 1.58 +chr3 12590855 12735917 1.58 +chr3 179511139 179653380 1.58 +chr3 179511200 179653300 1.58 +chr4 152963195 153151424 1.58 +chr5 6515876 6708632 1.58 +chr5 58128952 58280997 1.58 +chr5 65059220 65239073 1.58 +chr5 179870172 180060082 1.58 +chr6 14536149 14673791 1.58 +chr6 52294378 52456670 1.58 +chr6 108026474 108214952 1.58 +chr8 10795780 10796421 1.58 +chr8 80726279 80893793 1.58 +chr9 96434170 96615981 1.58 +chr12 95366392 95367124 1.58 +chr13 28837843 29008462 1.58 +chr13 39497391 39498139 1.58 +chr14 20383517 20541450 1.58 +chr15 81186971 81351624 1.58 +chr17 36236729 36373682 1.58 +chr19 59041063 59235473 1.58 +chrX 12582350 12582807 1.58 +chrX 77111573 77195698 1.58 +chrX 108665629 108804379 1.58 +chrX 119444059 119591078 1.58 +chr1 29538364 29679865 1.59 +chr1 53077428 53193598 1.59 +chr1 181839038 182030843 1.59 +chr2 60501800 60696137 1.59 +chr2 86130524 86330997 1.59 +chr2 168899606 169089871 1.59 +chr2 172117570 172284258 1.59 +chr2 230386971 230387771 1.59 +chr3 192498455 192698313 1.59 +chr4 113577898 113578539 1.59 +chr5 72794439 72920149 1.59 +chr6 3292077 3471147 1.59 +chr6 10551747 10751130 1.59 +chr6 151442675 151561999 1.59 +chr9 97394031 97558497 1.59 +chr10 111497648 111663117 1.59 +chr11 34935748 34935995 1.59 +chr12 25269925 25447810 1.59 +chr12 94119164 94318610 1.59 +chr12 108178811 108360902 1.59 +chr13 48903929 49068849 1.59 +chr15 75185326 75348634 1.59 +chr17 3241556 3398985 1.59 +chr18 46310160 46473840 1.59 +chr18 58572418 58756466 1.59 +chr19 9688758 9689294 1.59 +chr20 45970037 46146093 1.59 +chr22 24560716 24734198 1.59 +chr1 9083937 9084661 1.6 +chr1 20428363 20560773 1.6 +chr1 58653712 58843461 1.6 +chr1 243222295 243431391 1.6 +chr2 223180236 223349542 1.6 +chr2 238922713 239091229 1.6 +chr3 14886339 14886921 1.6 +chr3 150340151 150506775 1.6 +chr4 71879366 72033748 1.6 +chr4 84626781 84801949 1.6 +chr5 118271452 118444329 1.6 +chr7 50442692 50617642 1.6 +chr7 139186224 139329952 1.6 +chr7 154264109 154414449 1.6 +chr8 57211535 57353615 1.6 +chr9 4819733 4991796 1.6 +chr9 101231164 101410218 1.6 +chr10 126760603 126954956 1.6 +chr11 8144704 8368299 1.6 +chr11 8634965 8795687 1.6 +chr11 124585420 124761526 1.6 +chr12 15496644 15658323 1.6 +chr13 19136604 19137297 1.6 +chr15 83685716 83883618 1.6 +chr16 919727 1097284 1.6 +chr17 10055064 10253595 1.6 +chr18 54867340 55049496 1.6 +chr18 54867345 55049546 1.6 +chr20 49489010 49588240 1.6 +chr21 29627040 29804741 1.6 +chrX 13814937 14015038 1.6 +chrX 19155814 19156191 1.6 +chrX 78252510 78419277 1.6 +chrX 153783896 153962641 1.6 +chr1 23210578 23311475 1.61 +chr1 67239552 67370740 1.61 +chr1 221890096 221891232 1.61 +chr2 178079912 178252288 1.61 +chr3 5027953 5180913 1.61 +chr3 15780432 15940568 1.61 +chr3 54007394 54188434 1.61 +chr3 124853438 125034577 1.61 +chr3 143078415 143237513 1.61 +chr3 144154881 144312253 1.61 +chr3 158164991 158323275 1.61 +chr4 47677803 47874056 1.61 +chr5 78198048 78198544 1.61 +chr5 79172773 79351477 1.61 +chr5 115966010 116138288 1.61 +chr6 5028697 5217232 1.61 +chr6 25482580 25677388 1.61 +chr6 26302873 26459898 1.61 +chr6 39977178 40078522 1.61 +chr6 144431624 144627356 1.61 +chr8 99215537 99366374 1.61 +chr9 99583829 99744600 1.61 +chr9 100604522 100754437 1.61 +chr9 114501030 114687327 1.61 +chr10 105830098 106023281 1.61 +chr12 5926585 5926958 1.61 +chr12 25394087 25557266 1.61 +chr12 94481227 94629374 1.61 +chr13 45700578 45869746 1.61 +chr14 69594037 69800258 1.61 +chr15 28255532 28543404 1.61 +chr15 67981331 68181027 1.61 +chr18 41984362 41984869 1.61 +chr19 56315908 56503568 1.61 +chr20 54786438 54948801 1.61 +chr21 25481427 25638118 1.61 +chr1 3214534 3355042 1.62 +chr2 30665578 30833166 1.62 +chr2 62595499 62742752 1.62 +chr2 171080964 171261141 1.62 +chr3 17809328 17960713 1.62 +chr3 142172454 142173036 1.62 +chr3 173181145 173347945 1.62 +chr3 173688016 173855765 1.62 +chr5 88149138 88309856 1.62 +chr5 169138790 169139510 1.62 +chr6 7427280 7575675 1.62 +chr8 126798041 126798844 1.62 +chr9 99080853 99246269 1.62 +chr9 100883044 101058940 1.62 +chr11 10289439 10454001 1.62 +chr11 18541571 18742470 1.62 +chr11 73706065 73867546 1.62 +chr11 101724679 101939102 1.62 +chr11 102010679 102011116 1.62 +chr11 124487806 124646248 1.62 +chr14 91389787 91561645 1.62 +chr17 28282582 28423748 1.62 +chr17 62106614 62246742 1.62 +chr18 53397307 53398022 1.62 +chrX 40755147 40944392 1.62 +chrX 70619662 70620234 1.62 +chrX 117482391 117604994 1.62 +chr1 110897345 111090422 1.63 +chr1 203522749 203523529 1.63 +chr2 47693987 47694786 1.63 +chr3 36866879 37036085 1.63 +chr4 7937465 8151463 1.63 +chr6 37889307 38009607 1.63 +chr6 130232415 130405154 1.63 +chr6 155289807 155290365 1.63 +chr7 19997089 20186026 1.63 +chr7 134684519 134842787 1.63 +chr9 19310518 19506748 1.63 +chr10 73834334 73834924 1.63 +chr10 74954877 74955199 1.63 +chr11 3573936 3757991 1.63 +chr11 9666315 9667022 1.63 +chr11 108226260 108393306 1.63 +chr12 51027859 51174187 1.63 +chr13 41262233 41262987 1.63 +chr14 34839207 35022652 1.63 +chr15 64985158 65179621 1.63 +chr16 4702956 4851459 1.63 +chr17 51993140 52172780 1.63 +chr19 5713441 5893445 1.63 +chr20 55914021 56121669 1.63 +chr22 30835441 30932660 1.63 +chrX 24176952 24341732 1.63 +chr1 93768326 93910259 1.64 +chr1 172077256 172222546 1.64 +chr1 180226264 180383894 1.64 +chr2 73670508 73888473 1.64 +chr2 98011957 98199214 1.64 +chr2 191161999 191354926 1.64 +chr3 10613350 10788431 1.64 +chr5 77156061 77320968 1.64 +chr6 32404070 32498505 1.64 +chr7 36168129 36337418 1.64 +chr7 76963834 77117182 1.64 +chr8 61676214 61851180 1.64 +chr8 141395906 141551776 1.64 +chr9 96375866 96551155 1.64 +chr9 111106642 111321237 1.64 +chr9 134611262 134820433 1.64 +chr10 101701720 101872241 1.64 +chr10 102895114 103074769 1.64 +chr11 69162501 69323924 1.64 +chr12 26494860 26676684 1.64 +chr12 56286203 56497599 1.64 +chr12 127784893 127938159 1.64 +chr13 76523008 76666874 1.64 +chr15 96860070 97061802 1.64 +chr15 97225257 97225937 1.64 +chr15 98388085 98574555 1.64 +chr16 12336699 12522785 1.64 +chr16 15983938 16191749 1.64 +chr16 48210521 48394084 1.64 +chr18 49786579 49971825 1.64 +chr20 2441363 2600552 1.64 +chr20 4636907 4766293 1.64 +chr20 20143748 20240111 1.64 +chrX 2789811 2790584 1.64 +chrX 46494737 46616168 1.64 +chr1 101220701 101413217 1.65 +chr1 157953509 158150295 1.65 +chr2 70374526 70514351 1.65 +chr4 38175739 38357481 1.65 +chr4 38356729 38357541 1.65 +chr4 148951122 148951822 1.65 +chr5 67498164 67677068 1.65 +chr5 112074297 112242499 1.65 +chr6 106038433 106153492 1.65 +chr7 101175494 101390682 1.65 +chr7 155193735 155348314 1.65 +chr8 21698622 21872574 1.65 +chr8 27277284 27462575 1.65 +chr8 102544799 102710032 1.65 +chr9 128256298 128420866 1.65 +chr10 70288208 70459535 1.65 +chr10 103204733 103388522 1.65 +chr12 91204898 91367961 1.65 +chr12 101481982 101482369 1.65 +chr13 19738155 19920905 1.65 +chr13 99118130 99118732 1.65 +chr15 41409192 41591912 1.65 +chr15 42593672 42756125 1.65 +chr15 57657503 57658171 1.65 +chr15 87338954 87527174 1.65 +chr16 10432694 10596527 1.65 +chr16 24637564 24856451 1.65 +chr17 33794727 33977073 1.65 +chr17 58063444 58237753 1.65 +chr17 68199396 68366917 1.65 +chr17 72107950 72271167 1.65 +chr20 56817450 56973377 1.65 +chr21 39567363 39702870 1.65 +chrX 2466238 2622009 1.65 +chrX 122792466 122990233 1.65 +chrY 2466238 2622009 1.65 +chr1 114409026 114555080 1.66 +chr2 42333837 42518734 1.66 +chr2 61421368 61422149 1.66 +chr2 95675764 95676554 1.66 +chr2 238251721 238252119 1.66 +chr3 45989826 46150224 1.66 +chr3 153173960 153322734 1.66 +chr5 42897645 42898147 1.66 +chr5 61659616 61832898 1.66 +chr5 67322915 67501695 1.66 +chr5 136892127 137064639 1.66 +chr5 157180105 157349297 1.66 +chr6 108524960 108647021 1.66 +chr7 27976454 28166805 1.66 +chr7 43425453 43594825 1.66 +chr8 67179019 67344055 1.66 +chr8 135577514 135739934 1.66 +chr10 26797315 26941968 1.66 +chr10 69441097 69601751 1.66 +chr10 90596444 90783689 1.66 +chr10 91315272 91463649 1.66 +chr12 127840870 127841450 1.66 +chr13 26843897 27009985 1.66 +chr13 51243111 51243933 1.66 +chr14 77328585 77513223 1.66 +chr17 42087499 42268621 1.66 +chr19 53269630 53431701 1.66 +chr20 3475997 3580840 1.66 +chr20 51561551 51690342 1.66 +chr21 38601021 38740380 1.66 +chr1 156056126 156056893 1.67 +chr1 222762761 222926484 1.67 +chr2 54748826 54918968 1.67 +chr2 175041508 175231393 1.67 +chr3 12420266 12590814 1.67 +chr3 113764691 113980300 1.67 +chr3 196585074 196768555 1.67 +chr6 6119858 6280511 1.67 +chr7 37407807 37597713 1.67 +chr7 76490702 76687246 1.67 +chr7 129214418 129214818 1.67 +chr8 29818492 30006914 1.67 +chr8 125633463 125840510 1.67 +chr9 131818912 132006030 1.67 +chr10 63780499 63955335 1.67 +chr10 99620303 99781492 1.67 +chr11 47289757 47477534 1.67 +chr11 85137550 85342098 1.67 +chr12 54839394 55007887 1.67 +chr13 47794572 47964053 1.67 +chr14 54376859 54570373 1.67 +chr15 40544105 40544306 1.67 +chr15 41680206 41851733 1.67 +chr16 70269439 70453945 1.67 +chr17 16526746 16718786 1.67 +chr17 19211694 19360796 1.67 +chr17 42875381 43043105 1.67 +chr17 57301021 57473353 1.67 +chr1 200974587 201176406 1.68 +chr1 233871784 234056082 1.68 +chr2 23670212 23881957 1.68 +chr2 23670217 23881959 1.68 +chr2 28412635 28572084 1.68 +chr2 178966383 179139203 1.68 +chr3 49222599 49393280 1.68 +chr3 123838303 124037428 1.68 +chr3 195537808 195699146 1.68 +chr5 171714383 171955264 1.68 +chr6 34918606 35051428 1.68 +chr6 88286044 88456239 1.68 +chr6 135475561 135663726 1.68 +chr6 149545624 149673890 1.68 +chr7 7947777 8126039 1.68 +chr7 105583898 105763396 1.68 +chr8 101279091 101431725 1.68 +chr11 33907530 34049097 1.68 +chr11 116204416 116368601 1.68 +chr12 102490337 102647688 1.68 +chr12 115487351 115487968 1.68 +chr12 131855464 132036472 1.68 +chr14 63342212 63500585 1.68 +chr14 99081660 99247736 1.68 +chr16 68164927 68165567 1.68 +chr16 70619026 70788093 1.68 +chr18 58408938 58578499 1.68 +chr20 34168760 34346661 1.68 +chr20 35834739 35931146 1.68 +chr20 39296098 39390691 1.68 +chr20 54455167 54566131 1.68 +chrX 12952343 13058902 1.68 +chrX 41108001 41241482 1.68 +chrX 54079685 54157798 1.68 +chr1 12351219 12462984 1.69 +chr1 16660236 16806953 1.69 +chr1 152333539 152334265 1.69 +chr1 177942471 178115476 1.69 +chr1 234121480 234285489 1.69 +chr2 37650188 37838486 1.69 +chr2 201556033 201729254 1.69 +chr2 213713161 213874167 1.69 +chr3 4490514 4652956 1.69 +chr3 47858146 48047371 1.69 +chr3 102991643 103144247 1.69 +chr3 109236225 109385450 1.69 +chr3 153144934 153314608 1.69 +chr3 170975630 171133894 1.69 +chr3 186612234 186768120 1.69 +chr5 142505106 142742827 1.69 +chr5 148642237 148846264 1.69 +chr6 107020676 107112028 1.69 +chr9 100705049 100705492 1.69 +chr9 135531598 135710682 1.69 +chr10 14952575 15140784 1.69 +chr10 89694476 89694968 1.69 +chr11 3854187 4005769 1.69 +chr12 100590406 100752075 1.69 +chr14 103217347 103382885 1.69 +chr15 39583755 39584254 1.69 +chr16 12001822 12176016 1.69 +chr16 29408714 29609851 1.69 +chr18 2479744 2665791 1.69 +chr20 24936530 25109994 1.69 +chrX 9560995 9684171 1.69 +chrX 135361340 135484299 1.69 +chr1 44428131 44608760 1.7 +chr1 51656028 51797618 1.7 +chr2 26821205 26990177 1.7 +chr2 45893818 46085030 1.7 +chr2 65586797 65745895 1.7 +chr2 197681931 197850356 1.7 +chr3 103202967 103378300 1.7 +chr3 114747418 114895013 1.7 +chr3 172293476 172503074 1.7 +chr4 10207878 10373914 1.7 +chr4 37870461 37871030 1.7 +chr5 141852268 141998278 1.7 +chr6 137962604 138142635 1.7 +chr7 30381583 30382165 1.7 +chr9 21157685 21158452 1.7 +chr9 130501524 130668171 1.7 +chr10 104652460 104813472 1.7 +chr11 1585438 1785273 1.7 +chr13 102258686 102424760 1.7 +chr14 68520131 68700019 1.7 +chr15 70142508 70313623 1.7 +chr15 80867047 81024206 1.7 +chr16 15411955 15573494 1.7 +chr16 67318530 67478802 1.7 +chr17 34978799 34979103 1.7 +chr19 51665825 51835148 1.7 +chr1 53509194 53688167 1.71 +chr1 53802593 53986331 1.71 +chr1 209767120 209981362 1.71 +chr2 96435158 96597950 1.71 +chr2 96435213 96597933 1.71 +chr2 237040133 237220803 1.71 +chr3 52658450 52743025 1.71 +chr5 131817042 131977001 1.71 +chr6 6217514 6382300 1.71 +chr6 160224184 160354066 1.71 +chr7 65934746 66092390 1.71 +chr7 128410279 128568571 1.71 +chr8 11802619 11803057 1.71 +chr8 23107287 23286627 1.71 +chr8 95978837 96177980 1.71 +chr9 91887431 91888260 1.71 +chr10 1206029 1370732 1.71 +chr10 30925759 30926104 1.71 +chr10 89597006 89798429 1.71 +chr11 119363929 119364258 1.71 +chr13 112739429 112901590 1.71 +chr15 50535080 50684151 1.71 +chr15 82907017 82907548 1.71 +chr17 32189512 32371445 1.71 +chr17 33321866 33322229 1.71 +chr20 31582329 31675113 1.71 +chrX 118438914 118566974 1.71 +chrX 129036286 129145716 1.71 +chr1 10075630 10169954 1.72 +chr1 112837726 112960659 1.72 +chr1 160195323 160195745 1.72 +chr1 166251815 166352458 1.72 +chr1 227623770 227744106 1.72 +chr2 196538333 196753496 1.72 +chr3 123486790 123658097 1.72 +chr5 10644878 10824706 1.72 +chr5 55546666 55547446 1.72 +chr5 138219217 138414953 1.72 +chr6 88811053 88923153 1.72 +chr9 115619446 115806020 1.72 +chr11 85720098 85720574 1.72 +chr12 121815155 121982522 1.72 +chr12 122658602 122876941 1.72 +chr17 23307568 23308267 1.72 +chr17 76183573 76354819 1.72 +chr20 17799943 17961951 1.72 +chr20 54471430 54472070 1.72 +chr1 15425500 15560568 1.73 +chr1 219787706 219961446 1.73 +chr2 9588319 9772865 1.73 +chr2 217062057 217226494 1.73 +chr3 128599495 128752041 1.73 +chr5 149219507 149349990 1.73 +chr6 12406236 12579760 1.73 +chr7 28459809 28603601 1.73 +chr9 70318675 70488655 1.73 +chr10 90435254 90615085 1.73 +chr11 47864340 48047114 1.73 +chr11 76074455 76232396 1.73 +chr12 52417126 52574777 1.73 +chr12 93046177 93206723 1.73 +chr12 112653797 112826527 1.73 +chr14 64199412 64200177 1.73 +chr17 41439719 41565972 1.73 +chr17 53510745 53677092 1.73 +chr18 72266630 72448118 1.73 +chr19 56161423 56314474 1.73 +chr19 63516095 63516696 1.73 +chrX 148437108 148548633 1.73 +chr1 19127387 19266745 1.74 +chr1 24351995 24532035 1.74 +chr1 24599009 24781759 1.74 +chr1 144149973 144150623 1.74 +chr1 202748911 202933682 1.74 +chr2 46105110 46297018 1.74 +chr3 51806508 51927169 1.74 +chr3 188090387 188091023 1.74 +chr4 8153524 8313477 1.74 +chr6 160501428 160502221 1.74 +chr7 98844510 99008804 1.74 +chr7 148462610 148626409 1.74 +chr8 28927769 29094558 1.74 +chr9 111914216 112092130 1.74 +chr9 132470436 132643733 1.74 +chr11 44421785 44422195 1.74 +chr11 82426839 82581132 1.74 +chr11 111095171 111276128 1.74 +chr12 11528806 11739539 1.74 +chr13 27824701 27970943 1.74 +chr14 74588657 74589380 1.74 +chr14 95199640 95365712 1.74 +chr16 14529557 14723144 1.74 +chr17 6893949 6894703 1.74 +chr17 6894000 7063252 1.74 +chr20 29778833 29779350 1.74 +chr20 31093124 31211874 1.74 +chr22 21400636 21552718 1.74 +chr1 918164 1145847 1.75 +chr1 21904425 22097047 1.75 +chr1 39307926 39450770 1.75 +chr1 198548931 198714422 1.75 +chr3 15628045 15764879 1.75 +chr3 187299633 187451862 1.75 +chr7 6234052 6234587 1.75 +chr8 8489834 8677590 1.75 +chr9 70739219 70739964 1.75 +chr9 125452145 125649123 1.75 +chr12 858648 1084584 1.75 +chr14 72043432 72226400 1.75 +chr15 60932064 61119675 1.75 +chr16 21936647 21937453 1.75 +chr17 8408778 8574309 1.75 +chr20 32566759 32687747 1.75 +chr21 36765659 36936719 1.75 +chr1 5866184 6042798 1.76 +chr1 17140091 17356497 1.76 +chr1 109536893 109537533 1.76 +chr1 151954735 152104802 1.76 +chr1 180895642 181046126 1.76 +chr2 101950474 102136502 1.76 +chr3 58149241 58327168 1.76 +chr4 185872338 186040225 1.76 +chr6 156885777 157054875 1.76 +chr6 159404565 159586466 1.76 +chr10 6277674 6476639 1.76 +chr10 72645818 72803738 1.76 +chr11 56867267 57054678 1.76 +chr11 72378220 72573798 1.76 +chr11 75107934 75273492 1.76 +chr12 1719982 1855189 1.76 +chr12 4174840 4341675 1.76 +chr12 31916950 32086540 1.76 +chr12 92994994 93158935 1.76 +chr15 65164181 65330882 1.76 +chr16 21304276 21473433 1.76 +chr16 65152761 65333416 1.76 +chr16 69164308 69365092 1.76 +chr17 74607599 74792971 1.76 +chr19 34956752 35094150 1.76 +chr20 29939223 30102016 1.76 +chr20 46989159 47129952 1.76 +chr20 48846717 48952485 1.76 +chr1 11483207 11618991 1.77 +chr1 29481197 29601498 1.77 +chr1 46259106 46477518 1.77 +chr1 148424844 148425333 1.77 +chr1 202668576 202832483 1.77 +chr10 98421164 98525673 1.77 +chr11 75965024 76130350 1.77 +chr12 56117999 56288135 1.77 +chr12 109799653 109949314 1.77 +chr15 65872293 66060824 1.77 +chr17 54693901 54872929 1.77 +chr22 36120293 36212700 1.77 +chr1 28834716 28835372 1.78 +chr2 25697038 25870821 1.78 +chr2 60927184 61134244 1.78 +chr3 9803852 9993473 1.78 +chr4 3367127 3557717 1.78 +chr6 135533146 135718367 1.78 +chr12 3999892 4189702 1.78 +chr17 25520145 25693265 1.78 +chr17 38137289 38327610 1.78 +chr17 41095612 41096064 1.78 +chr17 52616475 52760769 1.78 +chr17 63619442 63836050 1.78 +chr20 34886009 34886445 1.78 +chr20 42799956 42800600 1.78 +chr1 36604265 36743128 1.79 +chr2 29261117 29453743 1.79 +chr2 85513681 85689354 1.79 +chr5 131642147 131731304 1.79 +chr7 25786649 25787407 1.79 +chr7 65647563 65782464 1.79 +chr9 122851372 123029736 1.79 +chr10 76881864 76882526 1.79 +chr10 82019058 82019379 1.79 +chr11 1687193 1687713 1.79 +chr11 65876904 66035373 1.79 +chr11 117022863 117194572 1.79 +chr12 124056104 124234341 1.79 +chr17 38927004 39091531 1.79 +chr19 51988000 52169534 1.79 +chr1 200418761 200596067 1.8 +chr11 68509567 68701448 1.8 +chr14 22435305 22627125 1.8 +chr15 63070265 63255108 1.8 +chr17 7438479 7599079 1.8 +chr17 27416322 27596064 1.8 +chr17 39379048 39379525 1.8 +chr20 41668572 41668909 1.8 +chr20 59894661 60016627 1.8 +chr22 29897783 30032831 1.8 +chr1 159890346 159891087 1.81 +chr2 64478283 64684358 1.81 +chr5 149407439 149494253 1.81 +chr7 71970754 71971176 1.81 +chr10 125057762 125058197 1.81 +chr11 118726259 118898358 1.81 +chr13 98801820 98995341 1.81 +chr14 67822628 67995564 1.81 +chr15 88048919 88207829 1.81 +chr15 88048967 88207890 1.81 +chr16 30954589 31190651 1.81 +chr17 35682130 35682517 1.81 +chr17 37192625 37370848 1.81 +chr17 55350495 55498032 1.81 +chr17 59626448 59627242 1.81 +chr19 6523485 6701760 1.81 +chr20 275014 424783 1.81 +chr20 52147821 52257711 1.81 +chr22 38345454 38559089 1.81 +chr22 39986642 39987174 1.81 +chr1 89836304 90021445 1.82 +chr1 151954692 152104830 1.82 +chr1 179093657 179296252 1.82 +chr1 225105730 225267337 1.82 +chr2 8605936 8781369 1.82 +chr2 111491810 111673234 1.82 +chr3 10137523 10347462 1.82 +chr5 126045881 126232819 1.82 +chr7 5704715 5845078 1.82 +chr9 127232116 127408009 1.82 +chr11 63843056 64009168 1.82 +chr12 46666796 46667275 1.82 +chr12 119399640 119534882 1.82 +chr14 74297073 74478914 1.82 +chr16 67553299 67731519 1.82 +chr17 38221350 38425990 1.82 +chr20 44219240 44398282 1.82 +chr20 47068467 47243628 1.82 +chr1 159338985 159509999 1.83 +chr1 202583864 202785074 1.83 +chr3 120926480 121091560 1.83 +chr6 41997884 42172187 1.83 +chr8 61829586 62011027 1.83 +chr10 5677116 5844781 1.83 +chr12 111697547 111800218 1.83 +chr15 56535071 56693130 1.83 +chr16 49081891 49252657 1.83 +chr17 35065379 35227093 1.83 +chr17 69779007 69974731 1.83 +chr17 72330424 72523882 1.83 +chr18 19024453 19181574 1.83 +chrX 152359276 152538530 1.83 +chrX 152359331 152538528 1.83 +chr1 10986318 11098993 1.84 +chr2 43281993 43437205 1.84 +chr2 113063927 113232323 1.84 +chr3 13474877 13656208 1.84 +chr3 125910485 126076506 1.84 +chr3 129803278 129803833 1.84 +chr5 176797689 176798343 1.84 +chr6 11482211 11482901 1.84 +chr6 42887766 42955906 1.84 +chr7 44476301 44657269 1.84 +chr7 73732805 73733598 1.84 +chr7 74971406 75153739 1.84 +chr11 34986532 35140537 1.84 +chr11 127930601 128090813 1.84 +chr15 64818125 64818855 1.84 +chr16 83357071 83531668 1.84 +chr17 45862395 46041800 1.84 +chr1 32874030 33046828 1.85 +chr3 48357048 48512499 1.85 +chr6 6647138 6805876 1.85 +chr8 38289058 38488992 1.85 +chr11 120790891 120960982 1.85 +chr13 29914797 30048599 1.85 +chr14 49608076 49608742 1.85 +chr14 61029917 61208384 1.85 +chr17 4001094 4169898 1.85 +chr17 46171561 46380473 1.85 +chr20 43889716 43975657 1.85 +chr20 45646214 45732628 1.85 +chr22 33798821 33828353 1.85 +chr5 176391379 176542031 1.86 +chr6 36906248 37077769 1.86 +chr7 1611841 1807604 1.86 +chr9 133967495 133968038 1.86 +chr11 62270871 62271625 1.86 +chr12 120268349 120440851 1.86 +chr16 4441449 4598878 1.86 +chr16 66952765 67134295 1.86 +chr18 75538799 75701174 1.86 +chr20 32907707 33049748 1.86 +chr20 60992889 61121982 1.86 +chr21 43550744 43727862 1.86 +chr1 11765728 11932249 1.87 +chr1 31946121 32129493 1.87 +chr1 38263874 38379421 1.87 +chr9 132841764 133018395 1.87 +chr10 88054888 88222653 1.87 +chr11 60851894 61061395 1.87 +chr15 38766152 38944382 1.87 +chr15 71764680 71904803 1.87 +chr19 44539203 44539916 1.87 +chr20 41804350 41804986 1.87 +chr1 32275078 32440655 1.88 +chr1 205087972 205280504 1.88 +chr3 39135103 39311642 1.88 +chr6 158244856 158440772 1.88 +chr10 97210760 97374404 1.88 +chr11 66710945 66872614 1.88 +chr12 12759639 12961302 1.88 +chr12 103550316 103714143 1.88 +chr14 23511789 23749068 1.88 +chr14 102319935 102479461 1.88 +chr16 11795525 11796320 1.88 +chr19 52914892 53095367 1.88 +chr20 33649536 33824840 1.88 +chr20 48091894 48092464 1.88 +chr2 74335462 74515970 1.89 +chr5 71659788 71823446 1.89 +chr7 1080569 1081263 1.89 +chr7 99507554 99508034 1.89 +chr7 149650854 149838701 1.89 +chr9 126127930 126290748 1.89 +chr10 49230238 49437120 1.89 +chr12 51493439 51493869 1.89 +chr12 51493494 51676901 1.89 +chr12 130834289 130834783 1.89 +chr13 113770458 113954546 1.89 +chr15 76071170 76279435 1.89 +chr15 78200185 78353829 1.89 +chr15 89307983 89308593 1.89 +chr16 79834964 80033098 1.89 +chr17 7563870 7733801 1.89 +chr19 13100938 13216789 1.89 +chr19 16712801 16899931 1.89 +chr19 51023195 51151414 1.89 +chr22 22510132 22789754 1.89 +chr1 38051102 38051746 1.9 +chr1 45524166 45524938 1.9 +chr1 226955326 227082922 1.9 +chr2 219018312 219018782 1.9 +chr2 241620162 241796109 1.9 +chr6 33467588 33615999 1.9 +chr8 128735637 128884770 1.9 +chr10 89705200 89888619 1.9 +chr11 61394968 61395556 1.9 +chr15 64628666 64838826 1.9 +chr17 7251966 7438343 1.9 +chr19 4806367 5009897 1.9 +chr1 153110698 153292792 1.91 +chr9 6566990 6567805 1.91 +chr15 63873345 64073088 1.91 +chr17 801989 1008120 1.91 +chr1 153411319 153581460 1.92 +chr3 197391879 197392198 1.92 +chr8 56945439 57129714 1.92 +chr9 113691304 113877333 1.92 +chr10 135071590 135072261 1.92 +chr11 62229957 62403825 1.92 +chr11 64564018 64751914 1.92 +chr14 94901754 95067534 1.92 +chr22 35478918 35479413 1.92 +chr14 76653370 76654077 1.93 +chr14 92565537 92566181 1.93 +chr16 30539964 30747822 1.93 +chr17 23823737 23824010 1.93 +chr19 46479944 46480344 1.93 +chr19 53951044 54181980 1.93 +chr1 109816111 109932200 1.94 +chr7 72073705 72269192 1.94 +chr10 11805252 12011792 1.94 +chr14 68409982 68576217 1.94 +chr8 103802271 103959652 1.95 +chr9 129242753 129460262 1.95 +chr16 73977120 73977825 1.95 +chr17 1705906 1882486 1.95 +chr22 28379404 28551049 1.95 +chr22 39482928 39604225 1.95 +chr4 1595392 1784503 1.96 +chr17 35754749 35920940 1.96 +chr2 10189987 10393154 1.97 +chr12 119062359 119247085 1.97 +chr16 84379908 84540021 1.97 +chr17 33964845 34251503 1.97 +chr17 71063165 71247066 1.97 +chr19 10248852 10410584 1.97 +chr19 43766631 43893238 1.97 +chr1 40830627 40958746 1.98 +chr1 154215584 154399117 1.98 +chr10 71487253 71487667 1.98 +chr16 66199799 66393264 1.98 +chr17 17338154 17521462 1.98 +chr19 49912622 50122984 1.98 +chr21 42507308 42689289 1.98 +chr6 32031967 32200774 1.99 +chr12 51745498 51903199 1.99 +chr17 78374103 78374783 1.99 +chr2 96022598 96200121 2 +chr6 43965943 44149957 2 +chr7 2777815 2778183 2 +chr12 47562010 47745122 2 +chr15 38393810 38394432 2 +chr15 72737468 72953319 2 +chr22 39890713 40012950 2 +chr22 40022423 40142026 2 +chr12 55727385 55912942 2.01 +chr12 55727416 55727833 2.01 +chr16 55369598 55559295 2.01 +chr19 10699196 10699522 2.01 +chr2 231787962 231788629 2.02 +chr22 41529087 41529734 2.02 +chr1 27575366 27652624 2.03 +chr17 43957677 44125703 2.03 +chr18 54567090 54747580 2.03 +chr22 39701633 39877788 2.03 +chr1 204651282 204822719 2.04 +chr3 49843918 50006856 2.04 +chr19 13815786 13816238 2.04 +chr19 55588771 55753067 2.04 +chr1 9135174 9264249 2.05 +chr11 63543757 63721176 2.05 +chr19 2595842 2773344 2.05 +chr1 27728323 27853587 2.06 +chr16 80148499 80307562 2.06 +chr1 27231523 27352489 2.08 +chr7 99873610 100038722 2.08 +chr16 2067723 2267343 2.08 +chr20 30526698 30684121 2.08 +chr11 46216229 46383009 2.09 +chr16 431054 431761 2.1 +chr17 17940393 18114679 2.1 +chr19 12627174 12774845 2.1 +chr17 73636230 73813841 2.11 +chr11 71992715 72182751 2.13 +chr19 7474977 7636673 2.13 +chr19 54525652 54718270 2.15 +chr19 2928780 3109070 2.17 +chr1 25064047 25159219 2.18 +chr20 62108686 62284676 2.38 \ No newline at end of file diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 tool_conf.xml.sample --- a/tool_conf.xml.sample +++ b/tool_conf.xml.sample @@ -175,6 +175,7 @@ <section name="Regional Variation" id="regVar"><tool file="regVariation/windowSplitter.xml" /><tool file="regVariation/featureCounter.xml" /> + <tool file="regVariation/WeightedAverage.xml" /><tool file="regVariation/quality_filter.xml" /><tool file="regVariation/maf_cpg_filter.xml" /><tool file="regVariation/getIndels_2way.xml" /> @@ -194,8 +195,10 @@ </section><section name="Multiple regression" id="multReg"><tool file="regVariation/linear_regression.xml" /> + <tool file="regVariation/logistic_regression_vif.xml" /><tool file="regVariation/best_regression_subsets.xml" /><tool file="regVariation/rcve.xml" /> + <tool file="regVariation/partialR_square.xml" /></section><section name="Multivariate Analysis" id="multVar"><tool file="multivariate_stats/pca.xml" /> diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 tool_data_table_conf.xml.sample --- a/tool_data_table_conf.xml.sample +++ b/tool_data_table_conf.xml.sample @@ -70,6 +70,11 @@ <columns>value, dbkey, name, path</columns><file path="tool-data/picard_index.loc" /></table> + <!-- Location of Picard dict files valid for GATK --> + <table name="gatk_picard_indexes" comment_char="#"> + <columns>value, dbkey, name, path, tools_valid_for</columns> + <file path="tool-data/picard_index.loc" /> + </table><!-- Location of SRMA dict file and other files --><table name="srma_indexes" comment_char="#"><columns>value, dbkey, name, path</columns> diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 tools/gatk/analyze_covariates.xml --- a/tools/gatk/analyze_covariates.xml +++ b/tools/gatk/analyze_covariates.xml @@ -11,6 +11,7 @@ -jar "${GALAXY_DATA_INDEX_DIR}/shared/jars/gatk/AnalyzeCovariates.jar" -recalFile "${input_recal}" -outputDir "${output_html.files_path}" + ##--num_threads 4 ##hard coded, for now ##-log "${output_log}" ##-Rscript,--path_to_Rscript path_to_Rscript; on path is good enough -resources "${GALAXY_DATA_INDEX_DIR}/gatk/R" diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 tools/gatk/count_covariates.xml --- a/tools/gatk/count_covariates.xml +++ b/tools/gatk/count_covariates.xml @@ -19,8 +19,8 @@ #end if --recal_file "${output_recal}" ${standard_covs} - #if $covariates.value: - #for $cov in $covariates.value: + #if str( $covariates ) != "None": + #for $cov in str( $covariates ).split( ',' ): -cov "${cov}" #end for #end if @@ -139,10 +139,10 @@ <param name="input_bam" type="data" format="bam" label="BAM file"><validator type="unspecified_build" /><validator type="metadata" check="bam_index" message="Metadata missing, click the pencil icon in the history item and use the auto-detect feature to correct this issue."/> - <validator type="dataset_metadata_in_file" filename="picard_index.loc" metadata_name="dbkey" metadata_column="1" message="Sequences are not currently available for the specified build." /><!-- fixme!!! this needs to be a select --> + <validator type="dataset_metadata_in_data_table" table_name="gatk_picard_indexes" metadata_name="dbkey" metadata_column="dbkey" message="Sequences are not currently available for the specified build." /><!-- fixme!!! this needs to be a select --></param><param name="ref_file" type="select" label="Using reference genome"> - <options from_data_table="picard_indexes"> + <options from_data_table="gatk_picard_indexes"><filter type="data_meta" key="dbkey" ref="input_bam" column="dbkey"/></options></param> diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 tools/gatk/indel_realigner.xml --- a/tools/gatk/indel_realigner.xml +++ b/tools/gatk/indel_realigner.xml @@ -13,6 +13,7 @@ -T "IndelRealigner" -o "${output_bam}" -et "NO_ET" ##ET no phone home + ##--num_threads 4 ##hard coded, for now ##-log "${output_log}" ##don't use this to log to file, instead directly capture stdout #if $reference_source.reference_source_selector != "history": -R "${reference_source.ref_file.fields.path}" @@ -50,13 +51,16 @@ #end for ' #end for - #if str( $gatk_param_type.input_intervals ) != "None": - -d "-L" "${gatk_param_type.input_intervals}" "${gatk_param_type.input_intervals.ext}" "input_intervals" - #end if - #if str( $gatk_param_type.input_exclude_intervals ) != "None": - -d "-XL" "${gatk_param_type.input_exclude_intervals}" "${gatk_param_type.input_exclude_intervals.ext}" "input_intervals" - #end if + #for $interval_count, $input_intervals in enumerate( $gatk_param_type.input_interval_repeat ): + -d "--intervals" "${input_intervals.input_intervals}" "${input_intervals.input_intervals.ext}" "input_intervals_${interval_count}" + #end for + + #for $interval_count, $input_intervals in enumerate( $gatk_param_type.input_exclude_interval_repeat ): + -d "--excludeIntervals" "${input_intervals.input_exclude_intervals}" "${input_intervals.input_exclude_intervals.ext}" "input_exlude_intervals_${interval_count}" + #end for + -p '--BTI_merge_rule "${gatk_param_type.BTI_merge_rule}"' + -p '--downsampling_type "${gatk_param_type.downsampling_type.downsampling_type_selector}"' #if str( $gatk_param_type.downsampling_type.downsampling_type_selector ) != "NONE": -p '--${gatk_param_type.downsampling_type.downsample_to_type.downsample_to_type_selector} "${gatk_param_type.downsampling_type.downsample_to_type.downsample_to_value}"' @@ -68,10 +72,16 @@ --defaultBaseQualities "${gatk_param_type.default_base_qualities}" --validation_strictness "${gatk_param_type.validation_strictness}" --interval_merging "${gatk_param_type.interval_merging}" + ${gatk_param_type.disable_experimental_low_memory_sharding} + ${gatk_param_type.non_deterministic_random_seed} ' - #if str( $gatk_param_type.read_group_black_list ) != "None": - -d "-read_group_black_list" "${gatk_param_type.read_group_black_list}" "txt" "input_read_group_black_list" - #end if + #for $rg_black_list_count, $rg_black_list in enumerate( $gatk_param_type.read_group_black_list_repeat ): + #if $rg_black_list.read_group_black_list_type.read_group_black_list_type_selector == "file": + -d "--read_group_black_list" "${rg_black_list.read_group_black_list_type.read_group_black_list}" "txt" "input_read_group_black_list_${rg_black_list_count}" + #else + -p '--read_group_black_list "${rg_black_list.read_group_black_list_type.read_group_black_list}"' + #end if + #end for #end if #if $reference_source.reference_source_selector == "history": -d "-R" "${reference_source.ref_file}" "${reference_source.ref_file.ext}" "gatk_input" @@ -108,10 +118,10 @@ <param name="input_bam" type="data" format="bam" label="BAM file"><validator type="unspecified_build" /><validator type="metadata" check="bam_index" message="Metadata missing, click the pencil icon in the history item and use the auto-detect feature to correct this issue."/> - <validator type="dataset_metadata_in_data_table" table_name="picard_indexes" metadata_name="dbkey" metadata_column="dbkey" message="Sequences are not currently available for the specified build." /><!-- fixme!!! this needs to be a select --> + <validator type="dataset_metadata_in_data_table" table_name="gatk_picard_indexes" metadata_name="dbkey" metadata_column="dbkey" message="Sequences are not currently available for the specified build." /><!-- fixme!!! this needs to be a select --></param><param name="ref_file" type="select" label="Using reference genome"> - <options from_data_table="picard_indexes"> + <options from_data_table="gatk_picard_indexes"><filter type="data_meta" key="dbkey" ref="input_bam" column="dbkey"/></options></param> diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 tools/gatk/realigner_target_creator.xml --- a/tools/gatk/realigner_target_creator.xml +++ b/tools/gatk/realigner_target_creator.xml @@ -13,6 +13,7 @@ -T "RealignerTargetCreator" -o "${output_interval}" -et "NO_ET" ##ET no phone home + ##--num_threads 4 ##hard coded, for now ##-log "${output_log}" ##don't use this to log to file, instead directly capture stdout #if $reference_source.reference_source_selector != "history": -R "${reference_source.ref_file.fields.path}" @@ -104,10 +105,10 @@ <param name="input_bam" type="data" format="bam" label="BAM file"><validator type="unspecified_build" /><validator type="metadata" check="bam_index" message="Metadata missing, click the pencil icon in the history item and use the auto-detect feature to correct this issue."/> - <validator type="dataset_metadata_in_data_table" table_name="picard_indexes" metadata_name="dbkey" metadata_column="dbkey" message="Sequences are not currently available for the specified build." /><!-- fixme!!! this needs to be a select --> + <validator type="dataset_metadata_in_data_table" table_name="gatk_picard_indexes" metadata_name="dbkey" metadata_column="dbkey" message="Sequences are not currently available for the specified build." /><!-- fixme!!! this needs to be a select --></param><param name="ref_file" type="select" label="Using reference genome"> - <options from_data_table="picard_indexes"> + <options from_data_table="gatk_picard_indexes"><filter type="data_meta" key="dbkey" ref="input_bam" column="dbkey"/></options></param> diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 tools/gatk/table_recalibration.xml --- a/tools/gatk/table_recalibration.xml +++ b/tools/gatk/table_recalibration.xml @@ -13,6 +13,7 @@ -T "TableRecalibration" -o "${output_bam}" -et "NO_ET" ##ET no phone home + ##--num_threads 4 ##hard coded, for now ##-log "${output_log}" ##don't use this to log to file, instead directly capture stdout #if $reference_source.reference_source_selector != "history": -R "${reference_source.ref_file.fields.path}" @@ -118,10 +119,10 @@ <param name="input_bam" type="data" format="bam" label="BAM file"><validator type="unspecified_build" /><validator type="metadata" check="bam_index" message="Metadata missing, click the pencil icon in the history item and use the auto-detect feature to correct this issue."/> - <validator type="dataset_metadata_in_data_table" table_name="picard_indexes" metadata_name="dbkey" metadata_column="dbkey" message="Sequences are not currently available for the specified build." /><!-- fixme!!! this needs to be a select --> + <validator type="dataset_metadata_in_data_table" table_name="gatk_picard_indexes" metadata_name="dbkey" metadata_column="dbkey" message="Sequences are not currently available for the specified build." /><!-- fixme!!! this needs to be a select --></param><param name="ref_file" type="select" label="Using reference genome"> - <options from_data_table="picard_indexes"> + <options from_data_table="gatk_picard_indexes"><filter type="data_meta" key="dbkey" ref="input_bam" column="dbkey"/></options></param> diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 tools/gatk/unified_genotyper.xml --- a/tools/gatk/unified_genotyper.xml +++ b/tools/gatk/unified_genotyper.xml @@ -112,13 +112,13 @@ --indelGapOpenPenalty "${analysis_param_type.indelGapOpenPenalty}" --indelHaplotypeSize "${analysis_param_type.indelHaplotypeSize}" ${analysis_param_type.doContextDependentGapPenalties} - #if $analysis_param_type.annotation.value: - #for $annotation in $analysis_param_type.annotation.value: + #if str( $analysis_param_type.annotation ) != "None": + #for $annotation in str( $analysis_param_type.annotation ).split( ','): --annotation "${annotation}" #end for #end if - #if $analysis_param_type.group.value: - #for $group in $analysis_param_type.group.value: + #if str( $analysis_param_type.group ) != "None": + #for $group in str( $analysis_param_type.group ).split( ','): --group "${group}" #end for #end if @@ -136,11 +136,11 @@ <param name="input_bam" type="data" format="bam" label="BAM file"><validator type="unspecified_build" /><validator type="metadata" check="bam_index" message="Metadata missing, click the pencil icon in the history item and use the auto-detect feature to correct this issue."/> - <validator type="dataset_metadata_in_data_table" table_name="picard_indexes" metadata_name="dbkey" metadata_column="dbkey" message="Sequences are not currently available for the specified build." /><!-- fixme!!! this needs to be a select --> + <validator type="dataset_metadata_in_data_table" table_name="gatk_picard_indexes" metadata_name="dbkey" metadata_column="dbkey" message="Sequences are not currently available for the specified build." /><!-- fixme!!! this needs to be a select --></param></repeat><param name="ref_file" type="select" label="Using reference genome"> - <options from_data_table="picard_indexes"> + <options from_data_table="gatk_picard_indexes"><!-- <filter type="data_meta" key="dbkey" ref="input_bam" column="dbkey"/> does not yet work in a repeat...--></options></param> @@ -396,7 +396,7 @@ <data format="txt" name="output_metrics" label="${tool.name} on ${on_string} (metrics)" /><data format="txt" name="output_log" label="${tool.name} on ${on_string} (log)" /></outputs> - <!-- FIXME! <trackster_conf/> --> + <trackster_conf/><tests><test><param name="reference_source_selector" value="history" /> diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 tools/gatk/variant_annotator.xml --- a/tools/gatk/variant_annotator.xml +++ b/tools/gatk/variant_annotator.xml @@ -24,7 +24,7 @@ #if str( $annotations_type.annotations_type_selector ) == "use_all_annotations": --useAllAnnotations #else: - #if $annotations_type.annotations.value: + #if str( $annotations_type.annotations ) != "None": #for $annotation in str( $annotations_type.annotations ).split( ',' ): --annotation "${annotation}" #end for @@ -127,7 +127,7 @@ ##end standard gatk options -p ' - #if $annotation_group.value: + #if str( $annotation_group ) != "None": #for $group in str( $annotation_group ).split( ',' ): --group "${group}" #end for @@ -146,10 +146,10 @@ <param name="input_bam" type="data" format="bam" label="BAM file" optional="True" help="Not needed for all annotations." ><validator type="unspecified_build" /><validator type="metadata" check="bam_index" message="Metadata missing, click the pencil icon in the history item and use the auto-detect feature to correct this issue."/> - <validator type="dataset_metadata_in_data_table" table_name="picard_indexes" metadata_name="dbkey" metadata_column="dbkey" message="Sequences are not currently available for the specified build." /><!-- fixme!!! this needs to be a select --> + <validator type="dataset_metadata_in_data_table" table_name="gatk_picard_indexes" metadata_name="dbkey" metadata_column="dbkey" message="Sequences are not currently available for the specified build." /><!-- fixme!!! this needs to be a select --></param><param name="ref_file" type="select" label="Using reference genome"> - <options from_data_table="picard_indexes"> + <options from_data_table="gatk_picard_indexes"><filter type="data_meta" key="dbkey" ref="input_variant" column="dbkey"/></options></param> diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 tools/gatk/variant_apply_recalibration.xml --- a/tools/gatk/variant_apply_recalibration.xml +++ b/tools/gatk/variant_apply_recalibration.xml @@ -102,7 +102,7 @@ <param name="input_recal" type="data" format="gatk_recal" label="Variant Recalibration file" /><param name="input_tranches" type="data" format="gatk_tranche" label="Variant Tranches file" /><param name="ref_file" type="select" label="Using reference genome"> - <options from_data_table="picard_indexes"> + <options from_data_table="gatk_picard_indexes"><!-- <filter type="data_meta" key="dbkey" ref="variants[0].input_variants" column="dbkey"/> --></options></param> diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 tools/gatk/variant_combine.xml --- a/tools/gatk/variant_combine.xml +++ b/tools/gatk/variant_combine.xml @@ -114,7 +114,7 @@ </param></repeat><param name="ref_file" type="select" label="Using reference genome"> - <options from_data_table="picard_indexes"> + <options from_data_table="gatk_picard_indexes"><!-- <filter type="data_meta" key="dbkey" ref="input_variants.input_variant" column="dbkey"/> --></options></param> diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 tools/gatk/variant_eval.xml --- a/tools/gatk/variant_eval.xml +++ b/tools/gatk/variant_eval.xml @@ -159,7 +159,7 @@ <param name="input_variant" type="data" format="vcf" label="Input variant file" /></repeat><param name="ref_file" type="select" label="Using reference genome"> - <options from_data_table="picard_indexes"> + <options from_data_table="gatk_picard_indexes"><!-- <filter type="data_meta" key="dbkey" ref="input_variant" column="dbkey"/> --></options></param> diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 tools/gatk/variant_filtration.xml --- a/tools/gatk/variant_filtration.xml +++ b/tools/gatk/variant_filtration.xml @@ -106,7 +106,7 @@ <when value="cached"><param name="input_variant" type="data" format="vcf" label="Variant file to annotate" /><param name="ref_file" type="select" label="Using reference genome"> - <options from_data_table="picard_indexes"> + <options from_data_table="gatk_picard_indexes"><filter type="data_meta" key="dbkey" ref="input_variant" column="dbkey"/></options></param> diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 tools/gatk/variant_recalibrator.xml --- a/tools/gatk/variant_recalibrator.xml +++ b/tools/gatk/variant_recalibrator.xml @@ -98,7 +98,7 @@ ##start analysis specific options -p ' - #if $annotations.value: + #if str( $annotations ) != "None": #for $annotation in str( $annotations ).split( ',' ): --use_annotation "${annotation}" #end for @@ -152,7 +152,7 @@ <param name="input_variants" type="data" format="vcf" label="Variant file to recalibrate" /></repeat><param name="ref_file" type="select" label="Using reference genome"> - <options from_data_table="picard_indexes"> + <options from_data_table="gatk_picard_indexes"><!-- <filter type="data_meta" key="dbkey" ref="variants[0].input_variants" column="dbkey"/> --></options></param> @@ -515,7 +515,7 @@ <param name="dirichlet" type="float" label="dirichlet parameter in variational Bayes algorithm" value="0.001"/><param name="prior_counts" type="float" label="number of prior counts to use in variational Bayes algorithm" value="20.0"/><conditional name="bad_variant_selector"> - <param name="bad_variant_selector_type" type="select" label="Basic or Advanced Analysis options"> + <param name="bad_variant_selector_type" type="select" label="How to specify bad variants"><option value="percent" selected="True">Percent</option><option value="min_num">Number</option></param> diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 tools/gatk/variants_validate.xml --- a/tools/gatk/variants_validate.xml +++ b/tools/gatk/variants_validate.xml @@ -12,6 +12,7 @@ -T "ValidateVariants" -et "NO_ET" ##ET no phone home + --num_threads 4 ##hard coded, for now ##-log "${output_log}" ##don't use this to log to file, instead directly capture stdout #if $reference_source.reference_source_selector != "history": -R "${reference_source.ref_file.fields.path}" @@ -91,7 +92,7 @@ <when value="cached"><param name="input_variant" type="data" format="vcf" label="Input variant file" /><param name="ref_file" type="select" label="Using reference genome"> - <options from_data_table="picard_indexes"> + <options from_data_table="gatk_picard_indexes"><filter type="data_meta" key="dbkey" ref="input_variant" column="dbkey"/></options></param> diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 tools/ngs_rna/cufflinks_wrapper.xml --- a/tools/ngs_rna/cufflinks_wrapper.xml +++ b/tools/ngs_rna/cufflinks_wrapper.xml @@ -61,10 +61,10 @@ </param><when value="No"></when><when value="Use reference annotation"> - <param format="gff3,gtf" name="reference_annotation_file" type="data" label="Reference Annotation" help="Make sure your annotation file is in GTF format and that Galaxy knows that your file is GTF--not GFF."/> + <param format="gff3,gtf" name="reference_annotation_file" type="data" label="Reference Annotation" help="Gene annotation dataset in GTF or GFF3 format."/></when><when value="Use reference annotation guide"> - <param format="gff3,gtf" name="reference_annotation_guide_file" type="data" label="Reference Annotation" help="Make sure your annotation file is in GTF format and that Galaxy knows that your file is GTF--not GFF."/> + <param format="gff3,gtf" name="reference_annotation_guide_file" type="data" label="Reference Annotation" help="Gene annotation dataset in GTF or GFF3 format."/></when></conditional><conditional name="bias_correction"> diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 tools/picard/picard_ReorderSam.xml --- a/tools/picard/picard_ReorderSam.xml +++ b/tools/picard/picard_ReorderSam.xml @@ -4,7 +4,7 @@ picard_wrapper.py --input=$inputFile #if $source.indexSource == "built-in" - --ref="${ filter( lambda x: str( x[0] ) == str( $source.ref ), $__app__.tool_data_tables[ 'picard_indexes' ].get_fields() )[0][-1] }" + --ref="${source.ref.fields.path}" #else --ref-file=$refFile --species-name=$source.speciesName diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 tools/regVariation/WeightedAverage.py --- /dev/null +++ b/tools/regVariation/WeightedAverage.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python +""" + +usage: %prog bed_file_1 bed_file_2 out_file + -1, --cols1=N,N,N,N: Columns for chr, start, end, strand in first file + -2, --cols2=N,N,N,N,N: Columns for chr, start, end, strand, name/value in second file +""" +from galaxy import eggs + +import collections +import sys, string +#import numpy +from galaxy import eggs +import pkg_resources +pkg_resources.require( "bx-python" ) +import sys, traceback, fileinput +from warnings import warn +from galaxy.tools.util.galaxyops import * +from bx.cookbook import doc_optparse + + +#export PYTHONPATH=~/galaxy/lib/ +#running command python WeightedAverage.py interval_interpolate.bed value_interpolate.bed interpolate_result.bed + +def stop_err(msg): + sys.stderr.write(msg) + sys.exit() + + +def FindRate(chromosome,start_stop,dictType): + OverlapList=[] + for tempO in dictType[chromosome]: + DatabaseInterval=[tempO[0],tempO[1]] + Overlap=GetOverlap(start_stop,DatabaseInterval) + if Overlap>0: + OverlapList.append([Overlap,tempO[2]]) + + if len(OverlapList)>0: + + SumRecomb=0 + SumOverlap=0 + for member in OverlapList: + SumRecomb+=member[0]*member[1] + SumOverlap+=member[0] + averageRate=SumRecomb/SumOverlap + + return averageRate + + else: + return 'NA' + + + +def GetOverlap(a,b): + return min(a[1],b[1])-max(a[0],b[0]) + +options, args = doc_optparse.parse( __doc__ ) + +try: + chr_col_1, start_col_1, end_col_1, strand_col1 = parse_cols_arg( options.cols1 ) + chr_col_2, start_col_2, end_col_2, strand_col2, name_col_2 = parse_cols_arg( options.cols2 ) + input1, input2, input3 = args +except Exception, eee: + print eee + stop_err( "Data issue: click the pencil icon in the history item to correct the metadata attributes." ) + + + +fd2=open(input2) +lines2=fd2.readlines() +RecombChrDict=collections.defaultdict(list) + +skipped=0 +for line in lines2: + temp=line.strip().split() + try: + assert float(temp[int(name_col_2)]) + except: + skipped+=1 + continue + tempIndex=[int(temp[int(start_col_2)]),int(temp[int(end_col_2)]),float(temp[int(name_col_2)])] + RecombChrDict[temp[int(chr_col_2)]].append(tempIndex) + +print "Skipped %d features with invalid values" %(skipped) + +fd1=open(input1) +lines=fd1.readlines() +finalProduct='' +for line in lines: + temp=line.strip().split('\t') + chromosome=temp[int(chr_col_1)] + start=int(temp[int(start_col_1)]) + stop=int(temp[int(end_col_1)]) + start_stop=[start,stop] + RecombRate=FindRate(chromosome,start_stop,RecombChrDict) + try: + RecombRate="%.4f" %(float(RecombRate)) + except: + RecombRate=RecombRate + finalProduct+=line.strip()+'\t'+str(RecombRate)+'\n' +fdd=open(input3,'w') +fdd.writelines(finalProduct) +fdd.close() diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 tools/regVariation/WeightedAverage.xml --- /dev/null +++ b/tools/regVariation/WeightedAverage.xml @@ -0,0 +1,71 @@ +<tool id="wtavg" name="Assign weighted-average" version="1.0.0"> + <description> of the values of features overlapping an interval </description> + <command interpreter="python">WeightedAverage.py $genomic_interval $genomic_feature $out_file1 -1 ${genomic_interval.metadata.chromCol},${genomic_interval.metadata.startCol},${genomic_interval.metadata.endCol},${genomic_interval.metadata.strandCol} -2 ${genomic_feature.metadata.chromCol},${genomic_feature.metadata.startCol},${genomic_feature.metadata.endCol},${genomic_feature.metadata.strandCol},${genomic_feature.metadata.nameCol}</command> + + <inputs> + <param format="interval" name="genomic_interval" type="data" label="Genomic intervals (first dataset)" help="Dataset missing? See Note below."/> + <param format="interval" name="genomic_feature" label="Genomic features (second dataset)" type="data" help="Make sure the value column is specified. See Note below." /> + </inputs> + <outputs> + <data format="input" name="out_file1" metadata_source="genomic_interval" /> + </outputs> + <tests> + <!-- Test data with valid values --> + <test> + <param name="genomic_interval" value="interval_interpolate.bed"/> + <param name="genomic_feature" value="value_interpolate.bed"/> + <output name="out_file1" file="interpolate_result.bed"/> + </test> + + </tests> + <help> + + +.. class:: infomark + +**What it does** + +For each interval in your first dataset, this tool calculates the weighted average value of the overlapping features in your second dataset. + +- When a genomic interval partially or totally overlaps a single genomic feature, the value of that genomic feature is assigned to the genomic interval. +- When a genomic interval partially or totally overlaps with more than one genomic features, the average of the values of the overlapping genomic features weighted by the corresponding number of overlapping bases is assigned to the genomic interval. +- When a genomic interval does not overlap with any genomic feature, 'NA' will be assigned as it's value. + +----- + +.. class:: warningmark + +**Note** + +The input datasets should be in **bed** or **interval** format. Please use "edit attributes"/pencil icon to specify the column containing the values for the features in the second dataset as **name/identifier** column. + +The output will contain all the columns in the first input plus a new column containing the assigned value for each interval. + +----- + +**Example** + +- Suppose our first dataset contains the following **genomic intervals**:: + + chr start stop + chr1 1000 2000 + chr1 3000 5000 + chr1 8000 9000 + +- and our second dataset contains the following **genomic features** each having an associated value (in fourth column) :: + + chr start stop name + chr1 900 1200 0.5 + chr1 2900 3100 0.2 + chr1 4800 5100 0.8 + +- For each **genomic interval** in our first dataset, this tool calculates the weighted average value of the overlapping **genomic features** in our second dataset :: + + chr1 1000 2000 0.5 + chr1 3000 5000 0.6 + chr1 8000 9000 NA + + + +</help> +</tool> \ No newline at end of file diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 tools/regVariation/logistic_regression_vif.py --- /dev/null +++ b/tools/regVariation/logistic_regression_vif.py @@ -0,0 +1,185 @@ +#!/usr/bin/env python + +from galaxy import eggs +import sys, string +from rpy import * +import numpy + +#export PYTHONPATH=~/galaxy/lib/ + +def stop_err(msg): + sys.stderr.write(msg) + sys.exit() +#infile = 'logreg_inp.tab' +#y_col=3 +#x_cols=[1,2,3] +#outfile='logreg_out.txt' +#python logistic_regression_vif.py logreg_inp.tab 4 1,2,3 logreg_out2.tabular # running test +infile = sys.argv[1] +y_col = int(sys.argv[2])-1 +x_cols = sys.argv[3].split(',') +outfile = sys.argv[4] + + +print "Predictor columns: %s; Response column: %d" %(x_cols,y_col+1) +fout = open(outfile,'w') +elems = [] +for i, line in enumerate( file ( infile )): + line = line.rstrip('\r\n') + if len( line )>0 and not line.startswith( '#' ): + elems = line.split( '\t' ) + break + if i == 30: + break # Hopefully we'll never get here... + +if len( elems )<1: + stop_err( "The data in your input dataset is either missing or not formatted properly." ) + +y_vals = [] +x_vals = [] + +for k,col in enumerate(x_cols): + x_cols[k] = int(col)-1 + x_vals.append([]) + +NA = 'NA' +for ind,line in enumerate( file( infile )): + if line and not line.startswith( '#' ): + try: + fields = line.split("\t") + try: + yval = float(fields[y_col]) + except: + yval = r('NA') + y_vals.append(yval) + for k,col in enumerate(x_cols): + try: + xval = float(fields[col]) + except: + xval = r('NA') + x_vals[k].append(xval) + except: + pass + +x_vals1 = numpy.asarray(x_vals).transpose() + +check1=0 +check0=0 +for i in y_vals: + if i == 1: + check1=1 + if i == 0: + check0=1 +if check1==0 or check0==0: + sys.exit("Warning: logistic regression must have at least two classes") + +for i in y_vals: + if i not in [1,0,r('NA')]: + print >>fout, str(i) + sys.exit("Warning: the current version of this tool can run only with two classes and need to be labeled as 0 and 1.") + + +dat= r.list(x=array(x_vals1), y=y_vals) +novif=0 +set_default_mode(NO_CONVERSION) +try: + linear_model = r.glm(r("y ~ x"), data = r.na_exclude(dat),family="binomial") + #r('library(car)') + #r.assign('dat',dat) + #r.assign('ncols',len(x_cols)) + #r.vif(r('glm(dat$y ~ ., data = na.exclude(data.frame(as.matrix(dat$x,ncol=ncols))->datx),family="binomial")')).as_py() + +except RException, rex: + stop_err("Error performing logistic regression on the input data.\nEither the response column or one of the predictor columns contain only non-numeric or invalid values.") +if len(x_cols)>1: + try: + + r('library(car)') + r.assign('dat',dat) + r.assign('ncols',len(x_cols)) + vif=r.vif(r('glm(dat$y ~ ., data = na.exclude(data.frame(as.matrix(dat$x,ncol=ncols))->datx),family="binomial")')) + except RException, rex: + print rex +else: + novif=1 + +set_default_mode(BASIC_CONVERSION) + +coeffs=linear_model.as_py()['coefficients'] +null_deviance=linear_model.as_py()['null.deviance'] +residual_deviance=linear_model.as_py()['deviance'] +yintercept= coeffs['(Intercept)'] +summary = r.summary(linear_model) +co = summary.get('coefficients', 'NA') +""" +if len(co) != len(x_vals)+1: + stop_err("Stopped performing logistic regression on the input data, since one of the predictor columns contains only non-numeric or invalid values.") +""" + +try: + yintercept = r.round(float(yintercept), digits=10) + pvaly = r.round(float(co[0][3]), digits=10) +except: + pass +print >>fout, "response column\tc%d" %(y_col+1) +tempP=[] +for i in x_cols: + tempP.append('c'+str(i+1)) +tempP=','.join(tempP) +print >>fout, "predictor column(s)\t%s" %(tempP) +print >>fout, "Y-intercept\t%s" %(yintercept) +print >>fout, "p-value (Y-intercept)\t%s" %(pvaly) + +if len(x_vals) == 1: #Simple linear regression case with 1 predictor variable + try: + slope = r.round(float(coeffs['x']), digits=10) + except: + slope = 'NA' + try: + pval = r.round(float(co[1][3]), digits=10) + except: + pval = 'NA' + print >>fout, "Slope (c%d)\t%s" %(x_cols[0]+1,slope) + print >>fout, "p-value (c%d)\t%s" %(x_cols[0]+1,pval) +else: #Multiple regression case with >1 predictors + ind=1 + while ind < len(coeffs.keys()): + try: + slope = r.round(float(coeffs['x'+str(ind)]), digits=10) + except: + slope = 'NA' + print >>fout, "Slope (c%d)\t%s" %(x_cols[ind-1]+1,slope) + try: + pval = r.round(float(co[ind][3]), digits=10) + except: + pval = 'NA' + print >>fout, "p-value (c%d)\t%s" %(x_cols[ind-1]+1,pval) + ind+=1 + +rsq = summary.get('r.squared','NA') + + +try: + rsq= r.round(float((null_deviance-residual_deviance)/null_deviance), digits=5) + null_deviance= r.round(float(null_deviance), digits=5) + residual_deviance= r.round(float(residual_deviance), digits=5) + + #rsq = r.round(float(rsq), digits=5) + +except: + pass + +print >>fout, "Null deviance\t%s" %(null_deviance) +print >>fout, "Residual deviance\t%s" %(residual_deviance) +print >>fout, "pseudo R-squared\t%s" %(rsq) +print >>fout, "\n" +print >>fout, 'vif' + +if novif==0: + py_vif=vif.as_py() + count=0 + for i in sorted(py_vif.keys()): + print >>fout,'c'+str(x_cols[count]+1) ,str(py_vif[i]) + count+=1 +elif novif==1: + print >>fout, "vif can calculate only when model have more than 1 predictor" diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 tools/regVariation/logistic_regression_vif.xml --- /dev/null +++ b/tools/regVariation/logistic_regression_vif.xml @@ -0,0 +1,74 @@ +<tool id="LogisticRegression" name="Perform Logistic Regression with vif" version="1.0.1"> + <description></description> + <command interpreter="python"> + logistic_regression_vif.py + $input1 + $response_col + $predictor_cols + $out_file1 + 1>/dev/null + </command> + <inputs> + <param format="tabular" name="input1" type="data" label="Select data" help="Dataset missing? See TIP below."/> + <param name="response_col" label="Response column (Y)" type="data_column" data_ref="input1" numerical="True"/> + <param name="predictor_cols" label="Predictor columns (X)" type="data_column" data_ref="input1" numerical="True" multiple="true" > + <validator type="no_options" message="Please select at least one column."/> + </param> + </inputs> + <outputs> + <data format="input" name="out_file1" metadata_source="input1" /> + + </outputs> + <requirements> + <requirement type="python-module">rpy</requirement> + </requirements> + <tests> + <test> + <param name="input1" value="logreg_inp.tabular"/> + <param name="response_col" value="4"/> + <param name="predictor_cols" value="1,2,3"/> + <output name="out_file1" file="logreg_out2.tabular"/> + + </test> + </tests> + <help> + + +.. class:: infomark + +**TIP:** If your data is not TAB delimited, use *Edit Datasets->Convert characters* + +----- + +.. class:: infomark + +**What it does** + +This tool uses the **'glm'** function from R statistical package to perform logistic regression on the input data. It outputs one file containing the summary statistics of the performed regression. Also, it calculates VIF(Variance Inflation Factor) with **'vif'** function from library (car) in R. + + +*R Development Core Team (2010). R: A language and environment for statistical computing. R Foundation for Statistical Computing, Vienna, Austria. ISBN 3-900051-07-0, URL http://www.R-project.org.* + +----- + +.. class:: warningmark + +**Note** + +- This tool currently treats all predictor variables as continuous numeric variables and response variable as categorical variable. Currently, the response variable can have only two classes, namely 0 and 1. The program will take 0 as base class. + +- Rows containing non-numeric (or missing) data in any of the chosen columns will be skipped from the analysis. + +- The summary statistics in the output are described below: + +- Pseudo R-squared: the proportion of model improvement from null model +- p-value: p-value for the z-test of the null hypothesis that the corresponding slope is equal to zero against the two-sided alternative. +- Coefficient indicates log ratio of (probability to be class 1 / probability to be class 0) + +- This tool also provides **Variance Inflation Factor or VIF** which quantifies the level of multicollinearity. The tool will automatic generate VIF if the model has more than one predictor. The higher the VIF, the higher is the multicollinearity. Multicollinearity will inflate standard error and reduce level of significance of the predictor. In the worst case, it can reverse direction of slope for highly correlated predictors if one of them is significant. A general thumb-rule is to use those predictors having VIF lower than 10 or 5. +- **vif** is calculated by + - First, regressing each predictor over all other predictors, and recording R-squared for each regression. + - Second, computing vif as 1/(1- R_squared) + + </help> +</tool> diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 tools/regVariation/partialR_square.py --- /dev/null +++ b/tools/regVariation/partialR_square.py @@ -0,0 +1,146 @@ +#!/usr/bin/env python + +from galaxy import eggs + +import sys, string +from rpy import * +import numpy + +#export PYTHONPATH=~/galaxy/lib/ +#running command python partialR_square.py reg_inp.tab 4 1,2,3 partialR_result.tabular + +def stop_err(msg): + sys.stderr.write(msg) + sys.exit() + +def sscombs(s): + if len(s) == 1: + return [s] + else: + ssc = sscombs(s[1:]) + return [s[0]] + [s[0]+comb for comb in ssc] + ssc + + +infile = sys.argv[1] +y_col = int(sys.argv[2])-1 +x_cols = sys.argv[3].split(',') +outfile = sys.argv[4] + +print "Predictor columns: %s; Response column: %d" %(x_cols,y_col+1) +fout = open(outfile,'w') + +for i, line in enumerate( file ( infile )): + line = line.rstrip('\r\n') + if len( line )>0 and not line.startswith( '#' ): + elems = line.split( '\t' ) + break + if i == 30: + break # Hopefully we'll never get here... + +if len( elems )<1: + stop_err( "The data in your input dataset is either missing or not formatted properly." ) + +y_vals = [] +x_vals = [] + +for k,col in enumerate(x_cols): + x_cols[k] = int(col)-1 + x_vals.append([]) + """ + try: + float( elems[x_cols[k]] ) + except: + try: + msg = "This operation cannot be performed on non-numeric column %d containing value '%s'." %( col, elems[x_cols[k]] ) + except: + msg = "This operation cannot be performed on non-numeric data." + stop_err( msg ) + """ +NA = 'NA' +for ind,line in enumerate( file( infile )): + if line and not line.startswith( '#' ): + try: + fields = line.split("\t") + try: + yval = float(fields[y_col]) + except Exception, ey: + yval = r('NA') + #print >>sys.stderr, "ey = %s" %ey + y_vals.append(yval) + for k,col in enumerate(x_cols): + try: + xval = float(fields[col]) + except Exception, ex: + xval = r('NA') + #print >>sys.stderr, "ex = %s" %ex + x_vals[k].append(xval) + except: + pass + +x_vals1 = numpy.asarray(x_vals).transpose() +dat= r.list(x=array(x_vals1), y=y_vals) + +set_default_mode(NO_CONVERSION) +try: + full = r.lm(r("y ~ x"), data= r.na_exclude(dat)) #full model includes all the predictor variables specified by the user +except RException, rex: + stop_err("Error performing linear regression on the input data.\nEither the response column or one of the predictor columns contain no numeric values.") +set_default_mode(BASIC_CONVERSION) + +summary = r.summary(full) +fullr2 = summary.get('r.squared','NA') + +if fullr2 == 'NA': + stop_error("Error in linear regression") + +if len(x_vals) < 10: + s = "" + for ch in range(len(x_vals)): + s += str(ch) +else: + stop_err("This tool only works with less than 10 predictors.") + +print >>fout, "#Model\tR-sq\tpartial_R_Terms\tpartial_R_Value" +all_combos = sorted(sscombs(s), key=len) +all_combos.reverse() +for j,cols in enumerate(all_combos): + #if len(cols) == len(s): #Same as the full model above + # continue + if len(cols) == 1: + x_vals1 = x_vals[int(cols)] + else: + x_v = [] + for col in cols: + x_v.append(x_vals[int(col)]) + x_vals1 = numpy.asarray(x_v).transpose() + dat= r.list(x=array(x_vals1), y=y_vals) + set_default_mode(NO_CONVERSION) + red = r.lm(r("y ~ x"), data= dat) #Reduced model + set_default_mode(BASIC_CONVERSION) + summary = r.summary(red) + redr2 = summary.get('r.squared','NA') + try: + partial_R = (float(fullr2)-float(redr2))/(1-float(redr2)) + except: + partial_R = 'NA' + col_str = "" + for col in cols: + col_str = col_str + str(int(x_cols[int(col)]) + 1) + " " + col_str.strip() + partial_R_col_str = "" + for col in s: + if col not in cols: + partial_R_col_str = partial_R_col_str + str(int(x_cols[int(col)]) + 1) + " " + partial_R_col_str.strip() + if len(cols) == len(s): #full model + partial_R_col_str = "-" + partial_R = "-" + try: + redr2 = "%.4f" %(float(redr2)) + except: + pass + try: + partial_R = "%.4f" %(float(partial_R)) + except: + pass + print >>fout, "%s\t%s\t%s\t%s" %(col_str,redr2,partial_R_col_str,partial_R) diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 tools/regVariation/partialR_square.xml --- /dev/null +++ b/tools/regVariation/partialR_square.xml @@ -0,0 +1,68 @@ +<tool id="partialRsq" name="Compute partial R square" version="1.0.0"> + <description></description> + <command interpreter="python"> + partialR_square.py + $input1 + $response_col + $predictor_cols + $out_file1 + 1>/dev/null + </command> + <inputs> + <param format="tabular" name="input1" type="data" label="Select data" help="Dataset missing? See TIP below."/> + <param name="response_col" label="Response column (Y)" type="data_column" data_ref="input1" /> + <param name="predictor_cols" label="Predictor columns (X)" type="data_column" data_ref="input1" multiple="true"> + <validator type="no_options" message="Please select at least one column."/> + </param> + </inputs> + <outputs> + <data format="input" name="out_file1" metadata_source="input1" /> + </outputs> + <requirements> + <requirement type="python-module">rpy</requirement> + </requirements> + <tests> + <!-- Test data with vlid values --> + <test> + <param name="input1" value="regr_inp.tabular"/> + <param name="response_col" value="3"/> + <param name="predictor_cols" value="1,2"/> + <output name="out_file1" file="partialR_result.tabular"/> + </test> + + </tests> + <help> + +.. class:: infomark + +**TIP:** If your data is not TAB delimited, use *Edit Datasets->Convert characters* + +----- + +.. class:: infomark + +**What it does** + +This tool computes the Partial R squared for all possible variable subsets using the following formula: + +**Partial R squared = [SSE(without i: 1,2,...,p-1) - SSE (full: 1,2,..,i..,p-1) / SSE(without i: 1,2,...,p-1)]**, which denotes the case where the 'i'th predictor is dropped. + + + +In general, **Partial R squared = [SSE(without i: 1,2,...,p-1) - SSE (full: 1,2,..,i..,p-1) / SSE(without i: 1,2,...,p-1)]**, where, + +- SSE (full: 1,2,..,i..,p-1) = Sum of Squares left out by the full set of predictors SSE(X1, X2 … Xp) +- SSE (full: 1,2,..,i..,p-1) = Sum of Squares left out by the set of predictors excluding; for example, if we omit the first predictor, it will be SSE(X2 … Xp). + + +The 4 columns in the output are described below: + +- Column 1 (Model): denotes the variables present in the model +- Column 2 (R-sq): denotes the R-squared value corresponding to the model in Column 1 +- Column 3 (Partial R squared_Terms): denotes the variable/s for which Partial R squared is computed. These are the variables that are absent in the reduced model in Column 1. A '-' in this column indicates that the model in Column 1 is the Full model. +- Column 4 (Partial R squared): denotes the Partial R squared value corresponding to the variable/s in Column 3. A '-' in this column indicates that the model in Column 1 is the Full model. + +*R Development Core Team (2010). R: A language and environment for statistical computing. R Foundation for Statistical Computing, Vienna, Austria. ISBN 3-900051-07-0, URL http://www.R-project.org.* + + </help> +</tool> diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 tools/sr_mapping/srma_wrapper.py --- a/tools/sr_mapping/srma_wrapper.py +++ b/tools/sr_mapping/srma_wrapper.py @@ -29,7 +29,7 @@ parser = optparse.OptionParser() parser.add_option( '-r', '--ref', dest='ref', help='The reference genome to index and use' ) parser.add_option( '-u', '--refUID', dest='refUID', help='The pre-index reference genome unique Identifier' ) - parser.add_option( '-L', '--refLocations', dest='refLocations', help='The filepath to the srma indices location file' ) + #parser.add_option( '-L', '--refLocations', dest='refLocations', help='The filepath to the srma indices location file' ) parser.add_option( '-i', '--input', dest='input', help='The SAM/BAM input file' ) parser.add_option( '-I', '--inputIndex', dest='inputIndex', help='The SAM/BAM input index file' ) parser.add_option( '-o', '--output', dest='output', help='The SAM/BAM output file' ) diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 tools/sr_mapping/srma_wrapper.xml --- a/tools/sr_mapping/srma_wrapper.xml +++ b/tools/sr_mapping/srma_wrapper.xml @@ -4,9 +4,9 @@ #if $refGenomeSource.refGenomeSource_type == "history": --ref=$refGenomeSource.ownFile #else: - --ref="${ filter( lambda x: str( x[0] ) == str( $refGenomeSource.ref ), $__app__.tool_data_tables[ 'srma_indexes' ].get_fields() )[0][-1] }" + --ref="${refGenomeSource.ref.fields.path}" --refUID=$refGenomeSource.ref - --refLocations=${GALAXY_DATA_INDEX_DIR}/srma_index.loc + ##--refLocations=${GALAXY_DATA_INDEX_DIR}/srma_index.loc #end if --input=$input --inputIndex=${input.metadata.bam_index} diff -r 42c8a6cfaa5b76204e978eedfd17647b05531b13 -r f05722e66a8a42e75f01a29b723ed50525e77e55 universe_wsgi.ini.sample --- a/universe_wsgi.ini.sample +++ b/universe_wsgi.ini.sample @@ -405,6 +405,9 @@ # Allow administrators to delete accounts. #allow_user_deletion = False +# Allow administrators to log in as other users (useful for debugging) +#allow_user_impersonation = False + # Allow users to remove their datasets from disk immediately (otherwise, # datasets will be removed after a time period specified by an administrator in # the cleanup scripts run via cron) https://bitbucket.org/galaxy/galaxy-central/changeset/b1a8b03710fe/ changeset: b1a8b03710fe user: natefoo date: 2011-11-08 18:20:06 summary: Actual user: Fix for ownership problems when using splitting. affected #: 3 files diff -r f05722e66a8a42e75f01a29b723ed50525e77e55 -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 lib/galaxy/jobs/__init__.py --- a/lib/galaxy/jobs/__init__.py +++ b/lib/galaxy/jobs/__init__.py @@ -530,19 +530,11 @@ self.sa_session.expunge_all() job = self.get_job() - if self.app.config.drmaa_external_runjob_script and job.user is not None: - try: - # FIXME: hardcoded path - cmd = [ '/usr/bin/sudo', '-E', self.app.config.external_chown_script, self.working_directory, self.galaxy_system_pwent[0], str( self.galaxy_system_pwent[3] ) ] - log.debug( '(%s) Changing ownership of working directory with: %s' % ( job.id, ' '.join( cmd ) ) ) - p = subprocess.Popen( cmd, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) - p.wait() - assert p.returncode == 0 - except: - # TODO: log stdout/stderr - log.exception( '(%s) Failed to change ownership of %s, failing' % ( job.id, self.working_directory ) ) - self.fail( job.info ) - return + try: + self.reclaim_ownership() + except: + self.fail( job.info ) + log.exception( '(%s) Failed to change ownership of %s, failing' % ( job.id, self.working_directory ) ) # if the job was deleted, don't finish it if job.state == job.states.DELETED: @@ -900,25 +892,38 @@ else: return 'anonymous@unknown' + def _change_ownership( self, username, gid ): + job = self.get_job() + # FIXME: hardcoded path + cmd = [ '/usr/bin/sudo', '-E', self.app.config.external_chown_script, self.working_directory, username, str( gid ) ] + log.debug( '(%s) Changing ownership of working directory with: %s' % ( job.id, ' '.join( cmd ) ) ) + p = subprocess.Popen( cmd, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) + # TODO: log stdout/stderr + stdout, stderr = p.communicate() + assert p.returncode == 0 + def change_ownership_for_run( self ): job = self.get_job() if self.app.config.external_chown_script and job.user is not None: try: - # FIXME: hardcoded path - cmd = [ '/usr/bin/sudo', '-E', self.app.config.external_chown_script, self.working_directory, self.user_system_pwent[0], str( self.user_system_pwent[3] ) ] - log.debug( '(%s) Changing ownership of working directory with: %s' % ( job.id, ' '.join( cmd ) ) ) - p = subprocess.Popen( cmd, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) - stdout, stderr = p.communicate() - assert p.returncode == 0 + self._change_ownership( self.user_system_pwent[0], str( self.user_system_pwent[3] ) ) except: log.exception( '(%s) Failed to change ownership of %s, making world-writable instead' % ( job.id, self.working_directory ) ) os.chmod( self.working_directory, 0777 ) + def reclaim_ownership( self ): + job = self.get_job() + if self.app.config.external_chown_script and job.user is not None: + self._change_ownership( self.galaxy_system_pwent[0], str( self.galaxy_system_pwent[3] ) ) + @property def user_system_pwent( self ): if self.__user_system_pwent is None: job = self.get_job() - self.__user_system_pwent = pwd.getpwnam( job.user.email.split('@')[0] ) + try: + self.__user_system_pwent = pwd.getpwnam( job.user.email.split('@')[0] ) + except: + pass return self.__user_system_pwent @property diff -r f05722e66a8a42e75f01a29b723ed50525e77e55 -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 lib/galaxy/jobs/runners/tasks.py --- a/lib/galaxy/jobs/runners/tasks.py +++ b/lib/galaxy/jobs/runners/tasks.py @@ -109,6 +109,10 @@ if sleep_time < 8: sleep_time *= 2 + import time + + job_wrapper.reclaim_ownership() # if running as the actual user, change ownership before merging. + log.debug('execution finished - beginning merge: %s' % command_line) stdout, stderr = splitter.do_merge(job_wrapper, task_wrappers) diff -r f05722e66a8a42e75f01a29b723ed50525e77e55 -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 lib/galaxy/jobs/splitters/multi.py --- a/lib/galaxy/jobs/splitters/multi.py +++ b/lib/galaxy/jobs/splitters/multi.py @@ -46,7 +46,7 @@ pass # pass original file name else: log_error = "The input '%s' does not define a method for implementing parallelism" % str(input.name) - log.error(log_error) + log.exception(log_error) raise Exception(log_error) if len(type_to_input_map) > 1: @@ -138,7 +138,7 @@ pickone_done.append(output) else: log_error = "The output '%s' does not define a method for implementing parallelism" % output - log.error(log_error) + log.exception(log_error) raise Exception(log_error) except Exception, e: stdout = 'Error merging files'; https://bitbucket.org/galaxy/galaxy-central/changeset/d24b1a15ab0a/ changeset: d24b1a15ab0a user: natefoo date: 2011-11-16 19:40:46 summary: Merge. affected #: 225 files diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca datatypes_conf.xml.sample --- a/datatypes_conf.xml.sample +++ b/datatypes_conf.xml.sample @@ -9,7 +9,7 @@ <converter file="bam_to_summary_tree_converter.xml" target_datatype="summary_tree" depends_on="bai"/><display file="ucsc/bam.xml" /><display file="ensembl/ensembl_bam.xml" /> - <!-- <display file="igv/bam.xml" /> --> + <display file="igv/bam.xml" /></datatype><datatype extension="bed" type="galaxy.datatypes.interval:Bed" display_in_upload="true"><converter file="bed_to_gff_converter.xml" target_datatype="gff"/> @@ -88,7 +88,7 @@ <datatype extension="gif" type="galaxy.datatypes.images:Gif" mimetype="image/gif"/><datatype extension="gmaj.zip" type="galaxy.datatypes.images:Gmaj" mimetype="application/zip"/><datatype extension="gtf" type="galaxy.datatypes.interval:Gtf" display_in_upload="true"/> - <datatype extension="h5" type="galaxy.datatypes.data:Data" mimetype="application/octet-stream"/> + <datatype extension="h5" type="galaxy.datatypes.binary:Binary" mimetype="application/octet-stream" subclass="True" /><datatype extension="html" type="galaxy.datatypes.images:Html" mimetype="text/html"/><datatype extension="interval" type="galaxy.datatypes.interval:Interval" display_in_upload="true"><converter file="interval_to_bed_converter.xml" target_datatype="bed"/> @@ -154,8 +154,10 @@ <datatype extension="blastxml" type="galaxy.datatypes.xml:BlastXml" mimetype="application/xml" display_in_upload="true"/><datatype extension="vcf" type="galaxy.datatypes.tabular:Vcf" display_in_upload="true"><converter file="vcf_to_bgzip_converter.xml" target_datatype="bgzip"/> + <converter file="vcf_to_vcf_bgzip_converter.xml" target_datatype="vcf_bgzip"/><converter file="vcf_to_tabix_converter.xml" target_datatype="tabix" depends_on="bgzip"/><converter file="vcf_to_summary_tree_converter.xml" target_datatype="summary_tree"/> + <display file="igv/vcf.xml" /></datatype><datatype extension="wsf" type="galaxy.datatypes.wsf:SnpFile" display_in_upload="true"/><datatype extension="velvet" type="galaxy.datatypes.assembly:Velvet" display_in_upload="false"/> @@ -164,10 +166,14 @@ <converter file="wiggle_to_simple_converter.xml" target_datatype="interval"/><!-- <display file="gbrowse/gbrowse_wig.xml" /> --></datatype> - <datatype extension="summary_tree" type="galaxy.datatypes.data:Data" /> - <datatype extension="interval_index" type="galaxy.datatypes.data:Data" /> - <datatype extension="tabix" type="galaxy.datatypes.data:Data" /> - <datatype extension="bgzip" type="galaxy.datatypes.data:Data" /> + <datatype extension="summary_tree" type="galaxy.datatypes.binary:Binary" subclass="True" /> + <datatype extension="interval_index" type="galaxy.datatypes.binary:Binary" subclass="True" /> + <datatype extension="tabix" type="galaxy.datatypes.binary:Binary" subclass="True" /> + <datatype extension="bgzip" type="galaxy.datatypes.binary:Binary" subclass="True" /> + <datatype extension="vcf_bgzip" type_extension="bgzip" subclass="True" > + <display file="igv/vcf.xml" /> + <converter file="vcf_bgzip_to_tabix_converter.xml" target_datatype="tabix"/> + </datatype><!-- Start EMBOSS tools --><datatype extension="acedb" type="galaxy.datatypes.data:Text"/><datatype extension="asn1" type="galaxy.datatypes.data:Text"/> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca display_applications/igv/bam.xml --- a/display_applications/igv/bam.xml +++ b/display_applications/igv/bam.xml @@ -1,12 +1,32 @@ +<?xml version="1.0"?><display id="igv_bam" version="1.0.0" name="display with IGV"> - <link id="web" name="web"> - <url>$jnlp.url</url> - <param type="data" name="bam_file" url="galaxy_${DATASET_HASH}.bam" strip_https="True" /> - <param type="data" name="bai_file" url="galaxy_${DATASET_HASH}.bam.bai" metadata="bam_index" strip_https="True" /> - <param type="template" name="jnlp" url="galaxy_${DATASET_HASH}.jnlp" viewable="True" strip_https="True" mimetype="application/x-java-jnlp-file"><?xml version="1.0" encoding="utf-8"?> + + <!-- Load links from file: one line to one link --> + <dynamic_links from_file="tool-data/shared/igv/igv_build_sites.txt" skip_startswith="#" id="0" name="1"> + + <!-- Define parameters by column from file, allow splitting on builds --> + <dynamic_param name="site_id" value="0"/> + <dynamic_param name="site_name" value="1"/> + <dynamic_param name="site_link" value="2"/> + <dynamic_param name="site_dbkeys" value="3" split="True" separator="," /> + <dynamic_param name="site_organisms" value="4" split="True" separator="," /> + + <!-- Filter out some of the links based upon matching site_dbkeys to dataset dbkey --> + <filter>${dataset.dbkey in $site_dbkeys}</filter> + + <!-- We define url and params as normal, but values defined in dynamic_param are available by specified name --> + <url>${redirect_url}</url> + + <param type="data" name="bam_file" url="galaxy_${DATASET_HASH}.bam" /> + <param type="data" name="bai_file" url="galaxy_${DATASET_HASH}.bam.bai" metadata="bam_index" /> + <param type="template" name="site_organism" strip="True" > + $site_organisms[ $site_dbkeys.index( $bam_file.dbkey ) ] + </param> + + <param type="template" name="jnlp" url="galaxy_${DATASET_HASH}.jnlp" viewable="True" mimetype="application/x-java-jnlp-file"><?xml version="1.0" encoding="utf-8"?> <jnlp spec="1.0+" - codebase="http://www.broadinstitute.org/igvdata/jws/prod"> + codebase="${site_link}"> <information> <title>IGV 1.5</title> <vendor>The Broad Institute</vendor> @@ -54,17 +74,22 @@ <application-desc main-class="org.broad.igv.ui.IGVMainFrame"> <argument>-g</argument> - <argument>${bam_file.dbkey}</argument> + <argument>${site_organism}</argument> <argument>${bam_file.url}</argument> </application-desc> </jnlp> - </param> - </link> - - <link id="local" name="local"> - <url>http://localhost:60151/load?file=${qp($bam_file.url)}&genome=${qp($bam_file.dbkey)}&merge=true</url> - <param type="data" name="bam_file" url="galaxy_${DATASET_HASH}.bam" strip_https="True" /> - <param type="data" name="bai_file" url="galaxy_${DATASET_HASH}.bam.bai" metadata="bam_index" strip_https="True" /> - </link> + <param type="template" name="redirect_url" strip="True" > + #if $site_id.startswith( 'local_' ) + ${site_link}?file=${bam_file.qp}&genome=${site_organism}&merge=true + #elif $site_id.startswith( 'web_link_' ): + ${site_link}?sessionURL=${bam_file.qp}&genome=${site_organism}&merge=true + #else: + ${jnlp.url} + #end if + </param> + </dynamic_links> + + </display> +<!-- Dan Blankenberg --> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca display_applications/igv/vcf.xml --- /dev/null +++ b/display_applications/igv/vcf.xml @@ -0,0 +1,95 @@ +<?xml version="1.0"?> +<display id="igv_vcf" version="1.0.0" name="display with IGV"> + + <!-- Load links from file: one line to one link --> + <dynamic_links from_file="tool-data/shared/igv/igv_build_sites.txt" skip_startswith="#" id="0" name="1"> + + <!-- Define parameters by column from file, allow splitting on builds --> + <dynamic_param name="site_id" value="0"/> + <dynamic_param name="site_name" value="1"/> + <dynamic_param name="site_link" value="2"/> + <dynamic_param name="site_dbkeys" value="3" split="True" separator="," /> + <dynamic_param name="site_organisms" value="4" split="True" separator="," /> + + <!-- Filter out some of the links based upon matching site_dbkeys to dataset dbkey --> + <filter>${dataset.dbkey in $site_dbkeys}</filter> + + <!-- We define url and params as normal, but values defined in dynamic_param are available by specified name --> + <url>${redirect_url}</url> + + <param type="data" name="bgzip_file" url="galaxy_${DATASET_HASH}.vcf.gz" format="vcf_bgzip" /> + <param type="data" name="tabix_file" dataset="bgzip_file" url="galaxy_${DATASET_HASH}.vcf.gz.tbi" format="tabix" /> + <param type="template" name="site_organism" strip="True" > + $site_organisms[ $site_dbkeys.index( $bgzip_file.dbkey ) ] + </param> + + <param type="template" name="jnlp" url="galaxy_${DATASET_HASH}.jnlp" viewable="True" mimetype="application/x-java-jnlp-file"><?xml version="1.0" encoding="utf-8"?> +<jnlp + spec="1.0+" + codebase="${site_link}"> + <information> + <title>IGV 1.5</title> + <vendor>The Broad Institute</vendor> + <homepage href="http://www.broadinstitute.org/igv"/> + <description>IGV Software</description> + <description kind="short">IGV</description> + </information> + <security> + <all-permissions/> + </security> + <resources> + +<j2se version="1.5+" initial-heap-size="256m" max-heap-size="1100m"/> + <jar href="igv.jar" download="eager" main="true"/> + <jar href="batik-codec.jar" download="eager"/> + <property name="apple.laf.useScreenMenuBar" value="true"/> + <property name="com.apple.mrj.application.growbox.intrudes" value="false"/> + <property name="com.apple.mrj.application.live-resize" value="true"/> + <property name="com.apple.macos.smallTabs" value="true"/> + </resources> + + <resources os="Mac" arch="i386"> + <property name="apple.awt.graphics.UseQuartz" value="false"/> + <nativelib href="hdfnative-macintel.jar"/> + </resources> + + <resources os="Mac" arch="ppc"> + <property name="apple.awt.graphics.UseQuartz" value="false"/> + <nativelib href="hdfnative-macppc.jar"/> + </resources> + + <resources os="Mac" arch="PowerPC"> + <property name="apple.awt.graphics.UseQuartz" value="false"/> + <nativelib href="hdfnative-macppc.jar"/> + </resources> + + <resources os="Windows"> + <property name="sun.java2d.noddraw" value="true"/> + <nativelib href="hdfnative-win.jar"/> + </resources> + + <resources os="Linux"> + <nativelib href="hdfnative-linux64.jar"/> + </resources> + + <application-desc main-class="org.broad.igv.ui.IGVMainFrame"> + <argument>-g</argument> + <argument>${site_organism}</argument> + <argument>${bgzip_file.url}</argument> + </application-desc> +</jnlp> + </param> + <param type="template" name="redirect_url" strip="True" > + #if $site_id.startswith( 'local_' ) + ${site_link}?file=${bgzip_file.qp}&genome=${site_organism}&merge=true + #elif $site_id.startswith( 'web_link_' ): + ${site_link}?sessionURL=${bgzip_file.qp}&genome=${site_organism}&merge=true + #else: + ${jnlp.url} + #end if + </param> + </dynamic_links> + + +</display> +<!-- Dan Blankenberg --> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca eggs.ini --- a/eggs.ini +++ b/eggs.ini @@ -12,7 +12,7 @@ no_auto = pbs_python DRMAA_python [eggs:platform] -bx_python = 0.7.0 +bx_python = 0.7.1 Cheetah = 2.2.2 ctypes = 1.0.2 DRMAA_python = 0.2 @@ -67,7 +67,7 @@ psycopg2 = _8.4.2_static pysqlite = _3.6.17_static MySQL_python = _5.1.41_static -bx_python = _494c2d1d68b3_rebuild1 +bx_python = _7b95ff194725 GeneTrack = _dev_48da9e998f0caf01c5be731e926f4b0481f658f0 SQLAlchemy = _dev_r6498 pysam = _kanwei_b10f6e722e9a diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca lib/galaxy/datatypes/binary.py --- a/lib/galaxy/datatypes/binary.py +++ b/lib/galaxy/datatypes/binary.py @@ -26,7 +26,7 @@ """Set the peek and blurb text""" if not dataset.dataset.purged: dataset.peek = 'binary data' - dataset.blurb = 'data' + dataset.blurb = data.nice_size( dataset.get_size() ) else: dataset.peek = 'file does not exist' dataset.blurb = 'file purged from disk' diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca lib/galaxy/datatypes/converters/interval_to_summary_tree_converter.py --- a/lib/galaxy/datatypes/converters/interval_to_summary_tree_converter.py +++ b/lib/galaxy/datatypes/converters/interval_to_summary_tree_converter.py @@ -50,4 +50,4 @@ st.write(out_fname) if __name__ == "__main__": - main() \ No newline at end of file + main() diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca lib/galaxy/datatypes/converters/vcf_bgzip_to_tabix_converter.xml --- /dev/null +++ b/lib/galaxy/datatypes/converters/vcf_bgzip_to_tabix_converter.xml @@ -0,0 +1,14 @@ +<tool id="CONVERTER_vcf_bgzip_to_tabix_0" name="Convert BGZ VCF to tabix" version="1.0.0" hidden="true"> +<!-- <description>__NOT_USED_CURRENTLY_FOR_CONVERTERS__</description> --> + <command interpreter="python">interval_to_tabix_converter.py 'vcf' '' '$input1' '$output1'</command> + <inputs> + <page> + <param format="vcf_bgzip" name="input1" type="data" label="Choose BGZIP'd VCF file"/> + </page> + </inputs> + <outputs> + <data format="tabix" name="output1"/> + </outputs> + <help> + </help> +</tool> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca lib/galaxy/datatypes/converters/vcf_to_vcf_bgzip_converter.xml --- /dev/null +++ b/lib/galaxy/datatypes/converters/vcf_to_vcf_bgzip_converter.xml @@ -0,0 +1,14 @@ +<tool id="CONVERTER_vcf_to_vcf_bgzip_0" name="Convert VCF to VCF_BGZIP" version="1.0.0" hidden="true"> +<!-- <description>__NOT_USED_CURRENTLY_FOR_CONVERTERS__</description> --> + <command interpreter="python">bgzip.py vcf $input1 $output1</command> + <inputs> + <page> + <param format="vcf" name="input1" type="data" label="Choose Vcf file"/> + </page> + </inputs> + <outputs> + <data format="vcf_bgzip" name="output1"/> + </outputs> + <help> + </help> +</tool> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca lib/galaxy/datatypes/registry.py --- a/lib/galaxy/datatypes/registry.py +++ b/lib/galaxy/datatypes/registry.py @@ -46,18 +46,22 @@ try: extension = elem.get( 'extension', None ) dtype = elem.get( 'type', None ) + type_extension = elem.get( 'type_extension', None ) mimetype = elem.get( 'mimetype', None ) display_in_upload = elem.get( 'display_in_upload', False ) make_subclass = galaxy.util.string_as_bool( elem.get( 'subclass', False ) ) - if extension and dtype: - fields = dtype.split( ':' ) - datatype_module = fields[0] - datatype_class_name = fields[1] - fields = datatype_module.split( '.' ) - module = __import__( fields.pop(0) ) - for mod in fields: - module = getattr( module, mod ) - datatype_class = getattr( module, datatype_class_name ) + if extension and ( dtype or type_extension ): + if dtype: + fields = dtype.split( ':' ) + datatype_module = fields[0] + datatype_class_name = fields[1] + fields = datatype_module.split( '.' ) + module = __import__( fields.pop(0) ) + for mod in fields: + module = getattr( module, mod ) + datatype_class = getattr( module, datatype_class_name ) + elif type_extension: + datatype_class = self.datatypes_by_extension[type_extension].__class__ if make_subclass: datatype_class = type( datatype_class_name, (datatype_class,), {} ) self.datatypes_by_extension[extension] = datatype_class() diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca lib/galaxy/jobs/__init__.py --- a/lib/galaxy/jobs/__init__.py +++ b/lib/galaxy/jobs/__init__.py @@ -554,7 +554,7 @@ self.version_string = open(version_filename).read() os.unlink(version_filename) - if self.app.config.outputs_to_working_directory: + if self.app.config.outputs_to_working_directory and not self.__link_file_check(): for dataset_path in self.get_output_fnames(): try: shutil.move( dataset_path.false_path, dataset_path.real_path ) @@ -604,7 +604,7 @@ dataset.blurb = 'done' dataset.peek = 'no peek' - dataset.info = context['stdout'] + context['stderr'] + dataset.info = ( dataset.info or '' ) + context['stdout'] + context['stderr'] dataset.tool_version = self.version_string dataset.set_size() if context['stderr']: @@ -892,6 +892,15 @@ else: return 'anonymous@unknown' + def __link_file_check( self ): + """ outputs_to_working_directory breaks library uploads where data is + linked. This method is a hack that solves that problem, but is + specific to the upload tool and relies on an injected job param. This + method should be removed ASAP and replaced with some properly generic + and stateful way of determining link-only datasets. -nate + """ + return self.tool.id == 'upload1' and self.param_dict.get( 'link_data_only', None ) == 'link_to_files' + def _change_ownership( self, username, gid ): job = self.get_job() # FIXME: hardcoded path diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca lib/galaxy/tools/actions/upload.py --- a/lib/galaxy/tools/actions/upload.py +++ b/lib/galaxy/tools/actions/upload.py @@ -25,4 +25,4 @@ json_file_path = upload_common.create_paramfile( trans, uploaded_datasets ) data_list = [ ud.data for ud in uploaded_datasets ] - return upload_common.create_job( trans, incoming, tool, json_file_path, data_list, return_job=True ) + return upload_common.create_job( trans, incoming, tool, json_file_path, data_list ) diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca lib/galaxy/tools/actions/upload_common.py --- a/lib/galaxy/tools/actions/upload_common.py +++ b/lib/galaxy/tools/actions/upload_common.py @@ -300,7 +300,7 @@ if trans.app.config.drmaa_external_runjob_script: os.chmod(json_file_path, 0777) return json_file_path -def create_job( trans, params, tool, json_file_path, data_list, folder=None, return_job=False ): +def create_job( trans, params, tool, json_file_path, data_list, folder=None ): """ Create the upload job. """ @@ -352,10 +352,7 @@ output = odict() for i, v in enumerate( data_list ): output[ 'output%i' % i ] = v - if return_job: - return job, output - else: - return output + return job, output def active_folders( trans, folder ): # Stolen from galaxy.web.controllers.library_common (importing from which causes a circular issues). # Much faster way of retrieving all active sub-folders within a given folder than the diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca lib/galaxy/tools/parameters/basic.py --- a/lib/galaxy/tools/parameters/basic.py +++ b/lib/galaxy/tools/parameters/basic.py @@ -164,9 +164,14 @@ @classmethod def build( cls, tool, param ): """Factory method to create parameter of correct type""" + param_name = param.get( "name" ) + if not param_name: + raise ValueError( "Tool parameters require a 'name'" ) param_type = param.get("type") - if not param_type or param_type not in parameter_types: - raise ValueError( "Unknown tool parameter type '%s'" % param_type ) + if not param_type: + raise ValueError( "Tool parameter '%s' requires a 'type'" % ( param_name ) ) + elif param_type not in parameter_types: + raise ValueError( "Tool parameter '%s' uses an unknown type '%s'" % ( param_name, param_type ) ) else: return parameter_types[param_type]( tool, param ) diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca lib/galaxy/util/__init__.py --- a/lib/galaxy/util/__init__.py +++ b/lib/galaxy/util/__init__.py @@ -574,11 +574,9 @@ """ Sends an email. """ - header_to = to - if isinstance( to, list ): - header_to = ', '.join( to ) + to = listify( to ) msg = MIMEText( body ) - msg[ 'To' ] = header_to + msg[ 'To' ] = ', '.join( to ) msg[ 'From' ] = frm msg[ 'Subject' ] = subject if config.smtp_server is None: @@ -609,12 +607,10 @@ log.error( "The server didn't accept the username/password combination: %s" % e ) s.close() raise - except smtplib.SMTPError, e: + except smtplib.SMTPException, e: log.error( "No suitable authentication method was found: %s" % e ) s.close() raise - if isinstance( to, basestring ): - to = [ to ] s.sendmail( frm, to, msg.as_string() ) s.quit() diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca lib/galaxy/visualization/tracks/data_providers.py --- a/lib/galaxy/visualization/tracks/data_providers.py +++ b/lib/galaxy/visualization/tracks/data_providers.py @@ -2,14 +2,15 @@ Data providers for tracks visualizations. """ -import sys -from math import ceil, log +import sys, time +from math import ceil, log, sqrt import pkg_resources pkg_resources.require( "bx-python" ) if sys.version_info[:2] == (2, 4): pkg_resources.require( "ctypes" ) pkg_resources.require( "pysam" ) pkg_resources.require( "numpy" ) +import numpy from galaxy.datatypes.util.gff_util import * from galaxy.util.json import from_json_string from bx.interval_index_file import Indexes @@ -362,14 +363,18 @@ for large datasets. """ - def get_iterator( self, chrom, start, end ): + def get_iterator( self, chrom=None, start=None, end=None ): def line_filter_iter(): for line in open( self.original_dataset.file_name ): + if line.startswith( "track" ) or line.startswith( "browser" ): + continue feature = line.split() feature_chrom = feature[0] feature_start = int( feature[1] ) feature_end = int( feature[2] ) - if feature_chrom != chrom or feature_start > int( end ) or feature_end < int( start ): + if ( chrom is not None and feature_chrom != chrom ) \ + or ( start is not None and feature_start > int( end ) ) \ + or ( end is not None and feature_end < int( start ) ): continue yield line return line_filter_iter() @@ -740,40 +745,73 @@ # Bigwig has the possibility of it being a standalone bigwig file, in which case we use # original_dataset, or coming from wig->bigwig conversion in which we use converted_dataset f, bbi = self._get_dataset() - + + # If the stats kwarg was provide, we compute overall summary data for + # the entire chromosome, but no reduced data -- currently only + # providing values used by trackster to determine the default range if 'stats' in kwargs: - all_dat = bbi.query(chrom, 0, 2147483647, 1) + # FIXME: use actual chromosome size + summary = bbi.summarize( chrom, 0, 214783647, 1 ) f.close() - if all_dat is None: + if summary is None: return None - - all_dat = all_dat[0] # only 1 summary - return { 'data' : { 'max': float( all_dat['max'] ), \ - 'min': float( all_dat['min'] ), \ - 'total_frequency': float( all_dat['coverage'] ) } \ - } - + else: + # Does the summary contain any defined values? + valid_count = summary.valid_count[0] + if summary.valid_count < 1: + return None + + # Compute $\mu \pm 2\sigma$ to provide an estimate for upper and lower + # bounds that contain ~95% of the data. + mean = summary.sum_data[0] / valid_count + var = summary.sum_squares[0] - mean + if valid_count > 1: + var /= valid_count - 1 + sd = numpy.sqrt( var ) + + return dict( data=dict( min=summary.min_val[0], max=summary.max_val[0], mean=mean, sd=sd ) ) + start = int(start) end = int(end) + + # The following seems not to work very well, for example it will only return one + # data point if the tile is 1280px wide. Not sure what the intent is. + # The first zoom level for BBI files is 640. If too much is requested, it will look at each block instead # of summaries. The calculation done is: zoom <> (end-start)/num_points/2. # Thus, the optimal number of points is (end-start)/num_points/2 = 640 # num_points = (end-start) / 1280 - num_points = (end-start) / 1280 - if num_points < 1: - num_points = end - start - else: - num_points = min(num_points, 500) + #num_points = (end-start) / 1280 + #if num_points < 1: + # num_points = end - start + #else: + # num_points = min(num_points, 500) - data = bbi.query(chrom, start, end, num_points) + # For now, we'll do 1000 data points by default However, the summaries + # don't seem to work when a summary pixel corresponds to less than one + # datapoint, so we prevent that. + # FIXME: need to switch over to using the full data at high levels of + # detail. + num_points = min( 1000, end - start ) + + summary = bbi.summarize( chrom, start, end, num_points ) f.close() + + result = [] + + if summary: + mean = summary.sum_data / summary.valid_count + + ## Standard deviation by bin, not yet used + ## var = summary.sum_squares - mean + ## var /= minimum( valid_count - 1, 1 ) + ## sd = sqrt( var ) - pos = start - step_size = (end - start) / num_points - result = [] - if data: - for dat_dict in data: - result.append( (pos, float_nan(dat_dict['mean']) ) ) + pos = start + step_size = (end - start) / num_points + + for i in range( num_points ): + result.append( (pos, float_nan( mean[i] ) ) ) pos += step_size return { 'data': result } diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca lib/galaxy/web/api/history_contents.py --- a/lib/galaxy/web/api/history_contents.py +++ b/lib/galaxy/web/api/history_contents.py @@ -50,7 +50,9 @@ """ content_id = id try: - content = self.get_history_dataset_association( trans, content_id, check_ownership=True, check_accessible=True ) + # get the history just for the access checks + history = self.get_history( trans, history_id, check_ownership=True, check_accessible=True, deleted=False ) + content = self.get_history_dataset_association( trans, history, content_id, check_ownership=True, check_accessible=True ) except Exception, e: return str( e ) try: diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca lib/galaxy/web/base/controller.py --- a/lib/galaxy/web/base/controller.py +++ b/lib/galaxy/web/base/controller.py @@ -6,6 +6,7 @@ from time import strftime from galaxy import config, tools, web, util from galaxy.util.hash_util import * +from galaxy.util.json import json_fix from galaxy.web import error, form, url_for from galaxy.model.orm import * from galaxy.workflow.modules import * @@ -19,9 +20,9 @@ from Cheetah.Template import Template - pkg_resources.require( 'elementtree' ) from elementtree import ElementTree, ElementInclude +from elementtree.ElementTree import Element log = logging.getLogger( __name__ ) @@ -233,16 +234,18 @@ else: error( "You are not allowed to access this dataset" ) return data - def get_history_dataset_association( self, trans, dataset_id, check_ownership=True, check_accessible=False ): + def get_history_dataset_association( self, trans, history, dataset_id, check_ownership=True, check_accessible=False ): """Get a HistoryDatasetAssociation from the database by id, verifying ownership.""" - hda = self.get_object( trans, id, 'HistoryDatasetAssociation', check_ownership=check_ownership, check_accessible=check_accessible, deleted=deleted ) - self.security_check( trans, history, check_ownership=check_ownership, check_accessible=False ) # check accessibility here + self.security_check( trans, history, check_ownership=check_ownership, check_accessible=check_accessible ) + hda = self.get_object( trans, dataset_id, 'HistoryDatasetAssociation', check_ownership=False, check_accessible=False, deleted=False ) + if check_accessible: if trans.app.security_agent.can_access_dataset( trans.get_current_user_roles(), hda.dataset ): if hda.state == trans.model.Dataset.states.UPLOAD: error( "Please wait until this dataset finishes uploading before attempting to view it." ) else: error( "You are not allowed to access this dataset" ) + return hda def get_data( self, dataset, preview=True ): """ Gets a dataset's data. """ # Get data from file, truncating if necessary. @@ -1295,6 +1298,9 @@ group_list_grid = None quota_list_grid = None repository_list_grid = None + delete_operation = None + undelete_operation = None + purge_operation = None @web.expose @web.require_admin @@ -2214,6 +2220,13 @@ **kwd ) ) elif operation == "manage roles and groups": return self.manage_roles_and_groups_for_user( trans, **kwd ) + if trans.app.config.allow_user_deletion: + if self.delete_operation not in self.user_list_grid.operations: + self.user_list_grid.operations.append( self.delete_operation ) + if self.undelete_operation not in self.user_list_grid.operations: + self.user_list_grid.operations.append( self.undelete_operation ) + if self.purge_operation not in self.user_list_grid.operations: + self.user_list_grid.operations.append( self.purge_operation ) # Render the list view return self.user_list_grid( trans, **kwd ) @web.expose diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca lib/galaxy/web/controllers/admin.py --- a/lib/galaxy/web/controllers/admin.py +++ b/lib/galaxy/web/controllers/admin.py @@ -3,13 +3,15 @@ from galaxy.model.orm import * from galaxy.web.framework.helpers import time_ago, iff, grids from galaxy.tools.search import ToolBoxSearch -from galaxy.tools import json_fix +from galaxy.tools import ToolSection, json_fix +from galaxy.util import inflector import logging log = logging.getLogger( __name__ ) from galaxy.actions.admin import AdminActions from galaxy.web.params import QuotaParamParser from galaxy.exceptions import * +import galaxy.datatypes.registry class UserListGrid( grids.Grid ): class EmailColumn( grids.TextColumn ): @@ -93,11 +95,6 @@ allow_popup=False, url_args=dict( webapp="galaxy", action="reset_user_password" ) ) ] - #TODO: enhance to account for trans.app.config.allow_user_deletion here so that we can eliminate these operations if - # the setting is False - #operations.append( grids.GridOperation( "Delete", condition=( lambda item: not item.deleted ), allow_multiple=True ) ) - #operations.append( grids.GridOperation( "Undelete", condition=( lambda item: item.deleted and not item.purged ), allow_multiple=True ) ) - #operations.append( grids.GridOperation( "Purge", condition=( lambda item: item.deleted and not item.purged ), allow_multiple=True ) ) standard_filters = [ grids.GridColumnFilter( "Active", args=dict( deleted=False ) ), grids.GridColumnFilter( "Deleted", args=dict( deleted=True, purged=False ) ), @@ -403,7 +400,7 @@ def get_value( self, trans, grid, tool_shed_repository ): return tool_shed_repository.tool_shed # Grid definition - title = "Tool shed repositories" + title = "Installed tool shed repositories" model_class = model.ToolShedRepository template='/admin/tool_shed_repository/grid.mako' default_sort_key = "name" @@ -443,6 +440,9 @@ group_list_grid = GroupListGrid() quota_list_grid = QuotaListGrid() repository_list_grid = RepositoryListGrid() + delete_operation = grids.GridOperation( "Delete", condition=( lambda item: not item.deleted ), allow_multiple=True ) + undelete_operation = grids.GridOperation( "Undelete", condition=( lambda item: item.deleted and not item.purged ), allow_multiple=True ) + purge_operation = grids.GridOperation( "Purge", condition=( lambda item: item.deleted and not item.purged ), allow_multiple=True ) @web.expose @web.require_admin @@ -807,28 +807,45 @@ status = kwd.get( 'status', 'done' ) tool_shed_url = kwd[ 'tool_shed_url' ] repo_info_dict = kwd[ 'repo_info_dict' ] + new_tool_panel_section = kwd.get( 'new_tool_panel_section', '' ) + tool_panel_section = kwd.get( 'tool_panel_section', '' ) if kwd.get( 'select_tool_panel_section_button', False ): shed_tool_conf = kwd[ 'shed_tool_conf' ] # Get the tool path. for k, tool_path in trans.app.toolbox.shed_tool_confs.items(): if k == shed_tool_conf: break - if 'tool_panel_section' in kwd: - section_key = 'section_%s' % kwd[ 'tool_panel_section' ] - tool_section = trans.app.toolbox.tool_panel[ section_key ] + if new_tool_panel_section or tool_panel_section: + if new_tool_panel_section: + section_id = new_tool_panel_section.lower().replace( ' ', '_' ) + new_section_key = 'section_%s' % str( section_id ) + if new_section_key in trans.app.toolbox.tool_panel: + # Appending a tool to an existing section in trans.app.toolbox.tool_panel + log.debug( "Appending to tool panel section: %s" % new_tool_panel_section ) + tool_section = trans.app.toolbox.tool_panel[ new_section_key ] + else: + # Appending a new section to trans.app.toolbox.tool_panel + log.debug( "Loading new tool panel section: %s" % new_tool_panel_section ) + elem = Element( 'section' ) + elem.attrib[ 'name' ] = new_tool_panel_section + elem.attrib[ 'id' ] = section_id + tool_section = ToolSection( elem ) + trans.app.toolbox.tool_panel[ new_section_key ] = tool_section + else: + section_key = 'section_%s' % tool_panel_section + tool_section = trans.app.toolbox.tool_panel[ section_key ] # Decode the encoded repo_info_dict param value. repo_info_dict = tool_shed_decode( repo_info_dict ) # Clone the repository to the configured location. current_working_dir = os.getcwd() + installed_repository_names = [] for name, repo_info_tuple in repo_info_dict.items(): description, repository_clone_url, changeset_revision = repo_info_tuple clone_dir = os.path.join( tool_path, self.__generate_tool_path( repository_clone_url, changeset_revision ) ) if os.path.exists( clone_dir ): # Repository and revision has already been cloned. # TODO: implement the ability to re-install or revert an existing repository. - message += 'Revision <b>%s</b> of repository <b>%s</b> has already been installed. Updating an existing repository is not yet supported.<br/>' % \ - ( changeset_revision, name ) - status = 'error' + message += 'Revision <b>%s</b> of repository <b>%s</b> was previously installed.<br/>' % ( changeset_revision, name ) else: os.makedirs( clone_dir ) log.debug( 'Cloning %s...' % repository_clone_url ) @@ -856,6 +873,10 @@ os.chdir( current_working_dir ) tmp_stderr.close() if returncode == 0: + # Load data types required by tools. + # TODO: uncomment the following when we're ready... + #self.__load_datatypes( trans, repo_files_dir ) + # Load tools and tool data files required by them. sample_files, repository_tools_tups = self.__get_repository_tools_and_sample_files( trans, tool_path, repo_files_dir ) if repository_tools_tups: # Handle missing data table entries for tool parameters that are dynamically generated select lists. @@ -892,9 +913,7 @@ if trans.app.toolbox_search.enabled: # If search support for tools is enabled, index the new installed tools. trans.app.toolbox_search = ToolBoxSearch( trans.app.toolbox ) - message += 'Revision <b>%s</b> of repository <b>%s</b> has been loaded into tool panel section <b>%s</b>.<br/>' % \ - ( changeset_revision, name, tool_section.name ) - #return trans.show_ok_message( message ) + installed_repository_names.append( name ) else: tmp_stderr = open( tmp_name, 'rb' ) message += '%s<br/>' % tmp_stderr.read() @@ -905,6 +924,20 @@ message += '%s<br/>' % tmp_stderr.read() tmp_stderr.close() status = 'error' + if installed_repository_names: + installed_repository_names.sort() + num_repositories_installed = len( installed_repository_names ) + message += 'Installed %d %s and all tools were loaded into tool panel section <b>%s</b>:<br/>Installed repositories: ' % \ + ( num_repositories_installed, inflector.cond_plural( num_repositories_installed, 'repository' ), tool_section.name ) + for i, repo_name in enumerate( installed_repository_names ): + if i == len( installed_repository_names ) -1: + message += '%s.<br/>' % repo_name + else: + message += '%s, ' % repo_name + return trans.response.send_redirect( web.url_for( controller='admin', + action='browse_tool_shed_repositories', + message=message, + status=status ) ) else: message = 'Choose the section in your tool panel to contain the installed tools.' status = 'error' @@ -921,6 +954,7 @@ shed_tool_conf=shed_tool_conf, shed_tool_conf_select_field=shed_tool_conf_select_field, tool_panel_section_select_field=tool_panel_section_select_field, + new_tool_panel_section=new_tool_panel_section, message=message, status=status ) @web.expose @@ -1144,24 +1178,62 @@ error = tmp_stderr.read() tmp_stderr.close() log.debug( 'Problem installing dependencies for tool "%s"\n%s' % ( repository_tool.name, error ) ) + def __load_datatypes( self, trans, repo_files_dir ): + # Find datatypes_conf.xml if it exists. + datatypes_config = None + for root, dirs, files in os.walk( repo_files_dir ): + if root.find( '.hg' ) < 0: + for name in files: + if name == 'datatypes_conf.xml': + datatypes_config = os.path.abspath( os.path.join( root, name ) ) + break + if datatypes_config: + # Parse datatypes_config. + tree = ElementTree.parse( datatypes_config ) + root = tree.getroot() + ElementInclude.include( root ) + datatype_files = root.find( 'datatype_files' ) + for elem in datatype_files.findall( 'datatype_file' ): + datatype_file_name = elem.get( 'name', None ) + if datatype_file_name: + # Find the file in the installed repository. + relative_path = None + for root, dirs, files in os.walk( repo_files_dir ): + if root.find( '.hg' ) < 0: + for name in files: + if name == datatype_file_name: + relative_path = os.path.join( root, name ) + break + relative_head, relative_tail = os.path.split( relative_path ) + # TODO: get the import_module by parsing the <registration><datatype> tags + if datatype_file_name.find( '.' ) > 0: + import_module = datatype_file_name.split( '.' )[ 0 ] + else: + import_module = datatype_file_name + try: + sys.path.insert( 0, relative_head ) + module = __import__( import_module ) + sys.path.pop( 0 ) + except Exception, e: + log.debug( "Execption importing datatypes code file included in installed repository: %s" % str( e ) ) + trans.app.datatypes_registry = galaxy.datatypes.registry.Registry( trans.app.config.root, datatypes_config ) def __get_repository_tools_and_sample_files( self, trans, tool_path, repo_files_dir ): # The sample_files list contains all files whose name ends in .sample sample_files = [] + # Find all special .sample files first. + for root, dirs, files in os.walk( repo_files_dir ): + if root.find( '.hg' ) < 0: + for name in files: + if name.endswith( '.sample' ): + sample_files.append( os.path.abspath( os.path.join( root, name ) ) ) # The repository_tools_tups list contains tuples of ( relative_path_to_tool_config, tool ) pairs repository_tools_tups = [] for root, dirs, files in os.walk( repo_files_dir ): - if not root.find( '.hg' ) >= 0 and not root.find( 'hgrc' ) >= 0: + if root.find( '.hg' ) < 0 and root.find( 'hgrc' ) < 0: if '.hg' in dirs: - # Don't visit .hg directories - should be impossible since we don't - # allow uploaded archives that contain .hg dirs, but just in case... dirs.remove( '.hg' ) if 'hgrc' in files: - # Don't include hgrc files in commit. files.remove( 'hgrc' ) - # Find all special .sample files first. - for name in files: - if name.endswith( '.sample' ): - sample_files.append( os.path.abspath( os.path.join( root, name ) ) ) for name in files: # Find all tool configs. if name.endswith( '.xml' ): diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca lib/galaxy/web/controllers/async.py --- a/lib/galaxy/web/controllers/async.py +++ b/lib/galaxy/web/controllers/async.py @@ -67,7 +67,7 @@ trans.log_event( 'Async executing tool %s' % tool.id, tool_id=tool.id ) galaxy_url = trans.request.base + '/async/%s/%s/%s' % ( tool_id, data.id, key ) galaxy_url = params.get("GALAXY_URL",galaxy_url) - params = dict( url=URL, GALAXY_URL=galaxy_url ) + params = dict( URL=URL, GALAXY_URL=galaxy_url, name=data.name, info=data.info, dbkey=data.dbkey, data_type=data.ext ) # Assume there is exactly one output file possible params[tool.outputs.keys()[0]] = data.id tool.execute( trans, incoming=params ) @@ -80,20 +80,20 @@ trans.sa_session.flush() return "Data %s with status %s received. OK" % (data_id, STATUS) - - # - # no data_id must be parameter submission - # - if not data_id and len(params)>3: - - if params.galaxyFileFormat == 'wig': + else: + # + # no data_id must be parameter submission + # + if params.data_type: + GALAXY_TYPE = params.data_type + elif params.galaxyFileFormat == 'wig': #this is an undocumented legacy special case GALAXY_TYPE = 'wig' else: - GALAXY_TYPE = params.GALAXY_TYPE or 'interval' + GALAXY_TYPE = params.GALAXY_TYPE or tool.outputs.values()[0].format - GALAXY_NAME = params.GALAXY_NAME or '%s query' % tool.name - GALAXY_INFO = params.GALAXY_INFO or params.galaxyDescription or '' - GALAXY_BUILD = params.GALAXY_BUILD or params.galaxyFreeze or 'hg17' + GALAXY_NAME = params.name or params.GALAXY_NAME or '%s query' % tool.name + GALAXY_INFO = params.info or params.GALAXY_INFO or params.galaxyDescription or '' + GALAXY_BUILD = params.dbkey or params.GALAXY_BUILD or params.galaxyFreeze or '?' #data = datatypes.factory(ext=GALAXY_TYPE)() #data.ext = GALAXY_TYPE diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca lib/galaxy/web/controllers/dataset.py --- a/lib/galaxy/web/controllers/dataset.py +++ b/lib/galaxy/web/controllers/dataset.py @@ -806,7 +806,11 @@ #in case some display app wants all files to be in the same 'directory', #data can be forced to param, but not the other way (no filename for other direction) #get param name from url param name - action_param = display_link.get_param_name_by_url( action_param ) + try: + action_param = display_link.get_param_name_by_url( action_param ) + except ValueError, e: + log.debug( e ) + return paste.httpexceptions.HTTPNotFound( str( e ) ) value = display_link.get_param_value( action_param ) assert value, "An invalid parameter name was provided: %s" % action_param assert value.parameter.viewable, "This parameter is not viewable." diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca lib/galaxy/web/controllers/library_common.py --- a/lib/galaxy/web/controllers/library_common.py +++ b/lib/galaxy/web/controllers/library_common.py @@ -1045,7 +1045,12 @@ status='error' ) ) json_file_path = upload_common.create_paramfile( trans, uploaded_datasets ) data_list = [ ud.data for ud in uploaded_datasets ] - return upload_common.create_job( trans, tool_params, tool, json_file_path, data_list, folder=library_bunch.folder ) + job, output = upload_common.create_job( trans, tool_params, tool, json_file_path, data_list, folder=library_bunch.folder ) + # HACK: Prevent outputs_to_working_directory from overwriting inputs when "linking" + job.add_parameter( 'link_data_only', to_json_string( kwd.get( 'link_data_only', 'copy_files' ) ) ) + trans.sa_session.add( job ) + trans.sa_session.flush() + return output def make_library_uploaded_dataset( self, trans, cntrller, params, name, path, type, library_bunch, in_folder=None ): library_bunch.replace_dataset = None # not valid for these types of upload uploaded_dataset = util.bunch.Bunch() @@ -1855,7 +1860,7 @@ status=status ) @web.expose - def import_datasets_to_histories( self, trans, cntrller, library_id='', folder_id='', ldda_ids='', target_history_ids='', new_history_name='', **kwd ): + def import_datasets_to_histories( self, trans, cntrller, library_id='', folder_id='', ldda_ids='', target_history_id='', target_history_ids='', new_history_name='', **kwd ): # This method is called from one of the following places: # - a menu option for a library dataset ( ldda_ids is a single ldda id ) # - a menu option for a library folder ( folder_id has a value ) @@ -1870,7 +1875,6 @@ action = params.get( 'do_action', None ) user = trans.get_user() current_history = trans.get_history() - selected_history_id = params.get( 'selected_history_id', trans.security.encode_id( current_history.id ) ) if library_id: library = trans.sa_session.query( trans.model.Library ).get( trans.security.decode_id( library_id ) ) else: @@ -1882,9 +1886,11 @@ ldda_ids = util.listify( ldda_ids ) if ldda_ids: ldda_ids = map( trans.security.decode_id, ldda_ids ) - target_history_ids = util.listify( target_history_ids ) if target_history_ids: - target_history_ids = [ trans.security.decode_id( target_history_id ) for target_history_id in target_history_ids if target_history_id ] + target_history_ids = util.listify( target_history_ids ) + target_history_ids = set( [ trans.security.decode_id( target_history_id ) for target_history_id in target_history_ids if target_history_id ] ) + elif target_history_id: + target_history_ids = [ trans.security.decode_id( target_history_id ) ] if params.get( 'import_datasets_to_histories_button', False ): invalid_datasets = 0 if not ldda_ids or not ( target_history_ids or new_history_name ): @@ -1965,7 +1971,7 @@ library=library, current_history=current_history, ldda_ids=ldda_ids, - selected_history_id=selected_history_id, + target_history_id=target_history_id, target_history_ids=target_history_ids, source_lddas=source_lddas, target_histories=target_histories, diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca lib/galaxy/web/controllers/tracks.py --- a/lib/galaxy/web/controllers/tracks.py +++ b/lib/galaxy/web/controllers/tracks.py @@ -13,7 +13,7 @@ from galaxy.web.framework import simplejson from galaxy.web.framework.helpers import time_ago, grids from galaxy.util.bunch import Bunch -from galaxy.datatypes.interval import Gff +from galaxy.datatypes.interval import Gff, Bed from galaxy.model import NoConverterException, ConverterDependencyException from galaxy.visualization.tracks.data_providers import * from galaxy.visualization.tracks.visual_analytics import get_tool_def, get_dataset_job @@ -246,6 +246,27 @@ "tool": get_tool_def( trans, dataset ) } return track + + @web.json + def bookmarks_from_dataset( self, trans, hda_id=None, ldda_id=None ): + if hda_id: + hda_ldda = "hda" + dataset = self.get_dataset( trans, hda_id, check_ownership=False, check_accessible=True ) + elif ldda_id: + hda_ldda = "ldda" + dataset = trans.sa_session.query( trans.app.model.LibraryDatasetDatasetAssociation ).get( trans.security.decode_id( ldda_id ) ) + rows = [] + if isinstance( dataset.datatype, Bed ): + data = RawBedDataProvider( original_dataset=dataset ).get_iterator() + for i, line in enumerate( data ): + if ( i > 500 ): break + fields = line.split() + location = name = "%s:%s-%s" % ( fields[0], fields[1], fields[2] ) + if len( fields ) > 3: + name = fields[4] + rows.append( [location, name] ) + return { 'data': rows } + @web.expose @web.require_login() @@ -528,6 +549,7 @@ if not standalone_provider.has_data( chrom ): return messages.NO_DATA valid_chroms = standalone_provider.valid_chroms() + # Have data if we get here return { "status": messages.DATA, "valid_chroms": valid_chroms } @@ -1041,4 +1063,4 @@ return_message = message elif return_message == None and message == messages.PENDING: return_message = message - return return_message \ No newline at end of file + return return_message diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca lib/galaxy/web/controllers/user.py --- a/lib/galaxy/web/controllers/user.py +++ b/lib/galaxy/web/controllers/user.py @@ -753,7 +753,7 @@ password = kwd.get( 'password', '' ) confirm = kwd.get( 'confirm', '' ) ok = True - if not webapp == 'galaxy' and not is_admin: + if not is_admin: # If the current user is changing their own password, validate their current password current = kwd.get( 'current', '' ) if not trans.user.check_password( current ): @@ -768,10 +768,17 @@ else: # Save new password user.set_password_cleartext( password ) + # Invalidate all other sessions + for other_galaxy_session in trans.sa_session.query( trans.app.model.GalaxySession ) \ + .filter( and_( trans.app.model.GalaxySession.table.c.user_id==trans.user.id, + trans.app.model.GalaxySession.table.c.is_valid==True, + trans.app.model.GalaxySession.table.c.id!=trans.galaxy_session.id ) ): + other_galaxy_session.is_valid = False + trans.sa_session.add( other_galaxy_session ) trans.sa_session.add( user ) trans.sa_session.flush() trans.log_event( "User change password" ) - message = 'The password has been changed.' + message = 'The password has been changed and any other existing Galaxy sessions have been logged out (but jobs in histories in those sessions will not be interrupted).' elif user and params.get( 'edit_user_info_button', False ): # Edit user information - webapp MUST BE 'galaxy' user_type_fd_id = params.get( 'user_type_fd_id', 'none' ) diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca lib/galaxy/web/controllers/workflow.py --- a/lib/galaxy/web/controllers/workflow.py +++ b/lib/galaxy/web/controllers/workflow.py @@ -149,7 +149,8 @@ # Legacy issue: all shared workflows must have slugs. slug_set = False for workflow_assoc in shared_by_others: - slug_set = self.create_item_slug( trans.sa_session, workflow_assoc.stored_workflow ) + if self.create_item_slug( trans.sa_session, workflow_assoc.stored_workflow ): + slug_set = True if slug_set: trans.sa_session.flush() @@ -1115,10 +1116,10 @@ workflow_name = tool_shed_decode( workflow_name ) # The following parameters will have a value only if the import originated # from a tool shed repository installed locally. - local_file = kwd.get( 'local_file', '' ) + installed_repository_file = kwd.get( 'installed_repository_file', '' ) repository_id = kwd.get( 'repository_id', '' ) - if local_file and not import_button: - workflow_file = open( local_file, 'rb' ) + if installed_repository_file and not import_button: + workflow_file = open( installed_repository_file, 'rb' ) workflow_text = workflow_file.read() workflow_file.close() import_button = True @@ -1197,27 +1198,26 @@ if shed_url.endswith( '/' ): shed_url = shed_url.rstrip( '/' ) url = '%s/repository/find_tools?galaxy_url=%s&webapp=%s' % ( shed_url, trans.request.host, webapp ) + if missing_tool_tups: + url += '&tool_id=' for missing_tool_tup in missing_tool_tups: missing_tool_id = missing_tool_tup[0] - url += '&tool_id=%s' % missing_tool_id + url += '%s,' % missing_tool_id message += '<a href="%s">%s</a><br/>' % ( url, shed_name ) status = 'error' - if local_file or tool_shed_url: + if installed_repository_file or tool_shed_url: # Another Galaxy panels Hack: The request did not originate from the Galaxy # workflow view, so we don't need to render the Galaxy panels. - return trans.response.send_redirect( web.url_for( controller='admin', - action='center', - webapp='galaxy', - message=message, - status=status ) ) + action = 'center' else: # Another Galaxy panels hack: The request originated from the Galaxy # workflow view, so we need to render the Galaxy panels. - return trans.response.send_redirect( web.url_for( controller='admin', - action='index', - webapp='galaxy', - message=message, - status=status ) ) + action = 'index' + return trans.response.send_redirect( web.url_for( controller='admin', + action=action, + webapp='galaxy', + message=message, + status=status ) ) else: # TODO: Figure out what to do here... pass @@ -1228,7 +1228,7 @@ url = 'http://%s/workflow/view_workflow?repository_metadata_id=%s&workflow_name=%s&webapp=%s&message=%s' % \ ( tool_shed_url, repository_metadata_id, tool_shed_encode( workflow_name ), webapp, message ) return trans.response.send_redirect( url ) - elif local_file: + elif installed_repository_file: # The workflow was read from a file included with an installed tool shed repository. message = "Workflow <b>%s</b> imported successfully." % workflow.name return trans.response.send_redirect( web.url_for( controller='admin', diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca lib/galaxy/webapps/community/config.py --- a/lib/galaxy/webapps/community/config.py +++ b/lib/galaxy/webapps/community/config.py @@ -61,6 +61,7 @@ self.remote_user_logout_href = kwargs.get( "remote_user_logout_href", None ) self.require_login = string_as_bool( kwargs.get( "require_login", "False" ) ) self.allow_user_creation = string_as_bool( kwargs.get( "allow_user_creation", "True" ) ) + self.allow_user_deletion = string_as_bool( kwargs.get( "allow_user_deletion", "False" ) ) self.enable_openid = string_as_bool( kwargs.get( 'enable_openid', False ) ) self.template_path = resolve_path( kwargs.get( "template_path", "templates" ), self.root ) self.template_cache = resolve_path( kwargs.get( "template_cache_path", "database/compiled_templates/community" ), self.root ) diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca lib/galaxy/webapps/community/controllers/common.py --- a/lib/galaxy/webapps/community/controllers/common.py +++ b/lib/galaxy/webapps/community/controllers/common.py @@ -26,6 +26,8 @@ Change description: ${description} +${content_alert_str} + ----------------------------------------------------------------------------- This change alert was sent from the Galaxy tool shed hosted on the server "${host}" @@ -124,34 +126,6 @@ .filter( trans.model.RepositoryMetadata.table.c.repository_id == trans.security.decode_id( id ) ) \ .order_by( trans.model.RepositoryMetadata.table.c.id.desc() ) \ .first() -def generate_workflow_metadata( trans, id, changeset_revision, exported_workflow_dict, metadata_dict ): - """ - Update the received metadata_dict with changes that have been applied - to the received exported_workflow_dict. Store everything in the database. - """ - if 'workflows' in metadata_dict: - metadata_dict[ 'workflows' ].append( exported_workflow_dict ) - else: - metadata_dict[ 'workflows' ] = [ exported_workflow_dict ] - return metadata_dict -def new_workflow_metadata_required( trans, id, metadata_dict ): - """ - Currently everything about an exported workflow except the name is hard-coded, so there's - no real way to differentiate versions of exported workflows. If this changes at some future - time, this method should be enhanced accordingly. - """ - if 'workflows' in metadata_dict: - repository_metadata = get_latest_repository_metadata( trans, id ) - if repository_metadata: - if repository_metadata.metadata: - # The repository has metadata, so update the workflows value - no new record is needed. - return False - else: - # There is no saved repository metadata, so we need to create a new repository_metadata table record. - return True - # The received metadata_dict includes no metadata for workflows, so a new repository_metadata table - # record is not needed. - return False def generate_clone_url( trans, repository_id ): repository = get_repository( trans, repository_id ) protocol, base = trans.request.base.split( '://' ) @@ -214,7 +188,8 @@ copy_sample_loc_file( trans, sample_file ) options.index_file = index_tail options.missing_index_file = None - options.tool_data_table.missing_index_file = None + if options.tool_data_table: + options.tool_data_table.missing_index_file = None sample_found = True break if not sample_found: @@ -312,6 +287,62 @@ # The received metadata_dict includes no metadata for tools, so a new repository_metadata table # record is not needed. return False +def generate_workflow_metadata( trans, id, changeset_revision, exported_workflow_dict, metadata_dict ): + """ + Update the received metadata_dict with changes that have been applied + to the received exported_workflow_dict. Store everything in the database. + """ + if 'workflows' in metadata_dict: + metadata_dict[ 'workflows' ].append( exported_workflow_dict ) + else: + metadata_dict[ 'workflows' ] = [ exported_workflow_dict ] + return metadata_dict +def new_workflow_metadata_required( trans, id, metadata_dict ): + """ + Currently everything about an exported workflow except the name is hard-coded, so there's + no real way to differentiate versions of exported workflows. If this changes at some future + time, this method should be enhanced accordingly. + """ + if 'workflows' in metadata_dict: + repository_metadata = get_latest_repository_metadata( trans, id ) + if repository_metadata: + if repository_metadata.metadata: + # The repository has metadata, so update the workflows value - no new record is needed. + return False + else: + # There is no saved repository metadata, so we need to create a new repository_metadata table record. + return True + # The received metadata_dict includes no metadata for workflows, so a new repository_metadata table + # record is not needed. + return False +def generate_datatypes_metadata( trans, id, changeset_revision, datatypes_config, metadata_dict ): + """ + Update the received metadata_dict with changes that have been applied + to the received datatypes_config. + """ + # Parse datatypes_config. + tree = ElementTree.parse( datatypes_config ) + root = tree.getroot() + ElementInclude.include( root ) + repository_datatype_code_files = [] + datatype_files = root.find( 'datatype_files' ) + if datatype_files: + for elem in datatype_files.findall( 'datatype_file' ): + name = elem.get( 'name', None ) + repository_datatype_code_files.append( name ) + metadata_dict[ 'datatype_files' ] = repository_datatype_code_files + datatypes = [] + registration = root.find( 'registration' ) + if registration: + for elem in registration.findall( 'datatype' ): + extension = elem.get( 'extension', None ) + dtype = elem.get( 'type', None ) + mimetype = elem.get( 'mimetype', None ) + datatypes.append( dict( extension=extension, + dtype=dtype, + mimetype=mimetype ) ) + metadata_dict[ 'datatypes' ] = datatypes + return metadata_dict def set_repository_metadata( trans, id, changeset_revision, **kwd ): """Set repository metadata""" message = '' @@ -321,37 +352,47 @@ repo = hg.repository( get_configured_ui(), repo_dir ) invalid_files = [] sample_files = [] + datatypes_config = None ctx = get_changectx_for_changeset( trans, repo, changeset_revision ) if ctx is not None: metadata_dict = {} if changeset_revision == repository.tip: + # Find datatypes_conf.xml if it exists. for root, dirs, files in os.walk( repo_dir ): - if not root.find( '.hg' ) >= 0 and not root.find( 'hgrc' ) >= 0: - if '.hg' in dirs: - # Don't visit .hg directories - should be impossible since we don't - # allow uploaded archives that contain .hg dirs, but just in case... - dirs.remove( '.hg' ) - if 'hgrc' in files: - # Don't include hgrc files in commit. - files.remove( 'hgrc' ) - # Find all special .sample files first. + if root.find( '.hg' ) < 0: + for name in files: + if name == 'datatypes_conf.xml': + datatypes_config = os.path.abspath( os.path.join( root, name ) ) + break + if datatypes_config: + metadata_dict = generate_datatypes_metadata( trans, id, changeset_revision, datatypes_config, metadata_dict ) + # Find all special .sample files. + for root, dirs, files in os.walk( repo_dir ): + if root.find( '.hg' ) < 0: for name in files: if name.endswith( '.sample' ): sample_files.append( os.path.abspath( os.path.join( root, name ) ) ) + # Find all tool configs and exported workflows. + for root, dirs, files in os.walk( repo_dir ): + if root.find( '.hg' ) < 0 and root.find( 'hgrc' ) < 0: + if '.hg' in dirs: + dirs.remove( '.hg' ) for name in files: # Find all tool configs. - if name.endswith( '.xml' ): + if name != 'datatypes_conf.xml' and name.endswith( '.xml' ): + full_path = os.path.abspath( os.path.join( root, name ) ) try: - full_path = os.path.abspath( os.path.join( root, name ) ) tool = load_tool( trans, full_path ) - if tool is not None: - can_set_metadata, invalid_files = check_tool_input_params( trans, name, tool, sample_files, invalid_files ) - if can_set_metadata: - # Update the list of metadata dictionaries for tools in metadata_dict. - tool_config = os.path.join( root, name ) - metadata_dict = generate_tool_metadata( trans, id, changeset_revision, tool_config, tool, metadata_dict ) + valid = True except Exception, e: + valid = False invalid_files.append( ( name, str( e ) ) ) + if valid and tool is not None: + can_set_metadata, invalid_files = check_tool_input_params( trans, name, tool, sample_files, invalid_files ) + if can_set_metadata: + # Update the list of metadata dictionaries for tools in metadata_dict. + tool_config = os.path.join( root, name ) + metadata_dict = generate_tool_metadata( trans, id, changeset_revision, tool_config, tool, metadata_dict ) # Find all exported workflows elif name.endswith( '.ga' ): try: @@ -370,11 +411,13 @@ # Find all special .sample files first. for filename in ctx: if filename.endswith( '.sample' ): - sample_files.append( os.path.abspath( os.path.join( root, filename ) ) ) + sample_files.append( os.path.abspath( filename ) ) # Get all tool config file names from the hgweb url, something like: # /repos/test/convert_chars1/file/e58dcf0026c7/convert_characters.xml for filename in ctx: - # Find all tool configs - should not have to update metadata for workflows for now. + # Find all tool configs - we do not have to update metadata for workflows or datatypes in anything + # but repository tips (handled above) since at the time this code was written, no workflows or + # dataytpes_conf.xml files exist in tool shed repositories, so they can only be added in future tips. if filename.endswith( '.xml' ): fctx = ctx[ filename ] # Write the contents of the old tool config to a temporary file. @@ -386,17 +429,19 @@ fh.close() try: tool = load_tool( trans, tmp_filename ) - if tool is not None: - can_set_metadata, invalid_files = check_tool_input_params( trans, filename, tool, sample_files, invalid_files ) - if can_set_metadata: - # Update the list of metadata dictionaries for tools in metadata_dict. Note that filename - # here is the relative path to the config file within the change set context, something - # like filtering.xml, but when the change set was the repository tip, the value was - # something like database/community_files/000/repo_1/filtering.xml. This shouldn't break - # anything, but may result in a bit of confusion when maintaining the code / data over time. - metadata_dict = generate_tool_metadata( trans, id, changeset_revision, filename, tool, metadata_dict ) + valid = True except Exception, e: - invalid_files.append( ( name, str( e ) ) ) + invalid_files.append( ( filename, str( e ) ) ) + valid = False + if valid and tool is not None: + can_set_metadata, invalid_files = check_tool_input_params( trans, filename, tool, sample_files, invalid_files ) + if can_set_metadata: + # Update the list of metadata dictionaries for tools in metadata_dict. Note that filename + # here is the relative path to the config file within the change set context, something + # like filtering.xml, but when the change set was the repository tip, the value was + # something like database/community_files/000/repo_1/filtering.xml. This shouldn't break + # anything, but may result in a bit of confusion when maintaining the code / data over time. + metadata_dict = generate_tool_metadata( trans, id, changeset_revision, filename, tool, metadata_dict ) try: os.unlink( tmp_filename ) except: @@ -481,7 +526,7 @@ def get_user( trans, id ): """Get a user from the database by id""" return trans.sa_session.query( trans.model.User ).get( trans.security.decode_id( id ) ) -def handle_email_alerts( trans, repository ): +def handle_email_alerts( trans, repository, content_alert_str='' ): repo_dir = repository.repo_path repo = hg.repository( get_configured_ui(), repo_dir ) smtp_server = trans.app.config.smtp_server @@ -502,14 +547,25 @@ username = ctx.user().split()[0] except: username = ctx.user() - # Build the email message + # We'll use 2 template bodies because we only want to send content + # alerts to tool shed admin users. + admin_body = string.Template( email_alert_template ) \ + .safe_substitute( host=trans.request.host, + repository_name=repository.name, + revision='%s:%s' %( str( ctx.rev() ), ctx ), + display_date=display_date, + description=ctx.description(), + username=username, + content_alert_str=content_alert_str ) body = string.Template( email_alert_template ) \ .safe_substitute( host=trans.request.host, repository_name=repository.name, revision='%s:%s' %( str( ctx.rev() ), ctx ), display_date=display_date, description=ctx.description(), - username=username ) + username=username, + content_alert_str='' ) + admin_users = trans.app.config.get( "admin_users", "" ).split( "," ) frm = email_from subject = "Galaxy tool shed repository update alert" email_alerts = from_json_string( repository.email_alerts ) @@ -517,9 +573,23 @@ to = email.strip() # Send it try: - util.send_mail( frm, to, subject, body, trans.app.config ) + if to in admin_users: + util.send_mail( frm, to, subject, admin_body, trans.app.config ) + else: + util.send_mail( frm, to, subject, body, trans.app.config ) except Exception, e: log.exception( "An error occurred sending a tool shed repository update alert by email." ) +def check_file_contents( trans ): + # See if any admin users have chosen to receive email alerts when a repository is updated. + # If so, the file contents of the update must be checked for inappropriate content. + admin_users = trans.app.config.get( "admin_users", "" ).split( "," ) + for repository in trans.sa_session.query( trans.model.Repository ) \ + .filter( trans.model.Repository.table.c.email_alerts != None ): + email_alerts = from_json_string( repository.email_alerts ) + for user_email in email_alerts: + if user_email in admin_users: + return True + return False def update_for_browsing( trans, repository, current_working_dir, commit_message='' ): # Make a copy of a repository's files for browsing, remove from disk all files that # are not tracked, and commit all added, modified or removed files that have not yet @@ -528,12 +598,10 @@ repo = hg.repository( get_configured_ui(), repo_dir ) # The following will delete the disk copy of only the files in the repository. #os.system( 'hg update -r null > /dev/null 2>&1' ) - repo.ui.pushbuffer() - commands.status( repo.ui, repo, all=True ) - status_and_file_names = repo.ui.popbuffer().strip().split( "\n" ) - # status_and_file_names looks something like: - # ['? README', '? tmap_tool/tmap-0.0.9.tar.gz', '? dna_filtering.py', 'C filtering.py', 'C filtering.xml'] - # The codes used to show the status of files are: + files_to_remove_from_disk = [] + files_to_commit = [] + # We may have files on disk in the repo directory that aren't being tracked, so they must be removed. + # The codes used to show the status of files are as follows. # M = modified # A = added # R = removed @@ -541,37 +609,50 @@ # ! = deleted, but still tracked # ? = not tracked # I = ignored - files_to_remove_from_disk = [] - files_to_commit = [] - for status_and_file_name in status_and_file_names: - if status_and_file_name.startswith( '?' ) or status_and_file_name.startswith( 'I' ): - files_to_remove_from_disk.append( os.path.abspath( os.path.join( repo_dir, status_and_file_name.split()[1] ) ) ) - elif status_and_file_name.startswith( 'M' ) or status_and_file_name.startswith( 'A' ) or status_and_file_name.startswith( 'R' ): - files_to_commit.append( os.path.abspath( os.path.join( repo_dir, status_and_file_name.split()[1] ) ) ) - for full_path in files_to_remove_from_disk: - # We'll remove all files that are not tracked or ignored. - if os.path.isdir( full_path ): - try: - os.rmdir( full_path ) - except OSError, e: - # The directory is not empty - pass - elif os.path.isfile( full_path ): - os.remove( full_path ) - dir = os.path.split( full_path )[0] - try: - os.rmdir( dir ) - except OSError, e: - # The directory is not empty - pass + # We'll use mercurial's purge extension to remove untracked file. Using this extension requires the + # following entry in the repository's hgrc file which was not required for some time, so we'll add it + # if it's missing. + # [extensions] + # hgext.purge= + lines = repo.opener( 'hgrc', 'rb' ).readlines() + if not '[extensions]\n' in lines: + # No extensions have been added at all, so just append to the file. + fp = repo.opener( 'hgrc', 'a' ) + fp.write( '[extensions]\n' ) + fp.write( 'hgext.purge=\n' ) + fp.close() + elif not 'hgext.purge=\n' in lines: + # The file includes and [extensions] section, but we need to add the + # purge extension. + fp = repo.opener( 'hgrc', 'wb' ) + for line in lines: + if line.startswith( '[extensions]' ): + fp.write( line ) + fp.write( 'hgext.purge=\n' ) + else: + fp.write( line ) + fp.close() + cmd = 'hg purge' + os.chdir( repo_dir ) + proc = subprocess.Popen( args=cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT ) + return_code = proc.wait() + os.chdir( current_working_dir ) + if return_code != 0: + output = proc.stdout.read( 32768 ) + log.debug( 'hg purge failed in repository directory %s, reason: %s' % ( repo_dir, output ) ) if files_to_commit: if not commit_message: commit_message = 'Committed changes to: %s' % ', '.join( files_to_commit ) repo.dirstate.write() repo.commit( user=trans.user.username, text=commit_message ) + cmd = 'hg update > /dev/null 2>&1' os.chdir( repo_dir ) - os.system( 'hg update > /dev/null 2>&1' ) + proc = subprocess.Popen( args=cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT ) + return_code = proc.wait() os.chdir( current_working_dir ) + if return_code != 0: + output = proc.stdout.read( 32768 ) + log.debug( 'hg update > /dev/null 2>&1 failed in repository directory %s, reason: %s' % ( repo_dir, output ) ) def load_tool( trans, config_file ): """ Load a single tool from the file named by `config_file` and return diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca lib/galaxy/webapps/community/controllers/repository.py --- a/lib/galaxy/webapps/community/controllers/repository.py +++ b/lib/galaxy/webapps/community/controllers/repository.py @@ -1,4 +1,4 @@ -import os, logging, urllib, ConfigParser, tempfile, shutil +import os, logging, tempfile, shutil from time import strftime from datetime import date, datetime from galaxy import util @@ -236,7 +236,7 @@ template='/webapps/community/repository/grid.mako' default_sort_key = "Repository.name" columns = [ - NameColumn( "Name", + NameColumn( "Repository name", link=( lambda item: dict( operation="view_or_manage_repository", id=item.id, webapp="community" ) ), @@ -588,17 +588,17 @@ match_tuples.append( ( repository_metadata.repository_id, repository_metadata.changeset_revision ) ) else: ok = False - if workflow_names: + elif workflow_names: if 'workflows' in metadata: workflows = metadata[ 'workflows' ] else: workflows = [] for workflow_dict in workflows: for workflow_name in workflow_names: - if self.__in_workflow_dict( workflow_dict, exact_matches_checked, workflow_name=workflow_name ): + if self.__in_workflow_dict( workflow_dict, exact_matches_checked, workflow_name ): match_tuples.append( ( repository_metadata.repository_id, repository_metadata.changeset_revision ) ) return ok, match_tuples - def __in_workflow_dict( self, workflow_dict, exact_matches_checked, workflow_name=None ): + def __in_workflow_dict( self, workflow_dict, exact_matches_checked, workflow_name ): workflow_dict_workflow_name = workflow_dict[ 'name' ].lower() return ( workflow_name == workflow_dict_workflow_name ) or \ ( not exact_matches_checked and workflow_dict_workflow_name.find( workflow_name ) >= 0 ) @@ -773,7 +773,7 @@ tool_guids = [] for filename in ctx: # Find all tool configs in this repository changeset_revision. - if filename.endswith( '.xml' ): + if filename != 'datatypes_conf.xml' and filename.endswith( '.xml' ): fctx = ctx[ filename ] # Write the contents of the old tool config to a temporary file. fh = tempfile.NamedTemporaryFile( 'w' ) @@ -784,11 +784,11 @@ fh.close() try: tool = load_tool( trans, tmp_filename ) - if tool is not None: - tool_guids.append( generate_tool_guid( trans, repository, tool ) ) + valid = True except: - # File must not be a valid tool config even though it has a .xml extension. - pass + valid = False + if valid and tool is not None: + tool_guids.append( generate_tool_guid( trans, repository, tool ) ) try: os.unlink( tmp_filename ) except: @@ -1001,20 +1001,25 @@ hgweb_config_copy = '%s/hgweb.config_%s_backup' % ( trans.app.config.root, backup_date ) shutil.copy( os.path.abspath( hgweb_config ), os.path.abspath( hgweb_config_copy ) ) def __add_hgweb_config_entry( self, trans, repository, repository_path ): - # Add an entry in the hgweb.config file for a new repository. - # An entry looks something like: + # Add an entry in the hgweb.config file for a new repository. An entry looks something like: # repos/test/mira_assembler = database/community_files/000/repo_123. hgweb_config = "%s/hgweb.config" % trans.app.config.root - # Make a backup of the hgweb.config file since we're going to be changing it. - self.__make_hgweb_config_copy( trans, hgweb_config ) + if repository_path.startswith( './' ): + repository_path = repository_path.replace( './', '', 1 ) entry = "repos/%s/%s = %s" % ( repository.user.username, repository.name, repository_path.lstrip( './' ) ) + tmp_fd, tmp_fname = tempfile.mkstemp() if os.path.exists( hgweb_config ): - output = open( hgweb_config, 'a' ) + # Make a backup of the hgweb.config file since we're going to be changing it. + self.__make_hgweb_config_copy( trans, hgweb_config ) + new_hgweb_config = open( tmp_fname, 'wb' ) + for i, line in enumerate( open( hgweb_config ) ): + new_hgweb_config.write( line ) else: - output = open( hgweb_config, 'w' ) - output.write( '[paths]\n' ) - output.write( "%s\n" % entry ) - output.close() + new_hgweb_config = open( tmp_fname, 'wb' ) + new_hgweb_config.write( '[paths]\n' ) + new_hgweb_config.write( "%s\n" % entry ) + new_hgweb_config.flush() + shutil.move( tmp_fname, os.path.abspath( hgweb_config ) ) def __change_hgweb_config_entry( self, trans, repository, old_repository_name, new_repository_name ): # Change an entry in the hgweb.config file for a repository. This only happens when # the owner changes the name of the repository. An entry looks something like: @@ -1024,7 +1029,6 @@ self.__make_hgweb_config_copy( trans, hgweb_config ) repo_dir = repository.repo_path old_lhs = "repos/%s/%s" % ( repository.user.username, old_repository_name ) - old_entry = "%s = %s" % ( old_lhs, repo_dir ) new_entry = "repos/%s/%s = %s\n" % ( repository.user.username, new_repository_name, repo_dir ) tmp_fd, tmp_fname = tempfile.mkstemp() new_hgweb_config = open( tmp_fname, 'wb' ) @@ -1033,17 +1037,16 @@ new_hgweb_config.write( new_entry ) else: new_hgweb_config.write( line ) + new_hgweb_config.flush() shutil.move( tmp_fname, os.path.abspath( hgweb_config ) ) def __create_hgrc_file( self, repository ): # At this point, an entry for the repository is required to be in the hgweb.config # file so we can call repository.repo_path. - # Create a .hg/hgrc file that looks something like this: - # [web] - # allow_push = test - # name = convert_characters1 - # push_ssl = False # Since we support both http and https, we set push_ssl to False to override # the default (which is True) in the mercurial api. + # The hg purge extension purges all files and directories not being tracked by + # mercurial in the current repository. It'll remove unknown files and empty + # directories. This is used in the update_for_browsing() method. repo = hg.repository( get_configured_ui(), path=repository.repo_path ) fp = repo.opener( 'hgrc', 'wb' ) fp.write( '[paths]\n' ) @@ -1053,6 +1056,8 @@ fp.write( 'allow_push = %s\n' % repository.user.username ) fp.write( 'name = %s\n' % repository.name ) fp.write( 'push_ssl = false\n' ) + fp.write( '[extensions]\n' ) + fp.write( 'hgext.purge=' ) fp.close() @web.expose def browse_repository( self, trans, id, **kwd ): @@ -1145,7 +1150,7 @@ tip = repository.tip for selected_file in selected_files_to_delete: try: - commands.remove( repo.ui, repo, repo_file, force=True ) + commands.remove( repo.ui, repo, selected_file, force=True ) except Exception, e: # I never have a problem with commands.remove on a Mac, but in the test/production # tool shed environment, it throws an exception whenever I delete all files from a @@ -1306,7 +1311,7 @@ if params.get( 'edit_repository_button', False ): flush_needed = False # TODO: add a can_manage in the security agent. - if user != repository.user: + if user != repository.user or not trans.user_is_admin(): message = "You are not the owner of this repository, so you cannot manage it." status = error return trans.response.send_redirect( web.url_for( controller='repository', @@ -1315,6 +1320,12 @@ webapp='community', message=message, status=status ) ) + if description != repository.description: + repository.description = description + flush_needed = True + if long_description != repository.long_description: + repository.long_description = long_description + flush_needed = True if repo_name != repository.name: message = self.__validate_repository_name( repo_name, user ) if message: @@ -1323,12 +1334,6 @@ self.__change_hgweb_config_entry( trans, repository, repository.name, repo_name ) repository.name = repo_name flush_needed = True - if description != repository.description: - repository.description = description - flush_needed = True - if long_description != repository.long_description: - repository.long_description = long_description - flush_needed = True if flush_needed: trans.sa_session.add( repository ) trans.sa_session.flush() @@ -1609,39 +1614,49 @@ status = params.get( 'status', 'done' ) webapp = params.get( 'webapp', 'community' ) repository = get_repository( trans, repository_id ) - repo = hg.repository( get_configured_ui(), repository.repo_path ) + repo = hg.repository( get_configured_ui(), repository.repo_path ) + valid = True + if changeset_revision == repository.tip: + try: + tool = load_tool( trans, os.path.abspath( tool_config ) ) + except Exception, e: + tool = None + valid = False + message = "Error loading tool: %s. Clicking <b>Reset metadata</b> may correct this error." % str( e ) + else: + # Get the tool config file name from the hgweb url, something like: + # /repos/test/convert_chars1/file/e58dcf0026c7/convert_characters.xml + old_tool_config_file_name = tool_config.split( '/' )[ -1 ] + ctx = get_changectx_for_changeset( trans, repo, changeset_revision ) + fctx = None + for filename in ctx: + filename_head, filename_tail = os.path.split( filename ) + if filename_tail == old_tool_config_file_name: + fctx = ctx[ filename ] + break + if fctx: + # Write the contents of the old tool config to a temporary file. + fh = tempfile.NamedTemporaryFile( 'w' ) + tmp_filename = fh.name + fh.close() + fh = open( tmp_filename, 'w' ) + fh.write( fctx.data() ) + fh.close() + try: + tool = load_tool( trans, tmp_filename ) + except Exception, e: + tool = None + valid = False + message = "Error loading tool: %s. Clicking <b>Reset metadata</b> may correct this error." % str( e ) + try: + os.unlink( tmp_filename ) + except: + pass + else: + tool = None + tool_state = self.__new_state( trans ) + is_malicious = change_set_is_malicious( trans, repository_id, repository.tip ) try: - if changeset_revision == repository.tip: - # Get the tool config from the file system we use for browsing. - tool = load_tool( trans, os.path.abspath( tool_config ) ) - else: - # Get the tool config file name from the hgweb url, something like: - # /repos/test/convert_chars1/file/e58dcf0026c7/convert_characters.xml - old_tool_config_file_name = tool_config.split( '/' )[ -1 ] - ctx = get_changectx_for_changeset( trans, repo, changeset_revision ) - fctx = None - for filename in ctx: - filename_head, filename_tail = os.path.split( filename ) - if filename_tail == old_tool_config_file_name: - fctx = ctx[ filename ] - break - if fctx: - # Write the contents of the old tool config to a temporary file. - fh = tempfile.NamedTemporaryFile( 'w' ) - tmp_filename = fh.name - fh.close() - fh = open( tmp_filename, 'w' ) - fh.write( fctx.data() ) - fh.close() - tool = load_tool( trans, tmp_filename ) - try: - os.unlink( tmp_filename ) - except: - pass - else: - tool = None - tool_state = self.__new_state( trans ) - is_malicious = change_set_is_malicious( trans, repository_id, repository.tip ) return trans.fill_template( "/webapps/community/repository/tool_form.mako", repository=repository, changeset_revision=changeset_revision, @@ -1652,7 +1667,7 @@ message=message, status=status ) except Exception, e: - message = "Error loading tool: %s. Click <b>Reset metadata</b> to correct this error." % str( e ) + message = "Error displaying tool, probably due to a problem in the tool config. The exception is: %s." % str( e ) if webapp == 'galaxy': return trans.response.send_redirect( web.url_for( controller='repository', action='preview_tools_in_changeset', diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca lib/galaxy/webapps/community/controllers/upload.py --- a/lib/galaxy/webapps/community/controllers/upload.py +++ b/lib/galaxy/webapps/community/controllers/upload.py @@ -1,4 +1,4 @@ -import sys, os, shutil, logging, tarfile, tempfile +import sys, os, shutil, logging, tarfile, tempfile, urllib from galaxy.web.base.controller import * from galaxy.model.orm import * from galaxy.datatypes.checkers import * @@ -11,9 +11,6 @@ SUCCESS, INFO, WARNING, ERROR = "done", "info", "warning", "error" CHUNK_SIZE = 2**20 # 1Mb -class UploadError( Exception ): - pass - class UploadController( BaseUIController ): @web.expose @web.require_login( 'upload', use_panels=True, webapp='community' ) @@ -32,20 +29,40 @@ remove_repo_files_not_in_tar = util.string_as_bool( params.get( 'remove_repo_files_not_in_tar', 'true' ) ) uploaded_file = None upload_point = self.__get_upload_point( repository, **kwd ) - # Get the current repository tip. tip = repository.tip + file_data = params.get( 'file_data', '' ) + url = params.get( 'url', '' ) if params.get( 'upload_button', False ): current_working_dir = os.getcwd() - file_data = params.get( 'file_data', '' ) - if file_data == '': + if file_data == '' and url == '': message = 'No files were entered on the upload form.' status = 'error' uploaded_file = None + elif url: + valid_url = True + try: + stream = urllib.urlopen( url ) + except Exception, e: + valid_url = False + message = 'Error uploading file via http: %s' % str( e ) + status = 'error' + uploaded_file = None + if valid_url: + fd, uploaded_file_name = tempfile.mkstemp() + uploaded_file = open( uploaded_file_name, 'wb' ) + while 1: + chunk = stream.read( CHUNK_SIZE ) + if not chunk: + break + uploaded_file.write( chunk ) + uploaded_file.flush() + uploaded_file_filename = url.split( '/' )[ -1 ] + isempty = os.path.getsize( os.path.abspath( uploaded_file_name ) ) == 0 elif file_data not in ( '', None ): uploaded_file = file_data.file uploaded_file_name = uploaded_file.name uploaded_file_filename = file_data.filename - isempty = os.path.getsize( os.path.abspath( uploaded_file_name ) ) == 0 + isempty = os.path.getsize( os.path.abspath( uploaded_file_name ) ) == 0 if uploaded_file: isgzip = False isbz2 = False @@ -86,6 +103,13 @@ full_path = os.path.abspath( os.path.join( repo_dir, uploaded_file_filename ) ) # Move the uploaded file to the load_point within the repository hierarchy. shutil.move( uploaded_file_name, full_path ) + # See if any admin users have chosen to receive email alerts when a repository is + # updated. If so, check every uploaded file to ensure content is appropriate. + check_contents = check_file_contents( trans ) + if check_contents and os.path.isfile( full_path ): + content_alert_str = self.__check_file_content( full_path ) + else: + content_alert_str = '' commands.add( repo.ui, repo, full_path ) try: commands.commit( repo.ui, repo, full_path, user=trans.user.username, message=commit_message ) @@ -107,7 +131,7 @@ # Handle the special case where a xxx.loc.sample file is # being uploaded by copying it to ~/tool-data/xxx.loc. copy_sample_loc_file( trans, full_path ) - handle_email_alerts( trans, repository ) + handle_email_alerts( trans, repository, content_alert_str=content_alert_str ) if ok: # Update the repository files for browsing. update_for_browsing( trans, repository, current_working_dir, commit_message=commit_message ) @@ -146,6 +170,7 @@ selected_categories = [ trans.security.decode_id( id ) for id in category_ids ] return trans.fill_template( '/webapps/community/repository/upload.mako', repository=repository, + url=url, commit_message=commit_message, uncompress_file=uncompress_file, remove_repo_files_not_in_tar=remove_repo_files_not_in_tar, @@ -172,6 +197,7 @@ tar.extractall( path=full_path ) tar.close() uploaded_file.close() + content_alert_str = '' if remove_repo_files_not_in_tar and not repository.is_new: # We have a repository that is not new (it contains files), so discover # those files that are in the repository, but not in the uploaded archive. @@ -215,7 +241,13 @@ except OSError, e: # The directory is not empty pass + # See if any admin users have chosen to receive email alerts when a repository is + # updated. If so, check every uploaded file to ensure content is appropriate. + check_contents = check_file_contents( trans ) for filename_in_archive in filenames_in_archive: + # Check file content to ensure it is appropriate. + if check_contents and os.path.isfile( filename_in_archive ): + content_alert_str += self.__check_file_content( filename_in_archive ) commands.add( repo.ui, repo, filename_in_archive ) if filename_in_archive.endswith( 'tool_data_table_conf.xml.sample' ): # Handle the special case where a tool_data_table_conf.xml.sample @@ -237,7 +269,7 @@ # exception. If this happens, we'll try the following. repo.dirstate.write() repo.commit( user=trans.user.username, text=commit_message ) - handle_email_alerts( trans, repository ) + handle_email_alerts( trans, repository, content_alert_str ) return True, '', files_to_remove def uncompress( self, repository, uploaded_file_name, uploaded_file_filename, isgzip, isbz2 ): if isgzip: @@ -314,4 +346,10 @@ message = "Uploaded archives cannot contain hgrc files." return False, message return True, '' - + def __check_file_content( self, file_path ): + message = '' + if check_html( file_path ): + message = 'The file "%s" contains HTML content.\n' % str( file_path ) + elif check_image( file_path ): + message = 'The file "%s" contains image content.\n' % str( file_path ) + return message diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca lib/galaxy/webapps/demo_sequencer/config.py --- a/lib/galaxy/webapps/demo_sequencer/config.py +++ b/lib/galaxy/webapps/demo_sequencer/config.py @@ -40,6 +40,7 @@ self.remote_user_logout_href = kwargs.get( "remote_user_logout_href", None ) self.require_login = string_as_bool( kwargs.get( "require_login", "False" ) ) self.allow_user_creation = string_as_bool( kwargs.get( "allow_user_creation", "True" ) ) + self.allow_user_deletion = string_as_bool( kwargs.get( "allow_user_deletion", "False" ) ) self.template_path = resolve_path( kwargs.get( "template_path", "templates" ), self.root ) self.template_cache = resolve_path( kwargs.get( "template_cache_path", "database/compiled_templates/demo_sequencer" ), self.root ) self.admin_users = kwargs.get( "admin_users", "" ) diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca lib/galaxy/webapps/reports/config.py --- a/lib/galaxy/webapps/reports/config.py +++ b/lib/galaxy/webapps/reports/config.py @@ -31,6 +31,8 @@ self.template_path = resolve_path( kwargs.get( "template_path", "templates" ), self.root ) self.template_cache = resolve_path( kwargs.get( "template_cache_path", "database/compiled_templates/reports" ), self.root ) self.sendmail_path = kwargs.get('sendmail_path',"/usr/sbin/sendmail") + self.allow_user_creation = string_as_bool( kwargs.get( "allow_user_creation", "True" ) ) + self.allow_user_deletion = string_as_bool( kwargs.get( "allow_user_deletion", "False" ) ) self.log_actions = string_as_bool( kwargs.get( 'log_actions', 'False' ) ) self.brand = kwargs.get( 'brand', None ) self.wiki_url = kwargs.get( 'wiki_url', 'http://wiki.g2.bx.psu.edu/FrontPage' ) diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca locale/zh/LC_MESSAGES/ginga.mo Binary file locale/zh/LC_MESSAGES/ginga.mo has changed diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca locale/zh/LC_MESSAGES/ginga.po --- /dev/null +++ b/locale/zh/LC_MESSAGES/ginga.po @@ -0,0 +1,597 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: yinhe 1.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-10-15 13:58+0800\n" +"PO-Revision-Date: 2011-11-04 19:13+0900\n" +"Last-Translator: Hanfei Sun <hfsun.tju@gmail.com> Juan Wang <jinling8@gmail.com>\n" +"Language-Team: Chinese\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: +msgid "iso-8859-1" +msgstr "utf-8" + +#: +msgid "lang=\"en\"" +msgstr "lang=\"zh\"" + + +#: templates/base_panels.mako:5 +msgid "Galaxy" +msgstr "Galaxy" + +#: templates/history/options.mako:24 +msgid "Are you sure you want to delete the current history?" +msgstr "确认要删除当前的历史记录吗?" + + +#: templates/root/history.mako:38 +msgid "collapse all" +msgstr "全部收缩" + + +#: templates/root/index.mako:5 +msgid "Tools" +msgstr "工具" + + +#: tools/**.xml +msgid "Get Data" +msgstr "获取数据" + +msgid "Get ENCODE Data" +msgstr "获取ENCODE数据" + +msgid "ENCODE Tools" +msgstr "ENCODE工具" + +msgid "Lift-Over" +msgstr "版本转换" + + +msgid "Text Manipulation" +msgstr "文本操作" + +msgid "Filter and Sort" +msgstr "过滤和排序" + +msgid "Join, Subtract and Group" +msgstr "结合,差集与分组" + +msgid "Convert Formats" +msgstr "格式转换" + +msgid "Extract Features" +msgstr "特征提取" + +msgid "Fetch Sequences" +msgstr "获取序列" + +msgid "Fetch Alignments" +msgstr "获取比对上的序列" + +msgid "Get Genomic Scores" +msgstr "获得基因组分数" + +msgid "Operate on Genomic Intervals" +msgstr "基因组区间操作" + +msgid "Statistics" +msgstr "统计量" + +msgid "Graph/Display Data" +msgstr "图形/数据" + +msgid "Regional Variation" +msgstr "区域多态性" + +msgid "Evolution: HyPhy" +msgstr "进化: HyPhy" + +msgid "Taxonomy manipulation" +msgstr "分类处理" + +msgid "Solexa tools" +msgstr "Solexa工具" + +msgid "FASTA manipulation" +msgstr "FASTA处理" + +msgid "Short Read QC and Manipulation" +msgstr "短片段数据质量控制及处理" + +msgid "Short Read Mapping" +msgstr "短片段回贴" + + +#: templates/admin_main.mako:3 templates/admin_main.mako:8 +msgid "Galaxy Administration" +msgstr "Galaxy 管理" + +#: templates/admin_main.mako:17 +msgid "Admin password: " +msgstr "管理员密码: " + +#: templates/admin_main.mako:19 +msgid "Reload tool: " +msgstr "重新载入工具" + +#: templates/admin_main.mako:35 +msgid "Reload" +msgstr "重新载入" + +#: templates/dataset/edit_attributes.mako:2 +msgid "History Item Attributes" +msgstr "历史项目属性" + +#: templates/dataset/edit_attributes.mako:19 +msgid "Edit Attributes" +msgstr "编辑属性" + +#: templates/dataset/edit_attributes.mako:64 +msgid "" +"This will inspect the dataset and attempt to correct the above column values " +"if they are not accurate." +msgstr "数据集检查,若有错误,更正上述栏中的值。" + +#: templates/dataset/edit_attributes.mako:68 +msgid "" +"Required metadata values are missing. Some of these values may not be " +"editable by the user. Selecting \"Auto-detect\" will attempt to fix these " +"values." +msgstr "所需元数据值缺失。其中一些值可能无法被用户编辑。选择“自动检测”将修正这些值。" + +#: templates/dataset/edit_attributes.mako:78 +msgid "Convert to new format" +msgstr "转换成新格式" + +#: templates/dataset/edit_attributes.mako:84 +msgid "Convert to" +msgstr "转换" + +#: templates/dataset/edit_attributes.mako:95 +msgid "" +"This will create a new dataset with the contents of this dataset converted " +"to a new format." +msgstr "这将创建一个新的数据集,内容是转换后的数据集。" + +#: templates/dataset/edit_attributes.mako:111 +msgid "Change data type" +msgstr "改变数据类型" + +#: templates/dataset/edit_attributes.mako:117 +msgid "New Type" +msgstr "新类型" + +#: templates/dataset/edit_attributes.mako:124 +msgid "" +"This will change the datatype of the existing dataset but <i>not</i> modify " +"its contents. Use this if Galaxy has incorrectly guessed the type of your " +"dataset." +msgstr "这将改变已有数据集的数据类型,但是<i>不</i>改变其内容。当Galaxy不能正确判断你的数据类型时,设置该参数。" + +#: templates/dataset/edit_attributes.mako:137 +msgid "Copy History Item" +msgstr "复制历史记录项" + +#: templates/history/list.mako:3 +msgid "Saved Histories" +msgstr "保存的历史记录" + +#: templates/history/list.mako:19 +msgid "Stored Histories" +msgstr "存储的历史记录" + +#: templates/history/list.mako:21 templates/root/history.mako:239 +msgid "hide deleted" +msgstr "隐藏已删除" + +#: templates/history/list.mako:23 +msgid "show deleted" +msgstr "显示已删除" + +#: templates/history/list.mako:27 +msgid "Name" +msgstr "名称" + +#: templates/history/list.mako:27 +msgid "Size" +msgstr "大小" + +#: templates/history/list.mako:27 +msgid "Last modified" +msgstr "最后修改" + +#: templates/history/list.mako:27 +msgid "Actions" +msgstr "操作" + +#: templates/history/list.mako:45 +msgid "rename" +msgstr "重命名" + +#: templates/history/list.mako:46 +msgid "switch to" +msgstr "切换到" + +#: templates/history/list.mako:47 +msgid "delete" +msgstr "删除" + +#: templates/history/list.mako:49 +msgid "undelete" +msgstr "取消删除" + +#: templates/history/list.mako:55 +msgid "Action" +msgstr "操作" + +#: templates/history/list.mako:56 templates/history/options.mako:21 +msgid "Share" +msgstr "共享" + +#: templates/history/list.mako:56 templates/history/options.mako:15 +msgid "Rename" +msgstr "重命名" + +#: templates/history/list.mako:56 templates/history/options.mako:24 +msgid "Delete" +msgstr "删除" + +#: templates/history/list.mako:58 +msgid "Undelete" +msgstr "取消删除" + +#: templates/history/list.mako:65 +msgid "You have no stored histories" +msgstr "没有存储的历史记录" + +#: templates/history/options.mako:5 +msgid "History Options" +msgstr "历史记录选项" + +#: templates/history/options.mako:9 +msgid "You must be " +msgstr "你必须" + +#: templates/history/options.mako:9 +msgid "logged in" +msgstr "登录" + +#: templates/history/options.mako:9 +msgid " to store or switch histories." +msgstr "以存储或切换历史记录" + +#: templates/history/options.mako:15 +#, python-format +msgid " current history (stored as \"%s\")" +msgstr " 当前历史(以\"%s\"形式存储)" + +#: templates/history/options.mako:16 +msgid "List" +msgstr "列表" + +#: templates/history/options.mako:16 +msgid " previously stored histories" +msgstr " 以前存储的历史记录" + +#: templates/history/options.mako:18 +msgid "Create" +msgstr "创建" + +#: templates/history/options.mako:18 +msgid " a new empty history" +msgstr " 一个新的空历史记录" + +#: templates/history/options.mako:20 +msgid "Construct workflow" +msgstr "构建工作流程" + +#: templates/history/options.mako:20 +msgid " from the current history" +msgstr " 来源于当前历史" + +#: templates/history/options.mako:21 templates/history/options.mako:24 +msgid " current history" +msgstr " 当前历史" + +#: templates/history/options.mako:23 +msgid "Show deleted" +msgstr "显示已删除" + +#: templates/history/options.mako:23 +msgid " datasets in history" +msgstr " 历史中的数据集" + +#: templates/history/rename.mako:3 templates/history/rename.mako:6 +msgid "Rename History" +msgstr "重命名历史" + + +msgid "Rename Histories" +msgstr "重命名历史记录" + +msgid "Perform Action" +msgstr "运行操作" + +msgid "Submit" +msgstr "提交" + + + +#: templates/history/rename.mako:10 +msgid "Current Name" +msgstr "当前名称" + +#: templates/history/rename.mako:10 +msgid "New Name" +msgstr "新名称" + +#: templates/history/share.mako:3 +msgid "Share histories" +msgstr "共享历史记录" + +#: templates/history/share.mako:6 +msgid "Share Histories" +msgstr "共享历史记录" + +#: templates/history/share.mako:9 +msgid "History Name:" +msgstr "历史名称" + +#: templates/history/share.mako:9 +msgid "Number of Datasets:" +msgstr "数据集数量" + +#: templates/history/share.mako:9 +msgid "Share Link" +msgstr "共享链接" + +#: templates/history/share.mako:15 +msgid "This history contains no data." +msgstr "这项历史中没有数据" + +#: templates/history/share.mako:21 +msgid "copy link to share" +msgstr "复制链接以共享" + +#: templates/history/share.mako:24 +msgid "Email of User to share with:" +msgstr "发送到这些Email地址进行分享" + +#: templates/root/history.mako:7 +msgid "Galaxy History" +msgstr "Galaxy 历史" + +#: templates/root/history.mako:237 +msgid "refresh" +msgstr "刷新" + +#: templates/root/history.mako:245 +msgid "You are currently viewing a deleted history!" +msgstr "正在查看已删除的历史" + +#: templates/root/history.mako:289 +msgid "Your history is empty. Click 'Get Data' on the left pane to start" +msgstr "历史已空,请单击左边窗格中‘获取数据’" + +#: templates/root/history_common.mako:41 +msgid "Job is waiting to run" +msgstr "等待运行的进程" + +#: templates/root/history_common.mako:43 +msgid "Job is currently running" +msgstr "正在运行的进程" + +#: templates/root/history_common.mako:46 +msgid "An error occurred running this job: " +msgstr "进程运行时出错 " + +#: templates/root/history_common.mako:47 +msgid "report this error" +msgstr "报告错误" + +#: templates/root/history_common.mako:54 +msgid "No data: " +msgstr "没有数据: " + +#: templates/root/history_common.mako:58 +msgid "format: " +msgstr "格式: " + +#: templates/root/history_common.mako:59 +msgid "database: " +msgstr "数据库: " + +#: templates/root/history_common.mako:66 templates/root/masthead.mako:20 +msgid "Info: " +msgstr "信息: " + +#: templates/root/history_common.mako:85 +#, python-format +msgid "Error: unknown dataset state \"%s\"." +msgstr "错误:未知的数据集状态 \"%s\"。" + + +msgid "Options" +msgstr "选项" + +msgid "History" +msgstr "历史" + +#: templates/root/masthead.mako:20 +msgid "report bugs" +msgstr "错误报告" + +#: templates/root/masthead.mako:21 +msgid "wiki" +msgstr "wiki" + +#: templates/root/masthead.mako:22 +msgid "screencasts" +msgstr "演示视频" + + +#: templates/root/masthead.mako:23 +msgid "blog" +msgstr "博客" + +#: templates/root/masthead.mako:31 +#, python-format +msgid "Logged in as %s: " +msgstr "以%s的身份登录: " + +#: templates/root/masthead.mako:31 +msgid "manage" +msgstr "管理" + +#: templates/root/masthead.mako:32 +msgid "logout" +msgstr "注销" + +#: templates/root/masthead.mako:34 +msgid "Account: " +msgstr "帐户: " + +#: templates/root/masthead.mako:34 +msgid "create" +msgstr "创建" + +#: templates/root/masthead.mako:35 +msgid "login" +msgstr "登录" + +#: templates/root/tool_menu.mako:52 +msgid "Galaxy Tools" +msgstr "Galaxy 工具" + +#: templates/root/tool_menu.mako:129 +msgid "Workflow" +msgstr "工作流程" + +#: templates/root/tool_menu.mako:134 +msgid "Manage" +msgstr "管理" + +#: templates/root/tool_menu.mako:134 +msgid "workflows" +msgstr "工作流程" + +#: templates/user/index.mako:2 templates/user/index.mako:4 +msgid "Account settings" +msgstr "帐户设置" + +#: templates/user/index.mako:7 +#, python-format +msgid "You are currently logged in as %s." +msgstr "当前以%s的身份登录" + +#: templates/user/index.mako:9 +msgid "Change your password" +msgstr "修改密码" + +#: templates/user/index.mako:10 +msgid "Update your email address" +msgstr "更新电子邮件地址" + +#: templates/user/index.mako:11 +msgid "Logout" +msgstr "注销" + +#: templates/user/index.mako:16 +msgid "Login" +msgstr "登录" + +#: templates/user/index.mako:17 +msgid "Create new account" +msgstr "创建新帐户" + +msgid "Show Tool Search" +msgstr "显示工具搜索" + +msgid "Analyze Data" +msgstr "分析数据" + +msgid "analysis" +msgstr "分析" + +msgid "History Lists" +msgstr "历史记录清单" + +msgid "Histories Shared with Me" +msgstr "共享的数据" + +msgid "Current History" +msgstr "当前历史记录" + +msgid "Create New" +msgstr "创建" + +msgid "Clone" +msgstr "复制" + +msgid "Share or Publish" +msgstr "共享或发布" + +msgid "Extract Workflow" +msgstr "提取工作流程" + +msgid "Dataset Security" +msgstr "数据安全性" + + +msgid "Show Deleted Datasets" +msgstr "显示已删除数据" + +msgid "Show Hidden Datasets" +msgstr "显示隐藏数据" + +msgid "Show Structure" +msgstr "显示结构" + +msgid "Export to File" +msgstr "导出为文件" + +msgid "Other Actions" +msgstr "其他" + +msgid "Import from File" +msgstr "导入文件" + +msgid "Shared Data" +msgstr "数据共享" + +msgid "Data Libraries" +msgstr "数据仓库" + +msgid "Published Histories" +msgstr "已发布的历史记录" + +msgid "Published Workflows" +msgstr "已发布的工作流程" + +msgid "Published Pages" +msgstr "已发布的页面" + +msgid "Help" +msgstr "帮助" + +msgid "Email comments, bug reports, or suggestions" +msgstr "发邮件进行意见反馈或错误报告" + + +msgid "User" +msgstr "用户" + + +msgid "Register" +msgstr "注册" \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca locale/zh/LC_MESSAGES/tools.mo Binary file locale/zh/LC_MESSAGES/tools.mo has changed diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca locale/zh/LC_MESSAGES/tools.po --- /dev/null +++ b/locale/zh/LC_MESSAGES/tools.po @@ -0,0 +1,84 @@ +# Japanese translations for PROJECT. +# Copyright (C) 2009 ORGANIZATION +# This file is distributed under the same license as the PROJECT project. +# FIRST AUTHOR <EMAIL@ADDRESS>, 2009. +# +msgid "" +msgstr "" +"Project-Id-Version: PROJECT VERSION\n" +"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" +"POT-Creation-Date: 2009-03-17 04:06-0400\n" +"PO-Revision-Date: 2009-03-17 04:06-0400\n" +"Last-Translator: Hanfei Sun <hfsun.tju@gmail.com>\n" +"Language-Team: zh <hfsun.tju@gmail.com>\n" +"Plural-Forms: nplurals=1; plural=0\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 0.9.4\n" + +msgid "Get Data" +msgstr "获取数据" + +msgid "Get ENCODE Data" +msgstr "" + +msgid "ENCODE Tools" +msgstr "" + +msgid "Lift-Over" +msgstr "" + +msgid "Text Manipulation" +msgstr "" + +msgid "Filter and Sort" +msgstr "" + +msgid "Join, Subtract and Group" +msgstr "" + +msgid "Convert Formats" +msgstr "" + +msgid "Extract Features" +msgstr "" + +msgid "Fetch Sequences" +msgstr "" + +msgid "Fetch Alignments" +msgstr "" + +msgid "Get Genomic Scores" +msgstr "" + +msgid "Operate on Genomic Intervals" +msgstr "" + +msgid "Statistics" +msgstr "" + +msgid "Graph/Display Data" +msgstr "" + +msgid "Regional Variation" +msgstr "" + +msgid "Evolution: HyPhy" +msgstr "" + +msgid "Taxonomy manipulation" +msgstr "" + +msgid "Solexa tools" +msgstr "" + +msgid "FASTA manipulation" +msgstr "" + +msgid "Short Read QC and Manipulation" +msgstr "" + +msgid "Short Read Mapping" +msgstr "" diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca run.sh --- a/run.sh +++ b/run.sh @@ -15,6 +15,7 @@ tool_sheds_conf.xml.sample universe_wsgi.ini.sample tool-data/shared/ucsc/builds.txt.sample + tool-data/shared/igv/igv_build_sites.txt.sample tool-data/*.sample static/welcome.html.sample " diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca static/images/fugue/chevron-expand-bw.png Binary file static/images/fugue/chevron-expand-bw.png has changed diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca static/images/fugue/toggle-bw.png Binary file static/images/fugue/toggle-bw.png has changed diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca static/images/fugue/toggle-expand-bw.png Binary file static/images/fugue/toggle-expand-bw.png has changed diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca static/june_2007_style/base.css.tmpl --- a/static/june_2007_style/base.css.tmpl +++ b/static/june_2007_style/base.css.tmpl @@ -231,6 +231,10 @@ padding: 3px 0 0 1em; } +.form-row .help { + color: #666; +} + select, input, textarea { font: inherit; } @@ -865,10 +869,6 @@ -sprite-group: fugue; -sprite-image: fugue/toggle.png; } -.icon-button.toggle-contract { - -sprite-group: fugue; - -sprite-image: fugue/toggle.png; -} .icon-button.arrow-circle { -sprite-group: fugue; -sprite-image: fugue/arrow-circle.png; @@ -905,6 +905,14 @@ -sprite-group: fugue; -sprite-image: fugue/plus-circle.png; } +.icon-button.plus-button { + -sprite-group: fugue; + -sprite-image: fugue/plus-button.png; +} +.icon-button.gear { + -sprite-group: fugue; + -sprite-image: fugue/gear.png; +} .tipsy { padding: 5px; diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca static/june_2007_style/blue/base.css --- a/static/june_2007_style/blue/base.css +++ b/static/june_2007_style/blue/base.css @@ -43,6 +43,7 @@ div.form-row-input{float:left;} div.form-row-input label{font-weight:normal;display:inline;} div.form-row-error-message{width:300px;float:left;color:red;font-weight:bold;padding:3px 0 0 1em;} +.form-row .help{color:#666;} select,input,textarea{font:inherit;} select,textarea,input[type="text"],input[type="file"],input[type="password"]{-webkit-box-sizing:border-box;max-width:300px;} .errormessagelarge,.warningmessagelarge,.donemessagelarge,.infomessagelarge{padding:10px;padding-left:52px;min-height:32px;border:1px solid #AA6666;background-color:#FFCCCC;background-image:url(error_message_icon.png);background-repeat:no-repeat;background-position:10px 10px;} @@ -150,9 +151,10 @@ .icon-button.tag{background:url(fugue.png) no-repeat 0px -0px;} .icon-button.tags{background:url(fugue.png) no-repeat 0px -26px;} .icon-button.tag--plus{background:url(fugue.png) no-repeat 0px -52px;} -.icon-button.toggle-expand{background:url(fugue.png) no-repeat 0px -78px;} -.icon-button.toggle{background:url(fugue.png) no-repeat 0px -104px;} -.icon-button.toggle-contract{background:url(fugue.png) no-repeat 0px -104px;} +.icon-button.toggle-expand{background:transparent url(../images/fugue/toggle-expand-bw.png) no-repeat;} +.icon-button.toggle-expand:hover{background:url(fugue.png) no-repeat 0px -78px;} +.icon-button.toggle{background:transparent url(../images/fugue/toggle-bw.png) no-repeat;} +.icon-button.toggle:hover{background:url(fugue.png) no-repeat 0px -104px;} .icon-button.arrow-circle{background:url(fugue.png) no-repeat 0px -130px;} .icon-button.chevron{background:url(fugue.png) no-repeat 0px -156px;} .icon-button.bug{background:url(fugue.png) no-repeat 0px -182px;} @@ -162,6 +164,8 @@ .icon-button.vis-chart{background:url(fugue.png) no-repeat 0px -286px;} .icon-button.go-to-full-screen{background:url(fugue.png) no-repeat 0px -312px;} .icon-button.import{background:url(fugue.png) no-repeat 0px -338px;} +.icon-button.plus-button{background:url(fugue.png) no-repeat 0px -364px;} +.icon-button.gear{background:url(fugue.png) no-repeat 0px -390px;} .tipsy{padding:5px;font-size:10px;filter:alpha(opacity=80);background-repeat:no-repeat;background-image:url(../images/tipsy.gif);} .tipsy-inner{padding:5px 8px 4px 8px;background-color:black;color:white;max-width:200px;text-align:center;} .tipsy-north{background-position:top center;} @@ -170,7 +174,7 @@ .tipsy-west{background-position:left center;} .editable-text{cursor:pointer;} .editable-text:hover{cursor:text;border:dotted #999999 1px;} -.text-and-autocomplete-select{background:url(fugue.png) no-repeat right -364px;} +.text-and-autocomplete-select{background:url(fugue.png) no-repeat right -416px;} .icon-button.multiinput{background:url(../images/documents-stack.png) no-repeat;cursor:pointer;float:none;display:inline-block;margin-left:10px;} .icon-button.multiinput.disabled{background:url(../images/documents-stack-faded.png) no-repeat;cursor:auto;} .workflow-invocation-complete{border:solid 1px #6A6;border-left-width:5px;margin:10px 0;padding-left:5px;} diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca static/june_2007_style/blue/fugue.png Binary file static/june_2007_style/blue/fugue.png has changed diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca static/june_2007_style/blue/panel_layout.css --- a/static/june_2007_style/blue/panel_layout.css +++ b/static/june_2007_style/blue/panel_layout.css @@ -23,9 +23,11 @@ .panel-header-button:hover{color:black;background-color:#ccc;} .panel-header-button:active{color:white;background-color:#aaaaaa;} #overlay{position:fixed;top:0;left:0;width:100%;height:100%;z-index:20000;} +#overlay.modal #overlay-background{background:rgba(0,0,0,0.5);} .dialog-box-container{position:relative;margin-top:80px;margin-right:auto;margin-left:auto;} .dialog-box-wrapper{position:relative;padding:1em;background-color:rgba(0,0,0,0.5);-moz-border-radius:1em;-webkit-border-radius:1em;} .dialog-box{border:solid #999 1px;background:white;z-index:80000;} +#overlay.modal .dialog-box .body{min-width:600px;} .dialog-box .body{padding:5px;overflow:auto;max-height:500px;min-width:300px;} .dialog-box .buttons{padding:5px;} .panel-error-message,.panel-warning-message,.panel-done-message,.panel-info-message{height:24px;line-height:24px;color:#303030;padding:0px;padding-left:26px;background-color:#FFCCCC;background-image:url(error_small.png);background-repeat:no-repeat;background-position:6px 50%;} diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca static/june_2007_style/blue/trackster.css --- a/static/june_2007_style/blue/trackster.css +++ b/static/june_2007_style/blue/trackster.css @@ -3,30 +3,9 @@ .content{font:10px verdana;} .nav-controls{text-align:center;padding:1px 0;} .nav-controls input{margin:0 5px;} -.menu-button{padding: 0px 4px 0px 4px;} #zoom-in,#zoom-out{display:inline-block;height:16px;width:16px;margin-bottom:-3px;cursor:pointer;} #zoom-out{background:transparent url(../images/fugue/magnifier-zoom-out.png) center center no-repeat;} #zoom-in{margin-left:10px;background:transparent url(../images/fugue/magnifier-zoom.png) center center no-repeat;} -.overview-icon{background:transparent url(../images/fugue/application-dock-270-bw.png) no-repeat;} -.overview-icon:hover{background:transparent url(../images/fugue/application-dock-270.png) no-repeat;} -.settings-icon{background:transparent url(../images/fugue/gear-bw.png) no-repeat;} -.settings-icon:hover{background:transparent url(../images/fugue/gear.png) no-repeat;} -.tools-icon{background:transparent url(../images/fugue/toolbox-bw.png) no-repeat;} -.tools-icon:hover{background:transparent url(../images/fugue/toolbox.png) no-repeat;} -.filters-icon{background:transparent url(../images/fugue/ui-slider-050-bw.png) no-repeat;} -.filters-icon:hover{background:transparent url(../images/fugue/ui-slider-050.png) no-repeat;} -.remove-icon,.overview-close{background:transparent url(../images/fugue/cross-small-bw.png) no-repeat;} -.remove-icon:hover,.overview-close:hover{background:transparent url(../images/fugue/cross-circle.png) no-repeat;} -#close-icon{background:transparent url(../images/fugue/cross-circle-bw.png) no-repeat;margin-right:0px;} -#close-icon:hover{background:transparent url(../images/fugue/cross-circle.png) no-repeat;} -#add-tracks-icon{background:transparent url(../images/fugue/plus-button-bw.png) no-repeat;} -#add-tracks-icon:hover{background:transparent url(../images/fugue/plus-button.png) no-repeat;} -#add-group-icon{background:transparent url(../images/fugue/block--plus-bw.png) no-repeat;} -#add-group-icon:hover{background:transparent url(../images/fugue/block--plus.png) no-repeat;} -#bookmarks-icon{background:transparent url(../images/fugue/bookmarks-bw.png) no-repeat;} -#bookmarks-icon:hover{background:transparent url(../images/fugue/bookmarks.png) no-repeat;} -#save-icon{background:transparent url(../images/fugue/disk--arrow-bw.png) no-repeat;} -#save-icon:hover{background:transparent url(../images/fugue/disk--arrow.png) no-repeat;} .nav-input{font-size:12px;width:30em;z-index:1000;} .location{display:inline-block;width:15em;margin:0 10px;} .draghandle{margin-top:2px;cursor:move;float:left;background:transparent url(../images/visualization/draggable_horizontal.png) center center no-repeat;width:10px;height:12px;} @@ -65,16 +44,41 @@ input{font:10px verdana;} .dynamic-tool,.filters{margin-left:0.25em;padding-bottom:0.5em;} .dynamic-tool{width:410px;} -.filters>.sliders,.display-controls{float:left;margin:1em;} +.filters > .sliders,.display-controls{float:left;margin:1em;} .sliders{width:410px;} -.display-controls{border-left:solid 2px #DDDDDD;padding-left:1em} -.filter-row{margin-top:0.4em;} +.display-controls{border-left:solid 2px #DDDDDD;padding-left:1em +} +.filter-row { + margin-top:0.4em;} .slider-row{margin-left:1em;} .elt-label{float:left;font-weight:bold;margin-right:1em;} .slider{float:right;width:200px;position:relative;} .tool-name{font-size:110%;font-weight:bold;} .param-row{margin-top:0.2em;margin-left:1em;} .param-label{float:left;font-weight:bold;padding-top:0.2em;} +.menu-button{margin:0px 4px 0px 4px;} +.chevron-expand{background:transparent url(../images/fugue/chevron-expand-bw.png) no-repeat;} +.chevron-expand:hover{background:transparent url(../images/fugue/chevron-expand.png) no-repeat;} +.settings-icon{background:transparent url(../images/fugue/gear-bw.png) no-repeat;} +.settings-icon:hover{background:transparent url(../images/fugue/gear.png) no-repeat;} +.overview-icon{background:transparent url(../images/fugue/application-dock-270-bw.png) no-repeat;} +.overview-icon:hover{background:transparent url(../images/fugue/application-dock-270.png) no-repeat;} +.tools-icon{background:transparent url(../images/fugue/toolbox-bw.png) no-repeat;} +.tools-icon:hover{background:transparent url(../images/fugue/toolbox.png) no-repeat;} +.filters-icon{background:transparent url(../images/fugue/ui-slider-050-bw.png) no-repeat;} +.filters-icon:hover{background:transparent url(../images/fugue/ui-slider-050.png) no-repeat;} +.remove-icon,.overview-close{background:transparent url(../images/fugue/cross-small-bw.png) no-repeat;} +.remove-icon:hover,.overview-close:hover{background:transparent url(../images/fugue/cross-circle.png) no-repeat;} +#close-icon{background:transparent url(../images/fugue/cross-circle-bw.png) no-repeat;margin-right:0px;} +#close-icon:hover{background:transparent url(../images/fugue/cross-circle.png) no-repeat;} +#add-tracks-icon{background:transparent url(../images/fugue/plus-button-bw.png) no-repeat;} +#add-tracks-icon:hover{background:transparent url(../images/fugue/plus-button.png) no-repeat;} +#add-group-icon{background:transparent url(../images/fugue/block--plus-bw.png) no-repeat;} +#add-group-icon:hover{background:transparent url(../images/fugue/block--plus.png) no-repeat;} +#bookmarks-icon{background:transparent url(../images/fugue/bookmarks-bw.png) no-repeat;} +#bookmarks-icon:hover{background:transparent url(../images/fugue/bookmarks.png) no-repeat;} +#save-icon{background:transparent url(../images/fugue/disk--arrow-bw.png) no-repeat;} +#save-icon:hover{background:transparent url(../images/fugue/disk--arrow.png) no-repeat;} .child-track-icon{background:url('../images/fugue/arrow-000-small-bw.png') no-repeat;width:30px;cursor:move;} .track-resize{background:white url('../images/visualization/draggable_vertical.png') no-repeat top center;position:absolute;right:3px;bottom:-4px;width:14px;height:7px;border:solid #999 1px;z-index:100;} .bookmark{background:white;border:solid #999 1px;border-right:none;margin:0.5em;margin-right:0;padding:0.5em;} @@ -85,4 +89,5 @@ .icon.more-across{background:url('../images/fugue/arrow-transition-bw.png') no-repeat 0px 0px;} .intro{padding:1em;} .intro > .action-button{background-color:#CCC;padding:1em;} -.feature-popup{background-color:#DDD;position:absolute;z-index:1000} +.feature-popup{position:absolute;z-index:1000;padding:5px;font-size:10px;filter:alpha(opacity=80);background-repeat:no-repeat;background-image:url(../images/tipsy.gif);background-position:top center;} +.feature-popup-inner{padding:5px 8px 4px 8px;background-color:black;color:white;} diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca static/june_2007_style/panel_layout.css.tmpl --- a/static/june_2007_style/panel_layout.css.tmpl +++ b/static/june_2007_style/panel_layout.css.tmpl @@ -161,6 +161,10 @@ z-index: 20000; } +#overlay.modal #overlay-background { + background: rgba(0,0,0,0.5); +} + .dialog-box-container { position: relative; margin-top: 80px; @@ -182,6 +186,10 @@ z-index: 80000; } +#overlay.modal .dialog-box .body { + min-width: 600px; +} + .dialog-box .body { padding: 5px; overflow: auto; diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca static/june_2007_style/trackster.css.tmpl --- a/static/june_2007_style/trackster.css.tmpl +++ b/static/june_2007_style/trackster.css.tmpl @@ -295,7 +295,13 @@ padding-top: 0.2em; } .menu-button { - padding: 0px 4px 0px 4px; + margin: 0px 4px 0px 4px; +} +.chevron-expand { + background: transparent url(../images/fugue/chevron-expand-bw.png) no-repeat; +} +.chevron-expand:hover { + background:transparent url(../images/fugue/chevron-expand.png) no-repeat; } .settings-icon { background: transparent url(../images/fugue/gear-bw.png) no-repeat; @@ -405,8 +411,19 @@ background-color: #CCC; padding: 1em; } -.feature-popup{ - background-color: #DDD; + +.feature-popup { position: absolute; - z-index: 1000 + z-index: 1000; + padding: 5px; + font-size: 10px; + filter: alpha(opacity=80); + background-repeat: no-repeat; + background-image: url(../images/tipsy.gif); + background-position: top center; } +.feature-popup-inner { + padding: 5px 8px 4px 8px; + background-color: black; + color: white; +} diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca static/scripts/galaxy.panels.js --- a/static/scripts/galaxy.panels.js +++ b/static/scripts/galaxy.panels.js @@ -163,13 +163,23 @@ // Modal dialog boxes function hide_modal() { - $(".dialog-box-container" ).fadeOut( function() { + $(".dialog-box-container" ).hide( 0, function() { $("#overlay").hide(); + $("#overlay").removeClass( "modal" ); $( ".dialog-box" ).find( ".body" ).children().remove(); } ); }; -function show_modal( title, body, buttons, extra_buttons, init_fn ) { +function show_modal() { + $("#overlay").addClass( "modal" ); + _show_modal.apply( this, arguments ); +} + +function show_message() { + _show_modal.apply( this, arguments ); +} + +function _show_modal( title, body, buttons, extra_buttons, init_fn ) { if ( title ) { $( ".dialog-box" ).find( ".title" ).html( title ); $( ".dialog-box" ).find( ".unified-panel-header" ).show(); @@ -205,7 +215,7 @@ $( ".dialog-box" ).find( ".body" ).html( body ); if ( ! $(".dialog-box-container").is( ":visible" ) ) { $("#overlay").show(); - $(".dialog-box-container").fadeIn(); + $(".dialog-box-container").show(); } // Fix min-width so that modal cannot shrink considerably if // new content is loaded. diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca static/scripts/packed/galaxy.panels.js --- a/static/scripts/packed/galaxy.panels.js +++ b/static/scripts/packed/galaxy.panels.js @@ -1,1 +1,1 @@ -function ensure_dd_helper(){if($("#DD-helper").length==0){$("<div id='DD-helper'/>").css({background:"white",opacity:0,zIndex:9000,position:"absolute",top:0,left:0,width:"100%",height:"100%"}).appendTo("body").hide()}}var MIN_PANEL_WIDTH=100,MAX_PANEL_WIDTH=1000;function make_left_panel(h,c,e){var g=false;var f=null;var d=function(i){var j=i;if(i<0){i=0}$(h).css("width",i);$(e).css("left",j);$(c).css("left",i+7);if(document.recalc){document.recalc()}};var a=function(){if(g){$(e).removeClass("hover");$(e).animate({left:f},"fast");$(h).css("left",-f).show().animate({left:0},"fast",function(){d(f);$(e).removeClass("hidden")});g=false}else{f=$(e).position().left;$(c).css("left",$(e).innerWidth());if(document.recalc){document.recalc()}$(e).removeClass("hover");$(h).animate({left:-f},"fast");$(e).animate({left:-1},"fast",function(){$(this).addClass("hidden")});g=true}};$(e).bind("dragstart",function(){$("#DD-helper").show()}).bind("dragend",function(){$("#DD-helper").hide()}).bind("drag",function(i,j){x=j.offsetX;x=Math.min(MAX_PANEL_WIDTH,Math.max(MIN_PANEL_WIDTH,x));if(g){$(h).css("left",0);$(e).removeClass("hidden");g=false}d(x)}).bind("dragclickonly",function(){a()}).find("div").show();var b=function(i){if((g&&i=="show")||(!g&&i=="hide")){a()}};return{force_panel:b}}function make_right_panel(a,e,h){var j=false,g=false,c=null;var d=function(k){$(a).css("width",k);$(e).css("right",k+9);$(h).css("right",k).css("left","");if(document.recalc){document.recalc()}};var i=function(){if(j){$(h).removeClass("hover");$(h).animate({right:c},"fast");$(a).css("right",-c).show().animate({right:0},"fast",function(){d(c);$(h).removeClass("hidden")});j=false}else{c=$(document).width()-$(h).position().left-$(h).outerWidth();$(e).css("right",$(h).innerWidth()+1);if(document.recalc){document.recalc()}$(h).removeClass("hover");$(a).animate({right:-c},"fast");$(h).animate({right:-1},"fast",function(){$(this).addClass("hidden")});j=true}g=false};var b=function(k){var l=$(e).width()-(j?c:0);if(l<k){if(!j){i();g=true}}else{if(g){i();g=false}}};$(h).hover(function(){$(this).addClass("hover")},function(){$(this).removeClass("hover")}).bind("dragstart",function(){$("#DD-helper").show()}).bind("dragend",function(){$("#DD-helper").hide()}).bind("drag",function(k,l){x=l.offsetX;w=$(window).width();x=Math.min(w-MIN_PANEL_WIDTH,x);x=Math.max(w-MAX_PANEL_WIDTH,x);if(j){$(a).css("right",0);$(h).removeClass("hidden");j=false}d(w-x-$(this).outerWidth())}).bind("dragclickonly",function(){i()}).find("div").show();var f=function(k){if((j&&k=="show")||(!j&&k=="hide")){i()}};return{handle_minwidth_hint:b,force_panel:f}}function hide_modal(){$(".dialog-box-container").fadeOut(function(){$("#overlay").hide();$(".dialog-box").find(".body").children().remove()})}function show_modal(h,c,f,d,g){if(h){$(".dialog-box").find(".title").html(h);$(".dialog-box").find(".unified-panel-header").show()}else{$(".dialog-box").find(".unified-panel-header").hide()}var a=$(".dialog-box").find(".buttons").html("");if(f){$.each(f,function(b,i){a.append($("<button/>").text(b).click(i));a.append(" ")});a.show()}else{a.hide()}var a=$(".dialog-box").find(".extra_buttons").html("");if(d){$.each(d,function(b,i){a.append($("<button/>").text(b).click(i));a.append(" ")});a.show()}else{a.hide()}if(c=="progress"){c=$("<img/>").attr("src",image_path+"/yui/rel_interstitial_loading.gif")}var e=$(".dialog-box").find(".body");e.css("min-width","");$(".dialog-box").find(".body").html(c);if(!$(".dialog-box-container").is(":visible")){$("#overlay").show();$(".dialog-box-container").fadeIn()}e.css("min-width",e.width());if(g){g()}}function show_in_overlay(c){var d=c.width||"600";var b=c.height||"400";var a=c.scroll||"auto";$("#overlay-background").bind("click.overlay",function(){hide_modal();$("#overlay-background").unbind("click.overlay")});show_modal(null,$("<div style='margin: -5px;'><img id='close_button' style='position:absolute;right:-17px;top:-15px;src='"+image_path+"/closebox.png'><iframe style='margin: 0; padding: 0;' src='"+c.url+"' width='"+d+"' height='"+b+"' scrolling='"+a+"' frameborder='0'></iframe></div>"));$("#close_button").bind("click",function(){hide_modal()})}$(function(){$(".tab").each(function(){var a=$(this).children(".submenu");if(a.length>0){if($.browser.msie){a.prepend("<iframe style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: -1; filter:Alpha(Opacity='0');\"></iframe>")}$(this).hover(function(){a.show()},function(){a.hide()});a.click(function(){a.hide()})}})});function user_changed(a,b){if(a){$(".loggedin-only").show();$(".loggedout-only").hide();$("#user-email").text(a);if(b){$(".admin-only").show()}}else{$(".loggedin-only").hide();$(".loggedout-only").show();$(".admin-only").hide()}}; \ No newline at end of file +function ensure_dd_helper(){if($("#DD-helper").length==0){$("<div id='DD-helper'/>").css({background:"white",opacity:0,zIndex:9000,position:"absolute",top:0,left:0,width:"100%",height:"100%"}).appendTo("body").hide()}}var MIN_PANEL_WIDTH=100,MAX_PANEL_WIDTH=1000;function make_left_panel(h,c,e){var g=false;var f=null;var d=function(i){var j=i;if(i<0){i=0}$(h).css("width",i);$(e).css("left",j);$(c).css("left",i+7);if(document.recalc){document.recalc()}};var a=function(){if(g){$(e).removeClass("hover");$(e).animate({left:f},"fast");$(h).css("left",-f).show().animate({left:0},"fast",function(){d(f);$(e).removeClass("hidden")});g=false}else{f=$(e).position().left;$(c).css("left",$(e).innerWidth());if(document.recalc){document.recalc()}$(e).removeClass("hover");$(h).animate({left:-f},"fast");$(e).animate({left:-1},"fast",function(){$(this).addClass("hidden")});g=true}};$(e).bind("dragstart",function(){$("#DD-helper").show()}).bind("dragend",function(){$("#DD-helper").hide()}).bind("drag",function(i,j){x=j.offsetX;x=Math.min(MAX_PANEL_WIDTH,Math.max(MIN_PANEL_WIDTH,x));if(g){$(h).css("left",0);$(e).removeClass("hidden");g=false}d(x)}).bind("dragclickonly",function(){a()}).find("div").show();var b=function(i){if((g&&i=="show")||(!g&&i=="hide")){a()}};return{force_panel:b}}function make_right_panel(a,e,h){var j=false,g=false,c=null;var d=function(k){$(a).css("width",k);$(e).css("right",k+9);$(h).css("right",k).css("left","");if(document.recalc){document.recalc()}};var i=function(){if(j){$(h).removeClass("hover");$(h).animate({right:c},"fast");$(a).css("right",-c).show().animate({right:0},"fast",function(){d(c);$(h).removeClass("hidden")});j=false}else{c=$(document).width()-$(h).position().left-$(h).outerWidth();$(e).css("right",$(h).innerWidth()+1);if(document.recalc){document.recalc()}$(h).removeClass("hover");$(a).animate({right:-c},"fast");$(h).animate({right:-1},"fast",function(){$(this).addClass("hidden")});j=true}g=false};var b=function(k){var l=$(e).width()-(j?c:0);if(l<k){if(!j){i();g=true}}else{if(g){i();g=false}}};$(h).hover(function(){$(this).addClass("hover")},function(){$(this).removeClass("hover")}).bind("dragstart",function(){$("#DD-helper").show()}).bind("dragend",function(){$("#DD-helper").hide()}).bind("drag",function(k,l){x=l.offsetX;w=$(window).width();x=Math.min(w-MIN_PANEL_WIDTH,x);x=Math.max(w-MAX_PANEL_WIDTH,x);if(j){$(a).css("right",0);$(h).removeClass("hidden");j=false}d(w-x-$(this).outerWidth())}).bind("dragclickonly",function(){i()}).find("div").show();var f=function(k){if((j&&k=="show")||(!j&&k=="hide")){i()}};return{handle_minwidth_hint:b,force_panel:f}}function hide_modal(){$(".dialog-box-container").hide(0,function(){$("#overlay").hide();$("#overlay").removeClass("modal");$(".dialog-box").find(".body").children().remove()})}function show_modal(){$("#overlay").addClass("modal");_show_modal.apply(this,arguments)}function show_message(){_show_modal.apply(this,arguments)}function _show_modal(h,c,f,d,g){if(h){$(".dialog-box").find(".title").html(h);$(".dialog-box").find(".unified-panel-header").show()}else{$(".dialog-box").find(".unified-panel-header").hide()}var a=$(".dialog-box").find(".buttons").html("");if(f){$.each(f,function(b,i){a.append($("<button/>").text(b).click(i));a.append(" ")});a.show()}else{a.hide()}var a=$(".dialog-box").find(".extra_buttons").html("");if(d){$.each(d,function(b,i){a.append($("<button/>").text(b).click(i));a.append(" ")});a.show()}else{a.hide()}if(c=="progress"){c=$("<img/>").attr("src",image_path+"/yui/rel_interstitial_loading.gif")}var e=$(".dialog-box").find(".body");e.css("min-width","");$(".dialog-box").find(".body").html(c);if(!$(".dialog-box-container").is(":visible")){$("#overlay").show();$(".dialog-box-container").show()}e.css("min-width",e.width());if(g){g()}}function show_in_overlay(c){var d=c.width||"600";var b=c.height||"400";var a=c.scroll||"auto";$("#overlay-background").bind("click.overlay",function(){hide_modal();$("#overlay-background").unbind("click.overlay")});show_modal(null,$("<div style='margin: -5px;'><img id='close_button' style='position:absolute;right:-17px;top:-15px;src='"+image_path+"/closebox.png'><iframe style='margin: 0; padding: 0;' src='"+c.url+"' width='"+d+"' height='"+b+"' scrolling='"+a+"' frameborder='0'></iframe></div>"));$("#close_button").bind("click",function(){hide_modal()})}$(function(){$(".tab").each(function(){var a=$(this).children(".submenu");if(a.length>0){if($.browser.msie){a.prepend("<iframe style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: -1; filter:Alpha(Opacity='0');\"></iframe>")}$(this).hover(function(){a.show()},function(){a.hide()});a.click(function(){a.hide()})}})});function user_changed(a,b){if(a){$(".loggedin-only").show();$(".loggedout-only").hide();$("#user-email").text(a);if(b){$(".admin-only").show()}}else{$(".loggedin-only").hide();$(".loggedout-only").show();$(".admin-only").hide()}}; \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca static/scripts/packed/trackster.js --- a/static/scripts/packed/trackster.js +++ b/static/scripts/packed/trackster.js @@ -1,1 +1,1 @@ -var class_module=function(b,a){var c=function(){var f=arguments[0];for(var e=1;e<arguments.length;e++){var d=arguments[e];for(key in d){f[key]=d[key]}}return f};a.extend=c};var requestAnimationFrame=(function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(b,a){window.setTimeout(b,1000/60)}})();var BEFORE=1001,CONTAINS=1002,OVERLAP_START=1003,OVERLAP_END=1004,CONTAINED_BY=1005,AFTER=1006;var compute_overlap=function(e,b){var g=e[0],f=e[1],d=b[0],c=b[1],a;if(g<d){if(f<d){a=BEFORE}else{if(f<=c){a=OVERLAP_START}else{a=CONTAINS}}}else{if(g>c){a=AFTER}else{if(f<=c){a=CONTAINED_BY}else{a=OVERLAP_END}}}return a};var is_overlap=function(c,b){var a=compute_overlap(c,b);return(a!==BEFORE&&a!==AFTER)};var get_random_color=function(a){if(!a){a="#ffffff"}if(typeof(a)==="string"){a=[a]}for(var j=0;j<a.length;j++){a[j]=parseInt(a[j].slice(1),16)}var m=function(t,s,i){return((t*299)+(s*587)+(i*114))/1000};var e=function(u,t,v,r,i,s){return(Math.max(u,r)-Math.min(u,r))+(Math.max(t,i)-Math.min(t,i))+(Math.max(v,s)-Math.min(v,s))};var g,n,f,k,p,h,q,c,d,b,o,l=false;do{g=Math.random()*16777215;n=g|16711680;f=g|65280;k=g|255;d=m(n,f,k);l=true;for(var j=0;j<a.length;j++){p=a[j];h=p|16711680;q=p|65280;c=p|255;b=m(h,q,c);o=e(n,f,k,h,q,c);if((Math.abs(d-b)<125)||(o<500)){l=false;break}}}while(!l);return"#"+(16777216+g).toString(16).substr(1,6)};var trackster_module=function(f,X){var p=f("class").extend,s=f("slotting"),M=f("painters");var ae=function(af,ag){this.document=af;this.default_font=ag!==undefined?ag:"9px Monaco, Lucida Console, monospace";this.dummy_canvas=this.new_canvas();this.dummy_context=this.dummy_canvas.getContext("2d");this.dummy_context.font=this.default_font;this.char_width_px=this.dummy_context.measureText("A").width;this.patterns={};this.load_pattern("right_strand","/visualization/strand_right.png");this.load_pattern("left_strand","/visualization/strand_left.png");this.load_pattern("right_strand_inv","/visualization/strand_right_inv.png");this.load_pattern("left_strand_inv","/visualization/strand_left_inv.png")};p(ae.prototype,{load_pattern:function(af,aj){var ag=this.patterns,ah=this.dummy_context,ai=new Image();ai.src=image_path+aj;ai.onload=function(){ag[af]=ah.createPattern(ai,"repeat")}},get_pattern:function(af){return this.patterns[af]},new_canvas:function(){var af=this.document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(af)}af.manager=this;return af}});var n={};var l=function(af,ag){n[af.attr("id")]=ag};var m=function(af,ah,aj,ai){aj=".group";var ag={};n[af.attr("id")]=ai;af.bind("drag",{handle:"."+ah,relative:true},function(ar,at){var aq=$(this);var aw=$(this).parent(),an=aw.children(),ap=n[$(this).attr("id")],am,al,au,ak,ao;al=$(this).parents(aj);if(al.length!==0){au=al.position().top;ak=au+al.outerHeight();if(at.offsetY<au){$(this).insertBefore(al);var av=n[al.attr("id")];av.remove_drawable(ap);av.container.add_drawable_before(ap,av);return}else{if(at.offsetY>ak){$(this).insertAfter(al);var av=n[al.attr("id")];av.remove_drawable(ap);av.container.add_drawable(ap);return}}}al=null;for(ao=0;ao<an.length;ao++){am=$(an.get(ao));au=am.position().top;ak=au+am.outerHeight();if(am.is(aj)&&this!==am.get(0)&&at.offsetY>=au&&at.offsetY<=ak){if(at.offsetY-au<ak-at.offsetY){am.find(".content-div").prepend(this)}else{am.find(".content-div").append(this)}if(ap.container){ap.container.remove_drawable(ap)}n[am.attr("id")].add_drawable(ap);return}}for(ao=0;ao<an.length;ao++){if(at.offsetY<$(an.get(ao)).position().top){break}}if(ao===an.length){if(this!==an.get(ao-1)){aw.append(this);n[aw.attr("id")].move_drawable(ap,ao)}}else{if(this!==an.get(ao)){$(this).insertBefore(an.get(ao));n[aw.attr("id")].move_drawable(ap,(at.deltaY>0?ao-1:ao))}}}).bind("dragstart",function(){ag["border-top"]=af.css("border-top");ag["border-bottom"]=af.css("border-bottom");$(this).css({"border-top":"1px solid blue","border-bottom":"1px solid blue"})}).bind("dragend",function(){$(this).css(ag)})};X.moveable=m;var ad=16,H=9,E=20,T=H+2,z=100,J=12000,R=200,C=5,v=10,L=5000,w=100,o="There was an error in indexing this dataset. ",K="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",F="No data for this chrom/contig.",t="Currently indexing... please wait",x="Tool cannot be rerun: ",a="Loading data...",Y="Ready for display",d=10,u=5,B=5;function Z(ag,af){if(!af){af=0}var ah=Math.pow(10,af);return Math.round(ag*ah)/ah}var c=function(af){this.num_elements=af;this.clear()};p(c.prototype,{get:function(ag){var af=this.key_ary.indexOf(ag);if(af!==-1){if(this.obj_cache[ag].stale){this.key_ary.splice(af,1);delete this.obj_cache[ag]}else{this.move_key_to_end(ag,af)}}return this.obj_cache[ag]},set:function(ag,ah){if(!this.obj_cache[ag]){if(this.key_ary.length>=this.num_elements){var af=this.key_ary.shift();delete this.obj_cache[af]}this.key_ary.push(ag)}this.obj_cache[ag]=ah;return ah},move_key_to_end:function(ag,af){this.key_ary.splice(af,1);this.key_ary.push(ag)},clear:function(){this.obj_cache={};this.key_ary=[]},size:function(){return this.key_ary.length}});var S=function(ag,af,ah){c.call(this,ag);this.track=af;this.subset=(ah!==undefined?ah:true)};p(S.prototype,c.prototype,{load_data:function(ao,aj,am,ag,al){var an=this.track.view.chrom,ai={chrom:an,low:ao,high:aj,mode:am,resolution:ag,dataset_id:this.track.dataset_id,hda_ldda:this.track.hda_ldda};$.extend(ai,al);if(this.track.filters_manager){var ap=[];var af=this.track.filters_manager.filters;for(var ak=0;ak<af.length;ak++){ap[ap.length]=af[ak].name}ai.filter_cols=JSON.stringify(ap)}var ah=this;return $.getJSON(this.track.data_url,ai,function(aq){ah.set_data(ao,aj,am,aq)})},get_data:function(af,aj,ak,ag,ai){var ah=this.get_data_from_cache(af,aj,ak);if(ah){return ah}ah=this.load_data(af,aj,ak,ag,ai);this.set_data(af,aj,ak,ah);return ah},DEEP_DATA_REQ:"deep",BROAD_DATA_REQ:"breadth",get_more_data:function(an,ai,am,ah,al,aj){var ao=this.get_data_from_cache(an,ai,am);if(!ao){console.log("ERROR: no current data for: ",this.track,an,ai,am,ah,al);return}ao.stale=true;var ag=an;if(aj===this.DEEP_DATA_REQ){$.extend(al,{start_val:ao.data.length+1})}else{if(aj===this.BROAD_DATA_REQ){ag=(ao.max_high?ao.max_high:ao.data[ao.data.length-1][2])+1}}var af=this,ak=this.load_data(ag,ai,am,ah,al);new_data_available=$.Deferred();this.set_data(an,ai,am,new_data_available);$.when(ak).then(function(ap){if(ap.data){ap.data=ao.data.concat(ap.data);if(ap.max_low){ap.max_low=ao.max_low}if(ap.message){ap.message=ap.message.replace(/[0-9]+/,ap.data.length)}}af.set_data(an,ai,am,ap);new_data_available.resolve(ap)});return new_data_available},get_data_from_cache:function(af,ag,ah){return this.get(this.gen_key(af,ag,ah))},set_data:function(ag,ah,ai,af){return this.set(this.gen_key(ag,ah,ai),af)},gen_key:function(af,ah,ai){var ag=af+"_"+ah+"_"+ai;return ag},split_key:function(af){return af.split("_")}});var I=function(ag,af,ah){S.call(this,ag,af,ah)};p(I.prototype,S.prototype,c.prototype,{load_data:function(af,ai,aj,ag,ah){if(ag>1){return{data:null}}return S.prototype.load_data.call(this,af,ai,aj,ag,ah)}});var q=function(ai,ag,af,ah,aj){this.name=ai;this.view=ag;this.container=af;this.config=new G({track:this,params:[{key:"name",label:"Name",type:"text",default_value:ai}],saved_values:ah,onchange:function(){this.track.set_name(this.track.config.values.name)}});this.prefs=this.config.values;this.drag_handle_class=aj;this.is_overview=false};p(q.prototype,{init:function(){},request_draw:function(){},_draw:function(){},to_json:function(){},update_track_icons:function(){},set_name:function(af){this.old_name=this.name;this.name=af;this.name_div.text(this.name)},revert_name:function(){this.name=this.old_name;this.name_div.text(this.name)},remove:function(){this.container.remove_drawable(this);this.container_div.fadeOut("slow",function(){$(this).remove();view.update_intro_div();view.has_changes=true})}});var y=function(aj,ai,ag,af,ah,ak){q.call(this,ai,ag,af,ah,ak);this.obj_type=aj;this.drawables=[]};p(y.prototype,q.prototype,{init:function(){for(var af=0;af<this.drawables.length;af++){this.drawables[af].init()}},_draw:function(){for(var af=0;af<this.drawables.length;af++){this.drawables[af]._draw()}},to_json:function(){var ag=[];for(var af=0;af<this.drawables.length;af++){ag.push(this.drawables[af].to_json())}return{name:this.name,prefs:this.prefs,obj_type:this.obj_type,drawables:ag}},add_drawable:function(af){this.drawables.push(af);af.container=this},add_drawable_before:function(ah,af){var ag=this.drawables.indexOf(af);if(ag!=-1){this.drawables.splice(ag,0,ah);return true}return false},remove_drawable:function(ag){var af=this.drawables.indexOf(ag);if(af!=-1){this.drawables.splice(af,1);ag.container=null;return true}return false},move_drawable:function(ag,ah){var af=this.drawables.indexOf(ag);if(af!=-1){this.drawables.splice(af,1);this.drawables.splice(ah,0,ag);return true}return false}});var Q=function(ai,ag,af,ah){y.call(this,"DrawableGroup",ai,ag,af,ah,"group-handle");if(!Q.id_counter){Q.id_counter=0}var aj=Q.id_counter++;this.container_div=$("<div/>").addClass("group").attr("id","group_"+aj).appendTo(this.container.content_div);this.header_div=$("<div/>").addClass("track-header").appendTo(this.container_div);this.header_div.append($("<div/>").addClass(this.drag_handle_class));this.name_div=$("<div/>").addClass("group-name menubutton popup").text(this.name).appendTo(this.header_div);this.content_div=$("<div/>").addClass("content-div").attr("id","group_"+aj+"_content_div").appendTo(this.container_div);l(this.container_div,this);l(this.content_div,this);m(this.container_div,this.drag_handle_class,".group",this);this.update_track_icons()};p(Q.prototype,q.prototype,y.prototype,{update_track_icons:function(){var ag=this;var af={};af["Edit configuration"]=function(){var aj=function(){hide_modal();$(window).unbind("keypress.check_enter_esc")},ah=function(){ag.config.update_from_form($(".dialog-box"));hide_modal();$(window).unbind("keypress.check_enter_esc")},ai=function(ak){if((ak.keyCode||ak.which)===27){aj()}else{if((ak.keyCode||ak.which)===13){ah()}}};$(window).bind("keypress.check_enter_esc",ai);show_modal("Configure Group",ag.config.build_form(),{Cancel:aj,OK:ah})};af.Remove=function(){ag.remove()};make_popupmenu(ag.name_div,af)}});var ac=function(af,ai,ah,ag){y.call(this,"View");this.container=af;this.chrom=null;this.vis_id=ah;this.dbkey=ag;this.title=ai;this.label_tracks=[];this.tracks_to_be_redrawn=[];this.max_low=0;this.max_high=0;this.zoom_factor=3;this.min_separation=30;this.has_changes=false;this.load_chroms_deferred=null;this.init();this.canvas_manager=new ae(af.get(0).ownerDocument);this.reset()};p(ac.prototype,y.prototype,{init:function(){var ah=this.container,af=this;this.top_container=$("<div/>").addClass("top-container").appendTo(ah);this.browser_content_div=$("<div/>").addClass("content").css("position","relative").appendTo(ah);this.bottom_container=$("<div/>").addClass("bottom-container").appendTo(ah);this.top_labeltrack=$("<div/>").addClass("top-labeltrack").appendTo(this.top_container);this.viewport_container=$("<div/>").addClass("viewport-container").attr("id","viewport-container").appendTo(this.browser_content_div);this.content_div=this.viewport_container;l(this.viewport_container,af);this.intro_div=$("<div/>").addClass("intro");var ai=$("<div/>").text("Add Datasets to Visualization").addClass("action-button").appendTo(this.intro_div).click(function(){add_tracks()});this.nav_labeltrack=$("<div/>").addClass("nav-labeltrack").appendTo(this.bottom_container);this.nav_container=$("<div/>").addClass("nav-container").prependTo(this.top_container);this.nav=$("<div/>").addClass("nav").appendTo(this.nav_container);this.overview=$("<div/>").addClass("overview").appendTo(this.bottom_container);this.overview_viewport=$("<div/>").addClass("overview-viewport").appendTo(this.overview);this.overview_close=$("<a/>").attr("href","javascript:void(0);").attr("title","Close overview").addClass("icon-button overview-close tooltip").hide().appendTo(this.overview_viewport);this.overview_highlight=$("<div/>").addClass("overview-highlight").hide().appendTo(this.overview_viewport);this.overview_box_background=$("<div/>").addClass("overview-boxback").appendTo(this.overview_viewport);this.overview_box=$("<div/>").addClass("overview-box").appendTo(this.overview_viewport);this.default_overview_height=this.overview_box.height();this.nav_controls=$("<div/>").addClass("nav-controls").appendTo(this.nav);this.chrom_select=$("<select/>").attr({name:"chrom"}).css("width","15em").addClass("no-autocomplete").append("<option value=''>Loading</option>").appendTo(this.nav_controls);var ag=function(aj){if(aj.type==="focusout"||(aj.keyCode||aj.which)===13||(aj.keyCode||aj.which)===27){if((aj.keyCode||aj.which)!==27){af.go_to($(this).val())}$(this).hide();$(this).val("");af.location_span.show();af.chrom_select.show()}};this.nav_input=$("<input/>").addClass("nav-input").hide().bind("keyup focusout",ag).appendTo(this.nav_controls);this.location_span=$("<span/>").addClass("location").appendTo(this.nav_controls);this.location_span.click(function(){af.location_span.hide();af.chrom_select.hide();af.nav_input.val(af.chrom+":"+af.low+"-"+af.high);af.nav_input.css("display","inline-block");af.nav_input.select();af.nav_input.focus()});if(this.vis_id!==undefined){this.hidden_input=$("<input/>").attr("type","hidden").val(this.vis_id).appendTo(this.nav_controls)}this.zo_link=$("<a id='zoom-out' />").click(function(){af.zoom_out();af.request_redraw()}).appendTo(this.nav_controls);this.zi_link=$("<a id='zoom-in' />").click(function(){af.zoom_in();af.request_redraw()}).appendTo(this.nav_controls);this.load_chroms_deferred=this.load_chroms({low:0});this.chrom_select.bind("change",function(){af.change_chrom(af.chrom_select.val())});this.browser_content_div.click(function(aj){$(this).find("input").trigger("blur")});this.browser_content_div.bind("dblclick",function(aj){af.zoom_in(aj.pageX,this.viewport_container)});this.overview_box.bind("dragstart",function(aj,ak){this.current_x=ak.offsetX}).bind("drag",function(aj,al){var am=al.offsetX-this.current_x;this.current_x=al.offsetX;var ak=Math.round(am/af.viewport_container.width()*(af.max_high-af.max_low));af.move_delta(-ak)});this.overview_close.click(function(){af.reset_overview()});this.viewport_container.bind("draginit",function(aj,ak){if(aj.clientX>af.viewport_container.width()-16){return false}}).bind("dragstart",function(aj,ak){ak.original_low=af.low;ak.current_height=aj.clientY;ak.current_x=ak.offsetX}).bind("drag",function(al,an){var aj=$(this);var ao=an.offsetX-an.current_x;var ak=aj.scrollTop()-(al.clientY-an.current_height);aj.scrollTop(ak);an.current_height=al.clientY;an.current_x=an.offsetX;var am=Math.round(ao/af.viewport_container.width()*(af.high-af.low));af.move_delta(am)}).bind("mousewheel",function(al,an,ak,aj){if(ak){var am=Math.round(-ak/af.viewport_container.width()*(af.high-af.low));af.move_delta(am)}});this.top_labeltrack.bind("dragstart",function(aj,ak){return $("<div />").css({height:af.browser_content_div.height()+af.top_labeltrack.height()+af.nav_labeltrack.height()+1,top:"0px",position:"absolute","background-color":"#ccf",opacity:0.5,"z-index":1000}).appendTo($(this))}).bind("drag",function(an,ao){$(ao.proxy).css({left:Math.min(an.pageX,ao.startX),width:Math.abs(an.pageX-ao.startX)});var ak=Math.min(an.pageX,ao.startX)-af.container.offset().left,aj=Math.max(an.pageX,ao.startX)-af.container.offset().left,am=(af.high-af.low),al=af.viewport_container.width();af.update_location(Math.round(ak/al*am)+af.low,Math.round(aj/al*am)+af.low)}).bind("dragend",function(ao,ap){var ak=Math.min(ao.pageX,ap.startX),aj=Math.max(ao.pageX,ap.startX),am=(af.high-af.low),al=af.viewport_container.width(),an=af.low;af.low=Math.round(ak/al*am)+an;af.high=Math.round(aj/al*am)+an;$(ap.proxy).remove();af.request_redraw()});this.add_label_track(new ab(this,{content_div:this.top_labeltrack}));this.add_label_track(new ab(this,{content_div:this.nav_labeltrack}));$(window).bind("resize",function(){af.resize_window()});$(document).bind("redraw",function(){af.redraw()});this.reset();$(window).trigger("resize");this.update_intro_div()},update_intro_div:function(){if(this.num_tracks===0){this.intro_div.appendTo(this.viewport_container)}else{this.intro_div.remove()}},update_location:function(af,ag){this.location_span.text(commatize(af)+" - "+commatize(ag));this.nav_input.val(this.chrom+":"+commatize(af)+"-"+commatize(ag))},load_chroms:function(ah){ah.num=w;$.extend(ah,(this.vis_id!==undefined?{vis_id:this.vis_id}:{dbkey:this.dbkey}));var af=this,ag=$.Deferred();$.ajax({url:chrom_url,data:ah,dataType:"json",success:function(aj){if(aj.chrom_info.length===0){alert("Invalid chromosome: "+ah.chrom);return}if(aj.reference){af.add_label_track(new A(af))}af.chrom_data=aj.chrom_info;var am='<option value="">Select Chrom/Contig</option>';for(var al=0,ai=af.chrom_data.length;al<ai;al++){var ak=af.chrom_data[al].chrom;am+='<option value="'+ak+'">'+ak+"</option>"}if(aj.prev_chroms){am+='<option value="previous">Previous '+w+"</option>"}if(aj.next_chroms){am+='<option value="next">Next '+w+"</option>"}af.chrom_select.html(am);af.chrom_start_index=aj.start_index;ag.resolve(aj)},error:function(){alert("Could not load chroms for this dbkey:",af.dbkey)}});return ag},change_chrom:function(ak,ag,am){if(!ak||ak==="None"){return}var ah=this;if(ak==="previous"){ah.load_chroms({low:this.chrom_start_index-w});return}if(ak==="next"){ah.load_chroms({low:this.chrom_start_index+w});return}var al=$.grep(ah.chrom_data,function(an,ao){return an.chrom===ak})[0];if(al===undefined){ah.load_chroms({chrom:ak},function(){ah.change_chrom(ak,ag,am)});return}else{if(ak!==ah.chrom){ah.chrom=ak;ah.chrom_select.val(ah.chrom);ah.max_high=al.len-1;ah.reset();ah.request_redraw(true);for(var aj=0,af=ah.drawables.length;aj<af;aj++){var ai=ah.drawables[aj];if(ai.init){ai.init()}}}if(ag!==undefined&&am!==undefined){ah.low=Math.max(ag,0);ah.high=Math.min(am,ah.max_high)}ah.reset_overview();ah.request_redraw()}},go_to:function(aj){aj=aj.replace(/ |,/g,"");var an=this,af,ai,ag=aj.split(":"),al=ag[0],am=ag[1];if(am!==undefined){try{var ak=am.split("-");af=parseInt(ak[0],10);ai=parseInt(ak[1],10)}catch(ah){return false}}an.change_chrom(al,af,ai)},move_fraction:function(ah){var af=this;var ag=af.high-af.low;this.move_delta(ah*ag)},move_delta:function(ah){var af=this;var ag=af.high-af.low;if(af.low-ah<af.max_low){af.low=af.max_low;af.high=af.max_low+ag}else{if(af.high-ah>af.max_high){af.high=af.max_high;af.low=af.max_high-ag}else{af.high-=ah;af.low-=ah}}af.request_redraw()},add_drawable:function(af){y.prototype.add_drawable.call(this,af);af.init();this.has_changes=true;this.update_intro_div()},add_label_track:function(af){af.view=this;af.init();this.label_tracks.push(af)},remove_drawable:function(ah,ag){y.prototype.remove_drawable.call(this,ah);if(ag){var af=this;ah.container_div.fadeOut("slow",function(){$(this).remove();af.update_intro_div()});this.has_changes=true}},reset:function(){this.low=this.max_low;this.high=this.max_high;this.viewport_container.find(".yaxislabel").remove()},request_redraw:function(an,af,am,ag){var al=this,aj=(ag?[ag]:al.drawables),ah;var ag;for(var ak=0;ak<aj.length;ak++){ag=aj[ak];ah=-1;for(var ai=0;ai<al.tracks_to_be_redrawn.length;ai++){if(al.tracks_to_be_redrawn[ai][0]===ag){ah=ai;break}}if(ah<0){al.tracks_to_be_redrawn.push([ag,af,am])}else{al.tracks_to_be_redrawn[ak][1]=af;al.tracks_to_be_redrawn[ak][2]=am}}requestAnimationFrame(function(){al._redraw(an)})},_redraw:function(ap){var am=this.low,ai=this.high;if(am<this.max_low){am=this.max_low}if(ai>this.max_high){ai=this.max_high}var ao=this.high-this.low;if(this.high!==0&&ao<this.min_separation){ai=am+this.min_separation}this.low=Math.floor(am);this.high=Math.ceil(ai);this.resolution=Math.pow(C,Math.ceil(Math.log((this.high-this.low)/R)/Math.log(C)));this.zoom_res=Math.pow(v,Math.max(0,Math.ceil(Math.log(this.resolution,v)/Math.log(v))));var af=(this.low/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var al=((this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var aq=13;this.overview_box.css({left:af,width:Math.max(aq,al)}).show();if(al<aq){this.overview_box.css("left",af-(aq-al)/2)}if(this.overview_highlight){this.overview_highlight.css({left:af,width:al})}this.update_location(this.low,this.high);if(!ap){var ah,ag,an;for(var aj=0,ak=this.tracks_to_be_redrawn.length;aj<ak;aj++){ah=this.tracks_to_be_redrawn[aj][0];ag=this.tracks_to_be_redrawn[aj][1];an=this.tracks_to_be_redrawn[aj][2];if(ah){ah._draw(ag,an)}}this.tracks_to_be_redrawn=[];for(aj=0,ak=this.label_tracks.length;aj<ak;aj++){this.label_tracks[aj]._draw()}}},zoom_in:function(ag,ah){if(this.max_high===0||this.high-this.low<this.min_separation){return}var ai=this.high-this.low,aj=ai/2+this.low,af=(ai/this.zoom_factor)/2;if(ag){aj=ag/this.viewport_container.width()*(this.high-this.low)+this.low}this.low=Math.round(aj-af);this.high=Math.round(aj+af);this.request_redraw()},zoom_out:function(){if(this.max_high===0){return}var ag=this.high-this.low,ah=ag/2+this.low,af=(ag*this.zoom_factor)/2;this.low=Math.round(ah-af);this.high=Math.round(ah+af);this.request_redraw()},resize_window:function(){this.viewport_container.height(this.container.height()-this.top_container.height()-this.bottom_container.height());this.nav_container.width(this.container.width());this.request_redraw()},set_overview:function(ah){if(this.overview_drawable){if(this.overview_drawable.dataset_id===ah.dataset_id){return}this.overview_viewport.find(".track").remove()}var ag=ah.copy({content_div:this.overview_viewport}),af=this;ag.header_div.hide();ag.is_overview=true;af.overview_drawable=ag;this.overview_drawable.postdraw_actions=function(){af.overview_highlight.show().height(af.overview_drawable.content_div.height());af.overview_viewport.height(af.overview_drawable.content_div.height()+af.overview_box.outerHeight());af.overview_close.show();af.resize_window()};this.overview_drawable.init();af.has_changes=true},reset_overview:function(){$(".tipsy").remove();this.overview_viewport.find(".track-tile").remove();this.overview_viewport.height(this.default_overview_height);this.overview_box.height(this.default_overview_height);this.overview_close.hide();this.overview_highlight.hide();view.resize_window();view.overview_drawable=null}});var r=function(ah,al){this.track=ah;this.name=al.name;this.params=[];var at=al.params;for(var ai=0;ai<at.length;ai++){var an=at[ai],ag=an.name,ar=an.label,aj=unescape(an.html),au=an.value,ap=an.type;if(ap==="number"){this.params[this.params.length]=new g(ag,ar,aj,au,an.min,an.max)}else{if(ap=="select"){this.params[this.params.length]=new O(ag,ar,aj,au)}else{console.log("WARNING: unrecognized tool parameter type:",ag,ap)}}}this.parent_div=$("<div/>").addClass("dynamic-tool").hide();this.parent_div.bind("drag",function(aw){aw.stopPropagation()}).click(function(aw){aw.stopPropagation()}).bind("dblclick",function(aw){aw.stopPropagation()});var aq=$("<div class='tool-name'>").appendTo(this.parent_div).text(this.name);var ao=this.params;var am=this;$.each(this.params,function(ax,aA){var az=$("<div>").addClass("param-row").appendTo(am.parent_div);var aw=$("<div>").addClass("param-label").text(aA.label).appendTo(az);var ay=$("<div/>").addClass("slider").html(aA.html).appendTo(az);ay.find(":input").val(aA.value);$("<div style='clear: both;'/>").appendTo(az)});this.parent_div.find("input").click(function(){$(this).select()});var av=$("<div>").addClass("param-row").appendTo(this.parent_div);var ak=$("<input type='submit'>").attr("value","Run on complete dataset").appendTo(av);var af=$("<input type='submit'>").attr("value","Run on visible region").css("margin-left","3em").appendTo(av);var am=this;af.click(function(){am.run_on_region()});ak.click(function(){am.run_on_dataset()})};p(r.prototype,{get_param_values_dict:function(){var af={};this.parent_div.find(":input").each(function(){var ag=$(this).attr("name"),ah=$(this).val();af[ag]=JSON.stringify(ah)});return af},get_param_values:function(){var ag=[];var af={};this.parent_div.find(":input").each(function(){var ah=$(this).attr("name"),ai=$(this).val();if(ah){ag[ag.length]=ai}});return ag},run_on_dataset:function(){var af=this;af.run({dataset_id:this.track.original_dataset_id,tool_id:af.name},null,function(ag){show_modal(af.name+" is Running",af.name+" is running on the complete dataset. Tool outputs are in dataset's history.",{Close:hide_modal})})},run_on_region:function(){var ag={dataset_id:this.track.original_dataset_id,chrom:this.track.view.chrom,low:this.track.view.low,high:this.track.view.high,tool_id:this.name},aj=this.track,ah=ag.tool_id+aj.tool_region_and_parameters_str(ag.chrom,ag.low,ag.high),af;if(aj.container===view){var ai=new Q(this.name,this.track.view,this.track.container);aj.container.add_drawable(ai);aj.container.remove_drawable(aj);ai.add_drawable(aj);aj.container_div.appendTo(ai.content_div);af=ai}else{af=aj.container}var ak=new aj.constructor(ah,view,af,"hda");ak.init_for_tool_data();ak.change_mode(aj.mode);af.add_drawable(ak);ak.content_div.text("Starting job.");this.run(ag,ak,function(al){ak.dataset_id=al.dataset_id;ak.content_div.text("Running job.");ak.init()})},run:function(ag,ah,ai){$.extend(ag,this.get_param_values_dict());var af=function(){$.getJSON(rerun_tool_url,ag,function(aj){if(aj==="no converter"){ah.container_div.addClass("error");ah.content_div.text(K)}else{if(aj.error){ah.container_div.addClass("error");ah.content_div.text(x+aj.message)}else{if(aj==="pending"){ah.container_div.addClass("pending");ah.content_div.text("Converting input data so that it can be used quickly with tool.");setTimeout(af,2000)}else{ai(aj)}}}})};af()}});var O=function(ag,af,ah,ai){this.name=ag;this.label=af;this.html=ah;this.value=ai};var g=function(ah,ag,aj,ak,ai,af){O.call(this,ah,ag,aj,ak);this.min=ai;this.max=af};var h=function(ag,af,ah,ai){this.name=ag;this.index=af;this.tool_id=ah;this.tool_exp_name=ai};var V=function(ag,af,ah,ai){h.call(this,ag,af,ah,ai);this.low=-Number.MAX_VALUE;this.high=Number.MAX_VALUE;this.min=Number.MAX_VALUE;this.max=-Number.MAX_VALUE;this.container=null;this.slider=null;this.slider_label=null};p(V.prototype,{applies_to:function(af){if(af.length>this.index){return true}return false},keep:function(af){if(!this.applies_to(af)){return true}var ag=af[this.index];return(isNaN(ag)||(ag>=this.low&&ag<=this.high))},update_attrs:function(ag){var af=false;if(!this.applies_to(ag)){return af}if(ag[this.index]<this.min){this.min=Math.floor(ag[this.index]);af=true}if(ag[this.index]>this.max){this.max=Math.ceil(ag[this.index]);af=true}return af},update_ui_elt:function(){if(this.min!=this.max){this.container.show()}else{this.container.hide()}var ah=function(ak,ai){var aj=ai-ak;return(aj<=2?0.01:1)};var ag=this.slider.slider("option","min"),af=this.slider.slider("option","max");if(this.min<ag||this.max>af){this.slider.slider("option","min",this.min);this.slider.slider("option","max",this.max);this.slider.slider("option","step",ah(this.min,this.max));this.slider.slider("option","values",[this.min,this.max])}}});var aa=function(aq,ay){this.track=aq;this.filters=[];for(var at=0;at<ay.length;at++){var au=ay[at],az=au.name,af=au.type,ah=au.index,ax=au.tool_id,aw=au.tool_exp_name;if(af==="int"||af==="float"){this.filters[at]=new V(az,ah,ax,aw)}else{console.log("ERROR: unsupported filter: ",az,af)}}var ai=function(aA,aB,aC){aA.click(function(){var aD=aB.text();max=parseFloat(aC.slider("option","max")),input_size=(max<=1?4:max<=1000000?max.toString().length:6),multi_value=false;if(aC.slider("option","values")){input_size=2*input_size+1;multi_value=true}aB.text("");$("<input type='text'/>").attr("size",input_size).attr("maxlength",input_size).attr("value",aD).appendTo(aB).focus().select().click(function(aE){aE.stopPropagation()}).blur(function(){$(this).remove();aB.text(aD)}).keyup(function(aI){if(aI.keyCode===27){$(this).trigger("blur")}else{if(aI.keyCode===13){var aG=aC.slider("option","min"),aE=aC.slider("option","max"),aH=function(aJ){return(isNaN(aJ)||aJ>aE||aJ<aG)},aF=$(this).val();if(!multi_value){aF=parseFloat(aF);if(aH(aF)){alert("Parameter value must be in the range ["+aG+"-"+aE+"]");return $(this)}}else{aF=aF.split("-");aF=[parseFloat(aF[0]),parseFloat(aF[1])];if(aH(aF[0])||aH(aF[1])){alert("Parameter value must be in the range ["+aG+"-"+aE+"]");return $(this)}}aC.slider((multi_value?"values":"value"),aF)}}})})};this.parent_div=$("<div/>").addClass("filters").hide();this.parent_div.bind("drag",function(aA){aA.stopPropagation()}).click(function(aA){aA.stopPropagation()}).bind("dblclick",function(aA){aA.stopPropagation()}).bind("keydown",function(aA){aA.stopPropagation()});var av=$("<div/>").addClass("sliders").appendTo(this.parent_div);var an=this;$.each(this.filters,function(aD,aF){aF.container=$("<div/>").addClass("filter-row slider-row").appendTo(av);var aE=$("<div/>").addClass("elt-label").appendTo(aF.container);var aC=$("<span/>").addClass("slider-name").text(aF.name+" ").appendTo(aE);var aB=$("<span/>");var aH=$("<span/>").addClass("slider-value").appendTo(aE).append("[").append(aB).append("]");var aA=$("<div/>").addClass("slider").appendTo(aF.container);aF.control_element=$("<div/>").attr("id",aF.name+"-filter-control").appendTo(aA);var aG=[0,0];aF.control_element.slider({range:true,min:Number.MAX_VALUE,max:-Number.MIN_VALUE,values:[0,0],slide:function(aJ,aK){var aI=aK.values;aB.text(aI[0]+"-"+aI[1]);aF.low=aI[0];aF.high=aI[1];an.track.request_draw(true,true)},change:function(aI,aJ){aF.control_element.slider("option","slide").call(aF.control_element,aI,aJ)}});aF.slider=aF.control_element;aF.slider_label=aB;ai(aH,aB,aF.control_element);$("<div style='clear: both;'/>").appendTo(aF.container)});if(this.filters.length!==0){var ak=$("<div/>").addClass("param-row").appendTo(av);var am=$("<input type='submit'/>").attr("value","Run on complete dataset").appendTo(ak);var ag=this;am.click(function(){ag.run_on_dataset()})}var ap=$("<div/>").addClass("display-controls").appendTo(this.parent_div),ar,al,ao,aj={Transparency:function(aA){an.alpha_filter=aA},Height:function(aA){an.height_filter=aA}};$.each(aj,function(aC,aB){ar=$("<div/>").addClass("filter-row").appendTo(ap),al=$("<span/>").addClass("elt-label").text(aC+":").appendTo(ar),ao=$("<select/>").attr("name",aC+"_dropdown").css("float","right").appendTo(ar);$("<option/>").attr("value",-1).text("== None ==").appendTo(ao);for(var aA=0;aA<an.filters.length;aA++){$("<option/>").attr("value",aA).text(an.filters[aA].name).appendTo(ao)}ao.change(function(){$(this).children("option:selected").each(function(){var aD=parseInt($(this).val());aj[aC]((aD>=0?an.filters[aD]:null));an.track.request_draw(true,true)})});$("<div style='clear: both;'/>").appendTo(ar)});$("<div style='clear: both;'/>").appendTo(this.parent_div)};p(aa.prototype,{reset_filters:function(){for(var af=0;af<this.filters.length;af++){filter=this.filters[af];filter.slider.slider("option","values",[filter.min,filter.max])}this.alpha_filter=null;this.height_filter=null},run_on_dataset:function(){var an=function(ar,ap,aq){if(!(ap in ar)){ar[ap]=aq}return ar[ap]};var ah={},af,ag,ai;for(var aj=0;aj<this.filters.length;aj++){af=this.filters[aj];if(af.tool_id){if(af.min!=af.low){ag=an(ah,af.tool_id,[]);ag[ag.length]=af.tool_exp_name+" >= "+af.low}if(af.max!=af.high){ag=an(ah,af.tool_id,[]);ag[ag.length]=af.tool_exp_name+" <= "+af.high}}}var al=[];for(var ao in ah){al[al.length]=[ao,ah[ao]]}var am=al.length;(function ak(aw,at){var aq=at[0],ar=aq[0],av=aq[1],au="("+av.join(") and (")+")",ap={cond:au,input:aw,target_dataset_id:aw,tool_id:ar},at=at.slice(1);$.getJSON(run_tool_url,ap,function(ax){if(ax.error){show_modal("Filter Dataset","Error running tool "+ar,{Close:hide_modal})}else{if(at.length===0){show_modal("Filtering Dataset","Filter(s) are running on the complete dataset. Outputs are in dataset's history.",{Close:hide_modal})}else{ak(ax.dataset_id,at)}}})})(this.track.dataset_id,al)}});var D=function(af,ag){M.Scaler.call(this,ag);this.filter=af};D.prototype.gen_val=function(af){if(this.filter.high===Number.MAX_VALUE||this.filter.low===-Number.MAX_VALUE||this.filter.low===this.filter.high){return this.default_val}return((parseFloat(af[this.filter.index])-this.filter.low)/(this.filter.high-this.filter.low))};var G=function(af){this.track=af.track;this.params=af.params;this.values={};this.restore_values((af.saved_values?af.saved_values:{}));this.onchange=af.onchange};p(G.prototype,{restore_values:function(af){var ag=this;$.each(this.params,function(ah,ai){if(af[ai.key]!==undefined){ag.values[ai.key]=af[ai.key]}else{ag.values[ai.key]=ai.default_value}})},build_form:function(){var ag=this;var af=$("<div />");$.each(this.params,function(ak,ai){if(!ai.hidden){var ah="param_"+ak;var am=ag.values[ai.key];var ap=$("<div class='form-row' />").appendTo(af);ap.append($("<label />").attr("for",ah).text(ai.label+":"));if(ai.type==="bool"){ap.append($('<input type="checkbox" />').attr("id",ah).attr("name",ah).attr("checked",am))}else{if(ai.type==="text"){ap.append($('<input type="text"/>').attr("id",ah).val(am).click(function(){$(this).select()}))}else{if(ai.type==="color"){var al=$("<input />").attr("id",ah).attr("name",ah).val(am);var an=$("<div class='tipsy tipsy-north' style='position: absolute;' />").hide();var aj=$("<div style='background-color: black; padding: 10px;'></div>").appendTo(an);var ao=$("<div/>").appendTo(aj).farbtastic({width:100,height:100,callback:al,color:am});$("<div />").append(al).append(an).appendTo(ap).bind("click",function(aq){an.css({left:$(this).position().left+($(al).width()/2)-60,top:$(this).position().top+$(this.height)}).show();$(document).bind("click.color-picker",function(){an.hide();$(document).unbind("click.color-picker")});aq.stopPropagation()})}else{ap.append($("<input />").attr("id",ah).attr("name",ah).val(am))}}}}});return af},update_from_form:function(af){var ah=this;var ag=false;$.each(this.params,function(ai,ak){if(!ak.hidden){var al="param_"+ai;var aj=af.find("#"+al).val();if(ak.type==="float"){aj=parseFloat(aj)}else{if(ak.type==="int"){aj=parseInt(aj)}else{if(ak.type==="bool"){aj=af.find("#"+al).is(":checked")}}}if(aj!==ah.values[ak.key]){ah.values[ak.key]=aj;ag=true}}});if(ag){this.onchange()}}});var b=function(af,ai,ah,ag,aj){this.track=af;this.index=ai;this.low=ai*R*ah;this.high=(ai+1)*R*ah;this.resolution=ah;this.canvas=$("<div class='track-tile'/>").append(ag);this.data=aj;this.stale=false};b.prototype.predisplay_actions=function(){};var k=function(af,ai,ah,ag,aj,ak){b.call(this,af,ai,ah,ag,aj);this.max_val=ak};p(k.prototype,b.prototype);var P=function(af,aj,ai,ah,al,am,ak,ag){b.call(this,af,aj,ai,ah,al);this.mode=am;this.message=ak;this.feature_mapper=ag};p(P.prototype,b.prototype);P.prototype.predisplay_actions=function(){var ag=this,af={};if(ag.mode!=="Pack"){return}$(this.canvas).mousemove(function(ar){var am=$(this).offset(),aq=ar.pageX-am.left,ap=ar.pageY-am.top,aw=ag.feature_mapper.get_feature_data(aq,ap),an=(aw?aw[0]:null);$(this).siblings(".feature-popup").each(function(){if(!an||$(this).attr("id")!==an.toString()){$(this).remove()}});if(aw){var ai=af[an];if(!ai){var an=aw[0],at={name:aw[3],start:aw[1],end:aw[2],strand:aw[4]},al=ag.track.filters_manager.filters,ak;for(var ao=0;ao<al.length;ao++){ak=al[ao];at[ak.name]=aw[ak.index]}var ai=$("<div/>").attr("id",an).addClass("feature-popup"),av,au,ax=$("<table/>").appendTo(ai),ay;for(av in at){au=at[av];ay=$("<tr/>").appendTo(ax);$("<th/>").appendTo(ay).text(av);$("<td/>").attr("align","left").appendTo(ay).text(typeof(au)=="number"?Z(au,2):au)}af[an]=ai}ai.appendTo($(ag.canvas).parent());var aj=aq+parseInt(ag.canvas.css("left"))+7,ah=ap+parseInt(ag.canvas.css("top"))+7;ai.css("left",aj+"px").css("top",ah+"px")}else{if(!ar.isPropagationStopped()){ar.stopPropagation();$(this).siblings().each(function(){$(this).trigger(ar)})}}}).mouseleave(function(){$(this).siblings(".feature-popup").remove()})};var i=function(ai,aq,aj,am,ar,ah,ag){q.call(this,ai,aq,aj,{},"draghandle");this.data_url=(ah?ah:default_data_url);this.data_url_extra_params={};this.data_query_wait=(ag?ag:L);this.dataset_check_url=converted_datasets_state_url;if(!i.id_counter){i.id_counter=0}this.id=i.id_counter++;this.container_div=$("<div />").addClass("track").attr("id","track_"+this.id).css("position","relative");if(am){this.header_div=$("<div class='track-header' />").appendTo(this.container_div);if(this.view.editor){this.drag_div=$("<div/>").addClass(this.drag_handle_class).appendTo(this.header_div)}this.name_div=$("<div/>").addClass("track-name").appendTo(this.header_div).text(this.name).attr("id",this.name.replace(/\s+/g,"-").replace(/[^a-zA-Z0-9\-]/g,"").toLowerCase());this.icons_div=$("<div/>").css("float","left").appendTo(this.header_div).hide();this.settings_icon=$("<a/>").attr("href","javascript:void(0);").attr("title","Edit settings").addClass("icon-button settings-icon").tipsy({gravity:"s"}).appendTo(this.icons_div);this.overview_icon=$("<a/>").attr("href","javascript:void(0);").attr("title","Set as overview").addClass("icon-button overview-icon").tipsy({gravity:"s"}).appendTo(this.icons_div);this.filters_icon=$("<a/>").attr("href","javascript:void(0);").attr("title","Filters").addClass("icon-button filters-icon").tipsy({gravity:"s"}).appendTo(this.icons_div).hide();this.tools_icon=$("<a/>").attr("href","javascript:void(0);").attr("title","Tools").addClass("icon-button tools-icon").tipsy({gravity:"s"}).appendTo(this.icons_div).hide();this.remove_icon=$("<a/>").attr("href","javascript:void(0);").attr("title","Remove").addClass("icon-button remove-icon").tipsy({gravity:"s"}).appendTo(this.icons_div);var ak=this;this.header_div.dblclick(function(at){at.stopPropagation()});this.settings_icon.click(function(){var av=function(){hide_modal();$(window).unbind("keypress.check_enter_esc")},at=function(){ak.config.update_from_form($(".dialog-box"));hide_modal();$(window).unbind("keypress.check_enter_esc")},au=function(aw){if((aw.keyCode||aw.which)===27){av()}else{if((aw.keyCode||aw.which)===13){at()}}};$(window).bind("keypress.check_enter_esc",au);show_modal("Configure Track",ak.config.build_form(),{Cancel:av,OK:at})});this.overview_icon.click(function(){ak.view.set_overview(ak)});this.filters_icon.click(function(){ak.filters_div.toggle();ak.filters_manager.reset_filters()});this.tools_icon.click(function(){ak.dynamic_tool_div.toggle();if(ak.dynamic_tool_div.is(":visible")){ak.set_name(ak.name+ak.tool_region_and_parameters_str())}else{ak.revert_name()}$(".tipsy").remove()});this.remove_icon.click(function(){$(".tipsy").remove();ak.remove()});if(ak.display_modes!==undefined){if(ak.mode_div===undefined){ak.mode_div=$("<div class='right-float menubutton popup' />").appendTo(ak.header_div);var al=(ak.config&&ak.config.values.mode?ak.config.values.mode:ak.display_modes[0]);ak.mode=al;ak.mode_div.text(al);var af={};for(var an=0,ap=ak.display_modes.length;an<ap;an++){var ao=ak.display_modes[an];af[ao]=function(at){return function(){ak.change_mode(at)}}(ao)}make_popupmenu(ak.mode_div,af)}else{ak.mode_div.hide()}this.header_div.append($("<div/>").css("clear","both"));this.container_div.hover(function(){ak.icons_div.show()},function(){ak.icons_div.hide()})}}this.content_div=$("<div class='track-content'>").appendTo(this.container_div);this.container.content_div.append(this.container_div)};p(i.prototype,q.prototype,{get_type:function(){if(this instanceof ab){return"LabelTrack"}else{if(this instanceof A){return"ReferenceTrack"}else{if(this instanceof j){return"LineTrack"}else{if(this instanceof W){return"ReadTrack"}else{if(this instanceof U){return"VcfTrack"}else{if(this instanceof e){return"FeatureTrack"}}}}}}return""},init:function(){var af=this;af.enabled=false;af.tile_cache.clear();af.data_manager.clear();af.initial_canvas=undefined;af.content_div.css("height","auto");af.container_div.removeClass("nodata error pending");if(!af.dataset_id){return}$.getJSON(converted_datasets_state_url,{hda_ldda:af.hda_ldda,dataset_id:af.dataset_id,chrom:af.view.chrom},function(ag){if(!ag||ag==="error"||ag.kind==="error"){af.container_div.addClass("error");af.content_div.text(o);if(ag.message){var ah=$(" <a href='javascript:void(0);'></a>").text("View error").click(function(){show_modal("Trackster Error","<pre>"+ag.message+"</pre>",{Close:hide_modal})});af.content_div.append(ah)}}else{if(ag==="no converter"){af.container_div.addClass("error");af.content_div.text(K)}else{if(ag==="no data"||(ag.data!==undefined&&(ag.data===null||ag.data.length===0))){af.container_div.addClass("nodata");af.content_div.text(F)}else{if(ag==="pending"){af.container_div.addClass("pending");af.content_div.text(t);setTimeout(function(){af.init()},af.data_query_wait)}else{if(ag.status==="data"){if(ag.valid_chroms){af.valid_chroms=ag.valid_chroms;af.update_track_icons()}af.content_div.text(Y);if(af.view.chrom){af.content_div.text("");af.content_div.css("height",af.height_px+"px");af.enabled=true;$.when(af.predraw_init()).done(function(){af.container_div.removeClass("nodata error pending");af.request_draw()})}}}}}}});this.update_track_icons()},predraw_init:function(){}});var N=function(aj,ah,ag,am,ai,al,ak){i.call(this,aj,ah,ag,am,ai);var af=this,ah=af.view;m(af.container_div,af.drag_handle_class,".group",af);this.filters_manager=new aa(this,(al!==undefined?al:{}));this.filters_available=false;this.filters_visible=false;this.tool=(ak!==undefined&&obj_length(ak)>0?new r(this,ak):undefined);if(this.header_div){if(this.filters_manager){this.filters_div=this.filters_manager.parent_div;this.header_div.after(this.filters_div)}if(this.tool){this.dynamic_tool_div=this.tool.parent_div;this.header_div.after(this.dynamic_tool_div)}}};p(N.prototype,q.prototype,i.prototype,{copy:function(af){return new this.constructor(this.name,this.view,af,this.hda_ldda,this.dataset_id,this.prefs,this.filters,this.tool)},to_json:function(){return{track_type:this.get_type(),name:this.name,hda_ldda:this.hda_ldda,dataset_id:this.dataset_id,prefs:this.prefs,mode:this.mode,}},change_mode:function(ag){var af=this;af.mode_div.text(ag);af.mode=ag;af.config.values.mode=ag;af.tile_cache.clear();af.request_draw();return af},update_track_icons:function(){var af=this;if(af.filters_available>0){af.filters_icon.show()}else{af.filters_icon.hide()}if(af.tool){af.tools_icon.show()}else{af.tools_icon.hide()}},_gen_tile_cache_key:function(ag,ah,af){return ag+"_"+ah+"_"+af},request_draw:function(ag,af){this.view.request_redraw(false,ag,af,this)},_draw:function(ah,ap){if(!this.enabled){return}if(!(this instanceof A)&&(!this.dataset_id)){return}var ao=this.view.low,al=this.view.high,am=al-ao,ai=this.view.container.width(),at=ai/am,ak=this.view.resolution,ar=$("<div style='position: relative;'></div>");if(this.is_overview){ao=this.view.max_low;al=this.view.max_high;ak=Math.pow(C,Math.ceil(Math.log((view.max_high-view.max_low)/R)/Math.log(C)));at=ai/(view.max_high-view.max_low)}if(!ap){this.content_div.children().remove()}this.content_div.append(ar);this.max_height=0;var ag=Math.floor(ao/ak/R);var an=true;var aq=[];var af=0;while((ag*R*ak)<al){tile=this.draw_helper(ah,ai,ag,ak,ar,at);if(tile){aq.push(tile)}else{an=false}ag+=1;af++}var aj=this;if(an){aj.postdraw_actions(aq,ai,at,ap)}},postdraw_actions:function(aj,ak,al,af){var ah=this;var ai=false;for(var ag=0;ag<aj.length;ag++){if(aj[ag].message){ai=true;break}}if(ai){for(var ag=0;ag<aj.length;ag++){tile=aj[ag];if(!tile.message){tile.canvas.css("padding-top",E)}}}},draw_helper:function(ag,ah,ai,al,ar,aw,at,am){var aj=this,aq=this._gen_tile_cache_key(ah,aw,ai),an=ai*R*al,av=an+R*al;var ao=(ag?undefined:aj.tile_cache.get(aq));if(ao){aj.show_tile(ao,ar,aw);return ao}var ap=function(ax){return("isResolved" in ax)};var ak=true;var af=aj.data_manager.get_data(an,av,aj.mode,al,aj.data_url_extra_params);if(ap(af)){ak=false}var au;if(view.reference_track&&aw>view.canvas_manager.char_width_px){au=view.reference_track.data_manager.get_data(an,av,aj.mode,al,view.reference_track.data_url_extra_params);if(ap(au)){ak=false}}if(ak){p(af,am);var ao=aj.draw_tile(af,aj.mode,al,ai,aw,au);if(ao!==undefined){aj.tile_cache.set(aq,ao);aj.show_tile(ao,ar,aw)}return ao}$.when(af,au).then(function(){view.request_redraw(false,false,false,aj)});return null},show_tile:function(al,an,ao){var ah=this,ag=al.canvas,ak=ag;if(al.message){var ap=$("<div/>"),am=$("<div/>").addClass("tile-message").text(al.message).css({height:E-1,width:al.canvas.width}).appendTo(ap),aj=$("<a href='javascript:void(0);'/>").addClass("icon more-down").appendTo(am),af=$("<a href='javascript:void(0);'/>").addClass("icon more-across").appendTo(am);ap.append(ag);ak=ap;aj.click(function(){al.stale=true;ah.data_manager.get_more_data(al.low,al.high,ah.mode,al.resolution,{},ah.data_manager.DEEP_DATA_REQ);ah.request_draw()}).dblclick(function(aq){aq.stopPropagation()});af.click(function(){al.stale=true;ah.data_manager.get_more_data(al.low,al.high,ah.mode,al.resolution,{},ah.data_manager.BROAD_DATA_REQ);ah.request_draw()}).dblclick(function(aq){aq.stopPropagation()})}al.predisplay_actions();var ai=(al.low-(this.is_overview?this.view.max_low:this.view.low))*ao;if(this.left_offset){ai-=this.left_offset}ak.css({position:"absolute",top:0,left:ai,height:""});an.append(ak);ah.max_height=Math.max(ah.max_height,ak.height());ah.content_div.css("height",ah.max_height+"px");an.children().css("height",ah.max_height+"px")},_get_tile_bounds:function(af,ag){var ai=af*R*ag,aj=R*ag,ah=(ai+aj<=this.view.max_high?ai+aj:this.view.max_high);return[ai,ah]},tool_region_and_parameters_str:function(ah,af,ai){var ag=this,aj=(ah!==undefined&&af!==undefined&&ai!==undefined?ah+":"+af+"-"+ai:"all");return" - region=["+aj+"], parameters=["+ag.tool.get_param_values().join(", ")+"]"},init_for_tool_data:function(){this.data_url=raw_data_url;this.data_query_wait=1000;this.dataset_check_url=dataset_state_url;this.predraw_init=function(){var ag=this;var af=function(){if(ag.data_manager.size()===0){setTimeout(af,300)}else{ag.data_url=default_data_url;ag.data_query_wait=L;ag.dataset_state_url=converted_datasets_state_url;$.getJSON(ag.dataset_state_url,{dataset_id:ag.dataset_id,hda_ldda:ag.hda_ldda},function(ah){})}};af()}}});var ab=function(ag,af){i.call(this,"label",ag,af,false,{});this.container_div.addClass("label-track")};p(ab.prototype,i.prototype,{init:function(){this.enabled=true},_draw:function(){var ah=this.view,ai=ah.high-ah.low,al=Math.floor(Math.pow(10,Math.floor(Math.log(ai)/Math.log(10)))),af=Math.floor(ah.low/al)*al,aj=this.view.container.width(),ag=$("<div style='position: relative; height: 1.3em;'></div>");while(af<ah.high){var ak=(af-ah.low)/ai*aj;ag.append($("<div class='label'>"+commatize(af)+"</div>").css({position:"absolute",left:ak-1}));af+=al}this.content_div.children(":first").remove();this.content_div.append(ag)}});var A=function(af){N.call(this,"reference",af,{content_div:af.top_labeltrack},false,{});af.reference_track=this;this.left_offset=200;this.height_px=12;this.container_div.addClass("reference-track");this.content_div.css("background","none");this.content_div.css("min-height","0px");this.content_div.css("border","none");this.data_url=reference_url;this.data_url_extra_params={dbkey:af.dbkey};this.data_manager=new I(B,this,false);this.tile_cache=new c(u)};p(A.prototype,q.prototype,N.prototype,{init:function(){this.enabled=true},draw_tile:function(ap,al,ak,ag,aq){var aj=this,ah=R*ak;if(aq>this.view.canvas_manager.char_width_px){if(ap.data===null){aj.content_div.css("height","0px");return}var ai=this.view.canvas_manager.new_canvas();var ao=ai.getContext("2d");ai.width=Math.ceil(ah*aq+aj.left_offset);ai.height=aj.height_px;ao.font=ao.canvas.manager.default_font;ao.textAlign="center";ap=ap.data;for(var am=0,an=ap.length;am<an;am++){var af=Math.round(am*aq);ao.fillText(ap[am],af+aj.left_offset,10)}return new b(aj,ag,ak,ai,ap)}this.content_div.css("height","0px")}});var j=function(ak,ai,ah,al,af,aj){var ag=this;this.display_modes=["Histogram","Line","Filled","Intensity"];this.mode="Histogram";N.call(this,ak,ai,ah,true,aj);this.min_height_px=16;this.max_height_px=400;this.height_px=80;this.hda_ldda=al;this.dataset_id=af;this.original_dataset_id=af;this.data_manager=new S(B,this);this.tile_cache=new c(u);this.left_offset=0;this.config=new G({track:this,params:[{key:"name",label:"Name",type:"text",default_value:ak},{key:"color",label:"Color",type:"color",default_value:get_random_color()},{key:"min_value",label:"Min Value",type:"float",default_value:undefined},{key:"max_value",label:"Max Value",type:"float",default_value:undefined},{key:"mode",type:"string",default_value:this.mode,hidden:true},{key:"height",type:"int",default_value:this.height_px,hidden:true}],saved_values:aj,onchange:function(){ag.set_name(ag.prefs.name);ag.vertical_range=ag.prefs.max_value-ag.prefs.min_value;$("#linetrack_"+ag.dataset_id+"_minval").text(ag.prefs.min_value);$("#linetrack_"+ag.dataset_id+"_maxval").text(ag.prefs.max_value);ag.tile_cache.clear();ag.request_draw()}});this.prefs=this.config.values;this.height_px=this.config.values.height;this.vertical_range=this.config.values.max_value-this.config.values.min_value;this.add_resize_handle()};p(j.prototype,q.prototype,N.prototype,{add_resize_handle:function(){var af=this;var ai=false;var ah=false;var ag=$("<div class='track-resize'>");$(af.container_div).hover(function(){ai=true;ag.show()},function(){ai=false;if(!ah){ag.hide()}});ag.hide().bind("dragstart",function(aj,ak){ah=true;ak.original_height=$(af.content_div).height()}).bind("drag",function(ak,al){var aj=Math.min(Math.max(al.original_height+al.deltaY,af.min_height_px),af.max_height_px);$(af.content_div).css("height",aj);af.height_px=aj;af.request_draw(true)}).bind("dragend",function(aj,ak){af.tile_cache.clear();ah=false;if(!ai){ag.hide()}af.config.values.height=af.height_px}).appendTo(af.container_div)},predraw_init:function(){var af=this;af.vertical_range=undefined;return $.getJSON(af.data_url,{stats:true,chrom:af.view.chrom,low:null,high:null,hda_ldda:af.hda_ldda,dataset_id:af.dataset_id},function(ag){af.container_div.addClass("line-track");var ai=ag.data;if(isNaN(parseFloat(af.prefs.min_value))||isNaN(parseFloat(af.prefs.max_value))){af.prefs.min_value=ai.min;af.prefs.max_value=ai.max;$("#track_"+af.dataset_id+"_minval").val(af.prefs.min_value);$("#track_"+af.dataset_id+"_maxval").val(af.prefs.max_value)}af.vertical_range=af.prefs.max_value-af.prefs.min_value;af.total_frequency=ai.total_frequency;af.container_div.find(".yaxislabel").remove();var aj=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+af.dataset_id+"_minval").text(Z(af.prefs.min_value,3));var ah=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+af.dataset_id+"_maxval").text(Z(af.prefs.max_value,3));ah.css({position:"absolute",top:"24px",left:"10px"});ah.prependTo(af.container_div);aj.css({position:"absolute",bottom:"2px",left:"10px"});aj.prependTo(af.container_div)})},draw_tile:function(ar,ak,aj,ah,aq){if(this.vertical_range===undefined){return}var af=this._get_tile_bounds(ah,aj),al=af[0],ap=af[1],ag=Math.ceil((ap-al)*aq),an=this.height_px;var ai=this.view.canvas_manager.new_canvas();ai.width=ag,ai.height=an;var ao=ai.getContext("2d");var am=new M.LinePainter(ar.data,al,ap,this.prefs,ak);am.draw(ao,ag,an);return new b(this.track,ah,aj,ai,ar.data)}});var e=function(af,al,ag,ak,an,am,ai,aj){var ah=this;this.display_modes=["Auto","Histogram","Dense","Squish","Pack"];N.call(this,af,al,ag,true,am,ai,aj);this.config=new G({track:this,params:[{key:"name",label:"Name",type:"text",default_value:af},{key:"block_color",label:"Block color",type:"color",default_value:get_random_color()},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:am,onchange:function(){ah.set_name(ah.prefs.name);ah.tile_cache.clear();ah.request_draw()}});this.prefs=this.config.values;this.height_px=0;this.container_div.addClass("feature-track");this.hda_ldda=ak;this.dataset_id=an;this.original_dataset_id=an;this.show_labels_scale=0.001;this.showing_details=false;this.summary_draw_height=30;this.inc_slots={};this.start_end_dct={};this.tile_cache=new c(d);this.data_manager=new S(20,this);this.left_offset=200;this.painter=M.LinkedFeaturePainter};p(e.prototype,q.prototype,N.prototype,{postdraw_actions:function(av,af,aw,au){N.prototype.postdraw_actions.call(this,av,au);var ai=this;if(au){var ak=ai.content_div.children();var al=false;for(var aj=ak.length-1,ap=0;aj>=ap;aj--){var ah=$(ak[aj]);if(al){ah.remove()}else{if(ah.children().length!==0){al=true}}}}if(ai.mode=="Histogram"){var ao=-1;for(var aj=0;aj<av.length;aj++){var at=av[aj].max_val;if(at>ao){ao=at}}for(var aj=0;aj<av.length;aj++){var ar=av[aj];if(ar.max_val!==ao){ar.canvas.remove();ai.draw_helper(true,af,ar.index,ar.resolution,ar.canvas.parent(),aw,[],{max:ao})}}}if(ai.filters_manager){var ag=ai.filters_manager.filters;for(var an=0;an<ag.length;an++){ag[an].update_ui_elt()}var am=false,aq;for(var aj=0;aj<av.length;aj++){if(av[aj].data.length){aq=av[aj].data[0];for(var an=0;an<ag.length;an++){if(ag[an].applies_to(aq)){am=true;break}}}}if(ai.filters_available!==am){ai.filters_available=am;if(!ai.filters_available){ai.filters_div.hide()}ai.update_track_icons()}}},update_auto_mode:function(af){if(this.mode=="Auto"){if(af=="no_detail"){af="feature spans"}else{if(af=="summary_tree"){af="coverage histogram"}}this.mode_div.text("Auto ("+af+")")}},incremental_slots:function(aj,ag,ai){var ah=this.view.canvas_manager.dummy_context,af=this.inc_slots[aj];if(!af||(af.mode!==ai)){af=new (s.FeatureSlotter)(aj,ai==="Pack",z,function(ak){return ah.measureText(ak)});af.mode=ai;this.inc_slots[aj]=af}return af.slot_features(ag)},get_summary_tree_data:function(aj,am,ah,av){if(av>ah-am){av=ah-am}var aq=Math.floor((ah-am)/av),au=[],ai=0;var ak=0,al=0,ap,at=0,an=[],ar,ao;var ag=function(ay,ax,az,aw){ay[0]=ax+az*aw;ay[1]=ax+(az+1)*aw};while(at<av&&ak!==aj.length){var af=false;for(;at<av&&!af;at++){ag(an,am,at,aq);for(al=ak;al<aj.length;al++){ap=aj[al].slice(1,3);if(is_overlap(ap,an)){af=true;break}}if(af){break}}data_start_index=al;au[au.length]=ar=[an[0],0];for(;al<aj.length;al++){ap=aj[al].slice(1,3);if(is_overlap(ap,an)){ar[1]++}else{break}}if(ar[1]>ai){ai=ar[1]}at++}return{max:ai,delta:aq,data:au}},draw_tile:function(au,ax,aB,aF,ap,ai){var ay=this,ak=ay._get_tile_bounds(aF,aB),aI=ak[0],ag=ak[1],aw=ag-aI,az=Math.ceil(aw*ap),aO=25,aj=this.left_offset,av,al;if(ax==="Auto"){if(au.dataset_type==="summary_tree"){ax=au.dataset_type}else{if(au.extra_info==="no_detail"||ay.is_overview){ax="no_detail"}else{var aN=au.data;if(this.view.high-this.view.low>J){ax="Squish"}else{ax="Pack"}}}this.update_auto_mode(ax)}if(ax==="summary_tree"||ax==="Histogram"){al=this.summary_draw_height;this.container_div.find(".yaxislabel").remove();var af=$("<div />").addClass("yaxislabel");af.text(au.max);af.css({position:"absolute",top:"24px",left:"10px",color:this.prefs.label_color});af.prependTo(this.container_div);var ah=this.view.canvas_manager.new_canvas();ah.width=az+aj;ah.height=al+T;if(au.dataset_type!="summary_tree"){var aq=this.get_summary_tree_data(au.data,aI,ag,200);if(au.max){aq.max=au.max}au=aq}var aK=new M.SummaryTreePainter(au,aI,ag,this.prefs);var aA=ah.getContext("2d");aA.translate(aj,T);aK.draw(aA,az,al);return new k(ay,aF,aB,ah,au.data,au.max)}var av,an=1;if(ax==="no_detail"||ax==="Squish"||ax==="Pack"){an=this.incremental_slots(ap,au.data,ax);av=this.inc_slots[ap].slots}var ao=[];if(au.data){var ar=this.filters_manager.filters;for(var aC=0,aE=au.data.length;aC<aE;aC++){var am=au.data[aC];var aD=false;var at;for(var aH=0,aM=ar.length;aH<aM;aH++){at=ar[aH];at.update_attrs(am);if(!at.keep(am)){aD=true;break}}if(!aD){ao.push(am)}}}var aL=(this.filters_manager.alpha_filter?new D(this.filters_manager.alpha_filter):null);var aJ=(this.filters_manager.height_filter?new D(this.filters_manager.height_filter):null);var aK=new (this.painter)(ao,aI,ag,this.prefs,ax,aL,aJ,ai);var al=Math.max(ad,aK.get_required_height(an));var ah=this.view.canvas_manager.new_canvas();var aG=null;ah.width=az+aj;ah.height=al;var aA=ah.getContext("2d");aA.fillStyle=this.prefs.block_color;aA.font=aA.canvas.manager.default_font;aA.textAlign="right";this.container_div.find(".yaxislabel").remove();if(au.data){aA.translate(aj,0);aG=aK.draw(aA,az,al,av);aG.translation=-aj}return new P(ay,aF,aB,ah,au.data,ax,au.message,aG)}});var U=function(ak,ah,ag,am,af,aj,al,ai){e.call(this,ak,ah,ag,am,af,aj,al,ai);this.config=new G({track:this,params:[{key:"name",label:"Name",type:"text",default_value:ak},{key:"block_color",label:"Block color",type:"color",default_value:get_random_color()},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_insertions",label:"Show insertions",type:"bool",default_value:false},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:aj,onchange:function(){this.track.set_name(this.track.prefs.name);this.track.tile_cache.clear();this.track.request_draw()}});this.prefs=this.config.values;this.painter=M.ReadPainter};p(U.prototype,q.prototype,N.prototype,e.prototype);var W=function(aj,ah,ag,al,af,ai,ak){e.call(this,aj,ah,ag,al,af,ai,ak);this.config=new G({track:this,params:[{key:"name",label:"Name",type:"text",default_value:aj},{key:"block_color",label:"Block color",type:"color",default_value:get_random_color()},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_insertions",label:"Show insertions",type:"bool",default_value:false},{key:"show_differences",label:"Show differences only",type:"bool",default_value:true},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:ai,onchange:function(){this.track.set_name(this.track.prefs.name);this.track.tile_cache.clear();this.track.request_draw()}});this.prefs=this.config.values;this.painter=M.ReadPainter;this.update_track_icons()};p(W.prototype,q.prototype,N.prototype,e.prototype);X.View=ac;X.DrawableGroup=Q;X.LineTrack=j;X.FeatureTrack=e;X.ReadTrack=W;X.VcfTrack=U};var slotting_module=function(c,b){var e=c("class").extend;var d=2,a=5;b.FeatureSlotter=function(i,h,f,g){this.slots={};this.start_end_dct={};this.w_scale=i;this.include_label=h;this.max_rows=f;this.measureText=g};e(b.FeatureSlotter.prototype,{slot_features:function(m){var p=this.w_scale,s=this.slots,h=this.start_end_dct,y=[],A=[],n=0,z=this.max_rows;for(var w=0,x=m.length;w<x;w++){var l=m[w],o=l[0];if(s[o]!==undefined){n=Math.max(n,s[o]);A.push(s[o])}else{y.push(w)}}var q=function(F,G){for(var E=0;E<=z;E++){var C=false,H=h[E];if(H!==undefined){for(var B=0,D=H.length;B<D;B++){var i=H[B];if(G>i[0]&&F<i[1]){C=true;break}}}if(!C){return E}}return -1};for(var w=0,x=y.length;w<x;w++){var l=m[y[w]],o=l[0],u=l[1],f=l[2],r=l[3],g=Math.floor(u*p),k=Math.ceil(f*p),v=this.measureText(r).width,j;if(r!==undefined&&this.include_label){v+=(d+a);if(g-v>=0){g-=v;j="left"}else{k+=v;j="right"}}var t=q(g,k);if(t>=0){if(h[t]===undefined){h[t]=[]}h[t].push([g,k]);s[o]=t;n=Math.max(n,t)}else{}}return n+1}})};var painters_module=function(i,w){var t=i("class").extend;var o=function(H,z,F,y,E,C){if(C===undefined){C=4}var B=y-z;var A=E-F;var D=Math.floor(Math.sqrt(B*B+A*A)/C);var I=B/D;var G=A/D;var x;for(x=0;x<D;x++,z+=I,F+=G){if(x%2!==0){continue}H.fillRect(z,F,C,1)}};var p=function(A,z,x,D){var C=z-D/2,B=z+D/2,E=x-Math.sqrt(D*3/2);A.beginPath();A.moveTo(C,E);A.lineTo(B,E);A.lineTo(z,x);A.lineTo(C,E);A.strokeStyle=this.fillStyle;A.fill();A.stroke();A.closePath()};var d=function(x){this.default_val=(x?x:1)};d.prototype.gen_val=function(x){return this.default_val};var l=function(z,B,x,y,A){this.data=z;this.view_start=B;this.view_end=x;this.prefs=t({},this.default_prefs,y);this.mode=A};l.prototype.default_prefs={};var u=function(z,B,x,y,A){l.call(this,z,B,x,y,A)};u.prototype.default_prefs={show_counts:false};u.prototype.draw=function(M,z,L){var E=this.view_start,O=this.view_end-this.view_start,N=z/O;var J=this.data.data,I=this.data.delta,G=this.data.max,B=L;delta_x_px=Math.ceil(I*N);M.save();for(var C=0,D=J.length;C<D;C++){var H=Math.floor((J[C][0]-E)*N);var F=J[C][1];if(!F){continue}var K=F/G*L;if(F!==0&&K<1){K=1}M.fillStyle=this.prefs.block_color;M.fillRect(H,B-K,delta_x_px,K);var A=4;if(this.prefs.show_counts&&(M.measureText(F).width+A)<delta_x_px){M.fillStyle=this.prefs.label_color;M.textAlign="center";M.fillText(F,H+(delta_x_px/2),10)}}M.restore()};var b=function(x,B,D,E,z){l.call(this,x,B,D,E,z);if(this.prefs.min_value===undefined){var F=Infinity;for(var y=0,A=this.data.length;y<A;y++){F=Math.min(F,this.data[y][1])}this.prefs.min_value=F}if(this.prefs.max_value===undefined){var C=-Infinity;for(var y=0,A=this.data.length;y<A;y++){C=Math.max(C,this.data[y][1])}this.prefs.max_value=C}};b.prototype.default_prefs={min_value:undefined,max_value:undefined,mode:"Histogram",color:"#000",overflow_color:"#F66"};b.prototype.draw=function(M,L,J){var E=false,G=this.prefs.min_value,C=this.prefs.max_value,I=C-G,x=J,z=this.view_start,K=this.view_end-this.view_start,A=L/K,H=this.mode,S=this.data;M.save();var T=Math.round(J+G/I*J);if(H!=="Intensity"){M.fillStyle="#aaa";M.fillRect(0,T,L,1)}M.beginPath();var Q,D,B;if(S.length>1){B=Math.ceil((S[1][0]-S[0][0])*A)}else{B=10}for(var N=0,O=S.length;N<O;N++){M.fillStyle=this.prefs.color;Q=Math.round((S[N][0]-z)*A);D=S[N][1];var P=false,F=false;if(D===null){if(E&&H==="Filled"){M.lineTo(Q,x)}E=false;continue}if(D<G){F=true;D=G}else{if(D>C){P=true;D=C}}if(H==="Histogram"){D=Math.round(D/I*x);M.fillRect(Q,T,B,-D)}else{if(H==="Intensity"){D=255-Math.floor((D-G)/I*255);M.fillStyle="rgb("+D+","+D+","+D+")";M.fillRect(Q,0,B,x)}else{D=Math.round(x-(D-G)/I*x);if(E){M.lineTo(Q,D)}else{E=true;if(H==="Filled"){M.moveTo(Q,x);M.lineTo(Q,D)}else{M.moveTo(Q,D)}}}}M.fillStyle=this.prefs.overflow_color;if(P||F){var R;if(H==="Histogram"||H==="Intensity"){R=B}else{Q-=2;R=4}if(P){M.fillRect(Q,0,R,3)}if(F){M.fillRect(Q,x-3,R,3)}}M.fillStyle=this.prefs.color}if(H==="Filled"){if(E){M.lineTo(Q,T);M.lineTo(0,T)}M.fill()}else{M.stroke()}M.restore()};var m=function(x){this.feature_positions={};this.slot_height=x;this.translation=0};m.prototype.map_feature_data=function(y,A,x,z){if(!this.feature_positions[A]){this.feature_positions[A]=[]}this.feature_positions[A].push({data:y,x_start:x,x_end:z})};m.prototype.get_feature_data=function(z,D){var C=Math.floor(D/this.slot_height),B;if(!this.feature_positions[C]){return null}z+=this.translation;for(var A=0;A<this.feature_positions[C].length;A++){B=this.feature_positions[C][A];if(z>=B.x_start&&z<=B.x_end){return B.data}}};var n=function(z,C,x,y,B,D,A){l.call(this,z,C,x,y,B);this.alpha_scaler=(D?D:new d());this.height_scaler=(A?A:new d())};n.prototype.default_prefs={block_color:"#FFF",connector_color:"#FFF"};t(n.prototype,{get_required_height:function(y){var x=y_scale=this.get_row_height(),z=this.mode;if(z==="no_detail"||z==="Squish"||z==="Pack"){x=y*y_scale}return x+Math.max(Math.round(y_scale/2),5)},draw:function(J,H,F,E){var P=this.data,C=this.view_start,L=this.view_end;J.save();J.fillStyle=this.prefs.block_color;J.textAlign="right";var G=this.view_end-this.view_start,D=H/G,K=this.get_row_height(),O=new m(K),A;for(var M=0,N=P.length;M<N;M++){var z=P[M],B=z[0],I=z[1],x=z[2],y=(E&&E[B]!==undefined?E[B]:null);if((I<L&&x>C)&&(this.mode=="Dense"||y!==null)){A=this.draw_element(J,this.mode,z,y,C,L,D,K,H);O.map_feature_data(z,y,A[0],A[1])}}J.restore();return O},draw_element:function(D,z,F,B,A,C,E,y,x){console.log("WARNING: Unimplemented function.");return[0,0]}});var c=10,h=3,k=5,v=10,f=1,r=3,e=3,a=9,j=2,g="#ccc";var q=function(z,C,x,y,B,D,A){n.call(this,z,C,x,y,B,D,A)};t(q.prototype,n.prototype,{get_row_height:function(){var y=this.mode,x;if(y==="Dense"){x=c}else{if(y==="no_detail"){x=h}else{if(y==="Squish"){x=k}else{x=v}}}return x},draw_element:function(L,C,U,G,N,af,aj,al,x){var R=U[0],ah=U[1],Z=U[2],P=U[3],aa=Math.floor(Math.max(0,(ah-N)*aj)),M=Math.ceil(Math.min(x,Math.max(0,(Z-N)*aj))),Y=aa,ak=M,X=(C==="Dense"?0:(0+G))*al,K,ad,Q=null,an=null,A=this.prefs.block_color,ac=this.prefs.label_color;L.globalAlpha=this.alpha_scaler.gen_val(U);if(C==="Dense"){G=1}if(C==="no_detail"){L.fillStyle=A;L.fillRect(aa,X+5,M-aa,f)}else{var J=U[4],W=U[5],ab=U[6],B=U[7];if(W&&ab){Q=Math.floor(Math.max(0,(W-N)*aj));an=Math.ceil(Math.min(x,Math.max(0,(ab-N)*aj)))}var ai,S;if(C==="Squish"||C==="Dense"){ai=1;S=e}else{ai=5;S=a}if(!B){if(U.strand){if(U.strand==="+"){L.fillStyle=L.canvas.manager.get_pattern("right_strand_inv")}else{if(U.strand==="-"){L.fillStyle=L.canvas.manager.get_pattern("left_strand_inv")}}}else{L.fillStyle=A}L.fillRect(aa,X,M-aa,S)}else{var I,T;if(C==="Squish"||C==="Dense"){L.fillStyle=g;I=X+Math.floor(e/2)+1;T=1}else{if(J){var I=X;var T=S;if(J==="+"){L.fillStyle=L.canvas.manager.get_pattern("right_strand")}else{if(J==="-"){L.fillStyle=L.canvas.manager.get_pattern("left_strand")}}}else{L.fillStyle=g;I+=(e/2)+1;T=1}}L.fillRect(aa,I,M-aa,T);var D;for(var ag=0,z=B.length;ag<z;ag++){var E=B[ag],y=Math.floor(Math.max(0,(E[0]-N)*aj)),V=Math.ceil(Math.min(x,Math.max((E[1]-N)*aj)));if(y>V){continue}L.fillStyle=A;L.fillRect(y,X+(S-ai)/2+1,V-y,ai);if(Q!==undefined&&ab>W&&!(y>an||V<Q)){var ae=Math.max(y,Q),H=Math.min(V,an);L.fillRect(ae,X+1,H-ae,S);if(B.length==1&&C=="Pack"){if(J==="+"){L.fillStyle=L.canvas.manager.get_pattern("right_strand_inv")}else{if(J==="-"){L.fillStyle=L.canvas.manager.get_pattern("left_strand_inv")}}if(ae+14<H){ae+=2;H-=2}L.fillRect(ae,X+1,H-ae,S)}}}if(C==="Pack"){L.globalAlpha=1;L.fillStyle="white";var F=this.height_scaler.gen_val(U),O=Math.ceil(S*F),am=Math.round((S-O)/2);if(F!==1){L.fillRect(aa,I+1,M-aa,am);L.fillRect(aa,I+S-am+1,M-aa,am)}}}L.globalAlpha=1;if(C==="Pack"&&ah>N){L.fillStyle=ac;if(N===0&&aa-L.measureText(P).width<0){L.textAlign="left";L.fillText(P,M+j,X+8);ak+=L.measureText(P).width+j}else{L.textAlign="right";L.fillText(P,aa-j,X+8);Y-=L.measureText(P).width+j}}}L.globalAlpha=1;return[Y,ak]}});var s=function(A,D,x,z,C,E,B,y){n.call(this,A,D,x,z,C,E,B);this.ref_seq=(y?y.data:null)};s.prototype.default_prefs=t({},n.prototype.default_prefs,{show_insertions:false});t(s.prototype,n.prototype,{get_row_height:function(){var x,y=this.mode;if(y==="Dense"){x=c}else{if(y==="Squish"){x=k}else{x=v;if(this.prefs.show_insertions){x*=2}}}return x},draw_read:function(U,P,L,Z,A,T,I,F,E){U.textAlign="center";var S=this,z=[Z,A],O=0,V=0,R=0,x=U.canvas.manager.char_width_px;var ae=[];if((P==="Pack"||this.mode==="Auto")&&F!==undefined&&L>x){R=Math.round(L/2)}if(!I){I=[[0,F.length]]}for(var M=0,X=I.length;M<X;M++){var J=I[M],B="MIDNSHP=X"[J[0]],N=J[1];if(B==="H"||B==="S"){O-=N}var G=T+O,ad=Math.floor(Math.max(0,(G-Z)*L)),H=Math.floor(Math.max(0,(G+N-Z)*L));if(ad===H){H+=1}switch(B){case"H":break;case"S":case"M":case"=":if(is_overlap([G,G+N],z)){var Q=F.slice(V,V+N);if(R>0){U.fillStyle=this.prefs.block_color;U.fillRect(ad-R,E+1,H-ad,9);U.fillStyle=g;for(var ab=0,y=Q.length;ab<y;ab++){if(this.prefs.show_differences&&this.ref_seq){var K=this.ref_seq[G-Z+ab];if(!K||K.toLowerCase()===Q[ab].toLowerCase()){continue}}if(G+ab>=Z&&G+ab<=A){var ac=Math.floor(Math.max(0,(G+ab-Z)*L));U.fillText(Q[ab],ac,E+9)}}}else{U.fillStyle=this.prefs.block_color;U.fillRect(ad,E+4,H-ad,e)}}V+=N;O+=N;break;case"N":U.fillStyle=g;U.fillRect(ad-R,E+5,H-ad,1);O+=N;break;case"D":U.fillStyle="red";U.fillRect(ad-R,E+4,H-ad,3);O+=N;break;case"P":break;case"I":var Y=ad-R;if(is_overlap([G,G+N],z)){var Q=F.slice(V,V+N);if(this.prefs.show_insertions){var D=ad-(H-ad)/2;if((P==="Pack"||this.mode==="Auto")&&F!==undefined&&L>x){U.fillStyle="yellow";U.fillRect(D-R,E-9,H-ad,9);ae[ae.length]={type:"triangle",data:[Y,E+4,5]};U.fillStyle=g;switch(compute_overlap([G,G+N],z)){case (OVERLAP_START):Q=Q.slice(Z-G);break;case (OVERLAP_END):Q=Q.slice(0,G-A);break;case (CONTAINED_BY):break;case (CONTAINS):Q=Q.slice(Z-G,G-A);break}for(var ab=0,y=Q.length;ab<y;ab++){var ac=Math.floor(Math.max(0,(G+ab-Z)*L));U.fillText(Q[ab],ac-(H-ad)/2,E)}}else{U.fillStyle="yellow";U.fillRect(D,E+(this.mode!=="Dense"?2:5),H-ad,(P!=="Dense"?e:r))}}else{if((P==="Pack"||this.mode==="Auto")&&F!==undefined&&L>x){ae.push({type:"text",data:[Q.length,Y,E+9]})}else{}}}V+=N;break;case"X":V+=N;break}}U.fillStyle="yellow";var aa,C,af;for(var W=0;W<ae.length;W++){aa=ae[W];C=aa.type;af=aa.data;if(C==="text"){U.save();U.font="bold "+U.font;U.fillText(af[0],af[1],af[2]);U.restore()}else{if(C=="triangle"){p(U,af[0],af[1],af[2])}}}},draw_element:function(Q,L,D,A,T,y,H,R,O){var G=D[0],P=D[1],z=D[2],I=D[3],C=Math.floor(Math.max(0,(P-T)*H)),E=Math.ceil(Math.min(O,Math.max(0,(z-T)*H))),B=(L==="Dense"?0:(0+A))*R,U=this.prefs.block_color,F=this.prefs.label_color,N=0;if((L==="Pack"||this.mode==="Auto")&&H>Q.canvas.manager.char_width_px){var N=Math.round(H/2)}Q.fillStyle=U;if(D[5] instanceof Array){var M=Math.floor(Math.max(0,(D[4][0]-T)*H)),K=Math.ceil(Math.min(O,Math.max(0,(D[4][1]-T)*H))),J=Math.floor(Math.max(0,(D[5][0]-T)*H)),x=Math.ceil(Math.min(O,Math.max(0,(D[5][1]-T)*H)));if(D[4][1]>=T&&D[4][0]<=y&&D[4][2]){this.draw_read(Q,L,H,T,y,D[4][0],D[4][2],D[4][3],B)}if(D[5][1]>=T&&D[5][0]<=y&&D[5][2]){this.draw_read(Q,L,H,T,y,D[5][0],D[5][2],D[5][3],B)}if(J>K){Q.fillStyle=g;o(Q,K-N,B+5,J-N,B+5)}}else{Q.fillStyle=U;this.draw_read(Q,L,H,T,y,P,D[4],D[5],B)}if(L==="Pack"&&P>T&&I!=="."){Q.fillStyle=this.prefs.label_color;var S=1;if(S===0&&C-Q.measureText(I).width<0){Q.textAlign="left";Q.fillText(I,E+j-N,B+8)}else{Q.textAlign="right";Q.fillText(I,C-j-N,B+8)}Q.fillStyle=U}return[0,0]}});w.Scaler=d;w.SummaryTreePainter=u;w.LinePainter=b;w.LinkedFeaturePainter=q;w.ReadPainter=s};(function(d){var c={};var b=function(e){return c[e]};var a=function(f,g){var e={};g(b,e);c[f]=e};a("class",class_module);a("slotting",slotting_module);a("painters",painters_module);a("trackster",trackster_module);for(key in c.trackster){d[key]=c.trackster[key]}})(window); \ No newline at end of file +var class_module=function(b,a){var c=function(){var f=arguments[0];for(var e=1;e<arguments.length;e++){var d=arguments[e];for(key in d){f[key]=d[key]}}return f};a.extend=c};var requestAnimationFrame=(function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(b,a){window.setTimeout(b,1000/60)}})();var BEFORE=1001,CONTAINS=1002,OVERLAP_START=1003,OVERLAP_END=1004,CONTAINED_BY=1005,AFTER=1006;var compute_overlap=function(e,b){var g=e[0],f=e[1],d=b[0],c=b[1],a;if(g<d){if(f<d){a=BEFORE}else{if(f<=c){a=OVERLAP_START}else{a=CONTAINS}}}else{if(g>c){a=AFTER}else{if(f<=c){a=CONTAINED_BY}else{a=OVERLAP_END}}}return a};var is_overlap=function(c,b){var a=compute_overlap(c,b);return(a!==BEFORE&&a!==AFTER)};var get_random_color=function(a){if(!a){a="#ffffff"}if(typeof(a)==="string"){a=[a]}for(var j=0;j<a.length;j++){a[j]=parseInt(a[j].slice(1),16)}var m=function(t,s,i){return((t*299)+(s*587)+(i*114))/1000};var e=function(u,t,v,r,i,s){return(Math.max(u,r)-Math.min(u,r))+(Math.max(t,i)-Math.min(t,i))+(Math.max(v,s)-Math.min(v,s))};var g,n,f,k,p,h,q,c,d,b,o,l=false;do{g=Math.random()*16777215;n=g|16711680;f=g|65280;k=g|255;d=m(n,f,k);l=true;for(var j=0;j<a.length;j++){p=a[j];h=p|16711680;q=p|65280;c=p|255;b=m(h,q,c);o=e(n,f,k,h,q,c);if((Math.abs(d-b)<125)||(o<500)){l=false;break}}}while(!l);return"#"+(16777216+g).toString(16).substr(1,6)};var trackster_module=function(f,X){var p=f("class").extend,s=f("slotting"),M=f("painters");var ae=function(af,ag){this.document=af;this.default_font=ag!==undefined?ag:"9px Monaco, Lucida Console, monospace";this.dummy_canvas=this.new_canvas();this.dummy_context=this.dummy_canvas.getContext("2d");this.dummy_context.font=this.default_font;this.char_width_px=this.dummy_context.measureText("A").width;this.patterns={};this.load_pattern("right_strand","/visualization/strand_right.png");this.load_pattern("left_strand","/visualization/strand_left.png");this.load_pattern("right_strand_inv","/visualization/strand_right_inv.png");this.load_pattern("left_strand_inv","/visualization/strand_left_inv.png")};p(ae.prototype,{load_pattern:function(af,aj){var ag=this.patterns,ah=this.dummy_context,ai=new Image();ai.src=image_path+aj;ai.onload=function(){ag[af]=ah.createPattern(ai,"repeat")}},get_pattern:function(af){return this.patterns[af]},new_canvas:function(){var af=this.document.createElement("canvas");if(window.G_vmlCanvasManager){G_vmlCanvasManager.initElement(af)}af.manager=this;return af}});var n={};var l=function(af,ag){n[af.attr("id")]=ag};var m=function(af,ah,aj,ai){aj=".group";var ag={};n[af.attr("id")]=ai;af.bind("drag",{handle:"."+ah,relative:true},function(ar,at){var aq=$(this);var aw=$(this).parent(),an=aw.children(),ap=n[$(this).attr("id")],am,al,au,ak,ao;al=$(this).parents(aj);if(al.length!==0){au=al.position().top;ak=au+al.outerHeight();if(at.offsetY<au){$(this).insertBefore(al);var av=n[al.attr("id")];av.remove_drawable(ap);av.container.add_drawable_before(ap,av);return}else{if(at.offsetY>ak){$(this).insertAfter(al);var av=n[al.attr("id")];av.remove_drawable(ap);av.container.add_drawable(ap);return}}}al=null;for(ao=0;ao<an.length;ao++){am=$(an.get(ao));au=am.position().top;ak=au+am.outerHeight();if(am.is(aj)&&this!==am.get(0)&&at.offsetY>=au&&at.offsetY<=ak){if(at.offsetY-au<ak-at.offsetY){am.find(".content-div").prepend(this)}else{am.find(".content-div").append(this)}if(ap.container){ap.container.remove_drawable(ap)}n[am.attr("id")].add_drawable(ap);return}}for(ao=0;ao<an.length;ao++){if(at.offsetY<$(an.get(ao)).position().top){break}}if(ao===an.length){if(this!==an.get(ao-1)){aw.append(this);n[aw.attr("id")].move_drawable(ap,ao)}}else{if(this!==an.get(ao)){$(this).insertBefore(an.get(ao));n[aw.attr("id")].move_drawable(ap,(at.deltaY>0?ao-1:ao))}}}).bind("dragstart",function(){ag["border-top"]=af.css("border-top");ag["border-bottom"]=af.css("border-bottom");$(this).css({"border-top":"1px solid blue","border-bottom":"1px solid blue"})}).bind("dragend",function(){$(this).css(ag)})};X.moveable=m;var ad=16,H=9,E=20,T=H+2,z=100,J=12000,R=200,C=5,v=10,L=5000,w=100,o="There was an error in indexing this dataset. ",K="A converter for this dataset is not installed. Please check your datatypes_conf.xml file.",F="No data for this chrom/contig.",t="Currently indexing... please wait",x="Tool cannot be rerun: ",a="Loading data...",Y="Ready for display",d=10,u=5,B=5;function Z(ag,af){if(!af){af=0}var ah=Math.pow(10,af);return Math.round(ag*ah)/ah}var c=function(af){this.num_elements=af;this.clear()};p(c.prototype,{get:function(ag){var af=this.key_ary.indexOf(ag);if(af!==-1){if(this.obj_cache[ag].stale){this.key_ary.splice(af,1);delete this.obj_cache[ag]}else{this.move_key_to_end(ag,af)}}return this.obj_cache[ag]},set:function(ag,ah){if(!this.obj_cache[ag]){if(this.key_ary.length>=this.num_elements){var af=this.key_ary.shift();delete this.obj_cache[af]}this.key_ary.push(ag)}this.obj_cache[ag]=ah;return ah},move_key_to_end:function(ag,af){this.key_ary.splice(af,1);this.key_ary.push(ag)},clear:function(){this.obj_cache={};this.key_ary=[]},size:function(){return this.key_ary.length}});var S=function(ag,af,ah){c.call(this,ag);this.track=af;this.subset=(ah!==undefined?ah:true)};p(S.prototype,c.prototype,{load_data:function(ao,aj,am,ag,al){var an=this.track.view.chrom,ai={chrom:an,low:ao,high:aj,mode:am,resolution:ag,dataset_id:this.track.dataset_id,hda_ldda:this.track.hda_ldda};$.extend(ai,al);if(this.track.filters_manager){var ap=[];var af=this.track.filters_manager.filters;for(var ak=0;ak<af.length;ak++){ap[ap.length]=af[ak].name}ai.filter_cols=JSON.stringify(ap)}var ah=this;return $.getJSON(this.track.data_url,ai,function(aq){ah.set_data(ao,aj,am,aq)})},get_data:function(af,aj,ak,ag,ai){var ah=this.get_data_from_cache(af,aj,ak);if(ah){return ah}ah=this.load_data(af,aj,ak,ag,ai);this.set_data(af,aj,ak,ah);return ah},DEEP_DATA_REQ:"deep",BROAD_DATA_REQ:"breadth",get_more_data:function(an,ai,am,ah,al,aj){var ao=this.get_data_from_cache(an,ai,am);if(!ao){console.log("ERROR: no current data for: ",this.track,an,ai,am,ah,al);return}ao.stale=true;var ag=an;if(aj===this.DEEP_DATA_REQ){$.extend(al,{start_val:ao.data.length+1})}else{if(aj===this.BROAD_DATA_REQ){ag=(ao.max_high?ao.max_high:ao.data[ao.data.length-1][2])+1}}var af=this,ak=this.load_data(ag,ai,am,ah,al);new_data_available=$.Deferred();this.set_data(an,ai,am,new_data_available);$.when(ak).then(function(ap){if(ap.data){ap.data=ao.data.concat(ap.data);if(ap.max_low){ap.max_low=ao.max_low}if(ap.message){ap.message=ap.message.replace(/[0-9]+/,ap.data.length)}}af.set_data(an,ai,am,ap);new_data_available.resolve(ap)});return new_data_available},get_data_from_cache:function(af,ag,ah){return this.get(this.gen_key(af,ag,ah))},set_data:function(ag,ah,ai,af){return this.set(this.gen_key(ag,ah,ai),af)},gen_key:function(af,ah,ai){var ag=af+"_"+ah+"_"+ai;return ag},split_key:function(af){return af.split("_")}});var I=function(ag,af,ah){S.call(this,ag,af,ah)};p(I.prototype,S.prototype,c.prototype,{load_data:function(af,ai,aj,ag,ah){if(ag>1){return{data:null}}return S.prototype.load_data.call(this,af,ai,aj,ag,ah)}});var q=function(ai,ag,af,ah,aj){if(!q.id_counter){q.id_counter=0}this.id=q.id_counter++;this.name=ai;this.view=ag;this.container=af;this.config=new G({track:this,params:[{key:"name",label:"Name",type:"text",default_value:ai}],saved_values:ah,onchange:function(){this.track.set_name(this.track.config.values.name)}});this.prefs=this.config.values;this.drag_handle_class=aj;this.is_overview=false};p(q.prototype,{init:function(){},request_draw:function(){},_draw:function(){},to_json:function(){},update_icons:function(){},set_name:function(af){this.old_name=this.name;this.name=af;this.name_div.text(this.name)},revert_name:function(){this.name=this.old_name;this.name_div.text(this.name)},remove:function(){this.container.remove_drawable(this);this.container_div.hide(0,function(){$(this).remove();view.update_intro_div();view.has_changes=true})}});var y=function(aj,ai,ag,af,ah,ak){q.call(this,ai,ag,af,ah,ak);this.obj_type=aj;this.drawables=[]};p(y.prototype,q.prototype,{init:function(){for(var af=0;af<this.drawables.length;af++){this.drawables[af].init()}},_draw:function(){for(var af=0;af<this.drawables.length;af++){this.drawables[af]._draw()}},to_json:function(){var ag=[];for(var af=0;af<this.drawables.length;af++){ag.push(this.drawables[af].to_json())}return{name:this.name,prefs:this.prefs,obj_type:this.obj_type,drawables:ag}},add_drawable:function(af){this.drawables.push(af);af.container=this},add_drawable_before:function(ah,af){var ag=this.drawables.indexOf(af);if(ag!=-1){this.drawables.splice(ag,0,ah);return true}return false},remove_drawable:function(ag){var af=this.drawables.indexOf(ag);if(af!=-1){this.drawables.splice(af,1);ag.container=null;return true}return false},move_drawable:function(ag,ah){var af=this.drawables.indexOf(ag);if(af!=-1){this.drawables.splice(af,1);this.drawables.splice(ah,0,ag);return true}return false}});var Q=function(ai,ag,af,ah){y.call(this,"DrawableGroup",ai,ag,af,ah,"group-handle");this.container_div=$("<div/>").addClass("group").attr("id","group_"+this.id).appendTo(this.container.content_div);this.header_div=$("<div/>").addClass("track-header").appendTo(this.container_div);this.header_div.append($("<div/>").addClass(this.drag_handle_class));this.name_div=$("<div/>").addClass("group-name menubutton popup").text(this.name).appendTo(this.header_div);this.content_div=$("<div/>").addClass("content-div").attr("id","group_"+this.id+"_content_div").appendTo(this.container_div);l(this.container_div,this);l(this.content_div,this);m(this.container_div,this.drag_handle_class,".group",this);this.update_icons()};p(Q.prototype,q.prototype,y.prototype,{update_icons:function(){var ag=this;var af={};af["Edit configuration"]=function(){var aj=function(){hide_modal();$(window).unbind("keypress.check_enter_esc")},ah=function(){ag.config.update_from_form($(".dialog-box"));hide_modal();$(window).unbind("keypress.check_enter_esc")},ai=function(ak){if((ak.keyCode||ak.which)===27){aj()}else{if((ak.keyCode||ak.which)===13){ah()}}};$(window).bind("keypress.check_enter_esc",ai);show_modal("Configure Group",ag.config.build_form(),{Cancel:aj,OK:ah})};af.Remove=function(){ag.remove()};make_popupmenu(ag.name_div,af)}});var ac=function(af,ai,ah,ag){y.call(this,"View");this.container=af;this.chrom=null;this.vis_id=ah;this.dbkey=ag;this.title=ai;this.label_tracks=[];this.tracks_to_be_redrawn=[];this.max_low=0;this.max_high=0;this.zoom_factor=3;this.min_separation=30;this.has_changes=false;this.load_chroms_deferred=null;this.init();this.canvas_manager=new ae(af.get(0).ownerDocument);this.reset()};p(ac.prototype,y.prototype,{init:function(){var ah=this.container,af=this;this.top_container=$("<div/>").addClass("top-container").appendTo(ah);this.browser_content_div=$("<div/>").addClass("content").css("position","relative").appendTo(ah);this.bottom_container=$("<div/>").addClass("bottom-container").appendTo(ah);this.top_labeltrack=$("<div/>").addClass("top-labeltrack").appendTo(this.top_container);this.viewport_container=$("<div/>").addClass("viewport-container").attr("id","viewport-container").appendTo(this.browser_content_div);this.content_div=this.viewport_container;l(this.viewport_container,af);this.intro_div=$("<div/>").addClass("intro");var ai=$("<div/>").text("Add Datasets to Visualization").addClass("action-button").appendTo(this.intro_div).click(function(){add_tracks()});this.nav_labeltrack=$("<div/>").addClass("nav-labeltrack").appendTo(this.bottom_container);this.nav_container=$("<div/>").addClass("nav-container").prependTo(this.top_container);this.nav=$("<div/>").addClass("nav").appendTo(this.nav_container);this.overview=$("<div/>").addClass("overview").appendTo(this.bottom_container);this.overview_viewport=$("<div/>").addClass("overview-viewport").appendTo(this.overview);this.overview_close=$("<a/>").attr("href","javascript:void(0);").attr("title","Close overview").addClass("icon-button overview-close tooltip").hide().appendTo(this.overview_viewport);this.overview_highlight=$("<div/>").addClass("overview-highlight").hide().appendTo(this.overview_viewport);this.overview_box_background=$("<div/>").addClass("overview-boxback").appendTo(this.overview_viewport);this.overview_box=$("<div/>").addClass("overview-box").appendTo(this.overview_viewport);this.default_overview_height=this.overview_box.height();this.nav_controls=$("<div/>").addClass("nav-controls").appendTo(this.nav);this.chrom_select=$("<select/>").attr({name:"chrom"}).css("width","15em").addClass("no-autocomplete").append("<option value=''>Loading</option>").appendTo(this.nav_controls);var ag=function(aj){if(aj.type==="focusout"||(aj.keyCode||aj.which)===13||(aj.keyCode||aj.which)===27){if((aj.keyCode||aj.which)!==27){af.go_to($(this).val())}$(this).hide();$(this).val("");af.location_span.show();af.chrom_select.show()}};this.nav_input=$("<input/>").addClass("nav-input").hide().bind("keyup focusout",ag).appendTo(this.nav_controls);this.location_span=$("<span/>").addClass("location").attr("original-title","Click to change location").tipsy({gravity:"n"}).appendTo(this.nav_controls);this.location_span.click(function(){af.location_span.hide();af.chrom_select.hide();af.nav_input.val(af.chrom+":"+af.low+"-"+af.high);af.nav_input.css("display","inline-block");af.nav_input.select();af.nav_input.focus()});if(this.vis_id!==undefined){this.hidden_input=$("<input/>").attr("type","hidden").val(this.vis_id).appendTo(this.nav_controls)}this.zo_link=$("<a/>").attr("id","zoom-out").attr("title","Zoom out").tipsy({gravity:"n"}).click(function(){af.zoom_out();af.request_redraw()}).appendTo(this.nav_controls);this.zi_link=$("<a/>").attr("id","zoom-in").attr("title","Zoom in").tipsy({gravity:"n"}).click(function(){af.zoom_in();af.request_redraw()}).appendTo(this.nav_controls);this.load_chroms_deferred=this.load_chroms({low:0});this.chrom_select.bind("change",function(){af.change_chrom(af.chrom_select.val())});this.browser_content_div.click(function(aj){$(this).find("input").trigger("blur")});this.browser_content_div.bind("dblclick",function(aj){af.zoom_in(aj.pageX,this.viewport_container)});this.overview_box.bind("dragstart",function(aj,ak){this.current_x=ak.offsetX}).bind("drag",function(aj,al){var am=al.offsetX-this.current_x;this.current_x=al.offsetX;var ak=Math.round(am/af.viewport_container.width()*(af.max_high-af.max_low));af.move_delta(-ak)});this.overview_close.click(function(){af.reset_overview()});this.viewport_container.bind("draginit",function(aj,ak){if(aj.clientX>af.viewport_container.width()-16){return false}}).bind("dragstart",function(aj,ak){ak.original_low=af.low;ak.current_height=aj.clientY;ak.current_x=ak.offsetX}).bind("drag",function(al,an){var aj=$(this);var ao=an.offsetX-an.current_x;var ak=aj.scrollTop()-(al.clientY-an.current_height);aj.scrollTop(ak);an.current_height=al.clientY;an.current_x=an.offsetX;var am=Math.round(ao/af.viewport_container.width()*(af.high-af.low));af.move_delta(am)}).bind("mousewheel",function(al,an,ak,aj){if(ak){ak*=50;var am=Math.round(-ak/af.viewport_container.width()*(af.high-af.low));af.move_delta(am)}});this.top_labeltrack.bind("dragstart",function(aj,ak){return $("<div />").css({height:af.browser_content_div.height()+af.top_labeltrack.height()+af.nav_labeltrack.height()+1,top:"0px",position:"absolute","background-color":"#ccf",opacity:0.5,"z-index":1000}).appendTo($(this))}).bind("drag",function(an,ao){$(ao.proxy).css({left:Math.min(an.pageX,ao.startX),width:Math.abs(an.pageX-ao.startX)});var ak=Math.min(an.pageX,ao.startX)-af.container.offset().left,aj=Math.max(an.pageX,ao.startX)-af.container.offset().left,am=(af.high-af.low),al=af.viewport_container.width();af.update_location(Math.round(ak/al*am)+af.low,Math.round(aj/al*am)+af.low)}).bind("dragend",function(ao,ap){var ak=Math.min(ao.pageX,ap.startX),aj=Math.max(ao.pageX,ap.startX),am=(af.high-af.low),al=af.viewport_container.width(),an=af.low;af.low=Math.round(ak/al*am)+an;af.high=Math.round(aj/al*am)+an;$(ap.proxy).remove();af.request_redraw()});this.add_label_track(new ab(this,{content_div:this.top_labeltrack}));this.add_label_track(new ab(this,{content_div:this.nav_labeltrack}));$(window).bind("resize",function(){af.resize_window()});$(document).bind("redraw",function(){af.redraw()});this.reset();$(window).trigger("resize")},update_intro_div:function(){if(this.drawables.length===0){this.intro_div.appendTo(this.viewport_container)}else{this.intro_div.remove()}},update_location:function(af,ag){this.location_span.text(commatize(af)+" - "+commatize(ag));this.nav_input.val(this.chrom+":"+commatize(af)+"-"+commatize(ag))},load_chroms:function(ah){ah.num=w;$.extend(ah,(this.vis_id!==undefined?{vis_id:this.vis_id}:{dbkey:this.dbkey}));var af=this,ag=$.Deferred();$.ajax({url:chrom_url,data:ah,dataType:"json",success:function(aj){if(aj.chrom_info.length===0){alert("Invalid chromosome: "+ah.chrom);return}if(aj.reference){af.add_label_track(new A(af))}af.chrom_data=aj.chrom_info;var am='<option value="">Select Chrom/Contig</option>';for(var al=0,ai=af.chrom_data.length;al<ai;al++){var ak=af.chrom_data[al].chrom;am+='<option value="'+ak+'">'+ak+"</option>"}if(aj.prev_chroms){am+='<option value="previous">Previous '+w+"</option>"}if(aj.next_chroms){am+='<option value="next">Next '+w+"</option>"}af.chrom_select.html(am);af.chrom_start_index=aj.start_index;ag.resolve(aj)},error:function(){alert("Could not load chroms for this dbkey:",af.dbkey)}});return ag},change_chrom:function(ak,ag,am){if(!ak||ak==="None"){return}var ah=this;if(ak==="previous"){ah.load_chroms({low:this.chrom_start_index-w});return}if(ak==="next"){ah.load_chroms({low:this.chrom_start_index+w});return}var al=$.grep(ah.chrom_data,function(an,ao){return an.chrom===ak})[0];if(al===undefined){ah.load_chroms({chrom:ak},function(){ah.change_chrom(ak,ag,am)});return}else{if(ak!==ah.chrom){ah.chrom=ak;ah.chrom_select.val(ah.chrom);ah.max_high=al.len-1;ah.reset();ah.request_redraw(true);for(var aj=0,af=ah.drawables.length;aj<af;aj++){var ai=ah.drawables[aj];if(ai.init){ai.init()}}}if(ag!==undefined&&am!==undefined){ah.low=Math.max(ag,0);ah.high=Math.min(am,ah.max_high)}ah.reset_overview();ah.request_redraw()}},go_to:function(aj){aj=aj.replace(/ |,/g,"");var an=this,af,ai,ag=aj.split(":"),al=ag[0],am=ag[1];if(am!==undefined){try{var ak=am.split("-");af=parseInt(ak[0],10);ai=parseInt(ak[1],10)}catch(ah){return false}}an.change_chrom(al,af,ai)},move_fraction:function(ah){var af=this;var ag=af.high-af.low;this.move_delta(ah*ag)},move_delta:function(ah){var af=this;var ag=af.high-af.low;if(af.low-ah<af.max_low){af.low=af.max_low;af.high=af.max_low+ag}else{if(af.high-ah>af.max_high){af.high=af.max_high;af.low=af.max_high-ag}else{af.high-=ah;af.low-=ah}}af.request_redraw()},add_drawable:function(af){y.prototype.add_drawable.call(this,af);af.init();this.has_changes=true;this.update_intro_div()},add_label_track:function(af){af.view=this;af.init();this.label_tracks.push(af)},remove_drawable:function(ah,ag){y.prototype.remove_drawable.call(this,ah);if(ag){var af=this;ah.container_div.hide(0,function(){$(this).remove();af.update_intro_div()});this.has_changes=true}},reset:function(){this.low=this.max_low;this.high=this.max_high;this.viewport_container.find(".yaxislabel").remove()},request_redraw:function(an,af,am,ag){var al=this,aj=(ag?[ag]:al.drawables),ah;var ag;for(var ak=0;ak<aj.length;ak++){ag=aj[ak];ah=-1;for(var ai=0;ai<al.tracks_to_be_redrawn.length;ai++){if(al.tracks_to_be_redrawn[ai][0]===ag){ah=ai;break}}if(ah<0){al.tracks_to_be_redrawn.push([ag,af,am])}else{al.tracks_to_be_redrawn[ak][1]=af;al.tracks_to_be_redrawn[ak][2]=am}}requestAnimationFrame(function(){al._redraw(an)})},_redraw:function(ap){var am=this.low,ai=this.high;if(am<this.max_low){am=this.max_low}if(ai>this.max_high){ai=this.max_high}var ao=this.high-this.low;if(this.high!==0&&ao<this.min_separation){ai=am+this.min_separation}this.low=Math.floor(am);this.high=Math.ceil(ai);this.resolution=Math.pow(C,Math.ceil(Math.log((this.high-this.low)/R)/Math.log(C)));this.zoom_res=Math.pow(v,Math.max(0,Math.ceil(Math.log(this.resolution,v)/Math.log(v))));var af=(this.low/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var al=((this.high-this.low)/(this.max_high-this.max_low)*this.overview_viewport.width())||0;var aq=13;this.overview_box.css({left:af,width:Math.max(aq,al)}).show();if(al<aq){this.overview_box.css("left",af-(aq-al)/2)}if(this.overview_highlight){this.overview_highlight.css({left:af,width:al})}this.update_location(this.low,this.high);if(!ap){var ah,ag,an;for(var aj=0,ak=this.tracks_to_be_redrawn.length;aj<ak;aj++){ah=this.tracks_to_be_redrawn[aj][0];ag=this.tracks_to_be_redrawn[aj][1];an=this.tracks_to_be_redrawn[aj][2];if(ah){ah._draw(ag,an)}}this.tracks_to_be_redrawn=[];for(aj=0,ak=this.label_tracks.length;aj<ak;aj++){this.label_tracks[aj]._draw()}}},zoom_in:function(ag,ah){if(this.max_high===0||this.high-this.low<this.min_separation){return}var ai=this.high-this.low,aj=ai/2+this.low,af=(ai/this.zoom_factor)/2;if(ag){aj=ag/this.viewport_container.width()*(this.high-this.low)+this.low}this.low=Math.round(aj-af);this.high=Math.round(aj+af);this.request_redraw()},zoom_out:function(){if(this.max_high===0){return}var ag=this.high-this.low,ah=ag/2+this.low,af=(ag*this.zoom_factor)/2;this.low=Math.round(ah-af);this.high=Math.round(ah+af);this.request_redraw()},resize_window:function(){this.viewport_container.height(this.container.height()-this.top_container.height()-this.bottom_container.height());this.nav_container.width(this.container.width());this.request_redraw()},set_overview:function(ah){if(this.overview_drawable){if(this.overview_drawable.dataset_id===ah.dataset_id){return}this.overview_viewport.find(".track").remove()}var ag=ah.copy({content_div:this.overview_viewport}),af=this;ag.header_div.hide();ag.is_overview=true;af.overview_drawable=ag;this.overview_drawable.postdraw_actions=function(){af.overview_highlight.show().height(af.overview_drawable.content_div.height());af.overview_viewport.height(af.overview_drawable.content_div.height()+af.overview_box.outerHeight());af.overview_close.show();af.resize_window()};this.overview_drawable.init();af.has_changes=true},reset_overview:function(){$(".tipsy").remove();this.overview_viewport.find(".track-tile").remove();this.overview_viewport.height(this.default_overview_height);this.overview_box.height(this.default_overview_height);this.overview_close.hide();this.overview_highlight.hide();view.resize_window();view.overview_drawable=null}});var r=function(ah,al){this.track=ah;this.name=al.name;this.params=[];var at=al.params;for(var ai=0;ai<at.length;ai++){var an=at[ai],ag=an.name,ar=an.label,aj=unescape(an.html),au=an.value,ap=an.type;if(ap==="number"){this.params[this.params.length]=new g(ag,ar,aj,au,an.min,an.max)}else{if(ap=="select"){this.params[this.params.length]=new O(ag,ar,aj,au)}else{console.log("WARNING: unrecognized tool parameter type:",ag,ap)}}}this.parent_div=$("<div/>").addClass("dynamic-tool").hide();this.parent_div.bind("drag",function(aw){aw.stopPropagation()}).click(function(aw){aw.stopPropagation()}).bind("dblclick",function(aw){aw.stopPropagation()});var aq=$("<div class='tool-name'>").appendTo(this.parent_div).text(this.name);var ao=this.params;var am=this;$.each(this.params,function(ax,aA){var az=$("<div>").addClass("param-row").appendTo(am.parent_div);var aw=$("<div>").addClass("param-label").text(aA.label).appendTo(az);var ay=$("<div/>").addClass("slider").html(aA.html).appendTo(az);ay.find(":input").val(aA.value);$("<div style='clear: both;'/>").appendTo(az)});this.parent_div.find("input").click(function(){$(this).select()});var av=$("<div>").addClass("param-row").appendTo(this.parent_div);var ak=$("<input type='submit'>").attr("value","Run on complete dataset").appendTo(av);var af=$("<input type='submit'>").attr("value","Run on visible region").css("margin-left","3em").appendTo(av);var am=this;af.click(function(){am.run_on_region()});ak.click(function(){am.run_on_dataset()})};p(r.prototype,{get_param_values_dict:function(){var af={};this.parent_div.find(":input").each(function(){var ag=$(this).attr("name"),ah=$(this).val();af[ag]=JSON.stringify(ah)});return af},get_param_values:function(){var ag=[];var af={};this.parent_div.find(":input").each(function(){var ah=$(this).attr("name"),ai=$(this).val();if(ah){ag[ag.length]=ai}});return ag},run_on_dataset:function(){var af=this;af.run({dataset_id:this.track.original_dataset_id,tool_id:af.name},null,function(ag){show_modal(af.name+" is Running",af.name+" is running on the complete dataset. Tool outputs are in dataset's history.",{Close:hide_modal})})},run_on_region:function(){var ag={dataset_id:this.track.original_dataset_id,chrom:this.track.view.chrom,low:this.track.view.low,high:this.track.view.high,tool_id:this.name},aj=this.track,ah=ag.tool_id+aj.tool_region_and_parameters_str(ag.chrom,ag.low,ag.high),af;if(aj.container===view){var ai=new Q(this.name,this.track.view,this.track.container);aj.container.add_drawable(ai);aj.container.remove_drawable(aj);ai.add_drawable(aj);aj.container_div.appendTo(ai.content_div);af=ai}else{af=aj.container}var ak=new aj.constructor(ah,view,af,"hda");ak.init_for_tool_data();ak.change_mode(aj.mode);af.add_drawable(ak);ak.content_div.text("Starting job.");this.run(ag,ak,function(al){ak.dataset_id=al.dataset_id;ak.content_div.text("Running job.");ak.init()})},run:function(ag,ah,ai){$.extend(ag,this.get_param_values_dict());var af=function(){$.getJSON(rerun_tool_url,ag,function(aj){if(aj==="no converter"){ah.container_div.addClass("error");ah.content_div.text(K)}else{if(aj.error){ah.container_div.addClass("error");ah.content_div.text(x+aj.message)}else{if(aj==="pending"){ah.container_div.addClass("pending");ah.content_div.text("Converting input data so that it can be used quickly with tool.");setTimeout(af,2000)}else{ai(aj)}}}})};af()}});var O=function(ag,af,ah,ai){this.name=ag;this.label=af;this.html=ah;this.value=ai};var g=function(ah,ag,aj,ak,ai,af){O.call(this,ah,ag,aj,ak);this.min=ai;this.max=af};var h=function(ag,af,ah,ai){this.name=ag;this.index=af;this.tool_id=ah;this.tool_exp_name=ai};var V=function(ag,af,ah,ai){h.call(this,ag,af,ah,ai);this.low=-Number.MAX_VALUE;this.high=Number.MAX_VALUE;this.min=Number.MAX_VALUE;this.max=-Number.MAX_VALUE;this.container=null;this.slider=null;this.slider_label=null};p(V.prototype,{applies_to:function(af){if(af.length>this.index){return true}return false},keep:function(af){if(!this.applies_to(af)){return true}var ag=af[this.index];return(isNaN(ag)||(ag>=this.low&&ag<=this.high))},update_attrs:function(ag){var af=false;if(!this.applies_to(ag)){return af}if(ag[this.index]<this.min){this.min=Math.floor(ag[this.index]);af=true}if(ag[this.index]>this.max){this.max=Math.ceil(ag[this.index]);af=true}return af},update_ui_elt:function(){if(this.min!=this.max){this.container.show()}else{this.container.hide()}var ah=function(ak,ai){var aj=ai-ak;return(aj<=2?0.01:1)};var ag=this.slider.slider("option","min"),af=this.slider.slider("option","max");if(this.min<ag||this.max>af){this.slider.slider("option","min",this.min);this.slider.slider("option","max",this.max);this.slider.slider("option","step",ah(this.min,this.max));this.slider.slider("option","values",[this.min,this.max])}}});var aa=function(aq,ay){this.track=aq;this.filters=[];for(var at=0;at<ay.length;at++){var au=ay[at],az=au.name,af=au.type,ah=au.index,ax=au.tool_id,aw=au.tool_exp_name;if(af==="int"||af==="float"){this.filters[at]=new V(az,ah,ax,aw)}else{console.log("ERROR: unsupported filter: ",az,af)}}var ai=function(aA,aB,aC){aA.click(function(){var aD=aB.text();max=parseFloat(aC.slider("option","max")),input_size=(max<=1?4:max<=1000000?max.toString().length:6),multi_value=false;if(aC.slider("option","values")){input_size=2*input_size+1;multi_value=true}aB.text("");$("<input type='text'/>").attr("size",input_size).attr("maxlength",input_size).attr("value",aD).appendTo(aB).focus().select().click(function(aE){aE.stopPropagation()}).blur(function(){$(this).remove();aB.text(aD)}).keyup(function(aI){if(aI.keyCode===27){$(this).trigger("blur")}else{if(aI.keyCode===13){var aG=aC.slider("option","min"),aE=aC.slider("option","max"),aH=function(aJ){return(isNaN(aJ)||aJ>aE||aJ<aG)},aF=$(this).val();if(!multi_value){aF=parseFloat(aF);if(aH(aF)){alert("Parameter value must be in the range ["+aG+"-"+aE+"]");return $(this)}}else{aF=aF.split("-");aF=[parseFloat(aF[0]),parseFloat(aF[1])];if(aH(aF[0])||aH(aF[1])){alert("Parameter value must be in the range ["+aG+"-"+aE+"]");return $(this)}}aC.slider((multi_value?"values":"value"),aF)}}})})};this.parent_div=$("<div/>").addClass("filters").hide();this.parent_div.bind("drag",function(aA){aA.stopPropagation()}).click(function(aA){aA.stopPropagation()}).bind("dblclick",function(aA){aA.stopPropagation()}).bind("keydown",function(aA){aA.stopPropagation()});var av=$("<div/>").addClass("sliders").appendTo(this.parent_div);var an=this;$.each(this.filters,function(aD,aF){aF.container=$("<div/>").addClass("filter-row slider-row").appendTo(av);var aE=$("<div/>").addClass("elt-label").appendTo(aF.container);var aC=$("<span/>").addClass("slider-name").text(aF.name+" ").appendTo(aE);var aB=$("<span/>");var aH=$("<span/>").addClass("slider-value").appendTo(aE).append("[").append(aB).append("]");var aA=$("<div/>").addClass("slider").appendTo(aF.container);aF.control_element=$("<div/>").attr("id",aF.name+"-filter-control").appendTo(aA);var aG=[0,0];aF.control_element.slider({range:true,min:Number.MAX_VALUE,max:-Number.MIN_VALUE,values:[0,0],slide:function(aJ,aK){var aI=aK.values;aB.text(aI[0]+"-"+aI[1]);aF.low=aI[0];aF.high=aI[1];an.track.request_draw(true,true)},change:function(aI,aJ){aF.control_element.slider("option","slide").call(aF.control_element,aI,aJ)}});aF.slider=aF.control_element;aF.slider_label=aB;ai(aH,aB,aF.control_element);$("<div style='clear: both;'/>").appendTo(aF.container)});if(this.filters.length!==0){var ak=$("<div/>").addClass("param-row").appendTo(av);var am=$("<input type='submit'/>").attr("value","Run on complete dataset").appendTo(ak);var ag=this;am.click(function(){ag.run_on_dataset()})}var ap=$("<div/>").addClass("display-controls").appendTo(this.parent_div),ar,al,ao,aj={Transparency:function(aA){an.alpha_filter=aA},Height:function(aA){an.height_filter=aA}};$.each(aj,function(aC,aB){ar=$("<div/>").addClass("filter-row").appendTo(ap),al=$("<span/>").addClass("elt-label").text(aC+":").appendTo(ar),ao=$("<select/>").attr("name",aC+"_dropdown").css("float","right").appendTo(ar);$("<option/>").attr("value",-1).text("== None ==").appendTo(ao);for(var aA=0;aA<an.filters.length;aA++){$("<option/>").attr("value",aA).text(an.filters[aA].name).appendTo(ao)}ao.change(function(){$(this).children("option:selected").each(function(){var aD=parseInt($(this).val());aj[aC]((aD>=0?an.filters[aD]:null));an.track.request_draw(true,true)})});$("<div style='clear: both;'/>").appendTo(ar)});$("<div style='clear: both;'/>").appendTo(this.parent_div)};p(aa.prototype,{reset_filters:function(){for(var af=0;af<this.filters.length;af++){filter=this.filters[af];filter.slider.slider("option","values",[filter.min,filter.max])}this.alpha_filter=null;this.height_filter=null},run_on_dataset:function(){var an=function(ar,ap,aq){if(!(ap in ar)){ar[ap]=aq}return ar[ap]};var ah={},af,ag,ai;for(var aj=0;aj<this.filters.length;aj++){af=this.filters[aj];if(af.tool_id){if(af.min!=af.low){ag=an(ah,af.tool_id,[]);ag[ag.length]=af.tool_exp_name+" >= "+af.low}if(af.max!=af.high){ag=an(ah,af.tool_id,[]);ag[ag.length]=af.tool_exp_name+" <= "+af.high}}}var al=[];for(var ao in ah){al[al.length]=[ao,ah[ao]]}var am=al.length;(function ak(aw,at){var aq=at[0],ar=aq[0],av=aq[1],au="("+av.join(") and (")+")",ap={cond:au,input:aw,target_dataset_id:aw,tool_id:ar},at=at.slice(1);$.getJSON(run_tool_url,ap,function(ax){if(ax.error){show_modal("Filter Dataset","Error running tool "+ar,{Close:hide_modal})}else{if(at.length===0){show_modal("Filtering Dataset","Filter(s) are running on the complete dataset. Outputs are in dataset's history.",{Close:hide_modal})}else{ak(ax.dataset_id,at)}}})})(this.track.dataset_id,al)}});var D=function(af,ag){M.Scaler.call(this,ag);this.filter=af};D.prototype.gen_val=function(af){if(this.filter.high===Number.MAX_VALUE||this.filter.low===-Number.MAX_VALUE||this.filter.low===this.filter.high){return this.default_val}return((parseFloat(af[this.filter.index])-this.filter.low)/(this.filter.high-this.filter.low))};var G=function(af){this.track=af.track;this.params=af.params;this.values={};this.restore_values((af.saved_values?af.saved_values:{}));this.onchange=af.onchange};p(G.prototype,{restore_values:function(af){var ag=this;$.each(this.params,function(ah,ai){if(af[ai.key]!==undefined){ag.values[ai.key]=af[ai.key]}else{ag.values[ai.key]=ai.default_value}})},build_form:function(){var ai=this;var af=$("<div />");var ah;function ag(am,aj){for(var ao=0;ao<am.length;ao++){ah=am[ao];if(ah.hidden){continue}var ak="param_"+ao;var at=ai.values[ah.key];var av=$("<div class='form-row' />").appendTo(aj);av.append($("<label />").attr("for",ak).text(ah.label+":"));if(ah.type==="bool"){av.append($('<input type="checkbox" />').attr("id",ak).attr("name",ak).attr("checked",at))}else{if(ah.type==="text"){av.append($('<input type="text"/>').attr("id",ak).val(at).click(function(){$(this).select()}))}else{if(ah.type=="select"){var aq=$("<select />").attr("id",ak);for(var an=0;an<ah.options.length;an++){$("<option/>").text(ah.options[an].label).attr("value",ah.options[an].value).appendTo(aq)}aq.val(at);av.append(aq)}else{if(ah.type==="color"){var ap=$("<input />").attr("id",ak).attr("name",ak).val(at);var ar=$("<div class='tipsy tipsy-west' style='position: absolute;' />").hide();var al=$("<div style='background-color: black; padding: 10px;'></div>").appendTo(ar);var au=$("<div/>").appendTo(al).farbtastic({width:100,height:100,callback:ap,color:at});$("<div />").append(ap).append(ar).appendTo(av).bind("click",function(aw){ar.css({left:$(this).position().left+$(ap).width()+5,top:$(this).position().top-($(ar).height()/2)+($(ap).height()/2)}).show();$(document).bind("click.color-picker",function(){ar.hide();$(document).unbind("click.color-picker")});aw.stopPropagation()})}else{av.append($("<input />").attr("id",ak).attr("name",ak).val(at))}}}}if(ah.help){av.append($("<div class='help'/>").text(ah.help))}}}ag(this.params,af);return af},update_from_form:function(af){var ah=this;var ag=false;$.each(this.params,function(ai,ak){if(!ak.hidden){var al="param_"+ai;var aj=af.find("#"+al).val();if(ak.type==="float"){aj=parseFloat(aj)}else{if(ak.type==="int"){aj=parseInt(aj)}else{if(ak.type==="bool"){aj=af.find("#"+al).is(":checked")}}}if(aj!==ah.values[ak.key]){ah.values[ak.key]=aj;ag=true}}});if(ag){this.onchange()}}});var b=function(af,ai,ah,ag,aj){this.track=af;this.index=ai;this.low=ai*R*ah;this.high=(ai+1)*R*ah;this.resolution=ah;this.canvas=$("<div class='track-tile'/>").append(ag);this.data=aj;this.stale=false};b.prototype.predisplay_actions=function(){};var k=function(af,ai,ah,ag,aj,ak){b.call(this,af,ai,ah,ag,aj);this.max_val=ak};p(k.prototype,b.prototype);var P=function(af,aj,ai,ah,al,am,ak,ag){b.call(this,af,aj,ai,ah,al);this.mode=am;this.message=ak;this.feature_mapper=ag};p(P.prototype,b.prototype);P.prototype.predisplay_actions=function(){var ag=this,af={};if(ag.mode!=="Pack"){return}$(this.canvas).hover(function(){this.hovered=true;$(this).mousemove()},function(){this.hovered=false;$(this).siblings(".feature-popup").remove()}).mousemove(function(ar){if(!this.hovered){return}var am=$(this).offset(),aq=ar.pageX-am.left,ap=ar.pageY-am.top,aw=ag.feature_mapper.get_feature_data(aq,ap),an=(aw?aw[0]:null);$(this).siblings(".feature-popup").each(function(){if(!an||$(this).attr("id")!==an.toString()){$(this).remove()}});if(aw){var ai=af[an];if(!ai){var an=aw[0],at={name:aw[3],start:aw[1],end:aw[2],strand:aw[4]},al=ag.track.filters_manager.filters,ak;for(var ao=0;ao<al.length;ao++){ak=al[ao];at[ak.name]=aw[ak.index]}var ai=$("<div/>").attr("id",an).addClass("feature-popup"),ax=$("<table/>"),av,au,ay;for(av in at){au=at[av];ay=$("<tr/>").appendTo(ax);$("<th/>").appendTo(ay).text(av);$("<td/>").attr("align","left").appendTo(ay).text(typeof(au)=="number"?Z(au,2):au)}ai.append($("<div class='feature-popup-inner'>").append(ax));af[an]=ai}ai.appendTo($(ag.canvas).parent());var aj=aq+parseInt(ag.canvas.css("left"))-ai.width()/2,ah=ap+parseInt(ag.canvas.css("top"))+7;ai.css("left",aj+"px").css("top",ah+"px")}else{if(!ar.isPropagationStopped()){ar.stopPropagation();$(this).siblings().each(function(){$(this).trigger(ar)})}}}).mouseleave(function(){$(this).siblings(".feature-popup").remove()})};var i=function(ai,aq,aj,am,ar,ah,ag){q.call(this,ai,aq,aj,{},"draghandle");this.data_url=(ah?ah:default_data_url);this.data_url_extra_params={};this.data_query_wait=(ag?ag:L);this.dataset_check_url=converted_datasets_state_url;this.content_visible=true;if(!i.id_counter){i.id_counter=0}this.id=i.id_counter++;this.container_div=$("<div />").addClass("track").attr("id","track_"+this.id).css("position","relative");if(am){this.header_div=$("<div class='track-header' />").appendTo(this.container_div);if(this.view.editor){this.drag_div=$("<div/>").addClass(this.drag_handle_class).appendTo(this.header_div)}this.name_div=$("<div/>").addClass("track-name").appendTo(this.header_div).text(this.name).attr("id",this.name.replace(/\s+/g,"-").replace(/[^a-zA-Z0-9\-]/g,"").toLowerCase());this.icons_div=$("<div/>").css("float","left").appendTo(this.header_div).hide();this.toggle_icon=$("<a/>").attr("href","javascript:void(0);").attr("title","Hide/show track content").addClass("icon-button toggle").tipsy({gravity:"s"}).appendTo(this.icons_div);this.settings_icon=$("<a/>").attr("href","javascript:void(0);").attr("title","Edit settings").addClass("icon-button settings-icon").tipsy({gravity:"s"}).appendTo(this.icons_div);this.overview_icon=$("<a/>").attr("href","javascript:void(0);").attr("title","Set as overview").addClass("icon-button overview-icon").tipsy({gravity:"s"}).appendTo(this.icons_div);this.filters_icon=$("<a/>").attr("href","javascript:void(0);").attr("title","Filters").addClass("icon-button filters-icon").tipsy({gravity:"s"}).appendTo(this.icons_div).hide();this.tools_icon=$("<a/>").attr("href","javascript:void(0);").attr("title","Tools").addClass("icon-button tools-icon").tipsy({gravity:"s"}).appendTo(this.icons_div).hide();this.remove_icon=$("<a/>").attr("href","javascript:void(0);").attr("title","Remove").addClass("icon-button remove-icon").tipsy({gravity:"s"}).appendTo(this.icons_div);var ak=this;this.header_div.dblclick(function(at){at.stopPropagation()});this.toggle_icon.click(function(){if(ak.content_visible){ak.toggle_icon.addClass("toggle-expand").removeClass("toggle");ak.hide_contents();ak.mode_div.hide();ak.content_visible=false}else{ak.toggle_icon.addClass("toggle").removeClass("toggle-expand");ak.content_visible=true;ak.mode_div.show();ak.show_contents()}});this.settings_icon.click(function(){var av=function(){hide_modal();$(window).unbind("keypress.check_enter_esc")},at=function(){ak.config.update_from_form($(".dialog-box"));hide_modal();$(window).unbind("keypress.check_enter_esc")},au=function(aw){if((aw.keyCode||aw.which)===27){av()}else{if((aw.keyCode||aw.which)===13){at()}}};$(window).bind("keypress.check_enter_esc",au);show_modal("Configure Track",ak.config.build_form(),{Cancel:av,OK:at})});this.overview_icon.click(function(){ak.view.set_overview(ak)});this.filters_icon.click(function(){ak.filters_div.toggle();ak.filters_manager.reset_filters()});this.tools_icon.click(function(){ak.dynamic_tool_div.toggle();if(ak.dynamic_tool_div.is(":visible")){ak.set_name(ak.name+ak.tool_region_and_parameters_str())}else{ak.revert_name()}$(".tipsy").remove()});this.remove_icon.click(function(){$(".tipsy").remove();ak.remove()});if(ak.display_modes!==undefined){if(ak.mode_div===undefined){ak.mode_div=$("<div class='right-float menubutton popup' />").appendTo(ak.header_div);var al=(ak.config&&ak.config.values.mode?ak.config.values.mode:ak.display_modes[0]);ak.mode=al;ak.mode_div.text(al);var af={};for(var an=0,ap=ak.display_modes.length;an<ap;an++){var ao=ak.display_modes[an];af[ao]=function(at){return function(){ak.change_mode(at)}}(ao)}make_popupmenu(ak.mode_div,af)}else{ak.mode_div.hide()}this.header_div.append($("<div/>").css("clear","both"));this.container_div.hover(function(){ak.icons_div.show()},function(){ak.icons_div.hide()})}}this.content_div=$("<div class='track-content'>").appendTo(this.container_div);this.container.content_div.append(this.container_div)};p(i.prototype,q.prototype,{get_type:function(){if(this instanceof ab){return"LabelTrack"}else{if(this instanceof A){return"ReferenceTrack"}else{if(this instanceof j){return"LineTrack"}else{if(this instanceof W){return"ReadTrack"}else{if(this instanceof U){return"VcfTrack"}else{if(this instanceof e){return"FeatureTrack"}}}}}}return""},init:function(){var af=this;af.enabled=false;af.tile_cache.clear();af.data_manager.clear();af.initial_canvas=undefined;af.content_div.css("height","auto");af.container_div.removeClass("nodata error pending");if(!af.dataset_id){return}$.getJSON(converted_datasets_state_url,{hda_ldda:af.hda_ldda,dataset_id:af.dataset_id,chrom:af.view.chrom},function(ag){if(!ag||ag==="error"||ag.kind==="error"){af.container_div.addClass("error");af.content_div.text(o);if(ag.message){var ah=$(" <a href='javascript:void(0);'></a>").text("View error").click(function(){show_modal("Trackster Error","<pre>"+ag.message+"</pre>",{Close:hide_modal})});af.content_div.append(ah)}}else{if(ag==="no converter"){af.container_div.addClass("error");af.content_div.text(K)}else{if(ag==="no data"||(ag.data!==undefined&&(ag.data===null||ag.data.length===0))){af.container_div.addClass("nodata");af.content_div.text(F)}else{if(ag==="pending"){af.container_div.addClass("pending");af.content_div.text(t);setTimeout(function(){af.init()},af.data_query_wait)}else{if(ag.status==="data"){if(ag.valid_chroms){af.valid_chroms=ag.valid_chroms;af.update_icons()}af.content_div.text(Y);if(af.view.chrom){af.content_div.text("");af.content_div.css("height",af.height_px+"px");af.enabled=true;$.when(af.predraw_init()).done(function(){af.container_div.removeClass("nodata error pending");af.request_draw()})}}}}}}});this.update_icons()},hide_contents:function(){this.content_div.children().remove();this.content_div.hide();this.container_div.find(".yaxislabel, .track-resize").hide()},show_contents:function(){this.content_div.show();this.container_div.find(".yaxislabel, .track-resize").show();this.request_draw()},predraw_init:function(){}});var N=function(aj,ah,ag,am,ai,al,ak){i.call(this,aj,ah,ag,am,ai);var af=this,ah=af.view;m(af.container_div,af.drag_handle_class,".group",af);this.filters_manager=new aa(this,(al!==undefined?al:{}));this.filters_available=false;this.filters_visible=false;this.tool=(ak!==undefined&&obj_length(ak)>0?new r(this,ak):undefined);if(this.header_div){if(this.filters_manager){this.filters_div=this.filters_manager.parent_div;this.header_div.after(this.filters_div)}if(this.tool){this.dynamic_tool_div=this.tool.parent_div;this.header_div.after(this.dynamic_tool_div)}}};p(N.prototype,q.prototype,i.prototype,{copy:function(af){return new this.constructor(this.name,this.view,af,this.hda_ldda,this.dataset_id,this.prefs,this.filters,this.tool)},to_json:function(){return{track_type:this.get_type(),name:this.name,hda_ldda:this.hda_ldda,dataset_id:this.dataset_id,prefs:this.prefs,mode:this.mode,}},change_mode:function(ag){var af=this;af.mode_div.text(ag);af.mode=ag;af.config.values.mode=ag;af.tile_cache.clear();af.request_draw();return af},update_icons:function(){var af=this;if(af.filters_available>0){af.filters_icon.show()}else{af.filters_icon.hide()}if(af.tool){af.tools_icon.show()}else{af.tools_icon.hide()}},_gen_tile_cache_key:function(ag,ah,af){return ag+"_"+ah+"_"+af},request_draw:function(ag,af){this.view.request_redraw(false,ag,af,this)},_draw:function(ah,ap){if(!this.enabled){return}if(!this.content_visible){return}if(!(this instanceof A)&&(!this.dataset_id)){return}var ao=this.view.low,al=this.view.high,am=al-ao,ai=this.view.container.width(),at=ai/am,ak=this.view.resolution,ar=$("<div style='position: relative;'></div>");if(this.is_overview){ao=this.view.max_low;al=this.view.max_high;ak=Math.pow(C,Math.ceil(Math.log((view.max_high-view.max_low)/R)/Math.log(C)));at=ai/(view.max_high-view.max_low)}if(!ap){this.content_div.children().remove()}this.content_div.append(ar);this.max_height=0;var ag=Math.floor(ao/ak/R);var an=true;var aq=[];var af=0;while((ag*R*ak)<al){tile=this.draw_helper(ah,ai,ag,ak,ar,at);if(tile){aq.push(tile)}else{an=false}ag+=1;af++}var aj=this;if(an){aj.postdraw_actions(aq,ai,at,ap)}},postdraw_actions:function(aj,ak,al,af){var ah=this;var ai=false;for(var ag=0;ag<aj.length;ag++){if(aj[ag].message){ai=true;break}}if(ai){for(var ag=0;ag<aj.length;ag++){tile=aj[ag];if(!tile.message){tile.canvas.css("padding-top",E)}}}},draw_helper:function(ag,ah,ai,al,ar,aw,at,am){var aj=this,aq=this._gen_tile_cache_key(ah,aw,ai),an=ai*R*al,av=an+R*al;var ao=(ag?undefined:aj.tile_cache.get(aq));if(ao){aj.show_tile(ao,ar,aw);return ao}var ap=function(ax){return("isResolved" in ax)};var ak=true;var af=aj.data_manager.get_data(an,av,aj.mode,al,aj.data_url_extra_params);if(ap(af)){ak=false}var au;if(view.reference_track&&aw>view.canvas_manager.char_width_px){au=view.reference_track.data_manager.get_data(an,av,aj.mode,al,view.reference_track.data_url_extra_params);if(ap(au)){ak=false}}if(ak){p(af,am);var ao=aj.draw_tile(af,aj.mode,al,ai,aw,au);if(ao!==undefined){aj.tile_cache.set(aq,ao);aj.show_tile(ao,ar,aw)}return ao}$.when(af,au).then(function(){view.request_redraw(false,false,false,aj)});return null},show_tile:function(al,an,ao){var ah=this,ag=al.canvas,ak=ag;if(al.message){var ap=$("<div/>"),am=$("<div/>").addClass("tile-message").text(al.message).css({height:E-1,width:al.canvas.width}).appendTo(ap),aj=$("<a href='javascript:void(0);'/>").addClass("icon more-down").appendTo(am),af=$("<a href='javascript:void(0);'/>").addClass("icon more-across").appendTo(am);ap.append(ag);ak=ap;aj.click(function(){al.stale=true;ah.data_manager.get_more_data(al.low,al.high,ah.mode,al.resolution,{},ah.data_manager.DEEP_DATA_REQ);ah.request_draw()}).dblclick(function(aq){aq.stopPropagation()});af.click(function(){al.stale=true;ah.data_manager.get_more_data(al.low,al.high,ah.mode,al.resolution,{},ah.data_manager.BROAD_DATA_REQ);ah.request_draw()}).dblclick(function(aq){aq.stopPropagation()})}al.predisplay_actions();var ai=(al.low-(this.is_overview?this.view.max_low:this.view.low))*ao;if(this.left_offset){ai-=this.left_offset}ak.css({position:"absolute",top:0,left:ai,height:""});an.append(ak);ah.max_height=Math.max(ah.max_height,ak.height());ah.content_div.css("height",ah.max_height+"px");an.children().css("height",ah.max_height+"px")},_get_tile_bounds:function(af,ag){var ai=af*R*ag,aj=R*ag,ah=(ai+aj<=this.view.max_high?ai+aj:this.view.max_high);return[ai,ah]},tool_region_and_parameters_str:function(ah,af,ai){var ag=this,aj=(ah!==undefined&&af!==undefined&&ai!==undefined?ah+":"+af+"-"+ai:"all");return" - region=["+aj+"], parameters=["+ag.tool.get_param_values().join(", ")+"]"},init_for_tool_data:function(){this.data_url=raw_data_url;this.data_query_wait=1000;this.dataset_check_url=dataset_state_url;this.predraw_init=function(){var ag=this;var af=function(){if(ag.data_manager.size()===0){setTimeout(af,300)}else{ag.data_url=default_data_url;ag.data_query_wait=L;ag.dataset_state_url=converted_datasets_state_url;$.getJSON(ag.dataset_state_url,{dataset_id:ag.dataset_id,hda_ldda:ag.hda_ldda},function(ah){})}};af()}}});var ab=function(ag,af){i.call(this,"label",ag,af,false,{});this.container_div.addClass("label-track")};p(ab.prototype,i.prototype,{init:function(){this.enabled=true},_draw:function(){var ah=this.view,ai=ah.high-ah.low,al=Math.floor(Math.pow(10,Math.floor(Math.log(ai)/Math.log(10)))),af=Math.floor(ah.low/al)*al,aj=this.view.container.width(),ag=$("<div style='position: relative; height: 1.3em;'></div>");while(af<ah.high){var ak=(af-ah.low)/ai*aj;ag.append($("<div class='label'>"+commatize(af)+"</div>").css({position:"absolute",left:ak-1}));af+=al}this.content_div.children(":first").remove();this.content_div.append(ag)}});var A=function(af){N.call(this,"reference",af,{content_div:af.top_labeltrack},false,{});af.reference_track=this;this.left_offset=200;this.height_px=12;this.container_div.addClass("reference-track");this.content_div.css("background","none");this.content_div.css("min-height","0px");this.content_div.css("border","none");this.data_url=reference_url;this.data_url_extra_params={dbkey:af.dbkey};this.data_manager=new I(B,this,false);this.tile_cache=new c(u)};p(A.prototype,q.prototype,N.prototype,{init:function(){this.enabled=true},draw_tile:function(ap,al,ak,ag,aq){var aj=this,ah=R*ak;if(aq>this.view.canvas_manager.char_width_px){if(ap.data===null){aj.content_div.css("height","0px");return}var ai=this.view.canvas_manager.new_canvas();var ao=ai.getContext("2d");ai.width=Math.ceil(ah*aq+aj.left_offset);ai.height=aj.height_px;ao.font=ao.canvas.manager.default_font;ao.textAlign="center";ap=ap.data;for(var am=0,an=ap.length;am<an;am++){var af=Math.round(am*aq);ao.fillText(ap[am],af+aj.left_offset,10)}return new b(aj,ag,ak,ai,ap)}this.content_div.css("height","0px")}});var j=function(ak,ai,ah,al,af,aj){var ag=this;this.display_modes=["Histogram","Line","Filled","Intensity"];this.mode="Histogram";N.call(this,ak,ai,ah,true,aj);this.min_height_px=16;this.max_height_px=400;this.height_px=32;this.hda_ldda=al;this.dataset_id=af;this.original_dataset_id=af;this.data_manager=new S(B,this);this.tile_cache=new c(u);this.left_offset=0;this.config=new G({track:this,params:[{key:"name",label:"Name",type:"text",default_value:ak},{key:"color",label:"Color",type:"color",default_value:get_random_color()},{key:"min_value",label:"Min Value",type:"float",default_value:undefined},{key:"max_value",label:"Max Value",type:"float",default_value:undefined},{key:"mode",type:"string",default_value:this.mode,hidden:true},{key:"height",type:"int",default_value:this.height_px,hidden:true}],saved_values:aj,onchange:function(){ag.set_name(ag.prefs.name);ag.vertical_range=ag.prefs.max_value-ag.prefs.min_value;$("#linetrack_"+ag.dataset_id+"_minval").text(ag.prefs.min_value);$("#linetrack_"+ag.dataset_id+"_maxval").text(ag.prefs.max_value);ag.tile_cache.clear();ag.request_draw()}});this.prefs=this.config.values;this.height_px=this.config.values.height;this.vertical_range=this.config.values.max_value-this.config.values.min_value;this.add_resize_handle()};p(j.prototype,q.prototype,N.prototype,{add_resize_handle:function(){var af=this;var ai=false;var ah=false;var ag=$("<div class='track-resize'>");$(af.container_div).hover(function(){if(af.content_visible){ai=true;ag.show()}},function(){ai=false;if(!ah){ag.hide()}});ag.hide().bind("dragstart",function(aj,ak){ah=true;ak.original_height=$(af.content_div).height()}).bind("drag",function(ak,al){var aj=Math.min(Math.max(al.original_height+al.deltaY,af.min_height_px),af.max_height_px);$(af.content_div).css("height",aj);af.height_px=aj;af.request_draw(true)}).bind("dragend",function(aj,ak){af.tile_cache.clear();ah=false;if(!ai){ag.hide()}af.config.values.height=af.height_px}).appendTo(af.container_div)},predraw_init:function(){var af=this;af.vertical_range=undefined;return $.getJSON(af.data_url,{stats:true,chrom:af.view.chrom,low:null,high:null,hda_ldda:af.hda_ldda,dataset_id:af.dataset_id},function(ag){af.container_div.addClass("line-track");var aj=ag.data;if(isNaN(parseFloat(af.prefs.min_value))||isNaN(parseFloat(af.prefs.max_value))){var ah=aj.min;var al=aj.max;ah=Math.floor(Math.min(0,Math.max(ah,aj.mean-2*aj.sd)));al=Math.ceil(Math.max(0,Math.min(al,aj.mean+2*aj.sd)));af.prefs.min_value=ah;af.prefs.max_value=al;$("#track_"+af.dataset_id+"_minval").val(af.prefs.min_value);$("#track_"+af.dataset_id+"_maxval").val(af.prefs.max_value)}af.vertical_range=af.prefs.max_value-af.prefs.min_value;af.total_frequency=aj.total_frequency;af.container_div.find(".yaxislabel").remove();var ak=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+af.dataset_id+"_minval").text(Z(af.prefs.min_value,3));var ai=$("<div />").addClass("yaxislabel").attr("id","linetrack_"+af.dataset_id+"_maxval").text(Z(af.prefs.max_value,3));ai.css({position:"absolute",top:"24px",left:"10px"});ai.prependTo(af.container_div);ak.css({position:"absolute",bottom:"2px",left:"10px"});ak.prependTo(af.container_div)})},draw_tile:function(ar,ak,aj,ah,aq){if(this.vertical_range===undefined){return}var af=this._get_tile_bounds(ah,aj),al=af[0],ap=af[1],ag=Math.ceil((ap-al)*aq),an=this.height_px;var ai=this.view.canvas_manager.new_canvas();ai.width=ag,ai.height=an;var ao=ai.getContext("2d");var am=new M.LinePainter(ar.data,al,ap,this.prefs,ak);am.draw(ao,ag,an);return new b(this.track,ah,aj,ai,ar.data)}});var e=function(af,al,ag,ak,an,am,ai,aj){var ah=this;this.display_modes=["Auto","Histogram","Dense","Squish","Pack"];N.call(this,af,al,ag,true,am,ai,aj);this.config=new G({track:this,params:[{key:"name",label:"Name",type:"text",default_value:af},{key:"block_color",label:"Block color",type:"color",default_value:get_random_color()},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true,help:"Show the number of items in each bin when drawing summary histogram"},{key:"connector_style",label:"Connector style",type:"select",default_value:"fishbones",options:[{label:"Line with arrows",value:"fishbone"},{label:"Arcs",value:"arcs"}]},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:am,onchange:function(){ah.set_name(ah.prefs.name);ah.tile_cache.clear();ah.set_painter_from_config();ah.request_draw()}});this.prefs=this.config.values;this.height_px=0;this.container_div.addClass("feature-track");this.hda_ldda=ak;this.dataset_id=an;this.original_dataset_id=an;this.show_labels_scale=0.001;this.showing_details=false;this.summary_draw_height=30;this.inc_slots={};this.start_end_dct={};this.tile_cache=new c(d);this.data_manager=new S(20,this);this.left_offset=200;this.set_painter_from_config()};p(e.prototype,q.prototype,N.prototype,{set_painter_from_config:function(){if(this.config.values.connector_style=="arcs"){this.painter=M.ArcLinkedFeaturePainter}else{this.painter=M.LinkedFeaturePainter}},postdraw_actions:function(av,af,aw,au){N.prototype.postdraw_actions.call(this,av,au);var ai=this;if(au){var ak=ai.content_div.children();var al=false;for(var aj=ak.length-1,ap=0;aj>=ap;aj--){var ah=$(ak[aj]);if(al){ah.remove()}else{if(ah.children().length!==0){al=true}}}}if(ai.mode=="Histogram"){var ao=-1;for(var aj=0;aj<av.length;aj++){var at=av[aj].max_val;if(at>ao){ao=at}}for(var aj=0;aj<av.length;aj++){var ar=av[aj];if(ar.max_val!==ao){ar.canvas.remove();ai.draw_helper(true,af,ar.index,ar.resolution,ar.canvas.parent(),aw,[],{max:ao})}}}if(ai.filters_manager){var ag=ai.filters_manager.filters;for(var an=0;an<ag.length;an++){ag[an].update_ui_elt()}var am=false,aq;for(var aj=0;aj<av.length;aj++){if(av[aj].data.length){aq=av[aj].data[0];for(var an=0;an<ag.length;an++){if(ag[an].applies_to(aq)){am=true;break}}}}if(ai.filters_available!==am){ai.filters_available=am;if(!ai.filters_available){ai.filters_div.hide()}ai.update_icons()}}},update_auto_mode:function(af){if(this.mode=="Auto"){if(af=="no_detail"){af="feature spans"}else{if(af=="summary_tree"){af="coverage histogram"}}this.mode_div.text("Auto ("+af+")")}},incremental_slots:function(aj,ag,ai){var ah=this.view.canvas_manager.dummy_context,af=this.inc_slots[aj];if(!af||(af.mode!==ai)){af=new (s.FeatureSlotter)(aj,ai==="Pack",z,function(ak){return ah.measureText(ak)});af.mode=ai;this.inc_slots[aj]=af}return af.slot_features(ag)},get_summary_tree_data:function(aj,am,ah,av){if(av>ah-am){av=ah-am}var aq=Math.floor((ah-am)/av),au=[],ai=0;var ak=0,al=0,ap,at=0,an=[],ar,ao;var ag=function(ay,ax,az,aw){ay[0]=ax+az*aw;ay[1]=ax+(az+1)*aw};while(at<av&&ak!==aj.length){var af=false;for(;at<av&&!af;at++){ag(an,am,at,aq);for(al=ak;al<aj.length;al++){ap=aj[al].slice(1,3);if(is_overlap(ap,an)){af=true;break}}if(af){break}}data_start_index=al;au[au.length]=ar=[an[0],0];for(;al<aj.length;al++){ap=aj[al].slice(1,3);if(is_overlap(ap,an)){ar[1]++}else{break}}if(ar[1]>ai){ai=ar[1]}at++}return{max:ai,delta:aq,data:au}},draw_tile:function(au,ax,aB,aF,ap,ai){var ay=this,ak=ay._get_tile_bounds(aF,aB),aI=ak[0],ag=ak[1],aw=ag-aI,az=Math.ceil(aw*ap),aO=25,aj=this.left_offset,av,al;if(ax==="Auto"){if(au.dataset_type==="summary_tree"){ax=au.dataset_type}else{if(au.extra_info==="no_detail"||ay.is_overview){ax="no_detail"}else{var aN=au.data;if(this.view.high-this.view.low>J){ax="Squish"}else{ax="Pack"}}}this.update_auto_mode(ax)}if(ax==="summary_tree"||ax==="Histogram"){al=this.summary_draw_height;this.container_div.find(".yaxislabel").remove();var af=$("<div />").addClass("yaxislabel");af.text(au.max);af.css({position:"absolute",top:"24px",left:"10px",color:this.prefs.label_color});af.prependTo(this.container_div);var ah=this.view.canvas_manager.new_canvas();ah.width=az+aj;ah.height=al+T;if(au.dataset_type!="summary_tree"){var aq=this.get_summary_tree_data(au.data,aI,ag,200);if(au.max){aq.max=au.max}au=aq}var aK=new M.SummaryTreePainter(au,aI,ag,this.prefs);var aA=ah.getContext("2d");aA.translate(aj,T);aK.draw(aA,az,al);return new k(ay,aF,aB,ah,au.data,au.max)}var av,an=1;if(ax==="no_detail"||ax==="Squish"||ax==="Pack"){an=this.incremental_slots(ap,au.data,ax);av=this.inc_slots[ap].slots}var ao=[];if(au.data){var ar=this.filters_manager.filters;for(var aC=0,aE=au.data.length;aC<aE;aC++){var am=au.data[aC];var aD=false;var at;for(var aH=0,aM=ar.length;aH<aM;aH++){at=ar[aH];at.update_attrs(am);if(!at.keep(am)){aD=true;break}}if(!aD){ao.push(am)}}}var aL=(this.filters_manager.alpha_filter?new D(this.filters_manager.alpha_filter):null);var aJ=(this.filters_manager.height_filter?new D(this.filters_manager.height_filter):null);var aK=new (this.painter)(ao,aI,ag,this.prefs,ax,aL,aJ,ai);var al=Math.max(ad,aK.get_required_height(an,az));var ah=this.view.canvas_manager.new_canvas();var aG=null;ah.width=az+aj;ah.height=al;var aA=ah.getContext("2d");aA.fillStyle=this.prefs.block_color;aA.font=aA.canvas.manager.default_font;aA.textAlign="right";this.container_div.find(".yaxislabel").remove();if(au.data){aA.translate(aj,0);aG=aK.draw(aA,az,al,av);aG.translation=-aj}return new P(ay,aF,aB,ah,au.data,ax,au.message,aG)}});var U=function(ak,ah,ag,am,af,aj,al,ai){e.call(this,ak,ah,ag,am,af,aj,al,ai);this.config=new G({track:this,params:[{key:"name",label:"Name",type:"text",default_value:ak},{key:"block_color",label:"Block color",type:"color",default_value:get_random_color()},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_insertions",label:"Show insertions",type:"bool",default_value:false},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:aj,onchange:function(){this.track.set_name(this.track.prefs.name);this.track.tile_cache.clear();this.track.request_draw()}});this.prefs=this.config.values;this.painter=M.ReadPainter};p(U.prototype,q.prototype,N.prototype,e.prototype);var W=function(af,ak,ag,aj,an,am,ah){e.call(this,af,ak,ag,aj,an,am,ah);var ai=get_random_color(),al=get_random_color([ai,"#ffffff"]);this.config=new G({track:this,params:[{key:"name",label:"Name",type:"text",default_value:af},{key:"block_color",label:"Block and sense strand color",type:"color",default_value:ai},{key:"reverse_strand_color",label:"Antisense strand color",type:"color",default_value:al},{key:"label_color",label:"Label color",type:"color",default_value:"black"},{key:"show_insertions",label:"Show insertions",type:"bool",default_value:false},{key:"show_differences",label:"Show differences only",type:"bool",default_value:true},{key:"show_counts",label:"Show summary counts",type:"bool",default_value:true},{key:"mode",type:"string",default_value:this.mode,hidden:true},],saved_values:am,onchange:function(){this.track.set_name(this.track.prefs.name);this.track.tile_cache.clear();this.track.request_draw()}});this.prefs=this.config.values;this.painter=M.ReadPainter;this.update_icons()};p(W.prototype,q.prototype,N.prototype,e.prototype);X.View=ac;X.DrawableGroup=Q;X.LineTrack=j;X.FeatureTrack=e;X.ReadTrack=W;X.VcfTrack=U};var slotting_module=function(c,b){var e=c("class").extend;var d=2,a=5;b.FeatureSlotter=function(i,h,f,g){this.slots={};this.start_end_dct={};this.w_scale=i;this.include_label=h;this.max_rows=f;this.measureText=g};e(b.FeatureSlotter.prototype,{slot_features:function(m){var p=this.w_scale,s=this.slots,h=this.start_end_dct,y=[],A=[],n=0,z=this.max_rows;for(var w=0,x=m.length;w<x;w++){var l=m[w],o=l[0];if(s[o]!==undefined){n=Math.max(n,s[o]);A.push(s[o])}else{y.push(w)}}var q=function(F,G){for(var E=0;E<=z;E++){var C=false,H=h[E];if(H!==undefined){for(var B=0,D=H.length;B<D;B++){var i=H[B];if(G>i[0]&&F<i[1]){C=true;break}}}if(!C){return E}}return -1};for(var w=0,x=y.length;w<x;w++){var l=m[y[w]],o=l[0],u=l[1],f=l[2],r=l[3],g=Math.floor(u*p),k=Math.ceil(f*p),v=this.measureText(r).width,j;if(r!==undefined&&this.include_label){v+=(d+a);if(g-v>=0){g-=v;j="left"}else{k+=v;j="right"}}var t=q(g,k);if(t>=0){if(h[t]===undefined){h[t]=[]}h[t].push([g,k]);s[o]=t;n=Math.max(n,t)}else{}}return n+1}})};var painters_module=function(i,x){var u=i("class").extend;var p=function(I,A,G,z,F,D){if(D===undefined){D=4}var C=z-A;var B=F-G;var E=Math.floor(Math.sqrt(C*C+B*B)/D);var J=C/E;var H=B/E;var y;for(y=0;y<E;y++,A+=J,G+=H){if(y%2!==0){continue}I.fillRect(A,G,D,1)}};var q=function(B,A,z,E){var D=A-E/2,C=A+E/2,F=z-Math.sqrt(E*3/2);B.beginPath();B.moveTo(D,F);B.lineTo(C,F);B.lineTo(A,z);B.lineTo(D,F);B.strokeStyle=this.fillStyle;B.fill();B.stroke();B.closePath()};var d=function(y){this.default_val=(y?y:1)};d.prototype.gen_val=function(y){return this.default_val};var l=function(A,C,y,z,B){this.data=A;this.view_start=C;this.view_end=y;this.prefs=u({},this.default_prefs,z);this.mode=B};l.prototype.default_prefs={};var v=function(A,C,y,z,B){l.call(this,A,C,y,z,B)};v.prototype.default_prefs={show_counts:false};v.prototype.draw=function(M,z,L){var E=this.view_start,O=this.view_end-this.view_start,N=z/O;var J=this.data.data,I=this.data.delta,G=this.data.max,B=L;delta_x_px=Math.ceil(I*N);M.save();for(var C=0,D=J.length;C<D;C++){var H=Math.floor((J[C][0]-E)*N);var F=J[C][1];if(!F){continue}var K=F/G*L;if(F!==0&&K<1){K=1}M.fillStyle=this.prefs.block_color;M.fillRect(H,B-K,delta_x_px,K);var A=4;if(this.prefs.show_counts&&(M.measureText(F).width+A)<delta_x_px){M.fillStyle=this.prefs.label_color;M.textAlign="center";M.fillText(F,H+(delta_x_px/2),10)}}M.restore()};var b=function(y,C,E,F,A){l.call(this,y,C,E,F,A);if(this.prefs.min_value===undefined){var G=Infinity;for(var z=0,B=this.data.length;z<B;z++){G=Math.min(G,this.data[z][1])}this.prefs.min_value=G}if(this.prefs.max_value===undefined){var D=-Infinity;for(var z=0,B=this.data.length;z<B;z++){D=Math.max(D,this.data[z][1])}this.prefs.max_value=D}};b.prototype.default_prefs={min_value:undefined,max_value:undefined,mode:"Histogram",color:"#000",overflow_color:"#F66"};b.prototype.draw=function(N,M,K){var F=false,H=this.prefs.min_value,D=this.prefs.max_value,J=D-H,z=K,A=this.view_start,L=this.view_end-this.view_start,B=M/L,I=this.mode,T=this.data;N.save();var U=Math.round(K+H/J*K);if(I!=="Intensity"){N.fillStyle="#aaa";N.fillRect(0,U,M,1)}N.beginPath();var R,E,C;if(T.length>1){C=Math.ceil((T[1][0]-T[0][0])*B)}else{C=10}for(var O=0,P=T.length;O<P;O++){N.fillStyle=this.prefs.color;R=Math.round((T[O][0]-A)*B);E=T[O][1];var Q=false,G=false;if(E===null){if(F&&I==="Filled"){N.lineTo(R,z)}F=false;continue}if(E<H){G=true;E=H}else{if(E>D){Q=true;E=D}}if(I==="Histogram"){E=Math.round(E/J*z);N.fillRect(R,U,C,-E)}else{if(I==="Intensity"){E=255-Math.floor((E-H)/J*255);N.fillStyle="rgb("+E+","+E+","+E+")";N.fillRect(R,0,C,z)}else{E=Math.round(z-(E-H)/J*z);if(F){N.lineTo(R,E)}else{F=true;if(I==="Filled"){N.moveTo(R,z);N.lineTo(R,E)}else{N.moveTo(R,E)}}}}N.fillStyle=this.prefs.overflow_color;if(Q||G){var S;if(I==="Histogram"||I==="Intensity"){S=C}else{R-=2;S=4}if(Q){N.fillRect(R,0,S,3)}if(G){N.fillRect(R,z-3,S,3)}}N.fillStyle=this.prefs.color}if(I==="Filled"){if(F){N.lineTo(R,U);N.lineTo(0,U)}N.fill()}else{N.stroke()}N.restore()};var m=function(y){this.feature_positions={};this.slot_height=y;this.translation=0;this.y_translation=0};m.prototype.map_feature_data=function(z,B,y,A){if(!this.feature_positions[B]){this.feature_positions[B]=[]}this.feature_positions[B].push({data:z,x_start:y,x_end:A})};m.prototype.get_feature_data=function(z,D){var C=Math.floor((D-this.y_translation)/this.slot_height),B;if(!this.feature_positions[C]){return null}z+=this.translation;for(var A=0;A<this.feature_positions[C].length;A++){B=this.feature_positions[C][A];if(z>=B.x_start&&z<=B.x_end){return B.data}}};var o=function(A,D,y,z,C,E,B){l.call(this,A,D,y,z,C);this.alpha_scaler=(E?E:new d());this.height_scaler=(B?B:new d())};o.prototype.default_prefs={block_color:"#FFF",connector_color:"#FFF"};u(o.prototype,{get_required_height:function(A,z){var y=y_scale=this.get_row_height(),B=this.mode;if(B==="no_detail"||B==="Squish"||B==="Pack"){y=A*y_scale}return y+this.get_top_padding(z)+this.get_bottom_padding(z)},get_top_padding:function(y){return 0},get_bottom_padding:function(y){return Math.max(Math.round(this.get_row_height()/2),5)},draw:function(K,I,G,F){var Q=this.data,D=this.view_start,M=this.view_end;K.save();K.fillStyle=this.prefs.block_color;K.textAlign="right";var H=this.view_end-this.view_start,E=I/H,L=this.get_row_height(),P=new m(L),B;for(var N=0,O=Q.length;N<O;N++){var A=Q[N],C=A[0],J=A[1],y=A[2],z=(F&&F[C]!==undefined?F[C]:null);if((J<M&&y>D)&&(this.mode=="Dense"||z!==null)){B=this.draw_element(K,this.mode,A,z,D,M,E,L,I);P.map_feature_data(A,z,B[0],B[1])}}K.restore();P.y_translation=this.get_top_padding(I);return P},draw_element:function(E,A,G,C,B,D,F,z,y){console.log("WARNING: Unimplemented function.");return[0,0]}});var c=10,h=3,k=5,w=10,f=1,s=9,e=3,a=9,j=2,g="#ccc";var r=function(A,D,y,z,C,E,B){o.call(this,A,D,y,z,C,E,B);this.draw_background_connector=true;this.draw_individual_connectors=false};u(r.prototype,o.prototype,{get_row_height:function(){var z=this.mode,y;if(z==="Dense"){y=c}else{if(z==="no_detail"){y=h}else{if(z==="Squish"){y=k}else{y=w}}}return y},draw_element:function(M,D,X,H,O,aj,an,ap,y){var T=X[0],al=X[1],ad=X[2],Q=X[3],ae=Math.floor(Math.max(0,(al-O)*an)),N=Math.ceil(Math.min(y,Math.max(0,(ad-O)*an))),ac=ae,ao=N,aa=(D==="Dense"?0:(0+H))*ap+this.get_top_padding(y),L,ah,R=null,ar=null,B=this.prefs.block_color,ag=this.prefs.label_color;M.globalAlpha=this.alpha_scaler.gen_val(X);if(D==="Dense"){H=1}if(D==="no_detail"){M.fillStyle=B;M.fillRect(ae,aa+5,N-ae,f)}else{var K=X[4],Z=X[5],af=X[6],C=X[7],V=true;if(Z&&af){R=Math.floor(Math.max(0,(Z-O)*an));ar=Math.ceil(Math.min(y,Math.max(0,(af-O)*an)))}var am,U;if(D==="Squish"){am=1;U=e;V=false}else{if(D==="Dense"){am=5;U=s}else{am=5;U=a}}if(!C){M.fillStyle=B;M.fillRect(ae,aa+1,N-ae,U);if(K&&V){if(K==="+"){M.fillStyle=M.canvas.manager.get_pattern("right_strand_inv")}else{if(K==="-"){M.fillStyle=M.canvas.manager.get_pattern("left_strand_inv")}}M.fillRect(ae,aa+1,N-ae,U)}}else{var J,W;if(D==="Squish"||D==="Dense"){J=aa+Math.floor(e/2)+1;W=1}else{if(K){J=aa;W=U}else{J+=(e/2)+1;W=1}}if(this.draw_background_connector){if(D==="Squish"||D==="Dense"){M.fillStyle=g}else{if(K){if(K==="+"){M.fillStyle=M.canvas.manager.get_pattern("right_strand")}else{if(K==="-"){M.fillStyle=M.canvas.manager.get_pattern("left_strand")}}}else{M.fillStyle=g}}M.fillRect(ae,J,N-ae,W)}var E;for(var ak=0,A=C.length;ak<A;ak++){var F=C[ak],z=Math.floor(Math.max(0,(F[0]-O)*an)),Y=Math.ceil(Math.min(y,Math.max((F[1]-O)*an))),S,ab;if(z>Y){continue}M.fillStyle=B;M.fillRect(z,aa+(U-am)/2+1,Y-z,am);if(R!==undefined&&af>Z&&!(z>ar||Y<R)){var ai=Math.max(z,R),I=Math.min(Y,ar);M.fillRect(ai,aa+1,I-ai,U);if(C.length==1&&D=="Pack"){if(K==="+"){M.fillStyle=M.canvas.manager.get_pattern("right_strand_inv")}else{if(K==="-"){M.fillStyle=M.canvas.manager.get_pattern("left_strand_inv")}}if(ai+14<I){ai+=2;I-=2}M.fillRect(ai,aa+1,I-ai,U)}}if(this.draw_individual_connectors&&S){this.draw_connector(M,S,ab,z,Y,aa)}S=z;ab=Y}if(D==="Pack"){M.globalAlpha=1;M.fillStyle="white";var G=this.height_scaler.gen_val(X),P=Math.ceil(U*G),aq=Math.round((U-P)/2);if(G!==1){M.fillRect(ae,J+1,N-ae,aq);M.fillRect(ae,J+U-aq+1,N-ae,aq)}}}M.globalAlpha=1;if(D==="Pack"&&al>O){M.fillStyle=ag;if(O===0&&ae-M.measureText(Q).width<0){M.textAlign="left";M.fillText(Q,N+j,aa+8);ao+=M.measureText(Q).width+j}else{M.textAlign="right";M.fillText(Q,ae-j,aa+8);ac-=M.measureText(Q).width+j}}}M.globalAlpha=1;return[ac,ao]}});var t=function(B,E,y,A,D,F,C,z){o.call(this,B,E,y,A,D,F,C);this.ref_seq=(z?z.data:null)};u(t.prototype,o.prototype,{get_row_height:function(){var y,z=this.mode;if(z==="Dense"){y=c}else{if(z==="Squish"){y=k}else{y=w;if(this.prefs.show_insertions){y*=2}}}return y},draw_read:function(K,A,ag,V,L,aa,ad,C,B,M){K.textAlign="center";var J=this,R=[L,aa],Z=0,W=0,D=0,F=K.canvas.manager.char_width_px,y=(B==="+"?this.prefs.block_color:this.prefs.reverse_strand_color);var O=[];if((A==="Pack"||this.mode==="Auto")&&M!==undefined&&ag>F){D=Math.round(ag/2)}if(!C){C=[[0,M.length]]}for(var G=0,I=C.length;G<I;G++){var z=C[G],E="MIDNSHP=X"[z[0]],S=z[1];if(E==="H"||E==="S"){Z-=S}var U=ad+Z,Y=Math.floor(Math.max(0,(U-L)*ag)),ab=Math.floor(Math.max(0,(U+S-L)*ag));if(Y===ab){ab+=1}switch(E){case"H":break;case"S":case"M":case"=":if(is_overlap([U,U+S],R)){var N=M.slice(W,W+S);if(D>0){K.fillStyle=y;K.fillRect(Y-D,V+1,ab-Y,9);K.fillStyle=g;for(var af=0,H=N.length;af<H;af++){if(this.prefs.show_differences&&this.ref_seq){var P=this.ref_seq[U-L+af];if(!P||P.toLowerCase()===N[af].toLowerCase()){continue}}if(U+af>=L&&U+af<=aa){var X=Math.floor(Math.max(0,(U+af-L)*ag));K.fillText(N[af],X,V+9)}}}else{K.fillStyle=y;K.fillRect(Y,V+4,ab-Y,e)}}W+=S;Z+=S;break;case"N":K.fillStyle=g;K.fillRect(Y-D,V+5,ab-Y,1);Z+=S;break;case"D":K.fillStyle="red";K.fillRect(Y-D,V+4,ab-Y,3);Z+=S;break;case"P":break;case"I":var ah=Y-D;if(is_overlap([U,U+S],R)){var N=M.slice(W,W+S);if(this.prefs.show_insertions){var T=Y-(ab-Y)/2;if((A==="Pack"||this.mode==="Auto")&&M!==undefined&&ag>F){K.fillStyle="yellow";K.fillRect(T-D,V-9,ab-Y,9);O[O.length]={type:"triangle",data:[ah,V+4,5]};K.fillStyle=g;switch(compute_overlap([U,U+S],R)){case (OVERLAP_START):N=N.slice(L-U);break;case (OVERLAP_END):N=N.slice(0,U-aa);break;case (CONTAINED_BY):break;case (CONTAINS):N=N.slice(L-U,U-aa);break}for(var af=0,H=N.length;af<H;af++){var X=Math.floor(Math.max(0,(U+af-L)*ag));K.fillText(N[af],X-(ab-Y)/2,V)}}else{K.fillStyle="yellow";K.fillRect(T,V+(this.mode!=="Dense"?2:5),ab-Y,(A!=="Dense"?e:s))}}else{if((A==="Pack"||this.mode==="Auto")&&M!==undefined&&ag>F){O.push({type:"text",data:[N.length,ah,V+9]})}else{}}}W+=S;break;case"X":W+=S;break}}K.fillStyle="yellow";var Q,ai,ae;for(var ac=0;ac<O.length;ac++){Q=O[ac];ai=Q.type;ae=Q.data;if(ai==="text"){K.save();K.font="bold "+K.font;K.fillText(ae[0],ae[1],ae[2]);K.restore()}else{if(ai=="triangle"){q(K,ae[0],ae[1],ae[2])}}}},draw_element:function(R,M,E,B,U,z,I,S,P){var H=E[0],Q=E[1],A=E[2],J=E[3],D=Math.floor(Math.max(0,(Q-U)*I)),F=Math.ceil(Math.min(P,Math.max(0,(A-U)*I))),C=(M==="Dense"?0:(0+B))*S,G=this.prefs.label_color,O=0;if((M==="Pack"||this.mode==="Auto")&&I>R.canvas.manager.char_width_px){var O=Math.round(I/2)}if(E[5] instanceof Array){var N=Math.floor(Math.max(0,(E[4][0]-U)*I)),L=Math.ceil(Math.min(P,Math.max(0,(E[4][1]-U)*I))),K=Math.floor(Math.max(0,(E[5][0]-U)*I)),y=Math.ceil(Math.min(P,Math.max(0,(E[5][1]-U)*I)));if(E[4][1]>=U&&E[4][0]<=z&&E[4][2]){this.draw_read(R,M,I,C,U,z,E[4][0],E[4][2],E[4][3],E[4][4])}if(E[5][1]>=U&&E[5][0]<=z&&E[5][2]){this.draw_read(R,M,I,C,U,z,E[5][0],E[5][2],E[5][3],E[5][4])}if(K>L){R.fillStyle=g;p(R,L-O,C+5,K-O,C+5)}}else{this.draw_read(R,M,I,C,U,z,Q,E[4],E[5],E[6])}if(M==="Pack"&&Q>U&&J!=="."){R.fillStyle=this.prefs.label_color;var T=1;if(T===0&&D-R.measureText(J).width<0){R.textAlign="left";R.fillText(J,F+j-O,C+8)}else{R.textAlign="right";R.fillText(J,D-j-O,C+8)}}return[0,0]}});var n=function(A,D,y,z,C,E,B){r.call(this,A,D,y,z,C,E,B);this.longest_feature_length=this.calculate_longest_feature_length();this.draw_background_connector=false;this.draw_individual_connectors=true};u(n.prototype,o.prototype,r.prototype,{calculate_longest_feature_length:function(){var z=0;for(var C=0,y=this.data.length;C<y;C++){var B=this.data[C],A=B[1],D=B[2];z=Math.max(z,D-A)}return z},get_top_padding:function(z){var y=this.view_end-this.view_start,A=z/y;return Math.min(128,Math.ceil((this.longest_feature_length/2)*A))},draw_connector:function(G,B,F,H,E,D){var y=(F+H)/2,C=H-y;var A=Math.PI,z=0;if(C>0){G.beginPath();G.arc(y,D,H-y,Math.PI,0);G.stroke()}}});x.Scaler=d;x.SummaryTreePainter=v;x.LinePainter=b;x.LinkedFeaturePainter=r;x.ReadPainter=t;x.ArcLinkedFeaturePainter=n};(function(d){var c={};var b=function(e){return c[e]};var a=function(f,g){var e={};g(b,e);c[f]=e};a("class",class_module);a("slotting",slotting_module);a("painters",painters_module);a("trackster",trackster_module);for(key in c.trackster){d[key]=c.trackster[key]}})(window); \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca static/scripts/packed/trackster_ui.js --- a/static/scripts/packed/trackster_ui.js +++ b/static/scripts/packed/trackster_ui.js @@ -1,1 +1,1 @@ -var add_bookmark=function(b,a){var g=$("#bookmarks-container"),d=$("<div/>").addClass("bookmark").appendTo(g),c=$("<div/>").addClass("delete-icon-container").appendTo(d).click(function(){d.slideUp("fast");d.remove();view.has_changes=true;return false}),e=$("<a href=''/>").addClass("icon-button delete").appendTo(c),f=$("<div/>").addClass("position").appendTo(d),h=$("<a href=''/>").text(b).appendTo(f).click(function(){view.go_to(b);return false});annotation_div=get_editable_text_elt(a,true).addClass("annotation").appendTo(d);view.has_changes=true;return d};var addable_objects={LineTrack:LineTrack,FeatureTrack:FeatureTrack,VcfTrack:VcfTrack,ReadTrack:ReadTrack,DrawableGroup:DrawableGroup};var track_from_dict=function(c,b){var a=new addable_objects[c.track_type](c.name,view,b,c.hda_ldda,c.dataset_id,c.prefs,c.filters,c.tool);if(c.mode){a.change_mode(c.mode)}return a};var drawable_collection_from_dict=function(f,a){var e=new addable_objects[f.obj_type](f.name,view,a,f.prefs,view.viewport_container,view);for(var d=0;d<f.drawables.length;d++){var b=f.drawables[d],c;if(b.track_type){c=track_from_dict(b,e)}else{c=drawable_collection_from_dict(b)}e.add_drawable(c);e.content_div.append(c.container_div)}return e};var drawable_from_dict=function(b,a){return(b.track_type?track_from_dict(b,a):drawable_collection_from_dict(b,a))};var create_visualization=function(b,e,g,c,a,d,f){view=new View(b,e,g,c);view.editor=true;$.when(view.load_chroms_deferred).then(function(){if(a){var k=a.chrom,p=a.start,h=a.end,m=a.overview;if(k&&(p!==undefined)&&h){view.change_chrom(k,p,h)}}if(d){var o;for(var j=0;j<d.length;j++){o=d[j];view.add_drawable(drawable_from_dict(o,view))}}var n;for(var j=0;j<view.drawables.length;j++){if(view.drawables[j].name===m){view.set_overview(view.drawables[j]);break}}if(f){var l;for(var j=0;j<f.length;j++){l=f[j];add_bookmark(l.position,l.annotation)}}view.has_changes=false});return view};var init_keyboard_nav=function(a){$(document).keydown(function(b){if($(b.srcElement).is(":input")){return}switch(b.which){case 37:a.move_fraction(0.25);break;case 38:var c=Math.round(a.viewport_container.height()/15);a.viewport_container.scrollTo("-="+c+"px");break;case 39:a.move_fraction(-0.25);break;case 40:var c=Math.round(a.viewport_container.height()/15);a.viewport_container.scrollTo("+="+c+"px");break}})}; \ No newline at end of file +var add_bookmark=function(b,a){var g=$("#bookmarks-container"),d=$("<div/>").addClass("bookmark").appendTo(g),c=$("<div/>").addClass("delete-icon-container").appendTo(d).click(function(){d.slideUp("fast");d.remove();view.has_changes=true;return false}),e=$("<a href=''/>").addClass("icon-button delete").appendTo(c),f=$("<div/>").addClass("position").appendTo(d),h=$("<a href=''/>").text(b).appendTo(f).click(function(){view.go_to(b);return false});annotation_div=get_editable_text_elt(a,true).addClass("annotation").appendTo(d);view.has_changes=true;return d};var addable_objects={LineTrack:LineTrack,FeatureTrack:FeatureTrack,VcfTrack:VcfTrack,ReadTrack:ReadTrack,DrawableGroup:DrawableGroup};var track_from_dict=function(c,b){var a=new addable_objects[c.track_type](c.name,view,b,c.hda_ldda,c.dataset_id,c.prefs,c.filters,c.tool);if(c.mode){a.change_mode(c.mode)}return a};var drawable_collection_from_dict=function(f,a){var e=new addable_objects[f.obj_type](f.name,view,a,f.prefs,view.viewport_container,view);for(var d=0;d<f.drawables.length;d++){var b=f.drawables[d],c;if(b.track_type){c=track_from_dict(b,e)}else{c=drawable_collection_from_dict(b)}e.add_drawable(c);e.content_div.append(c.container_div)}return e};var drawable_from_dict=function(b,a){return(b.track_type?track_from_dict(b,a):drawable_collection_from_dict(b,a))};var create_visualization=function(b,e,g,c,a,d,f){view=new View(b,e,g,c);view.editor=true;$.when(view.load_chroms_deferred).then(function(){if(a){var k=a.chrom,p=a.start,h=a.end,m=a.overview;if(k&&(p!==undefined)&&h){view.change_chrom(k,p,h)}}if(d){var o;for(var j=0;j<d.length;j++){o=d[j];view.add_drawable(drawable_from_dict(o,view))}}view.update_intro_div();var n;for(var j=0;j<view.drawables.length;j++){if(view.drawables[j].name===m){view.set_overview(view.drawables[j]);break}}if(f){var l;for(var j=0;j<f.length;j++){l=f[j];add_bookmark(l.position,l.annotation)}}view.has_changes=false});return view};var init_keyboard_nav=function(a){$(document).keydown(function(b){if($(b.srcElement).is(":input")){return}switch(b.which){case 37:a.move_fraction(0.25);break;case 38:var c=Math.round(a.viewport_container.height()/15);a.viewport_container.scrollTop(a.viewport_container.scrollTop()-20);break;case 39:a.move_fraction(-0.25);break;case 40:var c=Math.round(a.viewport_container.height()/15);a.viewport_container.scrollTop(a.viewport_container.scrollTop()+20);break}})}; \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca static/scripts/trackster.js --- a/static/scripts/trackster.js +++ b/static/scripts/trackster.js @@ -650,8 +650,13 @@ */ /** - * Base interface for all drawable objects. Drawable objects have a name and are - * associated with a view and container. They optionally have a drag handle class. + * Base class for all drawable objects. Drawable objects are associated with a view and live in a + * container. They have the following HTML elements and structure: + * <container_div> + * <header_div> + * <content_div> + * + * They optionally have a drag handle class. */ var Drawable = function(name, view, container, prefs, drag_handle_class) { if (!Drawable.id_counter) { Drawable.id_counter = 0; } @@ -672,6 +677,33 @@ this.prefs = this.config.values; this.drag_handle_class = drag_handle_class; this.is_overview = false; + + // FIXME: this should be a saved setting + this.content_visible = true; + + // Build Drawable HTML and behaviors. + this.container_div = this.build_container_div(); + this.header_div = this.build_header_div(); + + if (this.header_div) { + this.container_div.append(this.header_div); + + this.icons_div = this.build_icons_div().hide(); + this.header_div.append(this.icons_div); + + // Suppress double clicks in header so that they do not impact viz. + this.header_div.dblclick( function(e) { e.stopPropagation(); } ); + + // Show icons when users is hovering over track. + var drawable = this; + this.container_div.hover( + function() { drawable.icons_div.show(); }, + function() { drawable.icons_div.hide(); } + ); + + // Needed for floating elts in header. + $("<div style='clear: both'/>").appendTo(this.container_div); + } }; extend(Drawable.prototype, { @@ -701,13 +733,37 @@ remove: function() { this.container.remove_drawable(this); - this.container_div.fadeOut('slow', function() { + this.container_div.hide(0, function() { $(this).remove(); // HACK: is there a better way to update the view? view.update_intro_div(); view.has_changes = true; }); - } + }, + /** + * Build drawable's container div; this is the parent div for all drawable's elements. + */ + build_container_div: function() {}, + /** + * Build drawable's header div. + */ + build_header_div: function() {}, + /** + * Build drawable's icons div. + */ + build_icons_div: function() {}, + /** + * Update icons. + */ + update_icons: function() {}, + /** + * Hide drawable's contents. + */ + hide_contents: function () {}, + /** + * Show drawable's contents. + */ + show_contents: function() {} }); /** @@ -805,36 +861,54 @@ var DrawableGroup = function(name, view, container, prefs) { DrawableCollection.call(this, "DrawableGroup", name, view, container, prefs, "group-handle"); - // HTML elements. - this.container_div = $("<div/>").addClass("group").attr("id", "group_" + this.id).appendTo(this.container.content_div); - this.header_div = $("<div/>").addClass("track-header").appendTo(this.container_div); - this.header_div.append($("<div/>").addClass(this.drag_handle_class)); - this.name_div = $("<div/>").addClass("group-name menubutton popup").text(this.name).appendTo(this.header_div); - this.content_div = $("<div/>").addClass("content-div").attr("id", "group_" + this.id + "_content_div").appendTo(this.container_div); - // Set up containers/moving for group: register both container_div and content div as container // because both are used as containers (container div to recognize container, content_div to // store elements). Group can be moved. + this.content_div = $("<div/>").addClass("content-div").attr("id", "group_" + this.id + "_content_div").appendTo(this.container_div); is_container(this.container_div, this); is_container(this.content_div, this); moveable(this.container_div, this.drag_handle_class, ".group", this); - - this.update_icons(); }; extend(DrawableGroup.prototype, Drawable.prototype, DrawableCollection.prototype, { - /** - * Make popup menu for group. - */ - update_icons: function() { + build_container_div: function() { + return $("<div/>").addClass("group").attr("id", "group_" + this.id).appendTo(this.container.content_div); + }, + build_header_div: function() { + var header_div = $("<div/>").addClass("track-header"); + header_div.append($("<div/>").addClass(this.drag_handle_class)); + this.name_div = $("<div/>").addClass("track-name").text(this.name).appendTo(header_div); + return header_div; + }, + build_icons_div: function() { + var icons_div = $("<div/>").css("float", "left"); + + this.toggle_icon = $("<a/>").attr("href", "javascript:void(0);").attr("title", "Hide/show group content") + .addClass("icon-button toggle").tipsy( {gravity: 's'} ) + .appendTo(icons_div); + this.settings_icon = $("<a/>").attr("href", "javascript:void(0);").attr("title", "Edit settings") + .addClass("icon-button settings-icon").tipsy( {gravity: 's'} ) + .appendTo(icons_div); + this.remove_icon = $("<a/>").attr("href", "javascript:void(0);").attr("title", "Remove") + .addClass("icon-button remove-icon").tipsy( {gravity: 's'} ) + .appendTo(icons_div); var group = this; - - var group_dropdown = {}; - - // - // Edit config option. - // - group_dropdown["Edit configuration"] = function() { + + // Toggle icon hides or shows the group content. + this.toggle_icon.click( function() { + if ( group.content_visible ) { + group.toggle_icon.addClass("toggle-expand").removeClass("toggle"); + group.hide_contents(); + group.content_visible = false; + } else { + group.toggle_icon.addClass("toggle").removeClass("toggle-expand"); + group.content_visible = true; + group.show_contents(); + } + }); + + // Clicking on settings icon opens group config. + this.settings_icon.click( function() { var cancel_fn = function() { hide_modal(); $(window).unbind("keypress.check_enter_esc"); }, ok_fn = function() { group.config.update_from_form( $(".dialog-box") ); @@ -854,16 +928,25 @@ "Cancel": cancel_fn, "OK": ok_fn }); - }; + }); - // - // Remove option. - // - group_dropdown.Remove = function() { + // Clicking on remove icon removes group. + this.remove_icon.click( function() { + // Tipsy for remove icon must be deleted when group is deleted. + $(".tipsy").remove(); group.remove(); - }; + }); - make_popupmenu(group.name_div, group_dropdown); + return icons_div; + }, + hide_contents : function () { + this.content_div.hide(); + }, + show_contents : function() { + // Show the contents div and labels (if present) + this.content_div.show(); + // Request a redraw of the content + this.request_draw(); } }); @@ -909,7 +992,7 @@ this.content_div = this.viewport_container; is_container(this.viewport_container, view); // Introduction div shown when there are no tracks. - this.intro_div = $("<div/>").addClass("intro"); + this.intro_div = $("<div/>").addClass("intro").appendTo(this.viewport_container).hide(); var add_tracks_button = $("<div/>").text("Add Datasets to Visualization").addClass("action-button").appendTo(this.intro_div).click(function () { add_tracks(); }); @@ -1027,6 +1110,7 @@ // Only act on x axis scrolling if we see if, y will be i // handled by the browser when the event bubbles up if ( dx ) { + dx *= 50; var delta_chrom = Math.round( - dx / view.viewport_container.width() * (view.high - view.low) ); view.move_delta( delta_chrom ); } @@ -1076,10 +1160,10 @@ /** Add or remove intro div depending on view state. */ update_intro_div: function() { if (this.drawables.length === 0) { - this.intro_div.appendTo(this.viewport_container); + this.intro_div.show(); } else { - this.intro_div.remove(); + this.intro_div.hide(); } }, update_location: function(low, high) { @@ -1255,7 +1339,7 @@ DrawableCollection.prototype.remove_drawable.call(this, drawable); if (hide) { var view = this; - drawable.container_div.fadeOut('slow', function() { + drawable.container_div.hide(0, function() { $(this).remove(); view.update_intro_div(); }); @@ -2114,31 +2198,49 @@ build_form: function() { var track_config = this; var container = $("<div />"); - $.each( this.params, function( index, param ) { - if ( ! param.hidden ) { + var param; + // Function to process parameters recursively + function handle_params( params, container ) { + for ( var index = 0; index < params.length; index++ ) { + param = params[index]; + // Hidden params have no representation in the form + if ( param.hidden ) { continue; } + // Build row for param var id = 'param_' + index; var value = track_config.values[ param.key ]; var row = $("<div class='form-row' />").appendTo( container ); row.append( $('<label />').attr("for", id ).text( param.label + ":" ) ); + // Draw parameter as checkbox if ( param.type === 'bool' ) { row.append( $('<input type="checkbox" />').attr("id", id ).attr("name", id ).attr( 'checked', value ) ); + // Draw parameter as textbox } else if ( param.type === 'text' ) { row.append( $('<input type="text"/>').attr("id", id ).val(value).click( function() { $(this).select() })); + // Draw paramter as select area + } else if ( param.type == 'select' ) { + var select = $('<select />').attr("id", id); + for ( var i = 0; i < param.options.length; i++ ) { + $("<option/>").text( param.options[i].label ).attr( "value", param.options[i].value ).appendTo( select ); + } + select.val( value ); + row.append( select ); + // Draw parameter as color picker } else if ( param.type === 'color' ) { var input = $('<input />').attr("id", id ).attr("name", id ).val( value ); // Color picker in tool tip style float - var tip = $( "<div class='tipsy tipsy-north' style='position: absolute;' />" ).hide(); + var tip = $( "<div class='tipsy tipsy-west' style='position: absolute;' />" ).hide(); // Inner div for padding purposes var tip_inner = $("<div style='background-color: black; padding: 10px;'></div>").appendTo(tip); var farb_container = $("<div/>") .appendTo(tip_inner) .farbtastic( { width: 100, height: 100, callback: input, color: value }); - // Outer div container input and tip for hover to work $("<div />").append( input ).append( tip ).appendTo( row ).bind( "click", function ( e ) { tip.css( { - left: $(this).position().left + ( $(input).width() / 2 ) - 60, - top: $(this).position().top + $(this.height) + // left: $(this).position().left + ( $(input).width() / 2 ) - 60, + // top: $(this).position().top + $(this.height) + left: $(this).position().left + $(input).width() + 5, + top: $(this).position().top - ( $(tip).height() / 2 ) + ( $(input).height() / 2 ) } ).show(); $(document).bind( "click.color-picker", function() { tip.hide(); @@ -2150,8 +2252,15 @@ else { row.append( $('<input />').attr("id", id ).attr("name", id ).val( value ) ); } + // Help text + if ( param.help ) { + row.append( $("<div class='help'/>").text( param.help ) ); + } } - }); + } + // Handle top level parameters in order + handle_params( this.params, container ); + // Return element containing constructed form return container; }, update_from_form: function( container ) { @@ -2229,7 +2338,16 @@ // Only show popups in Pack mode. if (tile.mode !== "Pack") { return; } - $(this.canvas).mousemove(function (e) { + $(this.canvas).hover( function() { + this.hovered = true; + $(this).mousemove(); + }, function() { + this.hovered = false; + // Clear popup if it is still hanging around (this is probably not needed) + $(this).siblings(".feature-popup").remove(); + } ).mousemove(function (e) { + // Use the hover plugin to get a delay before showing popup + if ( !this.hovered ) { return; } // Get feature data for position. var this_offset = $(this).offset(), @@ -2270,8 +2388,8 @@ // Build popup. var popup = $("<div/>").attr("id", feature_uid).addClass("feature-popup"), - key, value, - table = $("<table/>").appendTo(popup), row; + table = $("<table/>"), + key, value, row; for (key in feature_dict) { value = feature_dict[key]; row = $("<tr/>").appendTo(table); @@ -2279,6 +2397,7 @@ $("<td/>").attr("align", "left").appendTo(row) .text(typeof(value) == 'number' ? round(value, 2) : value); } + popup.append( $("<div class='feature-popup-inner'>").append( table ) ); popups[feature_uid] = popup; } @@ -2289,7 +2408,7 @@ // parseInt strips "px" from left, top measurements. +7 so that mouse pointer does not // overlap popup. var - popupX = offsetX + parseInt( tile.canvas.css("left") ) + 7, + popupX = offsetX + parseInt( tile.canvas.css("left") ) - popup.width() / 2, popupY = offsetY + parseInt( tile.canvas.css("top") ) + 7; popup.css("left", popupX + "px").css("top", popupY + "px") } @@ -2320,7 +2439,7 @@ * -------> ReadTrack * -------> VcfTrack */ -var Track = function(name, view, container, show_header, prefs, data_url, data_query_wait) { +var Track = function(name, view, container, prefs, data_url, data_query_wait) { // For now, track's container is always view. Drawable.call(this, name, view, container, {}, "draghandle"); @@ -2331,41 +2450,89 @@ this.data_url_extra_params = {} this.data_query_wait = (data_query_wait ? data_query_wait : DEFAULT_DATA_QUERY_WAIT); this.dataset_check_url = converted_datasets_state_url; - + + if (!Track.id_counter) { Track.id_counter = 0; } + this.id = Track.id_counter++; + // - // Create HTML element structure for track. + // Create content div, which is where track is displayed. // - this.container_div = $("<div />").addClass('track').attr("id", "track_" + this.id).css("position", "relative"); - - // Create and initialize track header and icons. - if (show_header) { - this.header_div = $("<div class='track-header' />").appendTo(this.container_div); - if (this.view.editor) { this.drag_div = $("<div/>").addClass(this.drag_handle_class).appendTo(this.header_div); } - this.name_div = $("<div/>").addClass("track-name").appendTo(this.header_div).text(this.name) + this.content_div = $("<div class='track-content'>").appendTo(this.container_div); + this.container.content_div.append(this.container_div); +}; +extend(Track.prototype, Drawable.prototype, { + build_container_div: function () { + return $("<div/>").addClass('track').attr("id", "track_" + this.id).css("position", "relative"); + }, + build_header_div: function() { + var header_div = $("<div class='track-header'/>"); + if (this.view.editor) { this.drag_div = $("<div/>").addClass(this.drag_handle_class).appendTo(header_div); } + this.name_div = $("<div/>").addClass("track-name").appendTo(header_div).text(this.name) .attr( "id", this.name.replace(/\s+/g,'-').replace(/[^a-zA-Z0-9\-]/g,'').toLowerCase() ); - this.icons_div = $("<div/>").css("float", "left").appendTo(this.header_div).hide(); - + return header_div; + }, + build_icons_div: function() { + var icons_div = $("<div/>").css("float", "left"); + // Track icons. + this.mode_icon = $("<a/>").attr("href", "javascript:void(0);").attr("title", "Set display mode") + .addClass("icon-button chevron-expand").tipsy( {gravity: 's'} ).appendTo(icons_div); + this.toggle_icon = $("<a/>").attr("href", "javascript:void(0);").attr("title", "Hide/show track content") + .addClass("icon-button toggle").tipsy( {gravity: 's'} ) + .appendTo(icons_div); this.settings_icon = $("<a/>").attr("href", "javascript:void(0);").attr("title", "Edit settings") .addClass("icon-button settings-icon").tipsy( {gravity: 's'} ) - .appendTo(this.icons_div); + .appendTo(icons_div); this.overview_icon = $("<a/>").attr("href", "javascript:void(0);").attr("title", "Set as overview") .addClass("icon-button overview-icon").tipsy( {gravity: 's'} ) - .appendTo(this.icons_div); + .appendTo(icons_div); this.filters_icon = $("<a/>").attr("href", "javascript:void(0);").attr("title", "Filters") .addClass("icon-button filters-icon").tipsy( {gravity: 's'} ) - .appendTo(this.icons_div).hide(); + .appendTo(icons_div).hide(); this.tools_icon = $("<a/>").attr("href", "javascript:void(0);").attr("title", "Tools") .addClass("icon-button tools-icon").tipsy( {gravity: 's'} ) - .appendTo(this.icons_div).hide(); + .appendTo(icons_div).hide(); this.remove_icon = $("<a/>").attr("href", "javascript:void(0);").attr("title", "Remove") .addClass("icon-button remove-icon").tipsy( {gravity: 's'} ) - .appendTo(this.icons_div); + .appendTo(icons_div); var track = this; - - // Suppress double clicks in header so that they do not impact viz. - this.header_div.dblclick( function(e) { e.stopPropagation(); } ); - + + // Set up behavior for modes popup. + if (track.display_modes !== undefined) { + var init_mode = (track.config && track.config.values['mode'] ? + track.config.values['mode'] : track.display_modes[0]); + track.mode = init_mode; + this.mode_icon.attr("title", "Set display mode (now: " + track.mode + ")"); + + var mode_mapping = {}; + for (var i = 0, len = track.display_modes.length; i < len; i++) { + var mode = track.display_modes[i]; + mode_mapping[mode] = function(mode) { + return function() { + track.change_mode(mode); + // HACK: the popup menu messes with the track's hover event, so manually show/hide + // icons div for now. + track.icons_div.show(); + track.container_div.mouseleave(function() { track.icons_div.hide(); } ); }; + }(mode); + } + + make_popupmenu(this.mode_icon, mode_mapping); + } + + // Toggle icon hides or shows the track content. + this.toggle_icon.click( function() { + if ( track.content_visible ) { + track.toggle_icon.addClass("toggle-expand").removeClass("toggle"); + track.hide_contents(); + track.content_visible = false; + } else { + track.toggle_icon.addClass("toggle").removeClass("toggle-expand"); + track.content_visible = true; + track.show_contents(); + } + }); + // Clicking on settings icon opens track config. this.settings_icon.click( function() { var cancel_fn = function() { hide_modal(); $(window).unbind("keypress.check_enter_esc"); }, @@ -2388,22 +2555,22 @@ "OK": ok_fn }); }); - + this.overview_icon.click( function() { track.view.set_overview(track); }); - + this.filters_icon.click( function() { // TODO: update tipsy text. track.filters_div.toggle(); track.filters_manager.reset_filters(); }); - + this.tools_icon.click( function() { // TODO: update tipsy text. - + track.dynamic_tool_div.toggle(); - + // Update track name. if (track.dynamic_tool_div.is(":visible")) { track.set_name(track.name + track.tool_region_and_parameters_str()); @@ -2414,7 +2581,7 @@ // HACK: name change modifies icon placement, which leaves tooltip incorrectly placed. $(".tipsy").remove(); }); - + // Clicking on remove icon removes track. this.remove_icon.click( function() { // Tipsy for remove icon must be deleted when track is deleted. @@ -2422,44 +2589,31 @@ track.remove(); }); - // Set up behavior for modes popup. - if (track.display_modes !== undefined) { - if (track.mode_div === undefined) { - track.mode_div = $("<div class='right-float menubutton popup' />").appendTo(track.header_div); - var init_mode = (track.config && track.config.values['mode'] ? - track.config.values['mode'] : track.display_modes[0]); - track.mode = init_mode; - track.mode_div.text(init_mode); - - var mode_mapping = {}; - for (var i = 0, len = track.display_modes.length; i < len; i++) { - var mode = track.display_modes[i]; - mode_mapping[mode] = function(mode) { - return function() { track.change_mode(mode); }; - }(mode); - } - make_popupmenu(track.mode_div, mode_mapping); - } else { - track.mode_div.hide(); - } - - this.header_div.append( $("<div/>").css("clear", "both") ); - - // Set up config icon. - - // Show icons when users is hovering over track. - this.container_div.hover( function() { track.icons_div.show(); }, function() { track.icons_div.hide(); } ); - } - } - - // - // Create content div, which is where track is displayed. - // - this.content_div = $("<div class='track-content'>").appendTo(this.container_div); - this.container.content_div.append(this.container_div); -}; -extend(Track.prototype, Drawable.prototype, { - /** Returns track type. */ + return icons_div; + }, + /** + * Hide any elements that are part of the tracks contents area. Should + * remove as approprite, the track will be redrawn by show_contents. + */ + hide_contents : function () { + // Clear contents by removing any elements that are contained in + // the tracks content_div + this.content_div.children().remove(); + // Hide the content div + this.content_div.hide(); + // And any y axis labels (common to several track types) + this.container_div.find(".yaxislabel, .track-resize").hide() + }, + show_contents : function() { + // Show the contents div and labels (if present) + this.content_div.show(); + this.container_div.find(".yaxislabel, .track-resize").show() + // Request a redraw of the content + this.request_draw(); + }, + /** + * Returns track type. + */ get_type: function() { // Order is important: start with most-specific classes and go up the track hierarchy. if (this instanceof LabelTrack) { @@ -2557,8 +2711,8 @@ predraw_init: function() {} }); -var TiledTrack = function(name, view, container, show_header, prefs, filters_list, tool_dict) { - Track.call(this, name, view, container, show_header, prefs); +var TiledTrack = function(name, view, container, prefs, filters_list, tool_dict) { + Track.call(this, name, view, container, prefs); var track = this, view = track.view; @@ -2616,12 +2770,12 @@ */ change_mode: function(name) { var track = this; - track.mode_div.text(name); // TODO: is it necessary to store the mode in two places (.mode and track_config)? track.mode = name; track.config.values['mode'] = name; track.tile_cache.clear(); track.request_draw(); + this.mode_icon.attr("title", "Set display mode (now: " + track.mode + ")"); return track; }, /** @@ -2682,6 +2836,11 @@ */ _draw: function(force, clear_after) { if (!this.enabled) { return; } + + // TODO: There should probably be a general way to disable content drawing + // for all drawables. However the button to toggle this is currently + // only present for Track instances. + if (!this.content_visible) { return; } // HACK: ReferenceTrack can draw without dataset ID, but other tracks cannot. if ( !(this instanceof ReferenceTrack) && (!this.dataset_id) ) { return; } @@ -2694,7 +2853,7 @@ w_scale = width / range, resolution = this.view.resolution, parent_element = $("<div style='position: relative;'></div>"); - + // For overview, adjust high, low, resolution, and w_scale. if (this.is_overview) { low = this.view.max_low; @@ -2946,6 +3105,7 @@ this.container_div.addClass( "label-track" ); }; extend(LabelTrack.prototype, Track.prototype, { + build_header_div: function() {}, init: function() { // Enable by default because there should always be data when drawing track. this.enabled = true; @@ -2972,7 +3132,7 @@ }); var ReferenceTrack = function (view) { - TiledTrack.call(this, "reference", view, { content_div: view.top_labeltrack }, false, {}); + TiledTrack.call(this, "reference", view, { content_div: view.top_labeltrack }, {}); view.reference_track = this; this.left_offset = 200; @@ -2987,6 +3147,7 @@ this.tile_cache = new Cache(CACHED_TILES_LINE); }; extend(ReferenceTrack.prototype, Drawable.prototype, TiledTrack.prototype, { + build_header_div: function() {}, init: function() { // Enable by default because there should always be data when drawing track. this.enabled = true; @@ -3024,11 +3185,12 @@ var track = this; this.display_modes = ["Histogram", "Line", "Filled", "Intensity"]; this.mode = "Histogram"; - TiledTrack.call( this, name, view, container, true, prefs ); + TiledTrack.call( this, name, view, container, prefs ); this.min_height_px = 16; this.max_height_px = 400; - this.height_px = 80; + // Default height for new tracks, should be a defined constant? + this.height_px = 32; this.hda_ldda = hda_ldda; this.dataset_id = dataset_id; this.original_dataset_id = dataset_id; @@ -3076,8 +3238,10 @@ var drag_control = $( "<div class='track-resize'>" ) // Control shows on hover over track, stays while dragging $(track.container_div).hover( function() { - in_handle = true; - drag_control.show(); + if ( track.content_visible ) { + in_handle = true; + drag_control.show(); + } }, function() { in_handle = false; if ( ! in_drag ) { drag_control.hide(); } @@ -3108,9 +3272,20 @@ track.container_div.addClass( "line-track" ); var data = result.data; if ( isNaN(parseFloat(track.prefs.min_value)) || isNaN(parseFloat(track.prefs.max_value)) ) { - track.prefs.min_value = data.min; - track.prefs.max_value = data.max; + // Compute default minimum and maximum values + var min_value = data.min + var max_value = data.max + // If mean and sd are present, use them to compute a ~95% window + // but only if it would shrink the range on one side + min_value = Math.floor( Math.min( 0, Math.max( min_value, data.mean - 2 * data.sd ) ) ) + max_value = Math.ceil( Math.max( 0, Math.min( max_value, data.mean + 2 * data.sd ) ) ) + // Update the prefs + track.prefs.min_value = min_value; + track.prefs.max_value = max_value; // Update the config + // FIXME: we should probably only save this when the user explicately sets it + // since we lose the ability to compute it on the fly (when changing + // chromosomes for example). $('#track_' + track.dataset_id + '_minval').val(track.prefs.min_value); $('#track_' + track.dataset_id + '_maxval').val(track.prefs.max_value); } @@ -3170,7 +3345,7 @@ // // Initialization. // - TiledTrack.call(this, name, view, container, true, prefs, filters, tool); + TiledTrack.call(this, name, view, container, prefs, filters, tool); // Define and restore track configuration. this.config = new DrawableConfig( { @@ -3179,13 +3354,17 @@ { key: 'name', label: 'Name', type: 'text', default_value: name }, { key: 'block_color', label: 'Block color', type: 'color', default_value: get_random_color() }, { key: 'label_color', label: 'Label color', type: 'color', default_value: 'black' }, - { key: 'show_counts', label: 'Show summary counts', type: 'bool', default_value: true }, + { key: 'show_counts', label: 'Show summary counts', type: 'bool', default_value: true, + help: 'Show the number of items in each bin when drawing summary histogram' }, + { key: 'connector_style', label: 'Connector style', type: 'select', default_value: 'fishbones', + options: [ { label: 'Line with arrows', value: 'fishbone' }, { label: 'Arcs', value: 'arcs' } ] }, { key: 'mode', type: 'string', default_value: this.mode, hidden: true }, ], saved_values: prefs, onchange: function() { track.set_name(track.prefs.name); track.tile_cache.clear(); + track.set_painter_from_config(); track.request_draw(); } }); @@ -3205,9 +3384,17 @@ this.data_manager = new DataManager(20, this); this.left_offset = 200; - this.painter = painters.LinkedFeaturePainter; + // this.painter = painters.LinkedFeaturePainter; + this.set_painter_from_config(); }; extend(FeatureTrack.prototype, Drawable.prototype, TiledTrack.prototype, { + set_painter_from_config: function() { + if ( this.config.values['connector_style'] == 'arcs' ) { + this.painter = painters.ArcLinkedFeaturePainter; + } else { + this.painter = painters.LinkedFeaturePainter; + } + }, /** * Actions to be taken after draw has been completed. Draw is completed when all tiles have been * drawn/fetched and shown. @@ -3294,13 +3481,14 @@ } }, update_auto_mode: function( mode ) { + var mode; if ( this.mode == "Auto" ) { if ( mode == "no_detail" ) { mode = "feature spans"; } else if ( mode == "summary_tree" ) { mode = "coverage histogram"; } - this.mode_div.text( "Auto (" + mode + ")" ); + this.mode_icon.attr("title", "Set display mode (now: Auto/" + mode + ")"); } }, /** @@ -3527,7 +3715,7 @@ var filter_height_scaler = (this.filters_manager.height_filter ? new FilterScaler(this.filters_manager.height_filter) : null); // HACK: ref_seq will only be defined for ReadTracks, and only the ReadPainter accepts that argument var painter = new (this.painter)(filtered, tile_low, tile_high, this.prefs, mode, filter_alpha_scaler, filter_height_scaler, ref_seq); - var required_height = Math.max(MIN_TRACK_HEIGHT, painter.get_required_height(slots_required)); + var required_height = Math.max(MIN_TRACK_HEIGHT, painter.get_required_height(slots_required,width)); var canvas = this.view.canvas_manager.new_canvas(); var feature_mapper = null; @@ -4057,6 +4245,7 @@ this.feature_positions = {}; this.slot_height = slot_height; this.translation = 0; + this.y_translation = 0; }; /** @@ -4078,7 +4267,7 @@ */ FeaturePositionMapper.prototype.get_feature_data = function(x, y) { // Find slot using Y. - var slot = Math.floor( y/this.slot_height ), + var slot = Math.floor( (y-this.y_translation)/this.slot_height ), feature_dict; // May not be over a slot due to padding, margin, etc. @@ -4108,15 +4297,23 @@ FeaturePainter.prototype.default_prefs = { block_color: "#FFF", connector_color: "#FFF" }; extend(FeaturePainter.prototype, { - get_required_height: function(rows_required) { + get_required_height: function(rows_required, width) { // y_scale is the height per row var required_height = y_scale = this.get_row_height(), mode = this.mode; // If using a packing mode, need to multiply by the number of slots used if (mode === "no_detail" || mode === "Squish" || mode === "Pack") { required_height = rows_required * y_scale; } + return required_height + this.get_top_padding(width) + this.get_bottom_padding(width); + }, + /** Extra padding before first row of features */ + get_top_padding: function(width) { + return 0; + }, + /** Extra padding after last row of features */ + get_bottom_padding: function(width) { // Pad bottom by half a row, at least 5 px - return required_height + Math.max( Math.round( y_scale / 2 ), 5 ); + return Math.max( Math.round( this.get_row_height() / 2 ), 5 ) }, /** * Draw data on ctx using slots and within the rectangle defined by width and height. Returns @@ -4153,6 +4350,7 @@ } ctx.restore(); + feature_mapper.y_translation = this.get_top_padding(width); return feature_mapper; }, /** @@ -4171,7 +4369,7 @@ SQUISH_TRACK_HEIGHT = 5, PACK_TRACK_HEIGHT = 10, NO_DETAIL_FEATURE_HEIGHT = 1, - DENSE_FEATURE_HEIGHT = 3, + DENSE_FEATURE_HEIGHT = 9, SQUISH_FEATURE_HEIGHT = 3, PACK_FEATURE_HEIGHT = 9, LABEL_SPACING = 2, @@ -4179,6 +4377,10 @@ var LinkedFeaturePainter = function(data, view_start, view_end, prefs, mode, alpha_scaler, height_scaler) { FeaturePainter.call(this, data, view_start, view_end, prefs, mode, alpha_scaler, height_scaler); + // Whether to draw a single connector in the background that spans the entire feature (the intron fishbone) + this.draw_background_connector = true; + // Whether to call draw_connector for every pair of blocks + this.draw_individual_connectors = false; }; extend(LinkedFeaturePainter.prototype, FeaturePainter.prototype, { @@ -4216,7 +4418,7 @@ f_end = Math.ceil( Math.min(width, Math.max(0, (feature_end - tile_low) * w_scale)) ), draw_start = f_start, draw_end = f_end, - y_center = (mode === "Dense" ? 0 : (0 + slot)) * y_scale, + y_center = (mode === "Dense" ? 0 : (0 + slot)) * y_scale + this.get_top_padding(width), thickness, y_start, thick_start = null, thick_end = null, // TODO: is there any reason why block, label color cannot be set at the Painter level? block_color = this.prefs.block_color, @@ -4240,7 +4442,9 @@ var feature_strand = feature[4], feature_ts = feature[5], feature_te = feature[6], - feature_blocks = feature[7]; + feature_blocks = feature[7], + // Whether we are drawing full height or squished features + full_height = true; if (feature_ts && feature_te) { thick_start = Math.floor( Math.max(0, (feature_ts - tile_low) * w_scale) ); @@ -4249,9 +4453,13 @@ // Set vars that depend on mode. var thin_height, thick_height; - if (mode === "Squish" || mode === "Dense" ) { + if (mode === "Squish" ) { thin_height = 1; thick_height = SQUISH_FEATURE_HEIGHT; + full_height = false; + } else if ( mode === "Dense" ) { + thin_height = 5; + thick_height = DENSE_FEATURE_HEIGHT; } else { // mode === "Pack" thin_height = 5; thick_height = PACK_FEATURE_HEIGHT; @@ -4260,17 +4468,17 @@ // Draw feature/feature blocks + connectors. if (!feature_blocks) { // If there are no blocks, treat the feature as one big exon. - if ( feature.strand ) { - if (feature.strand === "+") { + ctx.fillStyle = block_color; + ctx.fillRect(f_start, y_center + 1, f_end - f_start, thick_height); + // If strand is specified, draw arrows over feature + if ( feature_strand && full_height ) { + if (feature_strand === "+") { ctx.fillStyle = ctx.canvas.manager.get_pattern( 'right_strand_inv' ); - } else if (feature.strand === "-") { + } else if (feature_strand === "-") { ctx.fillStyle = ctx.canvas.manager.get_pattern( 'left_strand_inv' ); } + ctx.fillRect(f_start, y_center + 1, f_end - f_start, thick_height); } - else { // No strand. - ctx.fillStyle = block_color; - } - ctx.fillRect(f_start, y_center, f_end - f_start, thick_height); } else { // // There are feature blocks and mode is either Squish or Pack. @@ -4279,38 +4487,51 @@ // needed. This ensures that whole feature, regardless of whether it starts with // a block, is visible. // - - // Draw whole feature as connector/intron. + + // Compute y axis center position and height var cur_y_center, cur_height; if (mode === "Squish" || mode === "Dense") { - ctx.fillStyle = CONNECTOR_COLOR; cur_y_center = y_center + Math.floor(SQUISH_FEATURE_HEIGHT/2) + 1; cur_height = 1; } else { // mode === "Pack" if (feature_strand) { - var cur_y_center = y_center; - var cur_height = thick_height; - if (feature_strand === "+") { - ctx.fillStyle = ctx.canvas.manager.get_pattern( 'right_strand' ); - } else if (feature_strand === "-") { - ctx.fillStyle = ctx.canvas.manager.get_pattern( 'left_strand' ); - } + cur_y_center = y_center; + cur_height = thick_height; } else { - ctx.fillStyle = CONNECTOR_COLOR; cur_y_center += (SQUISH_FEATURE_HEIGHT/2) + 1; cur_height = 1; } } - ctx.fillRect(f_start, cur_y_center, f_end - f_start, cur_height); + + // Draw whole feature as connector/intron. + if ( this.draw_background_connector ) { + if (mode === "Squish" || mode === "Dense") { + ctx.fillStyle = CONNECTOR_COLOR; + } + else { // mode === "Pack" + if (feature_strand) { + if (feature_strand === "+") { + ctx.fillStyle = ctx.canvas.manager.get_pattern( 'right_strand' ); + } else if (feature_strand === "-") { + ctx.fillStyle = ctx.canvas.manager.get_pattern( 'left_strand' ); + } + } + else { + ctx.fillStyle = CONNECTOR_COLOR; + } + } + ctx.fillRect(f_start, cur_y_center, f_end - f_start, cur_height); + } // Draw blocks. var start_and_height; for (var k = 0, k_len = feature_blocks.length; k < k_len; k++) { var block = feature_blocks[k], block_start = Math.floor( Math.max(0, (block[0] - tile_low) * w_scale) ), - block_end = Math.ceil( Math.min(width, Math.max((block[1] - tile_low) * w_scale)) ); + block_end = Math.ceil( Math.min(width, Math.max((block[1] - tile_low) * w_scale)) ), + last_block_start, last_block_end; // Skip drawing if block not on tile. if (block_start > block_end) { continue; } @@ -4341,6 +4562,12 @@ ctx.fillRect(block_thick_start, y_center + 1, block_thick_end - block_thick_start, thick_height ); } } + // Draw individual connectors if required + if ( this.draw_individual_connectors && last_block_start ) { + this.draw_connector( ctx, last_block_start, last_block_end, block_start, block_end, y_center ); + } + last_block_start = block_start; + last_block_end = block_end; } // FIXME: Height scaling only works in Pack mode right now. @@ -4673,11 +4900,54 @@ } }); +var ArcLinkedFeaturePainter = function(data, view_start, view_end, prefs, mode, alpha_scaler, height_scaler) { + LinkedFeaturePainter.call(this, data, view_start, view_end, prefs, mode, alpha_scaler, height_scaler); + // Need to know the longest feature length for adding spacing + this.longest_feature_length = this.calculate_longest_feature_length(); + this.draw_background_connector = false; + this.draw_individual_connectors = true; +}; + +extend(ArcLinkedFeaturePainter.prototype, FeaturePainter.prototype, LinkedFeaturePainter.prototype, { + + calculate_longest_feature_length: function () { + var longest_feature_length = 0; + for (var i = 0, len = this.data.length; i < len; i++) { + var feature = this.data[i], feature_start = feature[1], feature_end = feature[2]; + longest_feature_length = Math.max( longest_feature_length, feature_end - feature_start ); + } + return longest_feature_length; + }, + + get_top_padding: function( width ) { + var view_range = this.view_end - this.view_start, + w_scale = width / view_range; + return Math.min( 128, Math.ceil( ( this.longest_feature_length / 2 ) * w_scale ) ); + }, + + draw_connector: function( ctx, block1_start, block1_end, block2_start, block2_end, y_center ) { + // Arc drawing -- from closest endpoints + var x_center = ( block1_end + block2_start ) / 2, + radius = block2_start - x_center; + // For full half circles + var angle1 = Math.PI, angle2 = 0; + if ( radius > 0 ) { + ctx.beginPath(); + ctx.arc( x_center, y_center, block2_start - x_center, Math.PI, 0 ); + ctx.stroke(); + } + } +}); + + + + exports.Scaler = Scaler; exports.SummaryTreePainter = SummaryTreePainter; exports.LinePainter = LinePainter; exports.LinkedFeaturePainter = LinkedFeaturePainter; exports.ReadPainter = ReadPainter; +exports.ArcLinkedFeaturePainter = ArcLinkedFeaturePainter; // End painters_module encapsulation }; @@ -4708,4 +4978,4 @@ for ( key in modules.trackster ) { target[key] = modules.trackster[key]; } -})(window); \ No newline at end of file +})(window); diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca templates/admin/select_tool_panel_section.mako --- a/templates/admin/select_tool_panel_section.mako +++ b/templates/admin/select_tool_panel_section.mako @@ -23,7 +23,7 @@ <br/><div class="toolForm"> - <div class="toolFormTitle">Load tools into tool panel</div> + <div class="toolFormTitle">Choose section to load tools into tool panel</div><div class="toolFormBody"><form name="select_tool_panel_section" id="select_tool_panel_section" action="${h.url_for( controller='admin', action='install_tool_shed_repository', tool_shed_url=tool_shed_url, repo_info_dict=repo_info_dict )}" method="post" > %if shed_tool_conf_select_field: @@ -40,10 +40,17 @@ <input type="hidden" name="shed_tool_conf" value="${shed_tool_conf}"/> %endif <div class="form-row"> - <label>Tool panel section:</label> + <label>Add new tool panel section:</label> + <input name="new_tool_panel_section" type="textfield" value="${new_tool_panel_section}" size="40"/> + <div class="toolParamHelp" style="clear: both;"> + Add a new tool panel section or choose an existing section in your tool panel below to contain the installed tools. + </div> + </div> + <div class="form-row"> + <label>Select existing tool panel section:</label> ${tool_panel_section_select_field.get_html()} <div class="toolParamHelp" style="clear: both;"> - Choose the section in your tool panel to contain the installed tools. + Choose an existing section in your tool panel to contain the installed tools. </div></div><div class="form-row"> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca templates/admin/tool_shed_repository/browse_repository.mako --- a/templates/admin/tool_shed_repository/browse_repository.mako +++ b/templates/admin/tool_shed_repository/browse_repository.mako @@ -103,7 +103,7 @@ <div class="menubutton" style="float: left;" id="workflow-${index}-popup"> ${workflow_name} <div popupmenu="workflow-${index}-popup"> - <a class="action-button" href="${h.url_for( controller='workflow', action='import_workflow', local_file=full_path, repository_id=trans.security.encode_id( repository.id ) )}">Import to Galaxy</a> + <a class="action-button" href="${h.url_for( controller='workflow', action='import_workflow', installed_repository_file=full_path, repository_id=trans.security.encode_id( repository.id ) )}">Import to Galaxy</a></div></div></td> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca templates/embed_base.mako --- a/templates/embed_base.mako +++ b/templates/embed_base.mako @@ -44,7 +44,7 @@ <div style="float: left"><a class="display_in_embed icon-button toggle-expand tooltip" item_id="${trans.security.encode_id( item.id )}" item_class="$item.__class__.__name__" href="${display_href}" title="Show ${item_display_name} content"></a> - <a class="toggle-contract icon-button tooltip" href="${display_href}" title="Hide ${item_display_name} content"></a> + <a class="toggle icon-button tooltip" href="${display_href}" title="Hide ${item_display_name} content"></a></div><div style="float: right;"> ${self.render_item_links( item )} diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca templates/library/common/import_datasets_to_histories.mako --- a/templates/library/common/import_datasets_to_histories.mako +++ b/templates/library/common/import_datasets_to_histories.mako @@ -49,12 +49,12 @@ <div class="toolFormTitle">Destination Histories:</div><div class="toolFormBody"><div class="form-row" id="single-destination"> - <select id="single-dest-select" name="target_history_ids"> + <select id="single-dest-select" name="target_history_id"> %for i, target_history in enumerate( target_histories ): <% encoded_id = trans.security.encode_id( target_history.id ) - if encoded_id == selected_history_id: - selected_text = " selected" + if encoded_id == target_history_id: + selected_text = " selected='selected'" else: selected_text = "" if target_history == current_history: diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca templates/page/display.mako --- a/templates/page/display.mako +++ b/templates/page/display.mako @@ -26,7 +26,7 @@ container.find(".summary-content").hide("fast"); container.find(".item-content").html(item_content).show("fast"); container.find(".toggle-expand").hide(); - container.find(".toggle-contract").show(); + container.find(".toggle").show(); // Init needed for history items. init_history_items( container.find("div.historyItemWrapper"), "noinit", "nochanges" ); @@ -43,7 +43,7 @@ container.find(".summary-content").hide("fast"); container.find(".item-content").show("fast"); container.find(".toggle-expand").hide(); - container.find(".toggle-contract").show(); + container.find(".toggle").show(); } }; @@ -51,7 +51,7 @@ var hide_embedded_item = function() { container.find(".item-content").hide("fast"); container.find(".summary-content").show("fast"); - container.find(".toggle-contract").hide(); + container.find(".toggle").hide(); container.find(".toggle-expand").show(); }; @@ -63,7 +63,7 @@ }); // Setup toggle contract. - var toggle_contract = $(this).find('.toggle-contract'); + var toggle_contract = $(this).find('.toggle'); toggle_contract.click( function() { hide_embedded_item(); return false; @@ -89,7 +89,7 @@ ${parent.stylesheets()} ${h.css( "base", "history", "autocomplete_tagging" )} <style type="text/css"> - .toggle-contract { display: none; } + .toggle { display: none; } .embedded-item h4 { margin: 0px; } diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca templates/root/history.mako --- a/templates/root/history.mako +++ b/templates/root/history.mako @@ -432,7 +432,7 @@ <div id="top-links" class="historyLinks"><a title="${_('refresh')}" class="icon-button arrow-circle tooltip" href="${h.url_for('history', show_deleted=show_deleted)}"></a> - <a title='${_('collapse all')}' class='icon-button toggle tooltip' href='#' style="display: none;"></a> + <a title='${_('collapse all')}' class='icon-button toggle tooltip' href='#' style="display: none"></a> %if trans.get_user(): <div style="width: 40px; float: right; white-space: nowrap;"> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca templates/tracks/browser.mako --- a/templates/tracks/browser.mako +++ b/templates/tracks/browser.mako @@ -42,7 +42,7 @@ <script type='text/javascript' src="${h.url_for('/static/scripts/excanvas.js')}"></script><![endif]--> -${h.js( "galaxy.base", "galaxy.panels", "json2", "jquery", "jstorage", "jquery.event.drag", "jquery.mousewheel", "jquery.autocomplete", "trackster", "trackster_ui", "jquery.ui.sortable.slider", "farbtastic", "jquery.tipsy" )} +${h.js( "galaxy.base", "galaxy.panels", "json2", "jquery", "jstorage", "jquery.event.drag", "jquery.event.hover","jquery.mousewheel", "jquery.autocomplete", "trackster", "trackster_ui", "jquery.ui.sortable.slider", "farbtastic", "jquery.tipsy" )} <script type="text/javascript"> // @@ -110,6 +110,52 @@ } }); }; + + /** + * Use a popup grid to bookmarks from a dataset. + */ + var add_bookmarks = function() { + show_modal( "Select dataset for new bookmarks", "progress" ); + $.ajax({ + url: "${h.url_for( action='list_histories' )}", + data: { "f-dbkey": view.dbkey }, + error: function() { alert( "Grid failed" ); }, + success: function(table_html) { + show_modal( + "Select dataset for new bookmarks", + table_html, { + "Cancel": function() { + hide_modal(); + }, + "Insert": function() { + // Just use the first selected + $('input[name=id]:checked,input[name=ldda_ids]:checked').first().each(function(){ + var data, id = $(this).val(); + if ($(this).attr("name") === "id") { + data = { hda_id: id }; + } else { + data = { ldda_id: id}; + } + + $.ajax({ + url: "${h.url_for( action='bookmarks_from_dataset' )}", + data: data, + dataType: "json", + }).then( function(data) { + for( i = 0; i < data.data.length; i++ ) { + var row = data.data[i]; + console.log( row[0], row[1] ); + add_bookmark( row[0], row[1] ); + } + }); + }); + hide_modal(); + } + } + ); + } + }); + }; $(function() { // Manual tipsy config because default gravity is S and cannot be changed. @@ -240,7 +286,13 @@ annotation = "Bookmark description"; return add_bookmark(position, annotation); }); - + + // make_popupmenu( $("#bookmarks-more-button"), { + // "Add from BED dataset": function() { + // add_bookmarks(); + // } + // }); + init_keyboard_nav(view); }; @@ -271,14 +323,15 @@ <div class="unified-panel-header" unselectable="on"><div class="unified-panel-header-inner"> + <div style="float: right"> + <a id="add-bookmark-button" class='icon-button menu-button plus-button' href="javascript:void(0);" title="Add bookmark"></a> + ## <a id="bookmarks-more-button" class='icon-button menu-button gear popup' href="javascript:void(0);" title="More actions"></a> + </div> Bookmarks </div></div><div class="unified-panel-body" style="overflow: auto;"><div id="bookmarks-container"></div> - <div> - <a class="icon-button import" style="margin-left: .5em; width: 100%" original-title="Add Bookmark" id="add-bookmark-button" href="javascript:void(0);">Add Bookmark</a> - </div></div></%def> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca templates/webapps/community/repository/browse_repository.mako --- a/templates/webapps/community/repository/browse_repository.mako +++ b/templates/webapps/community/repository/browse_repository.mako @@ -97,7 +97,7 @@ %if can_browse_contents: <div class="toolForm"> - <div class="toolFormTitle">Browse ${repository.name}</div> + <div class="toolFormTitle">Browse ${repository.name} revision ${repository.tip} (repository tip)</div> %if can_download: <div class="form-row"><label>Clone this repository:</label> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca templates/webapps/community/repository/common.mako --- a/templates/webapps/community/repository/common.mako +++ b/templates/webapps/community/repository/common.mako @@ -83,7 +83,7 @@ hg clone <a href="${clone_str}">${clone_str}</a></%def> -<%def name="render_repository_tools_and_workflows( repository_metadata_id, metadata, can_set_metadata=False, webapp='community' )"> +<%def name="render_repository_items( repository_metadata_id, metadata, can_set_metadata=False, webapp='community' )"><% from galaxy.webapps.community.controllers.common import encode, decode %> %if metadata or can_set_metadata: <p/> @@ -195,6 +195,45 @@ </div><div style="clear: both"></div> %endif + %if 'datatypes' in metadata: + <div class="form-row"> + <table width="100%"> + <tr bgcolor="#D8D8D8" width="100%"> + <td><b>Data types</b></td> + </tr> + </table> + </div> + <div style="clear: both"></div> + <div class="form-row"> + <% datatypes_dicts = metadata[ 'datatypes' ] %> + <table class="grid"> + <tr> + <td><b>extension</b></td> + <td><b>dtype</b></td> + <td><b>mimetype</b></td> + </tr> + %for datatypes_dict in datatypes_dicts: + <% + extension = datatypes_dict[ 'extension' ] + dtype = datatypes_dict[ 'dtype' ] + mimetype = datatypes_dict[ 'mimetype' ] + %> + <tr> + <td>${extension}</td> + <td>${dtype}</td> + <td> + %if mimetype: + ${mimetype} + %else: + + %endif + </td> + </tr> + %endfor + </table> + </div> + <div style="clear: both"></div> + %endif %endif %if can_set_metadata: <form name="set_metadata" action="${h.url_for( controller='repository', action='set_metadata', id=trans.security.encode_id( repository.id ), ctx_str=changeset_revision )}" method="post"> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca templates/webapps/community/repository/contact_owner.mako --- a/templates/webapps/community/repository/contact_owner.mako +++ b/templates/webapps/community/repository/contact_owner.mako @@ -13,9 +13,9 @@ can_manage = is_admin or repository.user == trans.user can_view_change_log = not is_new if can_push: - browse_label = 'Browse or delete repository files' + browse_label = 'Browse or delete repository tip files' else: - browse_label = 'Browse repository files' + browse_label = 'Browse repository tip files' %><%! diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca templates/webapps/community/repository/manage_repository.mako --- a/templates/webapps/community/repository/manage_repository.mako +++ b/templates/webapps/community/repository/manage_repository.mako @@ -16,9 +16,9 @@ can_rate = not is_new and trans.user and repository.user != trans.user can_view_change_log = not is_new if can_push: - browse_label = 'Browse or delete repository files' + browse_label = 'Browse or delete repository tip files' else: - browse_label = 'Browse repository files' + browse_label = 'Browse repository tip files' can_set_malicious = metadata and can_set_metadata and is_admin and changeset_revision == repository.tip %> @@ -184,7 +184,7 @@ </form></div></div> -${render_repository_tools_and_workflows( repository_metadata_id, metadata, can_set_metadata=True )} +${render_repository_items( repository_metadata_id, metadata, can_set_metadata=True )} <p/><div class="toolForm"><div class="toolFormTitle">Manage categories</div> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca templates/webapps/community/repository/preview_tools_in_changeset.mako --- a/templates/webapps/community/repository/preview_tools_in_changeset.mako +++ b/templates/webapps/community/repository/preview_tools_in_changeset.mako @@ -13,9 +13,9 @@ can_browse_contents = not is_new can_view_change_log = not is_new if can_push: - browse_label = 'Browse or delete repository files' + browse_label = 'Browse or delete repository tip files' else: - browse_label = 'Browse repository files' + browse_label = 'Browse repository tip files' %><%! @@ -104,4 +104,4 @@ </div></div><p/> -${render_repository_tools_and_workflows( repository_metadata_id, metadata, webapp=webapp )} +${render_repository_items( repository_metadata_id, metadata, webapp=webapp )} diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca templates/webapps/community/repository/rate_repository.mako --- a/templates/webapps/community/repository/rate_repository.mako +++ b/templates/webapps/community/repository/rate_repository.mako @@ -16,9 +16,9 @@ can_manage = is_admin or repository.user == trans.user can_view_change_log = not is_new if can_push: - browse_label = 'Browse or delete repository files' + browse_label = 'Browse or delete repository tip files' else: - browse_label = 'Browse repository files' + browse_label = 'Browse repository tip files' %><%! diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca templates/webapps/community/repository/tool_form.mako --- a/templates/webapps/community/repository/tool_form.mako +++ b/templates/webapps/community/repository/tool_form.mako @@ -18,9 +18,9 @@ can_manage = is_admin or repository.user == trans.user can_view_change_log = not is_new if can_push: - browse_label = 'Browse or delete repository files' + browse_label = 'Browse or delete repository tip files' else: - browse_label = 'Browse repository files' + browse_label = 'Browse repository tip files' %><html> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca templates/webapps/community/repository/upload.mako --- a/templates/webapps/community/repository/upload.mako +++ b/templates/webapps/community/repository/upload.mako @@ -64,7 +64,13 @@ <div class="toolForm"><div class="toolFormTitle">Upload a single file or a tarball</div><div class="toolFormBody"> - ## TODO: nginx + <div class="form-row"> + <div class="warningmessage"> + Uploading may take a while, depending upon the size of the file. Wait until a message is displayed in your + browser after clicking the <b>Upload</b> button below. + </div> + <div style="clear: both"></div> + </div><form id="upload_form" name="upload_form" action="${h.url_for( controller='upload', action='upload', repository_id=trans.security.encode_id( repository.id ) )}" enctype="multipart/form-data" method="post"><div class="form-row"><label>File:</label> @@ -73,7 +79,16 @@ </div><div style="clear: both"></div></div> - + <div class="form-row"> + <label>Url:</label> + <div class="form-row-input"> + <input name="url" type="textfield" value="${url}" size="40"/> + </div> + <div class="toolParamHelp" style="clear: both;"> + Enter a URL to upload your files via http. + </div> + <div style="clear: both"></div> + </div><div class="form-row"><% if uncompress_file: diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca templates/webapps/community/repository/view_changelog.mako --- a/templates/webapps/community/repository/view_changelog.mako +++ b/templates/webapps/community/repository/view_changelog.mako @@ -15,9 +15,9 @@ can_upload = can_push can_download = not is_new and ( not is_malicious or can_push ) if can_push: - browse_label = 'Browse or delete repository files' + browse_label = 'Browse or delete repository tip files' else: - browse_label = 'Browse repository files' + browse_label = 'Browse repository tip files' %><%! diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca templates/webapps/community/repository/view_changeset.mako --- a/templates/webapps/community/repository/view_changeset.mako +++ b/templates/webapps/community/repository/view_changeset.mako @@ -16,9 +16,9 @@ can_upload = can_push can_download = not is_new and ( not is_malicious or can_push ) if can_push: - browse_label = 'Browse or delete repository files' + browse_label = 'Browse or delete repository tip files' else: - browse_label = 'Browse repository files' + browse_label = 'Browse repository tip files' %><%! diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca templates/webapps/community/repository/view_repository.mako --- a/templates/webapps/community/repository/view_repository.mako +++ b/templates/webapps/community/repository/view_repository.mako @@ -14,9 +14,9 @@ can_browse_contents = webapp == 'community' and not is_new can_view_change_log = webapp == 'community' and not is_new if can_push: - browse_label = 'Browse or delete repository files' + browse_label = 'Browse or delete repository tip files' else: - browse_label = 'Browse repository files' + browse_label = 'Browse repository tip files' %><%! @@ -186,7 +186,7 @@ %endif </div></div> -${render_repository_tools_and_workflows( repository_metadata_id, metadata, webapp=webapp )} +${render_repository_items( repository_metadata_id, metadata, webapp=webapp )} %if repository.categories: <p/><div class="toolForm"> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca templates/webapps/community/repository/view_tool_metadata.mako --- a/templates/webapps/community/repository/view_tool_metadata.mako +++ b/templates/webapps/community/repository/view_tool_metadata.mako @@ -17,9 +17,9 @@ can_manage = is_admin or repository.user == trans.user can_view_change_log = webapp == 'community' and not is_new if can_push: - browse_label = 'Browse or delete repository files' + browse_label = 'Browse or delete repository tip files' else: - browse_label = 'Browse repository files' + browse_label = 'Browse repository tip files' %><%! diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca templates/webapps/community/repository/view_workflow.mako --- a/templates/webapps/community/repository/view_workflow.mako +++ b/templates/webapps/community/repository/view_workflow.mako @@ -20,9 +20,9 @@ can_rate = in_tool_shed and not is_new and trans.user and repository.user != trans.user can_view_change_log = in_tool_shed and not is_new if can_push: - browse_label = 'Browse or delete repository files' + browse_label = 'Browse or delete repository tip files' else: - browse_label = 'Browse repository files' + browse_label = 'Browse repository tip files' %><%! diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca templates/workflow/editor.mako --- a/templates/workflow/editor.mako +++ b/templates/workflow/editor.mako @@ -213,7 +213,7 @@ show_workflow_parameters(); }, beforeSubmit: function( data ) { - show_modal( "Loading workflow", "progress" ); + show_message( "Loading workflow", "progress" ); } }); } @@ -650,7 +650,7 @@ }; var save_current_workflow = function ( eventObj, success_callback ) { - show_modal( "Saving workflow", "progress" ); + show_message( "Saving workflow", "progress" ); workflow.check_changes_in_active_form(); if (!workflow.has_changes) { hide_modal(); diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca test-data/fastqc_report.html --- a/test-data/fastqc_report.html +++ b/test-data/fastqc_report.html @@ -1,117 +1,224 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Strict//EN"><html> -<head><title>1000gsample.fastq FastQC Report</title> +<head><title>dataset_1.dat FastQC Report</title><style type="text/css"> - body { - font-family: sans-serif; - color: #000000; - background-color: #FFFFFF; - border: 0; - margin: 0; - padding: 0; - } + @media screen { + div.summary { + width: 18em; + position:fixed; + top: 3em; + margin:1em 0 0 1em; + } + + div.main { + display:block; + position:absolute; + overflow:auto; + height:auto; + width:auto; + top:4.5em; + bottom:2.3em; + left:18em; + right:0; + border-left: 1px solid #CCC; + padding:0 0 0 1em; + background-color: white; + z-index:1; + } + + div.header { + background-color: #EEE; + border:0; + margin:0; + padding: 0.5em; + font-size: 200%; + font-weight: bold; + position:fixed; + width:100%; + top:0; + left:0; + z-index:2; + } + + div.footer { + background-color: #EEE; + border:0; + margin:0; + padding:0.5em; + height: 1.3em; + overflow:hidden; + font-size: 100%; + font-weight: bold; + position:fixed; + bottom:0; + width:100%; + z-index:2; + } + + img.indented { + margin-left: 3em; + } + } + + @media print { + img { + max-width:100% !important; + page-break-inside: avoid; + } + h2, h3 { + page-break-after: avoid; + } + div.header { + background-color: #FFF; + } + + } + + body { + font-family: sans-serif; + color: #000; + background-color: #FFF; + border: 0; + margin: 0; + padding: 0; + } + + div.header { + border:0; + margin:0; + padding: 0.5em; + font-size: 200%; + font-weight: bold; + width:100%; + } + + #header_title { + display:inline-block; + float:left; + clear:left; + } + #header_filename { + display:inline-block; + float:right; + clear:right; + font-size: 50%; + margin-right:2em; + text-align: right; + } + + div.header h3 { + font-size: 50%; + margin-bottom: 0; + } + + div.summary ul { + padding-left:0; + list-style-type:none; + } + + div.summary ul li img { + margin-bottom:-0.5em; + margin-top:0.5em; + } + + div.main { + background-color: white; + } - div.header { - background-color: #EEEEEE; - border:0; - margin:0; - padding: 0.5em; - font-size: 200%; - font-weight: bold; - } + div.module { + padding-bottom:1.5em; + padding-top:1.5em; + } + + div.footer { + background-color: #EEE; + border:0; + margin:0; + padding: 0.5em; + font-size: 100%; + font-weight: bold; + width:100%; + } - div.footer { - background-color: #EEEEEE; - border:0; - margin:0; - padding: 0.5em; - font-size: 100%; - font-weight: bold; - } - div.main { - margin-left: 2em; - margin-right: 2em; - } + a { + color: #000080; + } + + a:hover { + color: #800000; + } - div.module { - padding-bottom:1.5em; - padding-top:1.5em; - } + h2 { + color: #800000; + padding-bottom: 0; + margin-bottom: 0; + clear:left; + } - a { - color: #000080; - } + table { + margin-left: 3em; + text-align: center; + } + + th { + text-align: center; + background-color: #000080; + color: #FFF; + padding: 0.4em; + } + + td { + font-family: monospace; + text-align: left; + background-color: #EEE; + color: #000; + padding: 0.4em; + } - a:hover { - color: #800000; - } - - h2 { - color: #800000; - padding-bottom: 0; - margin-bottom: 0; - } + img { + padding-top: 0; + margin-top: 0; + border-top: 0; + } - table { - margin-left: 3em; - text-align: center; - } - - th { - text-align: center; - background-color: #000080; - color: #FFFFFF; - padding: 0.4em; - } - - td { - font-family: monospace; - text-align: left; - background-color: #EEEEEE; - color: #000000; - padding: 0.4em; - } - - img { - padding-top: 0; - margin-top: 0; - border-top: 0; - } - - img.indented { - margin-left: 3em; - } - - p { - padding-top: 0; - margin-top: 0; - } + + p { + padding-top: 0; + margin-top: 0; + } + </style></head><body> -<div class="header"><img src="Icons/fastqc_icon.png">FastQC Report</div> +<div class="header"> +<div id="header_title"><img src="fastqc_icon.png" alt="FastQC">FastQC Report</div> +<div id="header_filename"> +Wed 16 Nov 2011<br /> +dataset_1.dat +</div> +</div> +<div class="summary"> +<h2>Summary</h2> +<ul> +<li><img src="tick.png" alt="[PASS]"><a href="#M0">Basic Statistics</a></li> +<li><img src="warning.png" alt="[WARNING]"><a href="#M1">Per base sequence quality</a></li> +<li><img src="warning.png" alt="[WARNING]"><a href="#M2">Per sequence quality scores</a></li> +<li><img src="warning.png" alt="[WARNING]"><a href="#M3">Per base sequence content</a></li> +<li><img src="tick.png" alt="[PASS]"><a href="#M4">Per base GC content</a></li> +<li><img src="warning.png" alt="[WARNING]"><a href="#M5">Per sequence GC content</a></li> +<li><img src="tick.png" alt="[PASS]"><a href="#M6">Per base N content</a></li> +<li><img src="tick.png" alt="[PASS]"><a href="#M7">Sequence Length Distribution</a></li> +<li><img src="tick.png" alt="[PASS]"><a href="#M8">Sequence Duplication Levels</a></li> +<li><img src="warning.png" alt="[WARNING]"><a href="#M9">Overrepresented sequences</a></li> +<li><img src="error.png" alt="[FAIL]"><a href="#M10">Kmer Content</a></li> +</ul> +</div><div class="main"> -<h3>Wed 27 Apr 2011</h3> -<h3>1000gsample.fastq</h3> -<h2 id="summary">Summary</h2> -<ul> -<li><img src="Icons/tick.png" alt="[PASS]"><a href="#M0">Basic Statistics</a></li> -<li><img src="Icons/warning.png" alt="[WARNING]"><a href="#M1">Per base sequence quality</a></li> -<li><img src="Icons/warning.png" alt="[WARNING]"><a href="#M2">Per sequence quality scores</a></li> -<li><img src="Icons/tick.png" alt="[PASS]"><a href="#M3">Per base sequence content</a></li> -<li><img src="Icons/tick.png" alt="[PASS]"><a href="#M4">Per base GC content</a></li> -<li><img src="Icons/warning.png" alt="[WARNING]"><a href="#M5">Per sequence GC content</a></li> -<li><img src="Icons/tick.png" alt="[PASS]"><a href="#M6">Per base N content</a></li> -<li><img src="Icons/tick.png" alt="[PASS]"><a href="#M7">Sequence Length Distribution</a></li> -<li><img src="Icons/tick.png" alt="[PASS]"><a href="#M8">Sequence Duplication Levels</a></li> -<li><img src="Icons/warning.png" alt="[WARNING]"><a href="#M9">Overrepresented sequences</a></li> -<li><img src="Icons/error.png" alt="[FAIL]"><a href="#M10">Kmer Content</a></li> -</ul> -<div class="module"><h2 id="M0"><img src="Icons/tick.png" alt="[FAIL]"> Basic Statistics</h2> +<div class="module"><h2 id="M0"><img src="tick.png" alt="[OK]"> Basic Statistics</h2><table><tr><th>Measure</th> @@ -119,7 +226,7 @@ </tr><tr><td>Filename</td> -<td>1000gsample.fastq</td> +<td>dataset_1.dat</td></tr><tr><td>File type</td> @@ -134,6 +241,10 @@ <td>5000</td></tr><tr> +<td>Filtered Sequences</td> +<td>0</td> +</tr> +<tr><td>Sequence length</td><td>54</td></tr> @@ -142,32 +253,32 @@ <td>43</td></tr></table> -<p><a href="#summary">Back to summary</a></div> -<div class="module"><h2 id="M1"><img src="Icons/warning.png" alt="[FAIL]"> Per base sequence quality</h2> -<p><img class="indented" src="Images/per_base_quality.png"></p> -<p><a href="#summary">Back to summary</a></div> -<div class="module"><h2 id="M2"><img src="Icons/warning.png" alt="[FAIL]"> Per sequence quality scores</h2> -<p><img class="indented" src="Images/per_sequence_quality.png"></p> -<p><a href="#summary">Back to summary</a></div> -<div class="module"><h2 id="M3"><img src="Icons/tick.png" alt="[FAIL]"> Per base sequence content</h2> -<p><img class="indented" src="Images/per_base_sequence_content.png"></p> -<p><a href="#summary">Back to summary</a></div> -<div class="module"><h2 id="M4"><img src="Icons/tick.png" alt="[FAIL]"> Per base GC content</h2> -<p><img class="indented" src="Images/per_base_gc_content.png"></p> -<p><a href="#summary">Back to summary</a></div> -<div class="module"><h2 id="M5"><img src="Icons/warning.png" alt="[FAIL]"> Per sequence GC content</h2> -<p><img class="indented" src="Images/per_sequence_gc_content.png"></p> -<p><a href="#summary">Back to summary</a></div> -<div class="module"><h2 id="M6"><img src="Icons/tick.png" alt="[FAIL]"> Per base N content</h2> -<p><img class="indented" src="Images/per_base_n_content.png"></p> -<p><a href="#summary">Back to summary</a></div> -<div class="module"><h2 id="M7"><img src="Icons/tick.png" alt="[FAIL]"> Sequence Length Distribution</h2> -<p><img class="indented" src="Images/sequence_length_distribution.png"></p> -<p><a href="#summary">Back to summary</a></div> -<div class="module"><h2 id="M8"><img src="Icons/tick.png" alt="[FAIL]"> Sequence Duplication Levels</h2> -<p><img class="indented" src="Images/duplication_levels.png"></p> -<p><a href="#summary">Back to summary</a></div> -<div class="module"><h2 id="M9"><img src="Icons/warning.png" alt="[FAIL]"> Overrepresented sequences</h2> +</div> +<div class="module"><h2 id="M1"><img src="warning.png" alt="[WARN]"> Per base sequence quality</h2> +<p><img class="indented" src="per_base_quality.png" alt="Per base quality graph"></p> +</div> +<div class="module"><h2 id="M2"><img src="warning.png" alt="[WARN]"> Per sequence quality scores</h2> +<p><img class="indented" src="per_sequence_quality.png" alt="Per Sequence quality graph"></p> +</div> +<div class="module"><h2 id="M3"><img src="warning.png" alt="[WARN]"> Per base sequence content</h2> +<p><img class="indented" src="per_base_sequence_content.png" alt="Per base sequence content"></p> +</div> +<div class="module"><h2 id="M4"><img src="tick.png" alt="[OK]"> Per base GC content</h2> +<p><img class="indented" src="per_base_gc_content.png" alt="Per base GC content graph"></p> +</div> +<div class="module"><h2 id="M5"><img src="warning.png" alt="[WARN]"> Per sequence GC content</h2> +<p><img class="indented" src="per_sequence_gc_content.png" alt="Per sequence GC content graph"></p> +</div> +<div class="module"><h2 id="M6"><img src="tick.png" alt="[OK]"> Per base N content</h2> +<p><img class="indented" src="per_base_n_content.png" alt="N content graph"></p> +</div> +<div class="module"><h2 id="M7"><img src="tick.png" alt="[OK]"> Sequence Length Distribution</h2> +<p><img class="indented" src="sequence_length_distribution.png" alt="Sequence length distribution"></p> +</div> +<div class="module"><h2 id="M8"><img src="tick.png" alt="[OK]"> Sequence Duplication Levels</h2> +<p><img class="indented" src="duplication_levels.png" alt="Duplication level graph"></p> +</div> +<div class="module"><h2 id="M9"><img src="warning.png" alt="[WARN]"> Overrepresented sequences</h2><table><tr><th>Sequence</th> @@ -188,9 +299,9 @@ <td>Illumina Paired End PCR Primer 2 (100% over 35bp)</td></tr></table> -<p><a href="#summary">Back to summary</a></div> -<div class="module"><h2 id="M10"><img src="Icons/error.png" alt="[FAIL]"> Kmer Content</h2> -<p><img class="indented" src="Images/kmer_profiles.png"></p> +</div> +<div class="module"><h2 id="M10"><img src="error.png" alt="[FAIL]"> Kmer Content</h2> +<p><img class="indented" src="kmer_profiles.png" alt="Kmer graph"></p><table><tr><th>Sequence</th> @@ -201,1132 +312,1498 @@ </tr><tr><td>CCCCC</td> -<td>1110</td> -<td>9.557241</td> -<td>23.193876</td> -<td>44</td> +<td>1180</td> +<td>9.957459</td> +<td>29.638031</td> +<td>50</td></tr><tr><td>AAAAA</td> -<td>2130</td> -<td>4.1300144</td> -<td>5.698024</td> -<td>7</td> +<td>2175</td> +<td>4.133217</td> +<td>7.129659</td> +<td>47</td></tr><tr><td>CTCCC</td> -<td>530</td> -<td>3.5749238</td> +<td>555</td> +<td>3.668942</td><td>11.56272</td><td>11</td></tr><tr><td>CCTCC</td> -<td>510</td> -<td>3.440021</td> +<td>525</td> +<td>3.4706206</td><td>11.56272</td><td>14</td></tr><tr><td>CTGGG</td><td>465</td> -<td>3.1575248</td> -<td>8.314476</td> -<td>45</td> +<td>3.0945942</td> +<td>8.331139</td> +<td>39</td> +</tr> +<tr> +<td>GGGGG</td> +<td>350</td> +<td>2.9865708</td> +<td>12.818572</td> +<td>41</td></tr><tr><td>TGGAA</td> -<td>785</td> -<td>2.929684</td> +<td>800</td> +<td>2.9261596</td><td>6.397646</td><td>17</td></tr><tr> -<td>GGGGG</td> -<td>335</td> -<td>2.9167063</td> -<td>10.660779</td> -<td>6</td> +<td>CCCAG</td> +<td>455</td> +<td>2.855999</td> +<td>9.429343</td> +<td>40</td></tr><tr><td>GAATG</td><td>775</td> -<td>2.8923633</td> +<td>2.8347175</td><td>10.053445</td><td>20</td></tr><tr> -<td>CCCAG</td> -<td>450</td> -<td>2.8820548</td> -<td>7.8420706</td> -<td>22</td> +<td>GTGTG</td> +<td>530</td> +<td>2.763172</td> +<td>7.8240557</td> +<td>33</td></tr><tr> -<td>GTGTG</td> -<td>520</td> -<td>2.7661672</td> -<td>6.513526</td> -<td>23</td> +<td>GGGAG</td> +<td>435</td> +<td>2.7487729</td> +<td>6.3220544</td> +<td>43</td></tr><tr><td>TGTGT</td> -<td>660</td> -<td>2.744307</td> +<td>670</td> +<td>2.7303638</td><td>6.109576</td><td>27</td></tr><tr> -<td>GGGAG</td> -<td>425</td> -<td>2.7401958</td> -<td>6.315732</td> -<td>6</td> -</tr> -<tr><td>ATGGA</td> -<td>730</td> -<td>2.7244196</td> +<td>735</td> +<td>2.688409</td><td>6.397646</td><td>20</td></tr><tr> -<td>GCTGG</td> -<td>395</td> -<td>2.6821985</td> -<td>6.651581</td> -<td>16</td> -</tr> -<tr> -<td>GGAGG</td> -<td>410</td> -<td>2.643483</td> -<td>7.894665</td> -<td>7</td> -</tr> -<tr><td>GGAAT</td> -<td>700</td> -<td>2.612457</td> +<td>730</td> +<td>2.6701207</td><td>7.3115954</td><td>19</td></tr><tr> +<td>GCTGG</td> +<td>400</td> +<td>2.6620166</td> +<td>8.322799</td> +<td>31</td> +</tr> +<tr> +<td>GGAGG</td> +<td>420</td> +<td>2.6539874</td> +<td>7.9104857</td> +<td>40</td> +</tr> +<tr><td>GCAGG</td> -<td>400</td> -<td>2.5732677</td> +<td>405</td> +<td>2.5535064</td><td>14.17877</td><td>16</td></tr><tr><td>CCTGG</td> -<td>370</td> -<td>2.5068476</td> +<td>375</td> +<td>2.4900866</td><td>6.6367774</td><td>7</td></tr><tr><td>CAGCC</td> -<td>380</td> -<td>2.4337354</td> -<td>6.273657</td> -<td>4</td> +<td>390</td> +<td>2.4479992</td> +<td>6.279937</td> +<td>38</td> +</tr> +<tr> +<td>GGCTG</td> +<td>365</td> +<td>2.4290898</td> +<td>9.97737</td> +<td>24</td></tr><tr><td>TGGGA</td> -<td>480</td> -<td>2.419065</td> +<td>490</td> +<td>2.4202447</td><td>7.40506</td><td>20</td></tr><tr> +<td>CCAGC</td> +<td>385</td> +<td>2.4166145</td> +<td>6.286229</td> +<td>41</td> +</tr> +<tr><td>AATGG</td> -<td>645</td> -<td>2.4071925</td> +<td>660</td> +<td>2.4140818</td><td>5.4836965</td><td>18</td></tr><tr> +<td>GCCTG</td> +<td>360</td> +<td>2.3904827</td> +<td>8.295971</td> +<td>5</td> +</tr> +<tr><td>GCCTC</td> -<td>355</td> -<td>2.3998654</td> -<td>6.622006</td> -<td>2</td> +<td>360</td> +<td>2.3851626</td> +<td>6.6286345</td> +<td>31</td></tr><tr><td>CCCTC</td> -<td>355</td> -<td>2.394524</td> -<td>8.259085</td> -<td>13</td> +<td>360</td> +<td>2.379854</td> +<td>8.267352</td> +<td>34</td></tr><tr> -<td>CCAGC</td> -<td>370</td> -<td>2.3696895</td> -<td>6.2736564</td> -<td>14</td> +<td>CTGTG</td> +<td>450</td> +<td>2.3408678</td> +<td>9.09864</td> +<td>44</td></tr><tr><td>GGAAG</td> -<td>495</td> -<td>2.3634295</td> +<td>500</td> +<td>2.3397229</td><td>14.031037</td><td>2</td></tr><tr> -<td>GGCTG</td> -<td>345</td> -<td>2.3426795</td> -<td>9.97737</td> -<td>24</td> +<td>CAGCA</td> +<td>500</td> +<td>2.32932</td> +<td>10.47649</td> +<td>14</td></tr><tr><td>CAGGA</td> -<td>490</td> -<td>2.3343499</td> +<td>495</td> +<td>2.3111706</td><td>13.99981</td><td>17</td></tr><tr> -<td>CCAGG</td> -<td>360</td> -<td>2.3107867</td> -<td>6.2876506</td> -<td>11</td> -</tr> -<tr> -<td>CTGTG</td> -<td>435</td> -<td>2.3088553</td> -<td>9.09864</td> -<td>44</td> -</tr> -<tr> -<td>GCCTG</td> -<td>340</td> -<td>2.3035896</td> -<td>8.295971</td> -<td>5</td> -</tr> -<tr><td>TCCCA</td> -<td>460</td> -<td>2.3028264</td> -<td>6.1297736</td> -<td>9</td> +<td>470</td> +<td>2.305994</td> +<td>7.370469</td> +<td>39</td></tr><tr><td>CTGCC</td> -<td>340</td> -<td>2.2984629</td> +<td>345</td> +<td>2.285781</td><td>8.277508</td><td>10</td></tr><tr> -<td>CAGCA</td> -<td>480</td> -<td>2.2816207</td> -<td>10.47649</td> -<td>14</td> +<td>GGTGG</td> +<td>340</td> +<td>2.2677608</td> +<td>5.009832</td> +<td>42</td> +</tr> +<tr> +<td>CCAGG</td> +<td>360</td> +<td>2.264732</td> +<td>6.300251</td> +<td>41</td></tr><tr><td>TTCCT</td> -<td>545</td> -<td>2.256056</td> +<td>555</td> +<td>2.2516627</td><td>7.0961456</td><td>1</td></tr><tr> +<td>TCCCC</td> +<td>335</td> +<td>2.2145865</td> +<td>8.267353</td> +<td>29</td> +</tr> +<tr> +<td>CAGGC</td> +<td>350</td> +<td>2.2018228</td> +<td>6.300251</td> +<td>42</td> +</tr> +<tr><td>CTCCT</td> -<td>415</td> -<td>2.1929073</td> +<td>425</td> +<td>2.2009897</td><td>6.4701333</td><td>15</td></tr><tr> -<td>TCCCC</td> -<td>325</td> -<td>2.1921701</td> -<td>6.6072683</td> -<td>28</td> -</tr> -<tr> -<td>CAGGC</td> -<td>335</td> -<td>2.1503155</td> -<td>6.2876506</td> -<td>14</td> +<td>GGCAG</td> +<td>340</td> +<td>2.1436844</td> +<td>6.301676</td> +<td>16</td></tr><tr><td>CCCCA</td> -<td>335</td> -<td>2.1407545</td> -<td>6.259694</td> -<td>20</td> +<td>340</td> +<td>2.129403</td> +<td>6.26596</td> +<td>31</td> +</tr> +<tr> +<td>CTCTG</td> +<td>410</td> +<td>2.1280441</td> +<td>5.1928453</td> +<td>48</td></tr><tr><td>TGGTG</td> -<td>400</td> -<td>2.127821</td> -<td>6.513526</td> -<td>9</td> +<td>405</td> +<td>2.1114805</td> +<td>6.520046</td> +<td>33</td> +</tr> +<tr> +<td>TTCCA</td> +<td>545</td> +<td>2.094778</td> +<td>6.7295837</td> +<td>33</td></tr><tr><td>CCCCT</td><td>315</td> -<td>2.1247187</td> +<td>2.0823722</td><td>6.607268</td><td>12</td></tr><tr> -<td>GGCAG</td> -<td>330</td> -<td>2.122946</td> -<td>6.301676</td> -<td>16</td> +<td>CTCAG</td> +<td>420</td> +<td>2.0652719</td> +<td>6.149596</td> +<td>46</td></tr><tr> -<td>CTCTG</td> -<td>400</td> -<td>2.1183603</td> -<td>5.187652</td> -<td>16</td> -</tr> -<tr> -<td>TTCCA</td> -<td>540</td> -<td>2.1177678</td> -<td>6.7228537</td> -<td>28</td> +<td>AGGGA</td> +<td>440</td> +<td>2.0589561</td> +<td>7.0225415</td> +<td>31</td></tr><tr><td>CAGAG</td><td>440</td> -<td>2.0961509</td> -<td>5.833255</td> -<td>28</td> +<td>2.054374</td> +<td>5.8390937</td> +<td>38</td> +</tr> +<tr> +<td>AGCAG</td> +<td>440</td> +<td>2.0543735</td> +<td>10.499857</td> +<td>15</td></tr><tr><td>CCCTG</td><td>310</td> -<td>2.095657</td> +<td>2.05389</td><td>6.622006</td><td>24</td></tr><tr> -<td>AGGGA</td> -<td>435</td> -<td>2.0769534</td> -<td>5.846266</td> -<td>1</td> -</tr> -<tr> -<td>CTCAG</td> -<td>410</td> -<td>2.0570977</td> -<td>6.143447</td> -<td>24</td> -</tr> -<tr><td>CTTCC</td> -<td>385</td> -<td>2.034384</td> +<td>390</td> +<td>2.0197318</td><td>6.4701333</td><td>17</td></tr><tr> -<td>AGCAG</td> -<td>425</td> -<td>2.0246909</td> -<td>10.499857</td> -<td>15</td> -</tr> -<tr><td>AGGAA</td> -<td>570</td> -<td>2.015381</td> +<td>580</td> +<td>2.0098667</td><td>10.390455</td><td>18</td></tr><tr> +<td>AGAGC</td> +<td>430</td> +<td>2.0076835</td> +<td>10.499858</td> +<td>5</td> +</tr> +<tr> +<td>TCTCC</td> +<td>385</td> +<td>1.9938378</td> +<td>5.181288</td> +<td>29</td> +</tr> +<tr><td>TCCTC</td> -<td>380</td> -<td>2.0079634</td> -<td>5.1761065</td> -<td>1</td> +<td>385</td> +<td>1.9938378</td> +<td>5.181288</td> +<td>48</td></tr><tr><td>TCAGC</td> -<td>400</td> -<td>2.0069244</td> +<td>405</td> +<td>1.9915122</td><td>12.286894</td><td>44</td></tr><tr> -<td>AGAGC</td> -<td>420</td> -<td>2.0008712</td> -<td>10.499858</td> -<td>5</td> +<td>TGCTG</td> +<td>380</td> +<td>1.9767327</td> +<td>6.5055346</td> +<td>47</td> +</tr> +<tr> +<td>CACCC</td> +<td>315</td> +<td>1.9728295</td> +<td>6.259694</td> +<td>9</td></tr><tr><td>TCCTG</td> -<td>375</td> -<td>1.9859626</td> +<td>380</td> +<td>1.9723336</td><td>6.4845653</td><td>8</td></tr><tr> -<td>TCTCC</td> -<td>375</td> -<td>1.9815428</td> -<td>5.1761065</td> -<td>8</td> -</tr> -<tr> -<td>CACCC</td> +<td>CAGGG</td><td>310</td> -<td>1.9809967</td> -<td>6.259694</td> -<td>9</td> -</tr> -<tr> -<td>TGTGG</td> -<td>370</td> -<td>1.9682345</td> -<td>5.210821</td> -<td>4</td> +<td>1.954536</td> +<td>6.3016763</td> +<td>21</td></tr><tr><td>GATGG</td> -<td>390</td> -<td>1.9654902</td> +<td>395</td> +<td>1.9510134</td><td>6.1708827</td><td>1</td></tr><tr><td>TGGCT</td> -<td>370</td> -<td>1.9638538</td> +<td>375</td> +<td>1.9507233</td><td>9.098641</td><td>45</td></tr><tr> -<td>TCCCT</td> -<td>370</td> -<td>1.9551222</td> -<td>5.1761065</td> -<td>37</td> -</tr> -<tr> -<td>CAGGG</td> -<td>300</td> -<td>1.9299511</td> -<td>6.3016763</td> -<td>21</td> -</tr> -<tr><td>AAGAG</td> -<td>545</td> -<td>1.9269869</td> +<td>560</td> +<td>1.9405607</td><td>9.524584</td><td>4</td></tr><tr> +<td>TGTGG</td> +<td>370</td> +<td>1.929007</td> +<td>6.5200467</td> +<td>30</td> +</tr> +<tr> +<td>CTGAG</td> +<td>390</td> +<td>1.9220302</td> +<td>6.163313</td> +<td>35</td> +</tr> +<tr> +<td>CCTGT</td> +<td>370</td> +<td>1.9204301</td> +<td>6.4845653</td> +<td>6</td> +</tr> +<tr><td>CAGAA</td> -<td>545</td> -<td>1.9226985</td> +<td>555</td> +<td>1.9189543</td><td>6.0476103</td><td>6</td></tr><tr> -<td>CTGAG</td> +<td>TCCCT</td> +<td>370</td> +<td>1.9161558</td> +<td>6.4766097</td> +<td>33</td> +</tr> +<tr> +<td>CCCAC</td> +<td>305</td> +<td>1.9101999</td> +<td>6.259694</td> +<td>4</td> +</tr> +<tr> +<td>CACCA</td> +<td>405</td> +<td>1.8825499</td> +<td>6.9757566</td> +<td>33</td> +</tr> +<tr> +<td>AAAGA</td> +<td>730</td> +<td>1.8732982</td> +<td>5.1399345</td> +<td>42</td> +</tr> +<tr> +<td>CAGTG</td><td>380</td> -<td>1.9108309</td> -<td>6.15715</td> -<td>11</td> +<td>1.8727474</td> +<td>6.163313</td> +<td>30</td> +</tr> +<tr> +<td>GAAGA</td> +<td>540</td> +<td>1.8712552</td> +<td>7.792842</td> +<td>26</td></tr><tr><td>TCTCT</td><td>460</td> -<td>1.9041945</td> +<td>1.8662432</td><td>5.068676</td><td>8</td></tr><tr> +<td>TTTCC</td> +<td>460</td> +<td>1.8662429</td> +<td>5.073749</td> +<td>38</td> +</tr> +<tr><td>GAGGC</td><td>295</td> -<td>1.897785</td> +<td>1.8599615</td><td>6.301676</td><td>22</td></tr><tr> -<td>CCCAC</td> -<td>295</td> -<td>1.885142</td> -<td>6.259694</td> -<td>4</td> +<td>TCTGT</td> +<td>455</td> +<td>1.8500755</td> +<td>5.0850673</td> +<td>49</td></tr><tr><td>CCTGC</td><td>275</td> -<td>1.8590509</td> +<td>1.8219992</td><td>9.93301</td><td>6</td></tr><tr> -<td>CCTGT</td> +<td>CCTCT</td><td>350</td> -<td>1.8535651</td> -<td>6.4845653</td> -<td>6</td> -</tr> -<tr> -<td>TTTCC</td> -<td>445</td> -<td>1.8421009</td> -<td>5.0686755</td> -<td>14</td> +<td>1.8125799</td> +<td>7.7641597</td> +<td>2</td></tr><tr><td>TGCCT</td><td>345</td> -<td>1.8270856</td> +<td>1.7906713</td><td>5.187652</td><td>12</td></tr><tr> -<td>CACAC</td> -<td>380</td> -<td>1.8022629</td> -<td>5.8073177</td> -<td>17</td> -</tr> -<tr> -<td>CCTCT</td> -<td>340</td> -<td>1.7965988</td> -<td>7.7641597</td> -<td>2</td> -</tr> -<tr><td>TTCCC</td> -<td>340</td> -<td>1.7965986</td> +<td>345</td> +<td>1.7866857</td><td>6.470133</td><td>18</td></tr><tr> -<td>GAAGA</td> -<td>500</td> -<td>1.767878</td> -<td>7.792842</td> -<td>26</td> +<td>GAGGG</td> +<td>280</td> +<td>1.769325</td> +<td>6.3283887</td> +<td>41</td> +</tr> +<tr> +<td>CACAC</td> +<td>380</td> +<td>1.7663432</td> +<td>5.813131</td> +<td>33</td> +</tr> +<tr> +<td>TCTGC</td> +<td>340</td> +<td>1.7647195</td> +<td>5.1980486</td> +<td>42</td></tr><tr><td>CTGGC</td> -<td>260</td> -<td>1.7615684</td> -<td>6.636777</td> -<td>8</td> +<td>265</td> +<td>1.7596608</td> +<td>6.6434207</td> +<td>43</td></tr><tr><td>TTCAG</td> -<td>440</td> -<td>1.7294377</td> +<td>455</td> +<td>1.7527524</td><td>9.6255</td><td>12</td></tr><tr> +<td>AGCCA</td> +<td>375</td> +<td>1.74699</td> +<td>5.8319354</td> +<td>39</td> +</tr> +<tr><td>CTCTC</td> -<td>325</td> -<td>1.717337</td> +<td>335</td> +<td>1.7348979</td><td>5.1761065</td><td>3</td></tr><tr> -<td>GTGGT</td> -<td>320</td> -<td>1.7022567</td> -<td>5.2108207</td> -<td>24</td> -</tr> -<tr><td>GGGTG</td> -<td>250</td> -<td>1.7013805</td> +<td>260</td> +<td>1.7341703</td><td>8.333022</td><td>28</td></tr><tr> -<td>TGCTT</td> -<td>410</td> -<td>1.7010024</td> -<td>5.0799813</td> -<td>4</td> +<td>TGGGG</td> +<td>260</td> +<td>1.7341703</td> +<td>8.349721</td> +<td>39</td> +</tr> +<tr> +<td>GTGGG</td> +<td>255</td> +<td>1.7008208</td> +<td>6.6730905</td> +<td>31</td> +</tr> +<tr> +<td>GGCCA</td> +<td>270</td> +<td>1.698549</td> +<td>6.293945</td> +<td>43</td> +</tr> +<tr> +<td>GCCCC</td> +<td>200</td> +<td>1.6914694</td> +<td>6.3460584</td> +<td>32</td></tr><tr><td>CTTTG</td> -<td>405</td> -<td>1.6802584</td> +<td>415</td> +<td>1.6874313</td><td>5.0799813</td><td>2</td></tr><tr> +<td>ACACA</td> +<td>485</td> +<td>1.6731915</td> +<td>5.1721287</td> +<td>14</td> +</tr> +<tr> +<td>GTGGT</td> +<td>320</td> +<td>1.6683302</td> +<td>5.216037</td> +<td>31</td> +</tr> +<tr> +<td>CTCAC</td> +<td>340</td> +<td>1.6681659</td> +<td>7.363092</td> +<td>31</td> +</tr> +<tr> +<td>TGCTT</td> +<td>410</td> +<td>1.6671008</td> +<td>5.090162</td> +<td>40</td> +</tr> +<tr> +<td>GGGGC</td> +<td>195</td> +<td>1.6602434</td> +<td>8.526694</td> +<td>40</td> +</tr> +<tr> +<td>AGTGG</td> +<td>335</td> +<td>1.654657</td> +<td>6.1708827</td> +<td>3</td> +</tr> +<tr> +<td>TTCTG</td> +<td>405</td> +<td>1.6467704</td> +<td>5.0850663</td> +<td>49</td> +</tr> +<tr><td>AGAAG</td><td>475</td> -<td>1.6794841</td> +<td>1.6460115</td><td>5.1952276</td><td>22</td></tr><tr><td>ACTCC</td> -<td>330</td> -<td>1.6520276</td> +<td>335</td> +<td>1.6436341</td><td>6.1297736</td><td>10</td></tr><tr> +<td>GGCTC</td> +<td>245</td> +<td>1.6268562</td> +<td>8.304275</td> +<td>46</td> +</tr> +<tr> +<td>TGGCA</td> +<td>330</td> +<td>1.6263331</td> +<td>8.637284</td> +<td>40</td> +</tr> +<tr> +<td>TCCTT</td> +<td>400</td> +<td>1.6228201</td> +<td>6.0946</td> +<td>40</td> +</tr> +<tr> +<td>TCTGG</td> +<td>310</td> +<td>1.612598</td> +<td>5.204428</td> +<td>43</td> +</tr> +<tr> +<td>GGGGA</td> +<td>255</td> +<td>1.6113497</td> +<td>6.3157325</td> +<td>7</td> +</tr> +<tr><td>CTGCT</td><td>310</td> -<td>1.6417291</td> +<td>1.609009</td><td>6.4845653</td><td>3</td></tr><tr> -<td>GCCCC</td> -<td>190</td> -<td>1.6395733</td> -<td>6.339712</td> -<td>37</td> +<td>CCCAA</td> +<td>345</td> +<td>1.6036536</td> +<td>5.8073177</td> +<td>10</td></tr><tr> -<td>AGTGG</td> -<td>325</td> -<td>1.6379085</td> -<td>6.1708827</td> -<td>3</td> +<td>TGGCC</td> +<td>240</td> +<td>1.5936551</td> +<td>6.6434207</td> +<td>49</td></tr><tr> -<td>TGGCA</td> -<td>325</td> -<td>1.6342632</td> -<td>6.1571493</td> -<td>16</td> -</tr> -<tr> -<td>GGCTC</td> -<td>240</td> -<td>1.626063</td> -<td>6.636776</td> -<td>25</td> -</tr> -<tr> -<td>ACACA</td> -<td>460</td> -<td>1.6192161</td> -<td>5.1721287</td> -<td>14</td> +<td>GTGCT</td> +<td>305</td> +<td>1.5865883</td> +<td>5.220104</td> +<td>50</td></tr><tr><td>GCTTT</td><td>390</td> -<td>1.6180266</td> -<td>5.0799813</td> -<td>5</td> +<td>1.5857788</td> +<td>6.1081944</td> +<td>41</td></tr><tr> -<td>TTCTG</td> -<td>390</td> -<td>1.6180266</td> -<td>5.0799813</td> -<td>3</td> +<td>CCACA</td> +<td>335</td> +<td>1.5571709</td> +<td>5.813131</td> +<td>30</td></tr><tr> -<td>TCCTT</td> -<td>390</td> -<td>1.6144258</td> -<td>6.0824113</td> -<td>16</td> +<td>CCTTC</td> +<td>300</td> +<td>1.5536399</td> +<td>6.4701333</td> +<td>17</td></tr><tr> -<td>CCCAA</td> -<td>335</td> -<td>1.588837</td> -<td>5.8073177</td> -<td>10</td> +<td>CCACT</td> +<td>315</td> +<td>1.5455065</td> +<td>6.135909</td> +<td>32</td> +</tr> +<tr> +<td>TCTTC</td> +<td>380</td> +<td>1.5416791</td> +<td>5.0737495</td> +<td>49</td> +</tr> +<tr> +<td>GTTCA</td> +<td>400</td> +<td>1.5408814</td> +<td>7.700401</td> +<td>11</td> +</tr> +<tr> +<td>AGGCA</td> +<td>330</td> +<td>1.5407803</td> +<td>5.8332543</td> +<td>6</td> +</tr> +<tr> +<td>AAAAG</td> +<td>600</td> +<td>1.5396972</td> +<td>5.782427</td> +<td>41</td></tr><tr><td>GCACA</td><td>330</td> -<td>1.5686142</td> +<td>1.5373511</td><td>5.8202715</td><td>18</td></tr><tr> -<td>GTTCA</td> -<td>395</td> -<td>1.5525635</td> -<td>7.700401</td> -<td>11</td> -</tr> -<tr> -<td>TCTTC</td> -<td>375</td> -<td>1.5523325</td> -<td>5.068676</td> -<td>4</td> -</tr> -<tr> -<td>AGGCA</td> -<td>325</td> -<td>1.5482932</td> -<td>5.8332543</td> -<td>6</td> -</tr> -<tr> -<td>GGGGA</td> -<td>240</td> -<td>1.5474048</td> -<td>6.3157325</td> -<td>7</td> -</tr> -<tr> -<td>CCTTC</td> -<td>290</td> -<td>1.5323931</td> -<td>6.4701333</td> -<td>17</td> -</tr> -<tr><td>ATGCC</td><td>305</td> -<td>1.5302798</td> +<td>1.4997808</td><td>12.286893</td><td>22</td></tr><tr><td>GAAGG</td><td>320</td> -<td>1.5278738</td> +<td>1.4974226</td><td>5.8462653</td><td>8</td></tr><tr> +<td>GAGAG</td> +<td>320</td> +<td>1.4974226</td> +<td>5.857981</td> +<td>41</td> +</tr> +<tr> +<td>TGTGC</td> +<td>285</td> +<td>1.4825499</td> +<td>5.2044287</td> +<td>29</td> +</tr> +<tr> +<td>TTGGC</td> +<td>285</td> +<td>1.4825495</td> +<td>5.199223</td> +<td>15</td> +</tr> +<tr><td>GGGAT</td> -<td>295</td> -<td>1.4867171</td> +<td>300</td> +<td>1.4817826</td><td>7.40506</td><td>21</td></tr><tr> -<td>TGTGC</td> -<td>280</td> -<td>1.4861598</td> -<td>5.199224</td> -<td>7</td> +<td>AGCTG</td> +<td>300</td> +<td>1.4784846</td> +<td>6.1633124</td> +<td>30</td></tr><tr><td>AACAG</td> -<td>420</td> -<td>1.4817125</td> +<td>425</td> +<td>1.4694693</td><td>5.1836653</td><td>10</td></tr><tr> +<td>GAGTG</td> +<td>295</td> +<td>1.4570862</td> +<td>6.1770606</td> +<td>33</td> +</tr> +<tr> +<td>GGGAC</td> +<td>230</td> +<td>1.4501395</td> +<td>6.3143044</td> +<td>40</td> +</tr> +<tr> +<td>GTGTT</td> +<td>355</td> +<td>1.4466851</td> +<td>6.134112</td> +<td>50</td> +</tr> +<tr> +<td>TTTGG</td> +<td>355</td> +<td>1.4466851</td> +<td>6.1095753</td> +<td>3</td> +</tr> +<tr><td>TCTTT</td><td>455</td> -<td>1.4755235</td> +<td>1.4461157</td><td>5.5590916</td><td>1</td></tr><tr> -<td>TTGGC</td> -<td>275</td> -<td>1.4596211</td> -<td>5.199223</td> -<td>15</td> -</tr> -<tr><td>GAGAT</td> -<td>385</td> -<td>1.4368514</td> +<td>395</td> +<td>1.4447913</td><td>6.397646</td><td>27</td></tr><tr> -<td>TTTGG</td> -<td>345</td> -<td>1.4345239</td> -<td>6.1095753</td> -<td>3</td> +<td>CAAAA</td> +<td>560</td> +<td>1.4338523</td> +<td>5.123362</td> +<td>31</td></tr><tr><td>GGTTC</td> -<td>270</td> -<td>1.4330826</td> +<td>275</td> +<td>1.4305303</td><td>10.398446</td><td>10</td></tr><tr> +<td>CCCTT</td> +<td>275</td> +<td>1.4241698</td> +<td>5.186479</td> +<td>39</td> +</tr> +<tr> +<td>CTGTT</td> +<td>350</td> +<td>1.4231348</td> +<td>5.0799813</td> +<td>10</td> +</tr> +<tr> +<td>ATGGT</td> +<td>365</td> +<td>1.4091904</td> +<td>6.7596393</td> +<td>47</td> +</tr> +<tr> +<td>TGTTG</td> +<td>345</td> +<td>1.4059336</td> +<td>5.1015162</td> +<td>40</td> +</tr> +<tr> +<td>CTGTC</td> +<td>270</td> +<td>1.4013947</td> +<td>5.198048</td> +<td>39</td> +</tr> +<tr> +<td>GAGAC</td> +<td>300</td> +<td>1.4007094</td> +<td>5.856681</td> +<td>50</td> +</tr> +<tr> +<td>CTTCT</td> +<td>345</td> +<td>1.3996824</td> +<td>7.1246448</td> +<td>50</td> +</tr> +<tr> +<td>GGCCC</td> +<td>165</td> +<td>1.398575</td> +<td>6.353853</td> +<td>2</td> +</tr> +<tr> +<td>TGAGT</td> +<td>360</td> +<td>1.3898867</td> +<td>5.7939773</td> +<td>32</td> +</tr> +<tr> +<td>GGCAC</td> +<td>220</td> +<td>1.3840029</td> +<td>6.2876506</td> +<td>17</td> +</tr> +<tr> +<td>CCTTT</td> +<td>340</td> +<td>1.3793972</td> +<td>5.068676</td> +<td>8</td> +</tr> +<tr><td>CCTTG</td><td>265</td> -<td>1.4034137</td> +<td>1.3754432</td><td>5.187652</td><td>18</td></tr><tr> -<td>CCCTT</td> -<td>265</td> -<td>1.4002901</td> -<td>5.176106</td> -<td>14</td> -</tr> -<tr> -<td>CTGTT</td> -<td>335</td> -<td>1.3898433</td> -<td>5.0799813</td> -<td>10</td> -</tr> -<tr> -<td>CCTTT</td> -<td>335</td> -<td>1.3867503</td> -<td>5.068676</td> -<td>8</td> -</tr> -<tr> -<td>GGCAC</td> -<td>215</td> -<td>1.3800533</td> -<td>6.2876506</td> -<td>17</td> -</tr> -<tr><td>TTGAA</td> -<td>465</td> -<td>1.3564935</td> +<td>475</td> +<td>1.3580486</td><td>6.4295163</td><td>7</td></tr><tr> -<td>CTTGG</td> -<td>255</td> -<td>1.3534669</td> -<td>5.1992235</td> -<td>18</td> +<td>GAGCG</td> +<td>215</td> +<td>1.3555653</td> +<td>12.603353</td> +<td>6</td></tr><tr> -<td>GTGTT</td> -<td>325</td> -<td>1.3513632</td> -<td>5.091313</td> -<td>28</td> -</tr> -<tr> -<td>GGCCC</td> -<td>155</td> -<td>1.3405302</td> -<td>6.353853</td> -<td>2</td> -</tr> -<tr> -<td>TGGTT</td> -<td>320</td> -<td>1.330573</td> -<td>5.091313</td> -<td>25</td> +<td>AAGGA</td> +<td>390</td> +<td>1.3514621</td> +<td>5.1952276</td> +<td>44</td></tr><tr><td>TTCTT</td> -<td>410</td> -<td>1.3295923</td> +<td>420</td> +<td>1.3348758</td><td>7.941558</td><td>4</td></tr><tr><td>GGGGT</td> -<td>195</td> -<td>1.327077</td> +<td>200</td> +<td>1.3339773</td><td>8.333022</td><td>45</td></tr><tr> -<td>AAGGA</td> -<td>375</td> -<td>1.3259085</td> -<td>5.1952276</td> -<td>44</td> +<td>CAGAT</td> +<td>365</td> +<td>1.3320893</td> +<td>5.4769697</td> +<td>34</td></tr><tr> -<td>CAGAT</td> -<td>350</td> -<td>1.3033215</td> -<td>5.471493</td> -<td>10</td> +<td>CTTGG</td> +<td>255</td> +<td>1.3264918</td> +<td>5.1992235</td> +<td>18</td> +</tr> +<tr> +<td>TGGTT</td> +<td>320</td> +<td>1.3040541</td> +<td>5.091313</td> +<td>25</td> +</tr> +<tr> +<td>TTGGG</td> +<td>250</td> +<td>1.3033829</td> +<td>6.5135255</td> +<td>6</td></tr><tr><td>CTGGT</td> -<td>245</td> -<td>1.3003898</td> -<td>5.1992235</td> -<td>12</td> +<td>250</td> +<td>1.3004823</td> +<td>5.204428</td> +<td>48</td> +</tr> +<tr> +<td>GCTCC</td> +<td>195</td> +<td>1.2919631</td> +<td>8.277508</td> +<td>26</td> +</tr> +<tr> +<td>TGATG</td> +<td>330</td> +<td>1.2740628</td> +<td>5.7939773</td> +<td>46</td></tr><tr><td>TGTCC</td><td>245</td> -<td>1.2974956</td> +<td>1.2716361</td><td>5.187652</td><td>21</td></tr><tr> -<td>GCTCC</td> -<td>190</td> -<td>1.2844352</td> -<td>8.277508</td> -<td>26</td> +<td>GGCTT</td> +<td>240</td> +<td>1.2484628</td> +<td>5.199223</td> +<td>4</td></tr><tr><td>GACAG</td><td>265</td> -<td>1.2624544</td> +<td>1.2372932</td><td>5.833254</td><td>27</td></tr><tr> -<td>GAGCG</td> -<td>195</td> -<td>1.2544682</td> -<td>12.603353</td> -<td>6</td> -</tr> -<tr> -<td>TTGGG</td> +<td>GGTGT</td><td>235</td> -<td>1.2500948</td> -<td>6.5135255</td> -<td>6</td> +<td>1.2251799</td> +<td>5.21082</td> +<td>27</td></tr><tr><td>AATGC</td><td>335</td> -<td>1.2474647</td> +<td>1.2226022</td><td>10.031068</td><td>21</td></tr><tr> -<td>GGCTT</td> -<td>235</td> -<td>1.2473125</td> -<td>5.199223</td> -<td>4</td> -</tr> -<tr><td>TTTGC</td> -<td>295</td> -<td>1.223892</td> +<td>300</td> +<td>1.2198299</td><td>5.0799813</td><td>9</td></tr><tr> -<td>GGTGT</td> +<td>GTCCT</td><td>230</td> -<td>1.223497</td> -<td>5.21082</td> -<td>27</td> +<td>1.1937809</td> +<td>5.1928453</td> +<td>47</td> +</tr> +<tr> +<td>GGGCC</td> +<td>140</td> +<td>1.1893166</td> +<td>6.3744006</td> +<td>43</td> +</tr> +<tr> +<td>ATCCC</td> +<td>240</td> +<td>1.1775287</td> +<td>6.135909</td> +<td>43</td> +</tr> +<tr> +<td>GCTCT</td> +<td>225</td> +<td>1.1678292</td> +<td>7.789268</td> +<td>47</td> +</tr> +<tr> +<td>AGCCC</td> +<td>185</td> +<td>1.1612303</td> +<td>6.2799363</td> +<td>31</td></tr><tr><td>GATCG</td><td>235</td> -<td>1.181698</td> -<td>6.1571493</td> -<td>45</td> +<td>1.1581463</td> +<td>6.1633124</td> +<td>29</td> +</tr> +<tr> +<td>ACCCT</td> +<td>230</td> +<td>1.128465</td> +<td>6.129773</td> +<td>10</td> +</tr> +<tr> +<td>GTTGG</td> +<td>215</td> +<td>1.1209095</td> +<td>5.2160373</td> +<td>47</td></tr><tr><td>AGCTC</td><td>225</td> -<td>1.1288949</td> +<td>1.1063956</td><td>6.1434464</td><td>25</td></tr><tr> -<td>ACCCT</td> +<td>CCCAT</td><td>225</td> -<td>1.1263824</td> +<td>1.1039332</td><td>6.129773</td> -<td>10</td> +<td>21</td></tr><tr><td>CGGAA</td><td>235</td> -<td>1.119535</td> +<td>1.0972222</td><td>9.333206</td><td>1</td></tr><tr> -<td>CCCAT</td> -<td>220</td> -<td>1.1013516</td> -<td>6.129773</td> -<td>21</td> -</tr> -<tr><td>TCTTG</td><td>265</td> -<td>1.0994283</td> +<td>1.0775164</td><td>5.0799813</td><td>21</td></tr><tr><td>ATGCA</td><td>295</td> -<td>1.0985136</td> +<td>1.0766199</td><td>5.4714913</td><td>37</td></tr><tr><td>GCTTG</td><td>205</td> -<td>1.0880812</td> +<td>1.0663953</td><td>5.199223</td><td>2</td></tr><tr><td>AGCGG</td><td>165</td> -<td>1.061473</td> +<td>1.0403174</td><td>12.603352</td><td>7</td></tr><tr> +<td>TTGCC</td> +<td>200</td> +<td>1.0380702</td> +<td>5.1876516</td> +<td>3</td> +</tr> +<tr> +<td>AACCT</td> +<td>285</td> +<td>1.0378094</td> +<td>5.4593143</td> +<td>13</td> +</tr> +<tr><td>AACCA</td><td>300</td> -<td>1.0560105</td> +<td>1.0349638</td><td>5.1721287</td><td>22</td></tr><tr> -<td>AACCT</td> -<td>280</td> -<td>1.0403365</td> -<td>5.4593143</td> -<td>13</td> -</tr> -<tr><td>CCGAG</td><td>160</td> -<td>1.0270164</td> +<td>1.0065476</td><td>12.575301</td><td>25</td></tr><tr> -<td>TTGCC</td> +<td>GTTCC</td><td>190</td> -<td>1.0062209</td> -<td>5.1876516</td> -<td>3</td> +<td>0.9861668</td> +<td>6.4845653</td> +<td>27</td></tr><tr><td>ACTCA</td> -<td>265</td> -<td>0.9846043</td> +<td>270</td> +<td>0.983188</td><td>5.4593153</td><td>11</td></tr><tr><td>CTCAT</td> -<td>250</td> -<td>0.98044825</td> +<td>255</td> +<td>0.9801258</td><td>5.7624474</td><td>4</td></tr><tr> -<td>GTTCC</td> -<td>185</td> -<td>0.9797416</td> -<td>6.4845653</td> -<td>27</td> -</tr> -<tr><td>GAACC</td> -<td>205</td> -<td>0.97444224</td> +<td>210</td> +<td>0.9783144</td><td>5.820272</td><td>25</td></tr><tr><td>GGCGG</td><td>110</td> -<td>0.9555928</td> +<td>0.93654746</td><td>10.637051</td><td>44</td></tr><tr> +<td>GCGGG</td> +<td>110</td> +<td>0.93654746</td> +<td>6.3886194</td> +<td>36</td> +</tr> +<tr> +<td>ATCGG</td> +<td>190</td> +<td>0.93637353</td> +<td>6.163312</td> +<td>30</td> +</tr> +<tr> +<td>GTCTG</td> +<td>180</td> +<td>0.9363471</td> +<td>5.2096424</td> +<td>41</td> +</tr> +<tr><td>GCGGT</td> -<td>130</td> -<td>0.8827489</td> +<td>140</td> +<td>0.93170583</td><td>13.303162</td><td>8</td></tr><tr> -<td>GCGGG</td> -<td>100</td> -<td>0.86872077</td> -<td>6.3822303</td> -<td>45</td> +<td>CGGGG</td> +<td>105</td> +<td>0.8939771</td> +<td>6.3886194</td> +<td>46</td> +</tr> +<tr> +<td>GGGCG</td> +<td>105</td> +<td>0.8939771</td> +<td>8.518159</td> +<td>43</td> +</tr> +<tr> +<td>TCGGA</td> +<td>170</td> +<td>0.83780795</td> +<td>7.395975</td> +<td>31</td> +</tr> +<tr> +<td>CTTGT</td> +<td>205</td> +<td>0.83355045</td> +<td>5.0850673</td> +<td>38</td></tr><tr><td>TGCCG</td><td>125</td> -<td>0.846908</td> +<td>0.83002883</td><td>14.93275</td><td>23</td></tr><tr><td>AGGCG</td> -<td>120</td> -<td>0.7719804</td> +<td>125</td> +<td>0.7881193</td><td>6.3016763</td><td>15</td></tr><tr><td>CGGTT</td> -<td>140</td> -<td>0.74307984</td> +<td>150</td> +<td>0.78028923</td><td>10.398446</td><td>9</td></tr><tr> +<td>GTGAC</td> +<td>150</td> +<td>0.7392424</td> +<td>6.163313</td> +<td>32</td> +</tr> +<tr><td>GCCGA</td><td>115</td> -<td>0.738168</td> +<td>0.723456</td><td>12.575301</td><td>24</td></tr><tr> +<td>CCCGC</td> +<td>85</td> +<td>0.7188745</td> +<td>6.3460584</td> +<td>30</td> +</tr> +<tr> +<td>CCCCG</td> +<td>85</td> +<td>0.7188745</td> +<td>10.576764</td> +<td>29</td> +</tr> +<tr><td>CGAGA</td> -<td>130</td> -<td>0.61931723</td> +<td>135</td> +<td>0.6303192</td><td>9.333206</td><td>26</td></tr><tr><td>CGGGA</td> -<td>85</td> -<td>0.5468194</td> +<td>90</td> +<td>0.5674459</td><td>6.301676</td><td>24</td></tr><tr><td>CACGG</td><td>85</td> -<td>0.54560244</td> +<td>0.5347284</td><td>6.2876506</td><td>37</td></tr> +<tr> +<td>CGCCT</td> +<td>80</td> +<td>0.5300361</td> +<td>6.6286345</td> +<td>30</td> +</tr> +<tr> +<td>CCGCA</td> +<td>75</td> +<td>0.47076905</td> +<td>6.2799363</td> +<td>36</td> +</tr> +<tr> +<td>CGTTG</td> +<td>40</td> +<td>0.20807713</td> +<td>5.2044277</td> +<td>46</td> +</tr></table> -<p><a href="#summary">Back to summary</a></div> -</div><div class="footer">Produced by <a href="http://www.bioinformatics.bbsrc.ac.uk/projects/fastqc/">FastQC</a> (version 0.9.1)</div> -</body></html> \ No newline at end of file +</div> +</body></html><div class="module"><h2>Files created by FastQC</h2><table cellspacing="2" cellpadding="2"> +<tr><td><a href="dataset_1.dat_fastqc.zip">dataset_1.dat_fastqc.zip (312.4 KB)</a></td></tr> +<tr><td><a href="duplication_levels.png">duplication_levels.png (14.5 KB)</a></td></tr> +<tr><td><a href="fastqc_data.txt">fastqc_data.txt (15.0 KB)</a></td></tr> +<tr><td><a href="fastqc_report.html">fastqc_report.html (25.2 KB)</a></td></tr> +<tr><td><a href="kmer_profiles.png">kmer_profiles.png (186.7 KB)</a></td></tr> +<tr><td><a href="per_base_gc_content.png">per_base_gc_content.png (12.1 KB)</a></td></tr> +<tr><td><a href="per_base_n_content.png">per_base_n_content.png (7.4 KB)</a></td></tr> +<tr><td><a href="per_base_quality.png">per_base_quality.png (9.6 KB)</a></td></tr> +<tr><td><a href="per_base_sequence_content.png">per_base_sequence_content.png (23.9 KB)</a></td></tr> +<tr><td><a href="per_sequence_gc_content.png">per_sequence_gc_content.png (29.6 KB)</a></td></tr> +<tr><td><a href="per_sequence_quality.png">per_sequence_quality.png (21.9 KB)</a></td></tr> +<tr><td><a href="sequence_length_distribution.png">sequence_length_distribution.png (18.9 KB)</a></td></tr> +<tr><td><a href="summary.txt">summary.txt (465 B)</a></td></tr> +</table> +<a href="http://www.bioinformatics.bbsrc.ac.uk/projects/fastqc/">FastQC documentation and full attribution is here</a><br/><hr/> +FastQC was run by Galaxy using the rgenetics rgFastQC wrapper - see http://rgenetics.org for details and licensing +</div></div><div class="footer">Produced by <a href="http://www.bioinformatics.bbsrc.ac.uk/projects/fastqc/">FastQC</a> (version 0.10.0)</div> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca test-data/picard_input_sorted_pair.sam --- a/test-data/picard_input_sorted_pair.sam +++ b/test-data/picard_input_sorted_pair.sam @@ -5,11 +5,11 @@ @RG ID:rg1 SM:Z bar:record:1 77 chr1 10 0 * * 0 0 AAAAAAAAAAAAA 1111111111111 RG:Z:rg1 bar:record:1 141 chr1 20 0 * * 0 0 CCCCCCCCCCCCC 2222222222222 RG:Z:rg1 -bar:record:2 77 chr2 10 0 * * 0 0 AAAAAAAAAAAAA 1111111111111 RG:Z:rg1 -bar:record:2 141 chr2 30 0 * * 0 0 CCCCCCCCCCCCC 2222222222222 RG:Z:rg1 -bar:record:3 77 chr1 10 0 * * 0 0 AAAAAAAAAAAAA 1111111111111 RG:Z:rg1 -bar:record:3 141 chr3 20 0 * * 0 0 CCCCCCCCCCCCC 2222222222222 RG:Z:rg1 -bar:record:4 77 chr1 1 0 * * 0 0 AAAAAAAAAAAAA 1111111111111 RG:Z:rg1 -bar:record:4 141 chr1 40 0 * * 0 0 CCCCCCCCCCCCC 2222222222222 RG:Z:rg1 -bar:record:5 77 chr1 40 0 * * 0 0 AAAAAAAAAAAAA 1111111111111 RG:Z:rg1 -bar:record:5 141 chr3 40 0 * * 0 0 CCCCCCCCCCCCC 2222222222222 RG:Z:rg1 +bar:record:2 77 chr1 40 0 * * 0 0 AAAAAAAAAAAAA 1111111111111 RG:Z:rg1 +bar:record:2 141 chr1 50 0 * * 0 0 CCCCCCCCCCCCC 2222222222222 RG:Z:rg1 +bar:record:3 77 chr2 10 0 * * 0 0 AAAAAAAAAAAAA 1111111111111 RG:Z:rg1 +bar:record:3 141 chr2 20 0 * * 0 0 CCCCCCCCCCCCC 2222222222222 RG:Z:rg1 +bar:record:4 77 chr2 50 0 * * 0 0 AAAAAAAAAAAAA 1111111111111 RG:Z:rg1 +bar:record:4 141 chr2 60 0 * * 0 0 CCCCCCCCCCCCC 2222222222222 RG:Z:rg1 +bar:record:5 77 chr3 40 0 * * 0 0 AAAAAAAAAAAAA 1111111111111 RG:Z:rg1 +bar:record:5 141 chr3 50 0 * * 0 0 CCCCCCCCCCCCC 2222222222222 RG:Z:rg1 diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca test-data/picard_output_AsMetrics_indexed_hg18_sorted_pair.html --- a/test-data/picard_output_AsMetrics_indexed_hg18_sorted_pair.html +++ b/test-data/picard_output_AsMetrics_indexed_hg18_sorted_pair.html @@ -6,28 +6,51 @@ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> -<meta name="generator" content="Galaxy CollectAlignmentSummaryMetrics tool output - see http://getgalaxy.org/" /> +<meta name="generator" content="Galaxy picard_wrapper tool output - see http://getgalaxy.org/" /><title></title><link rel="stylesheet" href="/static/style/base.css" type="text/css" /></head><body><div class="document"> -Galaxy tool wrapper picard_wrapper at 09/05/2011 11:03:57</b><br/><b>The following output files were created (click the filename to view/download a copy):</b><hr/><table> +Galaxy tool CollectAlignmentSummaryMetrics run at 11/11/2011 08:07:27</b><br/><b>The following output files were created (click the filename to view/download a copy):</b><hr/><table><tr><td><a href="CollectAlignmentSummaryMetrics.log">CollectAlignmentSummaryMetrics.log</a></td></tr> +<tr><td><a href="CollectAlignmentSummaryMetrics.metrics.txt">CollectAlignmentSummaryMetrics.metrics.txt</a></td></tr></table><p/> -<b>Picard log</b><hr/> -<pre>## executing java -Xmx2g -jar /udd/rerla/galaxy-central/tool-data/shared/jars/CollectAlignmentSummaryMetrics.jar VALIDATION_STRINGENCY=LENIENT ASSUME_SORTED=true ADAPTER_SEQUENCE= IS_BISULFITE_SEQUENCED=false MAX_INSERT_SIZE=100000 OUTPUT=/udd/rerla/galaxy-central/database/job_working_directory/5/dataset_5_files/CollectAlignmentSummaryMetrics.metrics.txt R=/udd/rerla/galaxy-central/database/job_working_directory/5/dataset_5_files/hg19.fasta_fake.fasta TMP_DIR=/tmp INPUT=/export/tmp/tmpBrCiH5/database/files/000/dataset_4.dat returned status 1 and stderr: -[Mon May 09 11:03:51 EDT 2011] net.sf.picard.analysis.CollectAlignmentSummaryMetrics MAX_INSERT_SIZE=100000 ADAPTER_SEQUENCE=[AATGATACGGCGACCACCGAGATCTACACTCTTTCCCTACACGACGCTCTTCCGATCT, AGATCGGAAGAGCTCGTATGCCGTCTTCTGCTTG, AATGATACGGCGACCACCGAGATCTACACTCTTTCCCTACACGACGCTCTTCCGATCT, AGATCGGAAGAGCGGTTCAGCAGGAATGCCGAGACCGATCTCGTATGCCGTCTTCTGCTTG, AATGATACGGCGACCACCGAGATCTACACTCTTTCCCTACACGACGCTCTTCCGATCT, AGATCGGAAGAGCACACGTCTGAACTCCAGTCACNNNNNNNNATCTCGTATGCCGTCTTCTGCTTG, IS_BISULFITE_SEQUENCED=false] INPUT=/export/tmp/tmpBrCiH5/database/files/000/dataset_4.dat OUTPUT=/udd/rerla/galaxy-central/database/job_working_directory/5/dataset_5_files/CollectAlignmentSummaryMetrics.metrics.txt REFERENCE_SEQUENCE=/udd/rerla/galaxy-central/database/job_working_directory/5/dataset_5_files/hg19.fasta_fake.fasta ASSUME_SORTED=true TMP_DIR=/tmp VALIDATION_STRINGENCY=LENIENT IS_BISULFITE_SEQUENCED=false STOP_AFTER=0 VERBOSITY=INFO QUIET=false COMPRESSION_LEVEL=5 MAX_RECORDS_IN_RAM=500000 CREATE_INDEX=false CREATE_MD5_FILE=false -[Mon May 09 11:03:57 EDT 2011] net.sf.picard.analysis.CollectAlignmentSummaryMetrics done. -Runtime.totalMemory()=912588800 -Exception in thread "main" net.sf.picard.PicardException: Requesting earlier reference sequence: 0 < 1 - at net.sf.picard.reference.ReferenceSequenceFileWalker.get(ReferenceSequenceFileWalker.java:78) - at net.sf.picard.analysis.SinglePassSamProgram.makeItSo(SinglePassSamProgram.java:115) - at net.sf.picard.analysis.SinglePassSamProgram.doWork(SinglePassSamProgram.java:54) - at net.sf.picard.cmdline.CommandLineProgram.instanceMain(CommandLineProgram.java:157) - at net.sf.picard.cmdline.CommandLineProgram.instanceMainWithExit(CommandLineProgram.java:117) - at net.sf.picard.analysis.CollectAlignmentSummaryMetrics.main(CollectAlignmentSummaryMetrics.java:106) - +<b>Picard on line resources</b><ul> +<li><a href="http://picard.sourceforge.net/index.shtml">Click here for Picard Documentation</a></li> +<li><a href="http://picard.sourceforge.net/picard-metric-definitions.shtml">Click here for Picard Metrics definitions</a></li></ul><hr/> +<b>Picard output (transposed to make it easier to see)</b><hr/> +<table cellpadding="3" > +<tr class="d0"><td colspan="2">## net.sf.picard.metrics.StringHeader</td></tr><tr class="d1"><td colspan="2"># net.sf.picard.analysis.CollectAlignmentSummaryMetrics MAX_INSERT_SIZE=100000 ADAPTER_SEQUENCE=[AATGATACGGCGACCACCGAGATCTACACTCTTTCCCTACACGACGCTCTTCCGATCT, AGATCGGAAGAGCTCGTATGCCGTCTTCTGCTTG, AATGATACGGCGACCACCGAGATCTACACTCTTTCCCTACACGACGCTCTTCCGATCT, AGATCGGAAGAGCGGTTCAGCAGGAATGCCGAGACCGATCTCGTATGCCGTCTTCTGCTTG, AATGATACGGCGACCACCGAGATCTACACTCTTTCCCTACACGACGCTCTTCCGATCT, AGATCGGAAGAGCACACGTCTGAACTCCAGTCACNNNNNNNNATCTCGTATGCCGTCTTCTGCTTG, IS_BISULFITE_SEQUENCED=false] INPUT=/data/tmp/tmpLLcl1w/database/files/000/dataset_4.dat OUTPUT=/data/home/rlazarus/galaxy/database/job_working_directory/5/dataset_5_files/CollectAlignmentSummaryMetrics.metrics.txt REFERENCE_SEQUENCE=/data/home/rlazarus/galaxy/database/job_working_directory/5/dataset_5_files/hg19.fa_fake.fasta ASSUME_SORTED=true TMP_DIR=[/tmp] VALIDATION_STRINGENCY=LENIENT METRIC_ACCUMULATION_LEVEL=[ALL_READS] IS_BISULFITE_SEQUENCED=false STOP_AFTER=0 VERBOSITY=INFO QUIET=false COMPRESSION_LEVEL=5 MAX_RECORDS_IN_RAM=500000 CREATE_INDEX=false CREATE_MD5_FILE=false</td></tr><tr class="d0"><td colspan="2">## net.sf.picard.metrics.StringHeader</td></tr><tr class="d1"><td colspan="2"># Started on: Fri Nov 11 08:07:22 EST 2011</td></tr><tr class="d0"><td colspan="2">## METRICS CLASS net.sf.picard.analysis.AlignmentSummaryMetrics</td></tr><tr class="d0"><td>CATEGORY</td><td>FIRST_OF_PAIR </td></tr> +<tr class="d1"><td>TOTAL_READS</td><td>5 </td></tr> +<tr class="d0"><td>PF_READS</td><td>5 </td></tr> +<tr class="d1"><td>PCT_PF_READS</td><td>1 </td></tr> +<tr class="d0"><td>PF_NOISE_READS</td><td>0 </td></tr> +<tr class="d1"><td>PF_READS_ALIGNED</td><td>0 </td></tr> +<tr class="d0"><td>PCT_PF_READS_ALIGNED</td><td>0 </td></tr> +<tr class="d1"><td>PF_ALIGNED_BASES</td><td>0 </td></tr> +<tr class="d0"><td>PF_HQ_ALIGNED_READS</td><td>0 </td></tr> +<tr class="d1"><td>PF_HQ_ALIGNED_BASES</td><td>0 </td></tr> +<tr class="d0"><td>PF_HQ_ALIGNED_Q20_BASES</td><td>0 </td></tr> +<tr class="d1"><td>PF_HQ_MEDIAN_MISMATCHES</td><td>0 </td></tr> +<tr class="d0"><td>PF_MISMATCH_RATE</td><td>0 </td></tr> +<tr class="d1"><td>PF_HQ_ERROR_RATE</td><td>0 </td></tr> +<tr class="d0"><td>PF_INDEL_RATE</td><td>0 </td></tr> +<tr class="d1"><td>MEAN_READ_LENGTH</td><td>13 </td></tr> +<tr class="d0"><td>READS_ALIGNED_IN_PAIRS</td><td>0 </td></tr> +<tr class="d1"><td>PCT_READS_ALIGNED_IN_PAIRS</td><td>0 </td></tr> +<tr class="d0"><td>BAD_CYCLES</td><td>0 </td></tr> +<tr class="d1"><td>STRAND_BALANCE</td><td>0 </td></tr> +<tr class="d0"><td>PCT_CHIMERAS</td><td>0 </td></tr> +<tr class="d1"><td>PCT_ADAPTER</td><td>0 </td></tr> +<tr class="d0"><td>SAMPLE</td><td> </td></tr> +<tr class="d1"><td>LIBRARY</td><td> </td></tr> +<tr class="d0"><td>READ_GROUP +</td><td> + </td></tr> +</table> +<b>Picard Tool Run Log</b><hr/> +<pre>INFO:root:## executing java -Xmx4g -jar /data/home/rlazarus/galaxy/tool-data/shared/jars/picard/CollectAlignmentSummaryMetrics.jar VALIDATION_STRINGENCY=LENIENT ASSUME_SORTED=true ADAPTER_SEQUENCE= IS_BISULFITE_SEQUENCED=false MAX_INSERT_SIZE=100000 OUTPUT=/data/home/rlazarus/galaxy/database/job_working_directory/5/dataset_5_files/CollectAlignmentSummaryMetrics.metrics.txt R=/data/home/rlazarus/galaxy/database/job_working_directory/5/dataset_5_files/hg19.fa_fake.fasta TMP_DIR=/tmp INPUT=/data/tmp/tmpLLcl1w/database/files/000/dataset_4.dat returned status 0 and nothing on stderr </pre><hr/>The freely available <a href="http://picard.sourceforge.net/command-line-overview.shtml">Picard software</a> generated all outputs reported here running as a <a href="http://getgalaxy.org">Galaxy</a> tool</div></body></html> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca test-data/picard_output_alignment_summary_metrics.html --- a/test-data/picard_output_alignment_summary_metrics.html +++ b/test-data/picard_output_alignment_summary_metrics.html @@ -12,7 +12,7 @@ </head><body><div class="document"> -Galaxy tool CollectAlignmentSummaryMetrics run at 11/05/2011 23:16:24</b><br/><b>The following output files were created (click the filename to view/download a copy):</b><hr/><table> +Galaxy tool CollectAlignmentSummaryMetrics run at 11/11/2011 08:07:10</b><br/><b>The following output files were created (click the filename to view/download a copy):</b><hr/><table><tr><td><a href="CollectAlignmentSummaryMetrics.log">CollectAlignmentSummaryMetrics.log</a></td></tr><tr><td><a href="CollectAlignmentSummaryMetrics.metrics.txt">CollectAlignmentSummaryMetrics.metrics.txt</a></td></tr></table><p/> @@ -21,43 +21,38 @@ <li><a href="http://picard.sourceforge.net/picard-metric-definitions.shtml">Click here for Picard Metrics definitions</a></li></ul><hr/><b>Picard output (transposed to make it easier to see)</b><hr/><table cellpadding="3" > -<tr class="d0"><td colspan="2">## net.sf.picard.metrics.StringHeader</td></tr><tr class="d1"><td colspan="2"># net.sf.picard.analysis.CollectAlignmentSummaryMetrics MAX_INSERT_SIZE=100000 ADAPTER_SEQUENCE=[AATGATACGGCGACCACCGAGATCTACACTCTTTCCCTACACGACGCTCTTCCGATCT, AGATCGGAAGAGCTCGTATGCCGTCTTCTGCTTG, AATGATACGGCGACCACCGAGATCTACACTCTTTCCCTACACGACGCTCTTCCGATCT, AGATCGGAAGAGCGGTTCAGCAGGAATGCCGAGACCGATCTCGTATGCCGTCTTCTGCTTG, AATGATACGGCGACCACCGAGATCTACACTCTTTCCCTACACGACGCTCTTCCGATCT, AGATCGGAAGAGCACACGTCTGAACTCCAGTCACNNNNNNNNATCTCGTATGCCGTCTTCTGCTTG, IS_BISULFITE_SEQUENCED=false] INPUT=/export/tmp/tmp1-mt_l/database/files/000/dataset_2.dat OUTPUT=/udd/rerla/galaxy-central/database/job_working_directory/3/dataset_3_files/CollectAlignmentSummaryMetrics.metrics.txt REFERENCE_SEQUENCE=/udd/rerla/galaxy-central/database/job_working_directory/3/dataset_3_files/CollectAlignmentSummaryMetricsZJS8q6.fasta_fake.fasta ASSUME_SORTED=true TMP_DIR=/tmp VALIDATION_STRINGENCY=LENIENT IS_BISULFITE_SEQUENCED=false STOP_AFTER=0 VERBOSITY=INFO QUIET=false COMPRESSION_LEVEL=5 MAX_RECORDS_IN_RAM=500000 CREATE_INDEX=false CREATE_MD5_FILE=false</td></tr><tr class="d0"><td colspan="2">## net.sf.picard.metrics.StringHeader</td></tr><tr class="d1"><td colspan="2"># Started on: Wed May 11 23:16:24 EDT 2011</td></tr><tr class="d0"><td colspan="2">## METRICS CLASS net.sf.picard.analysis.AlignmentSummaryMetrics</td></tr><tr class="d0"><td>CATEGORY</td><td>FIRST_OF_PAIR </td></tr> +<tr class="d0"><td colspan="2">## net.sf.picard.metrics.StringHeader</td></tr><tr class="d1"><td colspan="2"># net.sf.picard.analysis.CollectAlignmentSummaryMetrics MAX_INSERT_SIZE=100000 ADAPTER_SEQUENCE=[AATGATACGGCGACCACCGAGATCTACACTCTTTCCCTACACGACGCTCTTCCGATCT, AGATCGGAAGAGCTCGTATGCCGTCTTCTGCTTG, AATGATACGGCGACCACCGAGATCTACACTCTTTCCCTACACGACGCTCTTCCGATCT, AGATCGGAAGAGCGGTTCAGCAGGAATGCCGAGACCGATCTCGTATGCCGTCTTCTGCTTG, AATGATACGGCGACCACCGAGATCTACACTCTTTCCCTACACGACGCTCTTCCGATCT, AGATCGGAAGAGCACACGTCTGAACTCCAGTCACNNNNNNNNATCTCGTATGCCGTCTTCTGCTTG, IS_BISULFITE_SEQUENCED=false] INPUT=/data/tmp/tmpLLcl1w/database/files/000/dataset_2.dat OUTPUT=/data/home/rlazarus/galaxy/database/job_working_directory/3/dataset_3_files/CollectAlignmentSummaryMetrics.metrics.txt REFERENCE_SEQUENCE=/data/home/rlazarus/galaxy/database/job_working_directory/3/dataset_3_files/CollectAlignmentSummaryMetricsfq2hit.fasta_fake.fasta ASSUME_SORTED=true TMP_DIR=[/tmp] VALIDATION_STRINGENCY=LENIENT METRIC_ACCUMULATION_LEVEL=[ALL_READS] IS_BISULFITE_SEQUENCED=false STOP_AFTER=0 VERBOSITY=INFO QUIET=false COMPRESSION_LEVEL=5 MAX_RECORDS_IN_RAM=500000 CREATE_INDEX=false CREATE_MD5_FILE=false</td></tr><tr class="d0"><td colspan="2">## net.sf.picard.metrics.StringHeader</td></tr><tr class="d1"><td colspan="2"># Started on: Fri Nov 11 08:07:10 EST 2011</td></tr><tr class="d0"><td colspan="2">## METRICS CLASS net.sf.picard.analysis.AlignmentSummaryMetrics</td></tr><tr class="d0"><td>CATEGORY</td><td>FIRST_OF_PAIR </td></tr><tr class="d1"><td>TOTAL_READS</td><td>4 </td></tr><tr class="d0"><td>PF_READS</td><td>4 </td></tr><tr class="d1"><td>PCT_PF_READS</td><td>1 </td></tr><tr class="d0"><td>PF_NOISE_READS</td><td>0 </td></tr><tr class="d1"><td>PF_READS_ALIGNED</td><td>4 </td></tr><tr class="d0"><td>PCT_PF_READS_ALIGNED</td><td>1 </td></tr> -<tr class="d1"><td>PF_HQ_ALIGNED_READS</td><td>4 </td></tr> -<tr class="d0"><td>PF_HQ_ALIGNED_BASES</td><td>404 </td></tr> -<tr class="d1"><td>PF_HQ_ALIGNED_Q20_BASES</td><td>28 </td></tr> -<tr class="d0"><td>PF_HQ_MEDIAN_MISMATCHES</td><td>78 </td></tr> +<tr class="d1"><td>PF_ALIGNED_BASES</td><td>404 </td></tr> +<tr class="d0"><td>PF_HQ_ALIGNED_READS</td><td>4 </td></tr> +<tr class="d1"><td>PF_HQ_ALIGNED_BASES</td><td>404 </td></tr> +<tr class="d0"><td>PF_HQ_ALIGNED_Q20_BASES</td><td>28 </td></tr> +<tr class="d1"><td>PF_HQ_MEDIAN_MISMATCHES</td><td>78 </td></tr> +<tr class="d0"><td>PF_MISMATCH_RATE</td><td>0.777228 </td></tr><tr class="d1"><td>PF_HQ_ERROR_RATE</td><td>0.777228 </td></tr> -<tr class="d0"><td>MEAN_READ_LENGTH</td><td>101 </td></tr> -<tr class="d1"><td>READS_ALIGNED_IN_PAIRS</td><td>3 </td></tr> -<tr class="d0"><td>PCT_READS_ALIGNED_IN_PAIRS</td><td>0.75 </td></tr> -<tr class="d1"><td>BAD_CYCLES</td><td>63 </td></tr> -<tr class="d0"><td>STRAND_BALANCE</td><td>0.25 </td></tr> -<tr class="d1"><td>PCT_CHIMERAS</td><td>0 </td></tr> -<tr class="d0"><td>PCT_ADAPTER -</td><td>0 +<tr class="d0"><td>PF_INDEL_RATE</td><td>0 </td></tr> +<tr class="d1"><td>MEAN_READ_LENGTH</td><td>101 </td></tr> +<tr class="d0"><td>READS_ALIGNED_IN_PAIRS</td><td>3 </td></tr> +<tr class="d1"><td>PCT_READS_ALIGNED_IN_PAIRS</td><td>0.75 </td></tr> +<tr class="d0"><td>BAD_CYCLES</td><td>63 </td></tr> +<tr class="d1"><td>STRAND_BALANCE</td><td>0.25 </td></tr> +<tr class="d0"><td>PCT_CHIMERAS</td><td>0 </td></tr> +<tr class="d1"><td>PCT_ADAPTER</td><td>0 </td></tr> +<tr class="d0"><td>SAMPLE</td><td> </td></tr> +<tr class="d1"><td>LIBRARY</td><td> </td></tr> +<tr class="d0"><td>READ_GROUP +</td><td> </td></tr></table><b>Picard Tool Run Log</b><hr/> -<pre>Wed, 11 May 2011 23:16:24 INFO - ## executing java -Xmx2g -jar /udd/rerla/galaxy-central/tool-data/shared/jars/CreateSequenceDictionary.jar REFERENCE=/tmp/CollectAlignmentSummaryMetricsZJS8q6.fasta OUTPUT=/tmp/CollectAlignmentSummaryMetricsZJS8q6.dict URI=dataset_1.dat TRUNCATE_NAMES_AT_WHITESPACE=None returned status 0 and stderr: -[Wed May 11 23:16:24 EDT 2011] net.sf.picard.sam.CreateSequenceDictionary REFERENCE=/tmp/CollectAlignmentSummaryMetricsZJS8q6.fasta OUTPUT=/tmp/CollectAlignmentSummaryMetricsZJS8q6.dict URI=dataset_1.dat TRUNCATE_NAMES_AT_WHITESPACE=false NUM_SEQUENCES=2147483647 TMP_DIR=/tmp/rerla VERBOSITY=INFO QUIET=false VALIDATION_STRINGENCY=STRICT COMPRESSION_LEVEL=5 MAX_RECORDS_IN_RAM=500000 CREATE_INDEX=false CREATE_MD5_FILE=false -[Wed May 11 23:16:24 EDT 2011] net.sf.picard.sam.CreateSequenceDictionary done. -Runtime.totalMemory()=9109504 +<pre>INFO:root:## executing java -Xmx4g -jar /data/home/rlazarus/galaxy/tool-data/shared/jars/picard/CreateSequenceDictionary.jar REFERENCE=/tmp/CollectAlignmentSummaryMetricsfq2hit.fasta OUTPUT=/tmp/CollectAlignmentSummaryMetricsfq2hit.dict URI=dataset_1.dat TRUNCATE_NAMES_AT_WHITESPACE=None returned status 0 and nothing on stderr - -Wed, 11 May 2011 23:16:24 INFO - ## executing java -Xmx2g -jar /udd/rerla/galaxy-central/tool-data/shared/jars/CollectAlignmentSummaryMetrics.jar VALIDATION_STRINGENCY=LENIENT ASSUME_SORTED=true ADAPTER_SEQUENCE= IS_BISULFITE_SEQUENCED=false MAX_INSERT_SIZE=100000 OUTPUT=/udd/rerla/galaxy-central/database/job_working_directory/3/dataset_3_files/CollectAlignmentSummaryMetrics.metrics.txt R=/udd/rerla/galaxy-central/database/job_working_directory/3/dataset_3_files/CollectAlignmentSummaryMetricsZJS8q6.fasta_fake.fasta TMP_DIR=/tmp INPUT=/export/tmp/tmp1-mt_l/database/files/000/dataset_2.dat returned status 0 and stderr: -[Wed May 11 23:16:24 EDT 2011] net.sf.picard.analysis.CollectAlignmentSummaryMetrics MAX_INSERT_SIZE=100000 ADAPTER_SEQUENCE=[AATGATACGGCGACCACCGAGATCTACACTCTTTCCCTACACGACGCTCTTCCGATCT, AGATCGGAAGAGCTCGTATGCCGTCTTCTGCTTG, AATGATACGGCGACCACCGAGATCTACACTCTTTCCCTACACGACGCTCTTCCGATCT, AGATCGGAAGAGCGGTTCAGCAGGAATGCCGAGACCGATCTCGTATGCCGTCTTCTGCTTG, AATGATACGGCGACCACCGAGATCTACACTCTTTCCCTACACGACGCTCTTCCGATCT, AGATCGGAAGAGCACACGTCTGAACTCCAGTCACNNNNNNNNATCTCGTATGCCGTCTTCTGCTTG, IS_BISULFITE_SEQUENCED=false] INPUT=/export/tmp/tmp1-mt_l/database/files/000/dataset_2.dat OUTPUT=/udd/rerla/galaxy-central/database/job_working_directory/3/dataset_3_files/CollectAlignmentSummaryMetrics.metrics.txt REFERENCE_SEQUENCE=/udd/rerla/galaxy-central/database/job_working_directory/3/dataset_3_files/CollectAlignmentSummaryMetricsZJS8q6.fasta_fake.fasta ASSUME_SORTED=true TMP_DIR=/tmp VALIDATION_STRINGENCY=LENIENT IS_BISULFITE_SEQUENCED=false STOP_AFTER=0 VERBOSITY=INFO QUIET=false COMPRESSION_LEVEL=5 MAX_RECORDS_IN_RAM=500000 CREATE_INDEX=false CREATE_MD5_FILE=false -WARNING 2011-05-11 23:16:24 SinglePassSamProgram File reports sort order 'queryname', assuming it's coordinate sorted anyway. -[Wed May 11 23:16:24 EDT 2011] net.sf.picard.analysis.CollectAlignmentSummaryMetrics done. -Runtime.totalMemory()=9109504 - +INFO:root:## executing java -Xmx4g -jar /data/home/rlazarus/galaxy/tool-data/shared/jars/picard/CollectAlignmentSummaryMetrics.jar VALIDATION_STRINGENCY=LENIENT ASSUME_SORTED=true ADAPTER_SEQUENCE= IS_BISULFITE_SEQUENCED=false MAX_INSERT_SIZE=100000 OUTPUT=/data/home/rlazarus/galaxy/database/job_working_directory/3/dataset_3_files/CollectAlignmentSummaryMetrics.metrics.txt R=/data/home/rlazarus/galaxy/database/job_working_directory/3/dataset_3_files/CollectAlignmentSummaryMetricsfq2hit.fasta_fake.fasta TMP_DIR=/tmp INPUT=/data/tmp/tmpLLcl1w/database/files/000/dataset_2.dat returned status 0 and nothing on stderr </pre><hr/>The freely available <a href="http://picard.sourceforge.net/command-line-overview.shtml">Picard software</a> generated all outputs reported here running as a <a href="http://getgalaxy.org">Galaxy</a> tool</div></body></html> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tool-data/shared/igv/igv_build_sites.txt.sample --- /dev/null +++ b/tool-data/shared/igv/igv_build_sites.txt.sample @@ -0,0 +1,4 @@ +#site_id site_name site_url dbkey ivg_build_name +web_link_main web current http://www.broadinstitute.org/igv/projects/current/igv.php hg19,hg_g1k_v37,hg18,1kg_ref,hg17,hg16,mm9,mm8,mm7,panTro2,rheMac2,rn4,canFam2,bosTau6,bosTau4,bosTau3,susScrofa,galGal3,cavPor3,monDom5,xenTro2,taeGut1,zebrafish,danRer6,danRer7,gasAcu1,Aplysia,Plasmodium_3D7_v2.1,Plasmodium_3D7_v5.5,Plasmodium_6.1,PlasmoDB_7.0,pvivax,GSM552910,sacCer1,sacCer2,sk1,Y55,sacCer62,spombe_709,spombe_1.55,candida,mg8,spur_2.1,spur_2.5,spur_3.0,WS201,ce6,ce4,dm3,dm2,dmel_5.9,dmel_r5.22,dmel_r5.33,tcas_2.0,tcas_3.0,ncrassa_v3,nc10,Glamblia_2.0,me49,tb927,tbgambi,lmjr,anidulans_4.1,NC_009012,U00096.2,NC_000913.2,NC_002655.2,CSavignyi_v2.1,tair8,tair9,tair10,O_Sativa_r6,osativa_6.1,B73,ZmB73_5a,ppatens_1.2,D.discoideum hg19,b37,hg18,1kg_ref,hg17,hg16,mm9,mm8,mm7,panTro2,rheMac2,rn4,canFam2,bosTau6,bosTau4,bosTau3,susScrofa,galGal3,cavPor3,monDom5,xenTro2,taeGut1,zebrafish,danRer6,danRer7,gasAcu1,Aplysia,Plasmodium_3D7_v2.1,Plasmodium_3D7_v5.5,Plasmodium_6.1,PlasmoDB_7.0,pvivax,GSM552910,sacCer1,sacCer2,sk1,Y55,sacCer62,spombe_709,spombe_1.55,candida,mg8,spur_2.1,spur_2.5,spur_3.0,WS201,ce6,ce4,dm3,dm2,dmel_5.9,dmel_r5.22,dmel_r5.33,tcas_2.0,tcas_3.0,ncrassa_v3,nc10,Glamblia_2.0,me49,tb927,tbgambi,lmjr,anidulans_4.1,NC_009012,U00096.2,NC_000913.2,NC_002655.2,CSavignyi_v2.1,tair8,tair9,tair10,O_Sativa_r6,osativa_6.1,B73,ZmB73_5a,ppatens_1.2,D.discoideum +#web_jnlp_1.5 web 1.5 http://www.broadinstitute.org/igvdata/jws/prod hg19,hg_g1k_v37,hg18,1kg_ref,hg17,hg16,mm9,mm8,mm7,panTro2,rheMac2,rn4,canFam2,bosTau6,bosTau4,bosTau3,susScrofa,galGal3,cavPor3,monDom5,xenTro2,taeGut1,zebrafish,danRer6,danRer7,gasAcu1,Aplysia,Plasmodium_3D7_v2.1,Plasmodium_3D7_v5.5,Plasmodium_6.1,PlasmoDB_7.0,pvivax,GSM552910,sacCer1,sacCer2,sk1,Y55,sacCer62,spombe_709,spombe_1.55,candida,mg8,spur_2.1,spur_2.5,spur_3.0,WS201,ce6,ce4,dm3,dm2,dmel_5.9,dmel_r5.22,dmel_r5.33,tcas_2.0,tcas_3.0,ncrassa_v3,nc10,Glamblia_2.0,me49,tb927,tbgambi,lmjr,anidulans_4.1,NC_009012,U00096.2,NC_000913.2,NC_002655.2,CSavignyi_v2.1,tair8,tair9,tair10,O_Sativa_r6,osativa_6.1,B73,ZmB73_5a,ppatens_1.2,D.discoideum hg19,b37,hg18,1kg_ref,hg17,hg16,mm9,mm8,mm7,panTro2,rheMac2,rn4,canFam2,bosTau6,bosTau4,bosTau3,susScrofa,galGal3,cavPor3,monDom5,xenTro2,taeGut1,zebrafish,danRer6,danRer7,gasAcu1,Aplysia,Plasmodium_3D7_v2.1,Plasmodium_3D7_v5.5,Plasmodium_6.1,PlasmoDB_7.0,pvivax,GSM552910,sacCer1,sacCer2,sk1,Y55,sacCer62,spombe_709,spombe_1.55,candida,mg8,spur_2.1,spur_2.5,spur_3.0,WS201,ce6,ce4,dm3,dm2,dmel_5.9,dmel_r5.22,dmel_r5.33,tcas_2.0,tcas_3.0,ncrassa_v3,nc10,Glamblia_2.0,me49,tb927,tbgambi,lmjr,anidulans_4.1,NC_009012,U00096.2,NC_000913.2,NC_002655.2,CSavignyi_v2.1,tair8,tair9,tair10,O_Sativa_r6,osativa_6.1,B73,ZmB73_5a,ppatens_1.2,D.discoideum +local_default local http://localhost:60151/load hg19,hg_g1k_v37,hg18,1kg_ref,hg17,hg16,mm9,mm8,mm7,panTro2,rheMac2,rn4,canFam2,bosTau6,bosTau4,bosTau3,susScrofa,galGal3,cavPor3,monDom5,xenTro2,taeGut1,zebrafish,danRer6,danRer7,gasAcu1,Aplysia,Plasmodium_3D7_v2.1,Plasmodium_3D7_v5.5,Plasmodium_6.1,PlasmoDB_7.0,pvivax,GSM552910,sacCer1,sacCer2,sk1,Y55,sacCer62,spombe_709,spombe_1.55,candida,mg8,spur_2.1,spur_2.5,spur_3.0,WS201,ce6,ce4,dm3,dm2,dmel_5.9,dmel_r5.22,dmel_r5.33,tcas_2.0,tcas_3.0,ncrassa_v3,nc10,Glamblia_2.0,me49,tb927,tbgambi,lmjr,anidulans_4.1,NC_009012,U00096.2,NC_000913.2,NC_002655.2,CSavignyi_v2.1,tair8,tair9,tair10,O_Sativa_r6,osativa_6.1,B73,ZmB73_5a,ppatens_1.2,D.discoideum hg19,b37,hg18,1kg_ref,hg17,hg16,mm9,mm8,mm7,panTro2,rheMac2,rn4,canFam2,bosTau6,bosTau4,bosTau3,susScrofa,galGal3,cavPor3,monDom5,xenTro2,taeGut1,zebrafish,danRer6,danRer7,gasAcu1,Aplysia,Plasmodium_3D7_v2.1,Plasmodium_3D7_v5.5,Plasmodium_6.1,PlasmoDB_7.0,pvivax,GSM552910,sacCer1,sacCer2,sk1,Y55,sacCer62,spombe_709,spombe_1.55,candida,mg8,spur_2.1,spur_2.5,spur_3.0,WS201,ce6,ce4,dm3,dm2,dmel_5.9,dmel_r5.22,dmel_r5.33,tcas_2.0,tcas_3.0,ncrassa_v3,nc10,Glamblia_2.0,me49,tb927,tbgambi,lmjr,anidulans_4.1,NC_009012,U00096.2,NC_000913.2,NC_002655.2,CSavignyi_v2.1,tair8,tair9,tair10,O_Sativa_r6,osativa_6.1,B73,ZmB73_5a,ppatens_1.2,D.discoideum \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tool_conf.xml.sample --- a/tool_conf.xml.sample +++ b/tool_conf.xml.sample @@ -477,17 +477,6 @@ <tool file="vcf_tools/filter.xml" /><tool file="vcf_tools/extract.xml" /></section> - <section name="PacBio/Illumina Assembly" id="hybrid"> - <tool file="ilmn_pacbio/quake.xml"/> - <tool file="ilmn_pacbio/quake_pe.xml"/> - <tool file="ilmn_pacbio/soap_denovo.xml"/> - <!-- - Uncomment this tool when we support the HDF5 format - <tool file="ilmn_pacbio/smrtpipe_filter.xml"/> - --> - <tool file="ilmn_pacbio/smrtpipe_hybrid.xml"/> - <tool file="ilmn_pacbio/assembly_stats.xml"/> - </section><!-- TODO: uncomment the following EMBOSS section whenever moving to test, but comment it in .sample to eliminate diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/annotation_profiler/annotation_profiler.xml --- a/tools/annotation_profiler/annotation_profiler.xml +++ b/tools/annotation_profiler/annotation_profiler.xml @@ -136,6 +136,8 @@ **Citation** +For the underlying data, please see http://genome.ucsc.edu/cite.html for the proper citation. + If you use this tool in Galaxy, please cite Blankenberg D, et al. *In preparation.* </help> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_antigenic.xml --- a/tools/emboss_5/emboss_antigenic.xml +++ b/tools/emboss_5/emboss_antigenic.xml @@ -48,8 +48,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_backtranseq.xml --- a/tools/emboss_5/emboss_backtranseq.xml +++ b/tools/emboss_5/emboss_backtranseq.xml @@ -219,8 +219,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_banana.xml --- a/tools/emboss_5/emboss_banana.xml +++ b/tools/emboss_5/emboss_banana.xml @@ -23,8 +23,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_biosed.xml --- a/tools/emboss_5/emboss_biosed.xml +++ b/tools/emboss_5/emboss_biosed.xml @@ -72,8 +72,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_btwisted.xml --- a/tools/emboss_5/emboss_btwisted.xml +++ b/tools/emboss_5/emboss_btwisted.xml @@ -23,8 +23,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_cai.xml --- a/tools/emboss_5/emboss_cai.xml +++ b/tools/emboss_5/emboss_cai.xml @@ -184,8 +184,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_cai_custom.xml --- a/tools/emboss_5/emboss_cai_custom.xml +++ b/tools/emboss_5/emboss_cai_custom.xml @@ -26,8 +26,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_chaos.xml --- a/tools/emboss_5/emboss_chaos.xml +++ b/tools/emboss_5/emboss_chaos.xml @@ -22,8 +22,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_charge.xml --- a/tools/emboss_5/emboss_charge.xml +++ b/tools/emboss_5/emboss_charge.xml @@ -34,8 +34,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_checktrans.xml --- a/tools/emboss_5/emboss_checktrans.xml +++ b/tools/emboss_5/emboss_checktrans.xml @@ -86,8 +86,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_chips.xml --- a/tools/emboss_5/emboss_chips.xml +++ b/tools/emboss_5/emboss_chips.xml @@ -29,8 +29,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_cirdna.xml --- a/tools/emboss_5/emboss_cirdna.xml +++ b/tools/emboss_5/emboss_cirdna.xml @@ -22,8 +22,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_codcmp.xml --- a/tools/emboss_5/emboss_codcmp.xml +++ b/tools/emboss_5/emboss_codcmp.xml @@ -329,8 +329,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_coderet.xml --- a/tools/emboss_5/emboss_coderet.xml +++ b/tools/emboss_5/emboss_coderet.xml @@ -72,8 +72,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_compseq.xml --- a/tools/emboss_5/emboss_compseq.xml +++ b/tools/emboss_5/emboss_compseq.xml @@ -41,8 +41,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_cpgplot.xml --- a/tools/emboss_5/emboss_cpgplot.xml +++ b/tools/emboss_5/emboss_cpgplot.xml @@ -32,8 +32,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_cpgreport.xml --- a/tools/emboss_5/emboss_cpgreport.xml +++ b/tools/emboss_5/emboss_cpgreport.xml @@ -48,8 +48,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_cusp.xml --- a/tools/emboss_5/emboss_cusp.xml +++ b/tools/emboss_5/emboss_cusp.xml @@ -29,8 +29,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_cutseq.xml --- a/tools/emboss_5/emboss_cutseq.xml +++ b/tools/emboss_5/emboss_cutseq.xml @@ -71,8 +71,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_dan.xml --- a/tools/emboss_5/emboss_dan.xml +++ b/tools/emboss_5/emboss_dan.xml @@ -83,8 +83,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_degapseq.xml --- a/tools/emboss_5/emboss_degapseq.xml +++ b/tools/emboss_5/emboss_degapseq.xml @@ -57,8 +57,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_descseq.xml --- a/tools/emboss_5/emboss_descseq.xml +++ b/tools/emboss_5/emboss_descseq.xml @@ -71,8 +71,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_diffseq.xml --- a/tools/emboss_5/emboss_diffseq.xml +++ b/tools/emboss_5/emboss_diffseq.xml @@ -63,8 +63,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_digest.xml --- a/tools/emboss_5/emboss_digest.xml +++ b/tools/emboss_5/emboss_digest.xml @@ -64,8 +64,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_dotmatcher.xml --- a/tools/emboss_5/emboss_dotmatcher.xml +++ b/tools/emboss_5/emboss_dotmatcher.xml @@ -28,8 +28,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_dotpath.xml --- a/tools/emboss_5/emboss_dotpath.xml +++ b/tools/emboss_5/emboss_dotpath.xml @@ -35,8 +35,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_dottup.xml --- a/tools/emboss_5/emboss_dottup.xml +++ b/tools/emboss_5/emboss_dottup.xml @@ -29,8 +29,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_dreg.xml --- a/tools/emboss_5/emboss_dreg.xml +++ b/tools/emboss_5/emboss_dreg.xml @@ -21,8 +21,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_einverted.xml --- a/tools/emboss_5/emboss_einverted.xml +++ b/tools/emboss_5/emboss_einverted.xml @@ -49,8 +49,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_epestfind.xml --- a/tools/emboss_5/emboss_epestfind.xml +++ b/tools/emboss_5/emboss_epestfind.xml @@ -64,8 +64,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_equicktandem.xml --- a/tools/emboss_5/emboss_equicktandem.xml +++ b/tools/emboss_5/emboss_equicktandem.xml @@ -59,8 +59,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_est2genome.xml --- a/tools/emboss_5/emboss_est2genome.xml +++ b/tools/emboss_5/emboss_est2genome.xml @@ -102,8 +102,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_etandem.xml --- a/tools/emboss_5/emboss_etandem.xml +++ b/tools/emboss_5/emboss_etandem.xml @@ -75,8 +75,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_extractfeat.xml --- a/tools/emboss_5/emboss_extractfeat.xml +++ b/tools/emboss_5/emboss_extractfeat.xml @@ -97,6 +97,8 @@ **Citation** +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_extractseq.xml --- a/tools/emboss_5/emboss_extractseq.xml +++ b/tools/emboss_5/emboss_extractseq.xml @@ -67,8 +67,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_freak.xml --- a/tools/emboss_5/emboss_freak.xml +++ b/tools/emboss_5/emboss_freak.xml @@ -35,8 +35,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_fuzznuc.xml --- a/tools/emboss_5/emboss_fuzznuc.xml +++ b/tools/emboss_5/emboss_fuzznuc.xml @@ -74,8 +74,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_fuzzpro.xml --- a/tools/emboss_5/emboss_fuzzpro.xml +++ b/tools/emboss_5/emboss_fuzzpro.xml @@ -43,8 +43,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_fuzztran.xml --- a/tools/emboss_5/emboss_fuzztran.xml +++ b/tools/emboss_5/emboss_fuzztran.xml @@ -94,8 +94,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_garnier.xml --- a/tools/emboss_5/emboss_garnier.xml +++ b/tools/emboss_5/emboss_garnier.xml @@ -57,8 +57,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_geecee.xml --- a/tools/emboss_5/emboss_geecee.xml +++ b/tools/emboss_5/emboss_geecee.xml @@ -23,8 +23,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_getorf.xml --- a/tools/emboss_5/emboss_getorf.xml +++ b/tools/emboss_5/emboss_getorf.xml @@ -128,8 +128,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_helixturnhelix.xml --- a/tools/emboss_5/emboss_helixturnhelix.xml +++ b/tools/emboss_5/emboss_helixturnhelix.xml @@ -62,8 +62,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_hmoment.xml --- a/tools/emboss_5/emboss_hmoment.xml +++ b/tools/emboss_5/emboss_hmoment.xml @@ -31,8 +31,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_iep.xml --- a/tools/emboss_5/emboss_iep.xml +++ b/tools/emboss_5/emboss_iep.xml @@ -37,8 +37,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_infoseq.xml --- a/tools/emboss_5/emboss_infoseq.xml +++ b/tools/emboss_5/emboss_infoseq.xml @@ -75,8 +75,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_isochore.xml --- a/tools/emboss_5/emboss_isochore.xml +++ b/tools/emboss_5/emboss_isochore.xml @@ -82,6 +82,8 @@ **Citation** +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_lindna.xml --- a/tools/emboss_5/emboss_lindna.xml +++ b/tools/emboss_5/emboss_lindna.xml @@ -98,8 +98,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_marscan.xml --- a/tools/emboss_5/emboss_marscan.xml +++ b/tools/emboss_5/emboss_marscan.xml @@ -44,8 +44,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_maskfeat.xml --- a/tools/emboss_5/emboss_maskfeat.xml +++ b/tools/emboss_5/emboss_maskfeat.xml @@ -71,8 +71,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_maskseq.xml --- a/tools/emboss_5/emboss_maskseq.xml +++ b/tools/emboss_5/emboss_maskseq.xml @@ -71,8 +71,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_matcher.xml --- a/tools/emboss_5/emboss_matcher.xml +++ b/tools/emboss_5/emboss_matcher.xml @@ -56,8 +56,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_megamerger.xml --- a/tools/emboss_5/emboss_megamerger.xml +++ b/tools/emboss_5/emboss_megamerger.xml @@ -62,8 +62,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_merger.xml --- a/tools/emboss_5/emboss_merger.xml +++ b/tools/emboss_5/emboss_merger.xml @@ -75,8 +75,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_msbar.xml --- a/tools/emboss_5/emboss_msbar.xml +++ b/tools/emboss_5/emboss_msbar.xml @@ -116,8 +116,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_needle.xml --- a/tools/emboss_5/emboss_needle.xml +++ b/tools/emboss_5/emboss_needle.xml @@ -125,8 +125,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_newcpgreport.xml --- a/tools/emboss_5/emboss_newcpgreport.xml +++ b/tools/emboss_5/emboss_newcpgreport.xml @@ -43,8 +43,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_newcpgseek.xml --- a/tools/emboss_5/emboss_newcpgseek.xml +++ b/tools/emboss_5/emboss_newcpgseek.xml @@ -34,8 +34,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_newseq.xml --- a/tools/emboss_5/emboss_newseq.xml +++ b/tools/emboss_5/emboss_newseq.xml @@ -71,8 +71,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_noreturn.xml --- a/tools/emboss_5/emboss_noreturn.xml +++ b/tools/emboss_5/emboss_noreturn.xml @@ -30,8 +30,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_notseq.xml --- a/tools/emboss_5/emboss_notseq.xml +++ b/tools/emboss_5/emboss_notseq.xml @@ -68,8 +68,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_nthseq.xml --- a/tools/emboss_5/emboss_nthseq.xml +++ b/tools/emboss_5/emboss_nthseq.xml @@ -68,8 +68,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_octanol.xml --- a/tools/emboss_5/emboss_octanol.xml +++ b/tools/emboss_5/emboss_octanol.xml @@ -39,6 +39,8 @@ **Citation** +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_oddcomp.xml --- a/tools/emboss_5/emboss_oddcomp.xml +++ b/tools/emboss_5/emboss_oddcomp.xml @@ -39,8 +39,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_palindrome.xml --- a/tools/emboss_5/emboss_palindrome.xml +++ b/tools/emboss_5/emboss_palindrome.xml @@ -52,8 +52,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_pasteseq.xml --- a/tools/emboss_5/emboss_pasteseq.xml +++ b/tools/emboss_5/emboss_pasteseq.xml @@ -72,8 +72,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_patmatdb.xml --- a/tools/emboss_5/emboss_patmatdb.xml +++ b/tools/emboss_5/emboss_patmatdb.xml @@ -48,8 +48,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_pepcoil.xml --- a/tools/emboss_5/emboss_pepcoil.xml +++ b/tools/emboss_5/emboss_pepcoil.xml @@ -45,8 +45,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_pepinfo.xml --- a/tools/emboss_5/emboss_pepinfo.xml +++ b/tools/emboss_5/emboss_pepinfo.xml @@ -27,8 +27,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_pepnet.xml --- a/tools/emboss_5/emboss_pepnet.xml +++ b/tools/emboss_5/emboss_pepnet.xml @@ -32,8 +32,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_pepstats.xml --- a/tools/emboss_5/emboss_pepstats.xml +++ b/tools/emboss_5/emboss_pepstats.xml @@ -29,8 +29,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_pepwheel.xml --- a/tools/emboss_5/emboss_pepwheel.xml +++ b/tools/emboss_5/emboss_pepwheel.xml @@ -44,8 +44,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_pepwindow.xml --- a/tools/emboss_5/emboss_pepwindow.xml +++ b/tools/emboss_5/emboss_pepwindow.xml @@ -21,8 +21,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_pepwindowall.xml --- a/tools/emboss_5/emboss_pepwindowall.xml +++ b/tools/emboss_5/emboss_pepwindowall.xml @@ -21,8 +21,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_plotcon.xml --- a/tools/emboss_5/emboss_plotcon.xml +++ b/tools/emboss_5/emboss_plotcon.xml @@ -21,8 +21,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_plotorf.xml --- a/tools/emboss_5/emboss_plotorf.xml +++ b/tools/emboss_5/emboss_plotorf.xml @@ -39,8 +39,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_polydot.xml --- a/tools/emboss_5/emboss_polydot.xml +++ b/tools/emboss_5/emboss_polydot.xml @@ -47,8 +47,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_preg.xml --- a/tools/emboss_5/emboss_preg.xml +++ b/tools/emboss_5/emboss_preg.xml @@ -20,8 +20,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_prettyplot.xml --- a/tools/emboss_5/emboss_prettyplot.xml +++ b/tools/emboss_5/emboss_prettyplot.xml @@ -112,8 +112,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_prettyseq.xml --- a/tools/emboss_5/emboss_prettyseq.xml +++ b/tools/emboss_5/emboss_prettyseq.xml @@ -52,8 +52,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_primersearch.xml --- a/tools/emboss_5/emboss_primersearch.xml +++ b/tools/emboss_5/emboss_primersearch.xml @@ -32,8 +32,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_revseq.xml --- a/tools/emboss_5/emboss_revseq.xml +++ b/tools/emboss_5/emboss_revseq.xml @@ -76,8 +76,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_seqmatchall.xml --- a/tools/emboss_5/emboss_seqmatchall.xml +++ b/tools/emboss_5/emboss_seqmatchall.xml @@ -53,8 +53,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_seqret.xml --- a/tools/emboss_5/emboss_seqret.xml +++ b/tools/emboss_5/emboss_seqret.xml @@ -69,8 +69,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_showfeat.xml --- a/tools/emboss_5/emboss_showfeat.xml +++ b/tools/emboss_5/emboss_showfeat.xml @@ -122,8 +122,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_shuffleseq.xml --- a/tools/emboss_5/emboss_shuffleseq.xml +++ b/tools/emboss_5/emboss_shuffleseq.xml @@ -61,8 +61,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_sigcleave.xml --- a/tools/emboss_5/emboss_sigcleave.xml +++ b/tools/emboss_5/emboss_sigcleave.xml @@ -54,8 +54,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_sirna.xml --- a/tools/emboss_5/emboss_sirna.xml +++ b/tools/emboss_5/emboss_sirna.xml @@ -117,8 +117,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_sixpack.xml --- a/tools/emboss_5/emboss_sixpack.xml +++ b/tools/emboss_5/emboss_sixpack.xml @@ -161,8 +161,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_skipseq.xml --- a/tools/emboss_5/emboss_skipseq.xml +++ b/tools/emboss_5/emboss_skipseq.xml @@ -58,8 +58,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_splitter.xml --- a/tools/emboss_5/emboss_splitter.xml +++ b/tools/emboss_5/emboss_splitter.xml @@ -78,8 +78,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_supermatcher.xml --- a/tools/emboss_5/emboss_supermatcher.xml +++ b/tools/emboss_5/emboss_supermatcher.xml @@ -63,8 +63,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_syco.xml --- a/tools/emboss_5/emboss_syco.xml +++ b/tools/emboss_5/emboss_syco.xml @@ -196,8 +196,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_tcode.xml --- a/tools/emboss_5/emboss_tcode.xml +++ b/tools/emboss_5/emboss_tcode.xml @@ -43,8 +43,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_textsearch.xml --- a/tools/emboss_5/emboss_textsearch.xml +++ b/tools/emboss_5/emboss_textsearch.xml @@ -57,8 +57,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_tmap.xml --- a/tools/emboss_5/emboss_tmap.xml +++ b/tools/emboss_5/emboss_tmap.xml @@ -38,8 +38,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_tranalign.xml --- a/tools/emboss_5/emboss_tranalign.xml +++ b/tools/emboss_5/emboss_tranalign.xml @@ -83,8 +83,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_transeq.xml --- a/tools/emboss_5/emboss_transeq.xml +++ b/tools/emboss_5/emboss_transeq.xml @@ -121,8 +121,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_trimest.xml --- a/tools/emboss_5/emboss_trimest.xml +++ b/tools/emboss_5/emboss_trimest.xml @@ -91,8 +91,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_trimseq.xml --- a/tools/emboss_5/emboss_trimseq.xml +++ b/tools/emboss_5/emboss_trimseq.xml @@ -96,8 +96,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_twofeat.xml --- a/tools/emboss_5/emboss_twofeat.xml +++ b/tools/emboss_5/emboss_twofeat.xml @@ -129,8 +129,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> \ No newline at end of file diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_union.xml --- a/tools/emboss_5/emboss_union.xml +++ b/tools/emboss_5/emboss_union.xml @@ -64,8 +64,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_vectorstrip.xml --- a/tools/emboss_5/emboss_vectorstrip.xml +++ b/tools/emboss_5/emboss_vectorstrip.xml @@ -81,8 +81,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_water.xml --- a/tools/emboss_5/emboss_water.xml +++ b/tools/emboss_5/emboss_water.xml @@ -65,8 +65,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_wobble.xml --- a/tools/emboss_5/emboss_wobble.xml +++ b/tools/emboss_5/emboss_wobble.xml @@ -39,8 +39,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_wordcount.xml --- a/tools/emboss_5/emboss_wordcount.xml +++ b/tools/emboss_5/emboss_wordcount.xml @@ -34,8 +34,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/emboss_5/emboss_wordmatch.xml --- a/tools/emboss_5/emboss_wordmatch.xml +++ b/tools/emboss_5/emboss_wordmatch.xml @@ -73,8 +73,10 @@ ------ -**Citation** - +**Citation** + +For the underlying tool, please cite `Rice P, Longden I, Bleasby A. EMBOSS: the European Molecular Biology Open Software Suite. Trends Genet. 2000 Jun;16(6):276-7. <http://www.ncbi.nlm.nih.gov/pubmed/10827456>`_ + If you use this tool in Galaxy, please cite `Blankenberg D, Taylor J, Schenck I, He J, Zhang Y, Ghent M, Veeraraghavan N, Albert I, Miller W, Makova KD, Hardison RC, Nekrutenko A. A framework for collaborative analysis of ENCODE data: making large-scale analyses biologist-friendly. Genome Res. 2007 Jun;17(6):960-4. <http://www.ncbi.nlm.nih.gov/pubmed/17568012>`_ </help></tool> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/fastq/fastq_groomer.xml --- a/tools/fastq/fastq_groomer.xml +++ b/tools/fastq/fastq_groomer.xml @@ -16,7 +16,7 @@ <param name="input_file" type="data" format="fastq" label="File to groom" /><param name="input_type" type="select" label="Input FASTQ quality scores type"><option value="solexa">Solexa</option> - <option value="illumina">Illumina 1.3+</option> + <option value="illumina">Illumina 1.3-1.7</option><option value="sanger" selected="True">Sanger</option><option value="cssanger">Color Space Sanger</option></param> @@ -358,6 +358,10 @@ Diagram adapted from http://en.wikipedia.org/wiki/FASTQ_format +.. class:: infomark + +Output from Illumina 1.8+ pipelines are Sanger encoded. + ------ **Citation** diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/filters/secure_hash_message_digest.xml --- a/tools/filters/secure_hash_message_digest.xml +++ b/tools/filters/secure_hash_message_digest.xml @@ -35,5 +35,11 @@ This tool outputs Secure Hashes / Message Digests of a dataset using the user selected algorithms. +------ + +**Citation** + +If you use this tool in Galaxy, please cite Blankenberg D, et al. *In preparation.* + </help></tool> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/filters/wc_gnu.xml --- a/tools/filters/wc_gnu.xml +++ b/tools/filters/wc_gnu.xml @@ -62,5 +62,11 @@ #lines words characters 7499 41376 624971 +------ + +**Citation** + +If you use this tool in Galaxy, please cite Blankenberg D, et al. *In preparation.* + </help></tool> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/gatk/indel_realigner.xml --- a/tools/gatk/indel_realigner.xml +++ b/tools/gatk/indel_realigner.xml @@ -1,4 +1,4 @@ -<tool id="gatk_indel_realigner" name="Indel Realigner" version="0.0.3"> +<tool id="gatk_indel_realigner" name="Indel Realigner" version="0.0.4"><description>- perform local realignment</description><requirements><requirement type="package" version="1.2">gatk</requirement> @@ -90,7 +90,6 @@ ##start analysis specific options -d "-targetIntervals" "${target_intervals}" "${target_intervals.ext}" "gatk_target_intervals" -p ' - -targetNotSorted ##always resort input intervals --disable_bam_indexing ' #if $analysis_param_type.analysis_param_type_selector == "advanced": diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/genetrack/genetrack_indexer.xml --- a/tools/genetrack/genetrack_indexer.xml +++ b/tools/genetrack/genetrack_indexer.xml @@ -49,10 +49,14 @@ When shifting the averaging process in GeneTrack is able correct for longer or shorter than expected fragment sizes as long as the errors are reasonably random. +See http://genetrack.bx.psu.edu/ for more information on GeneTrack. + ------ **Citation** +For the underlying tool, please cite `Albert I, Wachi S, Jiang C, Pugh BF. GeneTrack--a genomic data processing and visualization framework. Bioinformatics. 2008 May 15;24(10):1305-6. <http://www.ncbi.nlm.nih.gov/pubmed/18388141>`_ + If you use this tool in Galaxy, please cite Blankenberg D, et al. *In preparation.* </help> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/genetrack/genetrack_peak_prediction.xml --- a/tools/genetrack/genetrack_peak_prediction.xml +++ b/tools/genetrack/genetrack_peak_prediction.xml @@ -54,10 +54,14 @@ - **Prediction method** the function used to average nearby values +See http://genetrack.bx.psu.edu/ for more information on GeneTrack. + ------ **Citation** +For the underlying tool, please cite `Albert I, Wachi S, Jiang C, Pugh BF. GeneTrack--a genomic data processing and visualization framework. Bioinformatics. 2008 May 15;24(10):1305-6. <http://www.ncbi.nlm.nih.gov/pubmed/18388141>`_ + If you use this tool in Galaxy, please cite Blankenberg D, et al. *In preparation.* </help> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/human_genome_variation/freebayes.xml --- a/tools/human_genome_variation/freebayes.xml +++ b/tools/human_genome_variation/freebayes.xml @@ -5,11 +5,11 @@ </requirements><description>Bayesian genetic variant detector</description><command> - ln -s $reference localref.fa; - ln -s $bamfile localbam.bam; - samtools faidx localref.fa; - samtools sort localbam.bam localbam.bam; - samtools index localbam.bam; + ln -s $reference localref.fa && + ln -s $bamfile localbam.bam && + samtools faidx localref.fa 2>&1 || echo "Error running samtools faidx for FreeBayes" >&2 && + samtools sort localbam.bam localbam.bam 2>&1 || echo "Error running samtools sort for FreeBayes" >&2 && + samtools index localbam.bam 2>&1 || echo "Error running samtools index for FreeBayes" >&2 && freebayes --fasta-reference localref.fa localbam.bam --vcf $output #if $params.source_select == "full": $params.showRefRepeats diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/ilmn_pacbio/abyss.xml --- a/tools/ilmn_pacbio/abyss.xml +++ /dev/null @@ -1,30 +0,0 @@ -<tool id="abyss" name="ABySS" version="1.0.0"> - <description>Short-read de Bruijn assembly</description> - <command interpreter="python"> - quake_wrapper.py -k $k -r $input1 -p 8 > $output1 - </command> - <inputs> - <param name="input1" format="fastq" type="data" label="Select FASTQ file to correct" /> - <param name="k" type="integer" value="16" label="Size of k-mers to correct" /> - </inputs> - <outputs> - <data format="fastq" name="output1" label="Error-corrected reads from ${on_string}" /> - </outputs> - <help> - -**What it does** - -TBD. Calls ABySS assembler - -**Parameter list** - -k - -**Output** - -Corrected reads - - </help> -</tool> - - diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/ilmn_pacbio/assembly_stats.py --- a/tools/ilmn_pacbio/assembly_stats.py +++ /dev/null @@ -1,83 +0,0 @@ -#!/usr/bin/env python -# -#Copyright (c) 2011, Pacific Biosciences of California, Inc. -# -#All rights reserved. -# -#Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -# * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -# * Neither the name of Pacific Biosciences nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. -# -#THIS SOFTWARE IS PROVIDED BY PACIFIC BIOSCIENCES AND ITS CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -#WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL PACIFIC BIOSCIENCES OR ITS CONTRIBUTORS BE LIABLE FOR ANY -#DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -#LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -#(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -import sys, os -from optparse import OptionParser -from galaxy import eggs -import pkg_resources -pkg_resources.require( 'bx-python' ) -from bx.seq.fasta import FastaReader - -def getStats( fastaFile, genomeLength, minContigLength ): - lengths = [] - stats = { "Num" : 0, - "Sum" : 0, - "Max" : 0, - "Avg" : 0, - "N50" : 0, - "99%" : 0 } - fasta_reader = FastaReader( open( fastaFile, 'rb' ) ) - while True: - seq = fasta_reader.next() - if not seq: - break - if seq.length < minContigLength: - continue - lengths.append( seq.length ) - if lengths: - stats[ 'Num' ] = len( lengths ) - stats[ 'Sum' ] = sum( lengths ) - stats[ 'Max' ] = max( lengths ) - stats[ 'Avg' ] = int( sum( lengths ) / float( len( lengths ) ) ) - stats[ 'N50' ] = 0 - stats[ '99%' ] = 0 - if genomeLength == 0: - genomeLength = sum( lengths ) - lengths.sort() - lengths.reverse() - lenSum = 0 - stats[ "99%" ] = len( lengths ) - for idx, length in enumerate( lengths ): - lenSum += length - if ( lenSum > genomeLength / 2 ): - stats[ "N50" ] = length - break - lenSum = 0 - for idx, length in enumerate( lengths ): - lenSum += length - if lenSum > genomeLength * 0.99: - stats[ "99%" ] = idx + 1 - break - return stats - -def __main__(): - #Parse Command Line - usage = 'Usage: %prog input output --minContigLength' - parser = OptionParser( usage=usage ) - parser.add_option( "--minContigLength", dest="minContigLength", help="Minimum length of contigs to analyze" ) - parser.add_option( "--genomeLength", dest="genomeLength", help="Length of genome for which to calculate N50s" ) - parser.set_defaults( minContigLength=0, genomeLength=0 ) - options, args = parser.parse_args() - input_fasta_file = args[ 0 ] - output_tabular_file = args[ 1 ] - statKeys = "Num Sum Max Avg N50 99%".split( " " ) - stats = getStats( input_fasta_file, int( options.genomeLength ), int( options.minContigLength ) ) - fout = open( output_tabular_file, "w" ) - fout.write( "%s\n" % "\t".join( map( lambda key: str( stats[ key ] ), statKeys ) ) ) - fout.close() - -if __name__=="__main__": __main__() diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/ilmn_pacbio/assembly_stats.xml --- a/tools/ilmn_pacbio/assembly_stats.xml +++ /dev/null @@ -1,54 +0,0 @@ -<tool id="assembly_stats" name="Assembly Statistics" version="1.0.0"> - <description>Calculate common measures of assembly quality</description> - <command interpreter="python"> - assembly_stats.py $input1 $output1 --minContigLength=${minLength} - </command> - <inputs> - <param name="input1" format="fasta" type="data" label="Select FASTA file containing contigs"/> - <param name="minLength" type="integer" value="0" label="Minimum length of contigs to consider"/> - </inputs> - <outputs> - <data name="output1" format="tabular" label="Assembly statistics for ${on_string}"/> - </outputs> - <tests> - <test> - <param name="input1" value="3.fasta" ftype="fasta"/> - <param name="minLength" value="100"/> - <output name="output1" ftype="tabular" file="assembly_stats.tabular" /> - </test> - </tests> - <help> - -**What it does** - -Reports standard measures of *de novo* assembly quality such as number of contigs, sum of contigs, mean contig length, and N50. - -**Parameter list** - -Minimum length - Only include contigs of this size or greater for calculating statistics. - -**Output** - -Num contigs - Total number of contigs in the assembly - -Sum of contig lengths - Total sum of contig lengths - -Maximum contig length - Maximum of the contig lengths - -Mean contig length - Average contig length - -N50 - Contig length at which 50% of the assembly is contained in contigs of this size or greater. - -99% - Number of contigs accounting for 99% of the observed assembly. - - </help> -</tool> - - diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/ilmn_pacbio/cov_model.py --- a/tools/ilmn_pacbio/cov_model.py +++ /dev/null @@ -1,238 +0,0 @@ -#!/usr/bin/env python -from optparse import OptionParser, SUPPRESS_HELP -import os, random, quake - -############################################################ -# cov_model.py -# -# Given a file of kmer counts, reports the cutoff to use -# to separate trusted/untrusted kmers. -############################################################ - -############################################################ -# main -############################################################ -def main(): - usage = 'usage: %prog [options] <counts file>' - parser = OptionParser(usage) - parser.add_option('--int', dest='count_kmers', action='store_true', default=False, help='Kmers were counted as integers w/o the use of quality values [default: %default]') - parser.add_option('--ratio', dest='ratio', type='int', default=200, help='Likelihood ratio to set trusted/untrusted cutoff [default: %default]') - parser.add_option('--no_sample', dest='no_sample', action='store_true', default=False, help='Do not sample kmer coverages into kmers.txt because its already done [default: %default]') - # help='Model kmer coverage as a function of GC content of kmers [default: %default]' - parser.add_option('--gc', dest='model_gc', action='store_true', default=False, help=SUPPRESS_HELP) - (options, args) = parser.parse_args() - - if len(args) != 1: - parser.error('Must provide kmers counts file') - else: - ctsf = args[0] - - if options.count_kmers: - model_cutoff(ctsf, options.ratio) - print 'Cutoff: %s' % open('cutoff.txt').readline().rstrip() - - else: - if options.model_gc: - model_q_gc_cutoffs(ctsf, 25000, options.ratio) - else: - model_q_cutoff(ctsf, 50000, options.ratio, options.no_sample) - print 'Cutoff: %s' % open('cutoff.txt').readline().rstrip() - - -############################################################ -# model_cutoff -# -# Make a histogram of kmers to give to R to learn the cutoff -############################################################ -def model_cutoff(ctsf, ratio): - # make kmer histogram - cov_max = 0 - for line in open(ctsf): - cov = int(line.split()[1]) - if cov > cov_max: - cov_max = cov - - kmer_hist = [0]*cov_max - for line in open(ctsf): - cov = int(line.split()[1]) - kmer_hist[cov-1] += 1 - - cov_out = open('kmers.hist', 'w') - for cov in range(0,cov_max): - if kmer_hist[cov]: - print >> cov_out, '%d\t%d' % (cov+1,kmer_hist[cov]) - cov_out.close() - - os.system('R --slave --args %d < %s/cov_model.r 2> r.log' % (ratio,quake.quake_dir)) - - -############################################################ -# model_q_cutoff -# -# Sample kmers to give to R to learn the cutoff -# 'div100' is necessary when the number of kmers is too -# large for random.sample, so we only consider every 100th -# kmer. -############################################################ -def model_q_cutoff(ctsf, sample, ratio, no_sample=False): - if not no_sample: - # count number of kmer coverages - num_covs = 0 - for line in open(ctsf): - num_covs += 1 - - # choose random kmer coverages - div100 = False - if sample >= num_covs: - rand_covs = range(num_covs) - else: - if num_covs > 1000000000: - div100 = True - rand_covs = random.sample(xrange(num_covs/100), sample) - else: - rand_covs = random.sample(xrange(num_covs), sample) - rand_covs.sort() - - # print to file - out = open('kmers.txt', 'w') - kmer_i = 0 - rand_i = 0 - for line in open(ctsf): - if div100: - if kmer_i % 100 == 0 and kmer_i/100 == rand_covs[rand_i]: - print >> out, line.split()[1] - rand_i += 1 - if rand_i >= sample: - break - else: - if kmer_i == rand_covs[rand_i]: - print >> out, line.split()[1] - rand_i += 1 - if rand_i >= sample: - break - kmer_i += 1 - out.close() - - os.system('R --slave --args %d < %s/cov_model_qmer.r 2> r.log' % (ratio,quake.quake_dir)) - - -############################################################ -# model_q_gc_cutoffs -# -# Sample kmers to give to R to learn the cutoff for each -# GC value -############################################################ -def model_q_gc_cutoffs(ctsf, sample, ratio): - # count number of kmer coverages at each at - k = len(open(ctsf).readline().split()[0]) - num_covs_at = [0]*(k+1) - for line in open(ctsf): - kmer = line.split()[0] - num_covs_at[count_at(kmer)] += 1 - - # for each AT bin - at_cutoffs = [] - for at in range(1,k): - # sample covs - if sample >= num_covs_at[at]: - rand_covs = range(num_covs_at[at]) - else: - rand_covs = random.sample(xrange(num_covs_at[at]), sample) - rand_covs.sort() - - # print to file - out = open('kmers.txt', 'w') - kmer_i = 0 - rand_i = 0 - for line in open(ctsf): - (kmer,cov) = line.split() - if count_at(kmer) == at: - if kmer_i == rand_covs[rand_i]: - print >> out, cov - rand_i += 1 - if rand_i >= sample: - break - kmer_i += 1 - out.close() - - os.system('R --slave --args %d < %s/cov_model_qmer.r 2> r%d.log' % (ratio,quake.quake_dir,at)) - - at_cutoffs.append( open('cutoff.txt').readline().rstrip() ) - if at in [1,k-1]: # setting extremes to next closests - at_cutoffs.append( open('cutoff.txt').readline().rstrip() ) - - os.system('mv kmers.txt kmers.at%d.txt' % at) - os.system('mv cutoff.txt cutoff.at%d.txt' % at) - - out = open('cutoffs.gc.txt','w') - print >> out, '\n'.join(at_cutoffs) - out.close() - - -############################################################ -# model_q_gc_cutoffs_bigmem -# -# Sample kmers to give to R to learn the cutoff for each -# GC value -############################################################ -def model_q_gc_cutoffs_bigmem(ctsf, sample, ratio): - # input coverages - k = 0 - for line in open(ctsf): - (kmer,cov) = line.split() - if k == 0: - k = len(kmer) - at_covs = ['']*(k+1) - else: - at = count_at(kmer) - if at_covs[at]: - at_covs[at].append(cov) - else: - at_covs[at] = [cov] - - for at in range(1,k): - print '%d %d' % (at,len(at_covs[at])) - - # for each AT bin - at_cutoffs = [] - for at in range(1,k): - # sample covs - if sample >= len(at_covs[at]): - rand_covs = at_covs[at] - else: - rand_covs = random.sample(at_covs[at], sample) - - # print to file - out = open('kmers.txt', 'w') - for rc in rand_covs: - print >> out, rc - out.close() - - os.system('R --slave --args %d < %s/cov_model_qmer.r 2> r%d.log' % (ratio,quake.quake_dir,at)) - - at_cutoffs.append( open('cutoff.txt').readline().rstrip() ) - if at in [1,k-1]: # setting extremes to next closests - at_cutoffs.append( open('cutoff.txt').readline().rstrip() ) - - os.system('mv kmers.txt kmers.at%d.txt' % at) - os.system('mv cutoff.txt cutoff.at%d.txt' % at) - - out = open('cutoffs.gc.txt','w') - print >> out, '\n'.join(at_cutoffs) - out.close() - - -############################################################ -# count_at -# -# Count A's and T's in the given sequence -############################################################ -def count_at(seq): - return len([nt for nt in seq if nt in ['A','T']]) - - -############################################################ -# __main__ -############################################################ -if __name__ == '__main__': - main() diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/ilmn_pacbio/quake.py --- a/tools/ilmn_pacbio/quake.py +++ /dev/null @@ -1,136 +0,0 @@ -#!/usr/bin/env python -from optparse import OptionParser, SUPPRESS_HELP -import os, random, sys -import cov_model - -############################################################ -# quake.py -# -# Launch pipeline to correct errors in Illumina sequencing -# reads. -############################################################ - -#r_dir = '/nfshomes/dakelley/research/error_correction/bin' -quake_dir = os.path.abspath(os.path.dirname(sys.argv[0])) - -############################################################ -# main -############################################################ -def main(): - usage = 'usage: %prog [options]' - parser = OptionParser(usage) - parser.add_option('-r', dest='readsf', help='Fastq file of reads') - parser.add_option('-f', dest='reads_listf', help='File containing fastq file names, one per line or two per line for paired end reads.') - parser.add_option('-k', dest='k', type='int', help='Size of k-mers to correct') - parser.add_option('-p', dest='proc', type='int', default=4, help='Number of processes [default: %default]') - parser.add_option('-q', dest='quality_scale', type='int', default=-1, help='Quality value ascii scale, generally 64 or 33. If not specified, it will guess.') - parser.add_option('--no_count', dest='no_count', action='store_true', default=False, help='Kmers are already counted and in expected file [reads file].qcts or [reads file].cts [default: %default]') - parser.add_option('--no_cut', dest='no_cut', action='store_true', default=False, help='Coverage model is optimized and cutoff was printed to expected file cutoff.txt [default: %default]') - parser.add_option('--int', dest='counted_kmers', action='store_true', default=False, help='Kmers were counted as integers w/o the use of quality values [default: %default]') - parser.add_option('--ratio', dest='ratio', type='int', default=200, help='Likelihood ratio to set trusted/untrusted cutoff. Generally set between 10-1000 with lower numbers suggesting a lower threshold. [default: %default]') - # help='Model kmer coverage as a function of GC content of kmers [default: %default]' - parser.add_option('--gc', dest='model_gc', action='store_true', default=False, help=SUPPRESS_HELP) - parser.add_option('--headers', action='store_true', default=False, help='Output original read headers (i.e. pass --headers to correct)' ) - (options, args) = parser.parse_args() - - if not options.readsf and not options.reads_listf: - parser.error('Must provide fastq file of reads with -r or file with list of fastq files of reads with -f') - if not options.k: - parser.error('Must provide k-mer size with -k') - if options.quality_scale == -1: - options.quality_scale = guess_quality_scale(options.readsf, options.reads_listf) - - if options.counted_kmers: - cts_suf = 'cts' - else: - cts_suf = 'qcts' - if options.readsf: - ctsf = '%s.%s' % (os.path.splitext( os.path.split(options.readsf)[1] )[0], cts_suf) - reads_str = '-r %s' % options.readsf - else: - ctsf = '%s.%s' % (os.path.split(options.reads_listf)[1], cts_suf) - reads_str = '-f %s' % options.reads_listf - - if not options.no_count and not options.no_cut: - count_kmers(options.readsf, options.reads_listf, options.k, ctsf, options.quality_scale) - - if not options.no_cut: - # model coverage - if options.counted_kmers: - cov_model.model_cutoff(ctsf, options.ratio) - else: - if options.model_gc: - cov_model.model_q_gc_cutoffs(ctsf, 10000, options.ratio) - else: - cov_model.model_q_cutoff(ctsf, 25000, options.ratio) - - - if options.model_gc: - # run correct C++ code - os.system('%s/correct %s -k %d -m %s -a cutoffs.gc.txt -p %d -q %d' % (quake_dir,reads_str, options.k, ctsf, options.proc, options.quality_scale)) - - else: - cutoff = open('cutoff.txt').readline().rstrip() - - # run correct C++ code - headers = '--headers' if options.headers else '' - os.system('%s/correct %s %s -k %d -m %s -c %s -p %d -q %d' % (quake_dir,headers, reads_str, options.k, ctsf, cutoff, options.proc, options.quality_scale)) - - -################################################################################ -# guess_quality_scale -# Guess at ascii scale of quality values by examining -# a bunch of reads and looking for quality values < 64, -# in which case we set it to 33. -################################################################################ -def guess_quality_scale(readsf, reads_listf): - reads_to_check = 1000 - if not readsf: - readsf = open(reads_listf).readline().split()[0] - - fqf = open(readsf) - reads_checked = 0 - header = fqf.readline() - while header and reads_checked < reads_to_check: - seq = fqf.readline() - mid = fqf.readline() - qual = fqf.readline().rstrip() - reads_checked += 1 - for q in qual: - if ord(q) < 64: - print 'Guessing quality values are on ascii 33 scale' - return 33 - header = fqf.readline() - - print 'Guessing quality values are on ascii 64 scale' - return 64 - - - -############################################################ -# count_kmers -# -# Count kmers in the reads file using AMOS count-kmers or -# count-qmers -############################################################ -def count_kmers(readsf, reads_listf, k, ctsf, quality_scale): - # find files - fq_files = [] - if readsf: - fq_files.append(readsf) - else: - for line in open(reads_listf): - for fqf in line.split(): - fq_files.append(fqf) - - if ctsf[-4:] == 'qcts': - os.system('cat %s | %s/count-qmers -k %d -q %d > %s' % (' '.join(fq_files), quake_dir, k, quality_scale, ctsf)) - else: - os.system('cat %s | %s/count-kmers -k %d > %s' % (' '.join(fq_files), quake_dir, k, ctsf)) - - -############################################################ -# __main__ -############################################################ -if __name__ == '__main__': - main() diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/ilmn_pacbio/quake.xml --- a/tools/ilmn_pacbio/quake.xml +++ /dev/null @@ -1,44 +0,0 @@ -<tool id="quake" name="Quake" version="1.0.0"> - <description>Quality-aware error correction</description> - <command interpreter="python"> - quake_wrapper.py --default_cutoff=10 --headers -k $k -f $fofnfile -p 12 > $output1 - </command> - <inputs> - <param name="input1" format="fastq" type="data" label="Select FASTQ file to correct" /> - <param name="k" type="integer" value="16" label="Size of k-mers to correct" /> - </inputs> - <configfiles> - <configfile name="fofnfile"> -${input1.file_name} - </configfile> - </configfiles> - <outputs> - <data format="fastq" name="output1" label="Error-corrected reads from ${on_string}" /> - </outputs> - <help> - -**What it does** - -Applies the Quake_ algorithm for quality-aware correction of -substitution error in short reads. - -Kelley DR, Schatz MC, Salzberg SL. -"Quake: quality-aware detection and correction of sequencing errors." -*Genome Biol.* 2010;11(11):R116. - -.. _Quake: http://www.cbcb.umd.edu/software/quake - -**Parameter list** - -k - k-mer size for detecting spurious k-mers versus true k-mers from - the genome. Recommendations for choosing a value of k can be found - here_. - -.. _here: http://www.cbcb.umd.edu/software/quake/faq.html - -**Output** - -A FASTQ file of corrected and trimmed reads. - </help> -</tool> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/ilmn_pacbio/quake_pe.xml --- a/tools/ilmn_pacbio/quake_pe.xml +++ /dev/null @@ -1,53 +0,0 @@ -<tool id="quake_pe" name="Quake PE" version="1.0.0"> - <description>Quality-aware error correction for paired-end reads</description> - <command interpreter="python"> - quake_wrapper.py --default_cutoff=$cutoff --headers -k $k -f $fofnfile -p 12 --output=$output1,$output2 - </command> - <inputs> - <param name="input1" format="fastq" type="data" label="FASTQ file for forward reads" /> - <param name="input2" format="fastq" type="data" label="FASTQ file for reverse reads" /> - <param name="k" type="integer" value="16" label="Size of k-mers to correct" /> - <param name="cutoff" type="integer" value="0" label="Default coverage cutoff if estimation fails"/> - </inputs> - <configfiles> - <configfile name="fofnfile">${input1.file_name} ${input2.file_name} - </configfile> - </configfiles> - <outputs> - <data format="fastq" name="output1" label="Error-corrected forward reads from ${on_string}" /> - <data format="fastq" name="output2" label="Error-corrected reverse reads from ${on_string}" /> - </outputs> - <help> - -**What it does** - -Applies the Quake_ algorithm for quality-aware correction of -substitution error in short reads. This form of the tool is customized -for correcting paired-end reads. - -Kelley DR, Schatz MC, Salzberg SL. -"Quake: quality-aware detection and correction of sequencing errors." -*Genome Biol.* 2010;11(11):R116. - -.. _Quake: http://www.cbcb.umd.edu/software/quake - -**Parameter list** - -K-mer size - k-mer size for detecting spurious k-mers versus true k-mers from - the genome. Recommendations for choosing a value of k can be found - here_. - -Default coverage cutoff - If the appropriate coverage cutoff can not be found then Quake can be - forced to proceed anyways with the supplied cutoff. In this case, - the optimal cutoff can be estimated by examining - the k-mer coverage histogram by eye. - -.. _here: http://www.cbcb.umd.edu/software/quake/faq.html - -**Output** - -A FASTQ file of corrected and trimmed reads. - </help> -</tool> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/ilmn_pacbio/quake_wrapper.py --- a/tools/ilmn_pacbio/quake_wrapper.py +++ /dev/null @@ -1,132 +0,0 @@ -#!/usr/bin/python -# -# Copyright (c) 2011, Pacific Biosciences of California, Inc. -# -# All rights reserved. -# -#Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -# * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. -# * Neither the name of Pacific Biosciences nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. -# -#THIS SOFTWARE IS PROVIDED BY PACIFIC BIOSCIENCES AND ITS CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -#WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL PACIFIC BIOSCIENCES OR ITS CONTRIBUTORS BE LIABLE FOR ANY -#DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -#LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -#(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -import sys -import os -import subprocess - -QUAKE_EXE = os.path.join( os.path.dirname(os.path.abspath(sys.argv[0])), 'quake.py' ) -cmdLine = sys.argv -cmdLine.pop(0) - -# -# horribly not robust, but it was a pain to rewrite everything with -# optparse -# -j = -1 -cut = 0 -for i,arg in enumerate(cmdLine): - if '--default_cutoff' in arg: - j = i - cut = int(arg.split('=')[1]) -if j>=0: - cmdLine = cmdLine[:j] + cmdLine[j+1:] - -j = -1 -output='' -for i,arg in enumerate(cmdLine): - if '--output' in arg: - j = i - output = arg.split('=')[1] -if j>=0: - cmdLine = cmdLine[:j] + cmdLine[j+1:] - -def backticks( cmd, merge_stderr=True ): - """ - Simulates the perl backticks (``) command with error-handling support - Returns ( command output as sequence of strings, error code, error message ) - """ - if merge_stderr: - _stderr = subprocess.STDOUT - else: - _stderr = subprocess.PIPE - - p = subprocess.Popen( cmd, shell=True, stdin=subprocess.PIPE, - stdout=subprocess.PIPE, stderr=_stderr, - close_fds=True ) - - out = [ l[:-1] for l in p.stdout.readlines() ] - - p.stdout.close() - if not merge_stderr: - p.stderr.close() - - # need to allow process to terminate - p.wait() - - errCode = p.returncode and p.returncode or 0 - if p.returncode>0: - errorMessage = os.linesep.join(out) - output = [] - else: - errorMessage = '' - output = out - - return output, errCode, errorMessage - -def to_stdout(): - def toCorFastq(f): - stem, ext = os.path.splitext( os.path.basename(f) ) - dir = os.path.dirname(f) - corFastq = os.path.join(dir,'%s.cor%s' % (stem,ext) ) - if not os.path.exists(corFastq): - print >>sys.stderr, "Can't find path %s" % corFastq - sys.exit(1) - return corFastq - if '-r' in cmdLine: - fastqFile = cmdLine[ cmdLine.index('-r')+1 ] - corFastq = toCorFastq(fastqFile) - infile = open( corFastq, 'r' ) - for line in infile: - sys.stdout.write( line ) - infile.close() - else: - fofnFile = cmdLine[ cmdLine.index('-f')+1 ] - infile = open(fofnFile,'r') - for line in infile: - line = line.strip() - if len(line)>0: - fastqFiles = line.split() - break - infile.close() - outs = output.split(',') - for o,f in zip(outs,fastqFiles): - cf = toCorFastq(f) - os.system( 'cp %s %s' % ( cf, o ) ) - -def run(): - cmd = '%s %s' % ( QUAKE_EXE, " ".join(cmdLine) ) - output, errCode, errMsg = backticks( cmd ) - - if errCode==0: - to_stdout() - else: - # if Quake exits with an error in cutoff determination we - # can force correction if requested - if 'cutoff.txt' in errMsg and cut>0: - outfile = open( 'cutoff.txt', 'w' ) - print >>outfile, str(cut) - outfile.close() - cmd = '%s --no_count --no_cut %s' % ( QUAKE_EXE, " ".join(cmdLine) ) - output, errCode, errMsg = backticks( cmd ) - if errCode==0: - to_stdout() - else: - print >>sys.stderr, errMsg - sys.exit(1) - -if __name__=='__main__': run() diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/ilmn_pacbio/smrtpipe.py --- a/tools/ilmn_pacbio/smrtpipe.py +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env python -# EASY-INSTALL-SCRIPT: 'pbpy==0.1','smrtpipe.py' -__requires__ = 'pbpy==0.1' -import pkg_resources -pkg_resources.run_script('pbpy==0.1', 'smrtpipe.py') diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/ilmn_pacbio/smrtpipe_filter.xml --- a/tools/ilmn_pacbio/smrtpipe_filter.xml +++ /dev/null @@ -1,67 +0,0 @@ -<tool id="smrtpipe_filter" name="SMRTpipe Filter" version="1.0.0"> - <description>Produce filtered reads from a set of PacBio primary analysis outputs.</description> - <command interpreter="python"> - smrtpipe_galaxy.py --output=data/filtered_subreads.fasta --galaxy_output=${outfile} ${iniFile} - </command> - <inputs> - <conditional name="source"> - <param name="input_source" type="select" label="Choose the source for the analysis inputs"> - <option value="path">Path to fofn or multiple bas.h5 paths</option> - <option value="history">History</option> - </param> - <when value="path"> - <repeat name="inputFiles" title="Input files"> - <param name="path" type="text" label="File path" size="75"/> - </repeat> - </when> - <when value="history"> - <param name="input1" type="data" format="tabular" label="File containing input paths" /> - </when> - </conditional> - <param name="minimum_readlength" type="integer" value="50" label="Minimum raw readlength" /> - <param name="minimum_readscore" type="float" value="0.75" label="Minimum read quality" /> - </inputs> - <configfiles> - <configfile name="iniFile"> -[input] -#if $source.input_source=="history": -#for $l in open($source.input1.file_name,'r'): -$l -#end for -#else -#for $p in $source.inputFiles -${p.path} -#end for -#end if - -[S_Filter] -filters=MinRL=${minimum_readlength},MinReadScore=${minimum_readscore} - </configfile> - </configfiles> - <outputs> - <data name="outfile" format="fasta" label="Filtered subreads" /> - </outputs> - <help> - -**What it does** - -Filters PacBio bas.h5 files and produces a FASTA file of filtered subreads. - -In PacBio SMRT sequencing, the template format is a SMRTbell: a circular -molecule with adapters at two locations in the circle. The subreads are the -portions of the read between adapters. - -**Parameter list** - -Minimum readlength - Only keep reads from ZMWs that produced this many bases or more. - -Minimum read quality - Only keep reads with overall quality scores of this value or more. The read quality score is a *de novo* prediction of the accuracy of the read. - -**Output** - -FASTA file of filtered reads. - - </help> -</tool> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/ilmn_pacbio/smrtpipe_galaxy.py --- a/tools/ilmn_pacbio/smrtpipe_galaxy.py +++ /dev/null @@ -1,265 +0,0 @@ -#!/usr/bin/python -import sys -import os -import subprocess -import optparse as op -import xml.etree.cElementTree as et - -TRACE=False -# -# Turn on tracing to dump out __input__.xml and __settings__.xml somewhere -# -#TRACE=True -#TRACE_PATH='/home/UNIXHOME/jsorenson' - -class SmrtpipeGalaxy: - """Wrapper for running smrtpipe under galaxy""" - def __init__( self, argv ): - self.__parseOptions( argv ) - - def __parseOptions( self, argv ): - usage = 'Usage: %prog [--help] [options] smrtpipe.ini' - parser = op.OptionParser( usage=usage, description=SmrtpipeGalaxy.__doc__ ) - parser.add_option( "--output", - help="Designate a file generated by smrtpipe as the expected output for galaxy" ) - parser.add_option( "--nproc", type="int", - help="Number of processes to use (-D NPROC)" ) - parser.add_option( "--galaxy_output", - help="File name provided by galaxy where output should be placed" ) - parser.add_option( "--dry_run", action="store_true", - help="Create auxiliary XML files and exit" ) - parser.add_option( "--dat_extension", - help="Soft link .dat files to have this extension (some pipelines require certain extensions)" ) - - parser.set_defaults( output=None, dry_run=False, galaxy_output=None, - dat_extension=None, nproc=0 ) - self.options, self.args = parser.parse_args( argv ) - - if len(self.args)!=2: - parser.error( 'Expected 1 argument' ) - - self.configFile = self.args[1] - - def __parseConfig( self ): - infile = open( self.configFile, 'r' ) - section = None - sections = [] - for line in infile: - l = line.strip() - if len(l)==0 or line.startswith('#'): - continue - if l.startswith('[') and l.endswith(']'): - section = section_factory( l[1:-1] ) - sections.append(section) - continue - if section is None: - continue - if '=' in l: - section.addParameterLine(l) - else: - section.addLine(l) - infile.close() - return sections - - def transferOutput( self ): - if not self.options.output or not self.options.galaxy_output: - return True, '' - if not os.path.exists(self.options.output): - return False, "Can't find file %s (job error?)" % self.options.output - os.system( 'cp %s %s' % (self.options.output, self.options.galaxy_output )) - return True, '' - - def run( self ): - if not os.path.exists( self.configFile ): - print >>sys.stderr, "Can't find config file %s" % self.configFile - return 1 - - sections = self.__parseConfig() - - if len(sections)==0: - print >>sys.stderr, "No sections found in %s" % self.configFile - return 1 - if sections[0].name != 'input': - print >>sys.stderr, "No [input] section found in %s" % self.configFile - return 1 - - INPUT_FILE = '__input__.xml' - SETTINGS_FILE = '__settings__.xml' - - sections[0].softLinkDats( self.options.dat_extension ) - inputXml = sections[0].makeXmlElement() - write_xml_to_file( INPUT_FILE, inputXml ) - if TRACE: - write_xml_to_file( os.path.join(TRACE_PATH,INPUT_FILE), inputXml ) - - settings = et.Element( 'smrtpipeSettings' ) - for s in sections[1:]: - s.makeXmlElement( settings ) - - write_xml_to_file( SETTINGS_FILE, settings ) - if TRACE: - write_xml_to_file( os.path.join(TRACE_PATH,SETTINGS_FILE), settings ) - - nproc = '-D NPROC=%d' % self.options.nproc if self.options.nproc>0 else '' - cmd = 'smrtpipe.py %s --params=%s xml:%s > smrtpipe.err 2>1' % \ - ( nproc, SETTINGS_FILE, INPUT_FILE ) - - if self.options.dry_run: - print 'Command to run:' - print cmd - return 0 - - out, errCode, errMsg = backticks( cmd ) - if errCode!=0: - print >>sys.stderr, "error while running: %s" % cmd - print >>sys.stderr, errMsg - if os.path.exists('log/smrtpipe.log'): - print >>sys.stderr, 'Log:' - infile = open('log/smrtpipe.log','r') - for line in infile: sys.stderr.write(line) - infile.close() - return errCode - - success, errMsg = self.transferOutput() - if not success: - print >>sys.stderr, errMsg - return 1 - - return 0 - -def write_xml_to_file( fileName, root ): - outfile = open( fileName, 'w' ) - outfile.write( '<?xml version="1.0"?>\n' ) - outfile.write( et.tostring(root) + '\n' ) - outfile.close() - -def section_factory( name ): - if name=='input': - return InputSection(name) - else: - return Section(name) - -class Section: - def __init__( self, name ): - self._name = name - self._lines = [] - self._vars = {} - - @property - def name(self): - return self._name - - def addLine( self, line ): - self._lines.append(line) - - def addParameterLine( self, line ): - self.addLine(line) - i = line.find( '=' ) - key = line[:i].strip() - value = line[i+1:].strip() - self._vars[key] = value - - def makeXmlElement( self, settings ): - if self._name=='global': - root = et.SubElement( settings, "protocol", {'name':'generic'} ) - else: - root = et.SubElement( settings, "module", {'name':self._name} ) - for k,v in self._vars.iteritems(): - param = et.SubElement( root, 'param', {'name':k} ) - val = et.SubElement( param, 'value' ) - val.text = v - return None - - def __str__( self ): - "for debugging" - buffer = [ 'S { name=' ] - buffer.append(self._name) - buffer.append('; lines=%s' % ','.join(self._lines) ) - for k,v in self._vars.iteritems(): - buffer.append('; %s=%s' % (k,v) ) - buffer.append(' }') - return ''.join(buffer) - -class InputSection( Section ): - def __init__( self, name ): - Section.__init__(self,name) - - def softLinkDats( self, newExtension ): - if not newExtension: - return - newLines = [] - for l in self._lines: - if ':' in l: - protocol = l[:l.find(':')+1] - file = l[l.find(':')+1:] - else: - protocol = '' - file = l - if os.path.exists(file) and file.endswith('.dat'): - newFile = '%s.%s' % ( file, newExtension ) - if not os.path.exists(newFile): - os.system( 'ln -s %s %s' % ( file, newFile ) ) - newLines.append(protocol+newFile) - else: - newLines.append(l) - self._lines = newLines - - def makeXmlElement( self, parent=None ): - root = et.Element( "pacbioAnalysisInputs" ) - data = et.SubElement( root, 'dataReferences' ) - iRef = 0 - for l in self._lines: - def add(x,iRef): - if len(x)==0: return iRef - node = et.SubElement( data, 'url' ) - if ':' in x: - node.attrib[ 'ref' ] = x - else: - node.attrib[ 'ref' ] = 'run:0000000-%04d' % iRef - node2 = et.SubElement( node, 'location' ) - node2.text = x - return iRef+1 - if l.endswith('fofn') and os.path.exists(l): - infile = open(l,'r') - for j,line in enumerate(infile): iRef=add(line.strip(),iRef) - infile.close() - else: - iRef=add(l,iRef) - return root - -def backticks( cmd, merge_stderr=True ): - """ - Simulates the perl backticks (``) command with error-handling support - Returns ( command output as sequence of strings, error code, error message ) - """ - if merge_stderr: - _stderr = subprocess.STDOUT - else: - _stderr = subprocess.PIPE - - p = subprocess.Popen( cmd, shell=True, stdin=subprocess.PIPE, - stdout=subprocess.PIPE, stderr=_stderr, - close_fds=True ) - - out = [ l[:-1] for l in p.stdout.readlines() ] - - p.stdout.close() - if not merge_stderr: - p.stderr.close() - - # need to allow process to terminate - p.wait() - - errCode = p.returncode and p.returncode or 0 - if p.returncode>0: - errorMessage = os.linesep.join(out) - output = [] - else: - errorMessage = '' - output = out - - return output, errCode, errorMessage - -if __name__=='__main__': - app = SmrtpipeGalaxy( sys.argv ) - sys.exit( app.run() ) diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/ilmn_pacbio/smrtpipe_hybrid.xml --- a/tools/ilmn_pacbio/smrtpipe_hybrid.xml +++ /dev/null @@ -1,59 +0,0 @@ -<tool id="smrtpipe_hybrid" name="AHA" version="1.0.0"> - <description>Assemble contigs from a set of contigs and PacBio reads.</description> - <command interpreter="python"> - smrtpipe_galaxy.py --nproc=24 --dat_extension=fasta --output=data/scaffold.fasta --galaxy_output=${outfile} ${iniFile} - </command> - <!-- - <command>cp ${iniFile} ${outfile}</command> - --> - <inputs> - <param name="contigs" format="fasta" type="data" label="Starting Contigs"/> - <param name="reads" format="fasta" type="data" label="PacBio Reads"/> - <param name="schedule" type="text" value="6,3,75;6,3,75;5,3,75;5,3,75;6,2,75;6,2,75;5,2,75;5,2,75" label="Parameter Schedule" size="60"/> - </inputs> - <configfiles> - <configfile name="iniFile"> -[input] -assembled_contigs:${contigs} -file:${reads} - -[HybridAssembly] -instrumentModel=RS -cleanup=False -untangler=pacbio -#set $schedule2 = $schedule.replace('X',';') -paramSchedule=${schedule2} -dontFillin=False -longReadsAsStrobe=True -exactQueryIds=True -rm4Opts=-minMatch 7 -minFrac 0.1 -minPctIdentity 65 -bestn 10 -noSplitSubreads -numberProcesses=16 -cluster=False -minRepeatLength=100000 - </configfile> - </configfiles> - <outputs> - <data name="outfile" format="fasta" label="Hybrid assembly contigs from ${on_string}"/> - </outputs> - <help> - -**What it does** - -The AHA assembly algorithm is an AMOS_-based pipeline -for finishing bacterial-sized -genomes using draft contigs and PacBio reads. - -.. _AMOS: http://sourceforge.net/apps/mediawiki/amos - -**Parameter list** - -Parameter schedule - The parameter schedule is a semi-colon delimited list of triples. Each triple represents an iteration of hybrid assembly (alignment/scaffolding/gap-filling). The three paremeters for each iteration are the Z-score, number of reads required to define a link, and the minimum length of subreads used in links. - -**Output** - -FASTA file containing scaffolded and gap-filled contigs resulting from the -hybrid assembly. - - </help> -</tool> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/ilmn_pacbio/soap_denovo.xml --- a/tools/ilmn_pacbio/soap_denovo.xml +++ /dev/null @@ -1,73 +0,0 @@ -<tool id="soap_denovo" name="SOAPdenovo" version="1.0.0"> - <description>Short-read de novo assembly</description> - <!-- - # SOAPdenovo-127mer all -s ${soap_config} -o assembly -K ${k} -p 8 -d -D - # cat ${soap_config} > ${output1} - # cp ${soap_config} ${output1} && - --> - <command> - SOAPdenovo-127mer all -s ${soap_config} -o assembly -K ${k} -p 24 -d -D -R - </command> - <inputs> - <conditional name="inputs"> - <param name="read_type" type="select" label="Illumina read type"> - <option value="single">Single fragment</option> - <option value="paired">Paired-end</option> - </param> - <when value="single"> - <param name="input1" format="fastq" type="data" label="FASTQ file for reads"/> - </when> - <when value="paired"> - <param name="input1" format="fastq" type="data" label="FASTQ file for forward reads"/> - <param name="input2" format="fastq" type="data" label="FASTQ file for reverse reads"/> - <param name="d" type="integer" value="500" label="Estimated insert size for paired-end reads" /> - </when> - </conditional> - <param name="k" type="integer" value="23" label="Size of k for forming the de Bruijn overlap graph" /> - </inputs> - <configfiles> - <configfile name="soap_config">max_rd_len=105 -[LIB] -#if $inputs.read_type == "single" -q=${inputs.input1.file_name} -#else -avg_ins=${inputs.d} -asm_flags=3 -reverse_seq=0 -q1=${inputs.input1.file_name} -q2=${inputs.input2.file_name} -#end if - </configfile> - </configfiles> - <outputs> - <data name="assembled_contigs" format="fasta" from_work_dir="assembly.scafSeq" label="Assembled contigs from ${on_string}" /> - </outputs> - <help> - -**What it does** - -Runs SOAPdenovo_ to generate a genome assembly -using single-fragment or paired-end short reads. - -Li R, Zhu H, Ruan J, Qian W, Fang X, Shi Z, Li Y, Li S, Shan G, Kristiansen K, Li S, Yang H, Wang J, Wang J. -"De novo assembly of human genomes with massively parallel short read sequencing." -*Genome Res.* 2010 Feb;20(2):265-72. - -.. _SOAPdenovo: http://soap.genomics.org.cn/soapdenovo.html - -**Parameter list** - -k - k-mer size for constructing the de Bruijn graph. The appropriate size of k is genome and data set dependent, but a good starting choice might be 75% of the read length. - -Insert size - For paired-end libraries, the expected insert size. - -**Output** - -assembly - - </help> -</tool> - - diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/peak_calling/ccat_wrapper.xml --- a/tools/peak_calling/ccat_wrapper.xml +++ b/tools/peak_calling/ccat_wrapper.xml @@ -112,7 +112,7 @@ <output name="output_top_file" file="peakcalling_ccat/3.0/ccat_test_top_out_1.interval.sorted.re_match" compare="re_match" sort="true" /><output name="output_log_file" file="peakcalling_ccat/3.0/ccat_test_log_out_1.txt" /></test> - <!-- Test below gives different results on different architectures, + <!-- Test below gives different answers on different architectures, e.g.: x86_64 GNU/Linux gave an extra line (additional peak called) when compared to the version running on 10.6.0 Darwin i386 slidingWinSize was fixed to be 1000, default as per readme.txt --> @@ -140,6 +140,8 @@ **Citation** +For the underlying tool, please cite `Xu H, Handoko L, Wei X, Ye C, Sheng J, Wei CL, Lin F, Sung WK. A signal-noise model for significance analysis of ChIP-seq with negative control. Bioinformatics. 2010 May 1;26(9):1199-204. <http://www.ncbi.nlm.nih.gov/pubmed/20371496>`_ + If you use this tool in Galaxy, please cite Blankenberg D, et al. *In preparation.* </help> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/peak_calling/macs_wrapper.xml --- a/tools/peak_calling/macs_wrapper.xml +++ b/tools/peak_calling/macs_wrapper.xml @@ -231,6 +231,8 @@ **Citation** +For the underlying tool, please cite `Zhang Y, Liu T, Meyer CA, Eeckhoute J, Johnson DS, Bernstein BE, Nusbaum C, Myers RM, Brown M, Li W, Liu XS. Model-based analysis of ChIP-Seq (MACS). Genome Biol. 2008;9(9):R137. <http://www.ncbi.nlm.nih.gov/pubmed/18798982>`_ + If you use this tool in Galaxy, please cite Blankenberg D, et al. *In preparation.* </help> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/picard/picard_AddOrReplaceReadGroups.xml --- a/tools/picard/picard_AddOrReplaceReadGroups.xml +++ b/tools/picard/picard_AddOrReplaceReadGroups.xml @@ -1,4 +1,4 @@ -<tool name="Add or Replace Groups" id="picard_ARRG" version="0.2.1"> +<tool name="Add or Replace Groups" id="picard_ARRG" version="1.56.0"><requirements><requirement type="package">picard</requirement></requirements><command interpreter="python"> picard_wrapper.py diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/picard/picard_BamIndexStats.xml --- a/tools/picard/picard_BamIndexStats.xml +++ b/tools/picard/picard_BamIndexStats.xml @@ -1,4 +1,4 @@ -<tool name="BAM Index Statistics" id="picard_BamIndexStats" version="0.2.1"> +<tool name="BAM Index Statistics" id="picard_BamIndexStats" version="1.56.0"><requirements><requirement type="package">picard</requirement></requirements><command interpreter="python"> picard_wrapper.py diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/picard/picard_FastqToSam.xml --- a/tools/picard/picard_FastqToSam.xml +++ b/tools/picard/picard_FastqToSam.xml @@ -1,4 +1,4 @@ -<tool id="picard_FastqToSam" name="FASTQ to BAM" version="0.0.1"> +<tool id="picard_FastqToSam" name="FASTQ to BAM" version="1.56.0"><description>creates an unaligned BAM file</description><requirements><requirement type="package">picard</requirement></requirements><command>java -XX:DefaultMaxRAMFraction=1 -XX:+UseParallelGC diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/picard/picard_MarkDuplicates.xml --- a/tools/picard/picard_MarkDuplicates.xml +++ b/tools/picard/picard_MarkDuplicates.xml @@ -1,4 +1,4 @@ -<tool name="Mark Duplicates" id="picard_MarkDuplicates" version="0.01.1"> +<tool name="Mark Duplicates" id="picard_MarkDuplicates" version="1.56.0"><command interpreter="python"> picard_wrapper.py --input="$input_file" diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/picard/picard_ReorderSam.xml --- a/tools/picard/picard_ReorderSam.xml +++ b/tools/picard/picard_ReorderSam.xml @@ -1,4 +1,4 @@ -<tool name="Reorder SAM/BAM" id="picard_ReorderSam" version="0.3.1"> +<tool name="Reorder SAM/BAM" id="picard_ReorderSam" version="1.56.0"><requirements><requirement type="package">picard</requirement></requirements><command interpreter="python"> picard_wrapper.py diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/picard/picard_ReplaceSamHeader.xml --- a/tools/picard/picard_ReplaceSamHeader.xml +++ b/tools/picard/picard_ReplaceSamHeader.xml @@ -1,4 +1,4 @@ -<tool name="Replace SAM/BAM Header" id="picard_ReplaceSamHeader" version="0.2.1"> +<tool name="Replace SAM/BAM Header" id="picard_ReplaceSamHeader" version="1.56.0"><requirements><requirement type="package">picard</requirement></requirements><command interpreter="python"> picard_wrapper.py diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/picard/picard_SamToFastq.xml --- a/tools/picard/picard_SamToFastq.xml +++ b/tools/picard/picard_SamToFastq.xml @@ -1,4 +1,4 @@ -<tool id="picard_SamToFastq" name="SAM to FASTQ" version="0.0.1"> +<tool id="picard_SamToFastq" name="SAM to FASTQ" version="1.56.0"><description>creates a FASTQ file</description><requirements><requirement type="package">picard</requirement></requirements><command>java -XX:DefaultMaxRAMFraction=1 -XX:+UseParallelGC diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/picard/picard_wrapper.py --- a/tools/picard/picard_wrapper.py +++ b/tools/picard/picard_wrapper.py @@ -102,7 +102,7 @@ pass tmp.close() except Exception, e: - stop_err( 'Error : %s' % str( e ) ) + stop_err( 'Read Large Exception : %s' % str( e ) ) return s def runCL(self,cl=None,output_dir=None): @@ -125,14 +125,15 @@ tef.close() stderrs = self.readLarge(temperr) stdouts = self.readLarge(templog) - if len(stderrs) > 0: + if rval > 0: s = '## executing %s returned status %d and stderr: \n%s\n' % (cl,rval,stderrs) + stdouts = '%s\n%s' % (stdouts,stderrs) else: s = '## executing %s returned status %d and nothing on stderr\n' % (cl,rval) logging.info(s) os.unlink(templog) # always os.unlink(temperr) # always - return s, stdouts # sometimes this is an output + return s, stdouts, rval # sometimes s is an output def runPic(self, jar, cl): """ @@ -141,8 +142,8 @@ runme = ['java -Xmx%s' % self.opts.maxjheap] runme.append('-jar %s' % jar) runme += cl - s,stdout = self.runCL(cl=runme, output_dir=self.opts.outdir) - return stdout + s,stdouts,rval = self.runCL(cl=runme, output_dir=self.opts.outdir) + return stdouts,rval def samToBam(self,infile=None,outdir=None): """ @@ -150,24 +151,15 @@ """ fd,tempbam = tempfile.mkstemp(dir=outdir,suffix='rgutilsTemp.bam') cl = ['samtools view -h -b -S -o ',tempbam,infile] - tlog,stdouts = self.runCL(cl,outdir) - return tlog,tempbam - - #def bamToSam(self,infile=None,outdir=None): - # """ - # use samtools view to convert bam to sam - # """ - # fd,tempsam = tempfile.mkstemp(dir=outdir,suffix='rgutilsTemp.sam') - # cl = ['samtools view -h -o ',tempsam,infile] - # tlog,stdouts = self.runCL(cl,outdir) - # return tlog,tempsam + tlog,stdouts,rval = self.runCL(cl,outdir) + return tlog,tempbam,rval def sortSam(self, infile=None,outfile=None,outdir=None): """ """ print '## sortSam got infile=%s,outfile=%s,outdir=%s' % (infile,outfile,outdir) cl = ['samtools sort',infile,outfile] - tlog,stdouts = self.runCL(cl,outdir) + tlog,stdouts,rval = self.runCL(cl,outdir) return tlog def cleanup(self): @@ -242,7 +234,11 @@ pdflist = [x for x in flist if os.path.splitext(x)[-1].lower() == '.pdf'] if len(pdflist) > 0: # assumes all pdfs come with thumbnail .jpgs for p in pdflist: - imghref = '%s.jpg' % os.path.splitext(p)[0] # removes .pdf + pbase = os.path.splitext(p)[0] # removes .pdf + imghref = '%s.jpg' % pbase + mimghref = '%s-0.jpg' % pbase # multiple pages pdf -> multiple thumbnails without asking! + if mimghref in flist: + imghref=mimghref # only one for thumbnail...it's a multi page pdf res.append('<table cellpadding="10"><tr><td>\n') res.append('<a href="%s"><img src="%s" title="Click image preview for a print quality PDF version" hspace="10" align="middle"></a>\n' % (p,imghref)) res.append('</tr></td></table>\n') @@ -383,9 +379,11 @@ op.add_option('', '--taillimit', default="0") op.add_option('', '--histwidth', default="0") op.add_option('', '--minpct', default="0.01") + op.add_option('', '--malevel', default='') + op.add_option('', '--deviations', default="0.0") # CollectAlignmentSummaryMetrics op.add_option('', '--maxinsert', default="20") - op.add_option('', '--adaptors', action='append', type="string") + op.add_option('', '--adaptors', default='') # FixMateInformation and validate # CollectGcBiasMetrics op.add_option('', '--windowsize', default='100') @@ -430,7 +428,8 @@ tmp_dir = opts.outdir haveTempout = False # we use this where sam output is an option - + rval = 0 + stdouts = 'Not run yet' # set ref and dict files to use (create if necessary) ref_file_name = opts.ref if opts.ref_file <> None: @@ -453,7 +452,7 @@ pic.delme.append(dict_file_name) pic.delme.append(ref_file_name) pic.delme.append(tmp_ref_name) - s = pic.runPic(jarpath, cl) + stdouts,rval = pic.runPic(jarpath, cl) # run relevant command(s) # define temporary output @@ -486,7 +485,7 @@ cl.append('RGCN="%s"' % opts.rg_seq_center) if opts.rg_desc: cl.append('RGDS="%s"' % opts.rg_desc) - pic.runPic(opts.jar, cl) + stdouts,rval = pic.runPic(opts.jar, cl) haveTempout = True elif pic.picname == 'BamIndexStats': @@ -499,9 +498,9 @@ pic.delme.append(tmp_bam_name) pic.delme.append(tmp_bai_name) pic.delme.append(tmp_name) - s = pic.runPic( opts.jar, cl ) + stdouts,rval = pic.runPic( opts.jar, cl ) f = open(pic.metricsOut,'a') - f.write(s) # got this on stdout from runCl + f.write(stdouts) # got this on stdout from runCl f.write('\n') f.close() doTranspose = False # but not transposed @@ -519,35 +518,48 @@ cl.append('READ_NAME_REGEX="%s"' % opts.readregex) if float(opts.optdupdist) > 0: cl.append('OPTICAL_DUPLICATE_PIXEL_DISTANCE=%s' % opts.optdupdist) - pic.runPic(opts.jar,cl) + stdouts,rval = pic.runPic(opts.jar, cl) elif pic.picname == 'CollectAlignmentSummaryMetrics': - # Why do we do this fakefasta thing? Because we need NO fai to be available or picard barfs unless it has the same length as the input data. + # Why do we do this fakefasta thing? + # Because we need NO fai to be available or picard barfs unless it matches the input data. # why? Dunno Seems to work without complaining if the .bai file is AWOL.... fakefasta = os.path.join(opts.outdir,'%s_fake.fasta' % os.path.basename(ref_file_name)) try: os.symlink(ref_file_name,fakefasta) except: - s = '## unable to symlink %s to %s - different devices? May need to replace with shutil.copy' + s = '## unable to symlink %s to %s - different devices? Will shutil.copy' info = s shutil.copy(ref_file_name,fakefasta) pic.delme.append(fakefasta) - cl.append('ASSUME_SORTED=%s' % opts.assumesorted) - adaptorseqs = ''.join([' ADAPTER_SEQUENCE=%s' % x for x in opts.adaptors]) - cl.append(adaptorseqs) + cl.append('ASSUME_SORTED=true') + adaptlist = opts.adaptors.split(',') + adaptorseqs = ['ADAPTER_SEQUENCE=%s' % x for x in adaptlist] + cl += adaptorseqs cl.append('IS_BISULFITE_SEQUENCED=%s' % opts.bisulphite) cl.append('MAX_INSERT_SIZE=%s' % opts.maxinsert) cl.append('OUTPUT=%s' % pic.metricsOut) cl.append('R=%s' % fakefasta) cl.append('TMP_DIR=%s' % opts.tmpdir) if not opts.assumesorted.lower() == 'true': # we need to sort input - fakeinput = '%s.sorted' % opts.input - s = pic.sortSam(opts.input, fakeinput, opts.outdir) - pic.delme.append(fakeinput) - cl.append('INPUT=%s' % fakeinput) + sortedfile = '%s.sorted' % os.path.basename(opts.input) + if opts.datatype == 'sam': # need to work with a bam + tlog,tempbam,trval = pic.samToBam(opts.input,opts.outdir) + pic.delme.append(tempbam) + try: + tlog = pic.sortSam(tempbam,sortedfile,opts.outdir) + except: + print '## exception on sorting sam file %s' % opts.input + else: # is already bam + try: + tlog = pic.sortSam(opts.input,sortedfile,opts.outdir) + except : # bug - [bam_sort_core] not being ignored - TODO fixme + print '## exception %s on sorting bam file %s' % (sys.exc_info()[0],opts.input) + cl.append('INPUT=%s.bam' % os.path.abspath(os.path.join(opts.outdir,sortedfile))) + pic.delme.append(os.path.join(opts.outdir,sortedfile)) else: cl.append('INPUT=%s' % os.path.abspath(opts.input)) - pic.runPic(opts.jar,cl) + stdouts,rval = pic.runPic(opts.jar, cl) elif pic.picname == 'CollectGcBiasMetrics': @@ -575,10 +587,10 @@ cl.append('TMP_DIR=%s' % opts.tmpdir) cl.append('CHART_OUTPUT=%s' % temppdf) cl.append('SUMMARY_OUTPUT=%s' % pic.metricsOut) - pic.runPic(opts.jar,cl) + stdouts,rval = pic.runPic(opts.jar, cl) if os.path.isfile(temppdf): cl2 = ['convert','-resize x400',temppdf,os.path.join(opts.outdir,jpgname)] # make the jpg for fixPicardOutputs to find - s,stdouts = pic.runCL(cl=cl2,output_dir=opts.outdir) + s,stdouts,rval = pic.runCL(cl=cl2,output_dir=opts.outdir) else: s='### runGC: Unable to find pdf %s - please check the log for the causal problem\n' % temppdf lf = open(pic.log_filename,'a') @@ -587,29 +599,40 @@ lf.close() elif pic.picname == 'CollectInsertSizeMetrics': + """ <command interpreter="python"> + picard_wrapper.py -i "$input_file" -n "$out_prefix" --tmpdir "${__new_file_path__}" --deviations "$deviations" + --histwidth "$histWidth" --minpct "$minPct" --malevel "$malevel" + -j "${GALAXY_DATA_INDEX_DIR}/shared/jars/picard/CollectInsertSizeMetrics.jar" -d "$html_file.files_path" -t "$html_file" + </command> + """ isPDF = 'InsertSizeHist.pdf' pdfpath = os.path.join(opts.outdir,isPDF) histpdf = 'InsertSizeHist.pdf' cl.append('I=%s' % opts.input) cl.append('O=%s' % pic.metricsOut) cl.append('HISTOGRAM_FILE=%s' % histpdf) - if opts.taillimit <> '0': - cl.append('TAIL_LIMIT=%s' % opts.taillimit) + #if opts.taillimit <> '0': # this was deprecated although still mentioned in the docs at 1.56 + # cl.append('TAIL_LIMIT=%s' % opts.taillimit) if opts.histwidth <> '0': cl.append('HISTOGRAM_WIDTH=%s' % opts.histwidth) if float( opts.minpct) > 0.0: cl.append('MINIMUM_PCT=%s' % opts.minpct) - pic.runPic(opts.jar,cl) + if float(opts.deviations) > 0.0: + cl.append('DEVIATIONS=%s' % opts.deviations) + if opts.malevel: + malists = opts.malevel.split(',') + malist = ['METRIC_ACCUMULATION_LEVEL=%s' % x for x in malists] + cl += malist + stdouts,rval = pic.runPic(opts.jar, cl) if os.path.exists(pdfpath): # automake thumbnail - will be added to html cl2 = ['mogrify', '-format jpg -resize x400 %s' % pdfpath] - s,stdouts = pic.runCL(cl=cl2,output_dir=opts.outdir) + pic.runCL(cl=cl2,output_dir=opts.outdir) else: s = 'Unable to find expected pdf file %s<br/>\n' % pdfpath s += 'This <b>always happens if single ended data was provided</b> to this tool,\n' s += 'so please double check that your input data really is paired-end NGS data.<br/>\n' s += 'If your input was paired data this may be a bug worth reporting to the galaxy-bugs list\n<br/>' - stdouts = '' - logging.info(s) + logging.info(s) if len(stdouts) > 0: logging.info(stdouts) @@ -627,13 +650,13 @@ cl.append('READ_NAME_REGEX="%s"' % opts.readregex) # maximum offset between two duplicate clusters cl.append('OPTICAL_DUPLICATE_PIXEL_DISTANCE=%s' % opts.optdupdist) - pic.runPic(opts.jar, cl) + stdouts,rval = pic.runPic(opts.jar, cl) elif pic.picname == 'FixMateInformation': cl.append('I=%s' % opts.input) cl.append('O=%s' % tempout) cl.append('SORT_ORDER=%s' % opts.sortorder) - pic.runPic(opts.jar,cl) + stdouts,rval = pic.runPic(opts.jar,cl) haveTempout = True elif pic.picname == 'ReorderSam': @@ -649,14 +672,14 @@ # contig length discordance if opts.allow_contig_len_discord == 'true': cl.append('ALLOW_CONTIG_LENGTH_DISCORDANCE=true') - pic.runPic(opts.jar, cl) + stdouts,rval = pic.runPic(opts.jar, cl) haveTempout = True elif pic.picname == 'ReplaceSamHeader': cl.append('INPUT=%s' % opts.input) cl.append('OUTPUT=%s' % tempout) cl.append('HEADER=%s' % opts.header_file) - pic.runPic(opts.jar, cl) + stdouts,rval = pic.runPic(opts.jar, cl) haveTempout = True elif pic.picname == 'CalculateHsMetrics': @@ -673,7 +696,7 @@ cl.append('INPUT=%s' % os.path.abspath(opts.input)) cl.append('OUTPUT=%s' % pic.metricsOut) cl.append('TMP_DIR=%s' % opts.tmpdir) - pic.runPic(opts.jar,cl) + stdouts,rval = pic.runPic(opts.jar,cl) elif pic.picname == 'ValidateSamFile': import pysam @@ -682,7 +705,7 @@ stf = open(pic.log_filename,'w') tlog = None if opts.datatype == 'sam': # need to work with a bam - tlog,tempbam = pic.samToBam(opts.input,opts.outdir) + tlog,tempbam,rval = pic.samToBam(opts.input,opts.outdir) try: tlog = pic.sortSam(tempbam,sortedfile,opts.outdir) except: @@ -709,7 +732,7 @@ cl.append('IS_BISULFITE_SEQUENCED=true') if opts.ref <> None or opts.ref_file <> None: cl.append('R=%s' % ref_file_name) - pic.runPic(opts.jar,cl) + stdouts,rval = pic.runPic(opts.jar,cl) if opts.datatype == 'sam': pic.delme.append(tempbam) newsam = opts.output @@ -725,10 +748,12 @@ if haveTempout: # Some Picard tools produced a potentially intermediate bam file. # Either just move to final location or create sam - shutil.move(tempout, os.path.abspath(opts.output)) - + if os.path.exists(tempout): + shutil.move(tempout, os.path.abspath(opts.output)) if opts.htmlout <> None or doFix: # return a pretty html page pic.fixPicardOutputs(transpose=doTranspose,maxloglines=maxloglines) - + if rval <> 0: + print >> sys.stderr, '## exit code=%d; stdout=%s' % (rval,stdouts) + # signal failure if __name__=="__main__": __main__() diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/picard/rgPicardASMetrics.xml --- a/tools/picard/rgPicardASMetrics.xml +++ b/tools/picard/rgPicardASMetrics.xml @@ -1,7 +1,7 @@ -<tool name="SAM/BAM Alignment Summary Metrics" id="PicardASMetrics" version="0.03.1"> +<tool name="SAM/BAM Alignment Summary Metrics" id="PicardASMetrics" version="1.56.0"><command interpreter="python"> picard_wrapper.py -i "$input_file" -d "$html_file.files_path" -t "$html_file" - --assumesorted "$sorted" -b "$bisulphite" --adaptors "$adaptors" --maxinsert "$maxinsert" -n "$out_prefix" + --assumesorted "$sorted" -b "$bisulphite" --adaptors "$adaptors" --maxinsert "$maxinsert" -n "$out_prefix" --datatype "$input_file.ext" -j ${GALAXY_DATA_INDEX_DIR}/shared/jars/picard/CollectAlignmentSummaryMetrics.jar #if $genomeSource.refGenomeSource == "history": --ref-file "$genomeSource.ownFile" diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/picard/rgPicardFixMate.xml --- a/tools/picard/rgPicardFixMate.xml +++ b/tools/picard/rgPicardFixMate.xml @@ -1,4 +1,4 @@ -<tool name="Paired Read Mate Fixer" id="rgPicFixMate" version="0.2.1"> +<tool name="Paired Read Mate Fixer" id="rgPicFixMate" version="1.56.0"><description>for paired data</description><command interpreter="python"> picard_wrapper.py -i "$input_file" -o "$out_file" --tmpdir "${__new_file_path__}" -n "$out_prefix" diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/picard/rgPicardGCBiasMetrics.xml --- a/tools/picard/rgPicardGCBiasMetrics.xml +++ b/tools/picard/rgPicardGCBiasMetrics.xml @@ -1,4 +1,4 @@ -<tool name="SAM/BAM GC Bias Metrics" id="PicardGCBiasMetrics" version="0.02.1"> +<tool name="SAM/BAM GC Bias Metrics" id="PicardGCBiasMetrics" version="1.56.0"><command interpreter="python"> picard_wrapper.py -i "$input_file" -d "$html_file.files_path" -t "$html_file" --windowsize "$windowsize" --mingenomefrac "$mingenomefrac" -n "$out_prefix" --tmpdir "${__new_file_path__}" diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/picard/rgPicardHsMetrics.xml --- a/tools/picard/rgPicardHsMetrics.xml +++ b/tools/picard/rgPicardHsMetrics.xml @@ -1,4 +1,4 @@ -<tool name="SAM/BAM Hybrid Selection Metrics" id="PicardHsMetrics" version="0.02.1"> +<tool name="SAM/BAM Hybrid Selection Metrics" id="PicardHsMetrics" version="1.56.0"><description>for targeted resequencing data</description><command interpreter="python"> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/picard/rgPicardInsertSize.xml --- a/tools/picard/rgPicardInsertSize.xml +++ b/tools/picard/rgPicardInsertSize.xml @@ -1,9 +1,9 @@ -<tool name="Insertion size metrics" id="PicardInsertSize" version="0.3.1"> +<tool name="Insertion size metrics" id="PicardInsertSize" version="1.56.0"><description>for PAIRED data</description><requirements><requirement type="package">picard</requirement></requirements><command interpreter="python"> - picard_wrapper.py -i "$input_file" -n "$out_prefix" --tmpdir "${__new_file_path__}" --taillimit "$tailLimit" - --histwidth "$histWidth" --minpct "$minPct" + picard_wrapper.py -i "$input_file" -n "$out_prefix" --tmpdir "${__new_file_path__}" --deviations "$deviations" + --histwidth "$histWidth" --minpct "$minPct" --malevel "$malevel" -j "${GALAXY_DATA_INDEX_DIR}/shared/jars/picard/CollectInsertSizeMetrics.jar" -d "$html_file.files_path" -t "$html_file" </command><inputs> @@ -11,15 +11,22 @@ help="If empty, upload or import a SAM/BAM dataset."/><param name="out_prefix" value="Insertion size metrics" type="text" label="Title for the output file" help="Use this remind you what the job was for" size="120" /> - <param name="tailLimit" value="10000" type="integer" - label="Tail limit" size="5" - help="When calculating mean and stdev stop when the bins in the tail of the distribution contain fewer than mode/TAIL_LIMIT items" /> + <param name="deviations" value="10.0" type="float" + label="Deviations" size="5" + help="See Picard documentation: Generate mean, sd and plots by trimming the data down to MEDIAN + DEVIATIONS*MEDIAN_ABSOLUTE_DEVIATION" /><param name="histWidth" value="0" type="integer" label="Histogram width" size="5" - help="Explicitly sets the histogram width, overriding the TAIL_LIMIT option - leave 0 to ignore" /> - <param name="minPct" value="0.01" type="float" + help="Explicitly sets the histogram width option - leave 0 to ignore" /> + <param name="minPct" value="0.05" type="float" label="Minimum percentage" size="5" help="Discard any data categories (out of FR, TANDEM, RF) that have fewer than this percentage of overall reads" /> + <param name="malevel" value="0" type="select" multiple="true" label="Metric Accumulation Level" + help="Level(s) at which metrics will be accumulated"> + <option value="ALL_READS" selected="true">All reads (default)</option> + <option value="SAMPLE" default="true">Sample</option> + <option value="LIBRARY" default="true">Library</option> + <option value="READ_GROUP" default="true">Read group</option> + </param></inputs><outputs><data format="html" name="html_file" label="InsertSize_${out_prefix}.html"/> @@ -28,9 +35,10 @@ <test><param name="input_file" value="picard_input_tiny.sam" /><param name="out_prefix" value="Insertion size metrics" /> - <param name="tailLimit" value="10000" /> + <param name="deviations" value="10.0" /><param name="histWidth" value="0" /><param name="minPct" value="0.01" /> + <param name="malevel" value="ALL_READS" /><output name="html_file" file="picard_output_insertsize_tinysam.html" ftype="html" compare="contains" lines_diff="40" /></test></tests> diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/picard/rgPicardLibComplexity.xml --- a/tools/picard/rgPicardLibComplexity.xml +++ b/tools/picard/rgPicardLibComplexity.xml @@ -1,4 +1,4 @@ -<tool name="Estimate Library Complexity" id="rgEstLibComp" version="0.01.1"> +<tool name="Estimate Library Complexity" id="rgEstLibComp" version="1.56.0"><command interpreter="python"> picard_wrapper.py -i "$input_file" -n "$out_prefix" --tmpdir "${__new_file_path__}" --minid "$minIDbases" --maxdiff "$maxDiff" --minmeanq "$minMeanQ" --readregex "$readRegex" --optdupdist "$optDupeDist" diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/picard/rgPicardMarkDups.xml --- a/tools/picard/rgPicardMarkDups.xml +++ b/tools/picard/rgPicardMarkDups.xml @@ -1,4 +1,4 @@ -<tool name="Mark Duplicate reads" id="rgPicardMarkDups" version="0.01.1"> +<tool name="Mark Duplicate reads" id="rgPicardMarkDups" version="1.56.0"><command interpreter="python"> picard_wrapper.py -i "$input_file" -n "$out_prefix" --tmpdir "${__new_file_path__}" -o "$out_file" --remdups "$remDups" --assumesorted "$assumeSorted" --readregex "$readRegex" --optdupdist "$optDupeDist" diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/rgenetics/rgFastQC.py --- a/tools/rgenetics/rgFastQC.py +++ b/tools/rgenetics/rgFastQC.py @@ -91,21 +91,20 @@ def fix_fastqc(self,rep=[],flist=[],runlog=[]): """ add some of our stuff to the html """ - bs = '</body></html>\n' # hope they don't change this - try: - bodyindex = rep.index(bs) # hope they don't change this - except: - bodyindex = len(rep) - 1 - res = [] - res.append('<table>\n') + bodyindex = len(rep) -1 # hope they don't change this + footrow = bodyindex - 1 + footer = rep[footrow] + rep = rep[:footrow] + rep[footrow+1:] + res = ['<div class="module"><h2>Files created by FastQC</h2><table cellspacing="2" cellpadding="2">\n'] flist.sort() for i,f in enumerate(flist): if not(os.path.isdir(f)): fn = os.path.split(f)[-1] res.append('<tr><td><a href="%s">%s</a></td></tr>\n' % (fn,getFileString(fn, self.opts.outputdir))) - res.append('</table><p/>\n') + res.append('</table>\n') res.append('<a href="http://www.bioinformatics.bbsrc.ac.uk/projects/fastqc/">FastQC documentation and full attribution is here</a><br/><hr/>\n') - res.append('FastQC was run by Galaxy using the rgenetics rgFastQC wrapper - see http://rgenetics.org for details and licensing\n') + res.append('FastQC was run by Galaxy using the rgenetics rgFastQC wrapper - see http://rgenetics.org for details and licensing\n</div>') + res.append(footer) fixed = rep[:bodyindex] + res + rep[bodyindex:] return fixed # with our additions @@ -147,3 +146,4 @@ f.write(''.join(html)) f.close() + diff -r b1a8b03710fed782dd80a1ac2d554dca9df2c107 -r d24b1a15ab0a61a137f024305781eb77ae4774ca tools/rgenetics/rgFastQC.xml --- a/tools/rgenetics/rgFastQC.xml +++ b/tools/rgenetics/rgFastQC.xml @@ -1,4 +1,4 @@ -<tool name="Fastqc: Fastqc QC" id="fastqc" version="0.1"> +<tool name="Fastqc: Fastqc QC" id="fastqc" version="0.3"><description>using FastQC from Babraham</description><command interpreter="python"> rgFastQC.py -i $input_file -d $html_file.files_path -o $html_file -n "$out_prefix" -f $input_file.ext -e ${GALAXY_DATA_INDEX_DIR}/shared/jars/FastQC/fastqc https://bitbucket.org/galaxy/galaxy-central/changeset/be252c2ce6e4/ changeset: be252c2ce6e4 user: natefoo date: 2011-11-16 19:53:50 summary: Merge. affected #: 1 file diff -r d24b1a15ab0a61a137f024305781eb77ae4774ca -r be252c2ce6e401aa7abe2c1b1096bfedcd3eba16 lib/galaxy/jobs/__init__.py --- a/lib/galaxy/jobs/__init__.py +++ b/lib/galaxy/jobs/__init__.py @@ -899,7 +899,9 @@ method should be removed ASAP and replaced with some properly generic and stateful way of determining link-only datasets. -nate """ - return self.tool.id == 'upload1' and self.param_dict.get( 'link_data_only', None ) == 'link_to_files' + job = self.get_job() + param_dict = job.get_param_values( self.app ) + return self.tool.id == 'upload1' and param_dict.get( 'link_data_only', None ) == 'link_to_files' def _change_ownership( self, username, gid ): job = self.get_job() https://bitbucket.org/galaxy/galaxy-central/changeset/2aa927225355/ changeset: 2aa927225355 user: natefoo date: 2011-12-08 19:22:39 summary: Actual User: Fix for newline conversion on upload, tighten file permissions for files in upload. Please make sure you clean your temp directory regularly. affected #: 5 files diff -r be252c2ce6e401aa7abe2c1b1096bfedcd3eba16 -r 2aa927225355959794e75fe3649085f81a901ea9 lib/galaxy/datatypes/sniff.py --- a/lib/galaxy/datatypes/sniff.py +++ b/lib/galaxy/datatypes/sniff.py @@ -95,7 +95,7 @@ fp.write( "%s\n" % line.rstrip( "\r\n" ) ) fp.close() if in_place: - shutil.copyfile( temp_name, fname ) + shutil.move( temp_name, fname ) # Return number of lines in file. return ( i + 1, None ) else: diff -r be252c2ce6e401aa7abe2c1b1096bfedcd3eba16 -r 2aa927225355959794e75fe3649085f81a901ea9 lib/galaxy/security/__init__.py --- a/lib/galaxy/security/__init__.py +++ b/lib/galaxy/security/__init__.py @@ -2,7 +2,7 @@ Galaxy Security """ -import logging, socket, operator +import logging, socket, operator, pwd from datetime import datetime, timedelta from galaxy.util.bunch import Bunch from galaxy.util import listify diff -r be252c2ce6e401aa7abe2c1b1096bfedcd3eba16 -r 2aa927225355959794e75fe3649085f81a901ea9 lib/galaxy/tools/actions/__init__.py --- a/lib/galaxy/tools/actions/__init__.py +++ b/lib/galaxy/tools/actions/__init__.py @@ -282,7 +282,7 @@ # Create an empty file immediately open( data.file_name, "w" ).close() # Fix permissions - util.umask_fix_perms( data.file_name, trans.app.config.umask, 0666) + util.umask_fix_perms( data.file_name, trans.app.config.umask, 0666 ) # This may not be neccesary with the new parent/child associations data.designation = name # Copy metadata from one of the inputs if requested. diff -r be252c2ce6e401aa7abe2c1b1096bfedcd3eba16 -r 2aa927225355959794e75fe3649085f81a901ea9 lib/galaxy/tools/actions/upload_common.py --- a/lib/galaxy/tools/actions/upload_common.py +++ b/lib/galaxy/tools/actions/upload_common.py @@ -1,4 +1,4 @@ -import os, tempfile, StringIO +import os, tempfile, StringIO, pwd, subprocess from cgi import FieldStorage from galaxy import datatypes, util from galaxy.util.odict import odict @@ -252,6 +252,18 @@ """ Create the upload tool's JSON "param" file. """ + def _chown( path ): + try: + pwent = pwd.getpwnam( trans.user.email.split('@')[0] ) + cmd = [ '/usr/bin/sudo', '-E', trans.app.config.external_chown_script, path, pwent[0], str( pwent[3] ) ] + log.debug( 'Changing ownership of %s with: %s' % ( path, ' '.join( cmd ) ) ) + p = subprocess.Popen( cmd, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) + stdout, stderr = p.communicate() + assert p.returncode == 0, stderr + except Exception, e: + log.warning( 'Changing ownership of uploaded file %s failed: %s' % ( path, str( e ) ) ) + + # TODO: json_file should go in the working directory json_file = tempfile.mkstemp() json_file_path = json_file[1] json_file = os.fdopen( json_file[0], 'w' ) @@ -279,10 +291,8 @@ is_binary = None try: link_data_only = uploaded_dataset.link_data_only - chmod_flag = 1 except: link_data_only = 'copy_files' - chmod_flag = 0 json = dict( file_type = uploaded_dataset.file_type, ext = uploaded_dataset.ext, name = uploaded_dataset.name, @@ -292,13 +302,17 @@ is_binary = is_binary, link_data_only = link_data_only, space_to_tab = uploaded_dataset.space_to_tab, + in_place = trans.app.config.external_chown_script is None, path = uploaded_dataset.path ) - if chmod_flag == 0 and trans.app.config.drmaa_external_runjob_script: - os.chmod(uploaded_dataset.path, 0777) + # TODO: This will have to change when we start bundling inputs. + # Also, in_place above causes the file to be left behind since the + # user cannot remove it unless the parent directory is writable. + if link_data_only == 'copy_files' and trans.app.config.external_chown_script: + _chown( uploaded_dataset.path ) json_file.write( to_json_string( json ) + '\n' ) json_file.close() - if trans.app.config.drmaa_external_runjob_script: - os.chmod(json_file_path, 0777) + if trans.app.config.external_chown_script: + _chown( json_file_path ) return json_file_path def create_job( trans, params, tool, json_file_path, data_list, folder=None ): """ @@ -331,16 +345,12 @@ # Create an empty file immediately if not dataset.dataset.external_filename: open( dataset.file_name, "w" ).close() - if trans.app.config.drmaa_external_runjob_script: - os.chmod(dataset.file_name, 0777) else: for i, dataset in enumerate( data_list ): job.add_output_dataset( 'output%i' % i, dataset ) # Create an empty file immediately if not dataset.dataset.external_filename: open( dataset.file_name, "w" ).close() - if trans.app.config.drmaa_external_runjob_script: - os.chmod(dataset.file_name, 0777) job.state = job.states.NEW trans.sa_session.add( job ) diff -r be252c2ce6e401aa7abe2c1b1096bfedcd3eba16 -r 2aa927225355959794e75fe3649085f81a901ea9 tools/data_source/upload.py --- a/tools/data_source/upload.py +++ b/tools/data_source/upload.py @@ -80,6 +80,7 @@ converted_path = None stdout = None link_data_only = dataset.get( 'link_data_only', 'copy_files' ) + in_place = dataset.get( 'in_place', True ) try: ext = dataset.file_type @@ -161,7 +162,7 @@ os.close( fd ) gzipped_file.close() # Replace the gzipped file with the decompressed file if it's safe to do so - if dataset.type in ( 'server_dir', 'path_paste' ): + if dataset.type in ( 'server_dir', 'path_paste' ) or not in_place: dataset.path = uncompressed else: shutil.move( uncompressed, dataset.path ) @@ -194,7 +195,7 @@ os.close( fd ) bzipped_file.close() # Replace the bzipped file with the decompressed file if it's safe to do so - if dataset.type in ( 'server_dir', 'path_paste' ): + if dataset.type in ( 'server_dir', 'path_paste' ) or not in_place: dataset.path = uncompressed else: shutil.move( uncompressed, dataset.path ) @@ -251,7 +252,7 @@ z.close() # Replace the zipped file with the decompressed file if it's safe to do so if uncompressed is not None: - if dataset.type in ( 'server_dir', 'path_paste' ): + if dataset.type in ( 'server_dir', 'path_paste' ) or not in_place: dataset.path = uncompressed else: shutil.move( uncompressed, dataset.path ) @@ -280,7 +281,6 @@ return if data_type != 'binary': if link_data_only == 'copy_files': - in_place = True if dataset.type in ( 'server_dir', 'path_paste' ) and data_type not in [ 'gzip', 'bz2', 'zip' ]: in_place = False if dataset.space_to_tab: @@ -305,27 +305,18 @@ '<b>Copy files into Galaxy</b> instead of <b>Link to files without copying into Galaxy</b> so grooming can be performed.' file_err( err_msg, dataset, json_file ) return - if link_data_only == 'copy_files' and dataset.type in ( 'server_dir', 'path_paste' ) and data_type not in [ 'gzip', 'bz2', 'zip' ]: - # Move the dataset to its "real" path - if converted_path is not None: - shutil.copy( converted_path, output_path ) - try: - os.remove( converted_path ) - except: - pass - else: - # This should not happen, but it's here just in case - shutil.move( dataset.path, output_path ) - try: - os.chmod(output_path,0644) - except: - pass + if link_data_only == 'copy_files' and converted_path is not None: + # Move the converted dataset to its "real" path + shutil.move( converted_path, output_path ) + elif link_data_only == 'copy_files' and in_place: + # Dataset was not converted but should still be removed from original location + shutil.move( dataset.path, output_path ) elif link_data_only == 'copy_files': - shutil.move( dataset.path, output_path ) - try: - os.chmod(output_path,0644) - except: - pass + shutil.copy( dataset.path, output_path ) + + if link_data_only == 'copy_files' and datatype.dataset_content_needs_grooming( output_path ): + # Groom the dataset content if necessary + datatype.groom_dataset_content( output_path ) # Write the job info stdout = stdout or 'uploaded %s file' % data_type @@ -336,9 +327,7 @@ name = dataset.name, line_count = line_count ) json_file.write( to_json_string( info ) + "\n" ) - if link_data_only == 'copy_files' and datatype.dataset_content_needs_grooming( output_path ): - # Groom the dataset content if necessary - datatype.groom_dataset_content( output_path ) + def add_composite_file( dataset, registry, json_file, output_path, files_path ): if dataset.composite_files: os.mkdir( files_path ) @@ -396,7 +385,10 @@ add_composite_file( dataset, registry, json_file, output_path, files_path ) else: add_file( dataset, registry, json_file, output_path ) + # clean up paramfile + # TODO: this will not work when running as the actual user unless the + # parent directory is writable by the user. try: os.remove( sys.argv[3] ) except: https://bitbucket.org/galaxy/galaxy-central/changeset/4f12603141ce/ changeset: 4f12603141ce user: natefoo date: 2012-01-17 19:47:13 summary: Galaxy can now read an environment file before executing jobs on the cluster, useful if your DRM does not give you an easy way to do this directly. affected #: 5 files diff -r 2aa927225355959794e75fe3649085f81a901ea9 -r 4f12603141ce7688c197d8722231397404d7a2d9 lib/galaxy/config.py --- a/lib/galaxy/config.py +++ b/lib/galaxy/config.py @@ -109,7 +109,7 @@ self.drmaa_external_runjob_script = kwargs.get('drmaa_external_runjob_script', None ) self.drmaa_external_killjob_script = kwargs.get('drmaa_external_killjob_script', None) self.external_chown_script = kwargs.get('external_chown_script', None) - self.TMPDIR = kwargs.get('TMPDIR', None) + self.environment_setup_file = kwargs.get( 'environment_setup_file', None ) self.use_heartbeat = string_as_bool( kwargs.get( 'use_heartbeat', 'False' ) ) self.use_memdump = string_as_bool( kwargs.get( 'use_memdump', 'False' ) ) self.log_actions = string_as_bool( kwargs.get( 'log_actions', 'False' ) ) diff -r 2aa927225355959794e75fe3649085f81a901ea9 -r 4f12603141ce7688c197d8722231397404d7a2d9 lib/galaxy/jobs/__init__.py --- a/lib/galaxy/jobs/__init__.py +++ b/lib/galaxy/jobs/__init__.py @@ -733,6 +733,11 @@ def get_session_id( self ): return self.session_id + def get_env_setup_clause( self ): + if self.app.config.environment_setup_file is None: + return '' + return '[ -f "%s" ] && . %s' % ( self.app.config.environment_setup_file, self.app.config.environment_setup_file ) + def get_input_dataset_fnames( self, ds ): filenames = [] filenames = [ ds.file_name ] diff -r 2aa927225355959794e75fe3649085f81a901ea9 -r 4f12603141ce7688c197d8722231397404d7a2d9 lib/galaxy/jobs/runners/drmaa.py --- a/lib/galaxy/jobs/runners/drmaa.py +++ b/lib/galaxy/jobs/runners/drmaa.py @@ -52,7 +52,6 @@ %s cd %s %s -%s """ def __lineno__(): """Returns the current line number in our program.""" @@ -112,8 +111,7 @@ # external_runJob_script can be None, in which case it's not used. self.external_runJob_script = app.config.drmaa_external_runjob_script self.external_killJob_script = app.config.drmaa_external_killjob_script - self.TMPDIR = app.config.TMPDIR - self.userid = [] + self.userid = None def get_native_spec( self, url ): """Get any native DRM arguments specified by the site configuration""" @@ -176,26 +174,22 @@ native_spec = self.get_native_spec( runner_url ) if native_spec is not None: jt.nativeSpecification = native_spec - #set and export galaxy user PATH enviroment to actual user if submitting jobs as actual user + + # fill in the DRM's job run template + script = drm_template % ( job_wrapper.galaxy_lib_dir, + job_wrapper.get_env_setup_clause(), + os.path.abspath( job_wrapper.working_directory ), + command_line ) + try: - if self.external_runJob_script: - export_path = 'export PATH=%s:$PATH' %(os.environ['PATH']) - else: - export_path = '' + fh = file( jt.remoteCommand, "w" ) + fh.write( script ) + fh.close() + os.chmod( jt.remoteCommand, 0755 ) except: - export_path = '' - - if self.TMPDIR: - export_tmp = 'export TMPDIR=%s' %self.TMPDIR - else: - export_tmp = '' - - script = drm_template % ( job_wrapper.galaxy_lib_dir, export_path, os.path.abspath( job_wrapper.working_directory ), export_tmp, command_line ) - - fh = file( jt.remoteCommand, "w" ) - fh.write( script ) - fh.close() - os.chmod( jt.remoteCommand, 0755 ) + job_wrapper.fail( "failure preparing job script", exception=True ) + log.exception( "failure running job %s" % job_wrapper.get_id_tag() ) + return # job was deleted while we were preparing it if job_wrapper.get_state() == model.Job.states.DELETED: diff -r 2aa927225355959794e75fe3649085f81a901ea9 -r 4f12603141ce7688c197d8722231397404d7a2d9 lib/galaxy/jobs/runners/pbs.py --- a/lib/galaxy/jobs/runners/pbs.py +++ b/lib/galaxy/jobs/runners/pbs.py @@ -42,6 +42,7 @@ export PYTHONPATH="$GALAXY_LIB" fi fi +%s cd %s %s """ @@ -61,6 +62,7 @@ [ ! -d $dir ] && mkdir -p $dir [ ! -e $dataset ] && ln -s %s/$file $dataset done +%s cd %s %s """ @@ -265,9 +267,17 @@ # write the job script if self.app.config.pbs_stage_path != '': - script = pbs_symlink_template % (job_wrapper.galaxy_lib_dir, " ".join(job_wrapper.get_input_fnames() + output_files), self.app.config.pbs_stage_path, exec_dir, command_line) + script = pbs_symlink_template % ( job_wrapper.galaxy_lib_dir, + " ".join( job_wrapper.get_input_fnames() + output_files ), + self.app.config.pbs_stage_path, + job_wrapper.get_env_setup_clause(), + exec_dir, + command_line ) else: - script = pbs_template % ( job_wrapper.galaxy_lib_dir, exec_dir, command_line ) + script = pbs_template % ( job_wrapper.galaxy_lib_dir, + job_wrapper.get_env_setup_clause(), + exec_dir, + command_line ) job_file = "%s/%s.sh" % (self.app.config.cluster_files_directory, job_wrapper.job_id) fh = file(job_file, "w") fh.write(script) diff -r 2aa927225355959794e75fe3649085f81a901ea9 -r 4f12603141ce7688c197d8722231397404d7a2d9 universe_wsgi.ini.sample --- a/universe_wsgi.ini.sample +++ b/universe_wsgi.ini.sample @@ -551,29 +551,27 @@ # currently available are 'pbs' and 'drmaa'. #start_job_runners = None -# Uncomment drmaa_external_runjob_script , drmaa_external_killjob_script, and external_chown_script pameters and have them point to the -# absolute path for scripts/drmaa_external_runner.py and scripts/drmaa_external_killer.py. -# The scripts directory is located in the top level galaxy directory. The parameters when -# uncommented allow for submission to the drmaa queue with the user name of the user submitting -# the job and not the galaxy user. In order for this to work the actual user must log into galaxy -# and the galaxy authentication must be consistent with the authentication on the server in which the -# drmaa queue is running (i.e. the username must have an account on the server and be allowed to -# submit jobs to the queue). The galaxy user must also be given sudo permission to execute -# scripts/drmaa_external_runner.py and scripts/drmaa_external_killer.py in /etc/sudoers -# Example: -# galaxy ALL = (root) NOPASSWD: SETENV: /opt/galaxy/scripts/drmaa_external_runner.py -# galaxy ALL = (root) NOPASSWD: SETENV: /opt/galaxy/scripts/drmaa_external_killer.py -# Also the -# Defaults requiretty -# in /etc/sudoers must be commented out +# For sites where all users in Galaxy match users on the system on which Galaxy +# runs, the DRMAA job runner can be configured to submit jobs to the DRM as the +# actual user instead of as the user running the Galaxy server process. For +# details on these options, see the documentation at: +# +# http://galaxyproject.org/wiki/Admin/Config/Performance/Cluster +# #drmaa_external_runjob_script = scripts/drmaa_external_runner.py #drmaa_external_killjob_script = scripts/drmaa_external_killer.py #external_chown_script = scripts/external_chown_script.py -#important if running as actual user since enviromental variables are not passed -#will supercede an other definition of TMPDIR if using drmaa -#TMPDIR = /opt/galaxy/database/tmp - +# File to source to set up the environment when running jobs. By default, the +# environment in which the Galaxy server starts is used when running jobs +# locally, and the environment set up per the DRM's submission method and +# policy is used when running jobs on a cluster (try testing with `qsub` on the +# command line). environment_setup_file can be set to the path of a file on +# the cluster that should be sourced by the user to set up the environment +# prior to running tools. This can be especially useful for running jobs as +# the actual user, to remove the need to configure each user's environment +# individually. This only affects cluster jobs, not local jobs. +#environment_setup_file = None # The URL for the default runner to use when a tool doesn't explicitly define a # runner below. https://bitbucket.org/galaxy/galaxy-central/changeset/419260098a6f/ changeset: 419260098a6f user: natefoo date: 2012-01-18 16:34:39 summary: Merge galaxy-central. affected #: 396 files Diff too large to display. https://bitbucket.org/galaxy/galaxy-central/changeset/7c3c50784374/ changeset: 7c3c50784374 user: natefoo date: 2012-01-18 20:34:00 summary: A bit more actual user cleaning. affected #: 6 files diff -r 419260098a6f394eb44b890b9740a08ff9574c36 -r 7c3c507843740ce7cb766c11559bde58fdcc7916 lib/galaxy/datatypes/registry.py --- a/lib/galaxy/datatypes/registry.py +++ b/lib/galaxy/datatypes/registry.py @@ -589,3 +589,4 @@ os.write( fd, '</sniffers>\n' ) os.write( fd, '</datatypes>\n' ) os.close( fd ) + os.chmod( self.xml_filename, 0644 ) diff -r 419260098a6f394eb44b890b9740a08ff9574c36 -r 7c3c507843740ce7cb766c11559bde58fdcc7916 lib/galaxy/security/__init__.py --- a/lib/galaxy/security/__init__.py +++ b/lib/galaxy/security/__init__.py @@ -2,7 +2,7 @@ Galaxy Security """ -import logging, socket, operator, pwd +import logging, socket, operator from datetime import datetime, timedelta from galaxy.util.bunch import Bunch from galaxy.util import listify diff -r 419260098a6f394eb44b890b9740a08ff9574c36 -r 7c3c507843740ce7cb766c11559bde58fdcc7916 lib/galaxy/tools/__init__.py --- a/lib/galaxy/tools/__init__.py +++ b/lib/galaxy/tools/__init__.py @@ -30,8 +30,6 @@ from cgi import FieldStorage from galaxy.util.hash_util import * from galaxy.util import listify -from galaxy.web import security -import socket from galaxy.visualization.tracks.visual_analytics import TracksterConfig @@ -1637,13 +1635,13 @@ DatasetFilenameWrapper( converted_dataset, datatypes_registry = self.app.datatypes_registry, tool = Bunch( conversion_name = Bunch( extensions = conv_ext ) ), - name = conversion_name, config_info = self.app.config ) + name = conversion_name ) # Wrap actual input dataset input_values[ input.name ] = \ DatasetFilenameWrapper( input_values[ input.name ], datatypes_registry = self.app.datatypes_registry, tool = self, - name = input.name, config_info = self.app.config ) + name = input.name ) elif isinstance( input, SelectToolParameter ): input_values[ input.name ] = SelectToolParameterWrapper( input, input_values[ input.name ], self.app, other_values = param_dict ) @@ -1681,28 +1679,28 @@ param_dict[name] = DatasetFilenameWrapper( data, datatypes_registry = self.app.datatypes_registry, tool = self, - name = name, config_info = self.app.config ) + name = name ) if data: for child in data.children: - param_dict[ "_CHILD___%s___%s" % ( name, child.designation ) ] = DatasetFilenameWrapper( child,config_info = self.app.config ) + param_dict[ "_CHILD___%s___%s" % ( name, child.designation ) ] = DatasetFilenameWrapper( child ) for name, hda in output_datasets.items(): # Write outputs to the working directory (for security purposes) # if desired. if self.app.config.outputs_to_working_directory: try: false_path = [ dp.false_path for dp in output_paths if dp.real_path == hda.file_name ][0] - param_dict[name] = DatasetFilenameWrapper( hda, false_path = false_path, config_info = self.app.config ) + param_dict[name] = DatasetFilenameWrapper( hda, false_path = false_path ) open( false_path, 'w' ).close() except IndexError: log.warning( "Unable to determine alternate path for writing job outputs, outputs will be written to their real paths" ) - param_dict[name] = DatasetFilenameWrapper( hda, config_info = self.app.config ) + param_dict[name] = DatasetFilenameWrapper( hda ) else: - param_dict[name] = DatasetFilenameWrapper( hda, config_info = self.app.config ) + param_dict[name] = DatasetFilenameWrapper( hda ) # Provide access to a path to store additional files # TODO: path munging for cluster/dataset server relocatability param_dict[name].files_path = os.path.abspath(os.path.join( job_working_directory, "dataset_%s_files" % (hda.dataset.id) )) for child in hda.children: - param_dict[ "_CHILD___%s___%s" % ( name, child.designation ) ] = DatasetFilenameWrapper( child, config_info = self.app.config ) + param_dict[ "_CHILD___%s___%s" % ( name, child.designation ) ] = DatasetFilenameWrapper( child ) for out_name, output in self.outputs.iteritems(): if out_name not in param_dict and output.filters: # Assume the reason we lack this output is because a filter @@ -2294,7 +2292,7 @@ def items( self ): return iter( [ ( k, self.get( k ) ) for k, v in self.metadata.items() ] ) - def __init__( self, dataset, datatypes_registry = None, tool = None, name = None, false_path = None , config_info=None): + def __init__( self, dataset, datatypes_registry = None, tool = None, name = None, false_path = None ): if not dataset: try: # TODO: allow this to work when working with grouping @@ -2306,14 +2304,6 @@ self.dataset = dataset self.metadata = self.MetadataWrapper( dataset.metadata ) self.false_path = false_path - - # create web_display_url attribute - sec = security.SecurityHelper( id_secret=config_info.id_secret ) - try: - url = 'http://' + socket.getfqdn() + config_info.cookie_path + '/datasets/' + sec.encode_id(dataset.id) + '/display/?preview=True' - self.web_display_url = url - except: - self.web_display_url = None def __str__( self ): if self.false_path is not None: diff -r 419260098a6f394eb44b890b9740a08ff9574c36 -r 7c3c507843740ce7cb766c11559bde58fdcc7916 lib/galaxy/tools/actions/__init__.py --- a/lib/galaxy/tools/actions/__init__.py +++ b/lib/galaxy/tools/actions/__init__.py @@ -149,7 +149,7 @@ galaxy.tools.DatasetFilenameWrapper( input_values[ input.name ], datatypes_registry = trans.app.datatypes_registry, tool = tool, - name = input.name, config_info = trans.app.config) + name = input.name ) elif isinstance( input, SelectToolParameter ): input_values[ input.name ] = galaxy.tools.SelectToolParameterWrapper( input, input_values[ input.name ], tool.app, other_values = incoming ) else: diff -r 419260098a6f394eb44b890b9740a08ff9574c36 -r 7c3c507843740ce7cb766c11559bde58fdcc7916 tools/data_source/upload.py --- a/tools/data_source/upload.py +++ b/tools/data_source/upload.py @@ -305,19 +305,19 @@ '<b>Copy files into Galaxy</b> instead of <b>Link to files without copying into Galaxy</b> so grooming can be performed.' file_err( err_msg, dataset, json_file ) return - if link_data_only == 'copy_files' and converted_path is not None: - # Move the converted dataset to its "real" path - shutil.move( converted_path, output_path ) - elif link_data_only == 'copy_files' and in_place: - # Dataset was not converted but should still be removed from original location + if link_data_only == 'copy_files' and dataset.type in ( 'server_dir', 'path_paste' ) and data_type not in [ 'gzip', 'bz2', 'zip' ]: + # Move the dataset to its "real" path + if converted_path is not None: + shutil.copy( converted_path, output_path ) + try: + os.remove( converted_path ) + except: + pass + else: + # This should not happen, but it's here just in case + shutil.copy( dataset.path, output_path ) + elif link_data_only == 'copy_files': shutil.move( dataset.path, output_path ) - elif link_data_only == 'copy_files': - shutil.copy( dataset.path, output_path ) - - if link_data_only == 'copy_files' and datatype.dataset_content_needs_grooming( output_path ): - # Groom the dataset content if necessary - datatype.groom_dataset_content( output_path ) - # Write the job info stdout = stdout or 'uploaded %s file' % data_type info = dict( type = 'dataset', @@ -328,6 +328,10 @@ line_count = line_count ) json_file.write( to_json_string( info ) + "\n" ) + if link_data_only == 'copy_files' and datatype.dataset_content_needs_grooming( output_path ): + # Groom the dataset content if necessary + datatype.groom_dataset_content( output_path ) + def add_composite_file( dataset, registry, json_file, output_path, files_path ): if dataset.composite_files: os.mkdir( files_path ) diff -r 419260098a6f394eb44b890b9740a08ff9574c36 -r 7c3c507843740ce7cb766c11559bde58fdcc7916 universe_wsgi.ini.sample --- a/universe_wsgi.ini.sample +++ b/universe_wsgi.ini.sample @@ -640,6 +640,7 @@ # run with the runner defined with default_cluster_job_runner. [galaxy:tool_runners] + biomart = local:/// encode_db1 = local:/// hbvar = local:/// https://bitbucket.org/galaxy/galaxy-central/changeset/e250efd2a19c/ changeset: e250efd2a19c user: natefoo date: 2012-01-18 20:34:27 summary: Merge galaxy-central. affected #: 34 files diff -r 7c3c507843740ce7cb766c11559bde58fdcc7916 -r e250efd2a19c0bb214f02f09451b3afb3165e401 lib/galaxy/model/__init__.py --- a/lib/galaxy/model/__init__.py +++ b/lib/galaxy/model/__init__.py @@ -156,7 +156,7 @@ dict of tool parameter values. """ param_dict = dict( [ ( p.name, p.value ) for p in self.parameters ] ) - tool = app.toolbox.tools_by_id[self.tool_id] + tool = app.toolbox.get_tool( self.tool_id ) param_dict = tool.params_from_strings( param_dict, app, ignore_errors=ignore_errors ) return param_dict def check_if_output_datasets_deleted( self ): @@ -228,7 +228,7 @@ dict of tool parameter values. """ param_dict = dict( [ ( p.name, p.value ) for p in self.parent_job.parameters ] ) - tool = app.toolbox.tools_by_id[self.tool_id] + tool = app.toolbox.get_tool( self.tool_id ) param_dict = tool.params_from_strings( param_dict, app ) return param_dict diff -r 7c3c507843740ce7cb766c11559bde58fdcc7916 -r e250efd2a19c0bb214f02f09451b3afb3165e401 lib/galaxy/tool_shed/install_manager.py --- a/lib/galaxy/tool_shed/install_manager.py +++ b/lib/galaxy/tool_shed/install_manager.py @@ -4,6 +4,7 @@ shed. Tools included in tool_shed_install.xml that have already been installed will not be re-installed. """ +from galaxy.tools import ToolSection from galaxy.util.shed_util import * log = logging.getLogger( __name__ ) diff -r 7c3c507843740ce7cb766c11559bde58fdcc7916 -r e250efd2a19c0bb214f02f09451b3afb3165e401 lib/galaxy/tools/__init__.py --- a/lib/galaxy/tools/__init__.py +++ b/lib/galaxy/tools/__init__.py @@ -99,6 +99,44 @@ self.load_section_tag_set( elem, self.tool_panel, tool_path ) elif elem.tag == 'label': self.load_label_tag_set( elem, self.tool_panel ) + def get_tool( self, tool_id, tool_version=None ): + # Attempt to locate the tool in our in-memory dictionary. + if tool_id in self.tools_by_id: + tool = self.tools_by_id[ tool_id ] + if tool_version and tool.version == tool_version: + return tool + else: + return tool + # Handle the case where the tool was used when the tool was included in the Galaxy distribution, + # but now the tool is contained in an installed tool shed repository. In this case, the original + # tool id can be mapped to the new tool id, which is the tool's guid in the tool shed repository. + # This scenarios can occur in workflows and in a history item when the rerun icon is clicked. + # The weakness here is that workflows currently handle only tool ids and not versions. + tool_id_guid_map = self.__get_tool_id_guid_map( tool_id, tool_version=tool_version ) + if tool_id_guid_map: + guid = tool_id_guid_map.guid + if guid in self.tools_by_id: + return self.tools_by_id[ guid ] + # Handle the case where a proprietary tool was initially developed and hosted in a local Galaxy + # instance, but the developer later uploaded the tool to a Galaxy tool shed, removed the original + # tool from the local Galaxy instance and installed the tool's repository from the tool shed. + for k, tool in self.tools_by_id.items(): + if tool_id == tool.old_id: + if tool_version and tool.version == tool_version: + return tool + else: + return tool + return None + def __get_tool_id_guid_map( self, tool_id, tool_version=None ): + if tool_version: + return self.sa_session.query( self.app.model.ToolIdGuidMap ) \ + .filter( and_( self.app.model.ToolIdGuidMap.table.c.tool_id == tool_id, + self.app.model.ToolIdGuidMap.table.c.tool_version == tool_version ) ) \ + .first() + else: + return self.sa_session.query( self.app.model.ToolIdGuidMap ) \ + .filter( self.app.model.ToolIdGuidMap.table.c.tool_id == tool_id ) \ + .first() def __get_tool_shed_repository( self, tool_shed, name, owner, installed_changeset_revision ): return self.sa_session.query( self.app.model.ToolShedRepository ) \ .filter( and_( self.app.model.ToolShedRepository.table.c.tool_shed == tool_shed, @@ -193,7 +231,7 @@ self.tools_by_id[ tool.id ] = tool key = 'tool_' + tool.id panel_dict[ key ] = tool - log.debug( "Loaded tool: %s %s" % ( tool.id, tool.version ) ) + log.debug( "Loaded tool id: %s, version: %s." % ( tool.id, tool.version ) ) except: log.exception( "error reading tool from path: %s" % path ) def load_workflow_tag_set( self, elem, panel_dict ): diff -r 7c3c507843740ce7cb766c11559bde58fdcc7916 -r e250efd2a19c0bb214f02f09451b3afb3165e401 lib/galaxy/visualization/tracks/visual_analytics.py --- a/lib/galaxy/visualization/tracks/visual_analytics.py +++ b/lib/galaxy/visualization/tracks/visual_analytics.py @@ -44,7 +44,7 @@ # assert job is not None, 'Requested job has not been loaded.' if not job: return {} - tool = trans.app.toolbox.tools_by_id.get( job.tool_id, None ) + tool = trans.app.toolbox.get_tool( job.tool_id ) # TODO: could use this assertion to provide more information. # assert tool is not None, 'Requested tool has not been loaded.' if not tool: diff -r 7c3c507843740ce7cb766c11559bde58fdcc7916 -r e250efd2a19c0bb214f02f09451b3afb3165e401 lib/galaxy/web/api/workflows.py --- a/lib/galaxy/web/api/workflows.py +++ b/lib/galaxy/web/api/workflows.py @@ -171,7 +171,7 @@ for i, step in enumerate( workflow.steps ): job = None if step.type == 'tool' or step.type is None: - tool = self.app.toolbox.tools_by_id[ step.tool_id ] + tool = self.app.toolbox.get_tool( step.tool_id ) def callback( input, value, prefixed_name, prefixed_label ): if isinstance( input, DataToolParameter ): if prefixed_name in step.input_connections_by_name: diff -r 7c3c507843740ce7cb766c11559bde58fdcc7916 -r e250efd2a19c0bb214f02f09451b3afb3165e401 lib/galaxy/web/controllers/async.py --- a/lib/galaxy/web/controllers/async.py +++ b/lib/galaxy/web/controllers/async.py @@ -42,7 +42,7 @@ # initialize the tool toolbox = self.get_toolbox() - tool = toolbox.tools_by_id.get(tool_id, '') + tool = toolbox.get_tool( tool_id ) if not tool: return "Tool with id %s not found" % tool_id diff -r 7c3c507843740ce7cb766c11559bde58fdcc7916 -r e250efd2a19c0bb214f02f09451b3afb3165e401 lib/galaxy/web/controllers/dataset.py --- a/lib/galaxy/web/controllers/dataset.py +++ b/lib/galaxy/web/controllers/dataset.py @@ -1116,7 +1116,7 @@ try: # Load the tool toolbox = self.get_toolbox() - tool = toolbox.tools_by_id.get( job.tool_id, None ) + tool = toolbox.get_tool( job.tool_id ) assert tool is not None, 'Requested tool has not been loaded.' params_objects = job.get_param_values( trans.app ) except: diff -r 7c3c507843740ce7cb766c11559bde58fdcc7916 -r e250efd2a19c0bb214f02f09451b3afb3165e401 lib/galaxy/web/controllers/history.py --- a/lib/galaxy/web/controllers/history.py +++ b/lib/galaxy/web/controllers/history.py @@ -613,7 +613,7 @@ #.add_input( "file", "Archived History File", "archive_file", value=None, error=None ) ) # Run job to do import. - history_imp_tool = trans.app.toolbox.tools_by_id[ '__IMPORT_HISTORY__' ] + history_imp_tool = trans.app.toolbox.get_tool( '__IMPORT_HISTORY__' ) incoming = { '__ARCHIVE_SOURCE__' : archive_source, '__ARCHIVE_TYPE__' : archive_type } history_imp_tool.execute( trans, incoming=incoming ) return trans.show_message( "Importing history from '%s'. \ @@ -669,7 +669,7 @@ % ( { 'n' : history.name, 's' : url_for( action="export_archive", id=id, qualified=True ) } ) ) # Run job to do export. - history_exp_tool = trans.app.toolbox.tools_by_id[ '__EXPORT_HISTORY__' ] + history_exp_tool = trans.app.toolbox.get_tool( '__EXPORT_HISTORY__' ) params = { 'history_to_export' : history, 'compress' : gzip, diff -r 7c3c507843740ce7cb766c11559bde58fdcc7916 -r e250efd2a19c0bb214f02f09451b3afb3165e401 lib/galaxy/web/controllers/library_common.py --- a/lib/galaxy/web/controllers/library_common.py +++ b/lib/galaxy/web/controllers/library_common.py @@ -965,7 +965,7 @@ def upload_dataset( self, trans, cntrller, library_id, folder_id, replace_dataset=None, **kwd ): # Set up the traditional tool state/params tool_id = 'upload1' - tool = trans.app.toolbox.tools_by_id[ tool_id ] + tool = trans.app.toolbox.get_tool( tool_id ) state = tool.new_state( trans ) errors = tool.update_state( trans, tool.inputs_by_page[0], state.inputs, kwd ) tool_params = state.inputs diff -r 7c3c507843740ce7cb766c11559bde58fdcc7916 -r e250efd2a19c0bb214f02f09451b3afb3165e401 lib/galaxy/web/controllers/root.py --- a/lib/galaxy/web/controllers/root.py +++ b/lib/galaxy/web/controllers/root.py @@ -39,7 +39,7 @@ filter( self.app.model.Job.user==trans.user ). \ order_by( self.app.model.Job.create_time.desc() ): tool_id = row[0] - a_tool = toolbox.tools_by_id.get( tool_id, None ) + a_tool = toolbox.get_tool( tool_id ) if a_tool and not a_tool.hidden and a_tool not in recent_tools: recent_tools.append( a_tool ) ## TODO: make number of recently used tools a user preference. @@ -78,7 +78,7 @@ def tool_help( self, trans, id ): """Return help page for tool identified by 'id' if available""" toolbox = self.get_toolbox() - tool = toolbox.tools_by_id.get(id, '') + tool = toolbox.get_tool( id ) yield "<html><body>" if not tool: yield "Unknown tool id '%d'" % id @@ -179,7 +179,7 @@ job_hda = job_hda.copied_from_history_dataset_association force_history_refresh = False if job_hda.creating_job_associations: - tool = trans.app.toolbox.tools_by_id.get( job_hda.creating_job_associations[ 0 ].job.tool_id, None ) + tool = trans.app.toolbox.get_tool( job_hda.creating_job_associations[ 0 ].job.tool_id ) if tool: force_history_refresh = tool.force_history_refresh if not job_hda.visible: diff -r 7c3c507843740ce7cb766c11559bde58fdcc7916 -r e250efd2a19c0bb214f02f09451b3afb3165e401 lib/galaxy/web/controllers/tool_runner.py --- a/lib/galaxy/web/controllers/tool_runner.py +++ b/lib/galaxy/web/controllers/tool_runner.py @@ -49,7 +49,7 @@ else: tool_ids = [ tool_id ] for tool_id in tool_ids: - tool = toolbox.tools_by_id.get( tool_id, None ) + tool = toolbox.get_tool( tool_id ) if tool: break # No tool matching the tool id, display an error (shouldn't happen) @@ -112,7 +112,7 @@ try: # Load the tool toolbox = self.get_toolbox() - tool = toolbox.tools_by_id.get( tool_id, None ) + tool = toolbox.get_tool( tool_id ) assert tool is not None, 'Requested tool has not been loaded.' except: #this is expected, so not an exception @@ -202,7 +202,7 @@ else: library_bunch = None return upload_common.new_upload( trans, cntrller, ud, library_bunch=library_bunch, state=trans.app.model.HistoryDatasetAssociation.states.UPLOAD ) - tool = self.get_toolbox().tools_by_id.get( tool_id, None ) + tool = self.get_toolbox().get_tool( tool_id ) if not tool: return False # bad tool_id nonfile_params = util.Params( kwd, sanitize=False ) diff -r 7c3c507843740ce7cb766c11559bde58fdcc7916 -r e250efd2a19c0bb214f02f09451b3afb3165e401 lib/galaxy/web/controllers/tracks.py --- a/lib/galaxy/web/controllers/tracks.py +++ b/lib/galaxy/web/controllers/tracks.py @@ -787,7 +787,7 @@ # # Execute tool. # - tool = trans.app.toolbox.tools_by_id.get( tool_id, None ) + tool = trans.app.toolbox.get_tool( tool_id ) if not tool: return messages.NO_TOOL @@ -829,7 +829,7 @@ # have priority. # original_job = get_dataset_job( original_dataset ) - tool = trans.app.toolbox.tools_by_id.get( original_job.tool_id, None ) + tool = trans.app.toolbox.get_tool( original_job.tool_id ) if not tool: return messages.NO_TOOL tool_params = dict( [ ( p.name, p.value ) for p in original_job.parameters ] ) diff -r 7c3c507843740ce7cb766c11559bde58fdcc7916 -r e250efd2a19c0bb214f02f09451b3afb3165e401 lib/galaxy/web/controllers/user.py --- a/lib/galaxy/web/controllers/user.py +++ b/lib/galaxy/web/controllers/user.py @@ -925,7 +925,7 @@ filter( self.app.model.History.user==trans.user ). \ order_by( self.app.model.Job.create_time.desc() ).limit(1) tool_id = query[0][0] # Get first element in first row of query. - tool = self.get_toolbox().tools_by_id[ tool_id ] + tool = self.get_toolbox().get_tool( tool_id ) # Return tool info. tool_info = { diff -r 7c3c507843740ce7cb766c11559bde58fdcc7916 -r e250efd2a19c0bb214f02f09451b3afb3165e401 lib/galaxy/web/controllers/workflow.py --- a/lib/galaxy/web/controllers/workflow.py +++ b/lib/galaxy/web/controllers/workflow.py @@ -1306,16 +1306,7 @@ for job_id in job_ids: assert job_id in jobs_by_id, "Attempt to create workflow with job not connected to current history" job = jobs_by_id[ job_id ] - try: - tool = trans.app.toolbox.tools_by_id[ job.tool_id ] - except KeyError, e: - # Handle the case where the workflow requires a tool not available in the local Galaxy instance. - # The id value of tools installed from a Galaxy tool shed is a guid, but these tool's old_id - # attribute should contain what we're looking for. - for available_tool_id, available_tool in trans.app.toolbox.tools_by_id.items(): - if job.tool_id == available_tool.old_id: - tool = available_tool - break + tool = trans.app.toolbox.get_tool( job.tool_id ) param_values = job.get_param_values( trans.app ) associations = cleanup_param_values( tool.inputs, param_values ) # Doing it this way breaks dynamic parameters, backed out temporarily. @@ -1482,16 +1473,7 @@ # Execute module job = None if step.type == 'tool' or step.type is None: - try: - tool = trans.app.toolbox.tools_by_id[ step.tool_id ] - except KeyError, e: - # Handle the case where the workflow requires a tool not available in the local Galaxy instance. - # The id value of tools installed from a Galaxy tool shed is a guid, but these tool's old_id - # attribute should contain what we're looking for. - for available_tool_id, available_tool in trans.app.toolbox.tools_by_id.items(): - if step.tool_id == available_tool.old_id: - tool = available_tool - break + tool = trans.app.toolbox.get_tool( step.tool_id ) input_values = step.state.inputs # Connect up def callback( input, value, prefixed_name, prefixed_label ): diff -r 7c3c507843740ce7cb766c11559bde58fdcc7916 -r e250efd2a19c0bb214f02f09451b3afb3165e401 lib/galaxy/webapps/community/controllers/common.py --- a/lib/galaxy/webapps/community/controllers/common.py +++ b/lib/galaxy/webapps/community/controllers/common.py @@ -476,6 +476,200 @@ message += "<b>%s</b> - %s<br/>" % ( tool_file, correction_msg ) status = 'error' return message, status +def reset_all_repository_metadata( trans, id, **kwd ): + params = util.Params( kwd ) + message = util.restore_text( params.get( 'message', '' ) ) + status = params.get( 'status', 'done' ) + repository = get_repository( trans, id ) + log.debug( "Resetting all metadata on repository: %s" % repository.name ) + repo_dir = repository.repo_path + repo = hg.repository( get_configured_ui(), repo_dir ) + if len( repo ) == 1: + message, status = set_repository_metadata( trans, id, repository.tip, **kwd ) + else: + # The list of changeset_revisions refers to repository_metadata records that have been + # created or updated. When the following loop completes, we'll delete all repository_metadata + # records for this repository that do not have a changeset_revision value in this list. + changeset_revisions = [] + ancestor_changeset_revision = None + ancestor_metadata_dict = None + for changeset in repo.changelog: + current_changeset_revision = str( repo.changectx( changeset ) ) + ctx = get_changectx_for_changeset( trans, repo, current_changeset_revision ) + if current_changeset_revision == repository.tip: + current_metadata_dict, invalid_files = generate_metadata_for_repository_tip( trans, id, ctx, current_changeset_revision, repo_dir ) + else: + current_metadata_dict, invalid_files = generate_metadata_for_changeset_revision( trans, id, ctx, current_changeset_revision, repo_dir ) + if current_metadata_dict: + if ancestor_changeset_revision: + # Compare metadata from ancestor and current. The value of comparsion will be one of: + # 'no metadata' - no metadata for either ancestor or current, so continue from current + # 'equal' - ancestor metadata is equivalent to current metadata, so continue from current + # 'subset' - ancestor metadata is a subset of current metadata, so continue from current + # 'not equal and not subset' - ancestor metadata is neither equal to nor a subset of current + # metadata, so persist ancestor metadata. + comparison = compare_changeset_revisions( ancestor_changeset_revision, + ancestor_metadata_dict, + current_changeset_revision, + current_metadata_dict ) + if comparison in [ 'no metadata', 'equal', 'subset' ]: + ancestor_changeset_revision = current_changeset_revision + ancestor_metadata_dict = current_metadata_dict + elif comparison == 'not equal and not subset': + create_or_update_repository_metadata( trans, id, repository, ancestor_changeset_revision, ancestor_metadata_dict ) + # Keep track of the changeset_revisions that we've persisted. + changeset_revisions.append( ancestor_changeset_revision ) + ancestor_changeset_revision = None + ancestor_metadata_dict = None + else: + # We're either at the first change set in the change log or we have just created or updated + # a repository_metadata record. At this point we set the ancestor changeset to the current + # changeset for comparison in the next iteration. + ancestor_changeset_revision = current_changeset_revision + ancestor_metadata_dict = current_metadata_dict + if not ctx.children(): + # We're at the end of the change log. + create_or_update_repository_metadata( trans, id, repository, current_changeset_revision, current_metadata_dict ) + changeset_revisions.append( current_changeset_revision ) + ancestor_changeset_revision = None + ancestor_metadata_dict = None + elif ancestor_metadata_dict: + # Our current change set has no metadata, but our ancestor change set has metadata, so save it. + create_or_update_repository_metadata( trans, id, repository, ancestor_changeset_revision, ancestor_metadata_dict ) + # Keep track of the changeset_revisions that we've persisted. + changeset_revisions.append( ancestor_changeset_revision ) + ancestor_changeset_revision = None + ancestor_metadata_dict = None + clean_repository_metadata( trans, id, changeset_revisions ) +def clean_repository_metadata( trans, id, changeset_revisions ): + # Delete all repository_metadata reecords associated with the repository + # that have a changeset_revision that is not in changeset_revisions. + for repository_metadata in trans.sa_session.query( trans.model.RepositoryMetadata ) \ + .filter( trans.model.RepositoryMetadata.table.c.repository_id == trans.security.decode_id( id ) ): + if repository_metadata.changeset_revision not in changeset_revisions: + trans.sa_session.delete( repository_metadata ) + trans.sa_session.flush() +def create_or_update_repository_metadata( trans, id, repository, changeset_revision, metadata_dict ): + repository_metadata = get_repository_metadata_by_changeset_revision( trans, id, changeset_revision ) + if repository_metadata: + # Update RepositoryMetadata.metadata. + repository_metadata.metadata = metadata_dict + trans.sa_session.add( repository_metadata ) + trans.sa_session.flush() + else: + # Create a new repository_metadata table row. + repository_metadata = trans.model.RepositoryMetadata( repository.id, changeset_revision, metadata_dict ) + trans.sa_session.add( repository_metadata ) + trans.sa_session.flush() +def compare_changeset_revisions( ancestor_changeset_revision, ancestor_metadata_dict, current_changeset_revision, current_metadata_dict ): + # The metadata associated with ancestor_changeset_revision is ancestor_metadata_dict. This changeset_revision + # is an ancestor of current_changeset_revision which is associated with current_metadata_dict. + # + # TODO: a new repository_metadata record will be created only when this method returns the string + # 'not equal and not subset'. However, we're currently also returning the strings 'no metadata', + # 'equal' and 'subset', depending upon how the 2 change sets compare. We'll leave things this way + # for the current time in case we discover a use for these additional result strings. + # + # Get information about tools. + if 'tools' in ancestor_metadata_dict: + ancestor_tools = ancestor_metadata_dict[ 'tools' ] + else: + ancestor_tools = [] + if 'tools' in current_metadata_dict: + current_tools = current_metadata_dict[ 'tools' ] + else: + current_tools = [] + ancestor_guids = [] + for tool_dict in ancestor_tools: + ancestor_guids.append( tool_dict[ 'guid' ] ) + ancestor_guids.sort() + current_guids = [] + for tool_dict in current_tools: + current_guids.append( tool_dict[ 'guid' ] ) + current_guids.sort() + # Get information about workflows. + if 'workflows' in ancestor_metadata_dict: + ancestor_workflows = ancestor_metadata_dict[ 'workflows' ] + else: + ancestor_workflows = [] + if 'workflows' in current_metadata_dict: + current_workflows = current_metadata_dict[ 'workflows' ] + else: + current_workflows = [] + # Get information about datatypes. + if 'datatypes' in ancestor_metadata_dict: + ancestor_datatypes = ancestor_metadata_dict[ 'datatypes' ] + else: + ancestor_datatypes = [] + if 'datatypes' in current_metadata_dict: + current_datatypes = current_metadata_dict[ 'datatypes' ] + else: + current_datatypes = [] + # Handle case where no metadata exists for either changeset. + if not ancestor_guids and not current_guids and not ancestor_workflows and not current_workflows and not ancestor_datatypes and not current_datatypes: + return 'no metadata' + workflow_comparison = compare_workflows( ancestor_workflows, current_workflows ) + datatype_comparison = compare_datatypes( ancestor_datatypes, current_datatypes ) + # Handle case where all metadata is the same. + if ancestor_guids == current_guids and workflow_comparison == 'equal' and datatype_comparison == 'equal': + return 'equal' + if workflow_comparison == 'subset' and datatype_comparison == 'subset': + is_subset = True + for guid in ancestor_guids: + if guid not in current_guids: + is_subset = False + break + if is_subset: + return 'subset' + return 'not equal and not subset' +def compare_workflows( ancestor_workflows, current_workflows ): + # Determine if ancestor_workflows is the same as current_workflows + # or if ancestor_workflows is a subset of current_workflows. + if len( ancestor_workflows ) <= len( current_workflows ): + for ancestor_workflow in ancestor_workflows: + # Currently the only way to differentiate workflows is by name. + ancestor_workflow_name = ancestor_workflow[ 'name' ] + num_ancestor_workflow_steps = len( ancestor_workflow[ 'steps' ] ) + found_in_current = False + for current_workflow in current_workflows: + # Assume that if the name and number of steps are euqal, + # then the workflows are the same. Of course, this may + # not be true... + if current_workflow[ 'name' ] == ancestor_workflow_name and len( current_workflow[ 'steps' ] ) == num_ancestor_workflow_steps: + found_in_current = True + break + if not found_in_current: + return 'not equal and not subset' + if len( ancestor_workflows ) == len( current_workflows ): + return 'equal' + else: + return 'subset' + return 'not equal and not subset' +def compare_datatypes( ancestor_datatypes, current_datatypes ): + # Determine if ancestor_datatypes is the same as current_datatypes + # or if ancestor_datatypes is a subset of current_datatypes. Each + # datatype dict looks something like: + # {"dtype": "galaxy.datatypes.images:Image", "extension": "pdf", "mimetype": "application/pdf"} + if len( ancestor_datatypes ) <= len( current_datatypes ): + for ancestor_datatype in ancestor_datatypes: + # Currently the only way to differentiate datatypes is by name. + ancestor_datatype_dtype = ancestor_datatype[ 'dtype' ] + ancestor_datatype_extension = ancestor_datatype[ 'extension' ] + ancestor_datatype_mimetype = ancestor_datatype[ 'mimetype' ] + found_in_current = False + for current_datatype in current_datatypes: + if current_datatype[ 'dtype' ] == ancestor_datatype_dtype and \ + current_datatype[ 'extension' ] == ancestor_datatype_extension and \ + current_datatype[ 'mimetype' ] == ancestor_datatype_mimetype: + found_in_current = True + break + if not found_in_current: + return 'not equal and not subset' + if len( ancestor_datatypes ) == len( current_datatypes ): + return 'equal' + else: + return 'subset' + return 'not equal and not subset' def get_repository_by_name( trans, name ): """Get a repository from the database via name""" return trans.sa_session.query( trans.model.Repository ).filter_by( name=name ).one() diff -r 7c3c507843740ce7cb766c11559bde58fdcc7916 -r e250efd2a19c0bb214f02f09451b3afb3165e401 lib/galaxy/webapps/community/controllers/repository.py --- a/lib/galaxy/webapps/community/controllers/repository.py +++ b/lib/galaxy/webapps/community/controllers/repository.py @@ -1247,15 +1247,21 @@ message = "The selected files were deleted from the repository." else: message = 'No changes to repository.' - # Set metadata on the repository tip + # Set metadata on the repository tip. error_message, status = set_repository_metadata( trans, id, repository.tip, **kwd ) if error_message: + # If there is an error, display it. message = '%s<br/>%s' % ( message, error_message ) return trans.response.send_redirect( web.url_for( controller='repository', action='manage_repository', id=id, message=message, status=status ) ) + else: + # If no error occurred in setting metadata on the repository tip, reset metadata on all + # changeset revisions for the repository. This will result in a more standardized set of + # valid repository revisions that can be installed. + reset_all_repository_metadata( trans, id, **kwd ) else: message = "Select at least 1 file to delete from the repository before clicking <b>Delete selected files</b>." status = "error" @@ -1723,206 +1729,14 @@ status=status ) ) @web.expose def reset_all_metadata( self, trans, id, **kwd ): - params = util.Params( kwd ) - message = util.restore_text( params.get( 'message', '' ) ) - status = params.get( 'status', 'done' ) - repository = get_repository( trans, id ) - repo_dir = repository.repo_path - repo = hg.repository( get_configured_ui(), repo_dir ) - if len( repo ) == 1: - message, status = set_repository_metadata( trans, id, repository.tip, **kwd ) - else: - # The list of changeset_revisions refers to repository_metadata records that have been - # created or updated. When the following loop completes, we'll delete all repository_metadata - # records for this repository that do not have a changeset_revision value in this list. - changeset_revisions = [] - ancestor_changeset_revision = None - ancestor_metadata_dict = None - for changeset in repo.changelog: - current_changeset_revision = str( repo.changectx( changeset ) ) - ctx = get_changectx_for_changeset( trans, repo, current_changeset_revision ) - if current_changeset_revision == repository.tip: - current_metadata_dict, invalid_files = generate_metadata_for_repository_tip( trans, id, ctx, current_changeset_revision, repo_dir ) - else: - current_metadata_dict, invalid_files = generate_metadata_for_changeset_revision( trans, id, ctx, current_changeset_revision, repo_dir ) - if current_metadata_dict: - if ancestor_changeset_revision: - # Compare metadata from ancestor and current. The value of comparsion will be one of: - # 'no metadata' - no metadata for either ancestor or current, so continue from current - # 'equal' - ancestor metadata is equivalent to current metadata, so continue from current - # 'subset' - ancestor metadata is a subset of current metadata, so continue from current - # 'not equal and not subset' - ancestor metadata is neither equal to nor a subset of current - # metadata, so persist ancestor metadata. - comparison = self.__compare_changeset_revisions( ancestor_changeset_revision, - ancestor_metadata_dict, - current_changeset_revision, - current_metadata_dict ) - if comparison in [ 'no metadata', 'equal', 'subset' ]: - ancestor_changeset_revision = current_changeset_revision - ancestor_metadata_dict = current_metadata_dict - elif comparison == 'not equal and not subset': - self.__create_or_update_repository_metadata( trans, id, repository, ancestor_changeset_revision, ancestor_metadata_dict ) - # Keep track of the changeset_revisions that we've persisted. - changeset_revisions.append( ancestor_changeset_revision ) - ancestor_changeset_revision = None - ancestor_metadata_dict = None - else: - # We're either at the first change set in the change log or we have just created or updated - # a repository_metadata record. At this point we set the ancestor changeset to the current - # changeset for comparison in the next iteration. - ancestor_changeset_revision = current_changeset_revision - ancestor_metadata_dict = current_metadata_dict - if not ctx.children(): - # We're at the end of the change log. - self.__create_or_update_repository_metadata( trans, id, repository, current_changeset_revision, current_metadata_dict ) - changeset_revisions.append( current_changeset_revision ) - ancestor_changeset_revision = None - ancestor_metadata_dict = None - elif ancestor_metadata_dict: - # Our current change set has no metadata, but our ancestor change set has metadata, so save it. - self.__create_or_update_repository_metadata( trans, id, repository, ancestor_changeset_revision, ancestor_metadata_dict ) - # Keep track of the changeset_revisions that we've persisted. - changeset_revisions.append( ancestor_changeset_revision ) - ancestor_changeset_revision = None - ancestor_metadata_dict = None - self.__clean_repository_metadata( trans, id, changeset_revisions ) - if not message: - message = "Repository metadata has been reset." - status = 'done' + reset_all_repository_metadata( trans, id, **kwd ) + message = "All repository metadata has been reset." + status = 'done' return trans.response.send_redirect( web.url_for( controller='repository', action='manage_repository', id=id, message=message, status=status ) ) - def __clean_repository_metadata( self, trans, id, changeset_revisions ): - # Delete all repository_metadata reecords associated with the repository - # that have a changeset_revision that is not in changeset_revisions. - for repository_metadata in trans.sa_session.query( trans.model.RepositoryMetadata ) \ - .filter( trans.model.RepositoryMetadata.table.c.repository_id == trans.security.decode_id( id ) ): - if repository_metadata.changeset_revision not in changeset_revisions: - trans.sa_session.delete( repository_metadata ) - trans.sa_session.flush() - def __create_or_update_repository_metadata( self, trans, id, repository, changeset_revision, metadata_dict ): - repository_metadata = get_repository_metadata_by_changeset_revision( trans, id, changeset_revision ) - if repository_metadata: - # Update RepositoryMetadata.metadata. - repository_metadata.metadata = metadata_dict - trans.sa_session.add( repository_metadata ) - trans.sa_session.flush() - else: - # Create a new repository_metadata table row. - repository_metadata = trans.model.RepositoryMetadata( repository.id, changeset_revision, metadata_dict ) - trans.sa_session.add( repository_metadata ) - trans.sa_session.flush() - def __compare_changeset_revisions( self, ancestor_changeset_revision, ancestor_metadata_dict, current_changeset_revision, current_metadata_dict ): - # The metadata associated with ancestor_changeset_revision is ancestor_metadata_dict. This changeset_revision - # is an ancestor of current_changeset_revision which is associated with current_metadata_dict. - # - # TODO: a new repository_metadata record will be created only when this method returns the string - # 'not equal and not subset'. However, we're currently also returning the strings 'no metadata', - # 'equal' and 'subset', depending upon how the 2 change sets compare. We'll leave things this way - # for the current time in case we discover a use for these additional result strings. - # - # Get information about tools. - if 'tools' in ancestor_metadata_dict: - ancestor_tools = ancestor_metadata_dict[ 'tools' ] - else: - ancestor_tools = [] - if 'tools' in current_metadata_dict: - current_tools = current_metadata_dict[ 'tools' ] - else: - current_tools = [] - ancestor_guids = [] - for tool_dict in ancestor_tools: - ancestor_guids.append( tool_dict[ 'guid' ] ) - ancestor_guids.sort() - current_guids = [] - for tool_dict in current_tools: - current_guids.append( tool_dict[ 'guid' ] ) - current_guids.sort() - # Get information about workflows. - if 'workflows' in ancestor_metadata_dict: - ancestor_workflows = ancestor_metadata_dict[ 'workflows' ] - else: - ancestor_workflows = [] - if 'workflows' in current_metadata_dict: - current_workflows = current_metadata_dict[ 'workflows' ] - else: - current_workflows = [] - # Get information about datatypes. - if 'datatypes' in ancestor_metadata_dict: - ancestor_datatypes = ancestor_metadata_dict[ 'datatypes' ] - else: - ancestor_datatypes = [] - if 'datatypes' in current_metadata_dict: - current_datatypes = current_metadata_dict[ 'datatypes' ] - else: - current_datatypes = [] - # Handle case where no metadata exists for either changeset. - if not ancestor_guids and not current_guids and not ancestor_workflows and not current_workflows and not ancestor_datatypes and not current_datatypes: - return 'no metadata' - workflow_comparison = self.__compare_workflows( ancestor_workflows, current_workflows ) - datatype_comparison = self.__compare_datatypes( ancestor_datatypes, current_datatypes ) - # Handle case where all metadata is the same. - if ancestor_guids == current_guids and workflow_comparison == 'equal' and datatype_comparison == 'equal': - return 'equal' - if workflow_comparison == 'subset' and datatype_comparison == 'subset': - is_subset = True - for guid in ancestor_guids: - if guid not in current_guids: - is_subset = False - break - if is_subset: - return 'subset' - return 'not equal and not subset' - def __compare_workflows( self, ancestor_workflows, current_workflows ): - # Determine if ancestor_workflows is the same as current_workflows - # or if ancestor_workflows is a subset of current_workflows. - if len( ancestor_workflows ) <= len( current_workflows ): - for ancestor_workflow in ancestor_workflows: - # Currently the only way to differentiate workflows is by name. - ancestor_workflow_name = ancestor_workflow[ 'name' ] - num_ancestor_workflow_steps = len( ancestor_workflow[ 'steps' ] ) - found_in_current = False - for current_workflow in current_workflows: - # Assume that if the name and number of steps are euqal, - # then the workflows are the same. Of course, this may - # not be true... - if current_workflow[ 'name' ] == ancestor_workflow_name and len( current_workflow[ 'steps' ] ) == num_ancestor_workflow_steps: - found_in_current = True - break - if not found_in_current: - return 'not equal and not subset' - if len( ancestor_workflows ) == len( current_workflows ): - return 'equal' - else: - return 'subset' - return 'not equal and not subset' - def __compare_datatypes( self, ancestor_datatypes, current_datatypes ): - # Determine if ancestor_datatypes is the same as current_datatypes - # or if ancestor_datatypes is a subset of current_datatypes. Each - # datatype dict looks something like: - # {"dtype": "galaxy.datatypes.images:Image", "extension": "pdf", "mimetype": "application/pdf"} - if len( ancestor_datatypes ) <= len( current_datatypes ): - for ancestor_datatype in ancestor_datatypes: - # Currently the only way to differentiate datatypes is by name. - ancestor_datatype_dtype = ancestor_datatype[ 'dtype' ] - ancestor_datatype_extension = ancestor_datatype[ 'extension' ] - ancestor_datatype_mimetype = ancestor_datatype[ 'mimetype' ] - found_in_current = False - for current_datatype in current_datatypes: - if current_datatype[ 'dtype' ] == ancestor_datatype_dtype and \ - current_datatype[ 'extension' ] == ancestor_datatype_extension and \ - current_datatype[ 'mimetype' ] == ancestor_datatype_mimetype: - found_in_current = True - break - if not found_in_current: - return 'not equal and not subset' - if len( ancestor_datatypes ) == len( current_datatypes ): - return 'equal' - else: - return 'subset' - return 'not equal and not subset' @web.expose def display_tool( self, trans, repository_id, tool_config, changeset_revision, **kwd ): params = util.Params( kwd ) diff -r 7c3c507843740ce7cb766c11559bde58fdcc7916 -r e250efd2a19c0bb214f02f09451b3afb3165e401 lib/galaxy/webapps/community/controllers/upload.py --- a/lib/galaxy/webapps/community/controllers/upload.py +++ b/lib/galaxy/webapps/community/controllers/upload.py @@ -156,15 +156,21 @@ message += " %d files were removed from the repository root." % len( files_to_remove ) else: message = 'No changes to repository.' - # Set metadata on the repository tip + # Set metadata on the repository tip. error_message, status = set_repository_metadata( trans, repository_id, repository.tip, content_alert_str=content_alert_str, **kwd ) if error_message: + # If there is an error, display it. message = '%s<br/>%s' % ( message, error_message ) return trans.response.send_redirect( web.url_for( controller='repository', action='manage_repository', id=repository_id, message=message, status=status ) ) + else: + # If no error occurred in setting metadata on the repository tip, reset metadata on all + # changeset revisions for the repository. This will result in a more standardized set of + # valid repository revisions that can be installed. + reset_all_repository_metadata( trans, repository_id, **kwd ) trans.response.send_redirect( web.url_for( controller='repository', action='browse_repository', id=repository_id, @@ -261,7 +267,7 @@ # file is being uploaded by parsing the file and adding new entries # to the in-memory trans.app.tool_data_tables dictionary as well as # appending them to the shed's tool_data_table_conf.xml file on disk. - error, message = handle_sample_tool_data_table_conf_file( trans, filename_in_archive ) + error, message = handle_sample_tool_data_table_conf_file( trans.app, filename_in_archive ) if error: return False, message, files_to_remove, content_alert_str if filename_in_archive.endswith( '.loc.sample' ): diff -r 7c3c507843740ce7cb766c11559bde58fdcc7916 -r e250efd2a19c0bb214f02f09451b3afb3165e401 lib/galaxy/workflow/modules.py --- a/lib/galaxy/workflow/modules.py +++ b/lib/galaxy/workflow/modules.py @@ -166,17 +166,7 @@ def __init__( self, trans, tool_id ): self.trans = trans self.tool_id = tool_id - try: - self.tool = trans.app.toolbox.tools_by_id[ tool_id ] - except KeyError, e: - # Handle the case where the workflow requires a tool not available in the local Galaxy instance. - self.tool = None - # The id value of tools installed from a Galaxy tool shed is a guid, but - # these tool's old_id attribute should contain what we're looking for. - for available_tool_id, available_tool in trans.app.toolbox.tools_by_id.items(): - if tool_id == available_tool.old_id: - self.tool = available_tool - break + self.tool = trans.app.toolbox.get_tool( tool_id ) self.post_job_actions = {} self.workflow_outputs = [] self.state = None @@ -206,12 +196,14 @@ tool_id = step.tool_id install_tool_id = None if trans.app.toolbox and tool_id not in trans.app.toolbox.tools_by_id: - # The id value of tools installed from a Galaxy tool shed is a guid, but - # these tool's old_id attribute should contain what we're looking for. - for available_tool_id, available_tool in trans.app.toolbox.tools_by_id.items(): - if tool_id == available_tool.old_id: - install_tool_id = available_tool_id - break + # Handle the case where the tool was used when the tool was included in the Galaxy distribution, + # but now the tool is contained in an installed tool shed repository. In this case, the original + # tool id can be mapped to the new tool id, which is the tool's guid in the tool shed repository. + tool_id_guid_map = trans.sa_session.query( trans.model.ToolIdGuidMap ) \ + .filter( trans.model.ToolIdGuidMap.table.c.tool_id == tool_id ) \ + .first() + if tool_id_guid_map: + install_tool_id = tool_id_guid_map.guid if ( trans.app.toolbox and tool_id in trans.app.toolbox.tools_by_id ) or install_tool_id: module = Class( trans, tool_id ) module.state = DefaultToolState() diff -r 7c3c507843740ce7cb766c11559bde58fdcc7916 -r e250efd2a19c0bb214f02f09451b3afb3165e401 templates/dataset/edit_attributes.mako --- a/templates/dataset/edit_attributes.mako +++ b/templates/dataset/edit_attributes.mako @@ -48,7 +48,7 @@ Info: </label><div style="float: left; width: 250px; margin-right: 10px;"> - <input type="text" name="info" value="${data.info}" size="40"/> + <textarea name="info" cols="40" rows="2">${data.info | h}</textarea></div><div style="clear: both"></div></div> @@ -58,7 +58,7 @@ Annotation / Notes: </label><div style="float: left; width: 250px; margin-right: 10px;"> - <textarea name="annotation" cols="40" rows="2">${data_annotation}</textarea> + <textarea name="annotation" cols="40" rows="2">${data_annotation | h}</textarea></div><div style="clear: both"></div><div class="toolParamHelp">Add an annotation or notes to a dataset; annotations are available when a history is viewed.</div> diff -r 7c3c507843740ce7cb766c11559bde58fdcc7916 -r e250efd2a19c0bb214f02f09451b3afb3165e401 templates/history/display_structured.mako --- a/templates/history/display_structured.mako +++ b/templates/history/display_structured.mako @@ -98,8 +98,9 @@ <div class="tool toolForm"><% - if job.tool_id in trans.app.toolbox.tools_by_id: - tool_name = trans.app.toolbox.tools_by_id[job.tool_id].name + tool = trans.app.toolbox.get_tool( job.tool_id ) + if tool: + tool_name = tool.name else: tool_name = "Unknown tool with id '%s'" % job.tool_id %> diff -r 7c3c507843740ce7cb766c11559bde58fdcc7916 -r e250efd2a19c0bb214f02f09451b3afb3165e401 templates/workflow/build_from_current_history.mako --- a/templates/workflow/build_from_current_history.mako +++ b/templates/workflow/build_from_current_history.mako @@ -103,7 +103,7 @@ cls += " toolFormDisabled" disabled = True else: - tool = app.toolbox.tools_by_id.get( job.tool_id, None ) + tool = app.toolbox.get_tool( job.tool_id ) if tool: tool_name = tool.name if tool is None or not( tool.is_workflow_compatible ): diff -r 7c3c507843740ce7cb766c11559bde58fdcc7916 -r e250efd2a19c0bb214f02f09451b3afb3165e401 templates/workflow/display.mako --- a/templates/workflow/display.mako +++ b/templates/workflow/display.mako @@ -83,15 +83,7 @@ <tr><td> %if step.type == 'tool' or step.type is None: <% - try: - tool = trans.app.toolbox.tools_by_id[ step.tool_id ] - except KeyError, e: - # The id value of tools installed from a Galaxy tool shed is a guid, but - # these tool's old_id attribute should contain what we're looking for. - for available_tool_id, available_tool in trans.app.toolbox.tools_by_id.items(): - if step.tool_id == available_tool.old_id: - tool = available_tool - break + tool = trans.app.toolbox.get_tool( step.tool_id ) %><div class="toolForm"><div class="toolFormTitle">Step ${int(step.order_index)+1}: ${tool.name}</div> diff -r 7c3c507843740ce7cb766c11559bde58fdcc7916 -r e250efd2a19c0bb214f02f09451b3afb3165e401 templates/workflow/run.mako --- a/templates/workflow/run.mako +++ b/templates/workflow/run.mako @@ -364,15 +364,7 @@ %for i, step in enumerate( steps ): %if step.type == 'tool' or step.type is None: <% - try: - tool = trans.app.toolbox.tools_by_id[ step.tool_id ] - except KeyError, e: - # The id value of tools installed from a Galaxy tool shed is a guid, but - # these tool's old_id attribute should contain what we're looking for. - for available_tool_id, available_tool in trans.app.toolbox.tools_by_id.items(): - if step.tool_id == available_tool.old_id: - tool = available_tool - break + tool = trans.app.toolbox.get_tool( step.tool_id ) %><input type="hidden" name="${step.id}|tool_state" value="${step.state.encode( tool, app )}"><div class="toolForm"> diff -r 7c3c507843740ce7cb766c11559bde58fdcc7916 -r e250efd2a19c0bb214f02f09451b3afb3165e401 test-data/tophat_out1j.bed --- a/test-data/tophat_out1j.bed +++ b/test-data/tophat_out1j.bed @@ -1,3 +1,3 @@ track name=junctions description="TopHat junctions" -test_chromosome 180 400 JUNC00000001 26 + 180 400 255,0,0 2 70,50 0,170 -test_chromosome 349 550 JUNC00000002 22 + 349 550 255,0,0 2 51,50 0,151 +test_chromosome 180 400 JUNC00000001 23 + 180 400 255,0,0 2 70,50 0,170 +test_chromosome 350 550 JUNC00000002 24 + 350 550 255,0,0 2 50,50 0,150 diff -r 7c3c507843740ce7cb766c11559bde58fdcc7916 -r e250efd2a19c0bb214f02f09451b3afb3165e401 test-data/tophat_out2j.bed --- a/test-data/tophat_out2j.bed +++ b/test-data/tophat_out2j.bed @@ -1,3 +1,3 @@ track name=junctions description="TopHat junctions" -test_chromosome 177 400 JUNC00000001 61 + 177 400 255,0,0 2 73,50 0,173 -test_chromosome 350 550 JUNC00000002 45 + 350 550 255,0,0 2 50,50 0,150 +test_chromosome 179 400 JUNC00000001 38 + 179 400 255,0,0 2 71,50 0,171 +test_chromosome 350 549 JUNC00000002 30 + 350 549 255,0,0 2 50,49 0,150 diff -r 7c3c507843740ce7cb766c11559bde58fdcc7916 -r e250efd2a19c0bb214f02f09451b3afb3165e401 test-data/tophat_out3j.bed --- a/test-data/tophat_out3j.bed +++ b/test-data/tophat_out3j.bed @@ -1,3 +1,3 @@ track name=junctions description="TopHat junctions" -test_chromosome 177 400 JUNC00000001 32 + 177 400 255,0,0 2 73,50 0,173 -test_chromosome 350 550 JUNC00000002 26 + 350 550 255,0,0 2 50,50 0,150 +test_chromosome 180 400 JUNC00000001 23 + 180 400 255,0,0 2 70,50 0,170 +test_chromosome 350 550 JUNC00000002 24 + 350 550 255,0,0 2 50,50 0,150 diff -r 7c3c507843740ce7cb766c11559bde58fdcc7916 -r e250efd2a19c0bb214f02f09451b3afb3165e401 test-data/tophat_out4j.bed --- a/test-data/tophat_out4j.bed +++ b/test-data/tophat_out4j.bed @@ -1,3 +1,3 @@ track name=junctions description="TopHat junctions" -test_chromosome 180 402 JUNC00000001 49 + 180 402 255,0,0 2 70,52 0,170 -test_chromosome 349 550 JUNC00000002 38 + 349 550 255,0,0 2 51,50 0,151 +test_chromosome 179 400 JUNC00000001 38 + 179 400 255,0,0 2 71,50 0,171 +test_chromosome 350 549 JUNC00000002 30 + 350 549 255,0,0 2 50,49 0,150 diff -r 7c3c507843740ce7cb766c11559bde58fdcc7916 -r e250efd2a19c0bb214f02f09451b3afb3165e401 test/functional/test_toolbox.py --- a/test/functional/test_toolbox.py +++ b/test/functional/test_toolbox.py @@ -149,7 +149,7 @@ # Push all the toolbox tests to module level G = globals() for i, tool_id in enumerate( toolbox.tools_by_id ): - tool = toolbox.tools_by_id[ tool_id ] + tool = toolbox.get_tool( tool_id ) if tool.tests: # Create a new subclass of ToolTestCase dynamically adding methods # names test_tool_XXX that run each test defined in the tool. diff -r 7c3c507843740ce7cb766c11559bde58fdcc7916 -r e250efd2a19c0bb214f02f09451b3afb3165e401 tools/gatk/variant_eval.xml --- a/tools/gatk/variant_eval.xml +++ b/tools/gatk/variant_eval.xml @@ -1,4 +1,4 @@ -<tool id="gatk_variant_eval" name="Eval Variants" version="0.0.4"> +<tool id="gatk_variant_eval" name="Eval Variants" version="0.0.5"><description></description><requirements><requirement type="package" version="1.3">gatk</requirement> @@ -329,11 +329,12 @@ <when value="advanced"><repeat name="stratifications" title="Stratification"><param name="select_exps" value="" type="text" label="Stratification Expression"> - <sanitizer> - <valid> - <add value="""/> - </valid> - </sanitizer> + <sanitizer> + <valid initial="string.printable"> + <remove value="'"/> + </valid> + <mapping initial="none"/> + </sanitizer></param><param name="select_name" value="" type="text" label="Name"/></repeat> diff -r 7c3c507843740ce7cb766c11559bde58fdcc7916 -r e250efd2a19c0bb214f02f09451b3afb3165e401 tools/gatk/variant_filtration.xml --- a/tools/gatk/variant_filtration.xml +++ b/tools/gatk/variant_filtration.xml @@ -1,9 +1,10 @@ -<tool id="gatk_variant_filtration" name="Variant Filtration" version="0.0.3"> +<tool id="gatk_variant_filtration" name="Variant Filtration" version="0.0.4"><description>on VCF files</description><requirements><requirement type="package" version="1.3">gatk</requirement></requirements><command interpreter="python">gatk_wrapper.py + #from binascii import hexlify --max_jvm_heap_fraction "1" --stdout "${output_log}" -d "--variant:variant,%(file_type)s" "${reference_source.input_variant}" "${reference_source.input_variant.ext}" "input_variant" @@ -17,12 +18,11 @@ #if $reference_source.reference_source_selector != "history": -R "${reference_source.ref_file.fields.path}" #end if + ' #for $variant_filter in $variant_filters: - --${variant_filter.is_genotype_filter}Expression "${variant_filter.filter_expression}" - --${variant_filter.is_genotype_filter}Name "${variant_filter.filter_name}" + #set $variant_filter = "--%sExpression '%s' --%sName '%s'" % ( str( $variant_filter.is_genotype_filter ), str( $variant_filter.filter_expression ), str( $variant_filter.is_genotype_filter ), str( $variant_filter.filter_name ) ) + -o '${ hexlify( $variant_filter ) }' #end for - ' - #if str( $mask_rod_bind_type.mask_rod_bind_type_selector ) == 'set_mask': -d "--mask:${mask_rod_bind_type.mask_rod_name},%(file_type)s" "${mask_rod_bind_type.input_mask_rod}" "${mask_rod_bind_type.input_mask_rod.ext}" "input_mask_${mask_rod_bind_type.mask_rod_name}" @@ -125,7 +125,6 @@ <sanitizer><valid initial="string.printable"><remove value="'"/> - <remove value="""/></valid><mapping initial="none"/></sanitizer> diff -r 7c3c507843740ce7cb766c11559bde58fdcc7916 -r e250efd2a19c0bb214f02f09451b3afb3165e401 tools/new_operations/concat.xml --- a/tools/new_operations/concat.xml +++ b/tools/new_operations/concat.xml @@ -1,4 +1,4 @@ -<tool id="gops_concat_1" name="Concatenate"> +<tool id="gops_concat_1" name="Concatenate" version="1.0.1"><description>two datasets into one dataset</description><command interpreter="python">gops_concat.py $input1 $input2 $output -1 ${input1.metadata.chromCol},${input1.metadata.startCol},${input1.metadata.endCol},${input1.metadata.strandCol} -2 ${input2.metadata.chromCol},${input2.metadata.startCol},${input2.metadata.endCol},${input2.metadata.strandCol} $sameformat</command><inputs> diff -r 7c3c507843740ce7cb766c11559bde58fdcc7916 -r e250efd2a19c0bb214f02f09451b3afb3165e401 tools/new_operations/gops_concat.py --- a/tools/new_operations/gops_concat.py +++ b/tools/new_operations/gops_concat.py @@ -43,6 +43,7 @@ chrom_col=chr_col_1, start_col=start_col_1, end_col=end_col_1, + strand_col=strand_col_1, fix_strand=True ) g2 = NiceReaderWrapper( fileinput.FileInput( in_file_2 ), @@ -52,9 +53,6 @@ strand_col=strand_col_2, fix_strand=True ) - if strand_col_1 >= 0: - g1.strand_col = strand_col_1 - out_file = open( out_fname, "w" ) try: diff -r 7c3c507843740ce7cb766c11559bde58fdcc7916 -r e250efd2a19c0bb214f02f09451b3afb3165e401 tools/ngs_rna/tophat_wrapper.py --- a/tools/ngs_rna/tophat_wrapper.py +++ b/tools/ngs_rna/tophat_wrapper.py @@ -210,6 +210,7 @@ tmp_stdout = open( tmp_out, 'wb' ) tmp_err = tempfile.NamedTemporaryFile().name tmp_stderr = open( tmp_err, 'wb' ) + print cmd proc = subprocess.Popen( args=cmd, shell=True, cwd=".", stdout=tmp_stdout, stderr=tmp_stderr ) returncode = proc.wait() tmp_stderr.close() diff -r 7c3c507843740ce7cb766c11559bde58fdcc7916 -r e250efd2a19c0bb214f02f09451b3afb3165e401 tools/ngs_rna/tophat_wrapper.xml --- a/tools/ngs_rna/tophat_wrapper.xml +++ b/tools/ngs_rna/tophat_wrapper.xml @@ -518,7 +518,7 @@ <test><!-- Tophat commands: bowtie-build -f test-data/tophat_in1.fasta tophat_in1 - tophat -o tmp_dir -p 1 -a 8 -m 0 -i 70 -I 500000 -F 0.15 -g 40 +allow-indels +coverage-search +min-coverage-intron 50 +max-coverage-intro 20000 +segment-mismatches 2 +segment-length 25 +closure-search +min-closure-exon 50 +min-closure-intron 50 +max-closure-intro 5000 +microexon-search tophat_in1 test-data/tophat_in2.fastqsanger + tophat -o tmp_dir -p 1 -a 8 -m 0 -i 70 -I 500000 -F 0.15 -g 40 +coverage-search +min-coverage-intron 50 +max-coverage-intro 20000 +segment-mismatches 2 +segment-length 25 +closure-search +min-closure-exon 50 +min-closure-intron 50 +max-closure-intro 5000 +microexon-search tophat_in1 test-data/tophat_in2.fastqsanger Replace the + with double-dash Rename the files in tmp_dir appropriately --> @@ -561,7 +561,7 @@ <!-- Test base-space paired-end reads with user-supplied reference fasta and full parameters --><test><!-- TopHat commands: - tophat -o tmp_dir -r 20 -p 1 -a 8 -m 0 -i 70 -I 500000 -F 0.15 -g 40 +coverage-search +min-coverage-intron 50 +max-coverage-intro 20000 +segment-mismatches 2 +segment-length 25 +closure-search +min-closure-exon 50 +min-closure-intron 50 +max-closure-intron 5000 +microexon-search tophat_in1 test-data/tophat_in2.fastqsanger test-data/tophat_in3.fastqsanger + tophat -o tmp_dir -r 20 -p 1 -a 8 -m 0 -i 70 -I 500000 -F 0.15 -g 40 +coverage-search +min-coverage-intron 50 +max-coverage-intro 20000 +segment-mismatches 2 +segment-length 25 +microexon-search tophat_in1 test-data/tophat_in2.fastqsanger test-data/tophat_in3.fastqsanger Replace the + with double-dash Rename the files in tmp_dir appropriately --> @@ -589,13 +589,7 @@ <param name="use_annotations" value="No" /><param name="use_juncs" value="No" /><param name="no_novel_juncs" value="No" /> - <param name="use_search" value="Yes" /> - <param name="min_closure_exon" value="50" /> - <param name="min_closure_intron" value="50" /> - <param name="max_closure_intron" value="5000" /> - <param name="use_search" value="Yes" /> - <param name="min_coverage_intron" value="50" /> - <param name="max_coverage_intron" value="20000" /> + <param name="use_search" value="No" /><param name="microexon_search" value="Yes" /><output name="junctions" file="tophat_out4j.bed" /><output name="accepted_hits" file="tophat_out4h.bam" compare="sim_size" /> Repository URL: https://bitbucket.org/galaxy/galaxy-central/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email.