0
# File I/O
1
2
Flexible data persistence supporting HDF5 and CSV formats with object serialization. Enables storing and retrieving qubit calculations, parameter sweep results, and custom data structures.
3
4
## Capabilities
5
6
### Core I/O Functions
7
8
Primary functions for reading and writing scqubits objects to various file formats.
9
10
```python { .api }
11
def read(filename: str) -> object:
12
"""
13
Read scqubits object from file.
14
15
Parameters:
16
- filename (str): Path to file (supports .h5, .hdf5, .csv extensions)
17
18
Returns:
19
- object: Deserialized scqubits object
20
"""
21
22
def write(obj: object, filename: str, file_handle=None, overwrite: bool = False) -> None:
23
"""
24
Write scqubits object to file.
25
26
Parameters:
27
- obj (object): Scqubits object to serialize
28
- filename (str): Output file path
29
- file_handle: Optional existing file handle
30
- overwrite (bool): Whether to overwrite existing files
31
"""
32
```
33
34
### Data Storage Classes
35
36
Container classes for organizing and persisting calculation results with metadata.
37
38
```python { .api }
39
class DataStore:
40
def __init__(self, system_params: dict = None):
41
"""
42
Base class for data storage.
43
44
Parameters:
45
- system_params (dict): Dictionary of system parameters
46
"""
47
48
def serialize(self) -> dict:
49
"""Convert object to serializable dictionary."""
50
51
def deserialize(self, data_dict: dict) -> None:
52
"""Restore object from serialized dictionary."""
53
54
def to_file(self, filename: str) -> None:
55
"""Save object to file."""
56
57
@classmethod
58
def from_file(cls, filename: str):
59
"""Load object from file."""
60
61
class SpectrumData(DataStore):
62
def __init__(self, energy_table: np.ndarray, system_params: dict = None,
63
state_table: np.ndarray = None, matrixelem_table: np.ndarray = None):
64
"""
65
Storage for eigenvalue/eigenvector calculation results.
66
67
Parameters:
68
- energy_table (np.ndarray): Eigenvalues array [param_point, eigenvalue_index]
69
- system_params (dict): System parameters and metadata
70
- state_table (np.ndarray): Eigenvectors array [param_point, state_index, component]
71
- matrixelem_table (np.ndarray): Matrix elements [param_point, i, j]
72
"""
73
74
def eigenvals(self, param_index: int = None) -> np.ndarray:
75
"""Get eigenvalues at specific parameter point."""
76
77
def eigenvecs(self, param_index: int = None) -> np.ndarray:
78
"""Get eigenvectors at specific parameter point."""
79
80
def matrixelems(self, operator_name: str, param_index: int = None) -> np.ndarray:
81
"""Get matrix elements at specific parameter point."""
82
83
class WaveFunction(DataStore):
84
def __init__(self, basis_labels: list, amplitudes: np.ndarray, energy: float = None):
85
"""
86
Container for wavefunction data and visualization.
87
88
Parameters:
89
- basis_labels (list): Labels for basis states
90
- amplitudes (np.ndarray): Complex amplitudes in given basis
91
- energy (float): Energy eigenvalue
92
"""
93
94
def plot(self, mode: str = 'abs_sqr', **kwargs):
95
"""
96
Plot wavefunction.
97
98
Parameters:
99
- mode (str): Plotting mode ('abs_sqr', 'abs', 'real', 'imag')
100
- **kwargs: Additional plotting parameters
101
"""
102
```
103
104
### File Format Support
105
106
Utilities for handling different file formats and conversion between data types.
107
108
```python { .api }
109
def convert_to_csv(input_filename: str, output_filename: str = None) -> None:
110
"""
111
Convert HDF5 file to CSV format.
112
113
Parameters:
114
- input_filename (str): Input HDF5 file path
115
- output_filename (str): Output CSV file path (auto-generated if None)
116
"""
117
118
def convert_to_hdf5(input_filename: str, output_filename: str = None) -> None:
119
"""
120
Convert CSV file to HDF5 format.
121
122
Parameters:
123
- input_filename (str): Input CSV file path
124
- output_filename (str): Output HDF5 file path (auto-generated if None)
125
"""
126
127
def file_info(filename: str) -> dict:
128
"""
129
Get information about stored file.
130
131
Parameters:
132
- filename (str): File path to analyze
133
134
Returns:
135
- dict: File metadata and contents summary
136
"""
137
```
138
139
## Usage Examples
140
141
### Basic Object Persistence
142
143
```python
144
import scqubits as scq
145
import numpy as np
146
147
# Create and calculate transmon spectrum
148
transmon = scq.Transmon(EJ=25.0, EC=0.2, ng=0.0, ncut=30)
149
evals, evecs = transmon.eigensys(evals_count=6)
150
151
# Save transmon object
152
scq.io_utils.write(transmon, 'my_transmon.h5')
153
154
# Load transmon object
155
loaded_transmon = scq.io_utils.read('my_transmon.h5')
156
157
# Verify loaded object works
158
loaded_evals = loaded_transmon.eigenvals(evals_count=6)
159
print("Original energies:", evals[:3])
160
print("Loaded energies:", loaded_evals[:3])
161
```
162
163
### Parameter Sweep Storage
164
165
```python
166
# Create and run parameter sweep
167
ng_vals = np.linspace(-2, 2, 101)
168
hilbert_space = scq.HilbertSpace([transmon])
169
170
sweep = scq.ParameterSweep(
171
hilbert_space=hilbert_space,
172
paramvals_by_name={'ng': ng_vals},
173
evals_count=6
174
)
175
sweep.run()
176
177
# Save entire sweep
178
scq.io_utils.write(sweep, 'transmon_ng_sweep.h5')
179
180
# Load and analyze saved sweep
181
loaded_sweep = scq.io_utils.read('transmon_ng_sweep.h5')
182
loaded_sweep.plot_evals_vs_paramvals(subtract_ground=True)
183
184
# Save just the spectrum data
185
spectrum_data = sweep.dressed_specdata()
186
scq.io_utils.write(spectrum_data, 'spectrum_data_only.h5')
187
```
188
189
### Composite System Storage
190
191
```python
192
# Create composite system
193
transmon = scq.Transmon(EJ=25.0, EC=0.2, ng=0.0, ncut=25)
194
cavity = scq.Oscillator(E_osc=6.0, truncated_dim=4)
195
196
system = scq.HilbertSpace([transmon, cavity])
197
system.add_interaction(
198
g_strength=0.1,
199
op1=transmon.n_operator,
200
op2=cavity.creation_operator + cavity.annihilation_operator
201
)
202
203
# Save composite system
204
scq.io_utils.write(system, 'qubit_cavity_system.h5')
205
206
# Load and verify
207
loaded_system = scq.io_utils.read('qubit_cavity_system.h5')
208
original_spectrum = system.eigenvals(evals_count=8)
209
loaded_spectrum = loaded_system.eigenvals(evals_count=8)
210
211
print("Spectrum comparison:")
212
print("Original:", original_spectrum[:4])
213
print("Loaded:", loaded_spectrum[:4])
214
```
215
216
### Custom Data Storage
217
218
```python
219
# Create custom SpectrumData object
220
energy_data = np.random.random((50, 6)) # 50 parameter points, 6 eigenvalues
221
state_data = np.random.random((50, 6, 100)) + 1j * np.random.random((50, 6, 100))
222
223
spectrum_data = scq.SpectrumData(
224
energy_table=energy_data,
225
state_table=state_data,
226
system_params={
227
'system_type': 'transmon',
228
'EJ': 25.0,
229
'EC': 0.2,
230
'parameter_name': 'ng',
231
'parameter_values': np.linspace(-2, 2, 50)
232
}
233
)
234
235
# Save custom data
236
scq.io_utils.write(spectrum_data, 'custom_spectrum.h5')
237
238
# Load and access data
239
loaded_spectrum = scq.io_utils.read('custom_spectrum.h5')
240
print("System parameters:", loaded_spectrum.system_params)
241
print("Energy table shape:", loaded_spectrum.energy_table.shape)
242
```
243
244
### Wavefunction Storage
245
246
```python
247
# Calculate and store wavefunction
248
transmon = scq.Transmon(EJ=25.0, EC=0.2, ng=0.5, ncut=30)
249
wavefunction = transmon.wavefunction(which=0) # Ground state
250
251
# Save wavefunction
252
scq.io_utils.write(wavefunction, 'ground_state_wf.h5')
253
254
# Load and plot
255
loaded_wf = scq.io_utils.read('ground_state_wf.h5')
256
loaded_wf.plot(mode='abs_sqr')
257
```
258
259
### File Format Conversion
260
261
```python
262
# Save data in HDF5 format
263
scq.io_utils.write(transmon, 'transmon_data.h5')
264
265
# Convert to CSV for external analysis
266
scq.io_utils.convert_to_csv('transmon_data.h5', 'transmon_data.csv')
267
268
# Get file information
269
info = scq.io_utils.file_info('transmon_data.h5')
270
print("File contents:", info)
271
272
# Convert back to HDF5
273
scq.io_utils.convert_to_hdf5('transmon_data.csv', 'transmon_converted.h5')
274
```
275
276
### Batch Processing
277
278
```python
279
# Save multiple objects with systematic naming
280
systems = {
281
'transmon_low_EC': scq.Transmon(EJ=25.0, EC=0.1, ng=0.0, ncut=30),
282
'transmon_high_EC': scq.Transmon(EJ=25.0, EC=0.5, ng=0.0, ncut=30),
283
'fluxonium': scq.Fluxonium(EJ=2.0, EC=0.5, EL=0.8, flux=0.0)
284
}
285
286
# Save all systems
287
for name, system in systems.items():
288
filename = f'{name}_system.h5'
289
scq.io_utils.write(system, filename)
290
print(f"Saved {name} to {filename}")
291
292
# Load and compare spectra
293
spectra = {}
294
for name in systems.keys():
295
filename = f'{name}_system.h5'
296
loaded_system = scq.io_utils.read(filename)
297
spectra[name] = loaded_system.eigenvals(evals_count=4)
298
299
print("\nComparison of energy spectra:")
300
for name, spectrum in spectra.items():
301
print(f"{name}: {spectrum}")
302
```
303
304
### Error Handling
305
306
```python
307
# Safe file operations with error handling
308
try:
309
# Attempt to load file
310
data = scq.io_utils.read('nonexistent_file.h5')
311
except FileNotFoundError:
312
print("File not found - creating new data")
313
data = scq.Transmon(EJ=25.0, EC=0.2, ng=0.0, ncut=30)
314
315
# Safe write with overwrite protection
316
try:
317
scq.io_utils.write(data, 'important_data.h5', overwrite=False)
318
print("Data saved successfully")
319
except FileExistsError:
320
print("File already exists - use overwrite=True to replace")
321
322
# Explicit overwrite
323
scq.io_utils.write(data, 'important_data.h5', overwrite=True)
324
print("Data overwritten successfully")
325
```