def METHOD_NAME(self, coordinates, output=None, _selector=None):
    """Evalutes this nodes using the supplied coordinates.
    Parameters
    ----------
    coordinates : podpac.Coordinates
        {requested_coordinates}
    output : podpac.UnitsDataArray, optional
        {eval_output}
    _selector: callable(coordinates, request_coordinates)
        {eval_selector}
    Returns
    -------
    {eval_return}
    """
    self._requested_coordinates = coordinates
    inputs = {}
    if settings["MULTITHREADING"]:
        n_threads = thread_manager.request_n_threads(len(self.inputs))
        if n_threads == 1:
            thread_manager.release_n_threads(n_threads)
    else:
        n_threads = 0
    if settings["MULTITHREADING"] and n_threads > 1:
        # Create a function for each thread to execute asynchronously
        def f(node):
            return node.eval(coordinates, _selector=_selector)
        # Create pool of size n_threads, note, this may be created from a sub-thread (i.e. not the main thread)
        pool = thread_manager.get_thread_pool(processes=n_threads)
        # Evaluate nodes in parallel/asynchronously
        results = [pool.apply_async(f, [node]) for node in self.inputs.values()]
        # Collect the results in dictionary
        for key, res in zip(self.inputs.keys(), results):
            inputs[key] = res.get()
        # This prevents any more tasks from being submitted to the pool, and will close the workers once done
        pool.close()
        # Release these number of threads back to the thread pool
        thread_manager.release_n_threads(n_threads)
        self._multi_threaded = True
    else:
        # Evaluate nodes in serial
        for key, node in self.inputs.items():
            inputs[key] = node.eval(coordinates, output=output, _selector=_selector)
        self._multi_threaded = False
    result = self.algorithm(inputs, coordinates)
    if not isinstance(result, xr.DataArray):
        raise NodeException("algorithm returned unsupported type '%s'" % type(result))
    if "output" in result.dims and self.output is not None:
        result = result.sel(output=self.output)
    if output is not None:
        missing = [dim for dim in result.dims if dim not in output.dims]
        if any(missing):
            raise NodeException("provided output is missing dims %s" % missing)
        output_dims = output.dims
        output = output.transpose(..., *result.dims)
        output[:] = result.data
        output = output.transpose(*output_dims)
    elif isinstance(result, UnitsDataArray):
        output = result
    else:
        output_coordinates = Coordinates.from_xarray(result)
        output = self.create_output_array(output_coordinates, data=result.data)
    return output