def sun_elevetion(self): """ doc is not correct!!! This function uses telemetry data from the airplain (any timeseries including Lat and Lon) to calculate the sun's elevation. Based on the sun's elevation an airmass factor is calculated which the data is corrected for. Arguments --------- sun_intensities: Sun_Intensities_TS instance picco: any timeseries instance containing Lat and Lon """ if not self.housekeeping: txt = 'For this calculation we need information on Lat, Lon, Altitude. Please set the attribute housekeeping with a timeseries that has these informations' raise AttributeError(txt) if not self.__sun_elevation: cols = self.housekeeping.data.columns merged = self.merge(self.housekeeping, recognize_gaps=False) merged = merged._del_all_columns_but(cols) ts = solar.get_sun_position_TS(merged) ts = ts._del_all_columns_but(['Solar_position_elevation']) self.__sun_elevation = ts # picco_t = timeseries.TimeSeries(picco.data.loc[:, ['Lat', 'Lon', 'Altitude']]) # only Altitude, Lat and Lon # sun_int_su = self.merge(picco_t) # out = sun_int_su.get_sun_position() # # sun_int_su = sun_int_su.zoom_time(spiral_up_start, spiral_up_end) # arrays = np.array([sun_int_su.data.index, sun_int_su.data.Altitude, sun_int_su.data.Solar_position_elevation]) # tuples = list(zip(*arrays)) # index = pd.MultiIndex.from_tuples(tuples, names=['Time', 'Altitude', 'Sunelevation']) # sun_int_su.data.index = index # sun_int_su.data = sun_int_su.data.drop( # ['Altitude', 'Solar_position_elevation', 'Solar_position_azimuth', 'Lon', 'Lat'], axis=1) return self.__sun_elevation
def get_sun_position(self): """read docstring of solar.get_sun_position_TS""" out = solar.get_sun_position_TS(self) return out
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