def fit2dArrayToFn(arr, fn, mask=None, down_scale_factor=None,<EOL>output_shape=None, guess=None,<EOL>outgrid=None):
if mask is None:<EOL><INDENT>mask = np.ones(shape=arr.shape, dtype=bool)<EOL><DEDENT>if down_scale_factor is None:<EOL><INDENT>if mask.sum() > <NUM_LIT:1000>:<EOL><INDENT>down_scale_factor = <NUM_LIT><EOL><DEDENT>else:<EOL><INDENT>down_scale_factor = <NUM_LIT:1><EOL><DEDENT><DEDENT>if down_scale_factor != <NUM_LIT:1>:<EOL><INDENT>arr2 = zoom(arr, down_scale_factor)<EOL>mask = zoom(mask, down_scale_factor, output=bool)<EOL><DEDENT>else:<EOL><INDENT>arr2 = arr<EOL><DEDENT>x, y = np.where(mask)<EOL>z = arr2[mask]<EOL>parameters, cov_matrix = curve_fit(fn, (x, y), z, p0=guess)<EOL>perr = np.sqrt(np.diag(cov_matrix))<EOL>if outgrid is not None:<EOL><INDENT>yy,xx = outgrid<EOL>rebuilt = fn((yy,xx), *parameters)<EOL><DEDENT>else:<EOL><INDENT>if output_shape is None:<EOL><INDENT>output_shape = arr.shape<EOL><DEDENT>fx = arr2.shape[<NUM_LIT:0>] / output_shape[<NUM_LIT:0>]<EOL>fy = arr2.shape[<NUM_LIT:1>] / output_shape[<NUM_LIT:1>]<EOL>rebuilt = np.fromfunction(lambda x, y: fn((x * fx, y * fy),<EOL>*parameters), output_shape)<EOL><DEDENT>return rebuilt, parameters, perr<EOL>
Fit a 2d array to a 2d function

    USE ONLY MASKED VALUES

    * [down_scale_factor] map to speed up fitting procedure, set value smaller than 1
    * [output_shape] shape of the output array
    * [guess] must be scaled using [scale_factor]

    Returns:
        Fitted map, fitting params (scaled), error