def depolarization_factor(wl): """Bucholtz 95 Table 1 Depolarization factor as fct of wavelength in nm""" rho = np.array([[0.200, 4.545], [0.205, 4.384], [0.210, 4.221], [0.215, 4.113], [0.220, 4.004], [0.225, 3.895], [0.230, 3.785], [0.240, 3.675], [0.250, 3.565], [0.260, 3.455], [0.270, 3.400], [0.280, 3.289], [0.290, 3.233], [0.300, 3.178], [0.310, 3.178], [.32, 3.122], [.33, 3.066], [.34, 3.066], [.35, 3.01], [.37, 3.01], [.38, 2.955], [0.4, 2.955], [0.45, 2.899], [0.5, 2.842], [0.55, 2.842], [0.6, 2.786], [0.75, 2.786], [0.8, 2.73], [1., 2.73]]).transpose() rho[0] *= 1000 rho[1] *= 0.01 idx = array_tools.find_closest(rho[0], wl) return rho[1][idx]
def depolarization_factor(wl): """Bucholtz 95 Table 1 Depolarization factor as fct of wavelength in nm""" rho = np.array([[0.200, 4.545], [0.205, 4.384], [0.210, 4.221], [0.215, 4.113], [0.220, 4.004], [0.225, 3.895], [0.230, 3.785], [0.240, 3.675], [0.250, 3.565], [0.260, 3.455], [0.270, 3.400], [0.280, 3.289], [0.290, 3.233], [0.300, 3.178], [0.310, 3.178], [.32, 3.122], [.33, 3.066], [.34, 3.066], [.35, 3.01], [.37, 3.01], [.38, 2.955], [0.4, 2.955], [0.45, 2.899], [0.5, 2.842], [0.55, 2.842], [0.6, 2.786], [0.75, 2.786], [0.8, 2.73], [1., 2.73] ]).transpose() rho[0] *= 1000 rho[1] *= 0.01 idx = array_tools.find_closest(rho[0], wl) return rho[1][idx]
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_size_dist_opt(opt_prop, airmassfct=True, rotations=2, sun_azimuth=True, pressure=True, temp=True): """ Simulates miniSASP signal from a size distribution layer series (in particular from the optical property class derived from the layer series. The simulation calculates the position of the sun at the instruments position during the experiment. Slant angles are considert. The atmosphere above the top layer is unkonwn, therefore the measurement from the miniSASP at the top most layer should be added to all results. Note ---- Temperature and pressure are currently not considered in the underlying Rayleigh calculations. Instead, an international standard atmosphere was used. Arguments --------- OpticalProperties class which was created from a layer series (dist_LS) using the sizedistribution module. airmassfct: bool, optional. If True, results will be corrected for the airmassfactor (slant angle only) rotations: int. Number of rotations of the mSASP to be simulated. pressure: bool or array-like. If True the opt_prop.paretn_timeseries.Barometric_pressure timeseries. If False standard atmosphere is used. If array-like the this array is used. temp: bool or array-like. If True the opt_prop.paretn_timeseries.Temperature timeseries. If False standard atmosphere is used. If array-like the this array is used. Returns ------- dict: containing three (aerosol, rayleigh, sum) pandas DataFrames each with the sky brightness as a function of mSASPS azimuth angle. pandas DataFrame: AOD as a function of elevaton""" time_series = opt_prop.parent_dist_LS.parent_timeseries dist_ls = opt_prop.parent_dist_LS layerthickness = np.apply_along_axis(lambda line: line[1] - line[0], 1, dist_ls.layerbounderies) time_series = solar.get_sun_position_TS(time_series) where = array_tools.find_closest(time_series.data.Altitude.values, dist_ls.layercenters) alts = time_series.data.Altitude.values[where] solar_elev = time_series.data.Solar_position_elevation.values[where] solar_az = time_series.data.Solar_position_azimuth.values[where] # time = time_series.data.index[where] what_mSASP_sees_aerosols = pd.DataFrame() what_mSASP_sees_AOD_aerosols = np.zeros(alts.shape) for altitude in range(dist_ls.layercenters.shape[0]): # get the sun position at the time when the plane was at the particular altitude, sol_el = solar_elev[altitude] sol_az = solar_az[altitude] # 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=int(opt_prop.angular_scatt_func.shape[0] / 2) * rotations, # pretty arbitrary number ... this is just to get a reasonal number of angles no_rotations=rotations) # pick relevant angles in phase function for each layer, this includes selecting the relavant layers (selected altitude to top). closest_phase2sun_azi = array_tools.find_closest( opt_prop.angular_scatt_func.index.values, mSASP2Sunangles.mSASP_sun_angle.values) # minimize so values are calculated only once closest_phase2sun_azi = np.unique(closest_phase2sun_azi) phase_fct_rel = opt_prop.angular_scatt_func.iloc[closest_phase2sun_azi, altitude:] # Integrate ofer selected intensities in phase function along vertical line (from selected height to top) # x = phase_fct_rel.columns.values # do_integ = lambda y: integrate.simps(y, x) # phase_fct_rel_integ = pd.DataFrame(phase_fct_rel.apply(do_integ, axis=1), # columns=[alts[altitude]], # # columns=[dist_ls.layercenters[altitude]] # ) # these are the integrated intensities of scattered light into the relavant angles. Integration is from current (arbitrary) to top layer # print(phase_fct_rel.shape, layerthickness[altitude:].shape) phth = phase_fct_rel * layerthickness[altitude:] phase_fct_rel_integ = pd.DataFrame(phth.apply(np.sum, 1)) # return phase_fct_rel, phase_fct_rel_integ if airmassfct: slant_adjust = 1. / np.sin(solar_elev[altitude]) else: slant_adjust = 1. # similar to above this selects the different angels of mSASP to the sun. However, it keeps all of them (no unique) closest_phase2sun_azi = array_tools.find_closest( phase_fct_rel_integ.index.values, mSASP2Sunangles.mSASP_sun_angle.values) what_mSASP_sees_aerosols[dist_ls.layercenters[altitude]] = pd.Series( phase_fct_rel_integ.iloc[closest_phase2sun_azi].values.transpose() [0] * slant_adjust) # what_mSASP_sees_aerosols[dist_ls.layercenters[altitude]] = pd.Series( # phase_fct_rel_integ.iloc[closest_phase2sun_azi].values.transpose()[0] * slant_adjust) # what_mSASP_sees_AOD_aerosols[altitude] = opt_prop.data_orig['AOD_layer'][altitude:].sum().values[0] * slant_adjust what_mSASP_sees_AOD_aerosols[altitude] = opt_prop.data_orig[ 'AOD_cum'].values[altitude][0] * slant_adjust what_mSASP_sees_aerosols.index = mSASP2Sunangles.index # what_mSASP_sees_AOD_aerosols = pd.DataFrame(what_mSASP_sees_AOD_aerosols, index = alts, columns = ['AOD_aerosols']) what_mSASP_sees_AOD = pd.DataFrame(what_mSASP_sees_AOD_aerosols, columns=['aerosol']) what_mSASP_sees_sky = {'aerosol': what_mSASP_sees_aerosols} what_mSASP_sees_rayleigh, what_mSASP_sees_AOD_rayleigh = simulate_from_rayleigh( time_series, dist_ls.layerbounderies, pressure, temp, opt_prop.wavelength, what_mSASP_sees_aerosols.shape[0], rotations, airmassfct, sun_azimuth) what_mSASP_sees_rayleigh.columns = dist_ls.layercenters what_mSASP_sees_sky['rayleigh'] = what_mSASP_sees_rayleigh what_mSASP_sees_sum = what_mSASP_sees_aerosols + what_mSASP_sees_rayleigh what_mSASP_sees_sky['sum'] = what_mSASP_sees_sum # what_mSASP_sees_sky['aerosols'] = what_mSASP_sees_aerosols what_mSASP_sees_AOD_sum = what_mSASP_sees_AOD_aerosols + what_mSASP_sees_AOD_rayleigh.values.transpose( )[0] # what_mSASP_sees_AOD['aerosols'] = what_mSASP_sees_AOD_aerosols what_mSASP_sees_AOD[ 'rayleigh'] = what_mSASP_sees_AOD_rayleigh.values.transpose()[0] what_mSASP_sees_AOD['sum'] = what_mSASP_sees_AOD_sum # return what_mSASP_sees_AOD_aerosols , what_mSASP_sees_AOD_rayleigh.values.transpose()[0] # what_mSASP_sees_AOD_aerosols = pd.DataFrame(what_mSASP_sees_AOD_aerosols, index = alts, columns = ['AOD']) what_mSASP_sees_AOD.index = alts return what_mSASP_sees_sky, what_mSASP_sees_AOD
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_size_dist_opt(opt_prop, airmassfct=True, rotations=2, sun_azimuth=True, pressure=True, temp=True): """ Simulates miniSASP signal from a size distribution layer series (in particular from the optical property class derived from the layer series. The simulation calculates the position of the sun at the instruments position during the experiment. Slant angles are considert. The atmosphere above the top layer is unkonwn, therefore the measurement from the miniSASP at the top most layer should be added to all results. Note ---- Temperature and pressure are currently not considered in the underlying Rayleigh calculations. Instead, an international standard atmosphere was used. Arguments --------- OpticalProperties class which was created from a layer series (dist_LS) using the sizedistribution module. airmassfct: bool, optional. If True, results will be corrected for the airmassfactor (slant angle only) rotations: int. Number of rotations of the mSASP to be simulated. pressure: bool or array-like. If True the opt_prop.paretn_timeseries.Barometric_pressure timeseries. If False standard atmosphere is used. If array-like the this array is used. temp: bool or array-like. If True the opt_prop.paretn_timeseries.Temperature timeseries. If False standard atmosphere is used. If array-like the this array is used. Returns ------- dict: containing three (aerosol, rayleigh, sum) pandas DataFrames each with the sky brightness as a function of mSASPS azimuth angle. pandas DataFrame: AOD as a function of elevaton""" time_series = opt_prop.parent_dist_LS.parent_timeseries dist_ls = opt_prop.parent_dist_LS layerthickness = np.apply_along_axis(lambda line: line[1] - line[0], 1, dist_ls.layerbounderies) time_series = solar.get_sun_position_TS(time_series) where = array_tools.find_closest(time_series.data.Altitude.values, dist_ls.layercenters) alts = time_series.data.Altitude.values[where] solar_elev = time_series.data.Solar_position_elevation.values[where] solar_az = time_series.data.Solar_position_azimuth.values[where] # time = time_series.data.index[where] what_mSASP_sees_aerosols = pd.DataFrame() what_mSASP_sees_AOD_aerosols = np.zeros(alts.shape) for altitude in range(dist_ls.layercenters.shape[0]): # get the sun position at the time when the plane was at the particular altitude, sol_el = solar_elev[altitude] sol_az = solar_az[altitude] # 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=int(opt_prop.angular_scatt_func.shape[0] / 2) * rotations, # pretty arbitrary number ... this is just to get a reasonal number of angles no_rotations=rotations) # pick relevant angles in phase function for each layer, this includes selecting the relavant layers (selected altitude to top). closest_phase2sun_azi = array_tools.find_closest(opt_prop.angular_scatt_func.index.values, mSASP2Sunangles.mSASP_sun_angle.values) # minimize so values are calculated only once closest_phase2sun_azi = np.unique(closest_phase2sun_azi) phase_fct_rel = opt_prop.angular_scatt_func.iloc[closest_phase2sun_azi, altitude:] # Integrate ofer selected intensities in phase function along vertical line (from selected height to top) # x = phase_fct_rel.columns.values # do_integ = lambda y: integrate.simps(y, x) # phase_fct_rel_integ = pd.DataFrame(phase_fct_rel.apply(do_integ, axis=1), # columns=[alts[altitude]], # # columns=[dist_ls.layercenters[altitude]] # ) # these are the integrated intensities of scattered light into the relavant angles. Integration is from current (arbitrary) to top layer # print(phase_fct_rel.shape, layerthickness[altitude:].shape) phth = phase_fct_rel * layerthickness[altitude:] phase_fct_rel_integ = pd.DataFrame(phth.apply(np.sum, 1)) # return phase_fct_rel, phase_fct_rel_integ if airmassfct: slant_adjust = 1. / np.sin(solar_elev[altitude]) else: slant_adjust = 1. # similar to above this selects the different angels of mSASP to the sun. However, it keeps all of them (no unique) closest_phase2sun_azi = array_tools.find_closest(phase_fct_rel_integ.index.values, mSASP2Sunangles.mSASP_sun_angle.values) what_mSASP_sees_aerosols[dist_ls.layercenters[altitude]] = pd.Series( phase_fct_rel_integ.iloc[closest_phase2sun_azi].values.transpose()[0] * slant_adjust) # what_mSASP_sees_aerosols[dist_ls.layercenters[altitude]] = pd.Series( # phase_fct_rel_integ.iloc[closest_phase2sun_azi].values.transpose()[0] * slant_adjust) # what_mSASP_sees_AOD_aerosols[altitude] = opt_prop.data_orig['AOD_layer'][altitude:].sum().values[0] * slant_adjust what_mSASP_sees_AOD_aerosols[altitude] = opt_prop.data_orig['AOD_cum'].values[altitude][0] * slant_adjust what_mSASP_sees_aerosols.index = mSASP2Sunangles.index # what_mSASP_sees_AOD_aerosols = pd.DataFrame(what_mSASP_sees_AOD_aerosols, index = alts, columns = ['AOD_aerosols']) what_mSASP_sees_AOD = pd.DataFrame(what_mSASP_sees_AOD_aerosols, columns=['aerosol']) what_mSASP_sees_sky = {'aerosol': what_mSASP_sees_aerosols} what_mSASP_sees_rayleigh, what_mSASP_sees_AOD_rayleigh = simulate_from_rayleigh(time_series, dist_ls.layerbounderies, pressure, temp, opt_prop.wavelength, what_mSASP_sees_aerosols.shape[0], rotations, airmassfct, sun_azimuth) what_mSASP_sees_rayleigh.columns = dist_ls.layercenters what_mSASP_sees_sky['rayleigh'] = what_mSASP_sees_rayleigh what_mSASP_sees_sum = what_mSASP_sees_aerosols + what_mSASP_sees_rayleigh what_mSASP_sees_sky['sum'] = what_mSASP_sees_sum # what_mSASP_sees_sky['aerosols'] = what_mSASP_sees_aerosols what_mSASP_sees_AOD_sum = what_mSASP_sees_AOD_aerosols + what_mSASP_sees_AOD_rayleigh.values.transpose()[0] # what_mSASP_sees_AOD['aerosols'] = what_mSASP_sees_AOD_aerosols what_mSASP_sees_AOD['rayleigh'] = what_mSASP_sees_AOD_rayleigh.values.transpose()[0] what_mSASP_sees_AOD['sum'] = what_mSASP_sees_AOD_sum # return what_mSASP_sees_AOD_aerosols , what_mSASP_sees_AOD_rayleigh.values.transpose()[0] # what_mSASP_sees_AOD_aerosols = pd.DataFrame(what_mSASP_sees_AOD_aerosols, index = alts, columns = ['AOD']) what_mSASP_sees_AOD.index = alts return what_mSASP_sees_sky, what_mSASP_sees_AOD