def renderclientaccess(f, *args, **kwargs): """Decorator allowing functions asking for host, port, owner, project, client_script to default to a connection defined by :class:`RenderClient` object using its :func:`RenderClient.make_kwargs` method. Will also attempt to derive a :class:`RenderClient` from an input :class:`Render` object and fail if client scripts cannot be reached. Parameters ---------- f : func function to decorate Returns ------- obj output of decorated function """ args, kwargs = fitargspec(f, args, kwargs) render = kwargs.get('render') if render is not None: if not isinstance(render, RenderClient): if isinstance(render, Render): render = RenderClient(**render.make_kwargs(**kwargs)) else: raise ValueError( 'invalid RenderClient object type {} specified!'.format( type(render))) return f(*args, **render.make_kwargs(**kwargs)) else: try: client_script = kwargs.get('client_script') cs_valid = os.path.isfile(client_script) except TypeError: try: client_scripts = kwargs.get('client_scripts') if os.path.isdir(client_scripts): client_script = os.path.join(client_scripts, 'run_ws_client.sh') cs_valid = os.path.isfile(client_script) else: raise ClientScriptError( 'invalid client_scripts directory {}'.format( client_scripts)) except TypeError: raise ClientScriptError( 'No client script information specified: ' 'client_scripts={} client_script={}'.format( kwargs.get('client_scripts'), kwargs.get('client_script'))) if not cs_valid: # TODO should also check for executability raise ClientScriptError( 'invalid client script: {} not a file'.format(client_script)) return f(*args, **kwargs)
def sanitize_cmd(cmd): def jbool_str(c): return str(c) if type(c) is not bool else "true" if c else "false" if any([i is None for i in cmd]): raise ClientScriptError('missing argument in command "{}"'.format( map(str, cmd))) return map(jbool_str, cmd)
def call_run_ws_client(className, add_args=[], renderclient=None, memGB=None, client_script=None, **kwargs): """simple call for run_ws_client.sh -- all arguments set in add_args Parameters ---------- className : str Render java client classname to call as first argv for Render's call_run_ws_client.sh wrapper script add_args : :obj:`list` of :obj:`str`, optional command line arguments renderclient : :class:`renderapi.render.RenderClient`, optional render client connection object memGB : str, optional GB memory for this java process (defaults to '1G' or value defined in renderclient) client_script : str, optional client script to be used as the Render library's call_run_ws_client.sh wrapper script (this option overrides value in renderclient) subprocess_mode: str, optional subprocess mode 'call', 'check_call', 'check_output' (default 'call') Returns ------- obj result of subprocess_mode call """ logger.debug('call_run_ws_client -- classname:{} add_args:{} ' 'client_script:{} memGB:{}'.format(className, add_args, client_script, memGB)) if renderclient is not None: if isinstance(renderclient, RenderClient): return call_run_ws_client(className, add_args=add_args, **renderclient.make_kwargs( memGB=memGB, client_script=client_script, **kwargs)) if memGB is None: logger.warning('call_run_ws_client requires memory specification -- ' 'defaulting to 1G') memGB = '1G' args = list(map(str, [client_script, memGB, className] + add_args)) try: ret_val = run_subprocess_mode(args, **kwargs) except subprocess.CalledProcessError: raise ClientScriptError('client_script call {} failed'.format(args)) return ret_val
def importTransformChangesClient(stack, targetStack, transformFile, targetOwner=None, targetProject=None, changeMode=None, close_stack=True, subprocess_mode=None, host=None, port=None, owner=None, project=None, client_script=None, memGB=None, render=None, **kwargs): """run ImportTransformChangesClient.java Parameters ---------- stack : str stack from which tiles will be transformed targetStack : str stack that will hold results of transforms transformFile : str locaiton of json file in format defined below :: [{{"tileId": <tileId>, "transform": <transformDict>}}, {{"tileId": ...}}, ... ] targetOwner : str owner of target stack targetProject : str project of target stack changeMode : str method to apply transform to tiles. Options are: 'APPEND' -- add transform to tilespec's list of transforms 'REPLACE_LAST' -- change last transform in tilespec's list of transforms to match transform 'REPLACE_ALL' -- overwrite tilespec's transforms field to match transform Raises ------ ClientScriptError if changeMode is not valid """ if changeMode not in ['APPEND', 'REPLACE_LAST', 'REPLACE_ALL']: raise ClientScriptError( 'changeMode {} is not valid!'.format(changeMode)) argvs = (make_stack_params(host, port, owner, project, stack) + ['--targetStack', targetStack] + ['--transformFile', transformFile] + get_param(targetOwner, '--targetOwner') + get_param(targetProject, '--targetProject') + get_param(changeMode, '--changeMode')) call_run_ws_client( 'org.janelia.render.client.ImportTransformChangesClient', memGB=memGB, client_script=client_script, subprocess_mode=subprocess_mode, add_args=argvs, **kwargs) if close_stack: set_stack_state(stack, 'COMPLETE', host, port, owner, project)
def renderSectionClient(stack, rootDirectory, zs, scale=None, maxIntensity=None, minIntensity=None, bounds=None, format=None, channel=None, customOutputFolder=None, customSubFolder=None, padFileNamesWithZeros=None, doFilter=None, fillWithNoise=None, imageType=None, subprocess_mode=None, host=None, port=None, owner=None, project=None, client_script=None, memGB=None, render=None, **kwargs): """run RenderSectionClient.java Parameters ---------- stack : str stack to which zs to render belong rootDirectory : str directory to which rendered sections should be generated zs : :obj:`list` of :obj:`str` z indices of sections to render scale : float factor by which section image should be scaled (this materialization is 32-bit limited) maxIntensity : int value todisplay as white on a linear colormap minIntensity : int value to display as black on a linear colormap bounds: dict dictionary with keys of minX maxX minY maxY format : str output image format in 'PNG', 'TIFF', 'JPEG' channel : str channel to render out (use on multichannel stack) customOutputFolder : str folder to save all images in (overrides default of sections_at_%scale) customSubFolder : str folder to save all images in under outputFolder (overrides default of none) padFileNamesWithZeros: bool whether to pad file names with zeros to make sortable imageType: int 8,16,24 to specify what kind of image type to save doFilter : str string representing java boolean for whether to render image with default filter (varies with render version) fillWithNoise : str string representing java boolean for whether to replace saturated image values with uniform noise """ # noqa: E501 if bounds is not None: try: if bounds['maxX'] < bounds['minX']: raise ClientScriptError('maxX:{} is less than minX:{}'.format( bounds['maxX'], bounds['minX'])) if bounds['maxY'] < bounds['minY']: raise ClientScriptError('maxY:{} is less than minY:{}'.format( bounds['maxY'], bounds['minY'])) bound_list = ','.join( map(lambda x: str(int(x)), [ bounds['minX'], bounds['maxX'], bounds['minY'], bounds['maxY'] ])) bound_param = ['--bounds', bound_list] except KeyError as e: raise ClientScriptError( 'bounds does not contain correct keys {}. Missing {}'.format( bounds, e)) else: bound_param = [] argvs = (make_stack_params(host, port, owner, project, stack) + ['--rootDirectory', rootDirectory] + get_param(scale, '--scale') + get_param(format, '--format') + get_param(doFilter, '--doFilter') + get_param(minIntensity, '--minIntensity') + get_param(maxIntensity, '--maxIntensity') + get_param(fillWithNoise, '--fillWithNoise') + get_param(customOutputFolder, '--customOutputFolder') + get_param(imageType, '--imageType') + get_param(channel, '--channels') + get_param(customSubFolder, '--customSubFolder') + get_param(padFileNamesWithZeros, '--padFileNamesWithZeros') + bound_param + zs) call_run_ws_client('org.janelia.render.client.RenderSectionClient', memGB=memGB, client_script=client_script, subprocess_mode=subprocess_mode, add_args=argvs, **kwargs)