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.flow_rate = flow_rate + + 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
+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 +
Methods
+init(number, sourcefile, headlines, density, lower_bound, upper_bound, scan_up, scan_down, delta_time) -> OFRSample: +The constructor of the Object
+Constructor of a OFRSample object
+Description:
+Parameters
+-
+
number:int
+- The sample number +
Returns
+-
+
None:None
+- Does not have a return value +
+++Expand source code +
+
+class OFRSample: + + """Object to represent a single sample from the OFR + + Description: 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 + + Methods + ------- + __init__(number, sourcefile, headlines, density, lower_bound, upper_bound, scan_up, scan_down, delta_time) -> OFRSample: + The constructor of the Object + """ + + def __init__(self, number, sourcefile, headlines, density, lower_bound, upper_bound, scan_up, scan_down, delta_time = 0.1): + + """Constructor of a OFRSample object + + Description: + + Parameters + ---------- + number: int + The sample number + + Returns + ------- + None: None + Does not have a return value + """ + + # Sample information + self.number = number # sample number, i.e. 33 + self.sourcefile = sourcefile # where the data is stored, "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 + self.scan_down = scan_down # Time to ramp the voltage back down in DMA + self.delta_time = delta_time # Measuring interval to get raw count density; (s) + self.SOA_density = density # Expected density of SOA (kg/m3) + + # Sample distributions + self.diameters = None # Diameters (nm) + self.count_density = None # Count Density (#/(m3*m*s)) + self.surface_density = None # Surface Density (m2/(m3*m*s)) + self.volume_density = None # Volume Density (m3/(m3*m*s)) + self.mass_density = None # Mass Density (kg/(m3*m*s)) + + self.total_count = None # Total Count (#/(m3*s)) + self.total_surface = None # Total Surface (m2/(m3*s)) + self.total_volume = None # Total Volume (m3/(m3*s)) + self.total_mass = None # Total Mass (kg/(m3*s)) + + self.get_data() + + def get_data(self): + + columns = ['Diameter #' + str(self.number), 'Counts #' + str(self.number)] + sample_data = pd.read_csv(filepath_or_buffer=self.sourcefile, header=self.headlines, usecols=columns, index_col=False, + skipfooter=1, engine='python').to_numpy() + + 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*0.1s)) -> Output data in (#/(m3*m*s)): 1/(cm3*nm*s) = 1E16/(m3*m*s) + self.count_density = sample_data[filter_array, 1] * 1E16 + + self.surface_density = np.multiply(math.pi * self.diameters ** 2, self.count_density) + self.volume_density = np.multiply((math.pi / 6) * self.diameters ** 3, self.count_density) + self.mass_density = np.multiply(self.SOA_density, self.volume_density) + + self.total_count = self.__integrator(integrand = self.count_density) + self.total_surface = self.__integrator(integrand = self.surface_density) + self.total_volume = self.__integrator(integrand = self.volume_density) + self.total_mass = self.total_volume * self.SOA_density + + def __integrator(self, integrand: np.float64) -> np.float64: + + return np.trapezoid(y = integrand, x = self.diameters)Methods
+-
+
+def get_data(self) +
+- + + +
+