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