def _get_fileinfo(self): """ Reads some basic general information from the burp file without having to fully open the file. Returns ------- nrep number of reports in the file rep_max length of longest report in the file """ assert 'r' in self.mode, "BurpFile must be in read mode to use this function." ier = _brp.mrfopt(_rbc.BURPOP_MSGLVL, _rbc.BURPOP_MSG_FATAL) unit = _rb.fnom(self.fname, _rc.FST_RO) nrep = _brp.mrfnbr(unit) rep_max = _brp.mrfmxl(unit) ier = _rb.fclos(unit) return nrep, rep_max
def _get_fileinfo(self): """ Reads some basic general information from the burp file without having to fully open the file. Returns: (nrep, rep_max), tuple where: nrep : number of reports in the file rep_max : length of longest report in the file """ assert 'r' in self.mode, "BurpFile must be in read mode to use this function." ier = _brp.mrfopt(_rbc.BURPOP_MSGLVL, _rbc.BURPOP_MSG_FATAL) unit = _rb.fnom(self.fname, _rc.FST_RO) nrep = _brp.mrfnbr(unit) rep_max = _brp.mrfmxl(unit) ier = _rb.fclos(unit) return nrep, rep_max
def write_burpfile(self): """ Writes BurpFile instance to a BURP file. """ assert 'w' in self.mode, "BurpFile must be in write mode to use this function." print "Writing BURP file to \'%s\'" % self.fname handle = 0 nsup = 0 nxaux = 0 warn = True # convert lat, lon back into integers ilon = _np.round(100*self.lon).astype(int) ilat = _np.round(100*self.lat+9000).astype(int) ilon[ilon<0] = ilon[ilon<0]+36000 idate = self.year*10000 + self.month*100 + self.day itime = self.hour*100 + self.minute # buffer for report data nbuf = self._calc_nbuf() buf = _np.empty((nbuf, ), dtype=_np.int32) buf[0] = nbuf # open BURP file _brp.mrfopt(_rbc.BURPOP_MSGLVL, _rbc.BURPOP_MSG_FATAL) unit = _brp.burp_open(self.fname, _rbc.BURP_MODE_CREATE) # loop over reports for irep in xrange(self.nrep): # write report header _brp.mrbini(unit, buf, itime[irep], self.flgs[irep], self.stnids[irep], self.codtyp[irep], ilat[irep], ilon[irep], self.dx[irep], self.dy[irep], self.alt[irep], self.delay[irep], idate[irep], self.rs[irep], self.runn[irep], self.sup[irep], nsup, self.xaux[irep], nxaux) for iblk in xrange(self.nblk[irep]): nele = self.nelements[irep][iblk] nlev = self.nlev[irep][iblk] nt = self.nt[irep][iblk] # convert BUFR codes to CMC codes lstele = _np.empty((nele, ), dtype=_np.int32) _brp.mrbcol(self.elements[irep][iblk], lstele, nele) # convert real values to integer table values rval = _np.ravel(self.rval[irep][iblk], order='F') tblval = _np.round(rval).astype(_np.int32) if self.datyp[irep][iblk] < 5: _brp.mrbcvt(lstele, tblval, rval, nele, nlev, nt, _rbc.MRBCVT_ENCODE) tbl_out = tblval elif self.datyp[irep][iblk] < 7: tbl_out = rval else: if warn: _warnings.warn("Unrecognized data type value of %i. Unconverted table values will be written." % self.datyp[irep][iblk]) warn = False tbl_out = tblval # add block to report _brp.mrbadd(buf, _ct.pointer(_ct.c_int(iblk+1)), nele, nlev, nt, self.bfam[irep][iblk], self.bdesc[irep][iblk], self.btyp[irep][iblk], self.nbit[irep][iblk], _ct.pointer(_ct.c_int(self.bit0[irep][iblk])), self.datyp[irep][iblk], lstele, tbl_out) # write report _brp.mrfput(unit, handle, buf) # close BURP file _brp.mrfcls(unit) _rb.fclos(unit) return
def _read_data(self, nbuf): """ Reads all the the BURP file data and puts the file data in the rep_attr, blk_attr, and ele_attr arrays. Parameters ---------- nbuf buffer length for reading of BURP file """ assert 'r' in self.mode, "BurpFile must be in read mode to use this function." warn = True # open BURP file _brp.mrfopt(_rbc.BURPOP_MSGLVL, _rbc.BURPOP_MSG_FATAL) unit = _brp.burp_open(self.fname) nrep = _brp.mrfnbr(unit) self.nblk = _np.empty((self.nrep, ), dtype=_np.int) self.year = _np.empty((self.nrep, ), dtype=_np.int) self.month = _np.empty((self.nrep, ), dtype=_np.int) self.day = _np.empty((self.nrep, ), dtype=_np.int) self.hour = _np.empty((self.nrep, ), dtype=_np.int) self.minute = _np.empty((self.nrep, ), dtype=_np.int) self.codtyp = _np.empty((self.nrep, ), dtype=_np.int) self.flgs = _np.empty((self.nrep, ), dtype=_np.int) self.dx = _np.empty((self.nrep, ), dtype=_np.int) self.dy = _np.empty((self.nrep, ), dtype=_np.int) self.alt = _np.empty((self.nrep, ), dtype=_np.int) self.delay = _np.empty((self.nrep, ), dtype=_np.int) self.rs = _np.empty((self.nrep, ), dtype=_np.int) self.runn = _np.empty((self.nrep, ), dtype=_np.int) self.sup = _np.empty((self.nrep, ), dtype=_np.int) self.xaux = _np.empty((self.nrep, ), dtype=_np.int) self.lon = _np.empty((self.nrep, ), dtype=_np.float) self.lat = _np.empty((self.nrep, ), dtype=_np.float) self.stnids = _np.empty((self.nrep, ), dtype='|S9') for attr in BurpFile.blk_attr: setattr(self, attr, _np.empty((self.nrep, ), dtype=object)) # block data self.elements = _np.empty((self.nrep, ), dtype=object) self.rval = _np.empty((self.nrep, ), dtype=object) # loop over reports handle = 0 buf = nbuf for irep in xrange(nrep): # get next report and load data into buffer handle = _brp.mrfloc(unit, handle) buf = _brp.mrfget(handle, buf) # get report header rhp = _brp.mrbhdr(buf) self.flgs[irep] = rhp['flgs'] self.codtyp[irep] = rhp['idtyp'] self.dx[irep] = rhp['dx'] self.dy[irep] = rhp['dy'] self.alt[irep] = rhp['elev'] self.delay[irep] = rhp['drnd'] self.rs[irep] = rhp['oars'] self.runn[irep] = rhp['runn'] self.nblk[irep] = rhp['nblk'] self.sup[irep] = 0 self.xaux[irep] = 0 self.year[irep] = rhp['date']/10000 self.month[irep] = (rhp['date']%10000)/100 self.day[irep] = rhp['date']%100 self.hour[irep] = rhp['time']/100 self.minute[irep] = rhp['time']%100 self.lon[irep] = rhp['lon']/100. self.lat[irep] = (rhp['lat']-9000.)/100. self.stnids[irep] = rhp['stnid'] for attr in BurpFile.blk_attr: getattr(self, attr)[irep] = _np.empty((rhp['nblk'], ), dtype=int) self.elements[irep] = _np.empty((rhp['nblk'], ), dtype=object) self.rval[irep] = _np.empty((rhp['nblk'], ), dtype=object) # loop over blocks for iblk in xrange(rhp['nblk']): # get block header bhp = _brp.mrbprm(buf, iblk+1) self.nelements[irep][iblk] = bhp['nele'] self.nlev[irep][iblk] = bhp['nval'] self.nt[irep][iblk] = bhp['nt'] self.bfam[irep][iblk] = bhp['bfam'] self.bdesc[irep][iblk] = bhp['bdesc'] self.btyp[irep][iblk] = bhp['btyp'] self.nbit[irep][iblk] = bhp['nbit'] self.bit0[irep][iblk] = bhp['bit0'] self.datyp[irep][iblk] = bhp['datyp'] # get block elements and values and # convert integer table values to real value if bhp['datyp'] < 5: bdata = _brp.mrbxtr(buf, iblk+1) rval = _brp.mrbcvt_decode(bdata) elif bhp['datyp'] < 7: bdata = _brp.mrbxtr(buf, iblk+1, dtype=_np.float32) rval = bdata['tblval'] else: bdata = _brp.mrbxtr(buf, iblk+1) rval = bdata['tblval'].astype(_np.float32) if warn: _warnings.warn("Unrecognized data type value of %i. Unconverted table values will be returned." % bhp['datyp']) warn = False # convert CMC codes to BUFR codes self.elements[irep][iblk] = _brp.mrbdcl(bdata['lstele']) #TODO: since arrays are now allocated Fortran style, # should we do a transpose? ## self.rval[irep][iblk] = _np.resize(rval, (bhp['nval'], bhp['nele'])).T rval.resize((bhp['nval'], bhp['nele'])) self.rval[irep][iblk] = rval # close BURP file _brp.burp_close(unit) # change longitude to be between -180 and 180 degrees self.lon = self.lon % 360. self.lon[self.lon>180] = self.lon[self.lon>180] - 360. return
def write_burpfile(self): """ Writes BurpFile instance to a BURP file. Returns: None Raises: BurpError """ assert 'w' in self.mode, "BurpFile must be in write mode to use this function." print("Writing BURP file to \'{}\'".format(self.fname)) handle = 0 nsup = 0 nxaux = 0 warn = True # convert lat, lon back into integers ilon = _np.round(100 * self.lon).astype(int) ilat = _np.round(100 * self.lat + 9000).astype(int) ilon[ilon < 0] = ilon[ilon < 0] + 36000 idate = self.year * 10000 + self.month * 100 + self.day itime = self.hour * 100 + self.minute # buffer for report data nbuf = self._calc_nbuf() buf = _np.empty((nbuf, ), dtype=_np.int32) buf[0] = nbuf # open BURP file _brp.mrfopt(_rbc.BURPOP_MSGLVL, _rbc.BURPOP_MSG_FATAL) unit = _brp.burp_open(self.fname, _rbc.BURP_MODE_CREATE) # loop over reports for irep in range(self.nrep): # write report header _brp.mrbini(unit, buf, itime[irep], self.flgs[irep], self.stnids[irep], self.codtyp[irep], ilat[irep], ilon[irep], self.dx[irep], self.dy[irep], self.alt[irep], self.delay[irep], idate[irep], self.rs[irep], self.runn[irep], self.sup[irep], nsup, self.xaux[irep], nxaux) for iblk in range(self.nblk[irep]): nele = self.nelements[irep][iblk] nlev = self.nlev[irep][iblk] nt = self.nt[irep][iblk] # convert BUFR codes to CMC codes cmcids = _brp.mrbcol(self.elements[irep][iblk]) # convert real values to integer table values if self.datyp[irep][iblk] < 5: tblval = _brp.mrbcvt_encode(cmcids, self.rval[irep][iblk]) tblval = _np.ravel(tblval, order='F') else: rval = _np.ravel(self.rval[irep][iblk], order='F') tblval = _np.round(rval).astype(_np.int32) if self.datyp[irep][iblk] > 6 and warn: _warnings.warn( "Unrecognized data type value of %i. Unconverted table values will be written." % self.datyp[irep][iblk]) warn = False # add block to report _brp.mrbadd(buf, _ct.pointer(_ct.c_int(iblk + 1)), nele, nlev, nt, self.bfam[irep][iblk], self.bdesc[irep][iblk], self.btyp[irep][iblk], self.nbit[irep][iblk], _ct.pointer(_ct.c_int(self.bit0[irep][iblk])), self.datyp[irep][iblk], cmcids, tblval) # write report _brp.mrfput(unit, handle, buf) # close BURP file _brp.mrfcls(unit) _rb.fclos(unit) return
def _read_data(self, nbuf): """ Reads all the the BURP file data and puts the file data in the rep_attr, blk_attr, and ele_attr arrays. Args: nbuf : buffer length for reading of BURP file Returns: None Raises: BurpError """ assert 'r' in self.mode, "BurpFile must be in read mode to use this function." warn = True # open BURP file _brp.mrfopt(_rbc.BURPOP_MSGLVL, _rbc.BURPOP_MSG_FATAL) unit = _brp.burp_open(self.fname) nrep = _brp.mrfnbr(unit) self.nblk = _np.empty((self.nrep, ), dtype=_np.int) self.year = _np.empty((self.nrep, ), dtype=_np.int) self.month = _np.empty((self.nrep, ), dtype=_np.int) self.day = _np.empty((self.nrep, ), dtype=_np.int) self.hour = _np.empty((self.nrep, ), dtype=_np.int) self.minute = _np.empty((self.nrep, ), dtype=_np.int) self.codtyp = _np.empty((self.nrep, ), dtype=_np.int) self.flgs = _np.empty((self.nrep, ), dtype=_np.int) self.dx = _np.empty((self.nrep, ), dtype=_np.int) self.dy = _np.empty((self.nrep, ), dtype=_np.int) self.alt = _np.empty((self.nrep, ), dtype=_np.int) self.delay = _np.empty((self.nrep, ), dtype=_np.int) self.rs = _np.empty((self.nrep, ), dtype=_np.int) self.runn = _np.empty((self.nrep, ), dtype=_np.int) self.sup = _np.empty((self.nrep, ), dtype=_np.int) self.xaux = _np.empty((self.nrep, ), dtype=_np.int) self.lon = _np.empty((self.nrep, ), dtype=_np.float) self.lat = _np.empty((self.nrep, ), dtype=_np.float) self.stnids = _np.empty((self.nrep, ), dtype='|S9') for attr in BurpFile.blk_attr + BurpFile.ele_attr: setattr(self, attr, _np.empty((self.nrep, ), dtype=object)) # loop over reports handle = 0 buf = nbuf for irep in range(nrep): # get next report and load data into buffer handle = _brp.mrfloc(unit, handle) buf = _brp.mrfget(handle, buf) # get report header rhp = _brp.mrbhdr(buf) self.flgs[irep] = rhp['flgs'] self.codtyp[irep] = rhp['idtyp'] self.dx[irep] = rhp['idx'] self.dy[irep] = rhp['idy'] self.alt[irep] = rhp['ielev'] self.delay[irep] = rhp['drnd'] self.rs[irep] = rhp['oars'] self.runn[irep] = rhp['runn'] self.nblk[irep] = rhp['nblk'] self.sup[irep] = 0 self.xaux[irep] = 0 self.year[irep] = rhp['date'] / 10000 self.month[irep] = (rhp['date'] % 10000) / 100 self.day[irep] = rhp['date'] % 100 self.hour[irep] = rhp['time'] / 100 self.minute[irep] = rhp['time'] % 100 self.lon[irep] = rhp['ilon'] / 100. self.lat[irep] = (rhp['ilat'] - 9000.) / 100. self.stnids[irep] = rhp['stnid'] for attr in BurpFile.blk_attr: getattr(self, attr)[irep] = _np.empty((rhp['nblk'], ), dtype=int) for attr in BurpFile.ele_attr: getattr(self, attr)[irep] = _np.empty((rhp['nblk'], ), dtype=object) # loop over blocks for iblk in range(rhp['nblk']): # get block header bhp = _brp.mrbprm(buf, iblk + 1) self.nelements[irep][iblk] = bhp['nele'] self.nlev[irep][iblk] = bhp['nval'] self.nt[irep][iblk] = bhp['nt'] self.bfam[irep][iblk] = bhp['bfam'] self.bdesc[irep][iblk] = bhp['bdesc'] self.btyp[irep][iblk] = bhp['btyp'] self.nbit[irep][iblk] = bhp['nbit'] self.bit0[irep][iblk] = bhp['bit0'] self.datyp[irep][iblk] = bhp['datyp'] # get block elements and values and # convert integer table values to real value if bhp['datyp'] < 5: bdata = _brp.mrbxtr(buf, iblk + 1) rval = _brp.mrbcvt_decode(bdata) elif bhp['datyp'] < 7: bdata = _brp.mrbxtr(buf, iblk + 1, dtype=_np.float32) rval = bdata['tblval'] else: bdata = _brp.mrbxtr(buf, iblk + 1) rval = bdata['tblval'].astype(_np.float32) if warn: _warnings.warn( "Unrecognized data type value of %i. Unconverted table values will be returned." % bhp['datyp']) warn = False # convert CMC codes to BUFR codes self.elements[irep][iblk] = _brp.mrbdcl(bdata['cmcids']) #TODO: since arrays are now allocated Fortran style, # should we do a transpose? self.rval[irep][iblk] = rval # check that the element arrays have the correct dimensions if _np.any(self.elements[irep][iblk].shape != ( self.nelements[irep][iblk])): raise _brp.BurpError( "elements array does not have the correct dimensions.") if _np.any(self.rval[irep][iblk].shape != ( self.nelements[irep][iblk], self.nlev[irep][iblk], self.nt[irep][iblk])): raise _brp.BurpError( "rval array does not have the correct dimensions.") # close BURP file _brp.burp_close(unit) # change longitude to be between -180 and 180 degrees self.lon = self.lon % 360. self.lon[self.lon > 180] = self.lon[self.lon > 180] - 360. return