SDDS ToolKit Programs and Libraries for C and Python
All Classes Files Functions Variables Macros Pages
sdds.py
Go to the documentation of this file.
1"""
2@file sdds.py
3@brief Python script providing the SDDS Python module.
4@details
5This module provides the `SDDS` class and associated methods to load, manipulate, and save SDDS files.
6It supports both ASCII and binary SDDS formats and provides functionality to read, write, and manipulate SDDS data.
7
8Dependencies:
9 sddsdata module
10"""
11
12try:
13 from . import sddsdata
14except:
15 import sddsdata
16import sys
17import time
18from dataclasses import dataclass
19from typing import Optional, Any
20
21
22class SDDS:
23 """
24 A class to represent and manipulate SDDS datasets.
25
26 This class provides methods to load, manipulate, and save SDDS data.
27 It supports ASCII and binary formats and facilitates operations on parameters, arrays, and columns.
28
29 Attributes:
30 index (int): The index of the SDDS dataset (integer from 0 to 1000).
31 description (list): List containing the description text and contents of the SDDS file.
32 parameterName (list): List of parameter names.
33 arrayName (list): List of array names.
34 columnName (list): List of column names.
35 parameterDefinition (list): List of parameter definitions.
36 arrayDefinition (list): List of array definitions.
37 arrayDimensions (list): List of array dimensions.
38 columnDefinition (list): List of column definitions.
39 parameterData (list): List of parameter data values.
40 arrayData (list): List of array data values.
41 columnData (list): List of column data values.
42 mode (int): The data storage mode (`SDDS_ASCII` or `SDDS_BINARY`).
43 """
44
45 # Class constants for error printing modes
46 SDDS_VERBOSE_PrintErrors = 1 # Verbose error printing mode
47 SDDS_EXIT_PrintErrors = 2 # Exit on error printing mode
48
49 # Class constants for SDDS check statuses
50 SDDS_CHECK_OKAY = 0 # SDDS check status: okay
51 SDDS_CHECK_NONEXISTENT = 1 # SDDS check status: non-existent
52 SDDS_CHECK_WRONGTYPE = 2 # SDDS check status: wrong type
53 SDDS_CHECK_WRONGUNITS = 3 # SDDS check status: wrong units
54
55 # Class constants for data types
56 SDDS_LONGDOUBLE = 1
57 SDDS_DOUBLE = 2
58 SDDS_REAL64 = 2
59 SDDS_FLOAT = 3
60 SDDS_REAL32 = 3
61 SDDS_LONG64 = 4
62 SDDS_INT64 = 4
63 SDDS_ULONG64 = 5
64 SDDS_UINT64 = 5
65 SDDS_LONG = 6
66 SDDS_INT32 = 6
67 SDDS_ULONG = 7
68 SDDS_UINT32 = 7
69 SDDS_SHORT = 8
70 SDDS_INT16 = 8
71 SDDS_USHORT = 9
72 SDDS_UINT16 = 9
73 SDDS_STRING = 10
74 SDDS_CHARACTER = 11
75 SDDS_NUM_TYPES = 11
76
77 # Class constants for modes
78 SDDS_BINARY = 1
79 SDDS_ASCII = 2
80 SDDS_FLUSH_TABLE = 1
81
82 _used_indices = set() # Class-level attribute to track used indices
83 _max_index = 1000 # Maximum allowable index
84
85 def __init__(self, index=None):
86 """
87 Initializes a new SDDS object.
88
89 Args:
90 index (int, optional): Integer index of the SDDS object. If not provided, an available
91 index will be automatically assigned. Must be between 0 and 1000.
92
93 Raises:
94 ValueError: If no index is provided and all indices are in use.
95 """
96 if index is None:
97 # Automatically assign an unused index
98 for i in range(self._max_index + 1):
99 if i not in self._used_indices:
100 self.index = i
101 self._used_indices.add(i)
102 break
103 else:
104 raise ValueError("All SDDS indices are in use. Cannot create a new SDDS object.")
105 elif 0 <= index <= self._max_index:
106 if index in self._used_indices:
107 raise ValueError(f"Index {index} is already in use.")
108 self.index = index
109 self._used_indices.add(index)
110 else:
111 raise ValueError(f"Index {index} must be between 0 and {self._max_index}.")
112
113 # Initialize data storage variables
114 self.description = ["", ""]
116 self.arrayNamearrayName = []
117 self.columnNamecolumnName = []
118 self.parameterDefinition = []
119 self.arrayDefinition = []
120 self.arrayDimensions = []
121 self.columnDefinition = []
122 self.parameterData = []
123 self.arrayData = []
124 self.columnData = []
125 self.mode = self.SDDS_ASCII
126 self.loaded_pages = 0
127
128 def __del__(self):
129 """
130 Destructor to release the index when the object is deleted.
131 """
132 if hasattr(self, 'index') and self.index in self._used_indices:
133 self._used_indices.remove(self.index)
134
135 def load(self, input):
136 """
137 Loads an SDDS file into the SDDS object.
138
139 Args:
140 input (str): The input SDDS filename to load.
141
142 Raises:
143 Exception: If unable to read the SDDS data.
144
145 This method reads the SDDS file specified by `input`, and populates the object's data structures
146 with the parameters, arrays, columns, and their respective data.
147 """
148 try:
149 # Open SDDS file
150 if sddsdata.InitializeInput(self.index, input) != 1:
151 time.sleep(1)
152 if sddsdata.InitializeInput(self.index, input) != 1:
153 raise ValueError("Failed to initialize SDDS input.")
154
155 # Get data storage mode (SDDS_ASCII or SDDS_BINARY)
156 self.mode = sddsdata.GetMode(self.index)
157
158 # Get description text and contents
159 self.description = sddsdata.GetDescription(self.index)
160
161 # Get parameter names
162 self.parameterNameparameterName = sddsdata.GetParameterNames(self.index)
163 numberOfParameters = len(self.parameterNameparameterName)
164
165 # Get array names
166 self.arrayNamearrayName = sddsdata.GetArrayNames(self.index)
167 numberOfArrays = len(self.arrayNamearrayName)
168
169 # Get column names
170 self.columnNamecolumnName = sddsdata.GetColumnNames(self.index)
171 numberOfColumns = len(self.columnNamecolumnName)
172
173 # Get parameter definitions
174 self.parameterDefinition = [sddsdata.GetParameterDefinition(self.index, name) for name in self.parameterNameparameterName]
175
176 # Get array definitions
177 self.arrayDefinition = [sddsdata.GetArrayDefinition(self.index, name) for name in self.arrayNamearrayName]
178
179 # Get column definitions
180 self.columnDefinition = [sddsdata.GetColumnDefinition(self.index, name) for name in self.columnNamecolumnName]
181
182 # Initialize parameter, array, and column data
183 self.parameterData = [[] for _ in range(numberOfParameters)]
184 self.arrayData = [[] for _ in range(numberOfArrays)]
185 self.columnData = [[] for _ in range(numberOfColumns)]
186 self.arrayDimensions = [[] for _ in range(numberOfArrays)]
187
188 # Read in SDDS data
189 page = sddsdata.ReadPage(self.index)
190 if page != 1:
191 raise Exception("Unable to read SDDS data for the first page")
192 while page > 0:
193 self.loaded_pages += 1
194 for i in range(numberOfParameters):
195 self.parameterData[i].append(sddsdata.GetParameter(self.index, i))
196 for i in range(numberOfArrays):
197 self.arrayData[i].append(sddsdata.GetArray(self.index, i))
198 self.arrayDimensions[i].append(sddsdata.GetArrayDimensions(self.index, i))
199 rows = sddsdata.RowCount(self.index)
200 if rows > 0:
201 for i in range(numberOfColumns):
202 self.columnData[i].append(sddsdata.GetColumn(self.index, i))
203 else:
204 for i in range(numberOfColumns):
205 self.columnData[i].append([])
206 page = sddsdata.ReadPage(self.index)
207
208 # Close SDDS file
209 if sddsdata.Terminate(self.index) != 1:
210 raise ValueError("Failed to terminate SDDS input.")
211
212 except:
213 sddsdata.PrintErrors(self.SDDS_VERBOSE_PrintErrors)
214 raise
215
216 def loadSparse(self, input, interval, offset):
217 """
218 Loads an SDDS file into the SDDS object with sparse data reading.
219
220 Args:
221 input (str): The input SDDS filename to load.
222 interval (int): Interval between pages to read.
223 offset (int): Offset to start reading from.
224
225 Raises:
226 Exception: If unable to read the SDDS data.
227
228 This method reads every `interval` pages from the SDDS file, starting from the page at `offset`.
229 """
230 try:
231 # Open SDDS file
232 if sddsdata.InitializeInput(self.index, input) != 1:
233 time.sleep(1)
234 if sddsdata.InitializeInput(self.index, input) != 1:
235 raise ValueError("Failed to initialize SDDS input.")
236
237 # Get data storage mode (SDDS_ASCII or SDDS_BINARY)
238 self.mode = sddsdata.GetMode(self.index)
239
240 # Get description text and contents
241 self.description = sddsdata.GetDescription(self.index)
242
243 # Get parameter names
244 self.parameterNameparameterName = sddsdata.GetParameterNames(self.index)
245 numberOfParameters = len(self.parameterNameparameterName)
246
247 # Get array names
248 self.arrayNamearrayName = sddsdata.GetArrayNames(self.index)
249 numberOfArrays = len(self.arrayNamearrayName)
250
251 # Get column names
252 self.columnNamecolumnName = sddsdata.GetColumnNames(self.index)
253 numberOfColumns = len(self.columnNamecolumnName)
254
255 # Get parameter definitions
256 self.parameterDefinition = [sddsdata.GetParameterDefinition(self.index, name) for name in self.parameterNameparameterName]
257
258 # Get array definitions
259 self.arrayDefinition = [sddsdata.GetArrayDefinition(self.index, name) for name in self.arrayNamearrayName]
260
261 # Get column definitions
262 self.columnDefinition = [sddsdata.GetColumnDefinition(self.index, name) for name in self.columnNamecolumnName]
263
264 # Initialize parameter, array, and column data
265 self.parameterData = [[] for _ in range(numberOfParameters)]
266 self.arrayData = [[] for _ in range(numberOfArrays)]
267 self.columnData = [[] for _ in range(numberOfColumns)]
268 self.arrayDimensions = [[] for _ in range(numberOfArrays)]
269
270 # Read in SDDS data sparsely
271 page = sddsdata.ReadPageSparse(self.index, interval, offset)
272 if page != 1:
273 raise Exception("Unable to read SDDS data for the first page")
274 while page > 0:
275 for i in range(numberOfParameters):
276 self.parameterData[i].append(sddsdata.GetParameter(self.index, i))
277 for i in range(numberOfArrays):
278 self.arrayData[i].append(sddsdata.GetArray(self.index, i))
279 self.arrayDimensions[i].append(sddsdata.GetArrayDimensions(self.index, i))
280 rows = sddsdata.RowCount(self.index)
281 if rows > 0:
282 for i in range(numberOfColumns):
283 self.columnData[i].append(sddsdata.GetColumn(self.index, i))
284 else:
285 for i in range(numberOfColumns):
286 self.columnData[i].append([])
287 page = sddsdata.ReadPageSparse(self.index, interval, offset)
288
289 # Close SDDS file
290 if sddsdata.Terminate(self.index) != 1:
291 raise ValueError("Failed to terminate SDDS input.")
292
293 except:
294 sddsdata.PrintErrors(self.SDDS_VERBOSE_PrintErrors)
295 raise
296
297 def loadLastRows(self, input, lastrows):
298 """
299 Loads an SDDS file into the SDDS object, reading only the last few rows.
300
301 Args:
302 input (str): The input SDDS filename to load.
303 lastrows (int): Number of last rows to read.
304
305 Raises:
306 Exception: If unable to read the SDDS data.
307
308 This method reads only the last `lastrows` rows from each page of the SDDS file.
309 """
310 try:
311 # Open SDDS file
312 if sddsdata.InitializeInput(self.index, input) != 1:
313 time.sleep(1)
314 if sddsdata.InitializeInput(self.index, input) != 1:
315 raise ValueError("Failed to initialize SDDS input.")
316
317 # Get data storage mode (SDDS_ASCII or SDDS_BINARY)
318 self.mode = sddsdata.GetMode(self.index)
319
320 # Get description text and contents
321 self.description = sddsdata.GetDescription(self.index)
322
323 # Get parameter names
324 self.parameterNameparameterName = sddsdata.GetParameterNames(self.index)
325 numberOfParameters = len(self.parameterNameparameterName)
326
327 # Get array names
328 self.arrayNamearrayName = sddsdata.GetArrayNames(self.index)
329 numberOfArrays = len(self.arrayNamearrayName)
330
331 # Get column names
332 self.columnNamecolumnName = sddsdata.GetColumnNames(self.index)
333 numberOfColumns = len(self.columnNamecolumnName)
334
335 # Get parameter definitions
336 self.parameterDefinition = [sddsdata.GetParameterDefinition(self.index, name) for name in self.parameterNameparameterName]
337
338 # Get array definitions
339 self.arrayDefinition = [sddsdata.GetArrayDefinition(self.index, name) for name in self.arrayNamearrayName]
340
341 # Get column definitions
342 self.columnDefinition = [sddsdata.GetColumnDefinition(self.index, name) for name in self.columnNamecolumnName]
343
344 # Initialize parameter, array, and column data
345 self.parameterData = [[] for _ in range(numberOfParameters)]
346 self.arrayData = [[] for _ in range(numberOfArrays)]
347 self.columnData = [[] for _ in range(numberOfColumns)]
348 self.arrayDimensions = [[] for _ in range(numberOfArrays)]
349
350 # Read in SDDS data (last rows)
351 page = sddsdata.ReadPageLastRows(self.index, lastrows)
352 if page != 1:
353 raise Exception("Unable to read SDDS data for the first page")
354 while page > 0:
355 for i in range(numberOfParameters):
356 self.parameterData[i].append(sddsdata.GetParameter(self.index, i))
357 for i in range(numberOfArrays):
358 self.arrayData[i].append(sddsdata.GetArray(self.index, i))
359 self.arrayDimensions[i].append(sddsdata.GetArrayDimensions(self.index, i))
360 rows = sddsdata.RowCount(self.index)
361 if rows > 0:
362 for i in range(numberOfColumns):
363 self.columnData[i].append(sddsdata.GetColumn(self.index, i))
364 else:
365 for i in range(numberOfColumns):
366 self.columnData[i].append([])
367 page = sddsdata.ReadPageLastRows(self.index, lastrows)
368
369 # Close SDDS file
370 if sddsdata.Terminate(self.index) != 1:
371 raise ValueError("Failed to terminate SDDS input.")
372
373 except:
374 sddsdata.PrintErrors(self.SDDS_VERBOSE_PrintErrors)
375 raise
376
377 def save(self, output):
378 """
379 Saves the SDDS object's data to an SDDS file.
380
381 Args:
382 output (str): The output SDDS filename to save the data.
383
384 Raises:
385 Exception: If unable to write the SDDS data.
386
387 This method writes the data stored in the SDDS object to the specified file, including the
388 parameters, arrays, columns, and their data.
389 """
390 try:
391 # Check for invalid SDDS data
392 numberOfParameters = len(self.parameterNameparameterName)
393 numberOfArrays = len(self.arrayNamearrayName)
394 numberOfColumns = len(self.columnNamecolumnName)
395 pages = 0
396
397 if numberOfParameters != len(self.parameterData):
398 raise Exception("Unmatched parameterName and parameterData")
399 if numberOfArrays != len(self.arrayData):
400 raise Exception("Unmatched arrayName and arrayData")
401 if numberOfColumns != len(self.columnData):
402 raise Exception("Unmatched columnName and columnData")
403 if numberOfParameters != len(self.parameterDefinition):
404 raise Exception("Unmatched parameterName and parameterDefinition")
405 if numberOfArrays != len(self.arrayDefinition):
406 raise Exception("Unmatched arrayName and arrayDefinition")
407 if numberOfColumns != len(self.columnDefinition):
408 raise Exception("Unmatched columnName and columnDefinition")
409
410 if numberOfParameters > 0:
411 pages = len(self.parameterData[0])
412 elif numberOfColumns > 0:
413 pages = len(self.columnData[0])
414 elif numberOfArrays > 0:
415 pages = len(self.arrayData[0])
416
417 for i in range(numberOfParameters):
418 if pages != len(self.parameterData[i]):
419 raise Exception("Unequal number of pages in parameter data")
420 for i in range(numberOfArrays):
421 if pages != len(self.arrayData[i]):
422 raise Exception("Unequal number of pages in array data")
423 if pages != len(self.arrayDimensions[i]):
424 raise Exception("Unequal number of pages in array dimension data")
425 for i in range(numberOfColumns):
426 if pages != len(self.columnData[i]):
427 raise Exception("Unequal number of pages in column data")
428 for page in range(pages):
429 rows = 0
430 if numberOfColumns > 0:
431 rows = len(self.columnData[0][page])
432 for i in range(numberOfColumns):
433 if rows != len(self.columnData[i][page]):
434 raise Exception("Unequal number of rows in column data")
435
436 # Open SDDS output file
437 if sddsdata.InitializeOutput(self.index, self.mode, 1, self.description[0], self.description[1], output) != 1:
438 raise ValueError("Failed to initialize SDDS output.")
439
440 # Define parameters, arrays, and columns
441 for i in range(numberOfParameters):
442 if sddsdata.DefineParameter(
443 self.index,
445 self.parameterDefinition[i][0],
446 self.parameterDefinition[i][1],
447 self.parameterDefinition[i][2],
448 self.parameterDefinition[i][3],
449 self.parameterDefinition[i][4],
450 self.parameterDefinition[i][5],
451 ) == -1:
452 raise ValueError("Failed to define parameter.")
453
454 for i in range(numberOfArrays):
455 if sddsdata.DefineArray(
456 self.index,
457 self.arrayNamearrayName[i],
458 self.arrayDefinition[i][0],
459 self.arrayDefinition[i][1],
460 self.arrayDefinition[i][2],
461 self.arrayDefinition[i][3],
462 self.arrayDefinition[i][4],
463 self.arrayDefinition[i][5],
464 self.arrayDefinition[i][6],
465 self.arrayDefinition[i][7],
466 ) == -1:
467 raise ValueError("Failed to define array.")
468
469 for i in range(numberOfColumns):
470 if sddsdata.DefineColumn(
471 self.index,
472 self.columnNamecolumnName[i],
473 self.columnDefinition[i][0],
474 self.columnDefinition[i][1],
475 self.columnDefinition[i][2],
476 self.columnDefinition[i][3],
477 self.columnDefinition[i][4],
478 self.columnDefinition[i][5],
479 ) == -1:
480 raise ValueError("Failed to define column.")
481
482 # Write SDDS header
483 if sddsdata.WriteLayout(self.index) != 1:
484 raise ValueError("Failed to write SDDS layout.")
485
486 # Write SDDS data
487 for page in range(pages):
488 rows = 0
489 if numberOfColumns > 0:
490 rows = len(self.columnData[0][page])
491 if sddsdata.StartPage(self.index, rows) != 1:
492 raise ValueError("Failed to start SDDS page.")
493 for i in range(numberOfParameters):
494 if sddsdata.SetParameter(self.index, i, self.parameterData[i][page]) != 1:
495 raise ValueError("Failed to set parameter value.")
496 for i in range(numberOfArrays):
497 if sddsdata.SetArray(
498 self.index, i, self.arrayData[i][page], self.arrayDimensions[i][page]
499 ) != 1:
500 raise ValueError("Failed to set array value.")
501 for i in range(numberOfColumns):
502 if sddsdata.SetColumn(self.index, i, self.columnData[i][page]) != 1:
503 raise ValueError("Failed to set column value.")
504 if sddsdata.WritePage(self.index) != 1:
505 raise ValueError("Failed to write SDDS page.")
506
507 # Close SDDS output file
508 if sddsdata.Terminate(self.index) != 1:
509 raise ValueError("Failed to terminate SDDS output.")
510 except:
511 sddsdata.PrintErrors(self.SDDS_VERBOSE_PrintErrors)
512 raise
513
514 def setDescription(self, text, contents):
515 """
516 Sets the description for the SDDS object.
517
518 Args:
519 text (str): Description text.
520 contents (str): Description contents.
521 """
522 self.description = [text, contents]
523
524 def defineParameter(self, name, symbol="", units="", description="", formatString="", type=SDDS_DOUBLE, fixedValue=""):
525 """
526 Defines a parameter for the SDDS object.
527
528 Args:
529 name (str): Parameter name.
530 symbol (str, optional): Parameter symbol.
531 units (str, optional): Parameter units.
532 description (str, optional): Parameter description.
533 formatString (str, optional): Format string for the parameter.
534 type (int, optional): Data type of the parameter. Defaults to SDDS_DOUBLE. Valid options include:
535 - SDDS_SHORT: 16-bit signed integer.
536 - SDDS_USHORT: 16-bit unsigned integer.
537 - SDDS_LONG: 32-bit signed integer.
538 - SDDS_ULONG: 32-bit unsigned integer.
539 - SDDS_LONG64: 64-bit signed integer.
540 - SDDS_ULONG64: 64-bit unsigned integer.
541 - SDDS_FLOAT: Single-precision floating-point number.
542 - SDDS_DOUBLE: Double-precision floating-point number.
543 - SDDS_LONGDOUBLE: Long double-precision floating-point number.
544 - SDDS_STRING: String (textual data).
545 - SDDS_CHARACTER: Single character.
546 fixedValue (str, optional): Fixed value of the parameter.
547
548 This method adds a parameter definition to the SDDS object.
549 """
550 self.parameterNameparameterName.append(name)
551 self.parameterDefinition.append(
552 [symbol, units, description, formatString, type, fixedValue]
553 )
554 self.parameterData.append([])
555
556 def defineSimpleParameter(self, name, type):
557 """
558 Defines a simple parameter with minimal information.
559
560 Args:
561 name (str): Parameter name.
562 type (int): Data type of the parameter. Valid options include:
563 - SDDS_SHORT: 16-bit signed integer.
564 - SDDS_USHORT: 16-bit unsigned integer.
565 - SDDS_LONG: 32-bit signed integer.
566 - SDDS_ULONG: 32-bit unsigned integer.
567 - SDDS_LONG64: 64-bit signed integer.
568 - SDDS_ULONG64: 64-bit unsigned integer.
569 - SDDS_FLOAT: Single-precision floating-point number.
570 - SDDS_DOUBLE: Double-precision floating-point number.
571 - SDDS_LONGDOUBLE: Long double-precision floating-point number.
572 - SDDS_STRING: String (textual data).
573 - SDDS_CHARACTER: Single character.
574
575 This method adds a parameter definition with default attributes.
576 """
577 self.parameterNameparameterName.append(name)
578 self.parameterDefinition.append(["", "", "", "", type, ""])
579 self.parameterData.append([])
580
581 def defineArray(self, name, symbol="", units="", description="", formatString="", group_name="", type=SDDS_DOUBLE, fieldLength=0, dimensions=1):
582 """
583 Defines an array for the SDDS object.
584
585 Args:
586 name (str): Array name.
587 symbol (str, optional): Array symbol.
588 units (str, optional): Array units.
589 description (str, optional): Array description.
590 formatString (str, optional): Format string for the array.
591 group_name (str, optional): Group name for the array.
592 type (int, optional): Data type of the array. Defaults to SDDS_DOUBLE, Valid options include:
593 - SDDS_SHORT: 16-bit signed integer.
594 - SDDS_USHORT: 16-bit unsigned integer.
595 - SDDS_LONG: 32-bit signed integer.
596 - SDDS_ULONG: 32-bit unsigned integer.
597 - SDDS_LONG64: 64-bit signed integer.
598 - SDDS_ULONG64: 64-bit unsigned integer.
599 - SDDS_FLOAT: Single-precision floating-point number.
600 - SDDS_DOUBLE: Double-precision floating-point number.
601 - SDDS_LONGDOUBLE: Long double-precision floating-point number.
602 - SDDS_STRING: String (textual data).
603 - SDDS_CHARACTER: Single character.
604 fieldLength (int, optional): Field length for the array.
605 dimensions (int, optional): Number of dimensions of the array. Defaults to 1
606
607 This method adds an array definition to the SDDS object.
608 """
609 self.arrayNamearrayName.append(name)
610 self.arrayDefinition.append(
611 [symbol, units, description, formatString, group_name, type, fieldLength, dimensions]
612 )
613 self.arrayData.append([])
614 self.arrayDimensions.append([])
615
616 def defineSimpleArray(self, name, type, dimensions):
617 """
618 Defines a simple array with minimal information.
619
620 Args:
621 name (str): Array name.
622 type (int): Data type of the array. Valid options include:
623 - SDDS_SHORT: 16-bit signed integer.
624 - SDDS_USHORT: 16-bit unsigned integer.
625 - SDDS_LONG: 32-bit signed integer.
626 - SDDS_ULONG: 32-bit unsigned integer.
627 - SDDS_LONG64: 64-bit signed integer.
628 - SDDS_ULONG64: 64-bit unsigned integer.
629 - SDDS_FLOAT: Single-precision floating-point number.
630 - SDDS_DOUBLE: Double-precision floating-point number.
631 - SDDS_LONGDOUBLE: Long double-precision floating-point number.
632 - SDDS_STRING: String (textual data).
633 - SDDS_CHARACTER: Single character.
634 dimensions (int): Number of dimensions of the array.
635
636 This method adds an array definition with default attributes.
637 """
638 self.arrayNamearrayName.append(name)
639 self.arrayDefinition.append(["", "", "", "", "", type, 0, dimensions])
640 self.arrayData.append([])
641 self.arrayDimensions.append([])
642
643 def defineColumn(self, name, symbol="", units="", description="", formatString="", type=SDDS_DOUBLE, fieldLength=0):
644 """
645 Defines a column for the SDDS object.
646
647 Args:
648 name (str): Column name.
649 symbol (str, optional): Column symbol.
650 units (str, optional): Column units.
651 description (str, optional): Column description.
652 formatString (str, optional): Format string for the column.
653 type (int, optional): Data type of the column. Defaults to SDDS_DOUBLE. Valid options include:
654 - SDDS_SHORT: 16-bit signed integer.
655 - SDDS_USHORT: 16-bit unsigned integer.
656 - SDDS_LONG: 32-bit signed integer.
657 - SDDS_ULONG: 32-bit unsigned integer.
658 - SDDS_LONG64: 64-bit signed integer.
659 - SDDS_ULONG64: 64-bit unsigned integer.
660 - SDDS_FLOAT: Single-precision floating-point number.
661 - SDDS_DOUBLE: Double-precision floating-point number.
662 - SDDS_LONGDOUBLE: Long double-precision floating-point number.
663 - SDDS_STRING: String (textual data).
664 - SDDS_CHARACTER: Single character.
665 fieldLength (int, optional): Field length for the column.
666
667 This method adds a column definition to the SDDS object.
668 """
669 self.columnNamecolumnName.append(name)
670 self.columnDefinition.append(
671 [symbol, units, description, formatString, type, fieldLength]
672 )
673 self.columnData.append([])
674
675 def defineSimpleColumn(self, name, type):
676 """
677 Defines a simple column with minimal information.
678
679 Args:
680 name (str): Column name.
681 type (int): Data type of the column. Valid options include:
682 - SDDS_SHORT: 16-bit signed integer.
683 - SDDS_USHORT: 16-bit unsigned integer.
684 - SDDS_LONG: 32-bit signed integer.
685 - SDDS_ULONG: 32-bit unsigned integer.
686 - SDDS_LONG64: 64-bit signed integer.
687 - SDDS_ULONG64: 64-bit unsigned integer.
688 - SDDS_FLOAT: Single-precision floating-point number.
689 - SDDS_DOUBLE: Double-precision floating-point number.
690 - SDDS_LONGDOUBLE: Long double-precision floating-point number.
691 - SDDS_STRING: String (textual data).
692 - SDDS_CHARACTER: Single character.
693
694 This method adds a column definition with default attributes.
695 """
696 self.columnNamecolumnName.append(name)
697 self.columnDefinition.append(["", "", "", "", type, 0])
698 self.columnData.append([])
699
700 def setParameterValueList(self, name, valueList):
701 """
702 Sets the list of parameter values for a parameter. This can be used to set values for multiple pages at once.
703
704 Args:
705 name (str): Parameter name.
706 valueList (list): List of values for the parameter.
707
708 Raises:
709 Exception: If the parameter name is invalid.
710
711 This method assigns a list of values to a parameter across pages.
712 """
713 numberOfParameters = len(self.parameterNameparameterName)
714 if name in self.parameterNameparameterName:
715 self.parameterData[self.parameterNameparameterName.index(name)] = valueList
716 else:
717 msg = "Invalid parameter name " + name
718 raise Exception(msg)
719
720 def getParameterValueList(self, name):
721 """
722 Gets the list of parameter values for a parameter. This can be used to get values for multiple pages at once.
723
724 Args:
725 name (str): Parameter name.
726
727 Returns:
728 list: List of values for the parameter.
729
730 Raises:
731 Exception: If the parameter name is invalid.
732
733 """
734 numberOfParameters = len(self.parameterNameparameterName)
735 if name in self.parameterNameparameterName:
736 return(self.parameterData[self.parameterNameparameterName.index(name)])
737 else:
738 msg = "Invalid parameter name " + name
739 raise Exception(msg)
740
741 def setParameterValue(self, name, value, page=1):
742 """
743 Sets a single parameter value at a specific page.
744
745 Args:
746 name (str): Parameter name.
747 value: Parameter value.
748 page (int, optional): Page number (1-based index, defaults to 1).
749
750 Raises:
751 Exception: If the parameter name or page is invalid.
752
753 This method sets the parameter value at the specified page.
754 """
755 page = page - 1
756 numberOfParameters = len(self.parameterNameparameterName)
757 if name in self.parameterNameparameterName:
758 i = self.parameterNameparameterName.index(name)
759 if len(self.parameterData[i]) == page:
760 self.parameterData[i][page:] = [value]
761 elif len(self.parameterData[i]) < page or page < 0:
762 msg = "Invalid page " + str(page + 1)
763 raise Exception(msg)
764 else:
765 self.parameterData[i][page] = value
766 else:
767 msg = "Invalid parameter name " + name
768 raise Exception(msg)
769
770 def getParameterValue(self, name, page=1):
771 """
772 Gets a single parameter value at a specific page.
773
774 Args:
775 name (str): Parameter name.
776 page (int, optional): Page number (1-based index, defaults to 1).
777
778 Returns:
779 value: Parameter value.
780
781 Raises:
782 Exception: If the parameter name or page is invalid.
783 """
784 page = page - 1
785 numberOfParameters = len(self.parameterNameparameterName)
786 if name in self.parameterNameparameterName:
787 i = self.parameterNameparameterName.index(name)
788 if len(self.parameterData[i]) == page:
789 return(self.parameterData[i][page:])
790 elif len(self.parameterData[i]) < page or page < 0:
791 msg = "Invalid page " + str(page + 1)
792 raise Exception(msg)
793 else:
794 return(self.parameterData[i][page])
795 else:
796 msg = "Invalid parameter name " + name
797 raise Exception(msg)
798
799 def setArrayValueLists(self, name, valueList, dimensionList):
800 """
801 Sets the nested list of array values and dimensions for a single array. This can be used to set values for multiple pages at once.
802
803 Args:
804 name (str): Array name.
805 valueList (list): Nested list of array values.
806 dimensionList (list): Nested list of array dimensions.
807
808 Raises:
809 Exception: If the array name is invalid.
810
811 This method assigns values and dimensions to an array across pages.
812 """
813 numberOfArrays = len(self.arrayNamearrayName)
814 if name in self.arrayNamearrayName:
815 i = self.arrayNamearrayName.index(name)
816 self.arrayDimensions[i] = dimensionList
817 self.arrayData[i] = valueList
818 else:
819 msg = "Invalid array name " + name
820 raise Exception(msg)
821
822 def getArrayValueLists(self, name):
823 """
824 Gets the nested list of array values for a single array. This can be used to get values for multiple pages at once.
825
826 Args:
827 name (str): Array name.
828
829 Returns:
830 list: Nested list of array values.
831
832 Raises:
833 Exception: If the array name is invalid.
834 """
835 numberOfArrays = len(self.arrayNamearrayName)
836 if name in self.arrayNamearrayName:
837 return(self.arrayData[self.arrayNamearrayName.index(name)])
838 else:
839 msg = "Invalid array name " + name
840 raise Exception(msg)
841
842 def getArrayDimensionLists(self, name):
843 """
844 Gets the nested list of array dimensions for a single array. This can be used to get dimensions for multiple pages at once.
845
846 Args:
847 name (str): Array name.
848
849 Returns:
850 list: Nested list of array dimensions.
851
852 Raises:
853 Exception: If the array name is invalid.
854 """
855 numberOfArrays = len(self.arrayNamearrayName)
856 if name in self.arrayNamearrayName:
857 return(self.arrayDimensions[self.arrayNamearrayName.index(name)])
858 else:
859 msg = "Invalid array name " + name
860 raise Exception(msg)
861
862 def setArrayValueList(self, name, valueList, dimensionList, page=1):
863 """
864 Sets a single array value and dimension at a specific page.
865
866 Args:
867 name (str): Array name.
868 valueList (list): Array values.
869 dimensionList (list): Array dimensions.
870 page (int, optional): Page number (1-based index, defaults to 1).
871
872 Raises:
873 Exception: If the array name or page is invalid.
874
875 This method sets the array values and dimensions at the specified page.
876 """
877 page = page - 1
878 numberOfArrays = len(self.arrayNamearrayName)
879 if name in self.arrayNamearrayName:
880 i = self.arrayNamearrayName.index(name)
881 if len(self.arrayData[i]) == page:
882 self.arrayData[i][page:] = [valueList]
883 self.arrayDimensions[i][page:] = [dimensionList]
884 elif len(self.arrayData[i]) < page or page < 0:
885 msg = "Invalid page " + str(page + 1)
886 raise Exception(msg)
887 else:
888 self.arrayData[i][page] = valueList
889 self.arrayDimensions[i][page] = dimensionList
890 else:
891 msg = "Invalid array name " + name
892 raise Exception(msg)
893
894 def getArrayValueList(self, name, page=1):
895 """
896 Gets a single array value at a specific page.
897
898 Args:
899 name (str): Array name.
900 page (int, optional): Page number (1-based index, defaults to 1).
901
902 Returns:
903 list: Array values.
904
905 Raises:
906 Exception: If the array name or page is invalid.
907 """
908 page = page - 1
909 numberOfArrays = len(self.arrayNamearrayName)
910 if name in self.arrayNamearrayName:
911 i = self.arrayNamearrayName.index(name)
912 if len(self.arrayData[i]) == page:
913 return(self.arrayData[i][page:])
914 elif len(self.arrayData[i]) < page or page < 0:
915 msg = "Invalid page " + str(page + 1)
916 raise Exception(msg)
917 else:
918 return(self.arrayData[i][page])
919 else:
920 msg = "Invalid array name " + name
921 raise Exception(msg)
922
923 def getArrayDimensionList(self, name, page=1):
924 """
925 Gets a single array dimension at a specific page.
926
927 Args:
928 name (str): Array name.
929 page (int, optional): Page number (1-based index, defaults to 1).
930
931 Returns:
932 list: Array dimension.
933
934 Raises:
935 Exception: If the array name or page is invalid.
936 """
937 page = page - 1
938 numberOfArrays = len(self.arrayNamearrayName)
939 if name in self.arrayNamearrayName:
940 i = self.arrayNamearrayName.index(name)
941 if len(self.arrayData[i]) == page:
942 return(self.arrayDimensions[i][page:])
943 elif len(self.arrayData[i]) < page or page < 0:
944 msg = "Invalid page " + str(page + 1)
945 raise Exception(msg)
946 else:
947 return(self.arrayDimensions[i][page])
948 else:
949 msg = "Invalid array name " + name
950 raise Exception(msg)
951
952 def setColumnValueLists(self, name, valueList):
953 """
954 Sets the nested list of column values for a single column. This can be used to set values for multiple pages at once.
955
956 Args:
957 name (str): Column name.
958 valueList (list): Nested list of column values.
959
960 Raises:
961 Exception: If the column name is invalid.
962
963 This method assigns a list of values to a column across pages.
964 """
965 numberOfColumns = len(self.columnNamecolumnName)
966 if name in self.columnNamecolumnName:
967 self.columnData[self.columnNamecolumnName.index(name)] = valueList
968 else:
969 msg = "Invalid column name " + name
970 raise Exception(msg)
971
972 def getColumnValueLists(self, name):
973 """
974 Gets the nested list of column values for a single column. This can be used to get values for multiple pages at once.
975
976 Args:
977 name (str): Column name.
978
979 Returns:
980 list: Nested list of column values.
981
982 Raises:
983 Exception: If the column name is invalid.
984 """
985 numberOfColumns = len(self.columnNamecolumnName)
986 if name in self.columnNamecolumnName:
987 return(self.columnData[self.columnNamecolumnName.index(name)])
988 else:
989 msg = "Invalid column name " + name
990 raise Exception(msg)
991
992 def setColumnValueList(self, name, valueList, page=1):
993 """
994 Sets a single column value list at a specific page.
995
996 Args:
997 name (str): Column name.
998 valueList (list): Column values.
999 page (int, optional): Page number (1-based index, defaults to 1).
1000
1001 Raises:
1002 Exception: If the column name or page is invalid.
1003
1004 This method sets the column values at the specified page.
1005 """
1006 page = page - 1
1007 if name in self.columnNamecolumnName:
1008 i = self.columnNamecolumnName.index(name)
1009 if len(self.columnData[i]) == page:
1010 self.columnData[i][page:] = [valueList]
1011 elif len(self.columnData[i]) < page or page < 0:
1012 msg = "Invalid page " + str(page + 1)
1013 raise Exception(msg)
1014 else:
1015 self.columnData[i][page] = valueList
1016 else:
1017 msg = "Invalid column name " + name
1018 raise Exception(msg)
1019
1020 def getColumnValueList(self, name, page=1):
1021 """
1022 Gets a single column value list at a specific page.
1023
1024 Args:
1025 name (str): Column name.
1026 page (int, optional): Page number (1-based index, defaults to 1).
1027
1028 Returns:
1029 list: Column values.
1030
1031 Raises:
1032 Exception: If the column name or page is invalid.
1033 """
1034 page = page - 1
1035 numberOfColumns = len(self.columnNamecolumnName)
1036 if name in self.columnNamecolumnName:
1037 i = self.columnNamecolumnName.index(name)
1038 if len(self.columnData[i]) == page:
1039 return(self.columnData[i][page:])
1040 elif len(self.columnData[i]) < page or page < 0:
1041 msg = "Invalid page " + str(page + 1)
1042 raise Exception(msg)
1043 else:
1044 return(self.columnData[i][page])
1045 else:
1046 msg = "Invalid column name " + name
1047 raise Exception(msg)
1048
1049 def setColumnValue(self, name, value, page=1, row=1):
1050 """
1051 Sets a single column value at a specific page and row.
1052
1053 Args:
1054 name (str): Column name.
1055 value: Column value.
1056 page (int, optional): Page number (1-based index, defaults to 1).
1057 row (int, optional): Row number (1-based index, defaults to 1).
1058
1059 Raises:
1060 Exception: If the column name, page, or row is invalid.
1061
1062 This method sets the column value at the specified page and row.
1063 """
1064 page = page - 1
1065 row = row - 1
1066 numberOfColumns = len(self.columnNamecolumnName)
1067 if name in self.columnNamecolumnName:
1068 i = self.columnNamecolumnName.index(name)
1069 if len(self.columnData[i]) == page:
1070 if row == 0:
1071 self.columnData[i][page:] = [[value]]
1072 else:
1073 msg = "Invalid row " + str(row + 1)
1074 raise Exception(msg)
1075 elif len(self.columnData[i]) < page or page < 0:
1076 msg = "Invalid page " + str(page + 1)
1077 raise Exception(msg)
1078 else:
1079 if len(self.columnData[i][page]) == row:
1080 self.columnData[i][page][row:] = [value]
1081 elif len(self.columnData[i][page]) < row or row < 0:
1082 msg = "Invalid row " + str(row + 1)
1083 raise Exception(msg)
1084 else:
1085 self.columnData[i][page][row] = value
1086 else:
1087 msg = "Invalid column name " + name
1088 raise Exception(msg)
1089
1090 def getColumnValue(self, name, page=1, row=1):
1091 """
1092 Gets a single column value at a specific page and row.
1093
1094 Args:
1095 name (str): Column name.
1096 page (int, optional): Page number (1-based index, defaults to 1).
1097 row (int, optional): Row number (1-based index, defaults to 1).
1098
1099 Returns:
1100 value: Column value.
1101
1102 Raises:
1103 Exception: If the column name, page, or row is invalid.
1104 """
1105 page = page - 1
1106 row = row - 1
1107 numberOfColumns = len(self.columnNamecolumnName)
1108 if name in self.columnNamecolumnName:
1109 i = self.columnNamecolumnName.index(name)
1110 if len(self.columnData[i]) == page:
1111 if row == 0:
1112 return(self.columnData[i][page:])
1113 else:
1114 msg = "Invalid row " + str(row + 1)
1115 raise Exception(msg)
1116 elif len(self.columnData[i]) < page or page < 0:
1117 msg = "Invalid page " + str(page + 1)
1118 raise Exception(msg)
1119 else:
1120 if len(self.columnData[i][page]) == row:
1121 return(self.columnData[i][page][row:])
1122 elif len(self.columnData[i][page]) < row or row < 0:
1123 msg = "Invalid row " + str(row + 1)
1124 raise Exception(msg)
1125 else:
1126 return(self.columnData[i][page][row])
1127 else:
1128 msg = "Invalid column name " + name
1129 raise Exception(msg)
1130
1132 """
1133 Retrieves the number of parameters.
1134
1135 Returns:
1136 int: The number of parameters.
1137 """
1138 return(len(self.parameterNameparameterName))
1139
1140 def getArrayCount(self):
1141 """
1142 Retrieves the number of arrays.
1143
1144 Returns:
1145 int: The number of arrays.
1146 """
1147 return(len(self.arrayNamearrayName))
1148
1150 """
1151 Retrieves the number of columns.
1152
1153 Returns:
1154 int: The number of columns.
1155 """
1156 return(len(self.columnNamecolumnName))
1157
1159 """
1160 Retrieves a list of all parameter names.
1161
1162 Returns:
1163 list: A list of parameter names as strings, or an empty list.
1164 """
1165 return(self.parameterNameparameterName)
1166
1167 def getArrayNames(self):
1168 """
1169 Retrieves a list of all array names.
1170
1171 Returns:
1172 list: A list of array names as strings, or an empty list.
1173 """
1174 return(self.arrayNamearrayName)
1175
1177 """
1178 Retrieves a list of all column names.
1179
1180 Returns:
1181 list: A list of column names as strings, or an empty list.
1182 """
1183 return(self.columnNamecolumnName)
1184
1185 def getParameterDatatype(self, name):
1186 """
1187 Retrieves the data type of a parameter.
1188
1189 Args:
1190 name (str): Parameter name.
1191
1192 Returns:
1193 int: Number representing the data type of the parameter.
1194 """
1195 if name in self.parameterNameparameterName:
1196 return(self.parameterDefinition[self.parameterNameparameterName.index(name)][4])
1197 else:
1198 msg = "Invalid parameter name " + name
1199 raise Exception(msg)
1200
1201 def getArrayDatatype(self, name):
1202 """
1203 Retrieves the data type of a array.
1204
1205 Args:
1206 name (str): Array name.
1207
1208 Returns:
1209 int: Number representing the data type of the array.
1210 """
1211 if name in self.arrayNamearrayName:
1212 return(self.arrayDefinition[self.arrayNamearrayName.index(name)][5])
1213 else:
1214 msg = "Invalid array name " + name
1215 raise Exception(msg)
1216
1217 def getColumnDatatype(self, name):
1218 """
1219 Retrieves the data type of a column.
1220
1221 Args:
1222 name (str): Column name.
1223
1224 Returns:
1225 int: Number representing the data type of the column.
1226 """
1227 if name in self.columnNamecolumnName:
1228 return(self.columnDefinition[self.columnNamecolumnName.index(name)][4])
1229 else:
1230 msg = "Invalid column name " + name
1231 raise Exception(msg)
1232
1233 def getParameterUnits(self, name):
1234 """
1235 Retrieves the units of a parameter.
1236
1237 Args:
1238 name (str): Parameter name.
1239
1240 Returns:
1241 str: Units of the parameter.
1242 """
1243 if name in self.parameterNameparameterName:
1244 return(self.parameterDefinition[self.parameterNameparameterName.index(name)][1])
1245 else:
1246 msg = "Invalid parameter name " + name
1247 raise Exception(msg)
1248
1249 def getArrayDatatype(self, name):
1250 """
1251 Retrieves the units of a array.
1252
1253 Args:
1254 name (str): Array name.
1255
1256 Returns:
1257 str: Units of the array.
1258 """
1259 if name in self.arrayNamearrayName:
1260 return(self.arrayDefinition[self.arrayNamearrayName.index(name)][1])
1261 else:
1262 msg = "Invalid array name " + name
1263 raise Exception(msg)
1264
1265 def getColumnDatatype(self, name):
1266 """
1267 Retrieves the units of a column.
1268
1269 Args:
1270 name (str): Column name.
1271
1272 Returns:
1273 str: Units of the column.
1274 """
1275 if name in self.columnNamecolumnName:
1276 return(self.columnDefinition[self.columnNamecolumnName.index(name)][1])
1277 else:
1278 msg = "Invalid column name " + name
1279 raise Exception(msg)
1280
1281 def pageCount(self):
1282 """
1283 Retrieves the number or loaded pages
1284
1285 Returns:
1286 int: Number or loaded pages
1287 """
1288 return(self.loaded_pages)
1289
1290
1291
1292# Expose constants to the module-level namespace
1293SDDS_VERBOSE_PrintErrors = SDDS.SDDS_VERBOSE_PrintErrors
1294SDDS_EXIT_PrintErrors = SDDS.SDDS_EXIT_PrintErrors
1295SDDS_CHECK_OKAY = SDDS.SDDS_CHECK_OKAY
1296SDDS_CHECK_NONEXISTENT = SDDS.SDDS_CHECK_NONEXISTENT
1297SDDS_CHECK_WRONGTYPE = SDDS.SDDS_CHECK_WRONGTYPE
1298SDDS_CHECK_WRONGUNITS = SDDS.SDDS_CHECK_WRONGUNITS
1299SDDS_LONGDOUBLE = SDDS.SDDS_LONGDOUBLE
1300SDDS_DOUBLE = SDDS.SDDS_DOUBLE
1301SDDS_REAL64 = SDDS.SDDS_REAL64
1302SDDS_FLOAT = SDDS.SDDS_FLOAT
1303SDDS_REAL32 = SDDS.SDDS_REAL32
1304SDDS_LONG64 = SDDS.SDDS_LONG64
1305SDDS_INT64 = SDDS.SDDS_INT64
1306SDDS_ULONG64 = SDDS.SDDS_ULONG64
1307SDDS_UINT64 = SDDS.SDDS_UINT64
1308SDDS_LONG = SDDS.SDDS_LONG
1309SDDS_INT32 = SDDS.SDDS_INT32
1310SDDS_ULONG = SDDS.SDDS_ULONG
1311SDDS_UINT32 = SDDS.SDDS_UINT32
1312SDDS_SHORT = SDDS.SDDS_SHORT
1313SDDS_INT16 = SDDS.SDDS_INT16
1314SDDS_USHORT = SDDS.SDDS_USHORT
1315SDDS_UINT16 = SDDS.SDDS_UINT16
1316SDDS_STRING = SDDS.SDDS_STRING
1317SDDS_CHARACTER = SDDS.SDDS_CHARACTER
1318SDDS_NUM_TYPES = SDDS.SDDS_NUM_TYPES
1319SDDS_BINARY = SDDS.SDDS_BINARY
1320SDDS_ASCII = SDDS.SDDS_ASCII
1321SDDS_FLUSH_TABLE = SDDS.SDDS_FLUSH_TABLE
1322
1323def load(input_file) -> SDDS:
1324 """
1325 Loads an SDDS file into the SDDS object.
1326
1327 Args:
1328 input_file (str): The input SDDS filename to load.
1329
1330 Raises:
1331 Exception: If unable to read the SDDS data.
1332
1333 This method reads the SDDS file specified by `input`, and populates the object's data structures
1334 with the parameters, arrays, columns, and their respective data.
1335 """
1336
1337 # Initialize an SDDS object
1338 sdds_obj = SDDS()
1339
1340 # Load the file
1341 try:
1342 sdds_obj.load(input_file)
1343 except Exception as e:
1344 raise ValueError(f"Failed to load the SDDS file: {e}")
1345
1346 return sdds_obj
1347
1348def loadSparse(input_file, interval, offset) -> SDDS:
1349 """
1350 Loads an SDDS file into the SDDS object with sparse data reading.
1351
1352 Args:
1353 input_file (str): The input SDDS filename to load.
1354 interval (int): Interval between pages to read.
1355 offset (int): Offset to start reading from.
1356
1357 Raises:
1358 Exception: If unable to read the SDDS data.
1359
1360 This method reads every `interval` pages from the SDDS file, starting from the page at `offset`.
1361 """
1362 # Initialize an SDDS object
1363 sdds_obj = SDDS()
1364
1365 # Load the file
1366 try:
1367 sdds_obj.loadSparse(input_file, interval, offset)
1368 except Exception as e:
1369 raise ValueError(f"Failed to load the SDDS file: {e}")
1370
1371 return sdds_obj
1372
1373def loadLastRows(input_file, lastrows) -> SDDS:
1374 """
1375 Loads an SDDS file into the SDDS object, reading only the last few rows.
1376
1377 Args:
1378 input_file (str): The input SDDS filename to load.
1379 lastrows (int): Number of last rows to read.
1380
1381 Raises:
1382 Exception: If unable to read the SDDS data.
1383
1384 This method reads only the last `lastrows` rows from each page of the SDDS file.
1385 """
1386 # Initialize an SDDS object
1387 sdds_obj = SDDS()
1388
1389 # Load the file
1390 try:
1391 sdds_obj.loadLastRows(input_file, lastrows)
1392 except Exception as e:
1393 raise ValueError(f"Failed to load the SDDS file: {e}")
1394
1395 return sdds_obj
1396
1397def save(sdds_obj : SDDS, output_file):
1398 """
1399 Saves the SDDS object's data to an SDDS file.
1400
1401 Args:
1402 output (str): The output SDDS filename to save the data.
1403
1404 Raises:
1405 Exception: If unable to write the SDDS data.
1406
1407 This method writes the data stored in the SDDS object to the specified file, including the
1408 parameters, arrays, columns, and their data.
1409 """
1410 # Save the file
1411 try:
1412 sdds_obj.save(output_file)
1413 except Exception as e:
1414 raise ValueError(f"Failed to load the SDDS file: {e}")
1415
1416def sdds_data_type_to_string(data_type_code):
1417 """
1418 Converts a numeric SDDS data type code to its string representation.
1419
1420 Args:
1421 data_type_code (int): Numeric code of the SDDS data type.
1422
1423 Returns:
1424 str: String representation of the SDDS data type.
1425 """
1426 # Mapping of SDDS numeric data type codes to string representations
1427 data_type_map = {
1428 1: "SDDS_LONGDOUBLE",
1429 2: "SDDS_DOUBLE",
1430 3: "SDDS_FLOAT",
1431 4: "SDDS_LONG64",
1432 5: "SDDS_ULONG64",
1433 6: "SDDS_LONG",
1434 7: "SDDS_ULONG",
1435 8: "SDDS_SHORT",
1436 9: "SDDS_USHORT",
1437 10: "SDDS_STRING",
1438 11: "SDDS_CHARACTER",
1439 }
1440 return data_type_map.get(data_type_code, "Unknown Data Type")
1441
1442def sdds_data_type_to_short_string(data_type_code):
1443 """
1444 Converts a numeric SDDS data type code to its short string representation.
1445
1446 Args:
1447 data_type_code (int): Numeric code of the SDDS data type.
1448
1449 Returns:
1450 str: String representation of the SDDS data type.
1451 """
1452 # Mapping of SDDS numeric data type codes to string representations
1453 data_type_map = {
1454 1: "longdouble",
1455 2: "double",
1456 3: "float",
1457 4: "long64",
1458 5: "ulong64",
1459 6: "long",
1460 7: "ulong",
1461 8: "short",
1462 9: "ushort",
1463 10: "string",
1464 11: "character",
1465 }
1466 return data_type_map.get(data_type_code, "Unknown Data Type")
1467
1468def sdds_short_string_to_data_type(data_type_code):
1469 """
1470 Converts a numeric SDDS data type code to its short string representation.
1471
1472 Args:
1473 data_type_code (string): String representation of the SDDS data type.
1474
1475 Returns:
1476 int: Numeric code of the SDDS data type.
1477 """
1478 # Mapping of SDDS numeric data type codes to string representations
1479 data_type_map = {
1480 "longdouble": 1,
1481 "double": 2,
1482 "float": 3,
1483 "long64": 4,
1484 "ulong64": 5,
1485 "long": 6,
1486 "ulong": 7,
1487 "short": 8,
1488 "ushort": 9,
1489 "string": 10,
1490 "character": 11,
1491 }
1492 return data_type_map.get(data_type_code, "Unknown Data Type")
1493
1494def demo1(output):
1495 """
1496 Demonstrates how to save a demo SDDS file using the SDDS class.
1497
1498 Args:
1499 output (str): The output SDDS filename to save the demo data.
1500
1501 This function creates an SDDS object, populates it with sample data, and saves it to the specified output file.
1502 """
1503 x = SDDS()
1504 x.description[0] = "text"
1505 x.description[1] = "contents"
1506 x.parameterName = ["ShortP", "LongP", "FloatP", "DoubleP", "StringP", "CharacterP"]
1507 x.parameterData = [[1, 6], [2, 7], [3.3, 8.8], [4.4, 9.8], ["five", "ten"], ["a", "b"]]
1508 x.parameterDefinition = [
1509 ["", "", "", "", x.SDDS_SHORT, ""],
1510 ["", "", "", "", x.SDDS_LONG, ""],
1511 ["", "", "", "", x.SDDS_FLOAT, ""],
1512 ["", "", "", "", x.SDDS_DOUBLE, ""],
1513 ["", "", "", "", x.SDDS_STRING, ""],
1514 ["", "", "", "", x.SDDS_CHARACTER, ""],
1515 ]
1516
1517 x.arrayName = ["ShortA", "LongA", "FloatA", "DoubleA", "StringA", "CharacterA"]
1518 x.arrayDefinition = [
1519 ["", "", "", "", "", x.SDDS_SHORT, 0, 1],
1520 ["", "", "", "", "", x.SDDS_LONG, 0, 1],
1521 ["", "", "", "", "", x.SDDS_FLOAT, 0, 2],
1522 ["", "", "", "", "", x.SDDS_DOUBLE, 0, 1],
1523 ["", "", "", "", "", x.SDDS_STRING, 0, 1],
1524 ["", "", "", "", "", x.SDDS_CHARACTER, 0, 1],
1525 ]
1526 x.arrayDimensions = [
1527 [[6], [8]],
1528 [[5], [7]],
1529 [[2, 3], [2, 4]],
1530 [[4], [5]],
1531 [[4], [5]],
1532 [[4], [5]],
1533 ]
1534 x.arrayData = [
1535 [[1, 2, 3, 4, 5, 6], [1, 2, 3, 4, 5, 6, 7, 8]],
1536 [[1, 2, 3, 4, 5], [1, 2, 3, 4, 5, 6, 7]],
1537 [[1, 2, 3, 4, 5, 6], [1, 2, 3, 4, 5, 6, 7, 8]],
1538 [[1, 2, 3, 4], [1, 2, 3, 4, 5]],
1539 [["one", "two", "three", "four"], ["five", "six", "seven", "eight", "nine"]],
1540 [["a", "b", "c", "d"], ["e", "f", "g", "h", "i"]],
1541 ]
1542
1543 x.columnName = ["ShortC", "LongC", "FloatC", "DoubleC", "StringC", "CharacterC"]
1544 x.columnData = [
1545 [[1, 2, 3], [-1, -2, -3, -4]],
1546 [[1, 2, 3], [-1, -2, -3, -4]],
1547 [[1, 2, 3], [-1, -2, -3.6, -4.4]],
1548 [[1, 2, 3], [-1, -2, -3.6, -4.4]],
1549 [["row 1", "row 2", "row 3"], ["row 1", "row 2", "row 3", "row 4"]],
1550 [["x", "y", "z"], ["i", "j", "k", "l"]],
1551 ]
1552 x.columnDefinition = [
1553 ["", "", "", "", x.SDDS_SHORT, 0],
1554 ["", "", "", "", x.SDDS_LONG, 0],
1555 ["", "", "", "", x.SDDS_FLOAT, 0],
1556 ["", "", "", "", x.SDDS_DOUBLE, 0],
1557 ["", "", "", "", x.SDDS_STRING, 0],
1558 ["", "", "", "", x.SDDS_CHARACTER, 0],
1559 ]
1560
1561 x.save(output)
1562 del x
1563
1564
1565def demo2(output):
1566 """
1567 Demonstrates how to save a demo SDDS file using the SDDS class with simplified definitions.
1568
1569 Args:
1570 output (str): The output SDDS filename to save the demo data.
1571
1572 This function shows how to use simplified methods to define parameters, arrays, and columns.
1573 """
1574 x = SDDS()
1575 x.setDescription("text", "contents")
1576 names = ["Short", "Long", "Float", "Double", "String", "Character"]
1577 types = [x.SDDS_SHORT, x.SDDS_LONG, x.SDDS_FLOAT, x.SDDS_DOUBLE, x.SDDS_STRING, x.SDDS_CHARACTER]
1578 for i in range(6):
1579 x.defineSimpleParameter(names[i] + "P", types[i])
1580 if types[i] == x.SDDS_FLOAT:
1581 x.defineSimpleArray(names[i] + "A", types[i], 2)
1582 else:
1583 x.defineSimpleArray(names[i] + "A", types[i], 1)
1584 x.defineSimpleColumn(names[i] + "C", types[i])
1585 parameterData = [[1, 6], [2, 7], [3.3, 8.8], [4.4, 9.8], ["five", "ten"], ["a", "b"]]
1586 for i in range(6):
1587 x.setParameterValueList(names[i] + "P", parameterData[i])
1588
1589 arrayDimensions = [
1590 [[6], [8]],
1591 [[5], [7]],
1592 [[2, 3], [2, 4]],
1593 [[4], [5]],
1594 [[4], [5]],
1595 [[4], [5]],
1596 ]
1597 arrayData = [
1598 [[1, 2, 3, 4, 5, 6], [1, 2, 3, 4, 5, 6, 7, 8]],
1599 [[1, 2, 3, 4, 5], [1, 2, 3, 4, 5, 6, 7]],
1600 [[1, 2, 3, 4, 5, 6], [1, 2, 3, 4, 5, 6, 7, 8]],
1601 [[1, 2, 3, 4], [1, 2, 3, 4, 5]],
1602 [["one", "two", "three", "four"], ["five", "six", "seven", "eight", "nine"]],
1603 [["a", "b", "c", "d"], ["e", "f", "g", "h", "i"]],
1604 ]
1605 for i in range(6):
1606 x.setArrayValueLists(names[i] + "A", arrayData[i], arrayDimensions[i])
1607
1608 columnData = [
1609 [[1, 2, 3], [-1, -2, -3, -4]],
1610 [[1, 2, 3], [-1, -2, -3, -4]],
1611 [[1, 2, 3], [-1, -2, -3.6, -4.4]],
1612 [[1, 2, 3], [-1, -2, -3.6, -4.4]],
1613 [["row 1", "row 2", "row 3"], ["row 1", "row 2", "row 3", "row 4"]],
1614 [["x", "y", "z"], ["i", "j", "k", "l"]],
1615 ]
1616 for i in range(6):
1617 x.setColumnValueLists(names[i] + "C", columnData[i])
1618 x.save(output)
1619
1620
1621def demo3(output):
1622 """
1623 Demonstrates how to save a demo SDDS file using `sddsdata` commands directly.
1624
1625 Args:
1626 output (str): The output SDDS filename to save the demo data.
1627
1628 This function shows how to use `sddsdata` module functions directly to create and save an SDDS file.
1629 """
1630 x = SDDS()
1631
1632 try:
1633 # Open SDDS output file
1634 if sddsdata.InitializeOutput(x.index, x.SDDS_BINARY, 1, "", "", output) != 1:
1635 raise ValueError("Failed to initialize SDDS output.")
1636 # Setting column_major to true. Only use this if you are going to write whole columns and not one row at a time.
1637 sddsdata.SetColumnMajorOrder(x.index)
1638 # Define parameters
1639 if sddsdata.DefineSimpleParameter(x.index, "ParameterA", "mm", x.SDDS_DOUBLE) != 1:
1640 raise ValueError("Failed to define parameter.")
1641 # Define arrays
1642 if sddsdata.DefineSimpleArray(x.index, "ArrayA", "DegC", x.SDDS_DOUBLE, 1) != 1:
1643 raise ValueError("Failed to define array.")
1644 if sddsdata.DefineSimpleArray(x.index, "ArrayB", "DegC", x.SDDS_DOUBLE, 2) != 1:
1645 raise ValueError("Failed to define array.")
1646 # Define columns
1647 if sddsdata.DefineSimpleColumn(x.index, "ColumnA", "Volts", x.SDDS_DOUBLE) != 1:
1648 raise ValueError("Failed to define column.")
1649 if sddsdata.DefineSimpleColumn(x.index, "ColumnB", "Amps", x.SDDS_DOUBLE) != 1:
1650 raise ValueError("Failed to define column.")
1651 # Write SDDS header
1652 if sddsdata.WriteLayout(x.index) != 1:
1653 raise ValueError("Failed to write SDDS layout.")
1654 # Start SDDS page. Allocate 100 rows.
1655 if sddsdata.StartPage(x.index, 100) != 1:
1656 raise ValueError("Failed to start SDDS page.")
1657 # Set parameter values
1658 if sddsdata.SetParameter(x.index, "ParameterA", 1.1) != 1:
1659 raise ValueError("Failed to set parameter value.")
1660 # Set array values
1661 if sddsdata.SetArray(x.index, "ArrayA", [1, 2, 3], [3]) != 1:
1662 raise ValueError("Failed to set array value.")
1663 if sddsdata.SetArray(x.index, "ArrayB", [1, 2, 3, 4, 5, 6], [2, 3]) != 1:
1664 raise ValueError("Failed to set array value.")
1665 # Set column values
1666 if sddsdata.SetColumn(x.index, "ColumnA", [1, 2, 3]) != 1:
1667 raise ValueError("Failed to set column value.")
1668 if sddsdata.SetColumn(x.index, "ColumnB", [1, 2, 3]) != 1:
1669 raise ValueError("Failed to set column value.")
1670 # Write page to disk
1671 if sddsdata.WritePage(x.index) != 1:
1672 raise ValueError("Failed to write SDDS page.")
1673 # Close SDDS output file
1674 if sddsdata.Terminate(x.index) != 1:
1675 raise ValueError("Failed to terminate SDDS output.")
1676
1677 except:
1678 sddsdata.PrintErrors(x.SDDS_VERBOSE_PrintErrors)
1679 raise
1680
1681
1682def demo4(output):
1683 """
1684 Demonstrates how to save a demo SDDS file using `sddsdata` commands and writing one row at a time.
1685
1686 Args:
1687 output (str): The output SDDS filename to save the demo data.
1688
1689 This function shows how to write data to an SDDS file one row at a time, useful for logging applications.
1690 """
1691 x = SDDS()
1692
1693 try:
1694 # Open SDDS output file
1695 if sddsdata.InitializeOutput(x.index, x.SDDS_BINARY, 1, "", "", output) != 1:
1696 raise ValueError("Failed to initialize SDDS output.")
1697 # Turning on fsync mode and fixed rows count mode. These are useful for loggers.
1698 sddsdata.EnableFSync(x.index)
1699 sddsdata.SetFixedRowCountMode(x.index)
1700 # Define parameters
1701 if sddsdata.DefineSimpleParameter(x.index, "ParameterA", "mm", x.SDDS_DOUBLE) != 1:
1702 raise ValueError("Failed to define parameter.")
1703 # Define arrays
1704 if sddsdata.DefineSimpleArray(x.index, "ArrayA", "DegC", x.SDDS_DOUBLE, 1) != 1:
1705 raise ValueError("Failed to define array.")
1706 if sddsdata.DefineSimpleArray(x.index, "ArrayB", "DegC", x.SDDS_DOUBLE, 2) != 1:
1707 raise ValueError("Failed to define array.")
1708 # Define columns
1709 if sddsdata.DefineSimpleColumn(x.index, "ColumnA", "Volts", x.SDDS_DOUBLE) != 1:
1710 raise ValueError("Failed to define column.")
1711 if sddsdata.DefineSimpleColumn(x.index, "ColumnB", "Amps", x.SDDS_DOUBLE) != 1:
1712 raise ValueError("Failed to define column.")
1713 # Write SDDS header
1714 if sddsdata.WriteLayout(x.index) != 1:
1715 raise ValueError("Failed to write SDDS layout.")
1716 # Start SDDS page, allocate 2 rows.
1717 if sddsdata.StartPage(x.index, 2) != 1:
1718 raise ValueError("Failed to start SDDS page.")
1719 # Set parameter values
1720 if sddsdata.SetParameter(x.index, "ParameterA", 1.1) != 1:
1721 raise ValueError("Failed to set parameter value.")
1722 # Set array values
1723 if sddsdata.SetArray(x.index, "ArrayA", [1, 2, 3], [3]) != 1:
1724 raise ValueError("Failed to set array value.")
1725 if sddsdata.SetArray(x.index, "ArrayB", [1, 2, 3, 4, 5, 6], [2, 3]) != 1:
1726 raise ValueError("Failed to set array value.")
1727 # Set all columns, one row at a time
1728 if sddsdata.SetRowValues(x.index, 0, ["ColumnA", 1, "ColumnB", 1]) != 1:
1729 raise ValueError("Failed to set row values.")
1730 if sddsdata.SetRowValues(x.index, 1, ["ColumnA", 2, "ColumnB", 2]) != 1:
1731 raise ValueError("Failed to set row values.")
1732 # Update page because we reached the row allocation limit set in the StartPage command
1733 if sddsdata.UpdatePage(x.index, x.SDDS_FLUSH_TABLE) != 1:
1734 raise ValueError("Failed to update SDDS page.")
1735 # Set more rows
1736 if sddsdata.SetRowValues(x.index, 2, ["ColumnA", 3, "ColumnB", 3]) != 1:
1737 raise ValueError("Failed to set row values.")
1738 # Update page
1739 if sddsdata.UpdatePage(x.index, x.SDDS_FLUSH_TABLE) != 1:
1740 raise ValueError("Failed to update SDDS page.")
1741 # Close SDDS output file
1742 if sddsdata.Terminate(x.index) != 1:
1743 raise ValueError("Failed to terminate SDDS output.")
1744
1745 except:
1746 sddsdata.PrintErrors(x.SDDS_VERBOSE_PrintErrors)
1747 raise
1748
1749
1750def demo5(output):
1751 """
1752 Demonstrates how to open an existing SDDS file and add rows to the last page without loading the whole file into memory.
1753
1754 Args:
1755 output (str): The output SDDS filename to append data.
1756
1757 This function shows how to append data to an existing SDDS file efficiently.
1758 """
1759 x = SDDS()
1760
1761 try:
1762 # Open SDDS output file
1763 rows = sddsdata.InitializeAppendToPage(x.index, output, 100)
1764 if rows == 0:
1765 raise ValueError("Failed to initialize appending to SDDS page.")
1766 # Set all columns, one row at a time
1767 if sddsdata.SetRowValues(x.index, rows, ["ColumnA", 4, "ColumnB", 4]) != 1:
1768 raise ValueError("Failed to set row values.")
1769 if sddsdata.SetRowValues(x.index, rows + 1, ["ColumnA", 5, "ColumnB", 5]) != 1:
1770 raise ValueError("Failed to set row values.")
1771 if sddsdata.SetRowValues(x.index, rows + 2, ["ColumnA", 6, "ColumnB", 6]) != 1:
1772 raise ValueError("Failed to set row values.")
1773 # Update page
1774 if sddsdata.UpdatePage(x.index, x.SDDS_FLUSH_TABLE) != 1:
1775 raise ValueError("Failed to update SDDS page.")
1776 # Close SDDS output file
1777 if sddsdata.Terminate(x.index) != 1:
1778 raise ValueError("Failed to terminate SDDS output.")
1779
1780 except:
1781 sddsdata.PrintErrors(x.SDDS_VERBOSE_PrintErrors)
1782 raise
1783
1784
1785def demo6(output):
1786 """
1787 Demonstrates how to open an existing SDDS file and add a new page.
1788
1789 Args:
1790 output (str): The output SDDS filename to append data.
1791
1792 This function shows how to append a new page to an existing SDDS file.
1793 """
1794 x = SDDS()
1795
1796 try:
1797 # Open SDDS output file
1798 if sddsdata.InitializeAppend(x.index, output) != 1:
1799 raise ValueError("Failed to initialize appending to SDDS file.")
1800 # Allocate rows
1801 if sddsdata.StartPage(x.index, 100) != 1:
1802 raise ValueError("Failed to start SDDS page.")
1803 # Set parameter values
1804 if sddsdata.SetParameter(x.index, "ParameterA", 1.1) != 1:
1805 raise ValueError("Failed to set parameter value.")
1806 # Set array values
1807 if sddsdata.SetArray(x.index, "ArrayA", [1, 2, 3], [3]) != 1:
1808 raise ValueError("Failed to set array value.")
1809 if sddsdata.SetArray(x.index, "ArrayB", [1, 2, 3, 4, 5, 6], [2, 3]) != 1:
1810 raise ValueError("Failed to set array value.")
1811 # Set all columns, one row at a time
1812 if sddsdata.SetRowValues(x.index, 0, ["ColumnA", 7, "ColumnB", 7]) != 1:
1813 raise ValueError("Failed to set row values.")
1814 if sddsdata.SetRowValues(x.index, 1, ["ColumnA", 8, "ColumnB", 8]) != 1:
1815 raise ValueError("Failed to set row values.")
1816 if sddsdata.SetRowValues(x.index, 2, ["ColumnA", 9, "ColumnB", 9]) != 1:
1817 raise ValueError("Failed to set row values.")
1818 # Write page
1819 if sddsdata.WritePage(x.index) != 1:
1820 raise ValueError("Failed to write SDDS page.")
1821 # Close SDDS output file
1822 if sddsdata.Terminate(x.index) != 1:
1823 raise ValueError("Failed to terminate SDDS output.")
1824
1825 except:
1826 sddsdata.PrintErrors(x.SDDS_VERBOSE_PrintErrors)
1827 raise
1828
1829@dataclass
1831 text: Optional[str] = None
1832 contents: Optional[str] = None
1833@dataclass
1835 name: str
1836 type: str
1837 symbol: Optional[Any] = None
1838 units: Optional[Any] = None
1839 description: Optional[Any] = None
1840 format_string: Optional[Any] = None
1841 fixed_value: Optional[str] = None
1842@dataclass
1843class Array:
1844 name: str
1845 type: str
1846 symbol: Optional[Any] = None
1847 units: Optional[Any] = None
1848 description: Optional[Any] = None
1849 format_string: Optional[Any] = None
1850 group_name: Optional[Any] = None
1851 field_length: Optional[Any] = None
1852 dimensions: Optional[Any] = None
1853@dataclass
1855 name: str
1856 type: str
1857 symbol: Optional[Any] = None
1858 units: Optional[Any] = None
1859 description: Optional[Any] = None
1860 format_string: Optional[Any] = None
1861 field_length: Optional[Any] = None
1863 def __init__(self):
1864 self.pages = 0
1865 self.binary = False
1866 self.definitions = {}
1867 self.values = {}
1868 self.array_dims = {}
1869
1870def read(input_file) -> SddsFile:
1871 """
1872 Mostly backward compatible with the PyLHC sdds module read() function.
1873 Unlike the PyLHC version, this function reads all the SDDS pages and works with column data.
1874 The data is returned in a structured dictionary.
1875
1876 Args:
1877 input_file (str): The input SDDS file to be read.
1878
1879 Returns:
1880 dict: A dictionary with parameters, arrays, and columns data.
1881 Example structure:
1882 {
1883 pages = {integer},
1884 binary = {boolean},
1885 "definitions": {name: {"type:" string, "units": string, "description": string},
1886 "values": {parameter_name: {[Page1Value, Page2Value, ...]},
1887 {array_name: {[Page1List, Page2List, ...]},
1888 {column_name: {[Page1List, Page2List, ...]},
1889 "values": {array_name: {[page1DimList, Page2DimList, ...]}
1890 }
1891 """
1892 # Initialize an SDDS object
1893 sdds_obj = SDDS()
1894
1895 # Load the file
1896 try:
1897 sdds_obj.load(input_file)
1898 except Exception as e:
1899 raise ValueError(f"Failed to load the SDDS file: {e}")
1900
1901 # Initialize the output dictionary
1902 sdds_data = SddsFile()
1903
1904 # Store the data mode (ascii or binary)
1905 if sdds_obj.mode == SDDS.SDDS_BINARY:
1906 sdds_data.binary = True
1907 else:
1908 sdds_data.binary = False
1909
1910 # Store description data
1911 text = sdds_obj.description[0] if sdds_obj.description[0] != "" else None
1912 contents = sdds_obj.description[1] if sdds_obj.description[1] != "" else None
1913 description_instance = Description(text=text, contents=contents)
1914 sdds_data.description = description_instance
1915
1916 # Store number of pages
1917 sdds_data.pages = sdds_obj.loaded_pages
1918
1919 # Store parameter data
1920 if sdds_obj.parameterName:
1921 for i, definition in enumerate(sdds_obj.parameterDefinition):
1922 name = sdds_obj.parameterName[i]
1923 symbol = definition[0] if definition[0] != '' else None
1924 units = definition[1] if definition[1] != '' else None
1925 description = definition[2] if definition[2] != '' else None
1926 formatString = definition[3] if definition[3] != '' else None
1927 datatype = sdds_data_type_to_short_string(definition[4])
1928 fixedValue = definition[5] if definition[5] != '' else None
1929 parameter_instance = Parameter(name=name, type=datatype, symbol=symbol, units=units, description=description, format_string=formatString, fixed_value=fixedValue)
1930 sdds_data.definitions.update({name: parameter_instance})
1931 sdds_data.values.update({name: sdds_obj.parameterData[i]})
1932
1933 # Store array data
1934 if sdds_obj.arrayName:
1935 for i, definition in enumerate(sdds_obj.arrayDefinition):
1936 name = sdds_obj.arrayName[i]
1937 symbol = definition[0] if definition[0] != '' else None
1938 units = definition[1] if definition[1] != '' else None
1939 description = definition[2] if definition[2] != '' else None
1940 formatString = definition[3] if definition[3] != '' else None
1941 group_name = definition[4] if definition[4] != '' else None
1942 datatype = sdds_data_type_to_short_string(definition[5])
1943 fieldLength = definition[6] if definition[6] != 0 else None
1944 dimensions = definition[7] if definition[7] != '' else None
1945 array_instance = Array(name=name, type=datatype, symbol=symbol, units=units, description=description, format_string=formatString, group_name=group_name, field_length=fieldLength, dimensions=dimensions)
1946 sdds_data.definitions.update({name: array_instance})
1947 sdds_data.values.update({name: sdds_obj.arrayData[i]})
1948 sdds_data.array_dims.update({name: sdds_obj.arrayDimensions[i]})
1949
1950 # Store column data
1951 if sdds_obj.columnName:
1952 for i, definition in enumerate(sdds_obj.columnDefinition):
1953 name = sdds_obj.columnName[i]
1954 symbol = definition[0] if definition[0] != '' else None
1955 units = definition[1] if definition[1] != '' else None
1956 description = definition[2] if definition[2] != '' else None
1957 formatString = definition[3] if definition[3] != '' else None
1958 datatype = sdds_data_type_to_short_string(definition[4])
1959 fieldLength = definition[5] if definition[5] != 0 else None
1960 column_instance = Column(name=name, type=datatype, symbol=symbol, units=units, description=description, format_string=formatString, field_length=fieldLength)
1961 sdds_data.definitions.update({name: column_instance})
1962 sdds_data.values.update({name: sdds_obj.columnData[i]})
1963
1964 # Return the dictionary
1965 return sdds_data
1966
1967def write(sdds_file: SddsFile, output_file):
1968 """
1969 Mostly backward compatible with the PyLHC sdds module write() function.
1970 Unlike the PyLHC version, this function writes all the SDDS pages and works with column data.
1971 The data is expected to be in a structured dictionary like that returned from the read() function.
1972
1973 Args:
1974 output_file (str): The output SDDS file to be written to.
1975 """
1976 # Initialize an SDDS object
1977 sdds_obj = SDDS()
1978
1979 # Set the data mode (ascii or binary)
1980 if hasattr(sdds_file, 'binary'):
1981 if sdds_file.binary:
1982 sdds_obj.mode = SDDS.SDDS_BINARY
1983 else:
1984 sdds_obj.mode = SDDS.SDDS_ASCII
1985
1986 # Set description data
1987 if hasattr(sdds_file, 'description'):
1988 text = sdds_file.description.text if sdds_file.description.text != None else ''
1989 contents = sdds_file.description.contents if sdds_file.description.contents != None else ''
1990 sdds_obj.setDescription(text, contents)
1991
1992 for name in sdds_file.definitions:
1993 if isinstance(sdds_file.definitions[name], Parameter):
1994 # Set parameter data
1995 parameter_instance = sdds_file.definitions[name]
1996 symbol = parameter_instance.symbol if parameter_instance.symbol != None else ""
1997 units = parameter_instance.units if parameter_instance.units != None else ""
1998 description = parameter_instance.description if parameter_instance.description != None else ""
1999 formatString = parameter_instance.format_string if parameter_instance.format_string != None else ""
2000 datatype = sdds_short_string_to_data_type(parameter_instance.type)
2001 fixedValue = parameter_instance.fixed_value if parameter_instance.fixed_value != None else ""
2002 sdds_obj.defineParameter(name, symbol=symbol, units=units, description=description,
2003 formatString=formatString, type=datatype, fixedValue=fixedValue)
2004 sdds_obj.setParameterValueList(name, sdds_file.values[name])
2005 elif isinstance(sdds_file.definitions[name], Array):
2006 # Set array data
2007 array_instance = sdds_file.definitions[name]
2008 symbol = array_instance.symbol if array_instance.symbol != None else ""
2009 units = array_instance.units if array_instance.units != None else ""
2010 description = array_instance.description if array_instance.description != None else ""
2011 formatString = array_instance.format_string if array_instance.format_string != None else ""
2012 group_name = array_instance.group_name if array_instance.group_name != None else ""
2013 datatype = sdds_short_string_to_data_type(array_instance.type)
2014 fieldLength = array_instance.field_length if array_instance.field_length != None else 0
2015 dimensions = array_instance.dimensions if array_instance.dimensions != None else 1
2016 sdds_obj.defineArray(name, symbol=symbol, units=units, description=description,
2017 formatString=formatString, group_name=group_name, type=datatype,
2018 fieldLength=fieldLength, dimensions=dimensions)
2019 sdds_obj.setArrayValueLists(name, sdds_file.values[name], sdds_file.array_dims[name])
2020 elif isinstance(sdds_file.definitions[name], Column):
2021 # Set column data
2022 column_instance = sdds_file.definitions[name]
2023 symbol = column_instance.symbol if column_instance.symbol != None else ""
2024 units = column_instance.units if column_instance.units != None else ""
2025 description = column_instance.description if column_instance.description != None else ""
2026 formatString = column_instance.format_string if column_instance.format_string != None else ""
2027 datatype = sdds_short_string_to_data_type(column_instance.type)
2028 fieldLength = column_instance.field_length if column_instance.field_length != None else 0
2029 sdds_obj.defineColumn(name, symbol=symbol, units=units, description=description,
2030 formatString=formatString, type=datatype, fieldLength=fieldLength)
2031 sdds_obj.setColumnValueLists(name, sdds_file.values[name])
2032
2033 # Set the data to the output file
2034 sdds_obj.save(output_file)
A class to represent and manipulate SDDS datasets.
Definition sdds.py:22
getColumnValueLists(self, name)
Gets the nested list of column values for a single column.
Definition sdds.py:972
defineSimpleParameter(self, name, type)
Defines a simple parameter with minimal information.
Definition sdds.py:556
list parameterDefinition
Definition sdds.py:118
setArrayValueLists(self, name, valueList, dimensionList)
Sets the nested list of array values and dimensions for a single array.
Definition sdds.py:799
defineArray(self, name, symbol="", units="", description="", formatString="", group_name="", type=SDDS_DOUBLE, fieldLength=0, dimensions=1)
Defines an array for the SDDS object.
Definition sdds.py:581
defineSimpleColumn(self, name, type)
Defines a simple column with minimal information.
Definition sdds.py:675
getColumnValueList(self, name, page=1)
Gets a single column value list at a specific page.
Definition sdds.py:1020
loadSparse(self, input, interval, offset)
Loads an SDDS file into the SDDS object with sparse data reading.
Definition sdds.py:216
list parameterData
Definition sdds.py:122
getArrayCount(self)
Retrieves the number of arrays.
Definition sdds.py:1140
getArrayDatatype(self, name)
Retrieves the data type of a array.
Definition sdds.py:1201
load(self, input)
Loads an SDDS file into the SDDS object.
Definition sdds.py:135
getArrayValueLists(self, name)
Gets the nested list of array values for a single array.
Definition sdds.py:822
setParameterValue(self, name, value, page=1)
Sets a single parameter value at a specific page.
Definition sdds.py:741
__init__(self, index=None)
Initializes a new SDDS object.
Definition sdds.py:85
getColumnCount(self)
Retrieves the number of columns.
Definition sdds.py:1149
list arrayData
Definition sdds.py:123
getColumnValue(self, name, page=1, row=1)
Gets a single column value at a specific page and row.
Definition sdds.py:1090
setParameterValueList(self, name, valueList)
Sets the list of parameter values for a parameter.
Definition sdds.py:700
getParameterValue(self, name, page=1)
Gets a single parameter value at a specific page.
Definition sdds.py:770
list arrayName
Definition sdds.py:116
__del__(self)
Destructor to release the index when the object is deleted.
Definition sdds.py:128
getParameterValueList(self, name)
Gets the list of parameter values for a parameter.
Definition sdds.py:720
int mode
Definition sdds.py:125
getArrayNames(self)
Retrieves a list of all array names.
Definition sdds.py:1167
defineParameter(self, name, symbol="", units="", description="", formatString="", type=SDDS_DOUBLE, fixedValue="")
Defines a parameter for the SDDS object.
Definition sdds.py:524
defineColumn(self, name, symbol="", units="", description="", formatString="", type=SDDS_DOUBLE, fieldLength=0)
Defines a column for the SDDS object.
Definition sdds.py:643
int SDDS_ASCII
Definition sdds.py:79
getParameterNames(self)
Retrieves a list of all parameter names.
Definition sdds.py:1158
list description
Definition sdds.py:114
getColumnDatatype(self, name)
Retrieves the data type of a column.
Definition sdds.py:1217
pageCount(self)
Retrieves the number or loaded pages.
Definition sdds.py:1281
setColumnValue(self, name, value, page=1, row=1)
Sets a single column value at a specific page and row.
Definition sdds.py:1049
list columnName
Definition sdds.py:117
getArrayDimensionLists(self, name)
Gets the nested list of array dimensions for a single array.
Definition sdds.py:842
defineSimpleArray(self, name, type, dimensions)
Defines a simple array with minimal information.
Definition sdds.py:616
getParameterCount(self)
Retrieves the number of parameters.
Definition sdds.py:1131
list columnDefinition
Definition sdds.py:121
setArrayValueList(self, name, valueList, dimensionList, page=1)
Sets a single array value and dimension at a specific page.
Definition sdds.py:862
int SDDS_VERBOSE_PrintErrors
Definition sdds.py:46
getParameterUnits(self, name)
Retrieves the units of a parameter.
Definition sdds.py:1233
list parameterName
Definition sdds.py:115
setDescription(self, text, contents)
Sets the description for the SDDS object.
Definition sdds.py:514
list arrayDimensions
Definition sdds.py:120
_used_indices
Definition sdds.py:82
list arrayDefinition
Definition sdds.py:119
loadLastRows(self, input, lastrows)
Loads an SDDS file into the SDDS object, reading only the last few rows.
Definition sdds.py:297
list columnData
Definition sdds.py:124
getArrayValueList(self, name, page=1)
Gets a single array value at a specific page.
Definition sdds.py:894
getParameterDatatype(self, name)
Retrieves the data type of a parameter.
Definition sdds.py:1185
int loaded_pages
Definition sdds.py:126
getArrayDimensionList(self, name, page=1)
Gets a single array dimension at a specific page.
Definition sdds.py:923
int _max_index
Definition sdds.py:83
save(self, output)
Saves the SDDS object's data to an SDDS file.
Definition sdds.py:377
setColumnValueList(self, name, valueList, page=1)
Sets a single column value list at a specific page.
Definition sdds.py:992
getColumnNames(self)
Retrieves a list of all column names.
Definition sdds.py:1176
setColumnValueLists(self, name, valueList)
Sets the nested list of column values for a single column.
Definition sdds.py:952
bool binary
Definition sdds.py:1865
dict definitions
Definition sdds.py:1866
dict values
Definition sdds.py:1867
dict array_dims
Definition sdds.py:1868