code: def parrep(self, parfile=None,enforce_bounds=True):
          
          if parfile is None:
              parfile = self.filename.replace(".pst", ".par")
          par_df = pst_utils.read_parfile(parfile)
          self.parameter_data.index = self.parameter_data.parnme
          par_df.index = par_df.parnme
          self.parameter_data.parval1 = par_df.parval1
          self.parameter_data.scale = par_df.scale
          self.parameter_data.offset = par_df.offset
  
          if enforce_bounds:
              par = self.parameter_data
              idx = par.loc[par.parval1 > par.parubnd,"parnme"]
              par.loc[idx,"parval1"] = par.loc[idx,"parubnd"]
              idx = par.loc[par.parval1 < par.parlbnd,"parnme"]
              par.loc[idx, "parval1"] = par.loc[idx, "parlbnd"]
docs: replicates the pest parrep util. replaces the parval1 field in the
              parameter data section dataframe
  
          Parameters
          ----------
          parfile : str
              parameter file to use.  If None, try to use
              a parameter file that corresponds to the case name.
              Default is None
          enforce_hounds : bool
              flag to enforce parameter bounds after parameter values are updated.
              This is useful because PEST and PEST++ round the parameter values in the
              par file, which may cause slight bound violations