SDDSlib
Loading...
Searching...
No Matches
mcs2sdds.c
1/*************************************************************************\
2 * Copyright (c) 2002 The University of Chicago, as Operator of Argonne
3 * National Laboratory.
4 * Copyright (c) 2002 The Regents of the University of California, as
5 * Operator of Los Alamos National Laboratory.
6 * This file is distributed subject to a Software License Agreement found
7 * in the file LICENSE that is included with this distribution.
8\*************************************************************************/
9
10/* program: mcs2sdds
11 * purpose: convert EG&G Turbo MCS data files to SDDS
12 *
13 * M. Borland, 1994
14 * Based partly on readmcs.c, a sample program provided by EG&G.
15 $Log: not supported by cvs2svn $
16 Revision 1.5 2001/01/23 19:47:26 soliday
17 Fixed Solaris compiler warnings.
18
19 Revision 1.4 1999/05/25 19:03:49 soliday
20 Removed compiler warning on linux.
21
22 Revision 1.3 1995/09/06 14:55:53 saunders
23 First test release of SDDS1.5
24
25*/
26#include "mdb.h"
27#include "SDDS.h"
28#include "scan.h"
29
30#define SET_ASCII 0
31#define N_OPTIONS 1
32
33char *option[N_OPTIONS] = {
34 "ascii"};
35
36char *USAGE = "mcs2sdds <inputfile> <outputfile> [-ascii]\n\
37Link date: " __DATE__ " " __TIME__ ", SVN revision: " SVN_VERSION "\n";
38
39#define MCS -4
40
41void swapshort(short *data);
42void swaplong(long *data);
43void swapulong(unsigned long *data);
44void swapushort(unsigned short *data);
45void swapfloat(float *data);
46
47int main(int argc, char **argv) {
48 char reserved[100]; /* buffer to skip reserved bytes */
49 short f_type; /* MCS file type */
50 char trigger; /* Trigger Flag */
51 char dwell_flag; /* External Dwell Flag */
52 char dwell_units; /* 0=us, 1=ms, 2=sec, 3=ns */
53 char acq_mode; /* Acquisition mode flag 0=replace, 1=sum */
54 unsigned long dwell_913; /* Dwell time in old 913 format */
55 unsigned short pass_length; /* pass length in channels */
56 unsigned long pass_count;
57 unsigned long pass_count_preset;
58 char acq_time[9]; /* buffer for acquisition time */
59 char acq_date[9]; /* buffer for acquisition date */
60 unsigned short mark_chan; /* first marker channel */
61 char mcs_num; /* 1-8 are valid */
62 char cal_flag; /* 0=no calibration */
63 char cal_units[4]; /* calibration units */
64 float cal_zero; /* calibration zero intercept */
65 float cal_slope; /* calibration slope */
66 char id_byte; /* always 0xaa */
67 char detector_len; /* Detector description length */
68 char detector[65]; /* detector description */
69 char sample_len; /* Sample description length */
70 char sample[65]; /* Sample description */
71 char disc_sel; /* 0=SCA otherwise Disc */
72 char disc_edge; /* 0=falling else rising */
73 float disc; /* disc setting in volts */
74 float sca_uld; /* sca upper-level in volts */
75 float sca_lld; /* sca lower-level in volts */
76 float dwell; /* dwell time in dwell_units */
77 char consistent; /* settings consistent flag */
78 char mcs_id[9]; /* MCS ID string "0914-001" */
79
80 FILE *fpi;
81 char *input, *output;
82 SDDS_DATASET SDDS_dataset;
83 SCANNED_ARG *scanned;
84 long i, i_arg;
85 char ts1[256], ts2[256], ts3[256], ts4[256];
86 unsigned long *ucount;
87 long *count, *channel;
88 long ascii;
89
91 argc = scanargs(&scanned, argc, argv);
92 if (argc < 3)
93 bomb(NULL, USAGE);
94 input = output = NULL;
95 ascii = 0;
96 for (i_arg = 1; i_arg < argc; i_arg++) {
97 if (scanned[i_arg].arg_type == OPTION) {
98 switch (match_string(scanned[i_arg].list[0], option, N_OPTIONS, 0)) {
99 case SET_ASCII:
100 ascii = 1;
101 break;
102 default:
103 bomb("invalid option seen", USAGE);
104 break;
105 }
106 } else {
107 if (!input)
108 input = scanned[i_arg].list[0];
109 else if (!output)
110 output = scanned[i_arg].list[0];
111 else
112 bomb("too many filenames", USAGE);
113 }
114 }
115 if (!input)
116 SDDS_Bomb("input file not seen");
117 if (!output)
118 SDDS_Bomb("output file not seen");
119 fpi = fopen_e(input, "r", 0);
120
121 /***************************************************************************/
122 /* Header Data */
123 /* Read header info from MCS file */
124 /***************************************************************************/
125 /* Read filetype -4 (MCS) */
126 fread(&f_type, sizeof(short), 1, fpi);
127 swapshort(&f_type);
128 if (f_type != MCS) {
129 fprintf(stderr, "Not a valid file: f_type = %hx\n", f_type);
130 exit(1);
131 }
132 fread(&trigger, sizeof(char), 1, fpi); /* Read Trigger Flag */
133 fread(&dwell_flag, sizeof(char), 1, fpi); /* Read dwell flag */
134 fread(&dwell_units, sizeof(char), 1, fpi); /* Read dwell units */
135 fread(&acq_mode, sizeof(char), 1, fpi);
136 fread(&dwell_913, sizeof(long), 1, fpi);
137 swapulong(&dwell_913);
138 fread(&pass_length, sizeof(short), 1, fpi);
139 swapushort(&pass_length);
140 fread(&pass_count, sizeof(long), 1, fpi);
141 swapulong(&pass_count);
142 fread(&pass_count_preset, sizeof(long), 1, fpi);
143 swapulong(&pass_count_preset);
144 fread(acq_time, sizeof(char), 8, fpi);
145 fread(acq_date, sizeof(char), 8, fpi);
146 fread(&mark_chan, sizeof(short), 1, fpi);
147 swapushort(&mark_chan);
148 fread(&mcs_num, sizeof(char), 1, fpi);
149 fread(&cal_flag, sizeof(char), 1, fpi);
150 fread(cal_units, sizeof(char), 4, fpi);
151 fread(&cal_zero, sizeof(float), 1, fpi);
152 swapfloat(&cal_zero);
153 fread(&cal_slope, sizeof(float), 1, fpi);
154 swapfloat(&cal_slope);
155 fread(reserved, sizeof(char), 10, fpi);
156 fread(&id_byte, sizeof(char), 1, fpi);
157 fread(reserved, sizeof(char), 1, fpi);
158 fread(&detector_len, sizeof(char), 1, fpi);
159 fread(detector, sizeof(char), 63, fpi);
160 fread(&sample_len, sizeof(char), 1, fpi);
161 fread(sample, sizeof(char), 63, fpi);
162 fread(reserved, sizeof(char), 16, fpi); /* skip view info & reserved */
163 fread(&disc_sel, sizeof(char), 1, fpi);
164 fread(&disc_edge, sizeof(char), 1, fpi);
165 fread(&disc, sizeof(float), 1, fpi);
166 swapfloat(&disc);
167 fread(&sca_uld, sizeof(float), 1, fpi);
168 swapfloat(&sca_uld);
169 fread(&sca_lld, sizeof(float), 1, fpi);
170 swapfloat(&sca_lld);
171 fread(&dwell, sizeof(float), 1, fpi);
172 swapfloat(&dwell);
173 fread(&consistent, sizeof(char), 1, fpi);
174 fread(reserved, sizeof(char), 21, fpi);
175 fread(mcs_id, sizeof(char), 8, fpi);
176 mcs_id[8] = 0;
177
178 sprintf(ts1, "%d", mcs_num + 1);
179 sprintf(ts2, "%hd", pass_length);
180 sprintf(ts3, "%ld", pass_count);
181 sprintf(ts4, "%ld", pass_count_preset);
182
183 if (!SDDS_InitializeOutput(&SDDS_dataset, ascii ? SDDS_ASCII : SDDS_BINARY, 1, "Turbo MCS data", "Turbo MCS data", output) ||
184 SDDS_DefineParameter(&SDDS_dataset, "MCSNumber", NULL, NULL, "MCS number", NULL, SDDS_SHORT, ts1) < 0 ||
185 SDDS_DefineParameter(&SDDS_dataset, "MCSID", NULL, NULL, "MCS ID", NULL, SDDS_STRING, mcs_id) < 0 ||
186 SDDS_DefineParameter(&SDDS_dataset, "PassLength", NULL, NULL, "Pass length", NULL, SDDS_SHORT, ts2) < 0 ||
187 SDDS_DefineParameter(&SDDS_dataset, "PassCount", NULL, NULL, "Pass count", NULL, SDDS_LONG, ts3) < 0 ||
188 SDDS_DefineParameter(&SDDS_dataset, "PassCountPreset", NULL, NULL, "Pass count preset", NULL, SDDS_LONG, ts4) < 0)
189 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
190
191 if (dwell_flag == 0) {
192 if (dwell_units == 0)
193 dwell *= 1e-6;
194 else if (dwell_units == 1)
195 dwell *= 1e-3;
196 else if (dwell_units == 3)
197 dwell *= 1e-9;
198 } else
199 dwell = -1;
200 sprintf(ts1, "%15.8e", dwell);
201 sprintf(ts2, "%8s %8s", acq_time, acq_date);
202 if (SDDS_DefineParameter(&SDDS_dataset, "DwellTime", NULL, "s", "Dwell time", NULL, SDDS_DOUBLE, ts1) < 0 ||
203 SDDS_DefineParameter(&SDDS_dataset, "TriggerMode", NULL, NULL, "Trigger mode", NULL, SDDS_STRING, trigger ? "external" : "internal") < 0 ||
204 SDDS_DefineParameter(&SDDS_dataset, "AcquisitionMode", NULL, NULL, "Acquisition mode", NULL, SDDS_STRING, acq_mode ? "sum" : "replace") < 0 ||
205 SDDS_DefineParameter(&SDDS_dataset, "TimeStamp", NULL, NULL, "Time at which data collection started", NULL, SDDS_STRING, ts2) < 0)
206 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
207
208 sprintf(ts1, "%15.8e", cal_slope);
209 sprintf(ts2, "%15.8e", cal_zero);
210 if (cal_flag && (SDDS_DefineParameter(&SDDS_dataset, "CalibrationSlope", NULL, cal_units, "Spectrum calibration slope", NULL, SDDS_DOUBLE, ts1) < 0 ||
211 SDDS_DefineParameter(&SDDS_dataset, "CalibrationOffset", NULL, cal_units, "Spectrum calibration slope", NULL, SDDS_DOUBLE, ts2) < 0))
212 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
213
214 if (detector_len) {
215 detector[(unsigned)detector_len] = 0;
216 if (SDDS_DefineParameter(&SDDS_dataset, "HardwareDescription", NULL, NULL, NULL, NULL, SDDS_DOUBLE, detector) < 0)
217 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
218 }
219
220 if (sample_len) {
221 sample[(unsigned)sample_len] = 0;
222 if (SDDS_DefineParameter(&SDDS_dataset, "DataDescription", NULL, NULL, NULL, NULL, SDDS_STRING, sample) < 0 ||
223 SDDS_DefineParameter(&SDDS_dataset, "mplTitle", NULL, NULL, NULL, NULL, SDDS_STRING, sample) < 0)
224 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
225 }
226
227 if (disc_sel == 0) {
228 sprintf(ts1, "%15.8e", sca_lld);
229 sprintf(ts2, "%15.8e", sca_uld);
230 if (SDDS_DefineParameter(&SDDS_dataset, "SCA-LLD", NULL, "V", "SCA Lower-Level Discriminator Setting", NULL, SDDS_DOUBLE, ts1) < 0 ||
231 SDDS_DefineParameter(&SDDS_dataset, "SCA-ULD", NULL, "V", "SCA Upper-Level Discriminator Setting", NULL, SDDS_DOUBLE, ts2) < 0)
232 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
233 } else {
234 sprintf(ts1, "%15.8e", disc);
235 if (SDDS_DefineParameter(&SDDS_dataset, "DiscrimLevel", NULL, "V", "Discriminator Level", NULL, SDDS_DOUBLE, ts1) < 0 ||
236 SDDS_DefineParameter(&SDDS_dataset, "DiscrimSlope", NULL, NULL, "Discriminator Slope", NULL, SDDS_LONG, disc_edge ? "+1" : "-1") < 0)
237 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
238 }
239
240 if (consistent == 0) {
241 if (SDDS_DefineParameter(&SDDS_dataset, "Inconsistent", NULL, NULL, "Flag indicating whether data and settings are inconsistent", NULL, SDDS_LONG, "1") < 0)
242 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
243 fprintf(stderr, "WARNING: Settings are not consistent with data\n");
244 }
245
246 if (SDDS_DefineColumn(&SDDS_dataset, "ChannelNumber", NULL, NULL, "Channel number", NULL, SDDS_LONG, 0) < 0 ||
247 SDDS_DefineColumn(&SDDS_dataset, "EventCount", NULL, NULL, "Number of events", NULL, SDDS_LONG, 0) < 0 ||
248 !SDDS_WriteLayout(&SDDS_dataset) || !SDDS_StartPage(&SDDS_dataset, (long)pass_length))
249 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
250
251 /***************************************************************************/
252 /* Channel Data */
253 /* Output channel data from MCS file */
254 /***************************************************************************/
255 channel = tmalloc(sizeof(*channel) * pass_length);
256 count = tmalloc(sizeof(*count) * pass_length);
257 ucount = tmalloc(sizeof(*ucount) * pass_length);
258 if (fread(ucount, sizeof(*ucount), pass_length, fpi) != pass_length)
259 SDDS_Bomb("unable to read channel data");
260 for (i = 0; i < (long)pass_length; i++) {
261 swapulong(ucount + i);
262 count[i] = (long)ucount[i];
263 channel[i] = i;
264 }
265 if (!SDDS_SetColumn(&SDDS_dataset, SDDS_SET_BY_NAME, channel, (long)pass_length, "ChannelNumber") ||
266 !SDDS_SetColumn(&SDDS_dataset, SDDS_SET_BY_NAME, count, (long)pass_length, "EventCount") ||
267 !SDDS_WritePage(&SDDS_dataset) || !SDDS_Terminate(&SDDS_dataset))
268 SDDS_PrintErrors(stderr, SDDS_EXIT_PrintErrors | SDDS_VERBOSE_PrintErrors);
269 fclose(fpi);
270 return (0);
271}
272
273void swapshort(short *data) {
274 unsigned char c1;
275 c1 = *((char *)data);
276 *((char *)data) = *(((char *)data) + 1);
277 *(((char *)data) + 1) = c1;
278}
279
280void swapushort(unsigned short *data) {
281 unsigned char c1;
282 c1 = *((char *)data);
283 *((char *)data) = *(((char *)data) + 1);
284 *(((char *)data) + 1) = c1;
285}
286
287void swaplong(long *data) {
288 long copy;
289 copy = *data;
290 *(((char *)data) + 0) = *(((char *)&copy) + 3);
291 *(((char *)data) + 1) = *(((char *)&copy) + 2);
292 *(((char *)data) + 2) = *(((char *)&copy) + 1);
293 *(((char *)data) + 3) = *(((char *)&copy) + 0);
294}
295
296void swapulong(unsigned long *data) {
297 unsigned long copy;
298 copy = *data;
299 *(((char *)data) + 0) = *(((char *)&copy) + 3);
300 *(((char *)data) + 1) = *(((char *)&copy) + 2);
301 *(((char *)data) + 2) = *(((char *)&copy) + 1);
302 *(((char *)data) + 3) = *(((char *)&copy) + 0);
303}
304
305void swapfloat(float *data) {
306 float copy;
307 copy = *data;
308 *(((char *)data) + 0) = *(((char *)&copy) + 3);
309 *(((char *)data) + 1) = *(((char *)&copy) + 2);
310 *(((char *)data) + 2) = *(((char *)&copy) + 1);
311 *(((char *)data) + 3) = *(((char *)&copy) + 0);
312}
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_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
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
Definition bomb.c:26
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