Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion BurnIn_Worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -922,6 +922,7 @@ def BI_Start_Cmd(self):
session_dict["Current_ModuleID"] = "Undef"
session_dict["fc7Slot"] = "Undef"
session_dict["Current_ModuleHV"] = "Undef"
session_dict["Current_Slot"] = -1
session_dict["WorkingTemp"] = 20

session_dict["NCycles"] = [item.upper() for item in session_dict["StepList"]].count("COOL")
Expand Down Expand Up @@ -1103,10 +1104,18 @@ def BI_Start_Cmd(self):
self.SharedDict["BI_Action"].setText(session_dict["Action"][4:]+" Module test")
self.SharedDict["BI_TestActive"]=True
session_dict["TestType"]=session_dict["Action"][4:]
for slot in Slot_list:
# Determine starting slot index for recovery
start_slot_index = 0
if session_dict["Current_Slot"] >= 0 and session_dict["Current_Slot"] in Slot_list:
# Resume from the last tested slot (skip already completed modules)
start_slot_index = Slot_list.index(session_dict["Current_Slot"])
self.logger.info("BI: Resuming module testing from slot index %d (slot %d)" % (start_slot_index, Slot_list[start_slot_index] if start_slot_index < len(Slot_list) else -1))
Comment on lines +1109 to +1112
for slot_index in range(start_slot_index, len(Slot_list)):
slot = Slot_list[slot_index]
session_dict["fc7ID"]=self.SharedDict["BI_fc7IDs"][slot]
session_dict["fc7Slot"]=self.SharedDict["BI_fc7Slots"][slot]
session_dict["Current_ModuleID"] = self.SharedDict["BI_ModuleIDs"][slot]
session_dict["Current_Slot"] = slot
self.BI_Update_Status_file(session_dict)
self.SharedDict["BI_SUT"].setText(str(slot+1))
self.logger.info("BI: testing BI slot "+str(slot)+": module name "+session_dict["Current_ModuleID"]+", fc7 slot "+session_dict["fc7Slot"]+",board "+session_dict["fc7ID"])
Expand All @@ -1123,6 +1132,7 @@ def BI_Start_Cmd(self):

self.SharedDict["BI_TestActive"]=False
session_dict["TestType"]="Undef"
session_dict["Current_Slot"]=-1 # Reset after completing all modules in this step
Comment on lines 1133 to +1135

if (session_dict["Action"].upper()[0:4]=="WAIT"):
try:
Expand Down
2 changes: 1 addition & 1 deletion Config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Supervisor:
Enabled: "True"
BITest:
cwd: "/home/thermal/BurnIn_moduleTest"
version: "ph2_acf_v6-18"
version: "ph2_acf_v6-25"
IVScan:
cwd: "/home/thermal/BurnIn_moduleTest"
scanType: "after_encapsulation"
Expand Down
189 changes: 189 additions & 0 deletions generate_standard_burnin_v6.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
#!/usr/bin/env python3
"""generate_standard_burnin_v6.py

Generates standard_burnin_v6.txt — a complete burn-in command sequence.
Based on "QC Document for Production Modules (v6)" (23 April 2026)

Sequence layout
───────────────────────────────────────────────────────────────────────────────
warm-0, cold-0, warm-1, cold-1, …, warm-16, cold-16, warm-17
= 18 Heat steps, 17 Cool steps


DAQ:vtrxoff added before each ScanIV
───────────────────────────────────────────────────────────────────────────────
"""

OUTPUT_FILE = "standard_burnin_v6.txt"

# ──────────────────────────────────────────────────────────────────────────────
# CONFIGURATION — edit the values in this section to adjust the sequence
# ──────────────────────────────────────────────────────────────────────────────

# Number of full cold cycles (0 to 16 = 17 cold cycles, ending with warm-17)
MAX_CYCLE = 17

# Whether to include the DAQ:vtrxoff step before each ScanIV measurement
INCLUDE_VTRXOFF = True

# Stabilisation wait (minutes) after Heat or Cool
# 'When the specified temperature for a test is reached, stay 10 minutes at this target temperature before starting the test.'
WAIT_MINUTES = 10

# Wait (minutes) after ScanIV is finished and modules are switched off
# 'After the IV curve the modules are switched off for 20 minutes to reach the lowest possible temperature.'
WAIT_AFTER_SCANIV_MINUTES = 20

# A single schedule dictionary configuring exactly what tests to run at any pause.
# Ensure the key format is 'warm-N' or 'cold-N' (e.g., matching the names above).
# The final step is automatically warm-<last_cold+1> (e.g., warm-17).
#
# Available tests: 'ScanIV', 'PSfullTest', 'PSquickTest'
# Note: You can easily enforce execution order and re-run tests by repeating them in the list.

# 'According to Fig. 15, there are eight IV curves and eight switch-on processes (six of them cold).
# 1. In warm at the beginning
# 2. The first time in cold
# 3. The fifth time cold
# 4. The ninth time cold (performed twice)
# 5. The thirteenth time cold
# 6. The last time cold
# 7. The last time in warm'

TEST_SCHEDULE = {
'warm-0': ['ScanIV', 'PSquickTest'],
'cold-0': ['ScanIV', 'PSquickTest'],
'cold-4': ['ScanIV', 'PSquickTest'],
'cold-8': ['ScanIV', 'ScanIV', 'PSfullTest', 'PSquickTest'],
'cold-12': ['ScanIV', 'PSquickTest'],
'cold-16': ['ScanIV', 'PSfullTest'],
'warm-17': ['ScanIV', 'PSquickTest']
}

# ──────────────────────────────────────────────────────────────────────────────


def generate() -> str:
"""Build and return the full content of the burnin sequence file."""

lines: list = []

lines.append("""'''
This file is automatically generated.
To recreate or modify this sequence, run:
python3 generate_standard_burnin_v6.py

Note for the burn-in execution:
The relative humidity should stay below 10%, and the dew point at least 5◦C below target temperature.
At the warm condition the temperature shall be between 20 ◦ C and 25 ◦ C.
At cold, the temperature measurement shall be between −35 ◦ C and −33 ◦ C.
The temperature should be measured by temperature boards which are clipped to the carriers.

For the IV curve use:
0 V - -200 V in steps of 10 V,
-200 V - -800 V in steps of 20 V.
The settling time before the I measurement is 1 s.
Use a ramp speed of 10 V/s.
'''""")

# ── low-level line emitters ───────────────────────────────────────────────

def s(step, indent=0):
"""Append a single addStep line."""
lines.append(" " * indent + f'addStep("{step}")')

def comment(text, indent=2):
lines.append("")
lines.append(" " * indent + f"# {text}")

def section(title):
"""Print a visible section header."""
sep = "─" * 60
lines.append("")
lines.append(f"# {sep}")
lines.append(f"# {title}")
lines.append(f"# {sep}")

# ── building-block emitters ───────────────────────────────────────────────

def emit_vtrxoff_scaniv(indent=0):
"""LV_on / HV_off → [DAQ:vtrxoff] → ScanIV → HV_off / LV_off → Wait → LV_on / HV_on"""
s("LV_on", indent)
s("HV_off", indent)
if INCLUDE_VTRXOFF:
s("DAQ:vtrxoff", indent)
s("ScanIV", indent)
s("HV_off", indent)
s("LV_off", indent)
s(f"Wait:{WAIT_AFTER_SCANIV_MINUTES * 60}", indent)
s("LV_on", indent)
s("HV_on", indent)

def emit_fulltest(indent=0):
"""DAQ:PSfullTest"""
s("DAQ:PSfullTest", indent)

def emit_quicktest(indent=0):
"""DAQ:PSquickTest"""
s("DAQ:PSquickTest", indent)

def emit_stop_tests(stop_name, indent=0):
"""Emit all tests mapped to the current stop according to TEST_SCHEDULE."""
tests = TEST_SCHEDULE.get(stop_name, [])
total_scans = tests.count('ScanIV')
scan_idx = 1

for test in tests:
if test == 'ScanIV' and total_scans > 1:
comment(f"ScanIV {scan_idx}/{total_scans}", indent)
scan_idx += 1
else:
comment(test, indent)

if test == 'ScanIV':
emit_vtrxoff_scaniv(indent)
elif test == 'PSfullTest':
emit_fulltest(indent)
elif test == 'PSquickTest':
emit_quicktest(indent)
else:
comment(f"WARNING: Unknown test '{test}'", indent)

def section_title(stop_name, extra=""):
"""Format the section title with the scheduled tests."""
tests = TEST_SCHEDULE.get(stop_name, [])
tests_str = ", ".join(tests)
content = f" — [ {tests_str} ]" if tests_str else " — [ ]"
suffix = f" {extra}" if extra else ""
return f"{stop_name}{suffix}{content}"

# ── main sequence ─────────────────────────────────────────────────────────

section("Initialization")
s("LV_on")
s("HV_on")

for i in range(MAX_CYCLE + 1):
warm_name = f"warm-{i}"
extra = "(final stop)" if i == MAX_CYCLE else ""
section(section_title(warm_name, extra))
s("Heat")
s(f"Wait:{WAIT_MINUTES * 60}")
emit_stop_tests(warm_name)

if i < MAX_CYCLE:
cold_name = f"cold-{i}"
section(section_title(cold_name))
s("Cool")
s(f"Wait:{WAIT_MINUTES * 60}")
emit_stop_tests(cold_name)

return "\n".join(lines) + "\n"


if __name__ == "__main__":
content = generate()
with open(OUTPUT_FILE, "w") as f:
f.write(content)
Comment on lines +186 to +187
n_lines = content.count("\n")
print(f"Written '{OUTPUT_FILE}' ({n_lines} lines)")
2 changes: 1 addition & 1 deletion lastSession.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
session852
session1745
Loading