Compare commits

..

8 Commits

Author SHA1 Message Date
aeef8f9253 Finalise README 2024-10-25 16:21:42 +10:00
247c503885 Correct 2024-10-25 16:05:59 +10:00
c4b0dd1fef quick refactor and addition of README 2024-10-25 16:05:22 +10:00
3398414b55 Finalise Thesis Codebase 2024-10-25 15:55:16 +10:00
1b66ac1f24 fix title 2024-10-23 14:24:02 +10:00
7d6b3403f5 Make nice canning graph 2024-10-23 14:20:57 +10:00
313ef7d1de Use mean uncert not sqrt(sum) 2024-10-23 14:07:12 +10:00
9570111f61 Correct the shot numbers 2024-10-23 14:03:01 +10:00
7 changed files with 115 additions and 67 deletions

39
README.md Normal file
View File

@ -0,0 +1,39 @@
# Ionization Probe Analysis Code
> Written by Cal Wing (<c.wing@uq.net.au> - 45811953) in 2024 for his Thesis
## Installation
Run `pip install -r requirements.txt` or equivilient for your envoroment.
## Running
Run `main.py` it will then generate all the output graphs and put them in (a git untracked) folder called `./images`.
By default all data graphs will be generated - you need to change the functions called at the end in the `if '__name__ == '__main__':` section.
## `./data` Explanation
I like YAML files to store information. All the data shot folders have a file call `_info.yaml` this file contained all the info about the shot so that when it would load & be graphed it would be correct.
I hope the values are self explanatory but they may not - sorry
## Changes to [canny_shock_finder.py](./canny_shock_finder.py)
Basically I hacked in an extra argument `print_func`, that is used to override the `print` function in the file. It assumes its either a callable reference (like print, the default) or None (it then uses a no-operation function to silence all output)
I also removed the error catching around lines ~497 so the function blindly continues if it can't graph.
I also enabled grid lines on the graphs.
The UQ colours being used on the graphs is due to some funky ~~abuse~~ *utlitly* I built into my [`makeGraph`](#makegraph) library.
## MakeGraph
> This refers to the [makeGraph.py](./makeGraph.py) file/version *in this code base*, I would not trust the exact specifics for versions found elsewhere, but the general gist is the same.
A *long* time ago I wrote a wrapper for matplotlib that has expanded into a formatting tool. The crux of it is that I can throw a dictionary at the `makeGraph` function and it will do all the hard work for me.
There are a few fun things that loading the lib will do - like overriding the default colour cyclers to use only the UQ colours - so if your going to liberate / adapt it be wary.
All the graphing done in the [`main.py`](./main.py) uses makeGraph, its not the most scary thing in the world as its basically ~~AI~~ *a big if conditional*.

View File

@ -15,7 +15,7 @@ Chris James (c.james4@uq.edu.au) - 04/07/17
# Amened by Cal Wing to make the function not print
VERSION_STRING = "17-Oct-2024"
VERSION_STRING = "20-Oct-2024"
def canny_shock_finder(time_list, pressure_list, sigma = 4, derivative_threshold = 0.001, auto_derivative = False, post_suppression_threshold = 0.05,
post_shock_pressure = None, start_time = None, find_second_peak = None, plot = True, plot_scale_factor = None,
@ -116,6 +116,8 @@ def canny_shock_finder(time_list, pressure_list, sigma = 4, derivative_threshold
:param plot_time_scale: See plot_time_unit above. These two inputs allow the results plot to be in a different
time unit to the original data. The user must specify this scale to connect the original and plotted
time units. Defaults to 1.0 (so no change if time units are seconds).
:param print_func: Callable Reference to call when print is called in this function. Defaults to 'print' but if 'None'
is passed it uses a no-operation function to silence all output.
"""
# Make the function silent / have print overridable
@ -360,6 +362,9 @@ def canny_shock_finder(time_list, pressure_list, sigma = 4, derivative_threshold
data_ax.plot(time_list*plot_time_scale, pressure_list, '-o', label = 'original data')
data_ax.grid(True)
convolution_ax.grid(True)
convolution_ax.plot(time_list*plot_time_scale, first_order_data, '-o', label='first order gaussian (sigma = {0})'.format(sigma))
convolution_ax.plot(time_list*plot_time_scale, second_order_data, '-o', label='second order gaussian (sigma = {0})'.format(sigma))
convolution_ax.plot(time_list*plot_time_scale, suppressed_data, '-o', label='first order with non-max suppression')

View File

@ -56,7 +56,7 @@ probe-info:
- 2
locations: # In order of pulse
- "st2"
- "st3"
# - "st3"
data-records:
- type: "scope"

View File

@ -1,7 +1,7 @@
# Data Info File
# Cal Wing - Oct 24
long_name: "Shot 5 (x2s5829) - Thin Probe Pair (ST2 & ST3) - 2024-10-17\nProtruding ST2 & ST3 - Mars Entry Conditions"
long_name: "Shot 5 (x2s5830) - Thin Probe Pair (ST2 & ST3) - 2024-10-17\nProtruding ST2 & ST3 - Mars Entry Conditions"
name: "Shot 5"
date: "2024-10-18"
time: "08:51"

View File

@ -1,7 +1,7 @@
# Data Info File
# Cal Wing - Oct 24
long_name: "Shot 6 (x2s5829) - Thin Probe Set (ST1, ST2 & ST3) - 2024-10-18\nProtruding ST1 & ST3, Flush ST2 (Only Gauge 1) - Mars Entry Conditions"
long_name: "Shot 6 (x2s5831) - Thin Probe Set (ST1, ST2 & ST3) - 2024-10-18\nProtruding ST1 & ST3, Flush ST2 (Only Gauge 1) - Mars Entry Conditions"
comments: "G2 Pointless, Wasn't attached"
name: "Shot 6"
date: "2024-10-18"

View File

@ -1,7 +1,7 @@
# Data Info File
# Cal Wing - Oct 24
long_name: "Shot 7 (x2s5829) - Thin Probe Set (ST1, ST2 & ST3) - 2024-10-18\nProtruding ST1 & ST1, Flush ST3 (Only Gauge 1) - Low Pressure, 'Pure' Air Conditions"
long_name: "Shot 7 (x2s5832) - Thin Probe Set (ST1, ST2 & ST3) - 2024-10-18\nProtruding ST1 & ST1, Flush ST3 (Only Gauge 1) - Low Pressure, 'Pure' Air Conditions"
name: "Shot 7"
date: "2024-10-18"
time: "15:58"

54
main.py
View File

@ -29,22 +29,6 @@ CANNY_TIME_OFFSET = 50 #us
with open(TUNNEL_INFO_FILE, 'r') as file:
TUNNEL_INFO = yaml.safe_load(file)
data_to_load = [
"x2s5823",
"x2s5824",
"x2s5827",
"x2s5829",
"x2s5830",
"x2s5831",
"x2s5832"
]
ref_data_to_load = [
"x2s5820",
"x2s5821",
"x2s5822"
]
# ==== Uncerts ====
# Taken from DOI: 10.1007/s00193-017-0763-3 (Implementation of a state-to-state analytical framework for the calculation of expansion tube flow properties)
@ -319,7 +303,12 @@ def load_data(data_path: str, data={}) -> dict:
for i, probe in enumerate(dataInfo["probe-info"]["locations"]):
# Get the canny-args
cArgs = dataInfo["canny-args"]
doCannyPlot = False
doCannyPlot = False # x2_shot == "x2s5829" and probe == "st2" # This condition was used to generate some graphs
plotValues = {
"plot_title": f"Canny Shock Finding Result for {x2_shot} - ST2 Gauge 1",
"plot_time_unit": "$\\mu$s",
"y_label": "Voltage Reading (V)",
}
if i in range(len(cArgs)):
sigma = cArgs[i]["sigma"]
post_sup_thresh = cArgs[i]["post_pres"]
@ -336,7 +325,7 @@ def load_data(data_path: str, data={}) -> dict:
# Find G1 Shock Time
if 1 in dataInfo["probe-info"]["gauges"]:
first_value, first_value_uncertainty, _, _ = canny_shock_finder(scope_time, probeCh1, sigma=sigma, post_suppression_threshold=post_sup_thresh, plot=doCannyPlot, start_time=time_offset, print_func=None)
first_value, first_value_uncertainty, _, _ = canny_shock_finder(scope_time, probeCh1, sigma=sigma, post_suppression_threshold=post_sup_thresh, plot=doCannyPlot, start_time=time_offset, print_func=None, **plotValues)
if first_value is None:
print(f"[ERROR] {x2_shot} - {probe}-g1 could not be detected using: Sigma = {sigma}, post_suppression_threshold = {post_sup_thresh}")
raise ValueError(f"{probe}-g1 not detected")
@ -664,7 +653,7 @@ def genGraph(gData: dict, showPlot: bool = True, doLimits: bool = True, forcePlo
if not flag and not gData["shock-speed"][shock_speed_loc][2]:
flag = True
avg_speed = np.array(avg_speed_lst).mean()
avg_uncert = np.sqrt(np.sum(np.pow(np.array(avg_uncert_lst), 2)))
avg_uncert = np.array(avg_uncert_lst).mean() # np.sqrt(np.sum(np.pow(np.array(avg_uncert_lst), 2)))
probeText += f"\nAverage Speed - {avg_speed/1000:.2f} $\\pm${avg_uncert/1000:.2f} [{avg_uncert/avg_speed * 100:.2f}%] km/s"
probeText += "\n" + "-"*50
@ -732,7 +721,7 @@ def genRefGraph(gData: dict, showPlot: bool = True, addShockInfo: bool = True, f
if not flag and not gData["shock-speed"][shock_speed_loc][2]:
flag = True
avg_speed = np.array(avg_speed_lst).mean()
avg_uncert = np.sqrt(np.sum(np.pow(np.array(avg_uncert_lst), 2)))
avg_uncert = np.array(avg_uncert_lst).mean() # np.sqrt(np.sum(np.pow(np.array(avg_uncert_lst), 2)))
probeText += f"\nAverage Speed - {avg_speed/1000:.2f} $\\pm${avg_uncert/1000:.2f} [{avg_uncert/avg_speed * 100:.2f}%] km/s"
probeText += "\n" + "-"*50
@ -855,7 +844,7 @@ def genComboRefGraph(data: dict, plotCh: list[str] = ["st1", "st2", "st3"], show
probeText += f"\n{shock_speed_loc} - {speed/1000:.2f} $\\pm${uncert/1000:.2f} [{uncert/speed*100:.2f}%] km/s"
avg_sp = np.array(avg_speeds).mean()
avg_unc = np.sqrt(np.pow(np.array(avg_uncerts), 2).sum())
avg_unc = np.array(avg_uncerts).mean() #np.sqrt(np.pow(np.array(avg_uncerts), 2).sum())
probeText += f"\nAverage Speed - {avg_sp/1000:.2f} $\\pm${avg_unc/1000:.2f} [{avg_unc/avg_sp * 100:.2f}%] km/s"
graphData["plots"].append({
@ -1077,7 +1066,7 @@ def genX2CompGraphs(gData: dict, showPlot: bool = True):
graphData["plots"].append({
"type": "axvLine",
"x": gData["shock-point"]["x2"][f"{probe}-g1"][1],#[i],
"label": f"{probe}-Gauge 1 - X2 DAQ - Shock Point {gData['shock-point'][f'{probe}-g1'][1]:.2f}$\\mu$s",
"label": f"{probe}-Gauge 1 - X2 DAQ - Shock Point {gData['shock-point']["x2"][f'{probe}-g1'][1]:.2f}$\\mu$s",
"colour": UQC["dark_grey"],
"args":{"zorder":2, "linestyle":"--", "alpha":0.5}
})
@ -1087,7 +1076,7 @@ def genX2CompGraphs(gData: dict, showPlot: bool = True):
graphData["plots"].append({
"type": "axvLine",
"x": gData["shock-point"]["x2"][f"{probe}-g2"][1],#[i],
"label": f"{probe}-Gauge 2 - X2 DAQ - Shock Point {gData['shock-point'][f'{probe}-g2'][1]:.2f}$\\mu$s",
"label": f"{probe}-Gauge 2 - X2 DAQ - Shock Point {gData['shock-point']["x2"][f'{probe}-g2'][1]:.2f}$\\mu$s",
"colour": UQC["dark_grey"],
"args":{"zorder":2, "linestyle":":", "alpha":0.5}
})
@ -1111,6 +1100,23 @@ def genX2CompGraphs(gData: dict, showPlot: bool = True):
pass
if __name__ == "__main__":
data_to_load = [
"x2s5823",
"x2s5824",
"x2s5827",
"x2s5829",
"x2s5830",
"x2s5831",
"x2s5832"
]
ref_data_to_load = [
"x2s5820",
"x2s5821",
"x2s5822"
]
print("Loading Data")
# My Shot Data
@ -1128,8 +1134,6 @@ for refShot in ref_data_to_load:
print("Loaded Data")
print("Graphing Data")
# General Shot Graphing