decode-easyae-dta 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,41 @@
1
+ # Python environments, caches and build output
2
+ __pycache__/
3
+ *.py[cod]
4
+ .venv/
5
+ venv/
6
+ build/
7
+ dist/
8
+ *.egg-info/
9
+ .pytest_cache/
10
+ .mypy_cache/
11
+ .ruff_cache/
12
+ .coverage
13
+ htmlcov/
14
+ .ipynb_checkpoints/
15
+
16
+ # Local credentials and configuration
17
+ .pypirc
18
+ .env
19
+ .env.*
20
+ !.env.example
21
+ !.env.sample
22
+ /.vscode/
23
+ /.idea/
24
+ .DS_Store
25
+ Thumbs.db
26
+
27
+ # Internal working notes and diagnostic artifacts (kept locally)
28
+ /HANDOFF.md
29
+ /AGENTS.md
30
+ /CLAUDE.md
31
+ /.agents/
32
+ /.codex/
33
+ /docs/
34
+ /diagnostics/
35
+ /reports/
36
+ /results/
37
+
38
+ # Private acquisition data; public tests use in-memory synthetic fixtures
39
+ /data/
40
+ *.[dD][tT][aA]
41
+ *.[wW][fF][sS]
@@ -0,0 +1,12 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0
4
+
5
+ - Decode configured hit features and analog parametrics from the validated
6
+ EasyAE V1.00 DTA profile, with streaming and list-based Python APIs.
7
+ - Decode time-driven and forced-sample records into timestamp/channel rows.
8
+ - Export CSV with AEwin64 column names, source filename, product/version and
9
+ the recorded test-start date.
10
+ - Provide the `decode-easyae-dta` command and retain `mistras_dta` compatibility.
11
+ - Validate against 32 paired hit exports, 32 time exports, and a separate real
12
+ two-channel acquisition. Reject unsupported calibration and schema settings.
@@ -0,0 +1,27 @@
1
+ # Contributing
2
+
3
+ Use Python 3.10 or newer. The decoder and tests need only the standard library.
4
+
5
+ ```shell
6
+ python -m pip install -e ".[dev]"
7
+ python -m unittest -v
8
+ ```
9
+
10
+ Keep the public APIs dependency-free. Preserve the original recording clock and
11
+ the physical units identified by the field names and described in the README.
12
+ Unsupported layouts must fail explicitly. Include a portable synthetic fixture
13
+ for decoder changes and compare against independent AEwin64 exports when available.
14
+ Do not commit raw DTA/WFS files, vendor manuals, credentials or personal data paths.
15
+ The optional external-data validation commands are in the README. Input files
16
+ remain read-only; generated output belongs under the ignored `results/` directory.
17
+
18
+ To check the distribution:
19
+
20
+ ```shell
21
+ python -m build
22
+ python -m twine check dist/*
23
+ ```
24
+
25
+ Internal notes, diagnostic notebooks and generated reports are local working
26
+ material excluded by `.gitignore`. Keep public usage and support information
27
+ in the README.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 UARK-NED3
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,193 @@
1
+ Metadata-Version: 2.5
2
+ Name: decode-easyae-dta
3
+ Version: 0.1.0
4
+ Summary: Decode AEwin64 / EasyAE DTA hit and time-driven data and export CSV
5
+ Project-URL: Homepage, https://github.com/spier16/decode-easyae-dta
6
+ Project-URL: Source, https://github.com/spier16/decode-easyae-dta
7
+ Project-URL: Issues, https://github.com/spier16/decode-easyae-dta/issues
8
+ Project-URL: Changelog, https://github.com/spier16/decode-easyae-dta/blob/main/CHANGELOG.md
9
+ Author: Stephen Pierson
10
+ License-Expression: MIT
11
+ License-File: LICENSE
12
+ Keywords: AEwin64,DTA,EasyAE,MISTRAS,acoustic-emission
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Environment :: Console
15
+ Classifier: Intended Audience :: Science/Research
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3 :: Only
19
+ Classifier: Topic :: Scientific/Engineering
20
+ Requires-Python: >=3.10
21
+ Provides-Extra: dev
22
+ Requires-Dist: build>=1.2; extra == 'dev'
23
+ Requires-Dist: hatchling>=1.26; extra == 'dev'
24
+ Requires-Dist: twine>=6; extra == 'dev'
25
+ Description-Content-Type: text/markdown
26
+
27
+ # decode-easyae-dta
28
+
29
+ Read hits and time-driven data directly from MISTRAS EasyAE / AEwin64 `.DTA` files using
30
+ Python 3.10 or newer and the standard library.
31
+
32
+ The EMPIRE acceptance corpus passes: **180 files, 1,056,916 decoded hits**.
33
+ All **20 columns** agree with all **32 manual AEwin64 exports**, covering
34
+ 170,345 hits and 3,406,900 values, at the exports' printed precision.
35
+
36
+ Time-data extraction also passes: **180 files, 1,705,249 decoded rows**.
37
+ All **eight columns** match all **32 manual time exports**, covering 277,656
38
+ rows and 2,221,248 values.
39
+
40
+ ## Install
41
+
42
+ ```shell
43
+ python -m pip install decode-easyae-dta
44
+ ```
45
+
46
+ From a checkout, including before the first PyPI release, use `python -m pip install .`.
47
+ The package has no runtime dependencies. It provides the `decode-easyae-dta`
48
+ command and the `decode_easyae_dta` import. Earlier `mistras_dta` imports and
49
+ `python mistras_dta.py ...` commands remain compatible.
50
+
51
+ ## Read hits
52
+
53
+ ```python
54
+ from decode_easyae_dta import read_hits, iter_hits
55
+
56
+ hits = read_hits(r"C:\path\to\experiment.DTA")
57
+ print(len(hits), hits[0])
58
+
59
+ # Stream larger recordings; exhaust the iterator to validate the whole file.
60
+ for hit in iter_hits(r"C:\path\to\experiment.DTA"):
61
+ amplitude = hit["amplitude_db"]
62
+ ```
63
+
64
+ Both `read_hits()` and `read_time_data()` return **lists of dictionaries**, not
65
+ NumPy arrays or pandas DataFrames. Their `iter_` variants yield dictionaries one
66
+ at a time. For optional pandas use, call `pd.DataFrame(read_hits(path))`.
67
+
68
+ Each hit is a dictionary containing `id` (message type 1), `time_s` (relative
69
+ to the recording clock), `channel`, the configured features in physical units,
70
+ and `parametric_1` etc. Parametrics are volts under the supported unity-scaling
71
+ profile. Feature keys identify units: `_us` for microseconds, `_khz` for kHz,
72
+ `_db` for dB, `_v` for volts, `_pvs` for pVs and `_aj` for aJ. Counts and
73
+ `energy` retain instrument counts. Hits retain file order.
74
+
75
+ ## Extract CSV
76
+
77
+ ```powershell
78
+ decode-easyae-dta 'C:\path\to\experiment.DTA' --output results/experiment_hits.csv
79
+
80
+ # Extract the time data instead:
81
+ decode-easyae-dta 'C:\path\to\experiment.DTA' --kind time --output results/experiment_time.csv
82
+ ```
83
+
84
+ The command validates the input before creating the CSV, preserves numeric
85
+ precision, and requires a new output filename. CSV headings and column order match
86
+ the AEwin64 exports, including `PARA1`, `SIG STRNGTH`, and `R-FRQ`.
87
+
88
+ Each CSV starts with four metadata rows and a blank line:
89
+
90
+ ```csv
91
+ Source File,C:\path\to\experiment.DTA
92
+ Product,EasyAE (r) Location Version
93
+ Version,V1.00
94
+ Test Start,Mon Oct 26 11:33:41 2026
95
+
96
+ ID,SSSSSSSS.mmmuuun,PARA1,CH,...
97
+ ```
98
+
99
+ The product/version come from binary message ID 41; the test-start text comes
100
+ from ID 99. The source path is the current input file's absolute path. The stored
101
+ test time has no timezone, and missing metadata is shown as `Not recorded`.
102
+ Use `--no-metadata` for a CSV beginning directly with the data column headings.
103
+ For pandas, read the default CSV using `pd.read_csv(path, skiprows=5)`.
104
+
105
+ Metadata is also available separately in Python:
106
+
107
+ ```python
108
+ from decode_easyae_dta import read_metadata
109
+
110
+ metadata = read_metadata(r"C:\path\to\experiment.DTA")
111
+ print(metadata.source_file, metadata.test_start)
112
+ ```
113
+
114
+ ## Read time data
115
+
116
+ ```python
117
+ from decode_easyae_dta import read_time_data, iter_time_data, write_time_csv, read_metadata
118
+
119
+ path = r"C:\path\to\experiment.DTA"
120
+ rows = read_time_data(path)
121
+ print(len(rows), rows[0])
122
+
123
+ with open("experiment_time.csv", "x", encoding="utf-8", newline="") as stream:
124
+ write_time_csv(rows, stream, metadata=read_metadata(path))
125
+ ```
126
+
127
+ The time CSV uses `ID,SSSSSSSS.mmmuuun,PARA1,CH,RMS,THR,ABS-ENERGY,ASL`
128
+ for this corpus. AEwin64's text exports place the channel values in a separate
129
+ bracketed block below each timestamp. The CSV flattens that block into one row
130
+ per timestamp and channel, repeating timestamp and parametric values across
131
+ channels. The corpus uses one channel. Numeric values retain full decoded
132
+ precision; timestamps use the recording clock, as in the hit CSV.
133
+
134
+ Python rows use the same descriptive keys and physical units as hits:
135
+ `time_s`, `parametric_1`, `channel`, `rms_v`, `threshold_db`,
136
+ `absolute_energy_aj`, `asl_db`, and `id` (2 for time-driven records).
137
+ `iter_time_data(path)` streams these rows. Manufacturer-documented ID 3 sample
138
+ records use the same layout and retain ID 3; none occur in this corpus.
139
+
140
+ ## Validate
141
+
142
+ ```powershell
143
+ python -m unittest -v
144
+ $env:EMPIRE_AE_DATA = 'C:\path\to\EMPIRE_acoustic_tests'
145
+ python validate_mistras_dta.py "$env:EMPIRE_AE_DATA" --output results/empire_hit_validation.json
146
+ python validate_mistras_dta.py "$env:EMPIRE_AE_DATA" --kind time --output results/empire_time_validation.json
147
+
148
+ # Or compare a single pair:
149
+ python validate_mistras_dta.py 'C:\path\to\experiment.DTA' --export 'C:\path\to\experiment_hits.TXT'
150
+ python validate_mistras_dta.py 'C:\path\to\experiment.DTA' --kind time --export 'C:\path\to\experiment_time.TXT'
151
+ ```
152
+
153
+ The corpus command visits numbered `EMPIRE_acoustic_<number>` folders, excluding
154
+ `misc`. It reads every DTA, compares every column in every corresponding
155
+ `<DTA stem>_hits.txt` export (or `_time.txt` with `--kind time`), and writes a
156
+ report outside the raw-data directory.
157
+ The acquisition corpus and generated reports are kept locally and are not
158
+ included in the public repository or package.
159
+ Counts and integer features must agree exactly; other values must agree within
160
+ half the last printed decimal place. Failures produce a nonzero exit status.
161
+ The comparator checks schema equality and treats `SIG STRNGTH` as one column.
162
+
163
+ The earlier framing-only survey remains available:
164
+
165
+ ```powershell
166
+ python survey_mistras_dta.py "$env:EMPIRE_AE_DATA" --output results/empire_dta_survey.json
167
+ ```
168
+
169
+ ## Supported scope
170
+
171
+ This reader supports the **EasyAE V1.00 profile and calibration/scaling metadata
172
+ verified in the EMPIRE corpus**. It reads the configured feature order and checks
173
+ the product, hardware version, preamp/gain, channel calibration and parametric
174
+ scaling records. Unsupported characteristics or calibration settings raise
175
+ `DtaFormatError`, including byte offsets. General custom multiplier/offset
176
+ decoding remains unimplemented; the verified unity-scaling record is recognized
177
+ as a whole. Agreement at export precision does not establish extra digits of
178
+ parametric calibration accuracy.
179
+
180
+ Start markers are optional; the extra control byte is safely framed. Unknown
181
+ message IDs are skipped using declared boundaries. Waveforms,
182
+ continued-file setup and other instrument profiles are outside this milestone.
183
+ Time-data characteristics are restricted to the verified THR, RMS, ABS-ENERGY
184
+ and ASL encodings. Custom parametric scaling and cycle counters are unsupported.
185
+ Two-channel decoding also matches a separate real dual-sensor acquisition's
186
+ hit and time exports.
187
+ Multiple analog parametrics, schema updates, and ID 3 have synthetic coverage
188
+ only. The real time exports exercise PARA1.
189
+
190
+ Raw binaries, TXT exports and the vendor manual stay external to this repository.
191
+ The project uses the MIT license in [LICENSE](https://github.com/spier16/decode-easyae-dta/blob/main/LICENSE).
192
+ For development, see [CONTRIBUTING.md](https://github.com/spier16/decode-easyae-dta/blob/main/CONTRIBUTING.md). The separate
193
+ [decode-wfs](https://github.com/spier16/decode-wfs) project decodes waveform streams.
@@ -0,0 +1,167 @@
1
+ # decode-easyae-dta
2
+
3
+ Read hits and time-driven data directly from MISTRAS EasyAE / AEwin64 `.DTA` files using
4
+ Python 3.10 or newer and the standard library.
5
+
6
+ The EMPIRE acceptance corpus passes: **180 files, 1,056,916 decoded hits**.
7
+ All **20 columns** agree with all **32 manual AEwin64 exports**, covering
8
+ 170,345 hits and 3,406,900 values, at the exports' printed precision.
9
+
10
+ Time-data extraction also passes: **180 files, 1,705,249 decoded rows**.
11
+ All **eight columns** match all **32 manual time exports**, covering 277,656
12
+ rows and 2,221,248 values.
13
+
14
+ ## Install
15
+
16
+ ```shell
17
+ python -m pip install decode-easyae-dta
18
+ ```
19
+
20
+ From a checkout, including before the first PyPI release, use `python -m pip install .`.
21
+ The package has no runtime dependencies. It provides the `decode-easyae-dta`
22
+ command and the `decode_easyae_dta` import. Earlier `mistras_dta` imports and
23
+ `python mistras_dta.py ...` commands remain compatible.
24
+
25
+ ## Read hits
26
+
27
+ ```python
28
+ from decode_easyae_dta import read_hits, iter_hits
29
+
30
+ hits = read_hits(r"C:\path\to\experiment.DTA")
31
+ print(len(hits), hits[0])
32
+
33
+ # Stream larger recordings; exhaust the iterator to validate the whole file.
34
+ for hit in iter_hits(r"C:\path\to\experiment.DTA"):
35
+ amplitude = hit["amplitude_db"]
36
+ ```
37
+
38
+ Both `read_hits()` and `read_time_data()` return **lists of dictionaries**, not
39
+ NumPy arrays or pandas DataFrames. Their `iter_` variants yield dictionaries one
40
+ at a time. For optional pandas use, call `pd.DataFrame(read_hits(path))`.
41
+
42
+ Each hit is a dictionary containing `id` (message type 1), `time_s` (relative
43
+ to the recording clock), `channel`, the configured features in physical units,
44
+ and `parametric_1` etc. Parametrics are volts under the supported unity-scaling
45
+ profile. Feature keys identify units: `_us` for microseconds, `_khz` for kHz,
46
+ `_db` for dB, `_v` for volts, `_pvs` for pVs and `_aj` for aJ. Counts and
47
+ `energy` retain instrument counts. Hits retain file order.
48
+
49
+ ## Extract CSV
50
+
51
+ ```powershell
52
+ decode-easyae-dta 'C:\path\to\experiment.DTA' --output results/experiment_hits.csv
53
+
54
+ # Extract the time data instead:
55
+ decode-easyae-dta 'C:\path\to\experiment.DTA' --kind time --output results/experiment_time.csv
56
+ ```
57
+
58
+ The command validates the input before creating the CSV, preserves numeric
59
+ precision, and requires a new output filename. CSV headings and column order match
60
+ the AEwin64 exports, including `PARA1`, `SIG STRNGTH`, and `R-FRQ`.
61
+
62
+ Each CSV starts with four metadata rows and a blank line:
63
+
64
+ ```csv
65
+ Source File,C:\path\to\experiment.DTA
66
+ Product,EasyAE (r) Location Version
67
+ Version,V1.00
68
+ Test Start,Mon Oct 26 11:33:41 2026
69
+
70
+ ID,SSSSSSSS.mmmuuun,PARA1,CH,...
71
+ ```
72
+
73
+ The product/version come from binary message ID 41; the test-start text comes
74
+ from ID 99. The source path is the current input file's absolute path. The stored
75
+ test time has no timezone, and missing metadata is shown as `Not recorded`.
76
+ Use `--no-metadata` for a CSV beginning directly with the data column headings.
77
+ For pandas, read the default CSV using `pd.read_csv(path, skiprows=5)`.
78
+
79
+ Metadata is also available separately in Python:
80
+
81
+ ```python
82
+ from decode_easyae_dta import read_metadata
83
+
84
+ metadata = read_metadata(r"C:\path\to\experiment.DTA")
85
+ print(metadata.source_file, metadata.test_start)
86
+ ```
87
+
88
+ ## Read time data
89
+
90
+ ```python
91
+ from decode_easyae_dta import read_time_data, iter_time_data, write_time_csv, read_metadata
92
+
93
+ path = r"C:\path\to\experiment.DTA"
94
+ rows = read_time_data(path)
95
+ print(len(rows), rows[0])
96
+
97
+ with open("experiment_time.csv", "x", encoding="utf-8", newline="") as stream:
98
+ write_time_csv(rows, stream, metadata=read_metadata(path))
99
+ ```
100
+
101
+ The time CSV uses `ID,SSSSSSSS.mmmuuun,PARA1,CH,RMS,THR,ABS-ENERGY,ASL`
102
+ for this corpus. AEwin64's text exports place the channel values in a separate
103
+ bracketed block below each timestamp. The CSV flattens that block into one row
104
+ per timestamp and channel, repeating timestamp and parametric values across
105
+ channels. The corpus uses one channel. Numeric values retain full decoded
106
+ precision; timestamps use the recording clock, as in the hit CSV.
107
+
108
+ Python rows use the same descriptive keys and physical units as hits:
109
+ `time_s`, `parametric_1`, `channel`, `rms_v`, `threshold_db`,
110
+ `absolute_energy_aj`, `asl_db`, and `id` (2 for time-driven records).
111
+ `iter_time_data(path)` streams these rows. Manufacturer-documented ID 3 sample
112
+ records use the same layout and retain ID 3; none occur in this corpus.
113
+
114
+ ## Validate
115
+
116
+ ```powershell
117
+ python -m unittest -v
118
+ $env:EMPIRE_AE_DATA = 'C:\path\to\EMPIRE_acoustic_tests'
119
+ python validate_mistras_dta.py "$env:EMPIRE_AE_DATA" --output results/empire_hit_validation.json
120
+ python validate_mistras_dta.py "$env:EMPIRE_AE_DATA" --kind time --output results/empire_time_validation.json
121
+
122
+ # Or compare a single pair:
123
+ python validate_mistras_dta.py 'C:\path\to\experiment.DTA' --export 'C:\path\to\experiment_hits.TXT'
124
+ python validate_mistras_dta.py 'C:\path\to\experiment.DTA' --kind time --export 'C:\path\to\experiment_time.TXT'
125
+ ```
126
+
127
+ The corpus command visits numbered `EMPIRE_acoustic_<number>` folders, excluding
128
+ `misc`. It reads every DTA, compares every column in every corresponding
129
+ `<DTA stem>_hits.txt` export (or `_time.txt` with `--kind time`), and writes a
130
+ report outside the raw-data directory.
131
+ The acquisition corpus and generated reports are kept locally and are not
132
+ included in the public repository or package.
133
+ Counts and integer features must agree exactly; other values must agree within
134
+ half the last printed decimal place. Failures produce a nonzero exit status.
135
+ The comparator checks schema equality and treats `SIG STRNGTH` as one column.
136
+
137
+ The earlier framing-only survey remains available:
138
+
139
+ ```powershell
140
+ python survey_mistras_dta.py "$env:EMPIRE_AE_DATA" --output results/empire_dta_survey.json
141
+ ```
142
+
143
+ ## Supported scope
144
+
145
+ This reader supports the **EasyAE V1.00 profile and calibration/scaling metadata
146
+ verified in the EMPIRE corpus**. It reads the configured feature order and checks
147
+ the product, hardware version, preamp/gain, channel calibration and parametric
148
+ scaling records. Unsupported characteristics or calibration settings raise
149
+ `DtaFormatError`, including byte offsets. General custom multiplier/offset
150
+ decoding remains unimplemented; the verified unity-scaling record is recognized
151
+ as a whole. Agreement at export precision does not establish extra digits of
152
+ parametric calibration accuracy.
153
+
154
+ Start markers are optional; the extra control byte is safely framed. Unknown
155
+ message IDs are skipped using declared boundaries. Waveforms,
156
+ continued-file setup and other instrument profiles are outside this milestone.
157
+ Time-data characteristics are restricted to the verified THR, RMS, ABS-ENERGY
158
+ and ASL encodings. Custom parametric scaling and cycle counters are unsupported.
159
+ Two-channel decoding also matches a separate real dual-sensor acquisition's
160
+ hit and time exports.
161
+ Multiple analog parametrics, schema updates, and ID 3 have synthetic coverage
162
+ only. The real time exports exercise PARA1.
163
+
164
+ Raw binaries, TXT exports and the vendor manual stay external to this repository.
165
+ The project uses the MIT license in [LICENSE](https://github.com/spier16/decode-easyae-dta/blob/main/LICENSE).
166
+ For development, see [CONTRIBUTING.md](https://github.com/spier16/decode-easyae-dta/blob/main/CONTRIBUTING.md). The separate
167
+ [decode-wfs](https://github.com/spier16/decode-wfs) project decodes waveform streams.