SDDS ToolKit Programs and Libraries for C and Python
Loading...
Searching...
No Matches
mcs2sdds.c File Reference

Detailed Description

Converts EG&G Turbo MCS (Multi-Channel Scaler) data files to SDDS format.

This program reads an EG&G Turbo MCS file, processes its header and data sections, and outputs an equivalent SDDS (Self Describing Data Sets) file.

Usage

mcs2sdds <inputfile> <outputfile> [-ascii]

Options

Option Description
-ascii Outputs the SDDS file in ASCII format. Default is binary format.
License
This file is distributed under the terms of the Software License Agreement found in the file LICENSE included with this distribution.
Authors
M. Borland, C. Saunders, R. Soliday

Definition in file mcs2sdds.c.

#include "mdb.h"
#include "SDDS.h"
#include "scan.h"

Go to the source code of this file.

Functions

void swapshort (short *data)
 
void swaplong (long *data)
 
void swapulong (unsigned long *data)
 
void swapushort (unsigned short *data)
 
void swapfloat (float *data)
 
int main (int argc, char **argv)
 

Function Documentation

◆ main()

int main ( int argc,
char ** argv )

Definition at line 59 of file mcs2sdds.c.

59 {
60 char reserved[100]; /* buffer to skip reserved bytes */
61 short f_type; /* MCS file type */
62 char trigger; /* Trigger Flag */
63 char dwell_flag; /* External Dwell Flag */
64 char dwell_units; /* 0=us, 1=ms, 2=sec, 3=ns */
65 char acq_mode; /* Acquisition mode flag 0=replace, 1=sum */
66 unsigned long dwell_913; /* Dwell time in old 913 format */
67 unsigned short pass_length; /* pass length in channels */
68 unsigned long pass_count;
69 unsigned long pass_count_preset;
70 char acq_time[9]; /* buffer for acquisition time */
71 char acq_date[9]; /* buffer for acquisition date */
72 unsigned short mark_chan; /* first marker channel */
73 char mcs_num; /* 1-8 are valid */
74 char cal_flag; /* 0=no calibration */
75 char cal_units[4]; /* calibration units */
76 float cal_zero; /* calibration zero intercept */
77 float cal_slope; /* calibration slope */
78 char id_byte; /* always 0xaa */
79 char detector_len; /* Detector description length */
80 char detector[65]; /* detector description */
81 char sample_len; /* Sample description length */
82 char sample[65]; /* Sample description */
83 char disc_sel; /* 0=SCA otherwise Disc */
84 char disc_edge; /* 0=falling else rising */
85 float disc; /* disc setting in volts */
86 float sca_uld; /* sca upper-level in volts */
87 float sca_lld; /* sca lower-level in volts */
88 float dwell; /* dwell time in dwell_units */
89 char consistent; /* settings consistent flag */
90 char mcs_id[9]; /* MCS ID string "0914-001" */
91
92 FILE *fpi;
93 char *input, *output;
94 SDDS_DATASET SDDS_dataset;
95 SCANNED_ARG *scanned;
96 long i, i_arg;
97 char ts1[256], ts2[256], ts3[256], ts4[256];
98 unsigned long *ucount;
99 long *count, *channel;
100 long ascii;
101 size_t bytesRead;
102
104 argc = scanargs(&scanned, argc, argv);
105 if (argc < 3) {
106 fprintf(stderr, "Error: Insufficient arguments.\n");
107 fprintf(stderr, "%s", USAGE);
108 exit(EXIT_FAILURE);
109 }
110
111 input = output = NULL;
112 ascii = 0;
113 for (i_arg = 1; i_arg < argc; i_arg++) {
114 if (scanned[i_arg].arg_type == OPTION) {
115 switch (match_string(scanned[i_arg].list[0], option, N_OPTIONS, 0)) {
116 case SET_ASCII:
117 ascii = 1;
118 break;
119 default:
120 fprintf(stderr, "Error: Invalid option '%s'.\n", scanned[i_arg].list[0]);
121 fprintf(stderr, "%s", USAGE);
122 exit(EXIT_FAILURE);
123 }
124 } else {
125 if (!input)
126 input = scanned[i_arg].list[0];
127 else if (!output)
128 output = scanned[i_arg].list[0];
129 else {
130 fprintf(stderr, "Error: Too many filenames provided.\n");
131 fprintf(stderr, "%s", USAGE);
132 exit(EXIT_FAILURE);
133 }
134 }
135 }
136
137 if (!input) {
138 SDDS_Bomb("Error: Input file not specified.");
139 }
140 if (!output) {
141 SDDS_Bomb("Error: Output file not specified.");
142 }
143
144 fpi = fopen_e(input, "r", 0);
145
146 /***************************************************************************/
147 /* Header Data */
148 /* Read header info from MCS file */
149 /***************************************************************************/
150 /* Read filetype -4 (MCS) */
151 if (fread(&f_type, sizeof(short), 1, fpi) != 1) {
152 SDDS_Bomb("Error: Unable to read file type.");
153 }
154 swapshort(&f_type);
155 if (f_type != MCS) {
156 fprintf(stderr, "Error: Not a valid MCS file. f_type = %hx\n", f_type);
157 fclose(fpi);
158 exit(EXIT_FAILURE);
159 }
160
161 bytesRead = fread(&trigger, sizeof(char), 1, fpi); /* Read Trigger Flag */
162 (void)bytesRead;
163 bytesRead = fread(&dwell_flag, sizeof(char), 1, fpi); /* Read dwell flag */
164 (void)bytesRead;
165 bytesRead = fread(&dwell_units, sizeof(char), 1, fpi); /* Read dwell units */
166 (void)bytesRead;
167 bytesRead = fread(&acq_mode, sizeof(char), 1, fpi);
168 (void)bytesRead;
169 bytesRead = fread(&dwell_913, sizeof(long), 1, fpi);
170 (void)bytesRead;
171 swapulong(&dwell_913);
172 bytesRead = fread(&pass_length, sizeof(short), 1, fpi);
173 (void)bytesRead;
174 swapushort(&pass_length);
175 bytesRead = fread(&pass_count, sizeof(long), 1, fpi);
176 (void)bytesRead;
177 swapulong(&pass_count);
178 bytesRead = fread(&pass_count_preset, sizeof(long), 1, fpi);
179 (void)bytesRead;
180 swapulong(&pass_count_preset);
181 bytesRead = fread(acq_time, sizeof(char), 8, fpi);
182 (void)bytesRead;
183 bytesRead = fread(acq_date, sizeof(char), 8, fpi);
184 (void)bytesRead;
185 bytesRead = fread(&mark_chan, sizeof(short), 1, fpi);
186 (void)bytesRead;
187 swapushort(&mark_chan);
188 bytesRead = fread(&mcs_num, sizeof(char), 1, fpi);
189 (void)bytesRead;
190 bytesRead = fread(&cal_flag, sizeof(char), 1, fpi);
191 (void)bytesRead;
192 bytesRead = fread(cal_units, sizeof(char), 4, fpi);
193 (void)bytesRead;
194 bytesRead = fread(&cal_zero, sizeof(float), 1, fpi);
195 (void)bytesRead;
196 swapfloat(&cal_zero);
197 bytesRead = fread(&cal_slope, sizeof(float), 1, fpi);
198 (void)bytesRead;
199 swapfloat(&cal_slope);
200 bytesRead = fread(reserved, sizeof(char), 10, fpi);
201 (void)bytesRead;
202 bytesRead = fread(&id_byte, sizeof(char), 1, fpi);
203 (void)bytesRead;
204 bytesRead = fread(reserved, sizeof(char), 1, fpi);
205 (void)bytesRead;
206 bytesRead = fread(&detector_len, sizeof(char), 1, fpi);
207 (void)bytesRead;
208 bytesRead = fread(detector, sizeof(char), 63, fpi);
209 (void)bytesRead;
210 bytesRead = fread(&sample_len, sizeof(char), 1, fpi);
211 (void)bytesRead;
212 bytesRead = fread(sample, sizeof(char), 63, fpi);
213 (void)bytesRead;
214 bytesRead = fread(reserved, sizeof(char), 16, fpi); /* skip view info & reserved */
215 (void)bytesRead;
216 bytesRead = fread(&disc_sel, sizeof(char), 1, fpi);
217 (void)bytesRead;
218 bytesRead = fread(&disc_edge, sizeof(char), 1, fpi);
219 (void)bytesRead;
220 bytesRead = fread(&disc, sizeof(float), 1, fpi);
221 (void)bytesRead;
222 swapfloat(&disc);
223 bytesRead = fread(&sca_uld, sizeof(float), 1, fpi);
224 (void)bytesRead;
225 swapfloat(&sca_uld);
226 bytesRead = fread(&sca_lld, sizeof(float), 1, fpi);
227 (void)bytesRead;
228 swapfloat(&sca_lld);
229 bytesRead = fread(&dwell, sizeof(float), 1, fpi);
230 (void)bytesRead;
231 swapfloat(&dwell);
232 bytesRead = fread(&consistent, sizeof(char), 1, fpi);
233 (void)bytesRead;
234 bytesRead = fread(reserved, sizeof(char), 21, fpi);
235 (void)bytesRead;
236 bytesRead = fread(mcs_id, sizeof(char), 8, fpi);
237 (void)bytesRead;
238 mcs_id[8] = '\0';
239
240 sprintf(ts1, "%d", mcs_num + 1);
241 sprintf(ts2, "%hd", pass_length);
242 sprintf(ts3, "%ld", pass_count);
243 sprintf(ts4, "%ld", pass_count_preset);
244
245 if (!SDDS_InitializeOutput(&SDDS_dataset, ascii ? SDDS_ASCII : SDDS_BINARY, 1, "Turbo MCS data", "Turbo MCS data", output) ||
246 SDDS_DefineParameter(&SDDS_dataset, "MCSNumber", NULL, NULL, "MCS number", NULL, SDDS_SHORT, ts1) < 0 ||
247 SDDS_DefineParameter(&SDDS_dataset, "MCSID", NULL, NULL, "MCS ID", NULL, SDDS_STRING, mcs_id) < 0 ||
248 SDDS_DefineParameter(&SDDS_dataset, "PassLength", NULL, NULL, "Pass length", NULL, SDDS_SHORT, ts2) < 0 ||
249 SDDS_DefineParameter(&SDDS_dataset, "PassCount", NULL, NULL, "Pass count", NULL, SDDS_LONG, ts3) < 0 ||
250 SDDS_DefineParameter(&SDDS_dataset, "PassCountPreset", NULL, NULL, "Pass count preset", NULL, SDDS_LONG, ts4) < 0) {
251 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
252 }
253
254 if (dwell_flag == 0) {
255 if (dwell_units == 0)
256 dwell *= 1e-6;
257 else if (dwell_units == 1)
258 dwell *= 1e-3;
259 else if (dwell_units == 3)
260 dwell *= 1e-9;
261 } else {
262 dwell = -1;
263 }
264
265 sprintf(ts1, "%15.8e", dwell);
266 sprintf(ts2, "%8s %8s", acq_time, acq_date);
267 if (SDDS_DefineParameter(&SDDS_dataset, "DwellTime", NULL, "s", "Dwell time", NULL, SDDS_DOUBLE, ts1) < 0 ||
268 SDDS_DefineParameter(&SDDS_dataset, "TriggerMode", NULL, NULL, "Trigger mode", NULL, SDDS_STRING, trigger ? "external" : "internal") < 0 ||
269 SDDS_DefineParameter(&SDDS_dataset, "AcquisitionMode", NULL, NULL, "Acquisition mode", NULL, SDDS_STRING, acq_mode ? "sum" : "replace") < 0 ||
270 SDDS_DefineParameter(&SDDS_dataset, "TimeStamp", NULL, NULL, "Time at which data collection started", NULL, SDDS_STRING, ts2) < 0) {
271 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
272 }
273
274 sprintf(ts1, "%15.8e", cal_slope);
275 sprintf(ts2, "%15.8e", cal_zero);
276 if (cal_flag && (SDDS_DefineParameter(&SDDS_dataset, "CalibrationSlope", NULL, cal_units, "Spectrum calibration slope", NULL, SDDS_DOUBLE, ts1) < 0 ||
277 SDDS_DefineParameter(&SDDS_dataset, "CalibrationOffset", NULL, cal_units, "Spectrum calibration offset", NULL, SDDS_DOUBLE, ts2) < 0)) {
278 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
279 }
280
281 if (detector_len) {
282 detector[(unsigned)detector_len] = '\0';
283 if (SDDS_DefineParameter(&SDDS_dataset, "HardwareDescription", NULL, NULL, "Hardware description", NULL, SDDS_STRING, detector) < 0) {
284 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
285 }
286 }
287
288 if (sample_len) {
289 sample[(unsigned)sample_len] = '\0';
290 if (SDDS_DefineParameter(&SDDS_dataset, "DataDescription", NULL, NULL, "Data description", NULL, SDDS_STRING, sample) < 0 ||
291 SDDS_DefineParameter(&SDDS_dataset, "mplTitle", NULL, NULL, "MPL Title", NULL, SDDS_STRING, sample) < 0) {
292 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
293 }
294 }
295
296 if (disc_sel == 0) {
297 sprintf(ts1, "%15.8e", sca_lld);
298 sprintf(ts2, "%15.8e", sca_uld);
299 if (SDDS_DefineParameter(&SDDS_dataset, "SCA-LLD", NULL, "V", "SCA Lower-Level Discriminator Setting", NULL, SDDS_DOUBLE, ts1) < 0 ||
300 SDDS_DefineParameter(&SDDS_dataset, "SCA-ULD", NULL, "V", "SCA Upper-Level Discriminator Setting", NULL, SDDS_DOUBLE, ts2) < 0) {
301 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
302 }
303 } else {
304 sprintf(ts1, "%15.8e", disc);
305 if (SDDS_DefineParameter(&SDDS_dataset, "DiscrimLevel", NULL, "V", "Discriminator Level", NULL, SDDS_DOUBLE, ts1) < 0 ||
306 SDDS_DefineParameter(&SDDS_dataset, "DiscrimSlope", NULL, NULL, "Discriminator Slope", NULL, SDDS_STRING, disc_edge ? "+1" : "-1") < 0) {
307 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
308 }
309 }
310
311 if (consistent == 0) {
312 if (SDDS_DefineParameter(&SDDS_dataset, "Inconsistent", NULL, NULL, "Flag indicating whether data and settings are inconsistent", NULL, SDDS_LONG, "1") < 0) {
313 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
314 }
315 fprintf(stderr, "WARNING: Settings are not consistent with data\n");
316 }
317
318 if (SDDS_DefineColumn(&SDDS_dataset, "ChannelNumber", NULL, NULL, "Channel number", NULL, SDDS_LONG, 0) < 0 ||
319 SDDS_DefineColumn(&SDDS_dataset, "EventCount", NULL, NULL, "Number of events", NULL, SDDS_LONG, 0) < 0 ||
320 !SDDS_WriteLayout(&SDDS_dataset) || !SDDS_StartPage(&SDDS_dataset, (long)pass_length)) {
321 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
322 }
323
324 /***************************************************************************/
325 /* Channel Data */
326 /* Output channel data from MCS file */
327 /***************************************************************************/
328 channel = tmalloc(sizeof(*channel) * pass_length);
329 count = tmalloc(sizeof(*count) * pass_length);
330 ucount = tmalloc(sizeof(*ucount) * pass_length);
331 if (fread(ucount, sizeof(*ucount), pass_length, fpi) != pass_length) {
332 SDDS_Bomb("Error: Unable to read channel data.");
333 }
334 for (i = 0; i < (long)pass_length; i++) {
335 swapulong(&ucount[i]);
336 count[i] = (long)ucount[i];
337 channel[i] = i;
338 }
339 if (!SDDS_SetColumn(&SDDS_dataset, SDDS_SET_BY_NAME, channel, (long)pass_length, "ChannelNumber") ||
340 !SDDS_SetColumn(&SDDS_dataset, SDDS_SET_BY_NAME, count, (long)pass_length, "EventCount") ||
341 !SDDS_WritePage(&SDDS_dataset) || !SDDS_Terminate(&SDDS_dataset)) {
342 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
343 }
344
345 fclose(fpi);
346 return EXIT_SUCCESS;
347}
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_DefineColumn(SDDS_DATASET *SDDS_dataset, const char *name, const char *symbol, const char *units, const char *description, const char *format_string, int32_t type, int32_t field_length)
Defines a data column within the SDDS dataset.
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.
void SDDS_PrintErrors(FILE *fp, int32_t mode)
Prints recorded error messages to a specified file stream.
Definition SDDS_utils.c:474
void SDDS_RegisterProgramName(const char *name)
Registers the executable program name for use in error messages.
Definition SDDS_utils.c:318
void SDDS_Bomb(char *message)
Terminates the program after printing an error message and recorded errors.
Definition SDDS_utils.c:380
#define SDDS_STRING
Identifier for the string data type.
Definition SDDStypes.h:85
#define SDDS_LONG
Identifier for the signed 32-bit integer data type.
Definition SDDStypes.h:61
#define SDDS_SHORT
Identifier for the signed short integer data type.
Definition SDDStypes.h:73
#define SDDS_DOUBLE
Identifier for the double data type.
Definition SDDStypes.h:37
void * tmalloc(uint64_t size_of_block)
Allocates a memory block of the specified size with zero initialization.
Definition array.c:65
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

◆ swapfloat()

void swapfloat ( float * data)

Definition at line 381 of file mcs2sdds.c.

381 {
382 float copy;
383 copy = *data;
384 *(((char *)data) + 0) = *(((char *)&copy) + 3);
385 *(((char *)data) + 1) = *(((char *)&copy) + 2);
386 *(((char *)data) + 2) = *(((char *)&copy) + 1);
387 *(((char *)data) + 3) = *(((char *)&copy) + 0);
388}

◆ swaplong()

void swaplong ( long * data)

Definition at line 363 of file mcs2sdds.c.

363 {
364 long copy;
365 copy = *data;
366 *(((char *)data) + 0) = *(((char *)&copy) + 3);
367 *(((char *)data) + 1) = *(((char *)&copy) + 2);
368 *(((char *)data) + 2) = *(((char *)&copy) + 1);
369 *(((char *)data) + 3) = *(((char *)&copy) + 0);
370}

◆ swapshort()

void swapshort ( short * data)

Definition at line 349 of file mcs2sdds.c.

349 {
350 unsigned char c1;
351 c1 = *((char *)data);
352 *((char *)data) = *(((char *)data) + 1);
353 *(((char *)data) + 1) = c1;
354}

◆ swapulong()

void swapulong ( unsigned long * data)

Definition at line 372 of file mcs2sdds.c.

372 {
373 unsigned long copy;
374 copy = *data;
375 *(((char *)data) + 0) = *(((char *)&copy) + 3);
376 *(((char *)data) + 1) = *(((char *)&copy) + 2);
377 *(((char *)data) + 2) = *(((char *)&copy) + 1);
378 *(((char *)data) + 3) = *(((char *)&copy) + 0);
379}

◆ swapushort()

void swapushort ( unsigned short * data)

Definition at line 356 of file mcs2sdds.c.

356 {
357 unsigned char c1;
358 c1 = *((char *)data);
359 *((char *)data) = *(((char *)data) + 1);
360 *(((char *)data) + 1) = c1;
361}