Module defs.computing
-Classes
--
-
-class OFRAnalyser -(sourcefile, headlines=238, density=1.2, lower_bound=0, upper_bound=1896, scan_up=160, scan_down=20, flow_rate=5) -
--
-
---
-Expand source code -
-
-class OFRAnalyser: - - def __init__(self, sourcefile, headlines = 238, density=1.2, lower_bound = 0, upper_bound = 1896, scan_up=160, scan_down=20, - flow_rate=5) -> None: - - # where to take data from: - self.sourcefile = sourcefile - # how many lines to skip until the raw counts data section is reached: - self.headlines = headlines - # assumed SOA density - self.density = density - self.lower_bound = lower_bound - self.upper_bound = upper_bound - self.scan_up = scan_up - self.scan_down = scan_down - self.filter_flow_rate = flow_rate # Flow rate of the OFR flow through the filer in (m3/s) - - with open(self.sourcefile) as file: - file_reader = csv.reader(file) - for index, row in enumerate(file_reader): - if index != self.headlines: - continue - else: - head_row = row - - self.max_samples = int((len(head_row) - 1) / 2) - - # total mass in mg - self.total_counts = None - self.total_surface = None - self.total_volume = None - self.total_mass = None - - def __sample_number_list_check(self, sample_number_list) -> None: - - last_sample = sample_number_list[-1] - - if last_sample > self.max_samples: - raise IndexError("The last sample(s) are out of range of the number of recorded samples") - - def AggregateSamples(self, samples = [1]) -> None: - - self.__sample_number_list_check(samples) - - counts = [] - surfaces = [] - volumes = [] - masses = [] - - for samplenumber in samples: - sample = OFRSample(number=samplenumber, sourcefile=self.sourcefile, headlines=self.headlines, density=self.density, - lower_bound = self.lower_bound, upper_bound = self.upper_bound, scan_up = self.scan_up, - scan_down = self.scan_down) - - counts.append(sample.total_count) - surfaces.append(sample.total_surface) - volumes.append(sample.total_volume) - masses.append(sample.total_mass) - - self.total_count = sum(counts) - self.total_surface = sum(surfaces) - self.total_volume = sum(volumes) - self.total_mass = sum(masses)Methods
--
-
-def AggregateSamples(self, samples=[1]) ‑> None -
-- - - -
- -class OFRSample -(number, sourcefile, headlines, density, lower_bound, upper_bound, scan_up, scan_down, delta_time=0.1) -
--
--
Object to represent a single sample from the OFR
-Description
-Bla bla bla
-Attributes
--
-
number:int
-- The sample number -
sourcefile:str
-- The path to the data file -
headlines:int
-- The number of lines in the data file until raw data is reached -
lower_bound:float
-- The lower bound diameter (nm) of the SMPS -
upper_bound:float
-- The upper bound diameter (nm) of the SMPS -
scan_up:float
-- The time (s) to ramp up voltage in SMPS -
scan_down:float
-- The time (s) to ramp voltage back down in SMPS -
delta_time:float
-- The time interval (s) between two measured data points of the raw count density -
SOA_density:float
-- The density (kg/m3) of the SOA produced in the OFR -
---Expand source code -
-
-class OFRSample: - - """Object to represent a single sample from the OFR - - Description - ----------- - Bla bla bla - - Attributes - ---------- - - number: int - The sample number - sourcefile: str - The path to the data file - headlines: int - The number of lines in the data file until raw data is reached - lower_bound: float - The lower bound diameter (nm) of the SMPS - upper_bound: float - The upper bound diameter (nm) of the SMPS - scan_up: float - The time (s) to ramp up voltage in SMPS - scan_down: float - The time (s) to ramp voltage back down in SMPS - delta_time: float - The time interval (s) between two measured data points of the raw count density - SOA_density: float - The density (kg/m3) of the SOA produced in the OFR - """ - - def __init__(self, number, sourcefile, headlines, density, lower_bound, upper_bound, scan_up, scan_down, delta_time = 0.1): - - # Sample information - self.number = number # sample number, i.e. 33 - self.sourcefile = sourcefile # where the data is stored, i.e. "C:/Users/tschan_d/..." - self.headlines = headlines # Number of lines before raw data is reached, usually 238 - self.lower_bound = lower_bound # Lower Diameter (nm) where CPC works - self.upper_bound = upper_bound # Upper Diameter (nm) where CPC works - self.scan_up = scan_up # Time to scan up the voltage range in DMA, in (s) - self.scan_down = scan_down # Time to scan down the voltage range in DMA, in(s) - self.delta_time = delta_time # Measuring interval to get raw count density, in (s) - self.SOA_density = density # Expected density of SOA (kg/m3) - - # Sample distributions - self.diameters = None # Diameters (nm) - self.count_density = None # Count Density (#*s/(m3*m)) - self.surface_density = None # Surface Density (m2*s/(m3*m)) - self.volume_density = None # Volume Density (m3*s/(m3*m)) - self.mass_density = None # Mass Density (kg*s/(m3*m)) - - self.total_count = None # Total Count (#*s/(m3)) - self.total_surface = None # Total Surface (m2*s/(m3)) - self.total_volume = None # Total Volume (m3*s/(m3)) - self.total_mass = None # Total Mass (kg*s/(m3)) - - self.get_data() - - def get_data(self): - - r"""Method to load and process data from a file. - - Detailed Description - -------------------- - Load the raw data from a `.csv` file into the object instance. Raw data includes raw counts $c_{r}$ - ($\text{particles}/(cm^{3}nm$) and diameters $D_{r}$ ($nm$). Each data point in the raw counts, $c_{r,i}$, represents the - number of particles observed between $D_{r,i-1}$ and $D_{r,i}$ within the data point aqcuisition time of $\Delta t_{A}$, such that - $c_{r,i}$ represents the time-integrated quantity of the particle flux within $D_{r,i-1}\leq D\leq D_{r,i}$. The raw data is - filtered to include only data within $D_{L}\leq D_{r}\leq D_{u}$. Then, $c_{r}$ and $D_{r}$ are transformed to SI-Units, represented - by $c=1E15c_{0}$ ($\text{particles}s/(m^{3}m$) and $D=1E-9D_{r}$ ($m$), respectively. The final count data is then obtained by - integrating $c$ over the sampling time $\Delta t_{s}=t_{su}+t_{sd}$, where $t_{su}$ and $t_{sd}$ represent DMA voltage scan-up and - scan-down times, respectively. - - Parameters - ---------- - a: None - This function has no paramters - - Returns - ------- - n: None - This function has no return value - """ - - # The columns to use when reading the data file - columns = ['Diameter #' + str(self.number), 'Counts #' + str(self.number)] - # Reading the data file - sample_data = pd.read_csv(filepath_or_buffer=self.sourcefile, header=self.headlines, usecols=columns, index_col=False, - skipfooter=1, engine='python').to_numpy() - - # Filtering the data to include only lower_bound <= diameter <= upper_bound - filter_array = np.where((sample_data[:, 0] >= self.lower_bound) & (sample_data[:, 0] <= self.upper_bound), True, False) - - # Particle Diameter: Raw data in (nm) -> Output data in (m): 1 nm = 1E-9 m - self.diameters = sample_data[filter_array, 0] * 1E-9 - - # Particle Count Density: Raw data in (#/(cm3*nm)) -> Output data in (#/(m3*m)): 1/(cm3*nm) = 1E15/(m3*m*s). This is the inte- - # grated value of the density flux over Δt = time_delta. Furthermore, the count density is integrated over the sample scanning time - # of Δt = self.scan_up + self.scan_down. Then the time-integrated particle count density has units (#*s/(m3*m)) - self.count_density = sample_data[filter_array, 1] * 1E15 * (self.scan_up + self.scan_down) # (#*s/(m3*m)) - - # Obtaining the corresponding surface-, volume- and mass densities - self.surface_density = np.multiply(math.pi * self.diameters ** 2, self.count_density) # (m2*s/(m3*m)) - self.volume_density = np.multiply((math.pi / 6) * self.diameters ** 3, self.count_density) # (m3*s/(m3*m)) - self.mass_density = np.multiply(self.SOA_density, self.volume_density) # (kg*s/(m3*m)) - - # Obtaining the corresponding quantities integrated over all diameters - self.total_count = self.__integrator(integrand = self.count_density) # (#*s/m3) - self.total_surface = self.__integrator(integrand = self.surface_density) # (m2*s/m3) - self.total_volume = self.__integrator(integrand = self.volume_density) # (m3*s/m3) - self.total_mass = self.total_volume * self.SOA_density # (kg*s/m3) - - def __integrator(self, integrand: np.float64) -> np.float64: - - return np.trapezoid(y = integrand, x = self.diameters)Methods
--
-
-def get_data(self) -
--
--
Method to load and process data from a file.
-Detailed Description
-Load the raw data from a
-.csvfile into the object instance. Raw data includes raw counts $c_{r}$ -($\text{particles}/(cm^{3}nm$) and diameters $D_{r}$ ($nm$). Each data point in the raw counts, $c_{r,i}$, represents the -number of particles observed between $D_{r,i-1}$ and $D_{r,i}$ within the data point aqcuisition time of $\Delta t_{A}$, such that -$c_{r,i}$ represents the time-integrated quantity of the particle flux within $D_{r,i-1}\leq D\leq D_{r,i}$. The raw data is -filtered to include only data within $D_{L}\leq D_{r}\leq D_{u}$. Then, $c_{r}$ and $D_{r}$ are transformed to SI-Units, represented -by $c=1E15c_{0}$ ($\text{particles}s/(m^{3}m$) and $D=1E-9D_{r}$ ($m$), respectively. The final count data is then obtained by -integrating $c$ over the sampling time $\Delta t_{s}=t_{su}+t_{sd}$, where $t_{su}$ and $t_{sd}$ represent DMA voltage scan-up and -scan-down times, respectively.Parameters
--
-
a:None
-- This function has no paramters -
Returns
--
-
n:None
-- This function has no return value -
-
-