chromaquant 0.4.0__py3-none-any.whl → 0.5.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- chromaquant/__init__.py +9 -2
- chromaquant/data/__init__.py +14 -0
- chromaquant/data/breakdown.py +430 -0
- chromaquant/data/dataset.py +195 -0
- chromaquant/data/table.py +412 -0
- chromaquant/data/value.py +215 -0
- chromaquant/formula/__init__.py +13 -0
- chromaquant/formula/base_formulas.py +168 -0
- chromaquant/formula/formula.py +507 -0
- chromaquant/import_local_packages.py +55 -0
- chromaquant/logging_and_handling.py +76 -0
- chromaquant/match/__init__.py +13 -0
- chromaquant/match/match.py +184 -0
- chromaquant/match/match_config.py +296 -0
- chromaquant/match/match_tools.py +154 -0
- chromaquant/{Quant → results}/__init__.py +2 -2
- chromaquant/results/reporting_tools.py +190 -0
- chromaquant/results/results.py +250 -0
- chromaquant/utils/__init__.py +14 -0
- chromaquant/utils/categories.py +127 -0
- chromaquant/utils/chemical_formulas.py +104 -0
- chromaquant/utils/dataframe_processing.py +222 -0
- chromaquant/utils/file_tools.py +100 -0
- chromaquant/utils/formula_tools.py +119 -0
- chromaquant-0.5.0.dist-info/METADATA +61 -0
- chromaquant-0.5.0.dist-info/RECORD +29 -0
- {chromaquant-0.4.0.dist-info → chromaquant-0.5.0.dist-info}/WHEEL +1 -1
- {chromaquant-0.4.0.dist-info → chromaquant-0.5.0.dist-info}/licenses/LICENSE.txt +1 -1
- chromaquant-0.5.0.dist-info/licenses/LICENSES_bundled.txt +251 -0
- chromaquant/Handle/__init__.py +0 -13
- chromaquant/Handle/fileChecks.py +0 -172
- chromaquant/Handle/handleDirectories.py +0 -89
- chromaquant/Hydro/__init__.py +0 -12
- chromaquant/Hydro/hydroMain.py +0 -496
- chromaquant/Manual/HydroUI.py +0 -418
- chromaquant/Manual/QuantUPP.py +0 -373
- chromaquant/Manual/Quantification.py +0 -1305
- chromaquant/Manual/__init__.py +0 -10
- chromaquant/Manual/duplicateMatch.py +0 -211
- chromaquant/Manual/fpm_match.py +0 -798
- chromaquant/Manual/label-type.py +0 -179
- chromaquant/Match/AutoFpmMatch.py +0 -1133
- chromaquant/Match/MatchSub/__init__.py +0 -13
- chromaquant/Match/MatchSub/matchTools.py +0 -282
- chromaquant/Match/MatchSub/peakTools.py +0 -259
- chromaquant/Match/__init__.py +0 -13
- chromaquant/Match/matchMain.py +0 -233
- chromaquant/Quant/AutoQuantification.py +0 -1329
- chromaquant/Quant/QuantSub/__init__.py +0 -15
- chromaquant/Quant/QuantSub/gasFID.py +0 -241
- chromaquant/Quant/QuantSub/gasTCD.py +0 -425
- chromaquant/Quant/QuantSub/liquidFID.py +0 -310
- chromaquant/Quant/QuantSub/parseTools.py +0 -162
- chromaquant/Quant/quantMain.py +0 -417
- chromaquant/UAPP/__init__.py +0 -12
- chromaquant/UAPP/uappMain.py +0 -427
- chromaquant/__main__.py +0 -526
- chromaquant/oldui.py +0 -492
- chromaquant/properties.json +0 -4
- chromaquant-0.4.0.dist-info/METADATA +0 -189
- chromaquant-0.4.0.dist-info/RECORD +0 -38
- chromaquant-0.4.0.dist-info/entry_points.txt +0 -2
- chromaquant-0.4.0.dist-info/licenses/LICENSES_bundled.txt +0 -1035
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# -*- coding: utf-8 -*-
|
|
3
|
-
|
|
4
|
-
"""
|
|
5
|
-
ChromaQuant.Match.MatchSub package initialization
|
|
6
|
-
|
|
7
|
-
Julia Hancock
|
|
8
|
-
Created 10-19-2024
|
|
9
|
-
|
|
10
|
-
"""
|
|
11
|
-
|
|
12
|
-
from .parseTools import *
|
|
13
|
-
from .liquidFID import *
|
|
14
|
-
from .gasFID import *
|
|
15
|
-
from .gasTCD import *
|
|
@@ -1,241 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# -*- coding: utf-8 -*-
|
|
3
|
-
"""
|
|
4
|
-
COPYRIGHT STATEMENT:
|
|
5
|
-
|
|
6
|
-
ChromaQuant – A quantification software for complex gas chromatographic data
|
|
7
|
-
|
|
8
|
-
Copyright (c) 2024, by Julia Hancock
|
|
9
|
-
Affiliation: Dr. Julie Elaine Rorrer
|
|
10
|
-
URL: https://www.rorrerlab.com/
|
|
11
|
-
|
|
12
|
-
License: BSD 3-Clause License
|
|
13
|
-
|
|
14
|
-
---
|
|
15
|
-
|
|
16
|
-
SUBPACKAGE FOR PERFORMING GAS FID QUANTIFICATION STEPS
|
|
17
|
-
|
|
18
|
-
Julia Hancock
|
|
19
|
-
Started 12-29-2024
|
|
20
|
-
|
|
21
|
-
"""
|
|
22
|
-
""" PACKAGES """
|
|
23
|
-
import pandas as pd
|
|
24
|
-
import numpy as np
|
|
25
|
-
from chemformula import ChemFormula
|
|
26
|
-
|
|
27
|
-
#Function for quantifying gas FID data w/ external standard
|
|
28
|
-
def gasFID_ES(BreakdownDF,DBRF,Label_info,gasBag_cond,total_volume,cutoff=4):
|
|
29
|
-
"""
|
|
30
|
-
Function quantifies gas FID data and returns a breakdown dataframe
|
|
31
|
-
|
|
32
|
-
Parameters
|
|
33
|
-
----------
|
|
34
|
-
BreakdownDF : DataFrame
|
|
35
|
-
Dataframe containing columns associated with matched FID and MS peak data
|
|
36
|
-
DBRF : Dataframe
|
|
37
|
-
Dataframe containing nested dataframes with associated chemical lumps,
|
|
38
|
-
likely imported from an excel sheet where each sheet is specific to
|
|
39
|
-
a given chemical lump. The top-level keys must be associated with the
|
|
40
|
-
predefined chemical lumps given in 'LABELS' section above
|
|
41
|
-
gasBag_cond : List
|
|
42
|
-
List containing gas bag temperature [0] and gas bag pressure [1]
|
|
43
|
-
Label_info : List
|
|
44
|
-
List of dictionaries containing chemical lump and compound type abbreviations
|
|
45
|
-
total_volume : Float
|
|
46
|
-
Float describing the total amount of gas estimated by the external standard volume percent, mL
|
|
47
|
-
cutoff : Integer, optional
|
|
48
|
-
Integer representing the maximum cutoff carbon number that can be
|
|
49
|
-
quantified using FID.The default is 4.
|
|
50
|
-
|
|
51
|
-
Returns
|
|
52
|
-
-------
|
|
53
|
-
BreakdownDF : DataFrame
|
|
54
|
-
Dataframe containing columns associated with matched FID and MS peak data
|
|
55
|
-
|
|
56
|
-
"""
|
|
57
|
-
#Function for assigning response factors to compounds
|
|
58
|
-
def assignRF(BreakdownDF,DBRF):
|
|
59
|
-
|
|
60
|
-
#Get a dictionary of average response factors by carbon number
|
|
61
|
-
avgRF = {}
|
|
62
|
-
#Loop through every carbon number up to the max in DBRF
|
|
63
|
-
for i in range(1,DBRF['Carbon Number'].max()+1):
|
|
64
|
-
#Get a slice of all rows in DBRF with a given carbon number
|
|
65
|
-
slicer = DBRF.loc[DBRF['Carbon Number']==i]
|
|
66
|
-
#Average the response factor entries in this slice, appending the result to the average RF dictionary
|
|
67
|
-
avgRF['{0}'.format(i)] = slicer['RF'].mean()
|
|
68
|
-
|
|
69
|
-
#Loop through every row in the FIDpMS dataframe
|
|
70
|
-
for i, row in BreakdownDF.iterrows():
|
|
71
|
-
#Check that the formula is not nan
|
|
72
|
-
if not pd.isna(row['Formula']):
|
|
73
|
-
#Obtain a dictionary containing key:value pairs as element:count using the formula string for the ith row
|
|
74
|
-
chemFormDict = ChemFormula(row['Formula']).element
|
|
75
|
-
#Use the carbon entry from the above dictionary to assign a carbon number to the ith row
|
|
76
|
-
BreakdownDF.at[i,'Carbon Number'] = chemFormDict['C']
|
|
77
|
-
|
|
78
|
-
#If the row's compound name exists in the RF list explicitly, assign the row to the appropriate RF
|
|
79
|
-
if row['Compound Name'] in DBRF['Compound Name'].values:
|
|
80
|
-
BreakdownDF.at[i,'RF (Area/vol.%)'] = DBRF.loc[DBRF['Compound Name']==row['Compound Name'],'RF'].iloc[0]
|
|
81
|
-
#Assign response factor source
|
|
82
|
-
BreakdownDF.at[i,'RF Source'] = 'Direct RF assignment based on compound name'
|
|
83
|
-
#Otherwise, assign response factor based on average carbon number RF
|
|
84
|
-
else:
|
|
85
|
-
BreakdownDF.at[i,'RF (Area/vol.%)'] = avgRF['{0}'.format(int(BreakdownDF.at[i,'Carbon Number']))]
|
|
86
|
-
#Assign response factor source
|
|
87
|
-
BreakdownDF.at[i,'RF Source'] = 'RF assignment based on average response factor for DBRF carbon number entries'
|
|
88
|
-
#Otherwise if the row's formula is nan, pass
|
|
89
|
-
else:
|
|
90
|
-
pass
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
return BreakdownDF
|
|
94
|
-
|
|
95
|
-
#Function for quantifying compounds using ideal gas law
|
|
96
|
-
def gasQuant(BreakdownDF,DBRF,total_volume,cutoff):
|
|
97
|
-
|
|
98
|
-
#Remove rows in BreakdownDF with a carbon number at or below cutoff
|
|
99
|
-
BreakdownDF = BreakdownDF.loc[BreakdownDF['Carbon Number'] > cutoff].copy()
|
|
100
|
-
|
|
101
|
-
#Get gas bag conditions
|
|
102
|
-
temp = gasBag_cond[0] #temperature of gas bag, C
|
|
103
|
-
pressure = gasBag_cond[1] #sample pressure in gas bag, psi
|
|
104
|
-
|
|
105
|
-
#Convert gas bag conditions to new units
|
|
106
|
-
temp = temp + 273.15 #gas bag temperature, K
|
|
107
|
-
pressure = pressure / 14.504*100000 #gas bag pressure, Pa
|
|
108
|
-
total_volume /= 10**6 #gas bag volume, m^3
|
|
109
|
-
#Define ideal gas constant, m^3*Pa/K*mol
|
|
110
|
-
R = 8.314
|
|
111
|
-
|
|
112
|
-
#Loop through every row in BreakdownDF
|
|
113
|
-
for i, row in BreakdownDF.iterrows():
|
|
114
|
-
|
|
115
|
-
#Add molecular weight using ChemFormula
|
|
116
|
-
BreakdownDF.at[i,'MW (g/mol)'] = ChemFormula(row['Formula']).formula_weight
|
|
117
|
-
|
|
118
|
-
#Get volume percent using response factor
|
|
119
|
-
BreakdownDF.at[i,'Vol.%'] = row['FID Area']/row['RF (Area/vol.%)']
|
|
120
|
-
|
|
121
|
-
#Get moles using ideal gas law (PV=nRT)
|
|
122
|
-
BreakdownDF.at[i,'Moles'] = BreakdownDF.at[i,'Vol.%']/100*total_volume*pressure/(temp*R)
|
|
123
|
-
|
|
124
|
-
#Get mass (mg) using moles and molar mass
|
|
125
|
-
BreakdownDF.at[i,'Mass (mg)'] = BreakdownDF.at[i,'Moles'] * BreakdownDF.at[i,'MW (g/mol)'] * 1000
|
|
126
|
-
|
|
127
|
-
return BreakdownDF
|
|
128
|
-
|
|
129
|
-
#Function for further breaking down product distribution
|
|
130
|
-
def moreBreakdown(BreakdownDF,CT_dict):
|
|
131
|
-
"""
|
|
132
|
-
This function prepares further breakdown dictionaries for use in exporting to Excel
|
|
133
|
-
|
|
134
|
-
Parameters
|
|
135
|
-
----------
|
|
136
|
-
BreakdownDF : DataFrame
|
|
137
|
-
Dataframe containing columns associated with matched FID and MS peak data.
|
|
138
|
-
CT_dict : Dict
|
|
139
|
-
Dictionary of all compound type abbreviations in use and their associated expansions
|
|
140
|
-
|
|
141
|
-
Returns
|
|
142
|
-
-------
|
|
143
|
-
BreakdownDF : DataFrame
|
|
144
|
-
Dataframe containing columns associated with matched FID and MS peak data.
|
|
145
|
-
|
|
146
|
-
"""
|
|
147
|
-
|
|
148
|
-
#Get the total mass of product from the breakdown dataframe
|
|
149
|
-
m_total = np.nansum(BreakdownDF['Mass (mg)'])
|
|
150
|
-
|
|
151
|
-
#Iterate through every species in the breakdown dataframe and add entries in two new columns: Compound Type and Carbon Number
|
|
152
|
-
for i, row in BreakdownDF.iterrows():
|
|
153
|
-
#If there exists a formula..
|
|
154
|
-
try:
|
|
155
|
-
#Set breakdown compound type according to the abbreviation already in the breakdown dataframe
|
|
156
|
-
BreakdownDF.at[i,'Compound Type'] = CT_dict[BreakdownDF.at[i,'Compound Type Abbreviation']]
|
|
157
|
-
#Obtain a dictionary containing key:value pairs as element:count using the formula string for the ith row
|
|
158
|
-
chemFormDict = ChemFormula(row['Formula']).element
|
|
159
|
-
#Use the carbon entry from the above dictionary to assign a carbon number to the ith row
|
|
160
|
-
BreakdownDF.at[i,'Carbon Number'] = chemFormDict['C']
|
|
161
|
-
#Otherwise, pass
|
|
162
|
-
except:
|
|
163
|
-
pass
|
|
164
|
-
|
|
165
|
-
#Get maximum carbon number in breakdown dataframe
|
|
166
|
-
CN_max = int(BreakdownDF['Carbon Number'].max())
|
|
167
|
-
|
|
168
|
-
#Create a dataframe for saving quantitative results organized by compound type
|
|
169
|
-
CT_DF = pd.DataFrame({'Compound Type':['Aromatics','Linear Alkanes','Branched Alkanes',
|
|
170
|
-
'Cycloalkanes','Alkenes/Alkynes','Other'],
|
|
171
|
-
'Mass (mg)':np.empty(6),
|
|
172
|
-
'Mass fraction':np.empty(6)})
|
|
173
|
-
|
|
174
|
-
#Create a dataframe for saving quantitative results organized by carbon number
|
|
175
|
-
CN_DF = pd.DataFrame({'Carbon Number':range(1,CN_max+1,1),
|
|
176
|
-
'Mass (mg)':np.empty(CN_max)})
|
|
177
|
-
|
|
178
|
-
#Create a dataframe for saving quantitative results organized by both compound type and carbon number
|
|
179
|
-
CTCN_DF = pd.DataFrame({'Aromatics': pd.Series(np.empty(CN_max),index=range(CN_max)),
|
|
180
|
-
'Linear Alkanes': pd.Series(np.empty(CN_max),index=range(CN_max)),
|
|
181
|
-
'Branched Alkanes':pd.Series(np.empty(CN_max),index=range(CN_max)),
|
|
182
|
-
'Cycloalkanes':pd.Series(np.empty(CN_max),index=range(CN_max)),
|
|
183
|
-
'Alkenes/Alkynes':pd.Series(np.empty(CN_max),index=range(CN_max)),
|
|
184
|
-
'Other':pd.Series(np.empty(CN_max),index=range(CN_max))})
|
|
185
|
-
|
|
186
|
-
#Iterate through every compound type in the compound type dataframe, summing the total respective masses from the breakdown dataframe
|
|
187
|
-
for i, row in CT_DF.iterrows():
|
|
188
|
-
|
|
189
|
-
#Define a temporary dataframe which contains all rows matching the ith compound type
|
|
190
|
-
tempDF = BreakdownDF.loc[BreakdownDF['Compound Type'] == row['Compound Type']]
|
|
191
|
-
#Assign the ith compound type's mass as the sum of the temporary dataframe's m_i column, treating nan as zero
|
|
192
|
-
CT_DF.at[i,'Mass (mg)'] = np.nansum(tempDF['Mass (mg)'])
|
|
193
|
-
#Calculate and assign the ith compound type's mass fraction usingthe total mass from earlier
|
|
194
|
-
CT_DF.at[i,'Mass fraction'] = CT_DF.at[i,'Mass (mg)']/m_total
|
|
195
|
-
|
|
196
|
-
#Iterate through every carbon number in the carbon number dataframe, summing the total respective masses from the breakdown dataframe
|
|
197
|
-
for i, row in CN_DF.iterrows():
|
|
198
|
-
|
|
199
|
-
#Define a temporary dataframe which contains all rows matching the ith carbon number
|
|
200
|
-
tempDF = BreakdownDF.loc[BreakdownDF['Carbon Number'] == row['Carbon Number']]
|
|
201
|
-
#Assign the ith carbon number's mass as the sum of the temporary dataframe's m_i column, treating nan as zero
|
|
202
|
-
CN_DF.at[i,'Mass (mg)'] = np.nansum(tempDF['Mass (mg)'])
|
|
203
|
-
|
|
204
|
-
#Iterate through the entire dataframe, getting masses for every compound type - carbon number pair
|
|
205
|
-
for i, row in CTCN_DF.iterrows():
|
|
206
|
-
|
|
207
|
-
#For every entry in row
|
|
208
|
-
for j in row.index:
|
|
209
|
-
|
|
210
|
-
#Define a temporary dataframe which contains all rows matching the ith carbon number and compound type
|
|
211
|
-
tempDF = BreakdownDF.loc[(BreakdownDF['Carbon Number'] == i+1) & (BreakdownDF['Compound Type'] == j)]
|
|
212
|
-
#Assign the ith carbon number/jth compound type's mass as the sum of the temporary dataframe's m_i column, treating nan as zero
|
|
213
|
-
CTCN_DF.loc[i,j] = np.nansum(tempDF['Mass (mg)'])
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
#Get total masses from CT, CN, and CTCN dataframes
|
|
217
|
-
CT_mass = np.nansum(CT_DF['Mass (mg)'])
|
|
218
|
-
CN_mass = np.nansum(CN_DF['Mass (mg)'])
|
|
219
|
-
CTCN_mass = np.nansum(CTCN_DF)
|
|
220
|
-
|
|
221
|
-
#Create total mass dataframe
|
|
222
|
-
mass_DF = pd.DataFrame({'Total mass source':['Overall breakdown','Compound Type Breakdown','Carbon Number Breakdown','Compound Type + Carbon Number Breakdown'],'Mass (mg)':[m_total,CT_mass,CN_mass,CTCN_mass]})
|
|
223
|
-
|
|
224
|
-
return BreakdownDF, CT_DF, CN_DF, CTCN_DF, mass_DF
|
|
225
|
-
|
|
226
|
-
#Unpack compound type and carbon number dictionaries from list
|
|
227
|
-
CL_Dict, CT_Dict = Label_info
|
|
228
|
-
|
|
229
|
-
#Filter dataframe to remove compounds that do not contain carbon
|
|
230
|
-
BreakdownDF = BreakdownDF.drop(BreakdownDF[[not i for i in BreakdownDF['Formula'].str.contains('C')]].index)
|
|
231
|
-
#Reset the dataframe index
|
|
232
|
-
BreakdownDF.reset_index()
|
|
233
|
-
|
|
234
|
-
#Run response factor assignment function
|
|
235
|
-
BreakdownDF = assignRF(BreakdownDF, DBRF)
|
|
236
|
-
#Run gas quantification function
|
|
237
|
-
BreakdownDF = gasQuant(BreakdownDF,DBRF,total_volume,cutoff)
|
|
238
|
-
#Run further breakdown function
|
|
239
|
-
BreakdownDF, CT_DF, CN_DF, CTCN_DF, mass_DF = moreBreakdown(BreakdownDF, CT_Dict)
|
|
240
|
-
|
|
241
|
-
return BreakdownDF, CT_DF, CN_DF, CTCN_DF, mass_DF
|
|
@@ -1,425 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# -*- coding: utf-8 -*-
|
|
3
|
-
"""
|
|
4
|
-
COPYRIGHT STATEMENT:
|
|
5
|
-
|
|
6
|
-
ChromaQuant – A quantification software for complex gas chromatographic data
|
|
7
|
-
|
|
8
|
-
Copyright (c) 2024, by Julia Hancock
|
|
9
|
-
Affiliation: Dr. Julie Elaine Rorrer
|
|
10
|
-
URL: https://www.rorrerlab.com/
|
|
11
|
-
|
|
12
|
-
License: BSD 3-Clause License
|
|
13
|
-
|
|
14
|
-
---
|
|
15
|
-
|
|
16
|
-
SUBPACKAGE FOR PERFORMING GAS TCD QUANTIFICATION STEPS
|
|
17
|
-
|
|
18
|
-
Julia Hancock
|
|
19
|
-
Started 12-29-2024
|
|
20
|
-
|
|
21
|
-
"""
|
|
22
|
-
""" PACKAGES """
|
|
23
|
-
from chemformula import ChemFormula
|
|
24
|
-
|
|
25
|
-
#Function for quantifying gas TCD data w/ volume estimation method, no pressure adjustment
|
|
26
|
-
def gasTCD_VE(BreakdownDF,DBRF,gasBag_cond,peak_error):
|
|
27
|
-
|
|
28
|
-
#Unpack gas bag conditions
|
|
29
|
-
temp = gasBag_cond[0] #temperature of gas bag, C
|
|
30
|
-
pressure = gasBag_cond[1] #sample pressure in gas bag, psi
|
|
31
|
-
co2 = gasBag_cond[2] #CO2 volume, mL
|
|
32
|
-
|
|
33
|
-
#Initialize compound name column in BreakdownDF
|
|
34
|
-
BreakdownDF['Compound Name'] = 'None'
|
|
35
|
-
|
|
36
|
-
#Function to find if CO2 peak exists
|
|
37
|
-
def getCO2(BreakdownDF,DBRF,TCD_cond,peak_error):
|
|
38
|
-
|
|
39
|
-
#Unpack TCD conditions
|
|
40
|
-
co2 = TCD_cond[0]
|
|
41
|
-
pressure = TCD_cond[1]
|
|
42
|
-
temp = TCD_cond[2]
|
|
43
|
-
R = TCD_cond[3]
|
|
44
|
-
|
|
45
|
-
#Find the CO2 peak row in DBRF
|
|
46
|
-
CO2_row = DBRF.loc[DBRF['Compound Name'] == "Carbon Dioxide"].iloc[0]
|
|
47
|
-
|
|
48
|
-
#Get the retention time
|
|
49
|
-
CO2_RT = CO2_row['RT (min)']
|
|
50
|
-
|
|
51
|
-
#Get the minimum and maximum of the RT range using the peak error
|
|
52
|
-
CO2_RTmin = CO2_RT - peak_error
|
|
53
|
-
CO2_RTmax = CO2_RT + peak_error
|
|
54
|
-
|
|
55
|
-
#Define boolean describing whether or not CO2 match has been found
|
|
56
|
-
CO2_bool = False
|
|
57
|
-
#Define volume estimate
|
|
58
|
-
volume = 0
|
|
59
|
-
|
|
60
|
-
#Iterate through every row in BreakdownDF
|
|
61
|
-
for i, row in BreakdownDF.iterrows():
|
|
62
|
-
|
|
63
|
-
#If the TCD retention time is within range of the CO2 entry...
|
|
64
|
-
if CO2_RTmin <= row['RT'] <= CO2_RTmax:
|
|
65
|
-
|
|
66
|
-
#Add the compound name to the breakdown dataframe
|
|
67
|
-
BreakdownDF.at[i,'Compound Name'] = 'Carbon Dioxide'
|
|
68
|
-
|
|
69
|
-
#Add the other relevant information to the breakdown dataframe
|
|
70
|
-
BreakdownDF.at[i,'Formula'] = 'CO2'
|
|
71
|
-
BreakdownDF.at[i,'RF (Area/vol.%)'] = CO2_row['RF']
|
|
72
|
-
BreakdownDF.at[i,'MW (g/mol)'] = ChemFormula('CO2').formula_weight
|
|
73
|
-
|
|
74
|
-
#Get volume percent using response factor
|
|
75
|
-
volpercent = row['Area']/CO2_row['RF']
|
|
76
|
-
BreakdownDF.at[i,'Vol.%'] = volpercent
|
|
77
|
-
|
|
78
|
-
#Calculate total volume using volume percent
|
|
79
|
-
volume = co2 * 100 / volpercent #total volume, m^3
|
|
80
|
-
|
|
81
|
-
#Assign CO2 volume
|
|
82
|
-
BreakdownDF.at[i,'Volume (m^3)'] = co2
|
|
83
|
-
|
|
84
|
-
#Get moles using ideal gas law (PV=nRT)
|
|
85
|
-
BreakdownDF.at[i,'Moles (mol)'] = co2*pressure/(temp*R)
|
|
86
|
-
|
|
87
|
-
#Get mass (mg) using moles and molar mass
|
|
88
|
-
BreakdownDF.at[i,'Mass (mg)'] = BreakdownDF.at[i,'Moles (mol)'] * BreakdownDF.at[i,'MW (g/mol)'] * 1000
|
|
89
|
-
|
|
90
|
-
#Set CO2_bool to True
|
|
91
|
-
CO2_bool = True
|
|
92
|
-
|
|
93
|
-
break
|
|
94
|
-
|
|
95
|
-
#Otherwise, pass
|
|
96
|
-
else:
|
|
97
|
-
pass
|
|
98
|
-
|
|
99
|
-
return CO2_bool, volume, BreakdownDF
|
|
100
|
-
|
|
101
|
-
#Add min and max peak assignment values to DBRF
|
|
102
|
-
for i, row in DBRF.iterrows():
|
|
103
|
-
DBRF.at[i,'RT Max'] = DBRF.at[i,'RT (min)'] + peak_error
|
|
104
|
-
DBRF.at[i,'RT Min'] = DBRF.at[i,'RT (min)'] - peak_error
|
|
105
|
-
|
|
106
|
-
#Convert sinfo variables to new units
|
|
107
|
-
co2 = co2 / 10**6 #volume injected CO2, m^3
|
|
108
|
-
temp = temp + 273.15 #reactor temperature, K
|
|
109
|
-
pressure = pressure / 14.504*100000 #reactor pressure, Pa
|
|
110
|
-
|
|
111
|
-
#Define ideal gas constant, m^3*Pa/K*mol
|
|
112
|
-
R = 8.314
|
|
113
|
-
|
|
114
|
-
#Define variable to total volume (m^3)
|
|
115
|
-
V_TC = 0
|
|
116
|
-
|
|
117
|
-
#Define list of conditions
|
|
118
|
-
TCD_cond = [co2,pressure,temp,R]
|
|
119
|
-
|
|
120
|
-
#Check if there is a peak in the BreakdownDF that can be assigned to CO2
|
|
121
|
-
CO2_bool, V_TC, BreakdownDF = getCO2(BreakdownDF,DBRF,TCD_cond,peak_error)
|
|
122
|
-
|
|
123
|
-
if CO2_bool:
|
|
124
|
-
#Iterate through every row in BreakdownDF
|
|
125
|
-
for i, row in BreakdownDF.iterrows():
|
|
126
|
-
|
|
127
|
-
#Iterate through every row in DBRF
|
|
128
|
-
for i2, row2 in DBRF.iterrows():
|
|
129
|
-
|
|
130
|
-
#If the TCD retention time is within the range for a given DBRF entry...
|
|
131
|
-
if row2['RT Min'] <= row['RT'] <= row2['RT Max']:
|
|
132
|
-
|
|
133
|
-
#Add the compound name to the breakdown dataframe
|
|
134
|
-
BreakdownDF.at[i,'Compound Name'] = row2['Compound Name']
|
|
135
|
-
|
|
136
|
-
#Add the other relevant information to the breakdown dataframe
|
|
137
|
-
BreakdownDF.at[i,'Formula'] = row2['Formula']
|
|
138
|
-
BreakdownDF.at[i,'RF (Area/vol.%)'] = row2['RF']
|
|
139
|
-
BreakdownDF.at[i,'MW (g/mol)'] = ChemFormula(row2['Formula']).formula_weight
|
|
140
|
-
|
|
141
|
-
#Get volume percent using response factor
|
|
142
|
-
volpercent = row['Area']/row2['RF']
|
|
143
|
-
BreakdownDF.at[i,'Vol.%'] = volpercent
|
|
144
|
-
|
|
145
|
-
#Get volume using volume percent
|
|
146
|
-
vol = V_TC*volpercent/100
|
|
147
|
-
BreakdownDF.at[i,'Volume (m^3)'] = vol
|
|
148
|
-
|
|
149
|
-
#Get moles using ideal gas law (PV=nRT)
|
|
150
|
-
BreakdownDF.at[i,'Moles (mol)'] = vol*pressure/(temp*R)
|
|
151
|
-
|
|
152
|
-
#Get mass (mg) using moles and molar mass
|
|
153
|
-
BreakdownDF.at[i,'Mass (mg)'] = BreakdownDF.at[i,'Moles (mol)'] * BreakdownDF.at[i,'MW (g/mol)'] * 1000
|
|
154
|
-
|
|
155
|
-
#Otherwise, pass
|
|
156
|
-
else:
|
|
157
|
-
pass
|
|
158
|
-
#Otherwise, pass
|
|
159
|
-
else:
|
|
160
|
-
pass
|
|
161
|
-
|
|
162
|
-
#Convert total volume to mL
|
|
163
|
-
V_TC *= 10**6
|
|
164
|
-
|
|
165
|
-
return BreakdownDF, V_TC
|
|
166
|
-
|
|
167
|
-
#Function for quantifying gas TCD data w/ scale factor method
|
|
168
|
-
def gasTCD_SF(BreakdownDF,DBRF,gasBag_cond,reactor_cond,peak_error):
|
|
169
|
-
|
|
170
|
-
#Initialize compound name column in BreakdownDF
|
|
171
|
-
BreakdownDF['Compound Name'] = 'None'
|
|
172
|
-
|
|
173
|
-
#Function to determine total volume using ideal gas law
|
|
174
|
-
def volumeIGL(V_C,reactor_cond):
|
|
175
|
-
|
|
176
|
-
#Unpack reactor conditions
|
|
177
|
-
P_f = reactor_cond[0] #reactor quench pressure, psig
|
|
178
|
-
V_R = reactor_cond[1] #reactor internal volume, mL
|
|
179
|
-
P_0 = reactor_cond[2] #atmospheric pressure, psi
|
|
180
|
-
|
|
181
|
-
#Estimate total volume of gas bag, mL
|
|
182
|
-
V_T = V_R * (P_f + P_0) / P_0
|
|
183
|
-
|
|
184
|
-
#Estimate total volume of gas bag plus volume CO2, mL
|
|
185
|
-
V_TC = V_T + V_C
|
|
186
|
-
|
|
187
|
-
return V_T, V_TC
|
|
188
|
-
|
|
189
|
-
# Function to estimate scale factor from CO2
|
|
190
|
-
def getScaleFactor(BreakdownDF,DBRF,V_C,V_TC):
|
|
191
|
-
|
|
192
|
-
#Find the CO2 peak row in DBRF
|
|
193
|
-
CO2_row = DBRF.loc[DBRF['Compound Name'] == "Carbon Dioxide"].iloc[0]
|
|
194
|
-
|
|
195
|
-
#Get the retention time
|
|
196
|
-
CO2_RT = CO2_row['RT (min)']
|
|
197
|
-
|
|
198
|
-
#Get the minimum and maximum of the RT range using the peak error
|
|
199
|
-
CO2_RTmin = CO2_RT - peak_error
|
|
200
|
-
CO2_RTmax = CO2_RT + peak_error
|
|
201
|
-
|
|
202
|
-
#Define boolean describing whether or not CO2 match has been found
|
|
203
|
-
CO2_bool = False
|
|
204
|
-
|
|
205
|
-
#Iterate through every row in BreakdownDF
|
|
206
|
-
for i, row in BreakdownDF.iterrows():
|
|
207
|
-
|
|
208
|
-
#If the TCD retention time is within range of the CO2 entry...
|
|
209
|
-
if CO2_RTmin <= row['RT'] <= CO2_RTmax:
|
|
210
|
-
|
|
211
|
-
#Get estimated volume fraction of CO2
|
|
212
|
-
psiCO2_e = row['Area'] / (100 * CO2_row['RF'])
|
|
213
|
-
|
|
214
|
-
#Get actual volume fraction of CO2
|
|
215
|
-
psiCO2_a = V_C / V_TC
|
|
216
|
-
|
|
217
|
-
#Define scale factor as ratio of actual volume fraction to estimated volume fraction
|
|
218
|
-
SF = psiCO2_a / psiCO2_e
|
|
219
|
-
|
|
220
|
-
#Set CO2_bool to True
|
|
221
|
-
CO2_bool = True
|
|
222
|
-
|
|
223
|
-
break
|
|
224
|
-
|
|
225
|
-
#Otherwise, pass
|
|
226
|
-
else:
|
|
227
|
-
pass
|
|
228
|
-
|
|
229
|
-
#Raise error if no CO2 peak found
|
|
230
|
-
if CO2_bool == False:
|
|
231
|
-
raise Exception("[gasTCD][ERROR] No CO2 peak found in TCD")
|
|
232
|
-
|
|
233
|
-
else:
|
|
234
|
-
pass
|
|
235
|
-
|
|
236
|
-
return SF
|
|
237
|
-
|
|
238
|
-
#Function to calculate amounts of each species using the scale factor
|
|
239
|
-
def quantTCD(BreakdownDF,DBRF,gasBag_cond,reactor_cond):
|
|
240
|
-
|
|
241
|
-
# Unpack gas bag conditions
|
|
242
|
-
GB_temp = gasBag_cond[0] # Temperature of gas bag, C
|
|
243
|
-
GB_pressure = gasBag_cond[1] # Sample pressure in gas bag, psig
|
|
244
|
-
V_C = gasBag_cond[2] # CO2 volume, mL
|
|
245
|
-
|
|
246
|
-
# Get total and total+CO2 gas bag volumes
|
|
247
|
-
V_T, V_TC = volumeIGL(V_C,reactor_cond)
|
|
248
|
-
|
|
249
|
-
# Define ideal gas constant, m^3*Pa/K*mol
|
|
250
|
-
R = 8.314
|
|
251
|
-
|
|
252
|
-
#Define conversion factor, Pa * m^3 * psi^-1 * mL^-1
|
|
253
|
-
C = 0.00689476
|
|
254
|
-
|
|
255
|
-
#Get scale factor
|
|
256
|
-
SF = getScaleFactor(BreakdownDF,DBRF,V_C,V_TC)
|
|
257
|
-
|
|
258
|
-
#Add min and max peak assignment values to DBRF
|
|
259
|
-
for i, row in DBRF.iterrows():
|
|
260
|
-
DBRF.at[i,'RT Max'] = DBRF.at[i,'RT (min)'] + peak_error
|
|
261
|
-
DBRF.at[i,'RT Min'] = DBRF.at[i,'RT (min)'] - peak_error
|
|
262
|
-
|
|
263
|
-
#Iterate through every row in BreakdownDF
|
|
264
|
-
for i, row in BreakdownDF.iterrows():
|
|
265
|
-
|
|
266
|
-
#Iterate through every row in DBRF
|
|
267
|
-
for i2, row2 in DBRF.iterrows():
|
|
268
|
-
|
|
269
|
-
#If the TCD retention time is within the range for a given DBRF entry...
|
|
270
|
-
if row2['RT Min'] <= row['RT'] <= row2['RT Max']:
|
|
271
|
-
|
|
272
|
-
#Add the compound name to the breakdown dataframe
|
|
273
|
-
BreakdownDF.at[i,'Compound Name'] = row2['Compound Name']
|
|
274
|
-
|
|
275
|
-
#Add the other relevant information to the breakdown dataframe
|
|
276
|
-
BreakdownDF.at[i,'Formula'] = row2['Formula']
|
|
277
|
-
BreakdownDF.at[i,'RF (Area/vol.%)'] = row2['RF']
|
|
278
|
-
BreakdownDF.at[i,'MW (g/mol)'] = ChemFormula(row2['Formula']).formula_weight
|
|
279
|
-
|
|
280
|
-
#Get estimated volume percent using response factor
|
|
281
|
-
volpercent_e = row['Area']/row2['RF']
|
|
282
|
-
BreakdownDF.at[i,'Est. Vol.%'] = volpercent_e
|
|
283
|
-
|
|
284
|
-
#Get adjusted volume percent using scale factor
|
|
285
|
-
volpercent_a = volpercent_e * SF
|
|
286
|
-
BreakdownDF.at[i,'Adj. Vol.%'] = volpercent_a
|
|
287
|
-
|
|
288
|
-
#Get moles using ideal gas law (PV=nRT)
|
|
289
|
-
BreakdownDF.at[i,'Moles (mol)'] = C * (GB_pressure * volpercent_a / 100 * V_TC)/(R * (GB_temp + 273.15))
|
|
290
|
-
|
|
291
|
-
#Get mass (mg) using moles and molar mass
|
|
292
|
-
BreakdownDF.at[i,'Mass (mg)'] = BreakdownDF.at[i,'Moles (mol)'] * BreakdownDF.at[i,'MW (g/mol)'] * 1000
|
|
293
|
-
|
|
294
|
-
#Otherwise, pass
|
|
295
|
-
else:
|
|
296
|
-
pass
|
|
297
|
-
|
|
298
|
-
return BreakdownDF, V_TC, SF
|
|
299
|
-
|
|
300
|
-
BreakdownDF, V_TC, SF = quantTCD(BreakdownDF,DBRF,gasBag_cond,reactor_cond)
|
|
301
|
-
|
|
302
|
-
return BreakdownDF, V_TC, SF
|
|
303
|
-
|
|
304
|
-
#Function for quantifying gas TCD data w/ internal standard method
|
|
305
|
-
def gasTCD_IS(BreakdownDF,DBRF,gasBag_cond,reactor_cond,peak_error):
|
|
306
|
-
|
|
307
|
-
#Initialize compound name column in BreakdownDF
|
|
308
|
-
BreakdownDF['Compound Name'] = 'None'
|
|
309
|
-
|
|
310
|
-
#Define molar mass of CO2, g/mol
|
|
311
|
-
Mc = 44.009
|
|
312
|
-
|
|
313
|
-
# Function to estimate mass of CO2 from provided conditions and get area of CO2
|
|
314
|
-
def massCO2(BreakdownDF,DBRF,R,C,V_C,P_0,GB_temp):
|
|
315
|
-
|
|
316
|
-
#Find the CO2 peak row in DBRF
|
|
317
|
-
CO2_row = DBRF.loc[DBRF['Compound Name'] == "Carbon Dioxide"].iloc[0]
|
|
318
|
-
|
|
319
|
-
#Get the retention time
|
|
320
|
-
CO2_RT = CO2_row['RT (min)']
|
|
321
|
-
|
|
322
|
-
#Get the minimum and maximum of the RT range using the peak error
|
|
323
|
-
CO2_RTmin = CO2_RT - peak_error
|
|
324
|
-
CO2_RTmax = CO2_RT + peak_error
|
|
325
|
-
|
|
326
|
-
#Define boolean describing whether or not CO2 match has been found
|
|
327
|
-
CO2_bool = False
|
|
328
|
-
|
|
329
|
-
#Iterate through every row in BreakdownDF
|
|
330
|
-
for i, row in BreakdownDF.iterrows():
|
|
331
|
-
|
|
332
|
-
#If the TCD retention time is within range of the CO2 entry...
|
|
333
|
-
if CO2_RTmin <= row['RT'] <= CO2_RTmax:
|
|
334
|
-
|
|
335
|
-
#Get mass of CO2, mg
|
|
336
|
-
mc = C * Mc * (P_0 * V_C) / (R * (GB_temp + 273.15)) * 1000
|
|
337
|
-
|
|
338
|
-
#Get area of CO2
|
|
339
|
-
Ac = row['Area']
|
|
340
|
-
|
|
341
|
-
#Set CO2_bool to True
|
|
342
|
-
CO2_bool = True
|
|
343
|
-
|
|
344
|
-
break
|
|
345
|
-
|
|
346
|
-
#Otherwise, pass
|
|
347
|
-
else:
|
|
348
|
-
pass
|
|
349
|
-
|
|
350
|
-
#Raise error if no CO2 peak found
|
|
351
|
-
if CO2_bool == False:
|
|
352
|
-
raise Exception("[gasTCD][ERROR] No CO2 peak found in TCD")
|
|
353
|
-
|
|
354
|
-
else:
|
|
355
|
-
pass
|
|
356
|
-
|
|
357
|
-
return mc, Ac
|
|
358
|
-
|
|
359
|
-
#Function to calculate amounts of each species using the scale factor
|
|
360
|
-
def quantTCD(BreakdownDF,DBRF,gasBag_cond,reactor_cond):
|
|
361
|
-
|
|
362
|
-
# Unpack gas bag conditions
|
|
363
|
-
GB_temp = gasBag_cond[0] # Temperature of gas bag, C
|
|
364
|
-
GB_pressure = gasBag_cond[1] # Sample pressure in gas bag, psig
|
|
365
|
-
V_C = gasBag_cond[2] # CO2 volume, mL
|
|
366
|
-
|
|
367
|
-
#Unpack reactor conditions
|
|
368
|
-
P_f = reactor_cond[0] #reactor quench pressure, psig
|
|
369
|
-
V_R = reactor_cond[1] #reactor internal volume, mL
|
|
370
|
-
P_0 = reactor_cond[2] #atmospheric pressure, psi
|
|
371
|
-
|
|
372
|
-
# Define ideal gas constant, m^3*Pa/K*mol
|
|
373
|
-
R = 8.314
|
|
374
|
-
|
|
375
|
-
#Define conversion factor, Pa * m^3 * psi^-1 * mL^-1
|
|
376
|
-
C = 0.00689476
|
|
377
|
-
|
|
378
|
-
#Get mass of CO2
|
|
379
|
-
mc, Ac = massCO2(BreakdownDF,DBRF,R,C,V_C,P_0,GB_temp)
|
|
380
|
-
|
|
381
|
-
#Get total volume plus CO2
|
|
382
|
-
V_T = V_R * (P_f + P_0) / P_0
|
|
383
|
-
V_TC = V_T + V_C
|
|
384
|
-
print(V_TC)
|
|
385
|
-
#Add min and max peak assignment values to DBRF
|
|
386
|
-
for i, row in DBRF.iterrows():
|
|
387
|
-
DBRF.at[i,'RT Max'] = DBRF.at[i,'RT (min)'] + peak_error
|
|
388
|
-
DBRF.at[i,'RT Min'] = DBRF.at[i,'RT (min)'] - peak_error
|
|
389
|
-
|
|
390
|
-
#Iterate through every row in BreakdownDF
|
|
391
|
-
for i, row in BreakdownDF.iterrows():
|
|
392
|
-
|
|
393
|
-
#Iterate through every row in DBRF
|
|
394
|
-
for i2, row2 in DBRF.iterrows():
|
|
395
|
-
|
|
396
|
-
#If the TCD retention time is within the range for a given DBRF entry...
|
|
397
|
-
if row2['RT Min'] <= row['RT'] <= row2['RT Max']:
|
|
398
|
-
|
|
399
|
-
#Add the compound name to the breakdown dataframe
|
|
400
|
-
BreakdownDF.at[i,'Compound Name'] = row2['Compound Name']
|
|
401
|
-
|
|
402
|
-
#Add the other relevant information to the breakdown dataframe
|
|
403
|
-
BreakdownDF.at[i,'Formula'] = row2['Formula']
|
|
404
|
-
BreakdownDF.at[i,'RF'] = row2['RF']
|
|
405
|
-
BreakdownDF.at[i,'MW (g/mol)'] = ChemFormula(row2['Formula']).formula_weight
|
|
406
|
-
|
|
407
|
-
#If the peak is CO2...
|
|
408
|
-
if row['Compound Name'] == "Carbon Dioxide":
|
|
409
|
-
#Set mass to mc
|
|
410
|
-
BreakdownDF.at[i,'Mass(mg)'] = mc
|
|
411
|
-
|
|
412
|
-
#Otherwise...
|
|
413
|
-
else:
|
|
414
|
-
#Get mass (mg) using mass of carbon dioxide and response factor
|
|
415
|
-
BreakdownDF.at[i,'Mass (mg)'] = (mc * (BreakdownDF.at[i,'Area'] / Ac)) / BreakdownDF.at[i,'RF']
|
|
416
|
-
|
|
417
|
-
#Otherwise, pass
|
|
418
|
-
else:
|
|
419
|
-
pass
|
|
420
|
-
|
|
421
|
-
return BreakdownDF, V_TC
|
|
422
|
-
|
|
423
|
-
BreakdownDF, V_TC = quantTCD(BreakdownDF,DBRF,gasBag_cond,reactor_cond)
|
|
424
|
-
|
|
425
|
-
return BreakdownDF, V_TC
|