-1

I'm writing a script from C to python to generate a station data in binary format to be utilized in GrADS. Here the documentation about the structure: http://cola.gmu.edu/grads/gadoc/aboutstationdata.html#station

Python script's generating a binary file, but GrADS can read only the first station and the binary file generated from C is very different of the python output file. I'm thinking the problem is when a write de struct (ReportHeader) in file.

The C script:

  #include <stdio.h>

  /* Structure that describes a report header in a stn file */

  struct rpthdr { 
    char id[8];          /* Character station id           */
    float lat;            /* Latitude of report             */
    float lon;            /* Longitude of report            */
    float t;              /* Time in relative grid units    */
    int  nlev;            /* Number of levels following     */
    int flag;             /* Level independent var set flag */
  } hdr;

  main () {
  FILE *ifile, *ofile;
  char rec[80]; 
  int flag,year,month,yrsav,mnsav,i;
  float val1,val2,val3,val4,val5;

    /* Open files */

    ifile = fopen ("listabin1112.txt","r");
    ofile = fopen ("arquivo1112.dat","wb");
    if (ifile==NULL || ofile==NULL) {
      printf ("Error opening files\n");
      return 0 ;
    }

    /* Read,write loop */
      flag = 1;
    while (fgets(rec,79,ifile)!=NULL) {
    /* Format conversion */          
 sscanf (rec," %f %f %f %f %f %f %f",&hdr.lat,&hdr.lon,&val1,&val2,&val3,&val4,&val5);                    
    for (i=0; i<8; i++) {
      hdr.id[i] = rec[i+25]; 
    }
    printf("%f\n", hdr.lat);
/*Time group terminator if need */
 if (flag) {
   yrsav = year;
   mnsav = month;
   flag = 0;
 }
 if (yrsav!=year || mnsav!=month) {
          hdr.nlev = 0;    
        fwrite (&hdr,sizeof(struct rpthdr), 1, ofile);
 }
     yrsav = year;
     mnsav = month;

 /* Write this report */
      hdr.nlev = 1;
      hdr.flag = 1; 
      hdr.t = 0.0;
      fwrite (&hdr,sizeof(struct rpthdr), 1, ofile);
      fwrite (&val1,sizeof(float), 1, ofile);
      fwrite (&val2,sizeof(float), 1, ofile);
      fwrite (&val3,sizeof(float), 1, ofile);
      fwrite (&val4,sizeof(float), 1, ofile);
      fwrite (&val5,sizeof(float), 1, ofile);
    }
    hdr.nlev = 0;
    fwrite (&hdr,sizeof(struct rpthdr), 1, ofile);
  }

And my python script:

from ctypes import *
import struct 

class ReportHeader(Structure):
    _fields_ = [('id', c_char * 8),
            ('lat', c_float),
            ('lon', c_float),
            ('t', c_float),
            ('nlev', c_int),
            ('flag', c_int)]


if __name__ == '__main__':

    ifile = "listabin1112.txt"
    ofile = "teste.dat"
    of = open(ofile, "wb")

    hdr = ReportHeader()

    """ Read, write loop """
    ids = 10000000
    with open(ifile) as f:
    for line in f:
        lat, lon, val1, val2, val3, val4, val5, cidade = line.rstrip().split()
        hdr.lat = float(lat) - 0.000001
        hdr.lon = float(lon) - 0.000001
        hdr.id = str(ids)
        hdr.flag = 1
        hdr.nlev = 1
        hdr.t = 0.

        ids += 1

        print hdr.lat

        """ Escreve """
        of.write(hdr)
        of.write(struct.pack('f', float(val1)))
        of.write(struct.pack('f', float(val2)))
        of.write(struct.pack('f', float(val3)))
        of.write(struct.pack('f', float(val4)))
        of.write(struct.pack('f', float(val5)))

    hdr.nlev = 0
    of.write(hdr)
    of.close()
Tisp
  • 416
  • 2
  • 15

2 Answers2

1

Since there wasn't any sample input, I reduced the code to just creating the binary file with sample data:

C

#include <stdio.h>
#include <string.h>

struct rpthdr
{
    char id[8];          /* Character station id           */
    float lat;            /* Latitude of report             */
    float lon;            /* Longitude of report            */
    float t;              /* Time in relative grid units    */
    int  nlev;            /* Number of levels following     */
    int flag;             /* Level independent var set flag */
} hdr;

int main(void)
{
    FILE* ofile;
    float val1, val2, val3, val4, val5;

    /* Open files */
    ofile = fopen("arquivo1112.dat", "wb");

    /* Write this report */
    strcpy(hdr.id,"1234567");
    hdr.lat = 45.123f;
    hdr.lon = 110.456f;
    hdr.nlev = 1;
    hdr.flag = 2;
    hdr.t = 1.0f;
    val1 = 2.0f;
    val2 = 3.0f;
    val3 = 4.0f;
    val4 = 5.0f;
    val5 = 6.0f;
    fwrite(&hdr, sizeof(struct rpthdr), 1, ofile);
    fwrite(&val1, sizeof(float), 1, ofile);
    fwrite(&val2, sizeof(float), 1, ofile);
    fwrite(&val3, sizeof(float), 1, ofile);
    fwrite(&val4, sizeof(float), 1, ofile);
    fwrite(&val5, sizeof(float), 1, ofile);
}

Python

from ctypes import *
import struct 

class ReportHeader(Structure):
    _fields_ = [('id', c_char * 8),
                ('lat', c_float),
                ('lon', c_float),
                ('t', c_float),
                ('nlev', c_int),
                ('flag', c_int)]


ofile = "teste.dat"
with open(ofile, "wb") as of:
    hdr = ReportHeader()
    hdr.id = b'1234567'
    hdr.lat = 45.123
    hdr.lon = 110.456
    hdr.nlev = 1
    hdr.flag = 2
    hdr.t = 1.0
    val1 = 2.0
    val2 = 3.0
    val3 = 4.0
    val4 = 5.0
    val5 = 6.0
    of.write(hdr)
    of.write(struct.pack('5f',val1,val2,val3,val4,val5))

Result (both files 48 bytes)

C:\test1.exe
C:\test2.py
C:\>fc arquivo1112.dat teste.dat
Comparing files arquivo1112.dat and TESTE.DAT
FC: no differences encountered

So either you fixed the code when you edited it for floats, or the problem is the processing of the input data.

Mark Tolonen
  • 132,868
  • 21
  • 152
  • 208
0

The C code uses float and your python code uses d which is the format for double; you must use f to match the C format.

Antti Haapala
  • 117,318
  • 21
  • 243
  • 279
  • It doesn't work. I changed to d because was testing with double values. I'll edit the post – Tisp Aug 07 '17 at 14:18