saclay-format 0.2.1__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.
- saclay_format-0.2.1/PKG-INFO +114 -0
- saclay_format-0.2.1/README.md +97 -0
- saclay_format-0.2.1/pyproject.toml +17 -0
- saclay_format-0.2.1/setup.cfg +4 -0
- saclay_format-0.2.1/src/saclay_format/ev1_to_cr1.py +237 -0
- saclay_format-0.2.1/src/saclay_format/ev8_to_ev1.py +315 -0
- saclay_format-0.2.1/src/saclay_format/hdf5_yaml_converter.py +99 -0
- saclay_format-0.2.1/src/saclay_format/saclay_parser.py +293 -0
- saclay_format-0.2.1/src/saclay_format/visualisation_rho.py +161 -0
- saclay_format-0.2.1/src/saclay_format/visualisation_rho_TD.py +209 -0
- saclay_format-0.2.1/src/saclay_format.egg-info/PKG-INFO +114 -0
- saclay_format-0.2.1/src/saclay_format.egg-info/SOURCES.txt +14 -0
- saclay_format-0.2.1/src/saclay_format.egg-info/dependency_links.txt +1 -0
- saclay_format-0.2.1/src/saclay_format.egg-info/requires.txt +9 -0
- saclay_format-0.2.1/src/saclay_format.egg-info/top_level.txt +1 -0
- saclay_format-0.2.1/tests/test_saclay_format.py +233 -0
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: saclay-format
|
|
3
|
+
Version: 0.2.1
|
|
4
|
+
Summary: python parser and usefull script related to the saclay format
|
|
5
|
+
Maintainer-email: Guillaume Scamps <guillaume.scamps@l2it.in2p3.fr>, David Regnier <David.REGNIER@cea.fr>, Wouter Ryssens <Wouter.Ryssens@ulb.be>
|
|
6
|
+
Project-URL: Sources, https://gitlab.com/regnier/Saclay_format
|
|
7
|
+
Requires-Python: >=3.10
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
Requires-Dist: h5py
|
|
10
|
+
Requires-Dist: numpy
|
|
11
|
+
Requires-Dist: pyyaml
|
|
12
|
+
Provides-Extra: visu
|
|
13
|
+
Requires-Dist: matplotlib; extra == "visu"
|
|
14
|
+
Requires-Dist: PyQt5; extra == "visu"
|
|
15
|
+
Requires-Dist: scipy; extra == "visu"
|
|
16
|
+
Requires-Dist: scikit-image; extra == "visu"
|
|
17
|
+
|
|
18
|
+
# Saclay_format (v0.2.1)
|
|
19
|
+
|
|
20
|
+
This repository contains a proposal format definition to exchange inputs/outputs
|
|
21
|
+
between some mean-field theory codes in the nuclear physics and astrophysics communities.
|
|
22
|
+
This format relies on a series of custom binary files containing the raw data along with
|
|
23
|
+
a YAML header containing metadata. It adheres to the results of the 05/2025 and 10/2025 ESNT
|
|
24
|
+
workshops entitled *"Simulating dense matter on three-dimensional coordinate space meshes (part I and II)"*.
|
|
25
|
+
|
|
26
|
+
## Content
|
|
27
|
+
|
|
28
|
+
* `saclay_format` — Python3 package to parse and visualize this format
|
|
29
|
+
* `docs` — documentation of the format (not yet up to date)
|
|
30
|
+
* `examples` — nuclear mean-field outputs in this format
|
|
31
|
+
* `tests` — unit tests of the package (not yet up to date)
|
|
32
|
+
|
|
33
|
+
## Requirements
|
|
34
|
+
|
|
35
|
+
* `pyyaml` — Python3 package for YAML parsing
|
|
36
|
+
* `h5py` — Python3 package for HDF5 parsing
|
|
37
|
+
|
|
38
|
+
## Running the parser
|
|
39
|
+
|
|
40
|
+
From a Python terminal, import the `parser` module and use its `read()` and `write()` methods.
|
|
41
|
+
To see the expected structure of the data dictionary, check the
|
|
42
|
+
`create_dummy_data()` function in `tests/test_saclay_format.py`.
|
|
43
|
+
|
|
44
|
+
Example:
|
|
45
|
+
```bash
|
|
46
|
+
cd tests/
|
|
47
|
+
python3 test_saclay_format.py
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Examples
|
|
51
|
+
|
|
52
|
+
### Example structure
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
examples/20Ne_bcs/
|
|
56
|
+
├── 20Ne_rho_n.wdat
|
|
57
|
+
├── 20Ne_state
|
|
58
|
+
├── 20Ne.h5
|
|
59
|
+
├── 20Ne.yaml
|
|
60
|
+
└── README.md
|
|
61
|
+
|
|
62
|
+
examples/alpha_alpha_3MeV/
|
|
63
|
+
├── reaction_alpha_alpha_3MeV_header.yml
|
|
64
|
+
├── reaction_alpha_alpha_3MeV_rho_n.bin
|
|
65
|
+
├── reaction_alpha_alpha_3MeV_rho_p.bin
|
|
66
|
+
├── README_visualisation_convert.md
|
|
67
|
+
└── script_test.convert.sh
|
|
68
|
+
|
|
69
|
+
examples/Ca40_ev8/
|
|
70
|
+
├── Ca40_HF_SLy4.yaml
|
|
71
|
+
├── Ca40_HF_SLy4_*.dat
|
|
72
|
+
└── README_test.md
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Conversion test
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
python3 ../../saclay_format/hdf5_yaml_converter.py -h5 Ca40_HF_SLy4.yaml
|
|
79
|
+
python3 ../../saclay_format/ev8_to_ev1.py Ca40_HF_SLy4.h5 -o Ca40_HF_SLy4_ev1.h5
|
|
80
|
+
python3 ../../saclay_format/ev1_to_cr1.py Ca40_HF_SLy4_ev1.h5 -o Ca40_HF_SLy4_cr1.h5
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Visualization test
|
|
84
|
+
|
|
85
|
+
Static:
|
|
86
|
+
```bash
|
|
87
|
+
python3 ../../saclay_format/visualisation_rho.py reaction_alpha_alpha_3MeV_header.yml
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Dynamic:
|
|
91
|
+
```bash
|
|
92
|
+
python3 ../../saclay_format/visualisation_rho_TD.py -H reaction_alpha_alpha_3MeV_header.yml
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Conversion and round-trip test:
|
|
96
|
+
```bash
|
|
97
|
+
python3 ../../saclay_format/hdf5_yaml_converter.py -h5 reaction_alpha_alpha_3MeV_header.yml
|
|
98
|
+
mv reaction_alpha_alpha_3MeV_header.h5 reaction_alpha_alpha_3MeV_converted.h5
|
|
99
|
+
python3 ../../saclay_format/visualisation_rho_TD.py reaction_alpha_alpha_3MeV_converted.h5
|
|
100
|
+
python3 ../../saclay_format/hdf5_yaml_converter.py -yaml reaction_alpha_alpha_3MeV_converted.h5
|
|
101
|
+
python3 ../../saclay_format/visualisation_rho_TD.py reaction_alpha_alpha_3MeV_converted.yaml
|
|
102
|
+
rm reaction_alpha_alpha_3MeV_converted*
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Todo
|
|
106
|
+
|
|
107
|
+
- Test the format
|
|
108
|
+
- Add documentation
|
|
109
|
+
- Update unit tests
|
|
110
|
+
|
|
111
|
+
## Project layout
|
|
112
|
+
|
|
113
|
+
This project follows the structure recommended by the Hitchhiker’s Guide to Python:
|
|
114
|
+
[https://docs.python-guide.org/writing/structure](https://docs.python-guide.org/writing/structure)
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# Saclay_format (v0.2.1)
|
|
2
|
+
|
|
3
|
+
This repository contains a proposal format definition to exchange inputs/outputs
|
|
4
|
+
between some mean-field theory codes in the nuclear physics and astrophysics communities.
|
|
5
|
+
This format relies on a series of custom binary files containing the raw data along with
|
|
6
|
+
a YAML header containing metadata. It adheres to the results of the 05/2025 and 10/2025 ESNT
|
|
7
|
+
workshops entitled *"Simulating dense matter on three-dimensional coordinate space meshes (part I and II)"*.
|
|
8
|
+
|
|
9
|
+
## Content
|
|
10
|
+
|
|
11
|
+
* `saclay_format` — Python3 package to parse and visualize this format
|
|
12
|
+
* `docs` — documentation of the format (not yet up to date)
|
|
13
|
+
* `examples` — nuclear mean-field outputs in this format
|
|
14
|
+
* `tests` — unit tests of the package (not yet up to date)
|
|
15
|
+
|
|
16
|
+
## Requirements
|
|
17
|
+
|
|
18
|
+
* `pyyaml` — Python3 package for YAML parsing
|
|
19
|
+
* `h5py` — Python3 package for HDF5 parsing
|
|
20
|
+
|
|
21
|
+
## Running the parser
|
|
22
|
+
|
|
23
|
+
From a Python terminal, import the `parser` module and use its `read()` and `write()` methods.
|
|
24
|
+
To see the expected structure of the data dictionary, check the
|
|
25
|
+
`create_dummy_data()` function in `tests/test_saclay_format.py`.
|
|
26
|
+
|
|
27
|
+
Example:
|
|
28
|
+
```bash
|
|
29
|
+
cd tests/
|
|
30
|
+
python3 test_saclay_format.py
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Examples
|
|
34
|
+
|
|
35
|
+
### Example structure
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
examples/20Ne_bcs/
|
|
39
|
+
├── 20Ne_rho_n.wdat
|
|
40
|
+
├── 20Ne_state
|
|
41
|
+
├── 20Ne.h5
|
|
42
|
+
├── 20Ne.yaml
|
|
43
|
+
└── README.md
|
|
44
|
+
|
|
45
|
+
examples/alpha_alpha_3MeV/
|
|
46
|
+
├── reaction_alpha_alpha_3MeV_header.yml
|
|
47
|
+
├── reaction_alpha_alpha_3MeV_rho_n.bin
|
|
48
|
+
├── reaction_alpha_alpha_3MeV_rho_p.bin
|
|
49
|
+
├── README_visualisation_convert.md
|
|
50
|
+
└── script_test.convert.sh
|
|
51
|
+
|
|
52
|
+
examples/Ca40_ev8/
|
|
53
|
+
├── Ca40_HF_SLy4.yaml
|
|
54
|
+
├── Ca40_HF_SLy4_*.dat
|
|
55
|
+
└── README_test.md
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Conversion test
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
python3 ../../saclay_format/hdf5_yaml_converter.py -h5 Ca40_HF_SLy4.yaml
|
|
62
|
+
python3 ../../saclay_format/ev8_to_ev1.py Ca40_HF_SLy4.h5 -o Ca40_HF_SLy4_ev1.h5
|
|
63
|
+
python3 ../../saclay_format/ev1_to_cr1.py Ca40_HF_SLy4_ev1.h5 -o Ca40_HF_SLy4_cr1.h5
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Visualization test
|
|
67
|
+
|
|
68
|
+
Static:
|
|
69
|
+
```bash
|
|
70
|
+
python3 ../../saclay_format/visualisation_rho.py reaction_alpha_alpha_3MeV_header.yml
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Dynamic:
|
|
74
|
+
```bash
|
|
75
|
+
python3 ../../saclay_format/visualisation_rho_TD.py -H reaction_alpha_alpha_3MeV_header.yml
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Conversion and round-trip test:
|
|
79
|
+
```bash
|
|
80
|
+
python3 ../../saclay_format/hdf5_yaml_converter.py -h5 reaction_alpha_alpha_3MeV_header.yml
|
|
81
|
+
mv reaction_alpha_alpha_3MeV_header.h5 reaction_alpha_alpha_3MeV_converted.h5
|
|
82
|
+
python3 ../../saclay_format/visualisation_rho_TD.py reaction_alpha_alpha_3MeV_converted.h5
|
|
83
|
+
python3 ../../saclay_format/hdf5_yaml_converter.py -yaml reaction_alpha_alpha_3MeV_converted.h5
|
|
84
|
+
python3 ../../saclay_format/visualisation_rho_TD.py reaction_alpha_alpha_3MeV_converted.yaml
|
|
85
|
+
rm reaction_alpha_alpha_3MeV_converted*
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Todo
|
|
89
|
+
|
|
90
|
+
- Test the format
|
|
91
|
+
- Add documentation
|
|
92
|
+
- Update unit tests
|
|
93
|
+
|
|
94
|
+
## Project layout
|
|
95
|
+
|
|
96
|
+
This project follows the structure recommended by the Hitchhiker’s Guide to Python:
|
|
97
|
+
[https://docs.python-guide.org/writing/structure](https://docs.python-guide.org/writing/structure)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "saclay-format"
|
|
3
|
+
version = "0.2.1"
|
|
4
|
+
description = "python parser and usefull script related to the saclay format"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.10"
|
|
7
|
+
dependencies = ["h5py","numpy","pyyaml"]
|
|
8
|
+
|
|
9
|
+
optional-dependencies.visu = ["matplotlib", "PyQt5", "scipy", "scikit-image"]
|
|
10
|
+
|
|
11
|
+
maintainers = [{ name = "Guillaume Scamps", email = "guillaume.scamps@l2it.in2p3.fr"} ,
|
|
12
|
+
{name="David Regnier" , email = "David.REGNIER@cea.fr"},
|
|
13
|
+
{name="Wouter Ryssens" , email = "Wouter.Ryssens@ulb.be"},
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
urls.Sources="https://gitlab.com/regnier/Saclay_format"
|
|
17
|
+
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
import sys, os
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
from saclay_parser import read, write
|
|
6
|
+
|
|
7
|
+
def kramers_partner(states):
|
|
8
|
+
"""
|
|
9
|
+
Construct Kramers partners for 2-spinor wavefunctions:
|
|
10
|
+
psi_T = i sigma_y psi* -> ( psi_down*, -psi_up* )
|
|
11
|
+
Input shape: (nx, ny, nz, 2, nw)
|
|
12
|
+
Output shape: (nx, ny, nz, 2, nw)
|
|
13
|
+
"""
|
|
14
|
+
conj = np.conjugate(states)
|
|
15
|
+
up = conj[..., 0, :]
|
|
16
|
+
dn = conj[..., 1, :]
|
|
17
|
+
partner = np.empty_like(states)
|
|
18
|
+
partner[..., 0, :] = dn
|
|
19
|
+
partner[..., 1, :] = -up
|
|
20
|
+
return partner
|
|
21
|
+
|
|
22
|
+
def check_orthonormality(states, tol=1e-10):
|
|
23
|
+
"""
|
|
24
|
+
Check orthonormality of a set of wavefunctions.
|
|
25
|
+
states: shape (nx, ny, nz, 2, nw)
|
|
26
|
+
"""
|
|
27
|
+
nx, ny, nz, _, nw = states.shape
|
|
28
|
+
flat = states.reshape(-1, nw) # (nx*ny*nz*2, nw)
|
|
29
|
+
overlaps = flat.conj().T @ flat # Gram matrix (nw, nw)
|
|
30
|
+
# Normalize
|
|
31
|
+
norms = np.sqrt(np.real(np.diag(overlaps)))
|
|
32
|
+
overlaps = overlaps / (norms[:, None] * norms[None, :])
|
|
33
|
+
deviation = np.max(np.abs(overlaps - np.eye(nw)))
|
|
34
|
+
print("Max deviation from orthonormality: {:.2e}".format(deviation))
|
|
35
|
+
if deviation > tol:
|
|
36
|
+
print("Warning: orthonormality check FAILED")
|
|
37
|
+
else:
|
|
38
|
+
print("Orthonormality OK")
|
|
39
|
+
|
|
40
|
+
def interleave_with_partners(states, partners):
|
|
41
|
+
"""
|
|
42
|
+
Interleave original states and their Kramers partners along the last axis:
|
|
43
|
+
[1,2,...,N] + [1*,2*,...,N*] -> [1,1*,2,2*,...,N,N*]
|
|
44
|
+
"""
|
|
45
|
+
shape = list(states.shape)
|
|
46
|
+
shape[-1] *= 2 # double last axis
|
|
47
|
+
interleaved = np.empty(shape, dtype=states.dtype)
|
|
48
|
+
interleaved[..., ::2] = states
|
|
49
|
+
interleaved[..., 1::2] = partners
|
|
50
|
+
return interleaved
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def interleave_amplitudes(arr):
|
|
54
|
+
# arr: shape (N, ...)
|
|
55
|
+
conj = np.conjugate(arr)
|
|
56
|
+
shape = list(arr.shape)
|
|
57
|
+
shape[0] *= 2
|
|
58
|
+
interleaved = np.empty(shape, dtype=arr.dtype)
|
|
59
|
+
interleaved[::2] = arr
|
|
60
|
+
interleaved[1::2] = conj
|
|
61
|
+
return interleaved
|
|
62
|
+
|
|
63
|
+
def ev1_to_cr1(data):
|
|
64
|
+
"""
|
|
65
|
+
Translate EV1 dataset into CR1 by doubling wavefunctions.
|
|
66
|
+
Only wavefunctions and metadata are modified.
|
|
67
|
+
"""
|
|
68
|
+
md = data["metadata"].copy()
|
|
69
|
+
wf_md = md.get("wavefunction", {}).copy()
|
|
70
|
+
|
|
71
|
+
nw_n = wf_md["n_neutron_states"]
|
|
72
|
+
nw_p = wf_md["n_proton_states"]
|
|
73
|
+
|
|
74
|
+
# Build Kramers partners
|
|
75
|
+
statesn = data["statesn"]
|
|
76
|
+
statesp = data["statesp"]
|
|
77
|
+
pn = kramers_partner(statesn)
|
|
78
|
+
pp = kramers_partner(statesp)
|
|
79
|
+
|
|
80
|
+
statesn_cr1 = interleave_with_partners(statesn, pn)
|
|
81
|
+
statesp_cr1 = interleave_with_partners(statesp, pp)
|
|
82
|
+
|
|
83
|
+
# Bogoliubov amplitudes
|
|
84
|
+
un = data["un"]; vn = data["vn"]
|
|
85
|
+
up = data["up"]; vp = data["vp"]
|
|
86
|
+
|
|
87
|
+
un_cr1 = interleave_amplitudes(un)
|
|
88
|
+
vn_cr1 = interleave_amplitudes(vn)
|
|
89
|
+
up_cr1 = interleave_amplitudes(up)
|
|
90
|
+
vp_cr1 = interleave_amplitudes(vp)
|
|
91
|
+
|
|
92
|
+
# Update metadata
|
|
93
|
+
md["symmetry"] = "cr1"
|
|
94
|
+
md["prefix"] = md.get("prefix", "run") + "_cr1"
|
|
95
|
+
wf_md["n_neutron_states"] = 2 * nw_n
|
|
96
|
+
wf_md["n_proton_states"] = 2 * nw_p
|
|
97
|
+
md["wavefunction"] = wf_md
|
|
98
|
+
|
|
99
|
+
cr1_data = data.copy()
|
|
100
|
+
cr1_data['metadata'] = md
|
|
101
|
+
cr1_data['statesn'] = statesn_cr1
|
|
102
|
+
cr1_data['statesp'] = statesp_cr1
|
|
103
|
+
cr1_data['un'] = un_cr1
|
|
104
|
+
cr1_data['vn'] = vn_cr1
|
|
105
|
+
cr1_data['up'] = up_cr1
|
|
106
|
+
cr1_data['vp'] = vp_cr1
|
|
107
|
+
|
|
108
|
+
return cr1_data
|
|
109
|
+
|
|
110
|
+
def sort_by_occupation(data):
|
|
111
|
+
"""
|
|
112
|
+
Sort states and Bogoliubov amplitudes by descending occupation number.
|
|
113
|
+
Occupation is |v|^2 summed over all spatial and spin coordinates.
|
|
114
|
+
"""
|
|
115
|
+
vn = data["vn"]
|
|
116
|
+
vp = data["vp"]
|
|
117
|
+
|
|
118
|
+
occ_n = np.sum(np.abs(vn)**2, axis=tuple(range(1, vn.ndim))) # shape (N_n,)
|
|
119
|
+
occ_p = np.sum(np.abs(vp)**2, axis=tuple(range(1, vp.ndim))) # shape (N_p,)
|
|
120
|
+
|
|
121
|
+
idx_n = np.argsort(-occ_n) # descending
|
|
122
|
+
idx_p = np.argsort(-occ_p)
|
|
123
|
+
|
|
124
|
+
# Sort all neutron-related arrays
|
|
125
|
+
data["statesn"] = data["statesn"][..., idx_n]
|
|
126
|
+
data["un"] = data["un"][idx_n]
|
|
127
|
+
data["vn"] = data["vn"][idx_n]
|
|
128
|
+
|
|
129
|
+
# Sort all proton-related arrays
|
|
130
|
+
data["statesp"] = data["statesp"][..., idx_p]
|
|
131
|
+
data["up"] = data["up"][idx_p]
|
|
132
|
+
data["vp"] = data["vp"][idx_p]
|
|
133
|
+
|
|
134
|
+
return data
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
#----------------------------------------------------------
|
|
138
|
+
#----------------------------------------------------------
|
|
139
|
+
if __name__ == "__main__":
|
|
140
|
+
import argparse
|
|
141
|
+
import os
|
|
142
|
+
import sys
|
|
143
|
+
|
|
144
|
+
description = "Translate EV1 dataset into CR1 (no symmetry)"
|
|
145
|
+
parser = argparse.ArgumentParser(description=description)
|
|
146
|
+
parser.add_argument(
|
|
147
|
+
"input",
|
|
148
|
+
help="Input file (.yaml/.yml or .h5/.hdf5)"
|
|
149
|
+
)
|
|
150
|
+
parser.add_argument(
|
|
151
|
+
"-o", "--output",
|
|
152
|
+
type=str,
|
|
153
|
+
help="Output file name (.yaml/.yml or .h5/.hdf5). Default: overwrite input"
|
|
154
|
+
)
|
|
155
|
+
parser.add_argument(
|
|
156
|
+
"-f", "--format",
|
|
157
|
+
type=str,
|
|
158
|
+
choices=["yaml", "yml", "hdf5", "h5"],
|
|
159
|
+
help="Output format (default: same as input)"
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
args = parser.parse_args()
|
|
163
|
+
|
|
164
|
+
input_path = args.input
|
|
165
|
+
output_path = args.output or input_path
|
|
166
|
+
output_format = args.format
|
|
167
|
+
|
|
168
|
+
if not os.path.exists(input_path):
|
|
169
|
+
print(f"Input file '{input_path}' not found.")
|
|
170
|
+
sys.exit(1)
|
|
171
|
+
|
|
172
|
+
# --- Determine input format ---
|
|
173
|
+
ext = os.path.splitext(input_path)[1].lower()
|
|
174
|
+
if ext in (".yaml", ".yml"):
|
|
175
|
+
input_format = "yaml"
|
|
176
|
+
elif ext in (".h5", ".hdf5"):
|
|
177
|
+
input_format = "hdf5"
|
|
178
|
+
else:
|
|
179
|
+
print(f"Unsupported input file extension '{ext}'.")
|
|
180
|
+
sys.exit(1)
|
|
181
|
+
|
|
182
|
+
# --- Default output format same as input ---
|
|
183
|
+
if output_format is None:
|
|
184
|
+
output_format = input_format
|
|
185
|
+
|
|
186
|
+
# --- Prevent invalid conversion YAML -> HDF5 ---
|
|
187
|
+
if input_format == "yaml" and output_format in ("hdf5", "h5"):
|
|
188
|
+
print("ERROR: cannot convert YAML input directly to HDF5. Aborting.")
|
|
189
|
+
sys.exit(1)
|
|
190
|
+
|
|
191
|
+
# --- Read input ---
|
|
192
|
+
data_all = read(input_path)
|
|
193
|
+
|
|
194
|
+
sym = data_all["metadata"].get("symmetry", "").lower()
|
|
195
|
+
if sym != "ev1":
|
|
196
|
+
print(f"Symmetry is '{sym}', not 'ev1'. Aborting.")
|
|
197
|
+
sys.exit(1)
|
|
198
|
+
|
|
199
|
+
print("\n--- Input (EV1) ---")
|
|
200
|
+
wf_meta = data_all["metadata"]["wavefunction"]
|
|
201
|
+
print(f"Prefix: {data_all['metadata'].get('prefix')}")
|
|
202
|
+
print(f"Neutron states: {wf_meta['n_neutron_states']}")
|
|
203
|
+
print(f"Proton states: {wf_meta['n_proton_states']}")
|
|
204
|
+
|
|
205
|
+
# --- Translation EV1 -> CR1 ---
|
|
206
|
+
data_cr1 = ev1_to_cr1(data_all)
|
|
207
|
+
# data_cr1 = sort_by_occupation(data_cr1) # optional
|
|
208
|
+
|
|
209
|
+
# --- Update prefix to match output ---
|
|
210
|
+
output_dir = os.path.dirname(output_path) or "."
|
|
211
|
+
output_base = os.path.basename(output_path)
|
|
212
|
+
new_prefix = os.path.splitext(output_base)[0]
|
|
213
|
+
data_cr1["metadata"]["prefix"] = new_prefix
|
|
214
|
+
|
|
215
|
+
# --- Ensure file extension matches chosen format ---
|
|
216
|
+
out_ext = os.path.splitext(output_path)[1].lower()
|
|
217
|
+
if not out_ext:
|
|
218
|
+
if output_format in ("yaml", "yml"):
|
|
219
|
+
output_path += ".yaml"
|
|
220
|
+
elif output_format in ("hdf5", "h5"):
|
|
221
|
+
output_path += ".h5"
|
|
222
|
+
|
|
223
|
+
# --- Write output ---
|
|
224
|
+
print(f"\nWriting to '{output_path}' ({output_format} format)")
|
|
225
|
+
write(data_cr1, output_path)
|
|
226
|
+
|
|
227
|
+
print("\n--- Output (CR1) ---")
|
|
228
|
+
wf_meta = data_cr1["metadata"]["wavefunction"]
|
|
229
|
+
print(f"Prefix: {data_cr1['metadata'].get('prefix')}")
|
|
230
|
+
print(f"Neutron states: {wf_meta['n_neutron_states']}")
|
|
231
|
+
print(f"Proton states: {wf_meta['n_proton_states']}")
|
|
232
|
+
|
|
233
|
+
# --- Check orthonormality ---
|
|
234
|
+
print("\nChecking neutron states:")
|
|
235
|
+
check_orthonormality(data_cr1["statesn"])
|
|
236
|
+
print("Checking proton states:")
|
|
237
|
+
check_orthonormality(data_cr1["statesp"])
|