Beispiel #1
0
    def __init__(self, lon, lat=None, height=None, copy=True):
        if height is None and not isinstance(lon, self.__class__):
            height = 0 << u.m

        super().__init__(lon, lat, height, copy=copy)
        if not self.height.unit.is_equivalent(u.m):
            raise u.UnitTypeError(f"{self.__class__.__name__} requires "
                                  f"height with units of length.")
Beispiel #2
0
    def _set_unit(self, unit):
        if unit is None or unit != self._unit:
            raise u.UnitTypeError(
                "{0} instances require units of '{1}'"
                .format(type(self).__name__, self._unit)
                + (", but no unit was given." if unit is None else
                   ", so cannot set it to '{0}'.".format(unit)))

        super()._set_unit(unit)
Beispiel #3
0
def ingest_filter_set(path: str,
                      instrument: str,
                      instrument_response: bool = False,
                      atmosphere: bool = False,
                      source: str = None,
                      wavelength_unit: units.Unit = None,
                      percentage: bool = False,
                      lambda_name='LAMBDA',
                      quiet: bool = False):
    """

    :param path:
    :param instrument:
    :param instrument_response: Filter curve includes instrument response
    :param atmosphere: Filter curve includes atmospheric transmission
    :param source:
    :param wavelength_unit:
    :param percentage:
    :param lambda_name:
    :param quiet:
    :return:
    """

    if not wavelength_unit.is_equivalent(units.Angstrom):
        raise units.UnitTypeError(
            f"Wavelength units must be of type length, not {wavelength_unit}")

    type_str = "_filter"
    if instrument_response:
        type_str += "_instrument"
    if atmosphere:
        type_str += "_atmosphere"

    data = QTable.read(path, format='ascii')
    data.sort("col1")
    wavelengths = data["col1"] * wavelength_unit
    wavelengths = wavelengths.to("Angstrom")
    for f in data.colnames:
        if f != lambda_name:
            params = filter_params(f=f, instrument=instrument, quiet=quiet)
            transmissions = data[f]

            if params is None:
                params = new_filter_params(quiet=quiet)
            params['name'] = f
            if source is not None:
                params[f'source{type_str}'] = source
            if percentage:
                transmissions /= 100
            params[f'wavelengths{type_str}'] = wavelengths
            params[f'transmissions{type_str}'] = transmissions

            save_params(file=param_dir + f'filters/{instrument}-{f}',
                        dictionary=params,
                        quiet=quiet)
    refresh_params_filters(quiet=quiet)
Beispiel #4
0
    def __pow__(self, other):
        if isinstance(other, Measurement):
            if other.unit.physical_type != u'dimensionless':
                raise u.UnitTypeError('Can only raise something to a dimensionless quantity')

            new_value = self.value**other.value
            uncertainty = np.abs(new_value)*np.sqrt((other.value*self.uncertainty/self.value)**2 +\
                                                    (other.uncertainty*np.log(self.value))**2)
            return self._new_view(new_value, self.unit**other.value, uncertainty)
        elif isinstance(other, u.Quantity):
            if other.unit.physical_type != u'dimensionless':
                raise u.UnitTypeError('Can only raise something to a dimensionless quantity')

            new_value = self.value**other.value
            uncertainty = np.abs(new_value*other.value*self.uncertainty/self.value)
            return self._new_view(new_value, self.unit**other.value, uncertainty)
        else:
            return self._new_view(self.value**other, self.unit**other,
                                  np.abs(self.value**(other-1)*other*self.uncertainty))
Beispiel #5
0
def _check_optional_units(namespace, allowed_physical_types):
    for name, kinds in allowed_physical_types.items():
        if name not in namespace:
            continue

        obj = namespace[name]
        if isinstance(kinds, (str, u.PhysicalType)):
            kinds = (kinds, )

        if isinstance(obj, u.Quantity) and (obj.unit.physical_type
                                            not in kinds):
            raise u.UnitTypeError(f'Parameter {name} should have physical '
                                  f'type(s) {kinds}, not '
                                  f'{obj.unit.physical_type}.')
Beispiel #6
0
    def __rpow__(self, other):
        if self.unit.physical_type != u'dimensionless':
            raise u.UnitTypeError('Can only raise something to a dimensionless quantity')
            
        if isinstance(other, Measurement):
            new_value = other.value**self.value
            uncertainty = np.abs(new_value)*np.sqrt((self.value*other.uncertainty/other.value)**2+
                                                    (self.uncertainty*np.log(other.value))**2)
            return self._new_view(new_value, other.unit**self.value, uncertainty)

        elif isinstance(other, u.Quantity):
            new_value = other.value**self.value
            uncertainty = np.abs(new_value*self.uncertainty*np.log(other.value))
            return self._new_view(new_value, other.unit**self.value, uncertainty)
        else:
            new_value = other**self.value
            return self._new_view(new_value, u.dimensionless_unscaled,
                                  np.abs(new_value*self.uncertainty*np.log(other)))
Beispiel #7
0
    def _check_unit_core(
        self, arg, arg_name: str, arg_checks: Dict[str, Any]
    ) -> Tuple[
        Union[None, u.Quantity],
        Union[None, u.Unit],
        Union[None, List[Any]],
        Union[None, Exception],
    ]:
        """
        Determines if `arg` passes unit checks `arg_checks` and if the units of
        `arg` is equivalent to any units specified in `arg_checks`.

        Parameters
        ----------
        arg
            The argument to be checked

        arg_name: str
            The name of the argument to be checked

        arg_checks: Dict[str, Any]
            The requested checks for the argument

        Returns
        -------
        (`arg`, `unit`, `equivalencies`, `error`)
            * `arg` is the original input argument `arg` or `None` if unit
              checks fail
            * `unit` is the identified astropy :mod:`~astropy.units` that `arg`
              can be converted to or `None` if none exist
            * `equivalencies` is the astropy :mod:`~astropy.units.equivalencies`
              used for the unit conversion or `None`
            * `error` is the `Exception` associated with the failed unit checks
              or `None` for successful unit checks
        """
        # initialize str for error messages
        if arg_name == "checks_on_return":
            err_msg = "The return value "
        else:
            err_msg = f"The argument '{arg_name}' "
        err_msg += f"to function {self.f.__name__}()"

        # initialize ValueError message
        valueerror_msg = f"{err_msg} can not contain"

        # initialize TypeError message
        typeerror_msg = f"{err_msg} should be an astropy Quantity with "
        if len(arg_checks["units"]) == 1:
            typeerror_msg += f"the following unit: {arg_checks['units'][0]}"
        else:
            typeerror_msg += "one of the following units: "
            for unit in arg_checks["units"]:
                typeerror_msg += str(unit)
                if unit != arg_checks["units"][-1]:
                    typeerror_msg += ", "
        if arg_checks["none_shall_pass"]:
            typeerror_msg += "or None "

        # pass Nones if allowed
        if arg is None:
            if arg_checks["none_shall_pass"]:
                return arg, None, None, None
            else:
                return None, None, None, ValueError(f"{valueerror_msg} Nones")

        # check units
        in_acceptable_units = []
        equiv = arg_checks["equivalencies"]
        for unit in arg_checks["units"]:
            try:
                in_acceptable_units.append(
                    arg.unit.is_equivalent(unit, equivalencies=equiv)
                )
            except AttributeError:
                if hasattr(arg, "unit"):
                    err_specifier = (
                        "a 'unit' attribute without an 'is_equivalent' method"
                    )
                else:
                    err_specifier = "no 'unit' attribute"

                msg = (
                    f"{err_msg} has {err_specifier}. "
                    f"Use an astropy Quantity instead."
                )
                return None, None, None, TypeError(msg)

        # How many acceptable units?
        nacceptable = np.count_nonzero(in_acceptable_units)
        unit = None
        equiv = None
        err = None
        if nacceptable == 0:
            # NO equivalent units
            arg = None
            err = u.UnitTypeError(typeerror_msg)
        else:
            # is there an exact match?
            units_arr = np.array(arg_checks["units"])
            units_equal_mask = np.equal(units_arr, arg.unit)
            units_mask = np.logical_and(units_equal_mask, in_acceptable_units)
            if np.count_nonzero(units_mask) == 1:
                # matched exactly to a desired unit
                unit = units_arr[units_mask][0]
                equiv = arg_checks["equivalencies"]
            elif nacceptable == 1:
                # there is a match to 1 equivalent unit
                unit = units_arr[in_acceptable_units][0]
                equiv = arg_checks["equivalencies"]
                if not arg_checks["pass_equivalent_units"]:
                    err = u.UnitTypeError(typeerror_msg)
            elif arg_checks["pass_equivalent_units"]:
                # there is a match to more than one equivalent units
                pass
            else:
                # there is a match to more than 1 equivalent units
                arg = None
                err = u.UnitTypeError(typeerror_msg)
        return arg, unit, equiv, err
Beispiel #8
0
def ingest_filter_transmission(path: str,
                               fil_name: str,
                               instrument: str,
                               instrument_response: bool = False,
                               atmosphere: bool = False,
                               lambda_eff: units.Quantity = None,
                               fwhm: float = None,
                               source: str = None,
                               wavelength_unit: units.Unit = units.Angstrom,
                               percentage: bool = False,
                               quiet: bool = False):
    """

    :param path:
    :param fil_name:
    :param instrument:
    :param instrument_response: Filter curve includes instrument response
    :param atmosphere: Filter curve includes atmospheric transmission
    :param lambda_eff:
    :param fwhm:
    :param source:
    :param wavelength_unit:
    :param percentage:
    :param quiet:
    :return:
    """

    if not wavelength_unit.is_equivalent(units.Angstrom):
        raise units.UnitTypeError(
            f"Wavelength units must be of type length, not {wavelength_unit}")

    type_str = "_filter"
    if instrument_response:
        type_str += "_instrument"
    if atmosphere:
        type_str += "_atmosphere"

    params = filter_params(f=fil_name, instrument=instrument, quiet=quiet)
    if params is None:
        params = new_filter_params(quiet=quiet)
        params['name'] = fil_name
        params['instrument'] = instrument

    if lambda_eff is not None:
        lambda_eff = u.check_quantity(lambda_eff,
                                      unit=units.Angstrom,
                                      convert=True)
        params['lambda_eff'] = lambda_eff
        # TODO: If None, measure?
    if fwhm is not None:
        params['fwhm'] = fwhm
        # TODO: If None, measure?
    if source is not None:
        params[f'source{type_str}'] = source

    tbl = QTable.read(path, format="ascii")
    tbl["col1"].name = "wavelength"
    tbl["wavelength"] *= wavelength_unit
    tbl["wavelength"] = tbl["wavelength"].to("Angstrom")

    tbl["col2"].name = "transmission"

    if percentage:
        tbl["transmission"] /= 100

    tbl.sort("wavelength")

    params[f'wavelengths{type_str}'] = tbl["wavelength"].value.tolist()
    params[f'transmissions{type_str}'] = tbl["transmission"].value.tolist()

    save_params(file=os.path.join(param_dir, 'filters',
                                  f'{instrument}-{fil_name}'),
                dictionary=params,
                quiet=quiet)
Beispiel #9
0
    def __init__(self, dim):
        if not dim.unit.is_equivalent((u.radian, u.meter)):
            raise u.UnitTypeError(
                'aperture must be defined with angles or lengths.')

        self.dim = dim