This repository was archived by the owner on Sep 16, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathReadMarCCDFrame.py
More file actions
461 lines (416 loc) · 29.6 KB
/
ReadMarCCDFrame.py
File metadata and controls
461 lines (416 loc) · 29.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
#!/usr/bin/env python
from __future__ import division, print_function
'''Defines a routine to read from MARCCD files
'''
"""
from /opt/marccd/documentation/header.txt
MarCCD Header Documentataion
from C code in frame.h and types.h
Documentation updated by R. Doyle Mon Mar 22 15:04:00 CDT 2010
Documentation updated by M. Blum Tue Oct 11 11:49:20 CDT 2005
Description documents marccd v0.20.0
Summary of file structure:
|-- 1024 bytes TIFF HEADER -------------|
|-- 3072 byte frame_header structure ---|
|-- nfast*nslow*depth byte image -------|
The full header, as written to the file, is a TIFF header.
The initial 1024 bytes are a minimal TIFF header with a standard
TIFF TAG pointing to the image data and a private TIFF TAG
pointing to this header structure. As written by mmx/marccd, the
frame_header structure always begins at byte 1024 and is 3072 bytes long
making the full header 4096 bytes.
immediately following the header is the image - it is of arbitrary size defined
by the header fields nfast, nslow and depth. The total size is
nfast * nslow * depth bytes.
The meanings of the data types should be self evident:
(example: UINT32 is an unsigned 32 bit integer)
The exact C language definition is machine dependent but these
are the most common definitions on a 32bit architecture cpu.
#define UINT16 unsigned short
#define INT16 short
#define UINT32 unsigned int
#define INT32 int
Currently frames are always written as defined below:
origin=UPPER_LEFT
orientation=HFAST
view_direction=FROM_SOURCE
/* This number is written into the byte_order fields in the
native byte order of the machine writing the file */
#define LITTLE_ENDIAN 1234
#define BIG_ENDIAN 4321
/* possible orientations of frame data (stored in orienation field) */
#define HFAST 0 /* Horizontal axis is fast */
#define VFAST 1 /* Vertical axis is fast */
/* possible origins of frame data (stored in origin field) */
#define UPPER_LEFT 0
#define LOWER_LEFT 1
#define UPPER_RIGHT 2
#define LOWER_RIGHT 3
/* possible view directions of frame data for
the given orientation and origin (stored in view_direction field) */
#define FROM_SOURCE 0
#define TOWARD_SOURCE 1
/* possible types of data (in data_type field) */
#define DATA_UNSIGNED_INTEGER 0
#define DATA_SIGNED_INTEGER 1
#define DATA_FLOAT 2
#define MAXIMAGES 9
#define MAXSUBIMAGES 4096
#define MAXFRAMEDIMENSION 8192
typedef struct frame_header_type {
/* File/header format parameters (256 bytes) */
UINT32 header_type; /* flag for header type (can be used as magic number) */
char header_name[16]; /* header name (MARCCD) */
UINT32 header_major_version; /* header_major_version (n.) */
UINT32 header_minor_version; /* header_minor_version (.n) */
UINT32 header_byte_order;/* BIG_ENDIAN (Motorola,MIPS); LITTLE_ENDIAN (DEC, Intel) */
UINT32 data_byte_order; /* BIG_ENDIAN (Motorola,MIPS); LITTLE_ENDIAN (DEC, Intel) */
UINT32 header_size; /* in bytes */
UINT32 frame_type; /* flag for frame type */
UINT32 magic_number; /* to be used as a flag - usually to indicate new file */
UINT32 compression_type; /* type of image compression */
UINT32 compression1; /* compression parameter 1 */
UINT32 compression2; /* compression parameter 2 */
UINT32 compression3; /* compression parameter 3 */
UINT32 compression4; /* compression parameter 4 */
UINT32 compression5; /* compression parameter 4 */
UINT32 compression6; /* compression parameter 4 */
UINT32 nheaders; /* total number of headers */
UINT32 nfast; /* number of pixels in one line */
UINT32 nslow; /* number of lines in image */
UINT32 depth; /* number of bytes per pixel */
UINT32 record_length; /* number of pixels between succesive rows */
UINT32 signif_bits; /* true depth of data, in bits */
UINT32 data_type; /* (signed,unsigned,float...) */
UINT32 saturated_value; /* value marks pixel as saturated */
UINT32 sequence; /* TRUE or FALSE */
UINT32 nimages; /* total number of images - size of each is nfast*(nslow/nimages) */
UINT32 origin; /* corner of origin */
UINT32 orientation; /* direction of fast axis */
UINT32 view_direction; /* direction to view frame */
UINT32 overflow_location;/* FOLLOWING_HEADER, FOLLOWING_DATA */
UINT32 over_8_bits; /* # of pixels with counts > 255 */
UINT32 over_16_bits; /* # of pixels with count > 65535 */
UINT32 multiplexed; /* multiplex flag */
UINT32 nfastimages; /* # of images in fast direction */
UINT32 nslowimages; /* # of images in slow direction */
UINT32 darkcurrent_applied; /* flags correction has been applied - hold magic number ? */
UINT32 bias_applied; /* flags correction has been applied - hold magic number ? */
UINT32 flatfield_applied; /* flags correction has been applied - hold magic number ? */
UINT32 distortion_applied; /* flags correction has been applied - hold magic number ? */
UINT32 original_header_type; /* Header/frame type from file that frame is read from */
UINT32 file_saved; /* Flag that file has been saved, should be zeroed if modified */
UINT32 n_valid_pixels; /* Number of pixels holding valid data - first N pixels */
UINT32 defectmap_applied; /* flags correction has been applied - hold magic number ? */
UINT32 subimage_nfast; /* when divided into subimages (eg. frameshifted) */
UINT32 subimage_nslow; /* when divided into subimages (eg. frameshifted) */
UINT32 subimage_origin_fast; /* when divided into subimages (eg. frameshifted) */
UINT32 subimage_origin_slow; /* when divided into subimages (eg. frameshifted) */
UINT32 readout_pattern; /* BIT Code - 1 = A, 2 = B, 4 = C, 8 = D */
UINT32 saturation_level; /* at this value and above, data are not reliable */
UINT32 orientation_code; /* Describes how this frame needs to be rotated to make it "right" */
UINT32 frameshift_multiplexed; /* frameshift multiplex flag */
UINT32 prescan_nfast; /* Number of non-image pixels preceeding imaging pixels - fast direction */
UINT32 prescan_nslow; /* Number of non-image pixels preceeding imaging pixels - slow direction */
UINT32 postscan_nfast; /* Number of non-image pixels followng imaging pixels - fast direction */
UINT32 postscan_nslow; /* Number of non-image pixels followng imaging pixels - slow direction */
UINT32 prepost_trimmed; /* trimmed==1 means pre and post scan pixels have been removed */
char reserve1[(64-55)*sizeof(INT32)-16];
/* Data statistics (128) */
UINT32 total_counts[2]; /* 64 bit integer range = 1.85E19*/
UINT32 special_counts1[2];
UINT32 special_counts2[2];
UINT32 min;
UINT32 max;
INT32 mean; /* mean * 1000 */
UINT32 rms; /* rms * 1000 */
UINT32 n_zeros; /* number of pixels with 0 value - not included in stats in unsigned data */
UINT32 n_saturated; /* number of pixels with saturated value - not included in stats */
UINT32 stats_uptodate; /* Flag that stats OK - ie data not changed since last calculation */
UINT32 pixel_noise[MAXIMAGES]; /* 1000*base noise value (ADUs) */
char reserve2[(32-13-MAXIMAGES)*sizeof(INT32)];
/* Sample Changer info */
char barcode[16];
UINT32 barcode_angle;
UINT32 barcode_status;
/* Pad to 256 bytes */
char reserve2a[(64-6)*sizeof(INT32)];
/* Goniostat parameters (128 bytes) */
INT32 xtal_to_detector; /* 1000*distance in millimeters */
INT32 beam_x; /* 1000*x beam position (pixels) */
INT32 beam_y; /* 1000*y beam position (pixels) */
INT32 integration_time; /* integration time in milliseconds */
INT32 exposure_time; /* exposure time in milliseconds */
INT32 readout_time; /* readout time in milliseconds */
INT32 nreads; /* number of readouts to get this image */
INT32 start_twotheta; /* 1000*two_theta angle */
INT32 start_omega; /* 1000*omega angle */
INT32 start_chi; /* 1000*chi angle */
INT32 start_kappa; /* 1000*kappa angle */
INT32 start_phi; /* 1000*phi angle */
INT32 start_delta; /* 1000*delta angle */
INT32 start_gamma; /* 1000*gamma angle */
INT32 start_xtal_to_detector; /* 1000*distance in mm (dist in um)*/
INT32 end_twotheta; /* 1000*two_theta angle */
INT32 end_omega; /* 1000*omega angle */
INT32 end_chi; /* 1000*chi angle */
INT32 end_kappa; /* 1000*kappa angle */
INT32 end_phi; /* 1000*phi angle */
INT32 end_delta; /* 1000*delta angle */
INT32 end_gamma; /* 1000*gamma angle */
INT32 end_xtal_to_detector; /* 1000*distance in mm (dist in um)*/
INT32 rotation_axis; /* active rotation axis (index into above ie. 0=twotheta,1=omega...) */
INT32 rotation_range; /* 1000*rotation angle */
INT32 detector_rotx; /* 1000*rotation of detector around X */
INT32 detector_roty; /* 1000*rotation of detector around Y */
INT32 detector_rotz; /* 1000*rotation of detector around Z */
INT32 total_dose; /* Hz-sec (counts) integrated over full exposure */
char reserve3[(32-29)*sizeof(INT32)]; /* Pad Gonisotat parameters to 128 bytes */
/* Detector parameters (128 bytes) */
INT32 detector_type; /* detector type */
INT32 pixelsize_x; /* pixel size (nanometers) */
INT32 pixelsize_y; /* pixel size (nanometers) */
INT32 mean_bias; /* 1000*mean bias value */
INT32 photons_per_100adu; /* photons / 100 ADUs */
INT32 measured_bias[MAXIMAGES]; /* 1000*mean bias value for each image*/
INT32 measured_temperature[MAXIMAGES]; /* Temperature of each detector in milliKelvins */
INT32 measured_pressure[MAXIMAGES]; /* Pressure of each chamber in microTorr */
/* Retired reserve4 when MAXIMAGES set to 9 from 16 and two fields removed, and temp and pressure added
char reserve4[(32-(5+3*MAXIMAGES))*sizeof(INT32)];
*/
/* X-ray source and optics parameters (128 bytes) */
/* X-ray source parameters (14*4 bytes) */
INT32 source_type; /* (code) - target, synch. etc */
INT32 source_dx; /* Optics param. - (size microns) */
INT32 source_dy; /* Optics param. - (size microns) */
INT32 source_wavelength; /* wavelength (femtoMeters) */
INT32 source_power; /* (Watts) */
INT32 source_voltage; /* (Volts) */
INT32 source_current; /* (microAmps) */
INT32 source_bias; /* (Volts) */
INT32 source_polarization_x; /* () */
INT32 source_polarization_y; /* () */
INT32 source_intensity_0; /* (arbitrary units) */
INT32 source_intensity_1; /* (arbitrary units) */
char reserve_source[2*sizeof(INT32)];
/* X-ray optics_parameters (8*4 bytes) */
INT32 optics_type; /* Optics type (code)*/
INT32 optics_dx; /* Optics param. - (size microns) */
INT32 optics_dy; /* Optics param. - (size microns) */
INT32 optics_wavelength; /* Optics param. - (size microns) */
INT32 optics_dispersion; /* Optics param. - (*10E6) */
INT32 optics_crossfire_x; /* Optics param. - (microRadians) */
INT32 optics_crossfire_y; /* Optics param. - (microRadians) */
INT32 optics_angle; /* Optics param. - (monoch. 2theta - microradians) */
INT32 optics_polarization_x; /* () */
INT32 optics_polarization_y; /* () */
char reserve_optics[4*sizeof(INT32)];
char reserve5[((32-28)*sizeof(INT32))]; /* Pad X-ray parameters to 128 bytes */
/* File parameters (1024 bytes) */
char filetitle[128]; /* Title */
char filepath[128]; /* path name for data file */
char filename[64]; /* name of data file */
char acquire_timestamp[32]; /* date and time of acquisition */
char header_timestamp[32]; /* date and time of header update */
char save_timestamp[32]; /* date and time file saved */
char file_comment[512]; /* comments - can be used as desired */
char reserve6[1024-(128+128+64+(3*32)+512)]; /* Pad File parameters to 1024 bytes */
/* Dataset parameters (512 bytes) */
char dataset_comment[512]; /* comments - can be used as desired */
/* Reserved for user definable data - will not be used by Mar! */
char user_data[512];
/* char pad[----] USED UP! */ /* pad out to 3072 bytes */
} frame_header;
"""
import struct as st
import array as ar
MAXIMAGES=9
class marFrame():
'''A class to extract correct mar header and image info from a MarCCD file
:param str File: file object [from open()]
:param byteOrd: '<' (default) or '>'
:param dict IFD: ?
'''
def __init__(self,File,byteOrd='<',IFD={}):
# simple TIFF header info
self.TIFFsizeX = IFD[256][2][0]
self.TIFFsizeY = IFD[257][2][0]
self.TIFFbitDepth = IFD[258][2][0]
self.TIFFcompression = IFD[259][2][0] # 1 = no compression
self.TIFFphotometricInterpretation = IFD[262][2][0] # 1 = bilevel or grayscale where 0 is imaged as black
self.TIFFstripOffsets = IFD[273][2][0] # seems to be 4096 for marCCD
self.TIFForientation = IFD[274][2][0] # 1 = 0th row it top, 0th column is left
self.TIFFrowsPerStrip = IFD[278][2][0] # varies based on image size
self.TIFFstripByteCounts = IFD[279][2][0] # number of bytes in a strip also varies based on size
self.TIFFxResolution = IFD[282][2][0] # pixels per resolutionUnit in X direction (ImageWidth direction)
self.TIFFyResolution = IFD[283][2][0] # pixels per resolutionUnit in Y direction (ImageLength direction
self.TIFFresolutionUnit = IFD[296][2][0] # 3 = centimeter
self.byteDepth = self.TIFFbitDepth//8
self.arrayTypeCode = ['','B','H','I','I'][self.byteDepth]
# MarCCD specific header info
File.seek(IFD[34710][2][0])
self.headerType = st.unpack(byteOrd+'I',File.read(4))[0] #/* flag for header type (can be used as magic number) */
self.headerName = b''.join(st.unpack(byteOrd+16*'s',File.read(16))).replace(b'\x00',b'')
self.headerMajorVersion = st.unpack(byteOrd+'I',File.read(4))[0] #/* header_major_version (n.) */
self.headerMinorVersion = st.unpack(byteOrd+'I',File.read(4))[0] #/* header_minor_version (.n) */
self.headerByteOrder = st.unpack(byteOrd+'I',File.read(4))[0] #/* BIG_ENDIAN (Motorola,MIPS); LITTLE_ENDIAN (DEC, Intel) */
self.dataByteOrder = st.unpack(byteOrd+'I',File.read(4))[0] #/* BIG_ENDIAN (Motorola,MIPS); LITTLE_ENDIAN (DEC, Intel) */
self.headerSize = st.unpack(byteOrd+'I',File.read(4))[0] #/* in bytes */
self.frameType = st.unpack(byteOrd+'I',File.read(4))[0] #/* flag for frame type */
self.magicNumber = st.unpack(byteOrd+'I',File.read(4))[0] #/* to be used as a flag - usually to indicate new file */
self.compressionType = st.unpack(byteOrd+'I',File.read(4))[0] #/* type of image compression */
self.compression1 = st.unpack(byteOrd+'I',File.read(4))[0] #/* compression parameter 1 */
self.compression2 = st.unpack(byteOrd+'I',File.read(4))[0] #/* compression parameter 2 */
self.compression3 = st.unpack(byteOrd+'I',File.read(4))[0] #/* compression parameter 3 */
self.compression4 = st.unpack(byteOrd+'I',File.read(4))[0] #/* compression parameter 4 */
self.compression5 = st.unpack(byteOrd+'I',File.read(4))[0] #/* compression parameter 4 */
self.compression6 = st.unpack(byteOrd+'I',File.read(4))[0] #/* compression parameter 4 */
self.nheaders = st.unpack(byteOrd+'I',File.read(4))[0] #/* total number of headers */
self.nfast = st.unpack(byteOrd+'I',File.read(4))[0] #/* number of pixels in one line */
self.nslow = st.unpack(byteOrd+'I',File.read(4))[0] #/* number of lines in image */
self.depth = st.unpack(byteOrd+'I',File.read(4))[0] #/* number of bytes per pixel */
self.recordLength = st.unpack(byteOrd+'I',File.read(4))[0] #/* number of pixels between succesive rows */
self.signifBits = st.unpack(byteOrd+'I',File.read(4))[0] #/* true depth of data, in bits */
self.dataType = st.unpack(byteOrd+'I',File.read(4))[0] #/* (signed,unsigned,float...) */
self.saturatedValue = st.unpack(byteOrd+'I',File.read(4))[0] #/* value marks pixel as saturated */
self.sequence = st.unpack(byteOrd+'I',File.read(4))[0] #/* TRUE or FALSE */
self.nimages = st.unpack(byteOrd+'I',File.read(4))[0] #/* total number of images - size of each is nfast*(nslow/nimages) */
self.origin = st.unpack(byteOrd+'I',File.read(4))[0] #/* corner of origin */
self.orientation = st.unpack(byteOrd+'I',File.read(4))[0] #/* direction of fast axis */
self.viewDirection = st.unpack(byteOrd+'I',File.read(4))[0] #/* direction to view frame */
self.overflowLocation = st.unpack(byteOrd+'I',File.read(4))[0] #/* FOLLOWING_HEADER, FOLLOWING_DATA */
self.over8Bits = st.unpack(byteOrd+'I',File.read(4))[0] #/* # of pixels with counts > 255 */
self.over16Bits = st.unpack(byteOrd+'I',File.read(4))[0] #/* # of pixels with count > 65535 */
self.multiplexed = st.unpack(byteOrd+'I',File.read(4))[0] #/* multiplex flag */
self.nfastimages = st.unpack(byteOrd+'I',File.read(4))[0] #/* # of images in fast direction */
self.nslowimages = st.unpack(byteOrd+'I',File.read(4))[0] #/* # of images in slow direction */
self.darkcurrentApplied = st.unpack(byteOrd+'I',File.read(4))[0] #/* flags correction has been applied - hold magic number ? */
self.biasApplied = st.unpack(byteOrd+'I',File.read(4))[0] #/* flags correction has been applied - hold magic number ? */
self.flatfieldApplied = st.unpack(byteOrd+'I',File.read(4))[0] #/* flags correction has been applied - hold magic number ? */
self.distortionApplied = st.unpack(byteOrd+'I',File.read(4))[0] #/* flags correction has been applied - hold magic number ? */
self.originalHeaderType = st.unpack(byteOrd+'I',File.read(4))[0] #/* Header/frame type from file that frame is read from */
self.fileSaved = st.unpack(byteOrd+'I',File.read(4))[0] #/* Flag that file has been saved, should be zeroed if modified */
self.nValidPixels = st.unpack(byteOrd+'I',File.read(4))[0] #/* Number of pixels holding valid data - first N pixels */
self.defectmapApplied = st.unpack(byteOrd+'I',File.read(4))[0] #/* flags correction has been applied - hold magic number ? */
self.subimageNfast = st.unpack(byteOrd+'I',File.read(4))[0] #/* when divided into subimages (eg. frameshifted) */
self.subimageNslow = st.unpack(byteOrd+'I',File.read(4))[0] #/* when divided into subimages (eg. frameshifted) */
self.subimageOriginFast = st.unpack(byteOrd+'I',File.read(4))[0] #/* when divided into subimages (eg. frameshifted) */
self.subimageOriginSlow = st.unpack(byteOrd+'I',File.read(4))[0] #/* when divided into subimages (eg. frameshifted) */
self.readoutPattern = st.unpack(byteOrd+'I',File.read(4))[0] #/* BIT Code - 1 = A, 2 = B, 4 = C, 8 = D */
self.saturationLevel = st.unpack(byteOrd+'I',File.read(4))[0] #/* at this value and above, data are not reliable */
self.orientationCode = st.unpack(byteOrd+'I',File.read(4))[0] #/* Describes how this frame needs to be rotated to make it "right" */
self.frameshiftMultiplexed = st.unpack(byteOrd+'I',File.read(4))[0] #/* frameshift multiplex flag */
self.prescanNfast = st.unpack(byteOrd+'I',File.read(4))[0] #/* Number of non-image pixels preceeding imaging pixels - fast direction */
self.prescanNslow = st.unpack(byteOrd+'I',File.read(4))[0] #/* Number of non-image pixels preceeding imaging pixels - slow direction */
self.postscanNfast = st.unpack(byteOrd+'I',File.read(4))[0] #/* Number of non-image pixels followng imaging pixels - fast direction */
self.postscanNslow = st.unpack(byteOrd+'I',File.read(4))[0] #/* Number of non-image pixels followng imaging pixels - slow direction */
self.prepostTrimmed = st.unpack(byteOrd+'I',File.read(4))[0] #/* trimmed==1 means pre and post scan pixels have been removed */
File.seek(IFD[34710][2][0]+256)
#self.totalCounts = st.unpack(byteOrd+'Q',File.read(8))[0] # /* 64 bit integer range = 1.85E19*/
#self.specialCounts1 = st.unpack(byteOrd+'Q',File.read(8))[0]
#self.specialCounts2 = st.unpack(byteOrd+'Q',File.read(8))[0]
self.totalCounts = st.unpack(byteOrd+'II',File.read(8))
self.specialCounts1 = st.unpack(byteOrd+'II',File.read(8))
self.specialCounts2 = st.unpack(byteOrd+'II',File.read(8))
self.min = st.unpack(byteOrd+'I',File.read(4))[0]
self.max = st.unpack(byteOrd+'I',File.read(4))[0]
self.mean = st.unpack(byteOrd+'i',File.read(4))[0] # /* mean * 1000 */
self.rms = st.unpack(byteOrd+'I',File.read(4))[0] #/* rms * 1000 */
self.nZeros = st.unpack(byteOrd+'I',File.read(4))[0] #/* number of pixels with 0 value - not included in stats in unsigned data */
self.nSaturated = st.unpack(byteOrd+'I',File.read(4))[0] #/* number of pixels with saturated value - not included in stats */
self.statsUptodate = st.unpack(byteOrd+'I',File.read(4))[0] #/* Flag that stats OK - ie data not changed since last calculation */
self.pixelNoise = st.unpack(byteOrd+'I'*MAXIMAGES,File.read(4*MAXIMAGES)) # /* 1000*base noise value (ADUs) */
File.seek(IFD[34710][2][0]+256+128)
self.barcode = b''.join(st.unpack(byteOrd+16*'s',File.read(16))).replace(b'\x00',b'')
self.barcodeAngle = st.unpack(byteOrd+'I',File.read(4))[0]
self.barcodeStatus = st.unpack(byteOrd+'I',File.read(4))[0]
File.seek(IFD[34710][2][0]+256+128+256)
self.xtalToDetector = st.unpack(byteOrd+'i',File.read(4))[0] #/* 1000*distance in millimeters */
self.beamX = st.unpack(byteOrd+'i',File.read(4))[0] #/* 1000*x beam position (pixels) */
self.beamY = st.unpack(byteOrd+'i',File.read(4))[0] #/* 1000*y beam position (pixels) */
self.integrationTime = st.unpack(byteOrd+'i',File.read(4))[0] #/* integration time in milliseconds */
self.exposureTime = st.unpack(byteOrd+'i',File.read(4))[0] #/* exposure time in milliseconds */
self.readoutTime = st.unpack(byteOrd+'i',File.read(4))[0] #/* readout time in milliseconds */
self.nreads = st.unpack(byteOrd+'i',File.read(4))[0] #/* number of readouts to get this image */
self.startTwotheta = st.unpack(byteOrd+'i',File.read(4))[0] #/* 1000*two_theta angle */
self.startOmega = st.unpack(byteOrd+'i',File.read(4))[0] #/* 1000*omega angle */
self.startChi = st.unpack(byteOrd+'i',File.read(4))[0] #/* 1000*chi angle */
self.startKappa = st.unpack(byteOrd+'i',File.read(4))[0] #/* 1000*kappa angle */
self.startPhi = st.unpack(byteOrd+'i',File.read(4))[0] #/* 1000*phi angle */
self.startDelta = st.unpack(byteOrd+'i',File.read(4))[0] #/* 1000*delta angle */
self.startGamma = st.unpack(byteOrd+'i',File.read(4))[0] #/* 1000*gamma angle */
self.startXtalToDetector = st.unpack(byteOrd+'i',File.read(4))[0] #/* 1000*distance in mm (dist in um)*/
self.endTwotheta = st.unpack(byteOrd+'i',File.read(4))[0] #/* 1000*two_theta angle */
self.endOmega = st.unpack(byteOrd+'i',File.read(4))[0] #/* 1000*omega angle */
self.endChi = st.unpack(byteOrd+'i',File.read(4))[0] #/* 1000*chi angle */
self.endKappa = st.unpack(byteOrd+'i',File.read(4))[0] #/* 1000*kappa angle */
self.endPhi = st.unpack(byteOrd+'i',File.read(4))[0] #/* 1000*phi angle */
self.endDelta = st.unpack(byteOrd+'i',File.read(4))[0] #/* 1000*delta angle */
self.endGamma = st.unpack(byteOrd+'i',File.read(4))[0] #/* 1000*gamma angle */
self.endXtalToDetector = st.unpack(byteOrd+'i',File.read(4))[0] #/* 1000*distance in mm (dist in um)*/
self.rotationAxis = st.unpack(byteOrd+'i',File.read(4))[0] #/* active rotation axis (index into above ie. 0=twotheta,1=omega...) */
self.rotationRange = st.unpack(byteOrd+'i',File.read(4))[0] #/* 1000*rotation angle */
self.detectorRotx = st.unpack(byteOrd+'i',File.read(4))[0] #/* 1000*rotation of detector around X */
self.detectorRoty = st.unpack(byteOrd+'i',File.read(4))[0] #/* 1000*rotation of detector around Y */
self.detectorRotz = st.unpack(byteOrd+'i',File.read(4))[0] #/* 1000*rotation of detector around Z */
self.totalDose = st.unpack(byteOrd+'i',File.read(4))[0] #/* Hz-sec (counts) integrated over full exposure */
File.seek(IFD[34710][2][0]+256+128+256+128)
self.detectorType = st.unpack(byteOrd+'i',File.read(4))[0] #/* detector type */
self.pixelsizeX = st.unpack(byteOrd+'i',File.read(4))[0] #/* pixel size (nanometers) */
self.pixelsizeY = st.unpack(byteOrd+'i',File.read(4))[0] #/* pixel size (nanometers) */
self.meanBias = st.unpack(byteOrd+'i',File.read(4))[0] #/* 1000*mean bias value */
self.photonsPer100adu = st.unpack(byteOrd+'i',File.read(4))[0] #/* photons / 100 ADUs */
self.measuredBias = st.unpack(byteOrd+'i'*MAXIMAGES,File.read(4*MAXIMAGES)) # /* 1000*mean bias value for each image*/
self.measuredTemperature = st.unpack(byteOrd+'i'*MAXIMAGES,File.read(4*MAXIMAGES)) # /* Temperature of each detector in milliKelvins */
self.measuredPressure = st.unpack(byteOrd+'i'*MAXIMAGES,File.read(4*MAXIMAGES)) # /* Pressure of each chamber in microTorr */
File.seek(IFD[34710][2][0]+256+128+256+128+128)
self.sourceType = st.unpack(byteOrd+'i',File.read(4))[0] #/* (code) - target, synch. etc */
self.sourceDx = st.unpack(byteOrd+'i',File.read(4))[0] #/* Optics param. - (size microns) */
self.sourceDy = st.unpack(byteOrd+'i',File.read(4))[0] #/* Optics param. - (size microns) */
self.sourceWavelength = st.unpack(byteOrd+'i',File.read(4))[0] #/* wavelength (femtoMeters) */
self.sourcePower = st.unpack(byteOrd+'i',File.read(4))[0] #/* (Watts) */
self.sourceVoltage = st.unpack(byteOrd+'i',File.read(4))[0] #/* (Volts) */
self.sourceCurrent = st.unpack(byteOrd+'i',File.read(4))[0] #/* (microAmps) */
self.sourceBias = st.unpack(byteOrd+'i',File.read(4))[0] #/* (Volts) */
self.sourcePolarizationX = st.unpack(byteOrd+'i',File.read(4))[0] #/* () */
self.sourcePolarizationY = st.unpack(byteOrd+'i',File.read(4))[0] #/* () */
self.sourceIntensity0 = st.unpack(byteOrd+'i',File.read(4))[0] #/* (arbitrary units) */
self.sourceIntensity1 = st.unpack(byteOrd+'i',File.read(4))[0] #/* (arbitrary units) */
File.seek(IFD[34710][2][0]+256+128+256+128+128+14*4)
self.opticsType = st.unpack(byteOrd+'i',File.read(4))[0] #/* Optics type (code)*/
self.opticsDx = st.unpack(byteOrd+'i',File.read(4))[0] #/* Optics param. - (size microns) */
self.opticsDy = st.unpack(byteOrd+'i',File.read(4))[0] #/* Optics param. - (size microns) */
self.opticsWavelength = st.unpack(byteOrd+'i',File.read(4))[0] #/* Optics param. - (size microns) */
self.opticsDispersion = st.unpack(byteOrd+'i',File.read(4))[0] #/* Optics param. - (*10E6) */
self.opticsCrossfireX = st.unpack(byteOrd+'i',File.read(4))[0] #/* Optics param. - (microRadians) */
self.opticsCrossfireY = st.unpack(byteOrd+'i',File.read(4))[0] #/* Optics param. - (microRadians) */
self.opticsAngle = st.unpack(byteOrd+'i',File.read(4))[0] #/* Optics param. - (monoch. 2theta - microradians) */
self.opticsPolarizationX = st.unpack(byteOrd+'i',File.read(4))[0] #/* () */
self.opticsPolarizationY = st.unpack(byteOrd+'i',File.read(4))[0] #/* () */
File.seek(IFD[34710][2][0]+256+128+256+128+128+128)
self.filetitle = b''.join(st.unpack(byteOrd+128*'s',File.read(128))).replace(b'\x00',b'')
self.filepath = b''.join(st.unpack(byteOrd+'s'*128,File.read(128))).replace(b'\x00',b'') #/* path name for data file*/
self.filename = b''.join(st.unpack(byteOrd+'s'*64,File.read(64))).replace(b'\x00',b'') #/* name of data file*/
self.acquireTimestamp = b''.join(st.unpack(byteOrd+'s'*32,File.read(32))).replace(b'\x00',b'') #/* date and time of acquisition*/
self.headerTimestamp = b''.join(st.unpack(byteOrd+'s'*32,File.read(32))).replace(b'\x00',b'') #/* date and time of header update*/
self.saveTimestamp = b''.join(st.unpack(byteOrd+'s'*32,File.read(32))).replace(b'\x00',b'') #/* date and time file saved */
self.fileComment = b''.join(st.unpack(byteOrd+'s'*512,File.read(512))).replace(b'\x00',b'') #/* comments - can be used as desired */
self.datasetComment = b''.join(st.unpack(byteOrd+'s'*512,File.read(512))).replace(b'\x00',b'') #/* comments - can be used as desired */
self.userData = b''.join(st.unpack(byteOrd+'s'*512,File.read(512))).replace(b'\x00',b'')
File.seek(4096)
self.image = ar.array(self.arrayTypeCode,File.read(self.byteDepth*self.TIFFsizeX*self.TIFFsizeY))
# reverse the array so if can have the same view as is read in marccd
# also switch the view direction
self.image.reverse()
self.viewDirection = abs(self.viewDirection - 1)
def outputHead(self):
myHead = []
for curAttr in dir(self):
if ( curAttr != '__doc__' and \
curAttr != '__init__' and \
curAttr != '__module__' and \
curAttr != 'outputHead' and \
curAttr != 'image' ):
if '__' not in str(curAttr):
myHead.append(" %s = %s" % (curAttr,getattr(self,curAttr)))
return myHead