o  i\"@sPdZddlmZddlmZgdZdddZdd Zd d ZGd d d Z dS)a How to use the adaptor function ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The key to using 'adaptor' lies in understanding the function that want to adapt. The 'inputs' and 'outputs' parameters take either strings, lists/tuples of strings or a dictionary mapping strings, depending on call signature of the function being called. The adaptor function is written to minimise the cognitive load on the caller. There should be a minimal number of cases where the caller has to set anything on the input parameter, and for functions that return a single value, it is only necessary to name the dictionary keyword to which that value is assigned. Use of `outputs` ---------------- `outputs` can take either a string, a list/tuple of string or a dict of string to string, depending on what the transform being adapted returns: - If the transform returns a single argument, then outputs can be supplied a string that indicates what key to assign the return value to in the dictionary - If the transform returns a list/tuple of values, then outputs can be supplied a list/tuple of the same length. The strings in outputs map the return value at the corresponding position to a key in the dictionary - If the transform returns a dictionary of values, then outputs must be supplied a dictionary that maps keys in the function's return dictionary to the dictionary being passed between functions Note, the caller is free to use a more complex way of specifying the outputs parameter than is required. The following are synonymous and will be treated identically: .. code-block:: python # single argument adaptor(MyTransform(), 'image') adaptor(MyTransform(), ['image']) adaptor(MyTransform(), {'image': 'image'}) # multiple arguments adaptor(MyTransform(), ['image', 'label']) adaptor(MyTransform(), {'image': 'image', 'label': 'label'}) Use of `inputs` --------------- `inputs` can usually be omitted when using `adaptor`. It is only required when a the function's parameter names do not match the names in the dictionary that is used to chain transform calls. .. code-block:: python class MyTransform1: def __call__(self, image): # do stuff to image return image + 1 class MyTransform2: def __call__(self, img_dict): # do stuff to image img_dict["image"] += 1 return img_dict xform = Compose([adaptor(MyTransform1(), "image"), MyTransform2()]) d = {"image": 1} print(xform(d)) >>> {'image': 3} .. code-block:: python class MyTransform3: def __call__(self, img_dict): # do stuff to image img_dict["image"] -= 1 img_dict["segment"] = img_dict["image"] return img_dict class MyTransform4: def __call__(self, img, seg): # do stuff to image img -= 1 seg -= 1 return img, seg xform = Compose([MyTransform3(), adaptor(MyTransform4(), ["img", "seg"], {"image": "img", "segment": "seg"})]) d = {"image": 1} print(xform(d)) >>> {'image': 0, 'segment': 0, 'img': -1, 'seg': -1} Inputs: - dictionary in: None | Name maps - params in (match): None | Name list | Name maps - params in (mismatch): Name maps - params & `**kwargs` (match) : None | Name maps - params & `**kwargs` (mismatch) : Name maps Outputs: - dictionary out: None | Name maps - list/tuple out: list/tuple - variable out: string ) annotations)Callable)adaptor apply_alias to_kwargsFunctionSignatureNcs<ddddddddfd d }|S) NcSs8|durt||std|d|dt|dSdS)N'z' must be None or one of  but is  isinstance TypeErrortype variable_namevariabletypesr[/home/dell461/cl/sdc2/last_ska_mid/HISourceFinder-master-l/src/monai/transforms/adaptors.pymust_be_types_or_nones  z&adaptor..must_be_types_or_nonecSs,t||std|d|dt|dS)Nrz' must be one of r r rrrr must_be_typess zadaptor..must_be_typescsfdd|DS)Ncsi|] \}}|||qSrr.0kv input_maprr sz.adaptor..map_names..itemsditemsrrrr map_nameszadaptor..map_namescsfdd|DS)Nci|] \}}||qSrrrr rrrz3adaptor..map_only_names..rrrr$rmap_only_namesr"zadaptor..map_only_namescstjrdtfdurt|nM|nGfdd|Ddttttfdur7n-ttrNtj dkrGt d|intttfr_fddDn|d i }ttrd|tf|durfdd|Dn]tttfrtdkrd|tttfnd|ttft|tr|g}tt krt d tt |n"d|tttft|ttfrt|dkrt d |d }|it|}D]\}}|||<q|S) Ninputscs i|] \}}|jvr||qSr)non_var_parametersr)sigrrrs z+adaptor.._inner..zOif 'inputs' is a string, function may only have a single non-variadic parametercsi|]}||qSrr)rr)dinputsrrrsoutputscr#rrr)retrrrr%zP'outputs' must have the same length as the number of elements that were returnedz8'outputs' must be of length one if it is a list or tuplerr) r found_kwargsdictrstrlisttupler lenr( ValueErrorzip)r oprrfunctionr'r!r&rrr,)r+r-r)r_innersV         zadaptor.._innerr)r8r,r'r9rr7rrs @rcsfdd}|S)NcsTt|}D] \}}||||<q|}D] \}}||||<q|SN)r/rpop)dataZpre_callZ_from_toZ post_callfnname_maprrr9szapply_alias.._innerr)r?r@r9rr>rrsrcsfdd}|S)Ncsdi|S)Nrr)r<r?rrr9szto_kwargs.._innerr)r?r9rrArrs rc@s*eZdZd ddZddd Zdd d Zd S)rr8rreturnNonecCsddl}||}d|_d|_i|_t|_|jD](}|j |j j ur'd|_|j |j j ur2d|_q|j |j|j|ju|j|j<qdS)NrFT)inspect signature found_argsr.defaultssetr( parametersvalueskind ParameterVAR_POSITIONAL VAR_KEYWORDaddnamedefaultempty)selfr8rDZsfnprrr__init__s zFunctionSignature.__init__r0cCsd}||j|j|jS)NzGs q  T