SDDS ToolKit Programs and Libraries for C and Python
All Classes Files Functions Variables Macros Pages
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
103 argc = scanargs(&scanned, argc, argv);
104 if (argc < 3) {
105 fprintf(stderr, "Error: Insufficient arguments.\n");
106 fprintf(stderr, "%s", USAGE);
107 exit(EXIT_FAILURE);
108 }
109
110 input = output = NULL;
111 ascii = 0;
112 for (i_arg = 1; i_arg < argc; i_arg++) {
113 if (scanned[i_arg].arg_type == OPTION) {
114 switch (match_string(scanned[i_arg].list[0], option, N_OPTIONS, 0)) {
115 case SET_ASCII:
116 ascii = 1;
117 break;
118 default:
119 fprintf(stderr, "Error: Invalid option '%s'.\n", scanned[i_arg].list[0]);
120 fprintf(stderr, "%s", USAGE);
121 exit(EXIT_FAILURE);
122 }
123 } else {
124 if (!input)
125 input = scanned[i_arg].list[0];
126 else if (!output)
127 output = scanned[i_arg].list[0];
128 else {
129 fprintf(stderr, "Error: Too many filenames provided.\n");
130 fprintf(stderr, "%s", USAGE);
131 exit(EXIT_FAILURE);
132 }
133 }
134 }
135
136 if (!input) {
137 SDDS_Bomb("Error: Input file not specified.");
138 }
139 if (!output) {
140 SDDS_Bomb("Error: Output file not specified.");
141 }
142
143 fpi = fopen_e(input, "r", 0);
144
145 /***************************************************************************/
146 /* Header Data */
147 /* Read header info from MCS file */
148 /***************************************************************************/
149 /* Read filetype -4 (MCS) */
150 if (fread(&f_type, sizeof(short), 1, fpi) != 1) {
151 SDDS_Bomb("Error: Unable to read file type.");
152 }
153 swapshort(&f_type);
154 if (f_type != MCS) {
155 fprintf(stderr, "Error: Not a valid MCS file. f_type = %hx\n", f_type);
156 fclose(fpi);
157 exit(EXIT_FAILURE);
158 }
159
160 fread(&trigger, sizeof(char), 1, fpi); /* Read Trigger Flag */
161 fread(&dwell_flag, sizeof(char), 1, fpi); /* Read dwell flag */
162 fread(&dwell_units, sizeof(char), 1, fpi); /* Read dwell units */
163 fread(&acq_mode, sizeof(char), 1, fpi);
164 fread(&dwell_913, sizeof(long), 1, fpi);
165 swapulong(&dwell_913);
166 fread(&pass_length, sizeof(short), 1, fpi);
167 swapushort(&pass_length);
168 fread(&pass_count, sizeof(long), 1, fpi);
169 swapulong(&pass_count);
170 fread(&pass_count_preset, sizeof(long), 1, fpi);
171 swapulong(&pass_count_preset);
172 fread(acq_time, sizeof(char), 8, fpi);
173 fread(acq_date, sizeof(char), 8, fpi);
174 fread(&mark_chan, sizeof(short), 1, fpi);
175 swapushort(&mark_chan);
176 fread(&mcs_num, sizeof(char), 1, fpi);
177 fread(&cal_flag, sizeof(char), 1, fpi);
178 fread(cal_units, sizeof(char), 4, fpi);
179 fread(&cal_zero, sizeof(float), 1, fpi);
180 swapfloat(&cal_zero);
181 fread(&cal_slope, sizeof(float), 1, fpi);
182 swapfloat(&cal_slope);
183 fread(reserved, sizeof(char), 10, fpi);
184 fread(&id_byte, sizeof(char), 1, fpi);
185 fread(reserved, sizeof(char), 1, fpi);
186 fread(&detector_len, sizeof(char), 1, fpi);
187 fread(detector, sizeof(char), 63, fpi);
188 fread(&sample_len, sizeof(char), 1, fpi);
189 fread(sample, sizeof(char), 63, fpi);
190 fread(reserved, sizeof(char), 16, fpi); /* skip view info & reserved */
191 fread(&disc_sel, sizeof(char), 1, fpi);
192 fread(&disc_edge, sizeof(char), 1, fpi);
193 fread(&disc, sizeof(float), 1, fpi);
194 swapfloat(&disc);
195 fread(&sca_uld, sizeof(float), 1, fpi);
196 swapfloat(&sca_uld);
197 fread(&sca_lld, sizeof(float), 1, fpi);
198 swapfloat(&sca_lld);
199 fread(&dwell, sizeof(float), 1, fpi);
200 swapfloat(&dwell);
201 fread(&consistent, sizeof(char), 1, fpi);
202 fread(reserved, sizeof(char), 21, fpi);
203 fread(mcs_id, sizeof(char), 8, fpi);
204 mcs_id[8] = '\0';
205
206 sprintf(ts1, "%d", mcs_num + 1);
207 sprintf(ts2, "%hd", pass_length);
208 sprintf(ts3, "%ld", pass_count);
209 sprintf(ts4, "%ld", pass_count_preset);
210
211 if (!SDDS_InitializeOutput(&SDDS_dataset, ascii ? SDDS_ASCII : SDDS_BINARY, 1, "Turbo MCS data", "Turbo MCS data", output) ||
212 SDDS_DefineParameter(&SDDS_dataset, "MCSNumber", NULL, NULL, "MCS number", NULL, SDDS_SHORT, ts1) < 0 ||
213 SDDS_DefineParameter(&SDDS_dataset, "MCSID", NULL, NULL, "MCS ID", NULL, SDDS_STRING, mcs_id) < 0 ||
214 SDDS_DefineParameter(&SDDS_dataset, "PassLength", NULL, NULL, "Pass length", NULL, SDDS_SHORT, ts2) < 0 ||
215 SDDS_DefineParameter(&SDDS_dataset, "PassCount", NULL, NULL, "Pass count", NULL, SDDS_LONG, ts3) < 0 ||
216 SDDS_DefineParameter(&SDDS_dataset, "PassCountPreset", NULL, NULL, "Pass count preset", NULL, SDDS_LONG, ts4) < 0) {
217 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
218 }
219
220 if (dwell_flag == 0) {
221 if (dwell_units == 0)
222 dwell *= 1e-6;
223 else if (dwell_units == 1)
224 dwell *= 1e-3;
225 else if (dwell_units == 3)
226 dwell *= 1e-9;
227 } else {
228 dwell = -1;
229 }
230
231 sprintf(ts1, "%15.8e", dwell);
232 sprintf(ts2, "%8s %8s", acq_time, acq_date);
233 if (SDDS_DefineParameter(&SDDS_dataset, "DwellTime", NULL, "s", "Dwell time", NULL, SDDS_DOUBLE, ts1) < 0 ||
234 SDDS_DefineParameter(&SDDS_dataset, "TriggerMode", NULL, NULL, "Trigger mode", NULL, SDDS_STRING, trigger ? "external" : "internal") < 0 ||
235 SDDS_DefineParameter(&SDDS_dataset, "AcquisitionMode", NULL, NULL, "Acquisition mode", NULL, SDDS_STRING, acq_mode ? "sum" : "replace") < 0 ||
236 SDDS_DefineParameter(&SDDS_dataset, "TimeStamp", NULL, NULL, "Time at which data collection started", NULL, SDDS_STRING, ts2) < 0) {
237 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
238 }
239
240 sprintf(ts1, "%15.8e", cal_slope);
241 sprintf(ts2, "%15.8e", cal_zero);
242 if (cal_flag && (SDDS_DefineParameter(&SDDS_dataset, "CalibrationSlope", NULL, cal_units, "Spectrum calibration slope", NULL, SDDS_DOUBLE, ts1) < 0 ||
243 SDDS_DefineParameter(&SDDS_dataset, "CalibrationOffset", NULL, cal_units, "Spectrum calibration offset", NULL, SDDS_DOUBLE, ts2) < 0)) {
244 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
245 }
246
247 if (detector_len) {
248 detector[(unsigned)detector_len] = '\0';
249 if (SDDS_DefineParameter(&SDDS_dataset, "HardwareDescription", NULL, NULL, "Hardware description", NULL, SDDS_STRING, detector) < 0) {
250 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
251 }
252 }
253
254 if (sample_len) {
255 sample[(unsigned)sample_len] = '\0';
256 if (SDDS_DefineParameter(&SDDS_dataset, "DataDescription", NULL, NULL, "Data description", NULL, SDDS_STRING, sample) < 0 ||
257 SDDS_DefineParameter(&SDDS_dataset, "mplTitle", NULL, NULL, "MPL Title", NULL, SDDS_STRING, sample) < 0) {
258 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
259 }
260 }
261
262 if (disc_sel == 0) {
263 sprintf(ts1, "%15.8e", sca_lld);
264 sprintf(ts2, "%15.8e", sca_uld);
265 if (SDDS_DefineParameter(&SDDS_dataset, "SCA-LLD", NULL, "V", "SCA Lower-Level Discriminator Setting", NULL, SDDS_DOUBLE, ts1) < 0 ||
266 SDDS_DefineParameter(&SDDS_dataset, "SCA-ULD", NULL, "V", "SCA Upper-Level Discriminator Setting", NULL, SDDS_DOUBLE, ts2) < 0) {
267 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
268 }
269 } else {
270 sprintf(ts1, "%15.8e", disc);
271 if (SDDS_DefineParameter(&SDDS_dataset, "DiscrimLevel", NULL, "V", "Discriminator Level", NULL, SDDS_DOUBLE, ts1) < 0 ||
272 SDDS_DefineParameter(&SDDS_dataset, "DiscrimSlope", NULL, NULL, "Discriminator Slope", NULL, SDDS_STRING, disc_edge ? "+1" : "-1") < 0) {
273 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
274 }
275 }
276
277 if (consistent == 0) {
278 if (SDDS_DefineParameter(&SDDS_dataset, "Inconsistent", NULL, NULL, "Flag indicating whether data and settings are inconsistent", NULL, SDDS_LONG, "1") < 0) {
279 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
280 }
281 fprintf(stderr, "WARNING: Settings are not consistent with data\n");
282 }
283
284 if (SDDS_DefineColumn(&SDDS_dataset, "ChannelNumber", NULL, NULL, "Channel number", NULL, SDDS_LONG, 0) < 0 ||
285 SDDS_DefineColumn(&SDDS_dataset, "EventCount", NULL, NULL, "Number of events", NULL, SDDS_LONG, 0) < 0 ||
286 !SDDS_WriteLayout(&SDDS_dataset) || !SDDS_StartPage(&SDDS_dataset, (long)pass_length)) {
287 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
288 }
289
290 /***************************************************************************/
291 /* Channel Data */
292 /* Output channel data from MCS file */
293 /***************************************************************************/
294 channel = tmalloc(sizeof(*channel) * pass_length);
295 count = tmalloc(sizeof(*count) * pass_length);
296 ucount = tmalloc(sizeof(*ucount) * pass_length);
297 if (fread(ucount, sizeof(*ucount), pass_length, fpi) != pass_length) {
298 SDDS_Bomb("Error: Unable to read channel data.");
299 }
300 for (i = 0; i < (long)pass_length; i++) {
301 swapulong(&ucount[i]);
302 count[i] = (long)ucount[i];
303 channel[i] = i;
304 }
305 if (!SDDS_SetColumn(&SDDS_dataset, SDDS_SET_BY_NAME, channel, (long)pass_length, "ChannelNumber") ||
306 !SDDS_SetColumn(&SDDS_dataset, SDDS_SET_BY_NAME, count, (long)pass_length, "EventCount") ||
307 !SDDS_WritePage(&SDDS_dataset) || !SDDS_Terminate(&SDDS_dataset)) {
308 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
309 }
310
311 fclose(fpi);
312 return EXIT_SUCCESS;
313}
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: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_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:59
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 347 of file mcs2sdds.c.

347 {
348 float copy;
349 copy = *data;
350 *(((char *)data) + 0) = *(((char *)&copy) + 3);
351 *(((char *)data) + 1) = *(((char *)&copy) + 2);
352 *(((char *)data) + 2) = *(((char *)&copy) + 1);
353 *(((char *)data) + 3) = *(((char *)&copy) + 0);
354}

◆ swaplong()

void swaplong ( long * data)

Definition at line 329 of file mcs2sdds.c.

329 {
330 long copy;
331 copy = *data;
332 *(((char *)data) + 0) = *(((char *)&copy) + 3);
333 *(((char *)data) + 1) = *(((char *)&copy) + 2);
334 *(((char *)data) + 2) = *(((char *)&copy) + 1);
335 *(((char *)data) + 3) = *(((char *)&copy) + 0);
336}

◆ swapshort()

void swapshort ( short * data)

Definition at line 315 of file mcs2sdds.c.

315 {
316 unsigned char c1;
317 c1 = *((char *)data);
318 *((char *)data) = *(((char *)data) + 1);
319 *(((char *)data) + 1) = c1;
320}

◆ swapulong()

void swapulong ( unsigned long * data)

Definition at line 338 of file mcs2sdds.c.

338 {
339 unsigned long copy;
340 copy = *data;
341 *(((char *)data) + 0) = *(((char *)&copy) + 3);
342 *(((char *)data) + 1) = *(((char *)&copy) + 2);
343 *(((char *)data) + 2) = *(((char *)&copy) + 1);
344 *(((char *)data) + 3) = *(((char *)&copy) + 0);
345}

◆ swapushort()

void swapushort ( unsigned short * data)

Definition at line 322 of file mcs2sdds.c.

322 {
323 unsigned char c1;
324 c1 = *((char *)data);
325 *((char *)data) = *(((char *)data) + 1);
326 *(((char *)data) + 1) = c1;
327}