class_docstr: Stan Estimator for MAP Posteriors
  
  Parameters
  ----------
  stan_map_args : dict
      Supplemental stan vi args to pass to PyStan.optimizing()
code: def fit(
      self,
      model_name,
      model_param_names,
      data_input,
      fitter=None,
      init_values=None,
  ):
      compiled_mod = get_compiled_stan_model(model_name)
      data_input.update({"T_STAR": 1.0})
  
      # passing callable from the model as seen in `initfun1()`
      # init_values = init_values or self.stan_init
  
      # in case optimizing fails with given algorithm fallback to `Newton`
      # init values interface can be referred here: https://cmdstanpy.readthedocs.io/en/stable-0.9.65/api.html
      # Dict [Str, np.array] where key is the param name and value array dim matches the param dim
      try:
          stan_fit = compiled_mod.optimize(
              data=data_input,
              inits=init_values,
              seed=self.seed,
              algorithm=self.algorithm,
              **self._stan_map_args,
          )
      except RuntimeError:
          self.algorithm = "Newton"
          stan_fit = compiled_mod.optimize(
              data=data_input,
              inits=init_values,
              seed=self.seed,
              algorithm=self.algorithm,
              **self._stan_map_args,
          )
  
      stan_extract = stan_fit.stan_variables()
      # make sure that model param names are a subset of stan extract keys
      invalid_model_param = set(model_param_names) - set(
          list(stan_extract.keys())
      )
      if invalid_model_param:
          raise EstimatorException(
              "Stan model definition does not contain required parameters"
          )
  
      # `stan.optimizing` automatically returns all defined parameters
      # filter out unnecessary keys
      posteriors = {
          param: stan_extract[param]
          for param in model_param_names + ["loglk"]
      }
  
      training_metrics = {
          # loglk is needed for BIC calculation
          "loglk": stan_extract["loglk"],
          # TODO: this needs to be the full length of all parameters instead of the one we sampled?
          # TODO: i.e. should it include latent variables / derive variables?
          "num_of_params": len(model_param_names),
      }
  
      return posteriors, training_metrics
  
imports: from abc import abstractmethod
  from copy import copy
  import logging
  import multiprocessing
  from sys import platform, version_info
  from .base_estimator import BaseEstimator
  from ..exceptions import EstimatorException
  from ..utils.stan import get_compiled_stan_model, suppress_stdout_stderr
  from ..utils.general import update_dict
  from ..utils.logger import get_logger
label_desc: Use image node_id 3 for calling the StanEstimatorMAP obj's underlying member method code with example usage: obj.fit(model_name, model_param_names, data_input, fitter, init_values) and returns: posteriors,  training_metrics