SDDS ToolKit Programs and Libraries for C and Python
All Classes Files Functions Variables Macros Pages
lba2sdds.c
Go to the documentation of this file.
1/**
2 * @file lba2sdds.c
3 * @brief Converts a Spiricon LBA (Laser-Beam Analyzer) file to SDDS format.
4 *
5 * @details
6 * This program reads a Laser-Beam Analyzer (LBA) file from Spiricon and converts it into the
7 * Self Describing Data Set (SDDS) format. This conversion facilitates the analysis and visualization
8 * of beam data using SDDS-compatible tools.
9 *
10 * The program requires that the data type be set to `character`.
11 *
12 * @section Usage
13 * ```
14 * lba2sdds [<inputfile>] [<outputfile>]
15 * [-pipe[=input][,output]]
16 * -definition=<name>,<definition-entries>
17 * [-majorOrder=row|column]
18 * ```
19 *
20 * @section Options
21 * | Required | Description |
22 * |---------------------------------------|---------------------------------------------------------------------------------------|
23 * | `-definition` | Defines SDDS columns with the specified name and entries. |
24 *
25 * | Optional | Description |
26 * |---------------------------------------|---------------------------------------------------------------------------------------|
27 * | `-pipe` | Use pipe for input and/or output. |
28 * | `-majorOrder` | Sets data major order to row or column. Defaults to row order. |
29 *
30 * @subsection SR Specific Requirements
31 * - For `-definition`:
32 * - Must include `type=character` in the definition string.
33 * - Input file must be in a recognizable LBA format (A, B, or C header).
34 *
35 * @copyright
36 * - (c) 2002 The University of Chicago, as Operator of Argonne National Laboratory.
37 * - (c) 2002 The Regents of the University of California, as Operator of Los Alamos National Laboratory.
38 *
39 * @license
40 * This file is distributed under the terms of the Software License Agreement
41 * found in the file LICENSE included with this distribution.
42 *
43 * @author
44 * M. Borland, C. Saunders, R. Soliday, H. Shang
45 */
46
47#include "mdb.h"
48#include "SDDS.h"
49#include "scan.h"
50#include "match_string.h"
51
52/* Enumeration for option types */
53enum option_type {
54 SET_DEFINITION,
55 SET_PIPE,
56 SET_MAJOR_ORDER,
57 N_OPTIONS
58};
59
60char *option[N_OPTIONS] = {
61 "definition",
62 "pipe",
63 "majorOrder",
64};
65
66/* Improved usage message for better readability */
67char *USAGE =
68 "lba2sdds [<inputfile>] [<outputfile>]\n"
69 " [-pipe[=input][,output]]\n"
70 " -definition=<name>,<definition-entries>\n"
71 " [-majorOrder=row|column]\n\n"
72 "Options:\n"
73 " -pipe[=input][,output] Use pipe for input and/or output.\n"
74 " -definition=<name>,<entries> Define SDDS columns with name and entries.\n"
75 " -majorOrder=row|column Set data major order to row or column.\n\n"
76 "Description:\n"
77 " lba2sdds converts a Spiricon LBA file to SDDS format. The definition entries\n"
78 " are specified as <keyword>=<value>, where each keyword is a valid SDDS column field name.\n\n"
79 "Program by Michael Borland (" __DATE__ " " __TIME__ ", SVN revision: " SVN_VERSION ")\n";
80
81char *process_column_definition(char **argv, long argc);
82
83int main(int argc, char **argv) {
84 SDDS_DATASET SDDS_dataset;
85 SCANNED_ARG *scanned;
86 long i_arg;
87 char *input, *output, *definition;
88 long hsize, vsize;
89 char *data, *data_name;
90 char header[200];
91 char ts1[100], ts2[100];
92 FILE *fpi;
93 unsigned long pipeFlags, majorOrderFlag;
94 short columnMajorOrder = 0;
95
97
98 argc = scanargs(&scanned, argc, argv);
99 if (argc < 4) {
100 bomb(NULL, USAGE);
101 }
102
103 input = output = data_name = NULL;
104 definition = NULL;
105 pipeFlags = 0;
106 hsize = vsize = 0;
107
108 for (i_arg = 1; i_arg < argc; i_arg++) {
109 if (scanned[i_arg].arg_type == OPTION) {
110 /* Process options here */
111 switch (match_string(scanned[i_arg].list[0], option, N_OPTIONS, 0)) {
112 case SET_MAJOR_ORDER:
113 majorOrderFlag = 0;
114 scanned[i_arg].n_items--;
115 if (scanned[i_arg].n_items > 0 &&
116 (!scanItemList(&majorOrderFlag, scanned[i_arg].list + 1, &scanned[i_arg].n_items, 0,
117 "row", -1, NULL, 0, SDDS_ROW_MAJOR_ORDER,
118 "column", -1, NULL, 0, SDDS_COLUMN_MAJOR_ORDER, NULL))) {
119 SDDS_Bomb("Invalid -majorOrder syntax or values");
120 }
121 if (majorOrderFlag & SDDS_COLUMN_MAJOR_ORDER)
122 columnMajorOrder = 1;
123 else if (majorOrderFlag & SDDS_ROW_MAJOR_ORDER)
124 columnMajorOrder = 0;
125 break;
126
127 case SET_DEFINITION:
128 data_name = scanned[i_arg].list[1];
129 definition = process_column_definition(scanned[i_arg].list + 1, scanned[i_arg].n_items - 1);
130 if (!strstr(definition, "type=character"))
131 SDDS_Bomb("Data type must be character for now");
132 break;
133
134 case SET_PIPE:
135 if (!processPipeOption(scanned[i_arg].list + 1, scanned[i_arg].n_items - 1, &pipeFlags))
136 SDDS_Bomb("Invalid -pipe syntax");
137 break;
138
139 default:
140 bomb("Invalid option seen", USAGE);
141 break;
142 }
143 } else {
144 if (!input)
145 input = scanned[i_arg].list[0];
146 else if (!output)
147 output = scanned[i_arg].list[0];
148 else
149 bomb("Too many filenames provided", USAGE);
150 }
151 }
152
153 processFilenames("lba2sdds", &input, &output, pipeFlags, 0, NULL);
154
155 if (!definition)
156 SDDS_Bomb("Definition not specified");
157
158 if (input)
159 fpi = fopen_e(input, "r", 0);
160 else
161 fpi = stdin;
162
163 if (fread(header, sizeof(*header), 200, fpi) != 200)
164 SDDS_Bomb("Unable to read LBA file header");
165
166 switch (header[0]) {
167 case 'A':
168 hsize = vsize = 120;
169 break;
170 case 'B':
171 vsize = 256;
172 hsize = 240;
173 break;
174 case 'C':
175 vsize = 512;
176 hsize = 480;
177 break;
178 default:
179 SDDS_Bomb("Data does not appear to be in LBA format--invalid frame type");
180 break;
181 }
182
183 sprintf(ts1, "%ld", hsize);
184 sprintf(ts2, "%ld", vsize);
185
186 if (!SDDS_InitializeOutput(&SDDS_dataset, SDDS_BINARY, 0,
187 "Screen image from LBA file", "Screen Image",
188 output) ||
189 SDDS_ProcessColumnString(&SDDS_dataset, definition, 0) < 0 ||
190 SDDS_DefineParameter(&SDDS_dataset, "NumberOfRows", NULL, NULL, "Number of rows", NULL, SDDS_LONG, ts1) < 0 ||
191 SDDS_DefineParameter(&SDDS_dataset, "NumberOfColumns", NULL, NULL, "Number of columns", NULL, SDDS_LONG, ts2) < 0) {
192 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
193 }
194
195 SDDS_dataset.layout.data_mode.column_major = columnMajorOrder;
196
197 if (!SDDS_WriteLayout(&SDDS_dataset))
198 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
199
200 data = tmalloc(sizeof(*data) * hsize * vsize);
201
202 do {
203 if (fread(data, sizeof(*data), hsize * vsize, fpi) != hsize * vsize)
204 SDDS_Bomb("Unable to read all data from input file");
205
206 if (!SDDS_StartPage(&SDDS_dataset, hsize * vsize) ||
207 !SDDS_SetColumn(&SDDS_dataset, SDDS_SET_BY_NAME, data, hsize * vsize, data_name) ||
208 !SDDS_WritePage(&SDDS_dataset)) {
209 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
210 }
211 } while (fread(header, sizeof(*header), 200, fpi) == 200);
212
213 fclose(fpi);
214
215 if (!SDDS_Terminate(&SDDS_dataset))
216 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
217
218 return EXIT_SUCCESS;
219}
220
221char *process_column_definition(char **argv, long argc) {
222 char buffer[SDDS_MAXLINE], *ptr;
223 long i;
224
225 if (argc < 1)
226 return NULL;
227
228 sprintf(buffer, "&column name=%s, ", argv[0]);
229
230 for (i = 1; i < argc; i++) {
231 if (!strchr(argv[i], '=')) {
232 return NULL;
233 }
234 strcat(buffer, argv[i]);
235 strcat(buffer, ", ");
236 }
237
238 if (!strstr(buffer, "type=")) {
239 strcat(buffer, "type=character ");
240 }
241
242 strcat(buffer, "&end");
243 cp_str(&ptr, buffer);
244 return ptr;
245}
SDDS (Self Describing Data Set) Data Types Definitions and Function Prototypes.
int32_t SDDS_StartPage(SDDS_DATASET *SDDS_dataset, int64_t expected_n_rows)
int32_t SDDS_SetColumn(SDDS_DATASET *SDDS_dataset, int32_t mode, void *data, int64_t rows,...)
Sets the values for one data column in the current data table of an SDDS dataset.
int32_t SDDS_Terminate(SDDS_DATASET *SDDS_dataset)
int32_t SDDS_InitializeOutput(SDDS_DATASET *SDDS_dataset, int32_t data_mode, int32_t lines_per_row, const char *description, const char *contents, const char *filename)
Initializes the SDDS output dataset.
int32_t SDDS_WritePage(SDDS_DATASET *SDDS_dataset)
Writes the current data table to the output file.
int32_t SDDS_WriteLayout(SDDS_DATASET *SDDS_dataset)
Writes the SDDS layout header to the output file.
int32_t SDDS_DefineParameter(SDDS_DATASET *SDDS_dataset, const char *name, const char *symbol, const char *units, const char *description, const char *format_string, int32_t type, char *fixed_value)
Defines a data parameter with a fixed string value.
int32_t SDDS_ProcessColumnString(SDDS_DATASET *SDDS_dataset, char *string, int32_t mode)
Process a column definition string.
void SDDS_PrintErrors(FILE *fp, int32_t mode)
Prints recorded error messages to a specified file stream.
Definition SDDS_utils.c:432
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
Definition SDDS_utils.c:288
void SDDS_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
Definition SDDS_utils.c:342
#define SDDS_LONG
Identifier for the signed 32-bit integer data type.
Definition SDDStypes.h:61
void * tmalloc(uint64_t size_of_block)
Allocates a memory block of the specified size with zero initialization.
Definition array.c:59
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
Definition bomb.c:26
char * cp_str(char **s, char *t)
Copies a string, allocating memory for storage.
Definition cp_str.c:28
FILE * fopen_e(char *file, char *open_mode, long mode)
Opens a file with error checking, messages, and aborts.
Definition fopen_e.c:30
long match_string(char *string, char **option, long n_options, long mode)
Matches a given string against an array of option strings based on specified modes.
int scanargs(SCANNED_ARG **scanned, int argc, char **argv)
Definition scanargs.c:36
long processPipeOption(char **item, long items, unsigned long *flags)
Definition scanargs.c:356
void processFilenames(char *programName, char **input, char **output, unsigned long pipeFlags, long noWarnings, long *tmpOutputUsed)
Definition scanargs.c:390
long scanItemList(unsigned long *flags, char **item, long *items, unsigned long mode,...)
Scans a list of items and assigns values based on provided keywords and types.