示例#1
0
文件: _miniSASP.py 项目: hagne/atm-py
    def optical_depth_rayleigh(self):
        if not self.__housekeeping:
            txt = 'To claculate the optical depth you will have to set the housekeeping property with a timeseries containing Altitude (m) Temperature (C) and Pressure (hPa)'
            raise AttributeError(txt)

        if not self.__od_ray_orig:
            hkt = self.housekeeping.copy()
            # import pdb
            # pdb.set_trace()
            # to make sure there is no two values with the same altitude in a row (causes sims to fail) ...
            clean = False
            while not clean:
                alt = hkt.data.Altitude.values
                dist = alt[1:] - alt[:-1]
                if (dist == 0).sum():
                    hkt.data.iloc[np.where(dist == 0)] = np.nan
                else:
                    clean = True
            # pdb.set_trace()
            hkt.data.dropna(axis=1, inplace=True)
            # pdb.set_trace()
            # do the od calculations for each wavelength channel
            c_list = np.array(sorted(self.wavelength_channels.items(), key=lambda x: x[1]))[:, 0]
            for e, c in enumerate(c_list):
                wl = self.wavelength_channels[c]

                out = []
                for i in range(hkt.data.shape[0]):
                    if i < 1:
                        out.append(0.)
                        continue
                    hktt = hkt.data.iloc[0:i, :]
                    alt = -1 * hktt.Altitude.values
                    press = hktt.Pressure_Pa.values
                    temp = hktt.Temperature.values
                    ray = _bray.rayleigh_optical_depth(alt, press, temp + 273.15, float(wl))
                    out.append(ray)
                # pdb.set_trace()
                hkt.data[wl] = np.array(out)
                # pdb.set_trace()
            wll = np.array(sorted(self.wavelength_channels.items(), key=lambda x: x[1]))[:, 1]#.astype(float)
            # pdb.set_trace()
            hkt = hkt._del_all_columns_but(wll)
            # pdb.set_trace()
            self.__od_ray_orig = hkt


        if self.optical_depth_rayleigh_offsets != self.__od_ray_offset_last:
            # pdb.set_trace()
            self.__od_ray = self.__od_ray_orig.copy()
            # pdb.set_trace()
            # apply offset
            wll = np.array(sorted(self.wavelength_channels.items(), key=lambda x: x[1]))[:, 1]#.astype(float)
            for wl in wll:
                self.__od_ray.data[wl] += self.optical_depth_rayleigh_offsets[wl]

            self.__od_ray_offset_last = self.optical_depth_rayleigh_offsets
        # pdb.set_trace()
        return self.__od_ray
示例#2
0
def simulate_from_rayleigh(
        time_series,
        layerbounderies,
        # altitude,
        # layerbounderies,
        pressure,
        temp,
        wl,
        no_angles,
        rotations,
        airmassfct,
        sun_azimuth):
    """ Fix this documentation!


    Simulates miniSASP signal from a size distribution layer series
    Arguments
    ---------
    layerbounderies: array-like
    altitude: float or array-like.
        Altitude for which the mSASP signal is simulated for in meters
    pressure: array, bool
        Atmospheric pressure in mbar. If False, value is taken from international standard atmosphere.
    temp: array, bool in K
    wl: wavelength in nm

    no_angles: int
        total number of angles considered. This included the number in multiple roations. most likely this is
        int(opt_prop.angular_scatt_func.shape[0] / 2) * rotations

    rotations: int.
        number of rotations the of the mSASP.

    Returns
    -------
    pandas.DataFrame
        containing the sky brightness as a function of mSASPS azimuth angle"""
    layerbounderies = np.unique(layerbounderies.flatten())
    altitude = (layerbounderies[1:] + layerbounderies[:-1]) / 2.
    time_series = solar.get_sun_position_TS(time_series)
    where = array_tools.find_closest(time_series.data.Altitude.values,
                                     altitude)
    solar_elev = time_series.data.Solar_position_elevation.values[where]
    solar_az = time_series.data.Solar_position_azimuth.values[where]
    alts = time_series.data.Altitude.values[
        where]  # thats over acurate, cal simply use the layerbounderies

    if (type(pressure).__name__ == 'bool') or (type(temp).__name__ == 'bool'):
        if pressure and temp:
            # temp = time_series.data.Temperature
            # pressure = time_series.data.Barometric_pressure_Pa
            lb = pd.DataFrame(index=layerbounderies)
            select_list = ["Temperature", "Altitude", "Pressure_Pa"]

            bla = []
            for i in ["Temperature", "Altitude", "Pressure_Pa"]:
                if i not in time_series.data.columns:
                    bla.append(i)

            if len(bla) != 0:
                txt = 'The underlying housekeeping data has to have the following attributes for this operation to work: %s' % (
                    ["Temperature", "Altitude", "Pressure_Pa"])
                txt += '\nmissing:'
                for i in bla:
                    txt += '\n \t' + i
                # print(txt)
                raise AttributeError(txt)

            hkt = time_series.data.loc[:, select_list]

            hkt.index = hkt.Altitude
            hkt = hkt.sort_index()

            hkt_lb = pd.concat([hkt, lb]).sort_index().interpolate()
            hkt_lb = hkt_lb.groupby(hkt_lb.index).mean().reindex(lb.index)
            temp = hkt_lb.Temperature.values + 273.15
            pressure = hkt_lb.Pressure_Pa.values

        else:
            p, t = atmstd.standard_atmosphere(layerbounderies)
            if type(pressure).__name__ == 'bool':
                if pressure == False:
                    pressure = p
            if type(temp).__name__ == 'bool':
                if temp == False:
                    temp = t
    # print(pressure, temp)
    if (layerbounderies.shape != pressure.shape) or (layerbounderies.shape !=
                                                     temp.shape):
        raise ValueError('altitude, pressure and tmp have to have same shape')

    # time = time_series.data.index[where]

    what_mSASP_sees_rayleigh = pd.DataFrame()
    what_mSASP_sees_AOD_rayleigh = np.zeros(altitude.shape)

    for alt in range(altitude.shape[0]):
        # get the sun position at the time when the plane was at the particular altitude,

        sol_el = solar_elev[alt]
        sol_az = solar_az[alt]
        # print(alts[alt:])

        # return ray_scatt_fct

        # angles between mSASP positions and sun. This is used to pick the angle in the phase functions
        if sun_azimuth:
            sun_azimuth = sol_az
        else:
            sun_azimuth = 0
        mSASP2Sunangles = angle_MSASP_sun(
            sol_el,
            sun_azimuth=sun_azimuth,
            no_angles=no_angles,
            # pretty arbitrary number ... this is just to get a reasonal number of angles
            no_rotations=rotations)

        ray_scatt_fct = bray.rayleigh_angular_scattering_intensity(
            layerbounderies[alt:], pressure[alt:], temp[alt:], wl,
            mSASP2Sunangles.values.transpose())
        ray_scatt_fct = pd.DataFrame(ray_scatt_fct,
                                     index=mSASP2Sunangles.index)
        # return layerbounderies[alt:], pressure[alt:],temp[alt:], wl, ray_scatt_fct
        if airmassfct:
            slant_adjust = 1. / np.sin(solar_elev[alt])
        else:
            slant_adjust = 1.
        # closest_phase2sun_azi = array_tools.find_closest(ray_scatt_fct.index.values,
        #                                                  mSASP2Sunangles.mSASP_sun_angle.values)
        what_mSASP_sees_rayleigh[alts[alt]] = pd.Series(
            ray_scatt_fct.values.transpose()[0] * slant_adjust)
        # what_mSASP_sees_rayleigh.index = mSASP2Sunangles.index.values

        what_mSASP_sees_AOD_rayleigh[alt] = bray.rayleigh_optical_depth(
            layerbounderies[alt:], pressure[alt:], temp[alt:],
            wl) * slant_adjust
        # return layerbounderies[alt:],pressure[alt:],temp[alt:],wl, what_mSASP_sees_AOD_rayleigh[alt], slant_adjust

    what_mSASP_sees_rayleigh.index = mSASP2Sunangles.index
    what_mSASP_sees_AOD_rayleigh = pd.DataFrame(what_mSASP_sees_AOD_rayleigh,
                                                index=altitude,
                                                columns=['AOD_ray'])
    return what_mSASP_sees_rayleigh, what_mSASP_sees_AOD_rayleigh
示例#3
0
文件: miniSASP.py 项目: fanmei/atm-py
def simulate_from_rayleigh(time_series,
                           layerbounderies,
                           # altitude,
                           # layerbounderies,
                           pressure,
                           temp,
                           wl,
                           no_angles,
                           rotations,
                           airmassfct,
                           sun_azimuth):
    """ Fix this documentation!


    Simulates miniSASP signal from a size distribution layer series
    Arguments
    ---------
    layerbounderies: array-like
    altitude: float or array-like.
        Altitude for which the mSASP signal is simulated for in meters
    pressure: array, bool
        Atmospheric pressure in mbar. If False, value is taken from international standard atmosphere.
    temp: array, bool in K
    wl: wavelength in nm

    no_angles: int
        total number of angles considered. This included the number in multiple roations. most likely this is
        int(opt_prop.angular_scatt_func.shape[0] / 2) * rotations

    rotations: int.
        number of rotations the of the mSASP.

    Returns
    -------
    pandas.DataFrame
        containing the sky brightness as a function of mSASPS azimuth angle"""
    layerbounderies = np.unique(layerbounderies.flatten())
    altitude = (layerbounderies[1:] + layerbounderies[:-1]) / 2.
    time_series = solar.get_sun_position_TS(time_series)
    where = array_tools.find_closest(time_series.data.Altitude.values, altitude)
    solar_elev = time_series.data.Solar_position_elevation.values[where]
    solar_az = time_series.data.Solar_position_azimuth.values[where]
    alts = time_series.data.Altitude.values[where]  # thats over acurate, cal simply use the layerbounderies

    if (type(pressure).__name__ == 'bool') or (type(temp).__name__ == 'bool'):
        if pressure and temp:
            # temp = time_series.data.Temperature
            # pressure = time_series.data.Barometric_pressure_Pa
            lb = pd.DataFrame(index=layerbounderies)
            select_list = ["Temperature", "Altitude", "Pressure_Pa"]

            bla = []
            for i in ["Temperature", "Altitude", "Pressure_Pa"]:
                if i not in time_series.data.columns:
                    bla.append(i)

            if len(bla) != 0:
                txt='The underlying housekeeping data has to have the following attributes for this operation to work: %s'%(["Temperature", "Altitude", "Pressure_Pa"])
                txt+='\nmissing:'
                for i in bla:
                    txt += '\n \t' + i
                # print(txt)
                raise AttributeError(txt)

            hkt = time_series.data.loc[:, select_list]

            hkt.index = hkt.Altitude
            hkt = hkt.sort_index()

            hkt_lb = pd.concat([hkt, lb]).sort_index().interpolate()
            hkt_lb = hkt_lb.groupby(hkt_lb.index).mean().reindex(lb.index)
            temp = hkt_lb.Temperature.values + 273.15
            pressure = hkt_lb.Pressure_Pa.values

        else:
            p, t = atmstd.standard_atmosphere(layerbounderies)
            if type(pressure).__name__ == 'bool':
                if pressure == False:
                    pressure = p
            if type(temp).__name__ == 'bool':
                if temp == False:
                    temp = t
    # print(pressure, temp)
    if (layerbounderies.shape != pressure.shape) or (layerbounderies.shape != temp.shape):
        raise ValueError('altitude, pressure and tmp have to have same shape')

    # time = time_series.data.index[where]

    what_mSASP_sees_rayleigh = pd.DataFrame()
    what_mSASP_sees_AOD_rayleigh = np.zeros(altitude.shape)

    for alt in range(altitude.shape[0]):
        # get the sun position at the time when the plane was at the particular altitude,

        sol_el = solar_elev[alt]
        sol_az = solar_az[alt]
        # print(alts[alt:])

        # return ray_scatt_fct

        # angles between mSASP positions and sun. This is used to pick the angle in the phase functions
        if sun_azimuth:
            sun_azimuth = sol_az
        else:
            sun_azimuth = 0
        mSASP2Sunangles = angle_MSASP_sun(sol_el,
                                          sun_azimuth=sun_azimuth,
                                          no_angles=no_angles,
                                          # pretty arbitrary number ... this is just to get a reasonal number of angles
                                          no_rotations=rotations)

        ray_scatt_fct = bray.rayleigh_angular_scattering_intensity(layerbounderies[alt:], pressure[alt:], temp[alt:],
                                                                   wl, mSASP2Sunangles.values.transpose())
        ray_scatt_fct = pd.DataFrame(ray_scatt_fct, index=mSASP2Sunangles.index)
        # return layerbounderies[alt:], pressure[alt:],temp[alt:], wl, ray_scatt_fct
        if airmassfct:
            slant_adjust = 1. / np.sin(solar_elev[alt])
        else:
            slant_adjust = 1.
        # closest_phase2sun_azi = array_tools.find_closest(ray_scatt_fct.index.values,
        #                                                  mSASP2Sunangles.mSASP_sun_angle.values)
        what_mSASP_sees_rayleigh[alts[alt]] = pd.Series(ray_scatt_fct.values.transpose()[0] * slant_adjust)
        # what_mSASP_sees_rayleigh.index = mSASP2Sunangles.index.values

        what_mSASP_sees_AOD_rayleigh[alt] = bray.rayleigh_optical_depth(layerbounderies[alt:], pressure[alt:],
                                                                        temp[alt:], wl) * slant_adjust
        # return layerbounderies[alt:],pressure[alt:],temp[alt:],wl, what_mSASP_sees_AOD_rayleigh[alt], slant_adjust

    what_mSASP_sees_rayleigh.index = mSASP2Sunangles.index
    what_mSASP_sees_AOD_rayleigh = pd.DataFrame(what_mSASP_sees_AOD_rayleigh, index=altitude, columns=['AOD_ray'])
    return what_mSASP_sees_rayleigh, what_mSASP_sees_AOD_rayleigh
示例#4
0
    def optical_depth_rayleigh(self):
        if not self.__housekeeping:
            txt = 'To claculate the optical depth you will have to set the housekeeping property with a timeseries containing Altitude (m) Temperature (C) and Pressure (hPa)'
            raise AttributeError(txt)

        if not self.__od_ray_orig:
            hkt = self.housekeeping.copy()
            # import pdb
            # pdb.set_trace()
            # to make sure there is no two values with the same altitude in a row (causes sims to fail) ...
            clean = False
            while not clean:
                alt = hkt.data.Altitude.values
                dist = alt[1:] - alt[:-1]
                if (dist == 0).sum():
                    hkt.data.iloc[np.where(dist == 0)] = np.nan
                else:
                    clean = True
            # pdb.set_trace()
            hkt.data.dropna(axis=1, inplace=True)
            # pdb.set_trace()
            # do the od calculations for each wavelength channel
            c_list = np.array(
                sorted(self.wavelength_channels.items(),
                       key=lambda x: x[1]))[:, 0]
            for e, c in enumerate(c_list):
                wl = self.wavelength_channels[c]

                out = []
                for i in range(hkt.data.shape[0]):
                    if i < 1:
                        out.append(0.)
                        continue
                    hktt = hkt.data.iloc[0:i, :]
                    alt = -1 * hktt.Altitude.values
                    press = hktt.Pressure_Pa.values
                    temp = hktt.Temperature.values
                    ray = _bray.rayleigh_optical_depth(alt,
                                                       press, temp + 273.15,
                                                       float(wl))
                    out.append(ray)
                # pdb.set_trace()
                hkt.data[wl] = np.array(out)
                # pdb.set_trace()
            wll = np.array(
                sorted(self.wavelength_channels.items(),
                       key=lambda x: x[1]))[:, 1]  #.astype(float)
            # pdb.set_trace()
            hkt = hkt._del_all_columns_but(wll)
            # pdb.set_trace()
            self.__od_ray_orig = hkt

        if self.optical_depth_rayleigh_offsets != self.__od_ray_offset_last:
            # pdb.set_trace()
            self.__od_ray = self.__od_ray_orig.copy()
            # pdb.set_trace()
            # apply offset
            wll = np.array(
                sorted(self.wavelength_channels.items(),
                       key=lambda x: x[1]))[:, 1]  #.astype(float)
            for wl in wll:
                self.__od_ray.data[wl] += self.optical_depth_rayleigh_offsets[
                    wl]

            self.__od_ray_offset_last = self.optical_depth_rayleigh_offsets
        # pdb.set_trace()
        return self.__od_ray