def _read_header_config(fh, header_maxlines=HEADER_MAXLINES, header_comment=HEADER_COMMENT): """Read a ini-style file from the header of a text file. Return a PydosConfigParser object. Parameters ---------- fh : file handle, readable header_maxlines : max lines to read down from top of the file header_comment : comment sign w/ which the header must be prefixed Returns ------- PydosConfigParser object Examples -------- >>> !cat foo.txt # [array] # shape = 3 # axis = -1 1 2 3 >>> _get_header_config('foo.txt') <pwtools.common.PydosConfigParser instance at 0x2c52320> """ fn = common.get_filename(fh) verbose("[_read_header_config]: reading header from '%s'" %fn) header = '' for i in range(header_maxlines): try: line = fh.next().strip() except StopIteration: break if line.startswith(header_comment): header += line.replace(header_comment, '').strip() + '\n' # Read one more line to see if the header is bigger than header_maxlines. try: if fh.next().strip().startswith(header_comment): raise StandardError("header seems to be > header_maxlines (%i)" %header_maxlines) except StopIteration: pass c = PydosConfigParser() c.readfp(StringIO(header)) # If header_maxlines > header size, we read beyond the header into the data. That # causes havoc for all functions that read fh afterwards. fh.seek(0) return c
def writetxt(fn, arr, axis=-1, maxdim=TXT_MAXDIM, header=True): """Write 1d, 2d or 3d arrays to txt file. If 3d, write as 2d chunks. Take the 2d chunks along `axis`. Write a commented out ini-style header in the file with infos needed by readtxt() to restore the right shape. Parameters ---------- fn : filename arr : nd array axis : axis along which 2d chunks are written maxdim : highest number of dims that `arr` is allowed to have header : bool Write ini style header. Can be used by readtxt(). """ verbose("[writetxt] writing: %s" %fn) common.assert_cond(arr.ndim <= maxdim, 'no rank > %i arrays supported' %maxdim) fh = open(fn, 'w+') if header: c = PydosConfigParser() sec = 'array' c.add_section(sec) c.set(sec, 'shape', common.seq2str(arr.shape)) c.set(sec, 'axis', axis) _write_header_config(fh, c) # 1d and 2d case if arr.ndim < maxdim: np.savetxt(fh, arr) # 3d else: # TODO get rid of loop? # write 2d arrays, one by one sl = [slice(None)]*arr.ndim for ind in range(arr.shape[axis]): sl[axis] = ind np.savetxt(fh, arr[sl]) fh.close()