def _cleanup_our_var(var_):
     if hasattr(var_, attr_name):
         # cleanup placeholder attr if our var was altered
         var_.value, new_units = getattr(var_, attr_name)
         var_.units = units.to_cfunits(new_units)
         _log.debug("Updated (value, units) of '%s' to (%s, %s).",
                    var_.name, var_.value, var_.units)
         delattr(var_, attr_name)
    def edit_request(self, v, pod, data_mgr):
        """Edit *pod*\'s Varlist prior to query. If the
        :class:`~src.diagnostic.VarlistEntry` *v* has a ``standard_name`` in the
        recognized list, insert an alternate VarlistEntry whose translation
        requests the complementary type of variable (i.e., if given rate, add an
        entry for flux; if given flux, add an entry for rate.)

        The signature of this method is altered by the :func:`edit_request_wrapper`
        decorator.
        """
        std_name = getattr(v, 'standard_name', "")
        if std_name not in self._rate_d and std_name not in self._flux_d:
            # logic not applicable to this VE; do nothing
            return None
        # construct dummy var to translate (rather than modifying std_name & units)
        # on v's translation) because v may not have a translation
        if std_name in self._rate_d:
            # requested rate, so add alternate for flux
            v_to_translate = copy_as_alternate(
                v,
                data_mgr,
                standard_name=self._rate_d[std_name],
                units=units.to_cfunits(v.units) * self._liquid_water_density)
        elif std_name in self._flux_d:
            # requested flux, so add alternate for rate
            v_to_translate = copy_as_alternate(
                v,
                data_mgr,
                standard_name=self._flux_d[std_name],
                units=units.to_cfunits(v.units) / self._liquid_water_density)

        translate = core.VariableTranslator()
        try:
            new_tv = translate.translate(data_mgr.attrs.convention,
                                         v_to_translate)
        except KeyError as exc:
            pod.log.debug(("%s edit_request on %s: caught %r when trying to "
                           "translate '%s'; varlist unaltered."),
                          self.__class__.__name__, v.full_name, exc,
                          v_to_translate.standard_name)
            return None
        new_v = copy_as_alternate(v, data_mgr)
        new_v.translation = new_tv
        return new_v
 def edit_request(self, v, pod, data_mgr):
     """Edit the POD's Varlist prior to query. If v has a standard_name in the
     list above, insert an alternate varlist entry whose translation requests
     the complementary type of variable (ie, if given rate, add an entry for 
     flux; if given flux, add an entry for rate.)
     """
     std_name = getattr(v, 'standard_name', "")
     if std_name not in self._rate_d and std_name not in self._flux_d:
         # logic not applicable to this VE; do nothing
         return None
     # construct dummy var to translate (rather than modifying std_name & units)
     # on v's translation) because v may not have a translation
     if std_name in self._rate_d:
         # requested rate, so add alternate for flux
         v_to_translate = copy_as_alternate(
             v, data_mgr,
             standard_name = self._rate_d[std_name],
             units = units.to_cfunits(v.units) / self._liquid_water_density
         )
     elif std_name in self._flux_d:
         # requested flux, so add alternate for rate
         v_to_translate = copy_as_alternate(
             v, data_mgr,
             standard_name = self._flux_d[std_name],
             units = units.to_cfunits(v.units) * self._liquid_water_density
         )
     
     translate = core.VariableTranslator()
     try:
         new_tv = translate.translate(data_mgr.convention, v_to_translate)
     except KeyError as exc:
         _log.debug(("%s edit_request on %s: caught %r when trying to translate "
             "'%s'; varlist unaltered."), self.__class__.__name__, 
             v.full_name, exc, v_to_translate.standard_name)
         return None
     new_v = copy_as_alternate(v, data_mgr)
     new_v.translation = new_tv
     return new_v
    def check_names_and_units(self,
                              our_var,
                              ds,
                              ds_var_name,
                              update_name=False):
        """Reconcile the standard_name and units attributes between the
        'ground truth' of the dataset we downloaded (*ds_var*) and our expectations
        based on the model's convention (*our_var*).
        """
        # check name
        if ds_var_name not in ds:
            raise ValueError(
                f"Variable name '{ds_var_name}' not found in dataset: "
                f"({list(ds.variables)}).")
            # attempt to match on standard_name?
        self.check_name(our_var, ds_var_name, update_name=update_name)
        ds_var = ds[ds_var_name]  # abbreviate

        # check CF standard_name
        # see if standard_name has been stored in a nonstandard attribute
        # check_attr will set missing attr on ds
        _ = self.normalize_attr('standard_name', 'standard', ds_var.attrs)
        self.check_attr(our_var,
                        ds_var,
                        'standard_name',
                        update_our_var=True,
                        update_ds=True)

        # check units (and scalar coord value, if set)
        is_scalar = hasattr(our_var, 'is_scalar') and our_var.is_scalar
        # see if units has been stored in a nonstandard attribute
        # check_attr will set missing attr on ds
        _ = self.normalize_attr('units', 'unit', ds_var.attrs, "")
        # if units inequivalent, raise TypeError
        if is_scalar:
            self.check_scalar_coord_value(our_var, ds_var, equivalent=True)
        else:
            self.check_attr(our_var,
                            ds_var,
                            'units',
                            comparison_func=units.units_equivalent,
                            update_our_var=True,
                            update_ds=True)
        # now check equality of units - not an error, since we can convert
        try:
            if is_scalar:
                # test equality of quantities+units
                self.check_scalar_coord_value(our_var,
                                              ds_var,
                                              equivalent=False)
            else:
                # test units only, not quantities+units
                self.check_attr(our_var,
                                ds_var,
                                'units',
                                comparison_func=units.units_equal,
                                update_our_var=True,
                                update_ds=True)
        except TypeError as exc:
            _log.warning(exc)
            our_var.units = units.to_cfunits(our_var.units)