Size distribution
atmPy size_distribution is the gateway to exploring and manipulating aerosol properties based on their size distribution. Size distributions are treated in three different representations: simple one dimensional (SizeDist), size distribution timeseries (SizeDist_TS), or size distribution vertical profile (SizeDist_LS). The latter are a subclasses of the first and therefore inherit most properties, but in addition have tools specific to the representation. Explore the examples below to learn about some basics.
Examples
Module Overview
- class atmPy.aerosols.size_distribution.sizedistribution.SizeDist(data, bins, distType)
Bases:
object
Object defining a log normal aerosol size distribution
Arguments
- bincenters: NumPy array, optional
this is if you actually want to pass the bincenters, if False they will be calculated
- distributionType:
log normal: ‘dNdlogDp’,’dSdlogDp’,’dVdlogDp’ natural: ‘dNdDp’,’dSdDp’,’dVdDp’ number: ‘dNdlogDp’, ‘dNdDp’, ‘numberConcentration’ surface: ‘dSdlogDp’,’dSdDp’ volume: ‘dVdlogDp’,’dVdDp’
- data: pandas dataFrame, optional
- None, will generate an empty pandas data frame with columns defined by bins
- pandas dataFrame with
column names (each name is something like this: ‘150-200’)
index is time (at some point this should be arbitrary, convertable to altitude for example?)
- unit conventions:
diameters: nanometers
flowrates: cc (otherwise, axis label need to be adjusted an caution needs to be taken when dealing is AOD)
Notes
Diameters are specified in nanometers
- property DEPRECATEDoptical_properties
- property bincenters
- property bins
- property binwidth
- convert2dNdDp()
- convert2dNdlogDp()
- convert2dSdDp()
- convert2dSdlogDp()
- convert2dVdDp()
- convert2dVdlogDp()
- convert2numberconcentration()
- copy()
- correct4ambient_LFE_tmp_difference()
corrects for temperature differences between ambient and instrument. The Problem is that the instrument samples at a constant flow at the temperature of the laminar flow element not the ambient temperatrue … this corrects for it Make sure your housekeeping has a column named Temperature and one named Temperature_instrument
- correct4flowrate(flowrate)
This simply normalizes to to provided flow rate. In principle this could be the flow rate reported in the the housekeeping file … and in other instruments then POPS it probably shoud… However in POPS this value is questionable and the set_point is a more usefull value
- property data
- extend_bin_range(lower=None, upper=None, raise_uneven_bin_width_error=True, fill_value=0)
Extends the bin range. This will only work if bins are log-equally spaced. Only tested for SizeDist (not for TS or LS). Currently works on the small diameter side only … easy programming will allow for larger diameters too
Parameters
- lower: float
The new lower diameter limit.
upper:
Returns
size distribution instance with extra bins. Data filled with nan.
- extrapolate_size_dist(newlimit)
Extrapolates the size distribution range assuming a nomal distributed aerosol mode. This will only work if bins are log-equally spaced. Only tested for SizeDist (not for TS or LS). Currently works on the small diameter side only … easy programming will allow for larger diameters too
Parameters
- newlimit: float
The new lower diameter limit.
Returns
size distribution instance with extra bins. Data filled with results from fitting with normal distribution.
- fillGaps(scale=1.1)
Note: This function is purly esteticall and should be removed since it can also create errors … Finds gaps in dataset (e.g. when instrument was shut of) and fills them with zeros.
It adds one line of zeros to the beginning and one to the end of the gap. Therefore the gap is visible as zeros instead of the interpolated values
Parameters
- scale: float, optional
This is a scale.
- grow_sizedistribution(growthfactor, extend_diameter_limits=False, raise_particle_loss_error=True)
Shift the bins to simulate growth. But than rebins to the original bins.
Parameters
- growthfactorTYPE
DESCRIPTION.
- extend_diameter_limitsTYPE, optional
DESCRIPTION. The default is False.
- raise_particle_loss_errorTYPE, optional
DESCRIPTION. The default is True.
Returns
- distTYPE
DESCRIPTION.
- property housekeeping
- property hygroscopicity
- property mean_diameter_geometric
- property mode_analysis
- property normal_distribution_fits
- property optical_properties
- property particle_mass_concentration
- property particle_mass_mixing_ratio
- property particle_mean_diameter
- property particle_number_concentration
- property particle_number_mixing_ratio
- property particle_surface_concentration
- property particle_volume_concentration
- plot(showMinorTickLabels=True, removeTickLabels=['700', '900'], fit_res=True, fit_res_scale='log', ax=None, **kwargs)
Plots and returns f,a (figure, axis).
Arguments
- showMinorTickLabels: bool [True], optional
if minor tick labels are labled
- removeTickLabels: list of string [“700”, “900”], optional
list of tick labels aught to be removed (in case there are overlapping)
- fit_res: bool [True], optional
allows plotting of fitresults if fit_normal was previously executed
- fit_res: string
If fit_normal was done using log = False, you want to set this to linear!
- ax: axis object [None], optional
option to provide axis to plot on
Returns
Handles to the figure and axes of the figure.
- re_bin(number_of_bins=50, spaced='log', bins=None)
- reduce2temp_press_ambient(tmp_is='auto', tmp_is_column='Temperature_instrument', press_is_column='Pressure_Pa')
This function corrects the particles concentrations to ambient conditions. This is necessary if the temperature of the instrument is different then ambient. When the instrument is adjusting the flow to a constant rate it will be at the instrument temperature not ambient -> correction required tmp in C press in hPa
- reduce2temp_press_standard(tmp_is='auto', tmp_is_column='Temperature_instrument', press_is_column='Pressure_Pa')
tmp in C press in hPa
- save_csv(fname, header=True)
- save_hdf(hdf, variable_name=None, info='', force=False)
- save_netcdf(fname, housekeeping=True, value_added_products=True, binunit='nm', tags=[], test=False)
Save to netCDF format
Parameters
fname: str housekeeping: bool [True]
If housekeeping is saved
- value_added_products: bool [True]
If value added products (currently, norm_fitresults) are going to be saved
- binunit: str
The units of the diameter of the binedges and centers
tags: list test: bool
If true the xarray.Dataset is not saved but retured instead.
- property submicron_volume_ratio
- property sup_optical_properties_wavelength
- zoom_diameter(start=None, end=None)
- class atmPy.aerosols.size_distribution.sizedistribution.SizeDist_LS(data, bins, distributionType, layerbounderies)
Bases:
SizeDist
Parameters
data: pandas DataFrame … bins: array distributionType: str layerbounderies: array shape(n_layers,2)
OLD
- data: pandas dataFrame with
column names (each name is something like this: ‘150-200’)
altitude (at some point this should be arbitrary, convertable to altitude for example?)
- unit conventions:
diameters: nanometers
flowrates: cc (otherwise, axis label need to be adjusted an caution needs to be taken when dealing is AOD)
- distributionType:
log normal: ‘dNdlogDp’,’dSdlogDp’,’dVdlogDp’ natural: ‘dNdDp’,’dSdDp’,’dVdDp’ number: ‘dNdlogDp’, ‘dNdDp’, ‘numberConcentration’ surface: ‘dSdlogDp’,’dSdDp’ volume: ‘dVdlogDp’,’dVdDp’
- add_layer(sd, layerboundery)
Adds a sizedistribution instance to the layerseries. layerboundery
Parameters
sd: layerboundary:
- average_overAllAltitudes()
- average_overAltitude(window='1S')
- deprecated_apply_growth(growth_factor, how='shift_data')
see docstring of atmPy.sizedistribution.SizeDist for more information Parameters ———- kappa: float RH: bool, float, or array.
If None, RH from self.housekeeping will be taken
- deprecated_apply_hygro_growth(kappa, RH=None, how='shift_data')
see docstring of atmPy.sizedistribution.SizeDist for more information Parameters ———- kappa: float RH: bool, float, or array.
If None, RH from self.housekeeping will be taken
- deprecated_calculate_angstromex(wavelengths=[460.3, 550.4, 671.2, 860.7], n=1.455)
Calculates the Anstrome coefficience (overall, layerdependent)
Parameters
- wavelengths: array-like, optional.
the angstrom coefficient will be calculated based on the AOD of these wavelength values (in nm)
- n: float, optional.
index of refraction used in the underlying mie calculation.
Returns
Angstrom exponent, float List containing the OpticalProperties instances for the different wavelengths
New Attributes
- angstromexp: float
the resulting angstrom exponent
- angstromexp_fit: pandas instance.
AOD and fit result as a function of wavelength
- angstromexp_LS: pandas instance.
angstrom exponent as a function of altitude
- fit_normal()
Fits a single normal distribution to each line in the data frame.
Returns
pandas DataFrame instance (also added to namespace as data_fit_normal)
- grow_sizedistribution(growthfactor, extend_diameter_limits=False, raise_particle_loss_error=True)
Shift the bins to simulate growth. But than rebins to the original bins.
Parameters
- growthfactorTYPE
DESCRIPTION.
- extend_diameter_limitsTYPE, optional
DESCRIPTION. The default is False.
- raise_particle_loss_errorTYPE, optional
DESCRIPTION. The default is True.
Returns
- distTYPE
DESCRIPTION.
- property housekeeping
- property layerbounderies
- property layercenters
- property optical_properties
- property particle_mass_concentration
- property particle_mass_mixing_ratio
- property particle_number_concentration
- property particle_number_mixing_ratio
- plot(vmax=None, vmin=None, scale='linear', show_minor_tickLabels=True, removeTickLabels=['500', '700', '800', '900'], plotOnTheseAxes=False, cmap=<matplotlib.colors.LinearSegmentedColormap object>, fit_pos=False, ax=None, colorbar=True)
plots and returns f,a,pc,cb (figure, axis, pcolormeshInstance, colorbar)
Arguments
scale (optional): (‘log’,[‘linear’]) - defines how the z-direction is scaled vmax vmin show_minor_tickLabels: cma: fit_pos (optional): bool [True] - plots the position of a fitted normal distribution onto the plot.
in order for this to work execute fit_normal
ax (optional): axes instance [None] - option to plot on existing axes
- plot_angstromex_LS(corr_coeff=False, std=False)
- plot_angstromex_fit()
- plot_eachLayer(a=None, normalize=False)
Plots the distribution of each layer in one plot.
Returns
Handles to the figure and axes of the plot
- plot_overview(layers=None, show_center_of_layers=True, fit_pos=True)
Plot 3 plots: Size distribution Vertical profile, average size distribution, particle concentration. Optional layers can be defined that show up in the average plot instead of the overall average.
Parameters
- layers: dict, e.g. {‘bottom’: [0, 300]}
define layers do average over here
- show_center_of_layers: bool
if to show the centers of thelayers in the other plots
- zoom_altitude(bottom, top)
‘2014-11-24 16:02:30’
- class atmPy.aerosols.size_distribution.sizedistribution.SizeDist_TS(*args, fill_data_gaps_with=None, ignore_data_gap_error=True, **kwargs)
Bases:
SizeDist
Returns a SizeDistribution_TS instance.
Parameters:
- data: pandas dataFrame with
column names (each name is something like this: ‘150-200’)
index is time (at some point this should be arbitrary, convertable to altitude for example?)
- unit conventions:
diameters: nanometers
flowrates: cc (otherwise, axis label need to be adjusted an caution needs to be taken when dealing is AOD)
- distributionType:
log normal: ‘dNdlogDp’,’dSdlogDp’,’dVdlogDp’ natural: ‘dNdDp’,’dSdDp’,’dVdDp’ number: ‘dNdlogDp’, ‘dNdDp’, ‘numberConcentration’ surface: ‘dSdlogDp’,’dSdDp’ volume: ‘dVdlogDp’,’dVdDp’
- average_overAllTime(sigma=0, minmax=False, percentile=False)
averages over the entire dataFrame and returns a single sizedistribution (numpy.ndarray)
Args
- minmax: bool
returns in addition size distribution that represent the min and max values
- percentile: float
percentile to be calculated and returned in addition to averaged sizedist
- sigma (!experimental!): int
if not ==0 this function will additionally return the std according to sigma
- average_time(window='10s')
returns a copy of the sizedistribution_TS with reduced size by averaging over a given window. Thesedays it is merely a wrap around pandas resample function
Arguments
- window: str
see pandas resample doc
Returns
- SizeDistribution_TS instance
copy of current instance with resampled data frame
- close_gaps(verbose=False)
This is an older version to deal with gaps … rather consider using the ones in the data_structure module
- convert2verticalprofile(layer_thickness=2)
- deprecated_apply_growth(growth_factor, how='shift_data')
see docstring of atmPy.sizedistribution.SizeDist for more information Parameters ———- kappa: float RH: bool, float, or array.
If None, RH from self.housekeeping will be taken
- deprecated_apply_hygro_growth(kappa, RH=None, how='shift_data', adjust_refractive_index=True)
see docstring of atmPy.sizedistribution.SizeDist for more information Parameters ———- kappa: float RH: bool, float, or array.
If None, RH from self.housekeeping will be taken
- detect_gaps(toleranz=1.95, return_all=False)
- dprecated_convert2layerseries(hk, layer_thickness=10, force=False)
convertes the time series to a layer series.
Note
nan values are excluded when an average is taken over a the time that corresponds to the particular layer (altitude). If there are only nan values nan is returned and there is a gap in the Layerseries.
The the housekeeping instance has to have a column called “Altitude” and which is monotonicly in- or decreasing
Arguments
hk: housekeeping instance layer_thickness (optional): [10] thickness of each generated layer in meter
- fill_gaps_with(what=0, toleranz=1.95)
- fit_normal_deprecated(log=True, p0=[10, 180, 0.2])
Fits a single normal distribution to each line in the data frame.
Returns
pandas DataFrame instance (also added to namespace as data_fit_normal)
- get_timespan()
- grow_sizedistribution(growthfactor, extend_diameter_limits=False, raise_particle_loss_error=True)
Shift the bins to simulate growth. But than rebins to the original bins.
Parameters
- growthfactorTYPE
DESCRIPTION.
- extend_diameter_limitsTYPE, optional
DESCRIPTION. The default is False.
- raise_particle_loss_errorTYPE, optional
DESCRIPTION. The default is True.
Returns
- distTYPE
DESCRIPTION.
- property optical_properties
- property particle_mass_concentration
- property particle_mass_mixing_ratio
- property particle_mean_diameter
- property particle_number_concentration
- property particle_number_mixing_ratio
- plot(vmax=None, vmin=None, norm='linear', showMinorTickLabels=True, ax=None, fit_pos=False, cmap=<matplotlib.colors.LinearSegmentedColormap object>, colorbar=True)
plots an intensity plot of all data
Arguments
scale (optional): (‘log’,[‘linear’]) - defines how the z-direction is scaled vmax vmin show_minor_tickLabels: cma: fit_pos: bool[True]. Optional
plots the position of a fitted normal distribution onto the plot. in order for this to work execute fit_normal
ax (optional): axes instance [None] - option to plot on existing axes
Returns
f,a,pc,cb (figure, axis, pcolormeshInstance, colorbar)
- zoom_time(start=None, end=None)
2014-11-24 16:02:30
- atmPy.aerosols.size_distribution.sizedistribution.align2sizedist(sizedist, other)
- atmPy.aerosols.size_distribution.sizedistribution.fit_normal_distribution2sizedist(sizedist, log=True, p0=[10, 180, 0.2], show_error=False, curve_fit_kwargs=None)
Fits a single normal distribution to each line in the data frame.
Parameters
- p0: array-like
fit initiation parameters [amp, pos, width(log-width)]
- curve_fit_kwargs: dict
Additional kwargs that are passed to the fit routine
log: not really working
Returns
pandas DataFrame instance (also added to namespace as data_fit_normal)
- atmPy.aerosols.size_distribution.sizedistribution.generate_aerosolLayer(diameter=[0.01, 2.5], numberOfDiameters=30, centerOfAerosolMode=0.6, widthOfAerosolMode=0.2, numberOfParticsInMode=10000, layerBoundery=[0.0, 10000])
Probably deprecated!?! generates a numberconcentration of an aerosol layer which has a gaussian shape when plottet in dN/log(Dp). However, returned is a numberconcentrations (simply the number of particles in each bin, no normalization) Returns
Number concentration (#) bin edges (nm)
- atmPy.aerosols.size_distribution.sizedistribution.get_label(distType)
Return the appropriate label for a particular distribution type
- atmPy.aerosols.size_distribution.sizedistribution.get_settings()
- atmPy.aerosols.size_distribution.sizedistribution.merge_size_distributions(dist_self, dist_other, fill_value=0, round_dec=5)
Experimental!!! Merges (adds) two sizedistributions that have different length. Currently this is only working if the overlapping section of the size distributions is aligned (bins are exactly the same where overlapping)
Parameters
dist_self dist_other fill_value: float [0]
When adding a value to nan the result is nan. Therefore all the nans are replaced with this value.
- round_dec: int [5]
sometimes the bins are not equal due to rounding issue in the 10 or so digit. Rounding to the 5th digit ususally takes care of that without introducing an error
Returns
size distribution
- atmPy.aerosols.size_distribution.sizedistribution.open_csv(fname, fill_data_gaps_with=None, ignore_data_gap_error=False)
- Args:
fname: fill_data_gaps_with: float
If None gaps are not filled. This should eighter be np.nan (if the instrument failed) or 0 if particle concentration was so low, that no particle was detected in that time window
ignore_data_gap_error:
Returns:
- atmPy.aerosols.size_distribution.sizedistribution.open_netcdf(fname)
- atmPy.aerosols.size_distribution.sizedistribution.save_netcdf(sizedist, fname, housekeeping=True, value_added_products=True, binunit='nm', tags=[], test=False)
Save to netCDF format
Parameters
fname: str housekeeping: bool [True]
If housekeeping is saved
- value_added_products: bool [True]
If value added products (currently, norm_fitresults) are going to be saved
- binunit: str
The units of the diameter of the binedges and centers
tags: list test: bool
If true the xarray.Dataset is not saved but retured instead.
- atmPy.aerosols.size_distribution.sizedistribution.simulate_sizedistribution(diameter=[10, 2500], numberOfDiameters=100, centerOfAerosolMode=200, widthOfAerosolMode=0.2, numberOfParticsInMode=1000)
generates a numberconcentration of an aerosol layer which has a gaussian shape when plottet in dN/log(Dp). However, returned is a numberconcentrations (simply the number of particles in each bin, no normalization) Returns
Number concentration (#) bin edges (nm)
- atmPy.aerosols.size_distribution.sizedistribution.simulate_sizedistribution_layerseries(diameter=[10, 2500], numberOfDiameters=100, heightlimits=[0, 6000], noOflayers=100, layerHeight=[500.0, 4000.0], layerThickness=[100.0, 300.0], layerDensity=[1000.0, 5000.0], layerModecenter=[200.0, 800.0], widthOfAerosolMode=0.2)
- atmPy.aerosols.size_distribution.sizedistribution.simulate_sizedistribution_timeseries(diameter=[10, 2500], numberOfDiameters=100, centerOfAerosolMode=200, widthOfAerosolMode=0.2, numberOfParticsInMode=1000, startDate='2014-11-24 17:00:00', endDate='2014-11-24 18:00:00', frequency=10)
- atmPy.aerosols.size_distribution.sizedistribution.test_ext_coeff_vertical_profile()
- atmPy.aerosols.size_distribution.sizedistribution.test_generate_numberConcentration()
result should look identical to Atmospheric Chemistry and Physis page 422