Advanced Usage#

This section covers advanced topics that many users will not need. If you have questions on how to customize py-smps for your usage, please post to the discussions tab on the GitHub repository.

Create a custom particle sizer#

If you have a device that is not represented by one of the several available default classes of GenericParticleSizer, it may make sense for you to create a custom object that you can re-use. To do so, you simply need to build off of the GenericParticleSizer.

Let’s assume you have a device that is made up of 6 size bins defined as measuring the following:

  • bin0: 0.5 - 1 µm

  • bin1: 1 - 2.5 µm

  • bin2: 2.5 - 4 µm

  • bin3: 4 - 6 µm

  • bin4: 6 - 8 µm

  • bin5: 8 - 10 µm

[1]:
import smps
from smps.utils import make_bins
from smps.models import GenericParticleSizer
import numpy as np

# Create the class

class SuperSpecialSensor(GenericParticleSizer):
    """Create a super custom sensor class that inherits from the
    GenericParticleSizer.
    """
    def __init__(self, **kwargs):
        # Set the bins
        bins = make_bins(boundaries=np.array([0.5, 1., 2.5, 4., 6., 8., 10.]))

        # Set the bin labels
        bin_labels = [f"bin{i}" for i in range(bins.shape[0])]

        super(SuperSpecialSensor, self).__init__(bins=bins, bin_labels=bin_labels, **kwargs)

Above is all that is needed! The only thing we needed to customize was the bin boundaries as it can be quite repetitive to need to remember and type them in all of the time. If you wanted to, you could extend the class further and create your own custom methods or overwrite existing ones, but so far, no one has asked to do that!

Below, let’s go ahead and create a fake dataset and show how to initialize your new class and compute the PM2.5 value:

[2]:
import pandas as pd
import random

# Let's create a fake data source
df = pd.DataFrame({
    "bin0": [random.uniform(0, 100) for _ in range(100)],
    "bin1": [random.uniform(0, 80) for _ in range(100)],
    "bin2": [random.uniform(0, 60) for _ in range(100)],
    "bin3": [random.uniform(0, 40) for _ in range(100)],
    "bin4": [random.uniform(0, 20) for _ in range(100)],
    "bin5": [random.uniform(0, 10) for _ in range(100)],
})

# Initialize the new object with the fake data
obj = SuperSpecialSensor(data=df)

# Compute PM2.5
obj.integrate(weight='mass', dmin=0, dmax=2.5)
[2]:
0     340.986540
1     158.083108
2      58.874803
3     382.897253
4     108.371589
         ...
95     26.670686
96    330.302455
97    298.523118
98    136.981037
99     66.146042
Length: 100, dtype: float64