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
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
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
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