Author: Ifra Ilyas Ansari
Created: 2025-10-15
Updated: 2025-11-11
This repository contains a set of Python scripts for processing, analyzing, and plotting voltage transient data from Tektronix oscilloscopes. The pipeline is broken into modular stages to handle pulse detection, data alignment, voltage extraction, and metadata merging.
This pipeline requires the following Python libraries. You can install them using pip:
pandasnumpymatplotlibrich(for optional folder tree previews)openpyxl(for readingMetadata.xlsx)
Tested on Python 3.10β3.11 (macOS/Windows).
# (recommended) create a virtual environment
python -m venv .venv && source .venv/bin/activate # on Windows: .venv\Scripts\activate
# install dependencies
pip install -r requirements.txt
- Stages:
VT_Processor_Py_Stage1_PulseDetector: v3.6.4VT_Processor_Py_Stage2_VoltageSelector: v1.7.0VT_Processor_Py_BatchPlotter: v1.2.3
- Modules:
VT_Module_Py_GlobalSettings: v1.1.0VT_Module_Py_System: v1.0.2VT_Module_Py_DataIO: v1.2.0VT_Module_Py_Processing: v1.0.0VT_Module_Py_PlotHelpers: v1.0.1VT_Module_Py_UserInput: v1.0.1
- Prepare Input Files:
- Place all your raw Tektronix
.CSVfiles (e.g.,TEK00001.CSV,TEK00002.CSV) in a single data folder. - In that same folder, create and populate a
Metadata.xlsxfile. (See "Input File Formats" below for details).
- Place all your raw Tektronix
- Run Stage 1:
- Execute
VT_Processor_Py_Stage1_PulseDetector.py. - When prompted, select all the
.CSVfiles from your data folder. - This stage will auto-detect pulses, correct baseline drift, and save a
...wAutoOffset.pklfile inside a newVT_Py_Outputssubfolder.
- Execute
- Run Stage 2:
- Execute
VT_Processor_Py_Stage2_VoltageSelector.py. - When prompted, select the
PyPD_Dictionary_AllDataFiles_wAutoOffset.pklfile generated by Stage 1. - This stage will read your
Metadata.xlsxsnapshot to auto-calculate time points (t1-t5).
- Execute
- Interactive Validation:
- For each file, Stage 2 will show you a plot with the auto-detected points.
- In your terminal, press [Enter] to accept the points or type in 5 new comma-separated values to adjust them.
- Close the plot window to proceed to the next file.
- Get Results:
- Once complete, find your final, merged data in
.../VT_Py_Outputs/VT_Py_Outputs_VoltageSelector.../PyVS_VoltageSummary_Final.CSV.
- Once complete, find your final, merged data in
This pipeline processes voltage transient data in two main stages, with an optional plotting utility.
-
Stage 1: Pulse Detector (
VT_Processor_Py_Stage1_PulseDetector.py)- Input: Raw
TEK...csvfiles. - Action:
- Loads and standardizes each CSV.
- Auto-detects the primary biphasic pulse in the current trace.
- Calculates and applies a baseline correction (Y-offset) based on the pre-pulse region.
- Aligns all pulses to a common start time (X-offset).
- Finds and saves a snapshot of
Metadata.xlsxfrom the same folder.
- Output: A
.pkldictionary (PyPD_Dictionary_AllDataFiles_wAutoOffset.pkl) containing a clean, aligned DataFrame for each file.
- Input: Raw
-
Stage 2: Voltage Selector (
VT_Processor_Py_Stage2_VoltageSelector.py)- Input: The
.pklfile from Stage 1 and thePyPD_Metadata_Snapshot.CSVit created. - Action:
- Reads
PhaseWidth(Β΅s)andInterphaseDelay(Β΅s)from the metadata. - Uses these values to auto-calculate 5 time points (t1-t5) for voltage extraction.
- Enters an interactive loop for the user to validate or manually correct these 5 points for each trace.
- Extracts the final V/I values at the validated points (with a special local-minimum search for V3).
- Reads
- Output: The final summary table (
PyVS_VoltageSummary_Final.CSV), which merges your original metadata with all the new calculated voltage values (V1-V5, ΞV, etc.).
- Input: The
-
Utility: Batch Plotter (
VT_Processor_Py_BatchPlotter_v1.2.3.py)- This is a separate tool for creating comparison plots. It loads raw CSVs, allows you to apply manual time offsets (via the terminal), and overlays all traces on a single set of V/I plots.
These are the raw data files exported directly from the Tektronix oscilloscope.
- Header: The script assumes a standard Tektronix header and skips the first 15 rows by default (see
skip_rows=15inStage1). - Columns: The script does not rely on fixed column positions. Instead, it auto-detects the necessary columns by searching for common names (aliases).
- Time: Searches for
Time(s),Time (Β΅s),T (ms), etc., and converts to microseconds (Β΅s). - Voltage: Searches for
Voltage(V),V,CH1, etc. - Current: Searches for
Current(A),I,CH2, etc.
- Time: Searches for
- Channel Map: The default mapping is
VOLTAGE: "CH1"andCURRENT: "CH2". This can be changed inVT_Module_Py_GlobalSettings.py.
This single Excel file must be in the same directory as the raw .CSV files. It provides experimental context and parameters for processing.
FileID(Required): This column is the join key. It must contain the base filename of the corresponding data file (e.g.,TEK00001,TEK00002).- Stage 2 Calculation Columns (Required):
PhaseWidth(Β΅s): User-defined. This value is read by Stage 2 to auto-calculate the initialt3(Vc peak) andt4(Emc) time points.InterphaseDelay(Β΅s): User-defined. This value is read by Stage 2 to auto-calculate the initialt5(E IPend) time point.
- User-Defined Info Columns (Recommended):
- These columns are read, ignored during calculation, and merged directly into the final
PyVS_VoltageSummary_Final.CSVfor complete documentation. - Examples:
Date,WaferID,DeviceID,ElectrodeID,Electrolyte,Current(Β΅A), etc.
- These columns are read, ignored during calculation, and merged directly into the final
TotalPulses(Informational):- This is a user-defined column. You should enter the total number of pulses for your reference (e.g., from a pulse counter).
- The scripts do not use this value for any calculations. It is simply loaded and carried through to the final summary file for your records.
All scripts import their settings from the VT_Module_... files. The most important one is VT_Module_Py_GlobalSettings.py.
If your data is not loading or your plots look wrong, you probably need to edit this file:
- To swap Voltage/Current channels: Change
DICT_TEK_CHANNEL_MAP.# e.g., if Voltage is on CH2 and Current is on CH1 DICT_TEK_CHANNEL_MAP = { "VOLTAGE": "CH2", "CURRENT": "CH1", }
- To change plot appearance: Edit the
rcParams.update({...})dictionary to change fonts, line widths, and figure sizes.
The entire pipeline is designed to generate one primary file:
PyVS_VoltageSummary_Final.CSV- Location:
.../VT_Py_Outputs/VT_Py_Outputs_VoltageSelector_[timestamp]/ - Contents: This is the main result. It is a single CSV file containing all columns from your original
Metadata.xlsxplus all the new calculated voltage columns (e.g.,Eipp (V1),Vc peak (V3),ΞV (V3-V1), etc.) for every processed file.
- Location:
Other important intermediate files include:
PyPD_Dictionary_AllDataFiles_wAutoOffset.pkl(from Stage 1)- This is the primary input for Stage 2. It's a Python pickle file containing a dictionary where each key is a
FileIDand each value is a fully cleaned, baseline-corrected, and time-aligned DataFrame.
- This is the primary input for Stage 2. It's a Python pickle file containing a dictionary where each key is a
PyPD_Metadata_Snapshot.CSV(from Stage 1)- This is a snapshot of your
Metadata.xlsxfile, saved into the Stage 1 output folder. Stage 2 reads this file (not your original Excel) to ensure reproducibility.
- This is a snapshot of your
NeuroEng-Voltage-Transient-Processor/
βββ README.md
βββ LICENSE.txt
β
βββ VT_Processor.html
βββ __init__.py
β
βββ VT_Processor_Py_Stage1_PulseDetector.py
βββ VT_Processor_Py_Stage2_VoltageSelector.py
βββ VT_Processor_Py_BatchPlotter.py
β
βββ VT_Module_Py_GlobalSettings.py
βββ VT_Module_Py_Paths.py
βββ VT_Module_Py_Utilities.py
βββ VT_Module_Py_PulseAlgorithm.py
βββ VT_Module_Py_PlotHelpers.py
β
βββ test_global_settings.py
β
βββ π Example_Data_Files/
βββ π Metadata_Template.csv
βββ π Metadata.csv
βββ π TEK00001.CSV
βββ π TEK00002.CSV
βββ π TEK00003.CSV
βββ π TEK00004.CSV
βββ π TEK00005.CSV ... TEK000xx.CSV
βββ π VT_Py_Outputs/
βββ π VT_Py_Outputs_PulseDetector_YYYYMMDD_HHMM/
βββ π VT_Py_Outputs_VoltageSelector_YYYYMMDD_HHMM/
βββ π VT_Py_Outputs_BatchPlotter_YYYYMMDD_HHMM/
βββ π VT_Py_Outputs/
βββ π VT_Py_Outputs_PulseDetector_YYYYMMDD_HHMM
β βββ π PyPD_Summary.txt
β βββ π PyPD_Summary.json
β βββ π PyPD_Dictionary_AllDataFiles_wAutoOffset.pkl
β β
β βββ π PyPD_ProcessedDataFiles/
β βββ π PyPD_CSV_Files/
β β βββ π PyPD_TEK0001_AutoOffset.csv
β β βββ π PyPD_TEK0002_AutoOffset.csv
β β βββ ...
β β
β βββ π PyPD_PNG_Files/
β β βββ πΌοΈ PyPD_TEK0001_AutoOffset.png
β β βββ πΌοΈ PyPD_TEK0002_AutoOffset.png
β β βββ ...
β β
β βββ π PyPD_ExtraInfo_Files/
β βββ π PyPD_Dictionary_AllDataFiles_wAutoDetected.pkl
β βββ π PyPD_Dictionary_AllDataFiles_wRawTimeΒ΅s.pkl
β βββ π PyPD_TEK0001_RawTimeΒ΅s.csv
β βββ π PyPD_TEK0001_Detected.csv
β βββ ...
β
βββ π VT_Py_Outputs_VoltageSelector_YYYYMMDD_HHMM
β βββ π PyVS_VoltageSummary_Final.CSV
β βββ π PyVS_Dictionary_AllDataFiles_SelectedVals.pkl
β βββ π PyVS_Summary.txt
β βββ π PyVS_Summary.json
β β
β βββ π PyVS_ProcessedDataFiles/
β βββ π PyVS_CSV_Files/
β β βββ π PyVS_TEK0001_SelectedVals.csv
β β βββ π PyVS_Metadata_Input.CSV
β β βββ π PyVS_VoltageSummary_CalculatedVals.CSV
β β βββ ...
β β
β βββ π PyVS_PNG_Files/
β βββ πΌοΈ PyVS_TEK0001_SelectedVals_wOverlay.png
β βββ πΌοΈ PyVS_TEK0002_SelectedVals_wOverlay.png
β βββ ...
β
βββ π VT_Py_Outputs_BatchPlotter_YYYYMMDD_HHMM
βββ π PyBP_Summary.txt
βββ π PyBP_Summary.json
βββ π PyBP_Dictionary_AllDataFiles_Processed.pkl
β
βββ π PyBP_ProcessedDataFiles/
βββ π PyBP_CSV_Files/
β βββ π PyBP_TEK00001_UserOffset.csv
β βββ π PyBP_TEK00002_Raw.csv
β βββ ...
β
βββ π PyBP_PNG_Files/
β βββ πΌοΈ PyBP_Current_wBatchPlot_{custom_suffix}.png
β βββ πΌοΈ PyBP_Voltage_wBatchPlot_{custom_suffix}.png
β βββ ...
β
βββ π PyBP_SVG_Files/
βββ π PyBP_Current_wBatchPlot_{custom_suffix}.svg
βββ π PyBP_Voltage_wBatchPlot_{custom_suffix}.svg
βββ ...