def open_bh_sdt(fn, mode='r'): """ read Becker&Hickel SDT file into separate structures any error here might result from the file being corrupt """ #b = file(fn, 'rb').read() m = N.memmap(fn, mode=mode) hdrEnd = dtype_bhfile_header.itemsize lenDBhdr = dtype_BHFileBlockHeader.itemsize hdr = N.rec.array(m[:hdrEnd], dtype=dtype_bhfile_header) [0] #hdr = m[:hdrEnd].view(dtype_bhfile_header) if hdr['header_valid'] != BH_HEADER_VALID: print " * WARNING * SDT file file header not valid" infoStart = hdr['info_offs'] infoEnd = infoStart + hdr['info_length'] info= m[infoStart:infoEnd] info= info.view(N.dtype( (N.string_, len(info)) )) [0] setupStart= hdr['setup_offs'] setupEnd = setupStart + hdr['setup_length'] setup = m[setupStart:setupEnd] setup = setup.view(N.dtype( (N.string_, len(setup)) )) [0] setupTxtEnd = N.char.find(setup, '*END') + len('*END') setupTxt = setup[:setupTxtEnd] # following bytes are: '\r\n\r\n.......' # >>> U.hexdump(s.setup[s.setupTxtEnd:s.setupTxtEnd+21]) # 0000 0d 0a 0d 0a 42 49 4e 5f 50 41 52 41 5f 42 45 47 ....BIN_PARA_BEG # 0010 49 4e 3a 00 0e IN:.. #setupBin = nDBs = hdr['no_of_data_blocks'] if nDBs == 0x7fff: nDBs = hdr['reserved1'] #if nDBs != 1: # print " * WARNING * SDT file has more than one data block(nDBs=%s)"%(nDBs,) nMDBs = hdr['no_of_meas_desc_blocks'] mdbStart = hdr['meas_desc_block_offs'] lenMDB = hdr['meas_desc_block_length'] numMDB = hdr['no_of_meas_desc_blocks'] dataMeasInfos = m[mdbStart:mdbStart+numMDB*lenMDB].view(dtype=dtype_MeasureInfo) import weakref dbHdr = [] dbData = [] db0Start = hdr['data_block_offs'] o = db0Start for i in range(nDBs): dbh = m[o:o+lenDBhdr].view(dtype=dtype_BHFileBlockHeader) [0] dbHdr.append( dbh ) dbo = dbh['data_offs'] dbl = dbh['block_length'] #dbd = N.array(m[dbo:dbo+dbl], dtype=N.uint16) #ValueError: setting an array element with a sequence. dbd = m[dbo:dbo+dbl].view(dtype=N.uint16) #dbd.SDT_DataHdr = dbh #dbd.SDT_DataMeasInfo = weakref.proxy( measInfos[ dbh['meas_desc_block_no'] ] ) dbd = ndarray_inSdtFile(dbd, dataHdr=dbh, dataMeasInfo=dataMeasInfos[ dbh['meas_desc_block_no'] ] ) nx = dbd.SDT_DataMeasInfo['image_x'] ny = dbd.SDT_DataMeasInfo['image_y'] if nx>0 and ny >0: # FLIM !! dbd.shape = nx,ny,-1 dbd = dbd.T dbData.append(dbd) o = dbh['next_block_offs'] del dbh,dbd,dbo, dbl, nx, ny del o, i, weakref dataBlkHdrs = F.mockNDarray(*dbHdr) dataBlks = F.mockNDarray(*dbData) del dbHdr, dbData #return U.localsAsOneObject() #data = ndarray_inSdtFile(dbData[0], U.localsAsOneObject()) #data.SDT.data = weakref.proxy( self.) # remove circular reference dataBlks.SDT = U.localsAsOneObject() import weakref dataBlks.SDT.dataBlks = weakref.proxy( dataBlks ) # remove circular reference if len(dataBlks) == 1 and dataBlks[0].ndim>1: # one FLIM data block dataBlks[0].SDT = dataBlks.SDT.dataBlks return dataBlks[0] else: return dataBlks
# reading Becker & Hickl SDT files # from time resolved fluorescence spectroscopy # and FLIM experiments # ref SPC_data_file_structure.h dtype_bhfile_header = N.dtype([ ('revision', N.int16), #; // software revision number (lower 4 bits >= 10(decimal)) ('info_offs', N.int32), #; // offset of the info part which contains general text # // information (Title, date, time, contents etc.) ('info_length', N.int16),#; // length of the info part ('setup_offs', N.int32), #; // offset of the setup text data # // (system parameters, display parameters, trace parameters etc.) ('setup_length', N.int16),#;// length of the setup data ('data_block_offs', N.int32),#; offset of the first data block ('no_of_data_blocks', N.int16),#;no_of_data_blocks valid only when in 0 .. 0x7ffe range, #// if equal to 0x7fff the field 'reserved1' contains #// valid no_of_data_blocks ('data_block_length', N.int32),#// length of the longest block in the file ('meas_desc_block_offs', N.int32),#; // offset to 1st. measurement description block #// (system parameters connected to data blocks) ('no_of_meas_desc_blocks', N.int16),#; // number of measurement description blocks ('meas_desc_block_length', N.int16),#; // length of the measurement description blocks ('header_valid', N.uint16), #; // valid: 0x5555, not valid: 0x1111 ('reserved1', N.uint32), #; // reserved1 now contains no_of_data_blocks ('reserved2', N.uint16), ('chksum', N.uint16), #; // checksum of file header ]) BH_HEADER_CHKSUM = 0x55aa BH_HEADER_NOT_VALID = 0x1111 BH_HEADER_VALID = 0x5555