/[ascend]/trunk/models/johnpye/datareader/acdb.c
ViewVC logotype

Diff of /trunk/models/johnpye/datareader/acdb.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1772 by jpye, Fri May 16 07:31:56 2008 UTC revision 1773 by jpye, Mon May 19 02:52:08 2008 UTC
# Line 103  typedef struct AcdbPoint_struct{ Line 103  typedef struct AcdbPoint_struct{
103  #define DATA(D) ((AcdbPoint *)(D->data))[D->i]  #define DATA(D) ((AcdbPoint *)(D->data))[D->i]
104    
105  struct AcdbCity{  struct AcdbCity{
106      char code[2];      char code[3];
107      char name[40];      char name[40];
108      char state[40];      char state[40];
109      char dir[9];      char dir[9];
# Line 204  int datareader_acdb_header(DataReader *d Line 204  int datareader_acdb_header(DataReader *d
204      const struct AcdbCity *i;      const struct AcdbCity *i;
205      unsigned found=0;      unsigned found=0;
206      for(i=acdb_city_info; i->code[0] != '\0'; ++i){      for(i=acdb_city_info; i->code[0] != '\0'; ++i){
207            CONSOLE_DEBUG("Comparing code with '%s'",i->code);
208          if(strcmp(i->code,code)==0){          if(strcmp(i->code,code)==0){
209              found=1;              found=1;
210              break;              break;
# Line 225  int datareader_acdb_header(DataReader *d Line 226  int datareader_acdb_header(DataReader *d
226      }else{      }else{
227          data_rows = 365 * 24;          data_rows = 365 * 24;
228      }      }
229      CONSOLE_DEBUG("ACDB data file is for year %ud, expect %ud data rows.",yr,data_rows);      CONSOLE_DEBUG("ACDB data file is for year %u, expect %u data rows.",yr,data_rows);
230        ERROR_REPORTER_HERE(ASC_PROG_NOTE,"ACDB data file is for year %u, expect %u data rows.",yr,data_rows);
231    
232      d->ndata = data_rows;      d->ndata = data_rows;
233      d->i = 0;      d->i = 0;
234      d->ndata=8760;      d->ndata=8760;
# Line 240  int datareader_acdb_header(DataReader *d Line 243  int datareader_acdb_header(DataReader *d
243  int datareader_acdb_eof(DataReader *d){  int datareader_acdb_eof(DataReader *d){
244      if(feof(d->f)){      if(feof(d->f)){
245          CONSOLE_DEBUG("REACHED END OF FILE");          CONSOLE_DEBUG("REACHED END OF FILE");
246            if(d->i < d->ndata){
247                ERROR_REPORTER_HERE(ASC_PROG_WARNING,"Incomplete data set found (%d rows < %d expected",d->i, d->ndata);
248            }
249          d->ndata=d->i;          d->ndata=d->i;
250          ERROR_REPORTER_HERE(ASC_PROG_NOTE,"Read %d rows",d->ndata);          ERROR_REPORTER_HERE(ASC_PROG_NOTE,"Read %d rows",d->ndata);
251          return 1;          return 1;
# Line 261  int datareader_acdb_eof(DataReader *d){ Line 267  int datareader_acdb_eof(DataReader *d){
267  int datareader_acdb_data(DataReader *d){  int datareader_acdb_data(DataReader *d){
268      /* static int lastmonth=-1;      /* static int lastmonth=-1;
269      static int lastday=-1; */      static int lastday=-1; */
     int res = 0;  
270    
271      AcdbPoint *dat;      AcdbPoint *dat;
     char code[3];  
     unsigned year,month,day,hour;  
   
     int dry_bulb_temp; /* [0.1°C] */  
     int w; /* absolute moisture content [0.1 g/kg] */  
     int p_atm; /* atmospheric pressure [0.1 kPa] */  
     int v_wind; /* wind speed [0.1 m/s] */  
     int dir_wind; /* dir of wind: 0-16; 0 = CALM.  1 = NNE ,...,16 = N */  
     int cloud; /* total cloud cover (oktas, 0 - 8) */  
   
     int dry_bulb_temp_flag;  
     int w_flag;  
     int p_atm_flag;  
     int wind_flag;  
     int cloud_flag;  
   
     int GHI;  
     int IHI;  
     int DNI;  
     int altitude_deg;  
     int azimuth_deg;  
   
     int solar_flag;  
272    
273  /* still need to implement...  /* still need to implement...
274    
# Line 295  int datareader_acdb_data(DataReader *d){ Line 277  int datareader_acdb_data(DataReader *d){
277    57 - 61 wet bulb temperature (10-1 °C)       }    57 - 61 wet bulb temperature (10-1 °C)       }
278    62 - 81 Station name (first line only)       }    62 - 81 Station name (first line only)       }
279    
280    
281    
282       1 - 2  location identification (e.g.ME represents Melbourne)
283       3 - 4  year (e.g. 67)
284       5 - 6  month (i.e. 1 - 12)
285       7 - 8  day (i.e. 1 - 31)
286       9 - 10 hour standard (i.e. 0-23, 0 = midnight)
287    
288      11 - 14 dry bulb temperature (10-1 °C)
289      15 - 17 absolute moisture content (10-1 g/kg)
290      18 - 21 atmospheric pressure (10-1 kPa)
291      22 - 24 wind speed (10-1 m/s)
292      25 - 26 wind direction (0-16; 0 = CALM.  1 = NNE ,...,16 = N
293      27      total cloud cover  (oktas, 0 - 8)
294      28      flag relating to dry bulb temperature
295      29      flag relating to absolute moisture content
296      30      flag relating to atmospheric pressure
297      31      flag relating to wind speed and direction
298      32      flag relating to total cloud cover
299      33      blank
300      34 - 37 global solar irradiance on a horizontal plane (W/m2)
301      38 - 40 diffuse solar irradiance on a horizontal plane (W/m2)
302      41 - 44 direct solar irradiance on a plane normal to the beam ((W/m2)
303      45 - 46 solar altitude (degrees, 0-90)
304      47 - 49 solar azimuth (degrees, 0-360)
305      50      flag relating to global and diffuse solar irradiance
306      51      flag                                 }
307      52 - 56 Australian Met Station Number        } Some locations only
308      57 - 61 wet bulb temperature (10-1 °C)       }
309      62 - 81 Station name (first line only)       }
310    
311  */  */
312    
313      code[2]='\0';  #define N_FIELDS 22
314        const unsigned fieldsize[N_FIELDS] = {
315            2,2,2,2, 4,3,4,3,2,1, 1,1,1,1,1, 1, 4,3,4,3,3,1
316        };
317        
318        int data[N_FIELDS];
319    
320      /* brace yourself for this one... */      enum {
321            ACDB_YEAR
322            ,ACDB_MONTH
323            ,ACDB_DAY
324            ,ACDB_HOUR
325            ,ACDB_DRY_BULB_TEMP/* [0.1°C] */
326            ,ACDB_W /* ABSOLUTE MOISTURE CONTENT [0.1 G/KG] */
327            ,ACDB_P_ATM /* ATMOSPHERIC PRESSURE [0.1 KPA] */
328            ,ACDB_V_WIND /* WIND SPEED [0.1 M/S] */
329            ,ACDB_DIR_WIND /* DIR OF WIND: 0-16; 0 = CALM.  1 = NNE ,...,16 = N */
330            ,ACDB_CLOUD /* TOTAL CLOUD COVER (OKTAS, 0 - 8) */
331            ,ACDB_DRY_BULB_TEMP_FLAG
332            ,ACDB_W_FLAG
333            ,ACDB_P_ATM_FLAG
334            ,ACDB_WIND_FLAG
335            ,ACDB_CLOUD_FLAG
336            ,ACDB_WHITESPACE1
337            ,ACDB_GHI
338            ,ACDB_IHI /* indirect (diffuse) horizontal radiation */
339            ,ACDB_DNI
340            ,ACDB_ALTITUDE_DEG
341            ,ACDB_AZIMUTH_DEG
342            ,ACDB_SOLAR_FLAG
343        };
344    
345      res = fscanf(d->f,      char field[10];
346          /* 1 */ "%2s%2d%2d%2d%2d" "%3d%3d%4d%3d%2d" "%1d" /*  =11 */      char code[3];
347          /* 2 */ "%1d%1d%1d%1d%1d" /* +5=16 */      
348          /* 3 */ "%*1c" /* (ignore one space) */      unsigned i;
349          /* 4 */ "%4d%3d%4d%2d%3d%1d" /* +6=21 */      assert(N_FIELDS == sizeof(fieldsize) / sizeof(unsigned));
         /* 5 */ /* other optional stuff here... how to do that? */  
   
         " " /* to ensure that we move to the start of the next line, else end of file */  
   
         /* 1 */,code, &year, &month, &day, &hour, &dry_bulb_temp, &w, &p_atm, &v_wind, &dir_wind, &cloud  
         /* 2 */,&dry_bulb_temp_flag, &w_flag, &p_atm_flag, &wind_flag, &cloud_flag  
         /* 3 */  
         /* 4 */,&GHI,&IHI,&DNI,&altitude_deg,&azimuth_deg,&solar_flag  
         /* 5 */  
     );  
350    
351      if(res!=79){      fgets(code, 3, d->f);
352          CONSOLE_DEBUG("Bad input data in data row %d (read %d items OK) (%d/%d/%d %2d:00",d->i,res,day,month,year,hour);      //CONSOLE_DEBUG("code = '%s'",code);
353          return 1;      //assert(strcmp(code,"CA")==0);
354    
355        /*
356            this format includes spaces in the data file, so we can't use fscanf
357            because of the way it soaks up leading spaces without counting them
358            in the field width.
359        */
360        for(i=0; i < N_FIELDS; ++i){
361            fgets(field, fieldsize[i] + 1, d->f);
362            //CONSOLE_DEBUG("field %d: size = %d, str = '%s'", i, fieldsize[i], field);
363            if(i==ACDB_WHITESPACE1)continue;
364    
365            assert(field!=NULL);
366            assert(strlen(field)!=0);
367    
368            data[i] = atoi(field);
369      }      }
370    
371        fscanf(d->f," ");
372    
373        CONSOLE_DEBUG("Time: %d/%d/%d %2d:00",data[ACDB_DAY],data[ACDB_MONTH],data[ACDB_YEAR],data[ACDB_HOUR]);
374        CONSOLE_DEBUG("code = %s, dry_bulb_temp = %f, w = %f, p_atm = %f, v_wind = %f, dir_wind = %d"
375            ,code, data[ACDB_DRY_BULB_TEMP]/10., data[ACDB_W]/10., data[ACDB_P_ATM]/10., data[ACDB_V_WIND]/10., data[ACDB_DIR_WIND]
376        );
377        assert(strcmp(code,"CA")==0);
378        assert(data[ACDB_DRY_BULB_TEMP]/10. <= 70.);
379        assert(data[ACDB_DIR_WIND] >= 0 && data[ACDB_DIR_WIND] <= 16);
380    
381      /*      /*
382      if(month!=lastmonth || day!=lastday){      if(month!=lastmonth || day!=lastday){
383          CONSOLE_DEBUG("Reading data for %d/%d",day,month);          CONSOLE_DEBUG("Reading data for %d/%d",day,month);
# Line 336  int datareader_acdb_data(DataReader *d){ Line 392  int datareader_acdb_data(DataReader *d){
392      */      */
393    
394      dat = &DATA(d);      dat = &DATA(d);
395      dat->t = ((day_of_year_specific(day,month,year) - 1)*24.0 + hour)*3600.0;      dat->t = ((day_of_year_specific(data[ACDB_DAY],data[ACDB_MONTH],data[ACDB_YEAR]) - 1)*24.0 + data[ACDB_HOUR])*3600.0;
396      dat->I = GHI * 0.1; /* average W/m2 for the hour in question */      dat->I = data[ACDB_GHI] * 0.1; /* average W/m2 for the hour in question */
397      dat->Ibn = DNI * 0.1; /* normal beam radiation, W/m2 */      dat->Ibn = data[ACDB_DNI] * 0.1; /* normal beam radiation, W/m2 */
398      dat->Id = IHI * 0.1;      dat->Id = data[ACDB_IHI] * 0.1;
399      dat->T = 0.1*dry_bulb_temp + 273.15; /* temperature */      dat->T = 0.1*data[ACDB_DRY_BULB_TEMP] + 273.15; /* temperature */
400      dat->v_wind = v_wind * 0.1;      dat->v_wind = data[ACDB_V_WIND] * 0.1;
401    
402  #if 0  #if 0
403      if(d->i < 20){      if(d->i < 20){

Legend:
Removed from v.1772  
changed lines
  Added in v.1773

john.pye@anu.edu.au
ViewVC Help
Powered by ViewVC 1.1.22