import re import requests import pandas as pd import matplotlib.pyplot as plt def extract_predischarge_temp(shot_no, DEBUG=False, VERBOSE=False): """ Extracts the predischarge chamber temperature (T_ch) for a given shot number from the GOLEM ShotLogbook. Returns the temperature closest to the SecurePostDischargeState trigger and the time difference. """ try: url = f"http://golem.fjfi.cvut.cz/shots/{shot_no}/ShotLogbook" response = requests.get(url) response.raise_for_status() text = response.text except Exception: print(f"{shot_no} Error loading LOG") return float("nan"), float("nan") # Select the appropriate regex pattern based on shot number format changes if shot_no < 41065: # Old format: Chamber/VacuumLog line pattern = re.compile( r"^(\d{2}:\d{2}:\d{2}).*VacuumLog:.*mPa, ([\d\.]+)\s*C", re.MULTILINE ) elif shot_no < 42831: # Intermediate format: VacuumLog line with T=xx.xx C pattern = re.compile( r"^(\d{2}:\d{2}:\d{2}).*VacuumLog:.*T=([\d\.]+)\s*C", re.MULTILINE ) else: # New format: VacuumLog line with T_ch=xx.xx C pattern = re.compile( r"^(\d{2}:\d{2}:\d{2}).*VacuumLog:.*T_ch=([\d\.]+)\s*C", re.MULTILINE ) # With DEBUG, print matching lines and highlight matches if DEBUG: data = [] for i, line in enumerate(text.splitlines()): match = pattern.search(line) if match: # Highlight matched part in green start, end = match.span() highlighted = ( line[:start] + "\033[92m" + line[start:end] + "\033[0m" + line[end:] ) print(f"{i:03d}: {highlighted} <-- MATCH") data.append(match.groups()) else: print(f"{i:03d}: {line}") else: # Find all matches in the text data = pattern.findall(text) # Create DataFrame from extracted data df = pd.DataFrame(data, columns=["timestamp", "T_ch"]) df["T_ch"] = df["T_ch"].astype(float) df["timestamp"] = pd.to_datetime(df["timestamp"], format="%H:%M:%S") # Extract Trigger timestamp discharge_trigger_pattern = re.compile(r"^(\d{2}:\d{2}:\d{2}).*Trigger", re.MULTILINE) discharge_trigger_match = discharge_trigger_pattern.search(text) trigger_time = ( pd.to_datetime(discharge_trigger_match.group(1), format="%H:%M:%S") if discharge_trigger_match else None ) # If no temperature data found, return NaN if df.empty: if VERBOSE: print(f'{shot_no} no T_ch found') return float('nan'), float('nan') closest_T_ch, closest_T_ch_time_diff = float("nan"), float("nan") # Find the T_ch value closest in time to the Trigger if trigger_time is not None: idx = (df["timestamp"] - trigger_time).abs().idxmin() closest_T_ch = df.loc[idx, "T_ch"] closest_T_ch_time_diff = ( df.loc[idx, "timestamp"] - trigger_time ).total_seconds() if VERBOSE: print( f"{shot_no} T_ch_discharge = {closest_T_ch:.2f} C, t_diff = {closest_T_ch_time_diff} s" ) # If DEBUG, plot the temperature vs timestamp and mark the trigger time if DEBUG: plt.figure(figsize=(10, 5)) plt.plot(df["timestamp"], df["T_ch"], marker="o") plt.xlabel("Timestamp") plt.ylabel("T_ch [deg]") plt.title("T_ch vs Timestamp") # Add vertical line for Trigger if trigger_time is not None: plt.axvline( x=trigger_time, color="r", linestyle="--", label="Trigger", ) plt.legend() plt.xticks(rotation=45) plt.tight_layout() plt.show() return closest_T_ch, closest_T_ch_time_diff def main(): """ Iterates over a range of shot numbers, extracts predischarge temperature for each, and saves the results to a CSV file. """ index = pd.Index(list(range(33170,50055)), name='shot_no') df = pd.DataFrame(index=index, columns='T_ch t_delta'.split()) try: for shot_no, _ in df.iterrows(): T_ch, t_delta = extract_predischarge_temp(shot_no, VERBOSE=True) df.loc[shot_no] = T_ch, t_delta except Exception: pass df.to_csv('T_ch_discharge.csv') if __name__ == "__main__": ## for testing #T_ch, t_delta = extract_predischarge_temp(50055, VERBOSE=True, DEBUG=True) ## go over all Logs and save to csv main()