o
    Uݢg&(                     @   s  d Z ddlmZmZmZ ddlZddlZddlZddlZddl	Z	ddl
Z
ddlmZ ddlmZmZmZmZ de vr=daG dd deZG d	d
 d
Zdd Zdd ZdFddZdd Zdd Zdd Zdd Ze
jdrddl Z ddl!Z ddl"m#Z# e $e j%&dZ'e (dZ)dd Z*ndZ*ddddde*dddddddfd d!Z+dGd"d#Z,d$d% Z-d&d' Z.d(d) Z/d*d+ Z0d,d- Z1d.d/ Z2d0d1 Z3d2d3 Z4d4d5 Z5d6d7 Z6d8d9 Z7d:d; Z8d<d= Z9d>d? Z:d@dA Z;dBdC Z<dDdE Z=dS )HzMartian stage code API and common utility methods.

This module contains an API for python stage code to use to interact
with the higher-level martian logic, plus common utility methods.
    )absolute_importdivisionprint_functionN)PurePath)AnyDictNoReturnUnion	_INSTANCEc                   @   s   e Zd ZdZdS )StageExceptionz#Base exception type for stage code.N)__name__
__module____qualname____doc__ r   r   l/oak/stanford/groups/akundaje/marinovg/programs/cellranger-9.0.1/external/martian/adapters/python/martian.pyr   $   s    r   c                   @   s@   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dS )Recordz?An object with a set of attributes generated from a dictioanry.c                 C   s*   |  | _| jD ]
}t| |||  qdS )z)Initializes the object from a dictionary.N)keysslotssetattr)selfZf_dict
field_namer   r   r   __init__+   s   

zRecord.__init__c                    s    fdd j D S )zvReturns the a dictionary with the elements which were in the keys in
        dictionary used to initialize the record.c                    s   i | ]}|t  |qS r   )getattr).0r   r   r   r   
<dictcomp>5   s    z Record.items.<locals>.<dictcomp>)r   r   r   r   r   items2   s   
zRecord.itemsc                 C   s   t |  S )zFormats the object as a string.)strr   r   r   r   r   __str__9   s   zRecord.__str__c                 c   s    | j D ]}t| |V  qdS )zwIterate through the values of the object corresponding to keys in
        the dictionary used to initialize the object.N)r   r   )r   r   r   r   r   __iter__=   s   
zRecord.__iter__c                 C   s   t | | j| S )zKGet the value associated with the Nth key in the source
        dictionary.)r   r   )r   indexr   r   r   __getitem__C   s   zRecord.__getitem__c                 C   s   dS )z-This exists only for backwards compatibility.Nr   r   r   r   r   coerce_stringsI   s    zRecord.coerce_stringsN)
r   r   r   r   r   r   r   r    r"   r#   r   r   r   r   r   (   s    r   c                 C   s   | j D ]}t| |d qdS )zSet all of the outs to None.N)r   r   )outsr   r   r   r   clearM   s   
r%   c                 C   s   | }t | trt| s| tdks| tdkrd}|S t | tr4i }|  D ]
}t| | ||< q'|S t | tr<	 |S t | trJ| j	ddd}|S t | t
rUt| }|S t| dradd	 | D }|S )
z;Converts NaN values into None values, and decode raw bytes.z+Infz-InfNutf-8ignore)errorsr    c                 S   s   g | ]}t |qS r   )json_sanitize)r   dr   r   r   
<listcomp>j   s    z!json_sanitize.<locals>.<listcomp>)
isinstancefloatmathisnandictr   r)   r   bytesdecoder   hasattr)dataZretvalkr   r   r   r)   T   s,   
"




r)   c                 C   s   t jt| |dS )zSReturns a formatted json string of the data, with NaN values converted
    to None.)indent)jsondumpsr)   )r4   r6   r   r   r   json_dumps_safen   s   r9   c                   C   s   t ttjjttjjS )zRGet the current max rss memory for this process and completed child
    processes.)maxresourceZ	getrusageZRUSAGE_SELFZ	ru_maxrssZRUSAGE_CHILDRENr   r   r   r   
get_mem_kbt   s   r<   c                 C   s   | d d S )zConvert from gb to kb.i   r   )mem_gbr   r   r   convert_gb_to_kb~   s   r>   c                 C   s4   t | t t| }|dkrd| t| S t|S )zEPad a string with leading spaces to be the same length as field_name.r    )lenr   )r   valueoffsetr   r   r   padded_print   s   rC   c                 C   s   t dusJ t j|  | S )zJAdd a function to the set of functions to be covered by the line profiler.N)r
   funcsappend)funcr   r   r   profile   s   rG   Zlinux)SIGKILLc   c                  C   s&   t d} ttt t| | |  dS )zWhen used as the preexec_fn argument for subprocess.Popen etc,
        causes the subprocess to receive SIGKILL if the parent process
        terminates.r   N)ctypesZc_ulong_LIBCZprctl_PR_SET_PDEATHSIGrH   )Zzeror   r   r   child_preexec_set_pdeathsig   s   
rN   Fc                 C   sF   t dusJ t jdd|  tj| |||||||||	|
|||dS )zLog opening of a subprocess.Nexecr?   )bufsize
executablestdinstdoutstderr
preexec_fn	close_fdsshellcwdenvuniversal_newlinesstartupinfocreationflags)r
   metadatalogjoin
subprocessPopen)argsrP   rQ   rR   rS   rT   rU   rV   rW   rX   rY   rZ   r[   r\   r   r   r   ra      s$   ra   c                 C   s6   t dusJ t jdd|  tj| ||||tdS )zLog running a given subprocess.NrO   r?   )rW   rR   rS   rT   rU   )r
   r]   r^   r_   r`   
check_callrN   )rb   rR   rS   rT   rW   r   r   r   rc      s   rc   c                 C   s2   t | tr
| d} tdusJ tjtjj| S )z#Get the file path for a named file.r&   N)	r,   r   encoder
   ospathr_   r]   
files_path)filenamer   r   r   	make_path   s   

ri   c                   C   &   t dusJ t jdusJ t jjd S )z!Get the args from the invocation.Nrb   r
   jobinfo
invocationr   r   r   r   get_invocation_args      rn   c                   C   rj   )z-Get the call information from the invocation.Ncallrk   r   r   r   r   get_invocation_call   ro   rq   c                   C   rj   )z)Get the martian version from the jobinfo.Nmartianr
   rl   versionr   r   r   r   get_martian_version   ro   ru   c                   C   rj   )z+Get the pipelines version from the jobinfo.N	pipelinesrs   r   r   r   r   get_pipelines_version  ro   rw   c                   C   "   t dusJ t jdusJ t jjS )z?Get the number of threads allocated to this job by the runtime.N)r
   rl   threadsr   r   r   r   get_threads_allocation
     rz   c                   C   rx   )zDGet the amount of memory in GB allocated to this job by the runtime.N)r
   rl   r=   r   r   r   r   get_memory_allocation  r{   r|   c                   C   s   t dpt dpdS )zpGet the UUID of the top-level pipeline instance.

    Returns an empty string if the UUID is not available.
    ZMRO_UUIDZMRO_FORCE_UUID )re   getenvr   r   r   r   get_pipestance_uuid  s   r   c                 C      t dusJ t j|  dS )zUpdates the current progress of the stage, which will be displayed to
    the user (in the mrp log) next time mrp reads the file.N)r
   r]   progressmessager   r   r   update_progress#  s   r   c                 C      t dusJ t jd|  dS )zLog a message.Ninfor
   r]   r^   r   r   r   r   log_info+     r   c                 C   r   )zLog a warning.Nwarnr   r   r   r   r   log_warn2  r   r   c                 C   r   )zLog a timestamp for an action.Ntimer   r   r   r   r   log_time9  r   r   c                 C   s(   t dusJ t jdt| |d dS )zLog an object in json format.Nr7   )labelobject)r
   r]   r^   r9   )r   objr   r   r   log_json@  s   r   c                 C   s   t | )zRaise a stage exception.)r   r   r   r   r   throwI  s   r   c                 C   s$   t dusJ t j|  t   dS )z$Fail the pipeline with an assertion.N)r
   r]   write_assertdoner   r   r   r   exitO  s   r   c                 C   r   )zAdd a message to the alarms.N)r
   r]   alarmr   r   r   r   r   W  s   r   c                 C   s$   ddl }|ddd| | dgdatS )z%Initialize with a fake test metadata.r   Nmainr}   T)Zmartian_shellStageWrapperr
   )rf   Zmr_shellr   r   r   test_initializec  s
   r   )N)NNNF)>r   
__future__r   r   r   r7   r.   re   r;   r`   sysZpathlibr   typingr   r   r   r	   globalsr
   	Exceptionr   r   r%   r)   r9   r<   r>   rC   rG   platform
startswithrK   Zctypes.utilsignalrH   ZCDLLutilZfind_libraryrL   Zc_intrM   rN   ra   rc   ri   rn   rq   ru   rw   rz   r|   r   r   r   r   r   r   r   r   r   r   r   r   r   r   <module>   sz   
	%

	




'			