[1]:
import pyfas as fa
import pandas as pd
import matplotlib.pyplot as plt
3. OLGA tpl files, examples and howto¶
For an tpl file the following methods are available:
- filter_data - return a filtered subset of trends
- extract - extract a single trend variable
- to_excel - dump all the data to an excel file
The usual workflow should be:
- Load the correct tpl
- Select the desired variable(s)
- Extract the results or dump all the variables to an excel file
- Post-process your data in Excel or in the notebook itself
3.1. Tpl loading¶
To load a specific tpl file the correct path and filename have to be provided:
[2]:
tpl_path = '../../pyfas/test/test_files/'
fname = '11_2022_BD.tpl'
tpl = fa.Tpl(tpl_path+fname)
3.1.1. Trend selection¶
tpl.filter_trends("PT")
filters all the pressure trends (or better, all the trends with “PT” in the description, if you have defined a temperature trend in the position “PTTOPSIDE”, for example, this trend will be selected too). The resulting python dictionaly will have a unique index for each filtered trend that can be used to identify the interesting trend(s). In case of an emply pattern all the available trends will
be reported.[3]:
tpl.filter_data('PT')
[3]:
{9: "PT 'POSITION:' 'EXIT' '(PA)' 'Pressure'\n",
37: "PT 'POSITION:' 'BOTTOMHOLE' '(PA)' 'Pressure'\n",
38: "PT 'POSITION:' 'TUBINGHEAD' '(PA)' 'Pressure'\n",
39: "PT 'POSITION:' 'DC6' '(PA)' 'Pressure'\n",
40: "PT 'POSITION:' 'DC7' '(PA)' 'Pressure'\n",
41: "PT 'POSITION:' 'DC8' '(PA)' 'Pressure'\n",
42: "PT 'POSITION:' 'DC9' '(PA)' 'Pressure'\n",
43: "PT 'POSITION:' 'RBM' '(PA)' 'Pressure'\n",
44: "PT 'POSITION:' 'EXIT' '(PA)' 'Pressure'\n"}
or
[4]:
tpl.filter_data("'POSITION:' 'EXIT'")
[4]:
{3: "GLT 'POSITION:' 'EXIT' '(KG/S)' 'Total liquid mass flow'\n",
4: "GLTHL 'POSITION:' 'EXIT' '(KG/S)' 'Mass flow rate of oil'\n",
5: "GLTWT 'POSITION:' 'EXIT' '(KG/S)' 'Mass flow rate of water excluding vapour'\n",
6: "GLWVT 'POSITION:' 'EXIT' '(KG/S)' 'Total mass flow rate of water including Vapour'\n",
7: "GT 'POSITION:' 'EXIT' '(KG/S)' 'Total mass flow'\n",
8: "HOL 'POSITION:' 'EXIT' '(-)' 'Holdup (liquid volume fraction)'\n",
9: "PT 'POSITION:' 'EXIT' '(PA)' 'Pressure'\n",
10: "QLT 'POSITION:' 'EXIT' '(M3/S)' 'Total liquid volume flow'\n",
11: "TM 'POSITION:' 'EXIT' '(C)' 'Fluid temperature'\n",
12: "UL 'POSITION:' 'EXIT' '(M/S)' 'Average liquid film velocity'\n",
20: "HOL 'POSITION:' 'EXIT' '(-)' 'Holdup (liquid volume fraction)'\n",
28: "HOLWT 'POSITION:' 'EXIT' '(-)' 'Water volume fraction'\n",
36: "ID 'POSITION:' 'EXIT' '(-)' 'Flow regime: 1=Stratified, 2=Annular, 3=Slug, 4=Bubble.'\n",
44: "PT 'POSITION:' 'EXIT' '(PA)' 'Pressure'\n",
52: "Q2 'POSITION:' 'EXIT' '(W/M2-C)' 'Overall heat transfer coefficient'\n",
60: "TM 'POSITION:' 'EXIT' '(C)' 'Fluid temperature'\n",
68: "TU 'POSITION:' 'EXIT' '(C)' 'Ambient temperature'\n",
76: "TWS 'POSITION:' 'EXIT' '(C)' 'Inner wall surface temperature'\n",
84: "QGST 'POSITION:' 'EXIT' '(SM3/S)' 'Gas volume flow at standard conditions'\n",
92: "QOST 'POSITION:' 'EXIT' '(SM3/S)' 'Oil volume flow at standard conditions'\n",
100: "QWST 'POSITION:' 'EXIT' '(SM3/S)' 'Water volume flow at standard conditions'\n",
108: "AL 'POSITION:' 'EXIT' '(-)' 'Void (gas volume fraction)'\n",
116: "GG 'POSITION:' 'EXIT' '(KG/S)' 'Gas mass flow'\n",
124: "GLT 'POSITION:' 'EXIT' '(KG/S)' 'Total liquid mass flow'\n",
132: "GT 'POSITION:' 'EXIT' '(KG/S)' 'Total mass flow'\n",
140: "DTHYD 'POSITION:' 'EXIT' '(C)' 'Difference between hydrate and section temperature'\n"}
The same outpout can be reported as a pandas dataframe:
[5]:
pd.DataFrame(tpl.filter_data('PT'), index=("Trends",)).T
[5]:
Trends | |
---|---|
9 | PT 'POSITION:' 'EXIT' '(PA)' 'Pressure'\n |
37 | PT 'POSITION:' 'BOTTOMHOLE' '(PA)' 'Pressure'\n |
38 | PT 'POSITION:' 'TUBINGHEAD' '(PA)' 'Pressure'\n |
39 | PT 'POSITION:' 'DC6' '(PA)' 'Pressure'\n |
40 | PT 'POSITION:' 'DC7' '(PA)' 'Pressure'\n |
41 | PT 'POSITION:' 'DC8' '(PA)' 'Pressure'\n |
42 | PT 'POSITION:' 'DC9' '(PA)' 'Pressure'\n |
43 | PT 'POSITION:' 'RBM' '(PA)' 'Pressure'\n |
44 | PT 'POSITION:' 'EXIT' '(PA)' 'Pressure'\n |
The view_trends
method provides the same info better arranged:
[18]:
tpl.view_trends('PT')
[18]:
Index | Variable | Position | Unit | Description | |
---|---|---|---|---|---|
Filter: PT | |||||
0 | 37 | PT | POSITION - BOTTOMHOLE | PA | Pressure |
1 | 38 | PT | POSITION - TUBINGHEAD | PA | Pressure |
2 | 39 | PT | POSITION - DC6 | PA | Pressure |
3 | 40 | PT | POSITION - DC7 | PA | Pressure |
4 | 9 | PT | POSITION - EXIT | PA | Pressure |
5 | 41 | PT | POSITION - DC8 | PA | Pressure |
6 | 43 | PT | POSITION - RBM | PA | Pressure |
7 | 44 | PT | POSITION - EXIT | PA | Pressure |
8 | 42 | PT | POSITION - DC9 | PA | Pressure |
3.1.2. Dump to excel¶
To dump all the variables in an excel file use tpl.to_excel()
If no path is provided an excel file with the same name of the tpl file is generated in the working folder. Depending on the tpl size this may take a while.
3.1.3. Extract a specific variable¶
Once you know the variable(s) index you are interested in (see the filtering paragraph above for more info) you can extract it (or them) and use the data directly in python.
Let’s assume you are interested in the inlet pressure and the outlet temperature:
[17]:
tpl.view_trends('TM')
[17]:
Index | Variable | Position | Unit | Description | |
---|---|---|---|---|---|
Filter: TM | |||||
0 | 59 | TM | POSITION - RBM | C | Fluid temperature |
1 | 53 | TM | POSITION - BOTTOMHOLE | C | Fluid temperature |
2 | 54 | TM | POSITION - TUBINGHEAD | C | Fluid temperature |
3 | 55 | TM | POSITION - DC6 | C | Fluid temperature |
4 | 56 | TM | POSITION - DC7 | C | Fluid temperature |
5 | 57 | TM | POSITION - DC8 | C | Fluid temperature |
6 | 58 | TM | POSITION - DC9 | C | Fluid temperature |
7 | 11 | TM | POSITION - EXIT | C | Fluid temperature |
8 | 60 | TM | POSITION - EXIT | C | Fluid temperature |
[14]:
tpl.view_trends('PT')
[14]:
Index | Variable | Position | Unit | Description | |
---|---|---|---|---|---|
Filter: PT | |||||
0 | 37 | PT | POSITION - BOTTOMHOLE | PA | Pressure |
1 | 38 | PT | POSITION - TUBINGHEAD | PA | Pressure |
2 | 39 | PT | POSITION - DC6 | PA | Pressure |
3 | 40 | PT | POSITION - DC7 | PA | Pressure |
4 | 9 | PT | POSITION - EXIT | PA | Pressure |
5 | 41 | PT | POSITION - DC8 | PA | Pressure |
6 | 43 | PT | POSITION - RBM | PA | Pressure |
7 | 44 | PT | POSITION - EXIT | PA | Pressure |
8 | 42 | PT | POSITION - DC9 | PA | Pressure |
Our targets are:
variable 11 - TM ‘POSITION:’ ‘EXIT’ ‘(C)’ ‘Fluid temperature’
and
variable 38 - PT ‘POSITION:’ ‘TUBINGHEAD’ ‘(PA)’ ‘Pressure’
Now we can proceed with the data extraction:
[8]:
# single trend extraction
tpl.extract(11)
tpl.extract(38)
# multiple trends extraction
tpl.extract(12, 37)
The tpl object now has the four trends available in the data
attribute:
[11]:
tpl.data.keys()
[11]:
dict_keys([11, 12, 37, 38])
while the label attibute stores the variable type as a dictionary:
[15]:
tpl.label
[15]:
{11: 'TM POSITION: EXIT (C) Fluid temperature',
12: 'UL POSITION: EXIT (M/S) Average liquid film velocity',
37: 'PT POSITION: BOTTOMHOLE (PA) Pressure',
38: 'PT POSITION: TUBINGHEAD (PA) Pressure'}
3.1.4. Data processing¶
The results available in the data attribute are numpy arrays and can be easily manipulated and plotted:
[49]:
%matplotlib inline
pt_inlet = tpl.data[38]
tm_outlet = tpl.data[11]
fig, ax1 = plt.subplots(figsize=(12, 7));
ax1.grid(True)
p0, = ax1.plot(tpl.time/3600, tm_outlet)
ax1.set_ylabel("Outlet T [C]", fontsize=16)
ax1.set_xlabel("Time [h]", fontsize=16)
ax2 = ax1.twinx()
p1, = ax2.plot(tpl.time/3600, pt_inlet/1e5, 'r')
ax2.grid(False)
ax2.set_ylabel("Inlet P [bara]", fontsize=16)
ax1.tick_params(axis="both", labelsize=16)
ax2.tick_params(axis="both", labelsize=16)
plt.legend((p0, p1), ("Outlet T", "Inlet P"), loc=4, fontsize=16)
plt.title("Inlet P and Outlet T for case FC1", size=20);
3.1.5. Advanced data processing¶
An example of advanced data processing for Python enthusiasts and professional flow assurance. Script below extracts variable trends at given positions. Usage instructions: - For unit conversion multiplication factors for every variable can be provided. - Only few global variables and lists have to be defined (allMul, allVar, allPos, and myTPLFile), there is no need to edit functions, unless you understand what you are doing. - Extracted trends are written in to a CSV file “OLGA_Simulation.tpl.csv”, where “OLGA_Simulation.tpl” is the simulation file. - The script does not perform error checks, make sure that all variables and positions are present in the simulation file.
[ ]:
import os
import sys
import time
import pyfas as fa
def getVarsInds(tpl, emptyLst):
for _, pos in enumerate(allPos):
lst = []
# dictionary of the following kind:
# {3: "GLT 'POSITION:' 'EXIT' '(KG/S)' 'Total liquid mass flow'\n",
# 4: "GLTHL 'POSITION:' 'EXIT' '(KG/S)' 'Mass flow rate of oil'\n"}
myDic = tpl.filter_trends("'POSITION:' '{0}'".format(pos))
for _, var in enumerate(allVar):
for _, (k, v) in enumerate(myDic.items()):
lstStr = v.split(" ")
if lstStr[0] == var:
lst.append(int(k))
emptyLst.append(lst)
def getData(tplFileName, fullLst):
myFlag = False
fout = open("{0}.csv".format(tplFileName), 'w')
# write header
outLine = ""
for _, pos in enumerate(allPos):
for _, var in enumerate(allVar):
outLine += "{0},{1} {2},".format( "Time [H]", pos, var )
fout.writelines("{0}\n".format(outLine))
# write data
with open(tplFileName) as infile:
for line in infile:
if myFlag:
myValList = line.split()
myTime = float(myValList[0]) / 3600.0 # in hours
outLine = ""
for i in range(len(allPos)):
for j in range(len(allVar)):
outLine += "{0},{1},".format( myTime, float(myValList[fullLst[i][j]]) * allMul[j] )
fout.write("{0}\n".format(outLine))
else:
if line.find("TIME SERIES") > -1: myFlag = True
fout.close()
def main():
print( "{0} initialization".format(time.strftime("%H:%M:%S", time.localtime())) )
fname = myTPLFile
tpl = fa.Tpl(fname)
# list of indices for vars at every position (separate list for every position in order)
varIndLst = []
getVarsInds(tpl, varIndLst)
print( "{0} extraction".format(time.strftime("%H:%M:%S", time.localtime())) )
getData(fname, varIndLst)
print( "{0} done".format(time.strftime("%H:%M:%S", time.localtime())) )
# multiplication factors and variables
allMul = [1.0, 1.0, 1.0e-5, 1.0]
allVar = ["ROL", "ROG", "PT", "TM"]
# positions
allPos = ["FLOWLINE_1KM", "FLOWLINE_2KM", "FLOWLINE_3KM", "FLOWLINE_4KM", "FLOWLINE_5KM"]
myTPLFile = "OLGA_Simulation.tpl"
main()