U Ph"@sxdZddlmZddlmZddlmZddddgZed dd dZ ed d dZ ed d dZ GdddZ d S)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)exportadaptor apply_alias to_kwargsFunctionSignaturezmonai.transformsNcs<ddddddddfd d }|S) NcSs4|dk r0t||s0td|d|dt|dS)N'z' must be None or one of  but is  isinstance TypeErrortype variable_namevariabletypesrN/home/dell461/cl/sdc2/HISourceFinder-master-l/src/monai/transforms/adaptors.pymust_be_types_or_nones z&adaptor..must_be_types_or_nonecSs,t||s(td|d|dt|dS)Nr z' 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_namesszadaptor..map_namescsfdd|DS)Ncsi|]\}}||qSrrrr!rrrsz3adaptor..map_only_names..rr rr#rmap_only_namesszadaptor..map_only_namescstjr:dtfdkr.t|qȈ|nfdd|DdttttfdkrnnZttrtj dkrt d|in,tttfrfddDn |f }ttrd|tf|dk r؇fdd|DntttfrtdkrDd|tttfnd|ttft|trf|g}tt krt d tt |nHd|tttft|ttfrt|dkrt d |d }|it|}D]\}}|||<q|S) Ninputscs i|]\}}|jkr||qSr)non_var_parametersr)sigrrrs z+adaptor.._inner..zOif 'inputs' is a string, function may only have a single non-variadic parametercsi|]}||qSrr)rr)dinputsrrrsoutputscsi|]\}}||qSrrr)retrrrszP'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 tupler) r found_kwargsdictrstrlisttupler lenr& ValueErrorzip)r!oprrfunctionr%r"r$rrr*)r)r+r'r_innersT         zadaptor.._innerr)r6r*r%r7rr5rrs @csfdd}|S)NcsTt|}D]\}}||||<q|}D]\}}||||<q8|SN)r-rpop)dataZpre_callZ_from_toZ post_callfnname_maprrr7szapply_alias.._innerr)r=r>r7rr<rrscsfdd}|S)Ncs f|Sr8r)r:r=rrr7szto_kwargs.._innerr)r=r7rr?rrs c@s8eZdZdddddZdddd Zddd d Zd S) rrNone)r6returncCsddl}||}d|_d|_i|_t|_|jD]P}|j |j j krNd|_|j |j j krdd|_q6|j |j|j|jk |j|j<q6dS)NrFT)inspect signature found_argsr,defaultssetr& parametersvalueskind ParameterVAR_POSITIONAL VAR_KEYWORDaddnamedefaultempty)selfr6rBZsfnprrr__init__s zFunctionSignature.__init__r.)rAcCsd}||j|j|jS)NzG sq     T