fabio.marccdimage

Package fabio :: Module marccdimage |
[hide private]
[frames] | no frames]

# Source Code for Module fabio.marccdimage

      1  #!/usr/bin/env python
      2  """
      3
      4  Authors:
      5  ........
      6  * Henning O. Sorensen & Erik Knudsen:
      7    Center for Fundamental Research: Metal Structures in Four Dimensions;
      8    Risoe National Laboratory;
      9    Frederiksborgvej 399;
     10    DK-4000 Roskilde;
     11    email:erik.knudsen@risoe.dk
     12  * Jon Wright:
     13    European Synchrotron Radiation Facility;
     14    Grenoble (France)
     15
     16  marccdimage can read MarCCD and MarMosaic images including header info.
     17
     18  JPW : Use a parser in case of typos (sorry?)
     19
     20  """
     21
     22
     23  # Base this on the tifimage (as marccd seems to be tiff with a
     24  # special header
     25
     26  from tifimage import tifimage
     27  import logging
     28  logger = logging.getLogger("marccdimage")
     29
     30  # Now for the c definition (found on mar webpage)
     31  # The following string is therefore copyrighted by Mar I guess
     32
     33  CDEFINITION = """
     34  typedef struct frame_header_type {
     35           /* File/header format parameters (256 bytes) */
     36           UINT32        header_type;  /* flag for header type
     37                                             (can be  used as magic number) */
     38           char header_name[16];           /* header name (MMX) */
     39           UINT32        header_major_version;   /* header_major_version  (n.) */
     40           UINT32        header_minor_version;   /* header_minor_version  (.n) */
     41           UINT32        header_byte_order;/* BIG_ENDIAN (Motorola,MIPS);
     42                                              LITTLE_ENDIAN (DEC, Intel) */
     43           UINT32        data_byte_order;  /* BIG_ENDIAN (Motorola,MIPS);
     44                                              LITTLE_ENDIAN (DEC, Intel) */
     45           UINT32        header_size;      /* in bytes                     */
     46           UINT32        frame_type;       /* flag for frame type */
     47           UINT32        magic_number;     /* to be used as a flag -
     48                                              usually  to indicate new file */
     49           UINT32        compression_type; /* type of image compression    */
     50           UINT32        compression1;     /* compression parameter 1 */
     51           UINT32        compression2;     /* compression parameter 2 */
     52           UINT32        compression3;     /* compression parameter 3 */
     53           UINT32        compression4;     /* compression parameter 4 */
     54           UINT32        compression5;     /* compression parameter 4 */
     55           UINT32        compression6;     /* compression parameter 4 */
     56           UINT32        nheaders;         /* total number of headers      */
     57           UINT32        nfast;            /* number of pixels in one line */
     58           UINT32        nslow;            /* number of lines in image     */
     59           UINT32        depth;            /* number of bytes per pixel    */
     60           UINT32        record_length;    /* number of pixels between
     61                                              succesive rows */
     62           UINT32        signif_bits;      /* true depth of data, in bits  */
     63           UINT32        data_type;        /* (signed,unsigned,float...) */
     64           UINT32        saturated_value;  /* value marks pixel as saturated */
     65           UINT32        sequence;         /* TRUE or FALSE */
     66           UINT32        nimages;          /* total number of images - size of
     67                                              each is nfast*(nslow/nimages) */
     68           UINT32        origin;           /* corner of origin             */
     69           UINT32        orientation;      /* direction of fast axis       */
     70           UINT32        view_direction;   /* direction to view frame      */
     71           UINT32        overflow_location;/* FOLLOWING_HEADER,  FOLLOWING_DATA */
     72           UINT32        over_8_bits;      /* # of pixels with counts  255 */
     73           UINT32        over_16_bits;     /* # of pixels with count  65535 */
     74           UINT32        multiplexed;      /* multiplex flag */
     75           UINT32        nfastimages;      /* # of images in fast direction */
     76           UINT32        nslowimages;      /* # of images in slow direction */
     77           UINT32        background_applied;/* flags correction has been applied
     78                                                hold magic number ? */
     79           UINT32        bias_applied;     /* flags correction has been applied
     80                                               hold magic number ? */
     81           UINT32        flatfield_applied;/* flags correction has been applied -
     82                                                hold magic number ? */
     83           UINT32        distortion_applied;/*flags correction has been applied -
     84                                                hold magic number ? */
     85           UINT32        original_header_type;    /* Header/frame type from  file
     86                                                      that frame is read from */
     87           UINT32        file_saved;         /* Flag that file has been  saved,
     88                                                should be zeroed if modified */
     89           char reserve1[(64-40)*sizeof(INT32)-16];
     90
     91           /* Data statistics (128) */
     92           UINT32        total_counts[2];  /* 64 bit integer range = 1.85E19*/
     93           UINT32        special_counts1[2];
     94           UINT32        special_counts2[2];
     95           UINT32        min;
     96           UINT32        max;
     97           UINT32        mean;
     98           UINT32        rms;
     99           UINT32        p10;
    100           UINT32        p90;
    101           UINT32        stats_uptodate;
    102           UINT32        pixel_noise[MAXIMAGES]; /*1000*base noise value (ADUs) */
    103           char reserve2[(32-13-MAXIMAGES)*sizeof(INT32)];
    104
    105           /* More statistics (256) */
    106           UINT16 percentile[128];
    107
    108
    109           /* Goniostat parameters (128 bytes) */
    110           INT32 xtal_to_detector;  /* 1000*distance in millimeters */
    111           INT32 beam_x;            /* 1000*x beam position (pixels) */
    112           INT32 beam_y;            /* 1000*y beam position (pixels) */
    113           INT32 integration_time;  /* integration time in  milliseconds */
    114           INT32 exposure_time;     /* exposure time in milliseconds */
    115           INT32 readout_time;      /* readout time in milliseconds */
    116           INT32 nreads;            /* number of readouts to get this  image */
    117           INT32 start_twotheta;    /* 1000*two_theta angle */
    118           INT32 start_omega;       /* 1000*omega angle */
    119           INT32 start_chi;         /* 1000*chi angle */
    120           INT32 start_kappa;       /* 1000*kappa angle */
    121           INT32 start_phi;         /* 1000*phi angle */
    122           INT32 start_delta;       /* 1000*delta angle */
    123           INT32 start_gamma;       /* 1000*gamma angle */
    124           INT32 start_xtal_to_detector; /* 1000*distance in mm (dist in um)*/
    125           INT32 end_twotheta;           /* 1000*two_theta angle */
    126           INT32 end_omega;              /* 1000*omega angle */
    127           INT32 end_chi;                /* 1000*chi angle */
    128           INT32 end_kappa;              /* 1000*kappa angle */
    129           INT32 end_phi;                /* 1000*phi angle */
    130           INT32 end_delta;              /* 1000*delta angle */
    131           INT32 end_gamma;              /* 1000*gamma angle */
    132           INT32 end_xtal_to_detector;   /* 1000*distance in mm (dist in um)*/
    133           INT32 rotation_axis;          /* active rotation axis */
    134           INT32 rotation_range;         /* 1000*rotation angle */
    135           INT32 detector_rotx;          /* 1000*rotation of detector  around X */
    136           INT32 detector_roty;          /* 1000*rotation of detector  around Y */
    137           INT32 detector_rotz;          /* 1000*rotation of detector  around Z */
    138           char reserve3[(32-28)*sizeof(INT32)];
    139
    140           /* Detector parameters (128 bytes) */
    141           INT32 detector_type;            /* detector type */
    142           INT32 pixelsize_x;              /* pixel size (nanometers) */
    143           INT32 pixelsize_y;              /* pixel size (nanometers) */
    144           INT32 mean_bias;                        /* 1000*mean bias value */
    145           INT32 photons_per_100adu;       /* photons / 100 ADUs */
    146           INT32 measured_bias[MAXIMAGES];/* 1000*mean bias value for each image*/
    147           INT32 measured_temperature[MAXIMAGES];  /* Temperature of each
    148                                                      detector in milliKelvins */
    149           INT32 measured_pressure[MAXIMAGES]; /* Pressure of each  chamber
    150                                                 in microTorr */
    151           /* Retired reserve4 when MAXIMAGES set to 9 from 16 and
    152              two fields removed, and temp and pressure added
    153            char reserve4[(32-(5+3*MAXIMAGES))*sizeof(INT32)]
    154           */
    155
    156           /* X-ray source and optics parameters (128 bytes) */
    157           /* X-ray source parameters (8*4 bytes) */
    158           INT32 source_type;              /* (code) - target, synch. etc */
    159           INT32 source_dx;                /* Optics param. - (size  microns) */
    160           INT32 source_dy;                /* Optics param. - (size  microns) */
    161           INT32 source_wavelength;        /* wavelength  (femtoMeters) */
    162           INT32 source_power;             /* (Watts) */
    163           INT32 source_voltage;           /* (Volts) */
    164           INT32 source_current;           /* (microAmps) */
    165           INT32 source_bias;              /* (Volts) */
    166           INT32 source_polarization_x;    /* () */
    167           INT32 source_polarization_y;    /* () */
    168           char reserve_source[4*sizeof(INT32)];
    169
    170           /* X-ray optics_parameters (8*4 bytes) */
    171           INT32 optics_type;              /* Optics type (code)*/
    172           INT32 optics_dx;                /* Optics param. - (size  microns) */
    173           INT32 optics_dy;                /* Optics param. - (size  microns) */
    174           INT32 optics_wavelength;        /* Optics param. - (size  microns) */
    175           INT32 optics_dispersion;        /* Optics param. - (*10E6) */
    176           INT32 optics_crossfire_x;       /* Optics param. - (microRadians) */
    177           INT32 optics_crossfire_y;       /* Optics param. - (microRadians) */
    178           INT32 optics_angle;             /* Optics param. - (monoch.
    179                                                      2theta - microradians) */
    180           INT32 optics_polarization_x;    /* () */
    181           INT32 optics_polarization_y;    /* () */
    182           char reserve_optics[4*sizeof(INT32)];
    183
    184           char reserve5[((32-28)*sizeof(INT32))];
    185
    186           /* File parameters (1024 bytes) */
    187           char filetitle[128];            /*  Title                  */
    188           char filepath[128];             /* path name for data  file  */
    189           char filename[64];              /* name of data  file  */
    190           char acquire_timestamp[32];     /* date and time of  acquisition */
    191           char header_timestamp[32];      /* date and time of header  update  */
    192           char save_timestamp[32];        /* date and time file  saved */
    193           char file_comments[512];        /* comments, use as desired   */
    194           char reserve6[1024-(128+128+64+(3*32)+512)];
    195
    196           /* Dataset parameters (512 bytes) */
    197           char dataset_comments[512];     /* comments, used as desired   */
    198           /* pad out to  3072 bytes */
    199           char pad[3072-(256+128+256+(3*128)+1024+512)];
    200
    201           } frame_header;
    202  """
    203
    204  import struct
    205
    206  # Convert mar c header file types to python struct module types
    207  C_TO_STRUCT = {
    208      "INT32"  : "i",
    209      "UINT32" : "I",
    210      "char"   : "c",
    211      "UINT16" : "H"
    212      }
    213
    214  # Sizes (bytes) of mar c header objects
    215  C_SIZES = {
    216      "INT32"  : 4,
    217      "UINT32" : 4,
    218      "char"   : 1,
    219      "UINT16" : 2
    220      }
    221
    222  # This was worked out by trial and error from a trial image I think
    223  MAXIMAGES = 9
    224
    225
    226 -def make_format(c_def_string):
    227      """
    228      Reads the header definition in c and makes the format
    229      string to pass to struct.unpack
    230      """
    231      lines = c_def_string.split("\n")
    232      fmt = ""
    233      names = []
    234      expected = 0
    235      for line in lines:
    236          if line.find(";") == -1:
    237              continue
    238          decl = line.split(";")[0].lstrip().rstrip()
    239          try:
    240              [typ, name] = decl.split()
    241          except ValueError:
    242              logger.debug("skipping: %s" , line)
    243              continue
    244
    245          if name.find("[") > -1:
    246              # repeated ... times
    247              try:
    248                  num = name.split("[")[1].split("]")[0]
    249                  num = num.replace("MAXIMAGES", str(MAXIMAGES))
    250                  num = num.replace("sizeof(INT32)", "4")
    251                  times = eval(num)
    252              except Exception, error:
    253                  logger.error("%s Please decode %s", error, decl)
    254                  raise error
    255          else:
    256              times = 1
    257          try:
    258              fmt += C_TO_STRUCT[typ] * times
    259              names += [name] * times
    260              expected += C_SIZES[typ] * times
    261          except KeyError:
    262              continue
    263      return names, fmt
    264
    265  # Make these be compiled on loading module
    266  HEADER_NAMES, HEADER_FORMAT = make_format(CDEFINITION)
    267
    268 -def interpret_header(header, fmt, names):
    269      """
    270      given a format and header interpret it
    271      """
    272      values = struct.unpack(fmt, header)
    273      hdr = {}
    274      i = 0
    275      for name in names:
    276          if hdr.has_key(name):
    277              if type(values[i]) == type("string"):
    278                  hdr[name] = hdr[name] + values[i]
    279              else:
    280                  try:
    281                      hdr[name].append(values[i])
    282                  except AttributeError:
    283                      hdr[name] = [hdr[name], values[i]]
    284          else:
    285              hdr[name] = values[i]
    286          i = i + 1
    287
    288      return hdr
    289
    290
    291 -class marccdimage(tifimage):
    292      """ Read in data in mar ccd format, also
    293          MarMosaic images, including header info """
    294
    295
    296 -    def _readheader(self, infile):
    297          """
    298          Parser based approach
    299          Gets all entries
    300          """
    301          infile.seek(1024)
    302          hstr = infile.read(3072)
    303          self.header = interpret_header(hstr, HEADER_FORMAT, HEADER_NAMES)
    304
    305
    306
    307 -    def _read(self, fname):
    308          """
    309          inherited from tifimage
    310          ... a marccd image *is a* tif image
    311          just with a header
    312          """
    313          return tifimage.read(self, fname)
    314