Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Andrzejek on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

calculate average

Status
Not open for further replies.

KyrieXuX

Technical User
Jul 21, 2011
3
DE
Hello eyeryone,

i've tried to calculate an average of hourly meteorological values to a daily value.

here is an example of the ascii file:

pres2 wdsp
12100 2000010106 0.5 -0.3 -9.0 -9.0 2 -9.0 1.5 0.0 1.0
12100 2000010107 0.2 -0.6 -9.0 -9.0 4 -9.0 -99.0 -99.0 -5.0
12100 2000010108 0.2 -0.6 -9.0 1023.3 3 -9.0 -99.0 -99.0 -5.0
12100 2000010109 0.2 -0.6 -9.0 -9.0 3 -9.0 -99.0 -99.0 -5.0
12100 2000010110 0.6 -0.2 -9.0 -9.0 3 -9.0 -99.0 -99.0 -5.0
12100 2000010111 0.9 -0.1 1021.9 -9.0 3 -9.0 -99.0 -99.0 -5.0
12100 2000010112 1.1 0.1 -9.0 -9.0 4 -9.0 -99.0 -99.0 -5.0
12100 2000010113 1.2 0.0 -9.0 1023.3 4 -9.0 -99.0 -99.0 -5.0
12100 2000010114 1.2 0.0 -9.0 -9.0 2 -9.0 -99.0 -99.0 -5.0
12100 2000010115 1.0 0.3 -9.0 -9.0 3 -9.0 -99.0 -99.0 -5.0
12100 2000010116 0.8 0.0 -9.0 -9.0 3 -9.0 -99.0 -99.0 -5.0
12100 2000010117 0.6 0.1 -9.0 1019.8 3 -9.0 -99.0 -99.0 -5.0
12100 2000010118 0.5 -0.3 -9.0 -9.0 3 -9.0 1.4 -0.1 -5.0
12100 2000010206 2.4 2.2 1023.3 1022.6 2 -9.0 2.5 0.0 2.5
12100 2000010207 3.2 3.0 1023.8 1023.1 2 -9.0 -99.0 -99.0 -5.0
12100 2000010208 3.4 2.9 -9.0 -9.0 4 -9.0 -99.0 -99.0 -5.0
12100 2000010209 3.6 2.9 1024.5 1023.8 2 -9.0 -99.0 -99.0 -5.0
12100 2000010210 3.5 3.0 1024.0 1023.3 4 -9.0 -99.0 -99.0 -5.0

I want the daily value of the 6th and 7th column. So I write a fortran program. Here's an extract:

days=0
valu=pres2(0)
5 CONTINUE
DO j=1,length
IF (pres2(j) <= 0) THEN
GOTO 5
IF (day(j) == day(j-1) .AND. j /= length) THEN
counter=counter+1
valu=valu+pres2(j)
ELSEIF (day(j) /= day(j-1) .OR. j == length) THEN
days=days+1
tgl(days)=valu/REAL(counter)
y(days)=year(j-1)
m(days)=month(j-1)
d(days)=day(j-1)
counter=1
valu=pres2(j)

ENDIF
ENDIF
ENDDO

days=0
valu=wdsp(0)
DO j=1,length
IF (day(j) == day(j-1) .AND. j /= length) THEN
counter=counter+1
valu=valu+wdsp(j)
ELSEIF (day(j) /= day(j-1) .OR. j == length) THEN
days=days+1
tgl(days)=wert/REAL(counter)
y(days)=jahr(j-1)
m(days)=monat1(j-1)
d(days)=tag1(j-1)
counter=1
wert=wdsp1(j)
ENDIF
ENDDO



When I run the program i get this outfile:

00000 NaN 0.00 0.00
20000101 12100. 3.08 228.85
20000102 12100. 2.50 764.75

The 7th column is calculate correctly but the 6th isn't. It's because of the -9.0 values (-9.0 values mean there are no values for this hour so the program should skip this value)

How can I solve this problem correctly?

Thank you in advance
 
Well, you know IF statement so what's a problem to add "if abs(value-9) >= eps tnen don't add value to sum" condition in the code?

What happens with day(j-1) when j == 1 in your loops?
 
Hello ArkM,

thanks for your answer. I've tried to do but it didn't work. I am a Fortran Newbe. Maybe I upload the Program and the Ascii File.

Code:
        PROGRAM taeglich
       
       IMPLICIT NONE
!***********************************************************************
!****************       Variablendeklaration       *********************
!***********************************************************************
       INTEGER                              :: i, eps=-9
       INTEGER, PARAMETER                   :: Anz=1000
       INTEGER                              :: year, month, day, hour
       INTEGER                              :: bed,rich,wdsp
       INTEGER                              :: statNr
       REAL                                 :: temp,tau,druck1,druck2,tmin,tmax,rr24,rr6,sndur,tm,rboe,rboeh
       
       
       INTEGER                                          :: j, length, counter, days, valu
       INTEGER, PARAMETER                               :: z=1000
       INTEGER, ALLOCATABLE, DIMENSION (:)              :: year1, month1, day1, hour1
       INTEGER, ALLOCATABLE, DIMENSION (:)              :: statNr1  ! WMO Nummer
       INTEGER, ALLOCATABLE, DIMENSION (:)              :: wdsp1    ! Windspeed
       REAL, ALLOCATABLE, DIMENSION (:)                 :: temp1    ! Temperature
       REAL, ALLOCATABLE, DIMENSION (:)                 :: tau1     ! Dew Point
       REAL, ALLOCATABLE, DIMENSION (:)                 :: druck11  ! Pressure11
       REAL, ALLOCATABLE, DIMENSION (:)                 :: druck21  ! Pressure21
       REAL, ALLOCATABLE, DIMENSION (:)                 :: tmin1    ! Minimum Temperatur
       REAL, ALLOCATABLE, DIMENSION (:)                 :: tmax1    ! Maximum Temperatur
       REAL, ALLOCATABLE, DIMENSION (:)                 :: rr241    ! Pricipitation
       REAL, ALLOCATABLE, DIMENSION (:)                 :: rboe1    ! Gust
       REAL, ALLOCATABLE, DIMENSION (:)                 :: daily
       INTEGER, ALLOCATABLE, DIMENSION (:)              :: y, m, d
       
   
! ----> Outputfile


       OPEN(20,FILE='poland_red.txt')
       
! ----> Opening Landfile

       OPEN(10,FILE='poland_copy.txt')
       
! ----> Read and Write File

       DO i=1,Anz
         READ(10,'(I4,I2,I2,I2,2X,I5,2X,I2,2X,I2,1X,I3,2X,F5.1,2X, '//&
                  'F5.1,1X,F7.1,1X,F7.1,2X,F5.1,2X,F5.1,3X,F4.1,3X, '//&
                  'F4.1,3X,F4.1,2X,F5.1,2X,F4.1,2X,F4.1)',END=1) year,month,&
                  day,hour,statNr,bed,rich,wdsp,temp,tau,druck1,druck2,&
                  tmin,tmax,rr24,rr6,sndur,tm,rboe,rboeh
         WRITE(20,'(I5,2X,I4,I2.2,I2.2,I2.2,2X,F5.1,2X,F5.1,2X,F7.1, '//&
                  '2X,F7.1,2X,I3,2X,F4.1,2X,F5.1,2X,F5.1,2X,F4.1)') statNr,&
                  year,month,day,hour,temp,tau,druck1,druck2,wdsp,rboe,&
                  tmax,tmin,rr24
       
       ENDDO
       
1      CONTINUE

       PRINT*, '----->  Umwandlung fertig <-----' 
      
       CLOSE(10)
       CLOSE(20)
	   
	   
!-----> Speicher fuer die Variablen der eingelesenen Dateien reservieren

       ALLOCATE (year1(z))
       ALLOCATE (month1(z))
       ALLOCATE (day1(z))
       ALLOCATE (hour1(z))
       ALLOCATE (statNr1(z))
       ALLOCATE (wdsp1(z))
       ALLOCATE (temp1(z))
       ALLOCATE (tau1(z))
       ALLOCATE (druck11(z))
       ALLOCATE (druck21(z))
       ALLOCATE (tmin1(z))
       ALLOCATE (tmax1(z))
       ALLOCATE (rr241(z))
       ALLOCATE (rboe1(z))      
       
       OPEN(30,FILE='poland_red.txt',STATUS='OLD')
         DO j=1,z
           READ(30,'(I5,2X,I4,I2.2,I2.2,I2.2,2X,F5.1,2X,F5.1,2X,F7.1, '//&
                   '2X,F7.1,2X,I3,2X,F4.1,2X,F5.1,2X,F5.1,2X,F4.1)',END=2) statNr1(j),&
                    year1(j),month1(j),day1(j),hour1(j),temp1(j),tau1(j),&
                    druck11(j),druck21(j),wdsp1(j),rboe1(j),tmax1(j),tmin1(j),rr241(j)
           length=j
         ENDDO

2        CONTINUE

         CLOSE(30)
         
!-----> Speicher fuer die Output-Datein reservieren

        ALLOCATE (daily(CEILING(length/3.)))
        ALLOCATE (y(CEILING(length/3.)))
        ALLOCATE (m(CEILING(length/3.)))
        ALLOCATE (d(CEILING(length/3.)))
        
!-----> Mittelwerte werden berechnet

       

       days=0
       valu=wdsp1(0)
       DO j=1,length
         IF (day1(j) == day1(j-1) .AND. j /= length .AND. abs(valu-9) > eps) THEN
           counter=counter+1
           valu=valu+wdsp1(j)
         ELSEIF (day1(j) /= day1(j-1) .OR. j == length) THEN
             days=days+1
               daily(days)=valu/REAL(counter)
               y(days)=year1(j-1)
               m(days)=month1(j-1)
               d(days)=day1(j-1)
           counter=1
           valu=wdsp1(j)
         ENDIF
       ENDDO
	   

       
!-----> Speicher wieder freimachen


       DEALLOCATE (year1)
       DEALLOCATE (month1)
       DEALLOCATE (day1)
       DEALLOCATE (hour1)
       DEALLOCATE (statNr1)
       DEALLOCATE (wdsp1)
       DEALLOCATE (temp1)
       DEALLOCATE (tau1)
       DEALLOCATE (druck11)
       DEALLOCATE (druck21)
       DEALLOCATE (tmin1)
       DEALLOCATE (tmax1)
       DEALLOCATE (rr241)
       DEALLOCATE (rboe1)


       OPEN(40,FILE='poland_test.txt')
       DO j=1,days
         WRITE(40,'(I4,I2.2,I2.2,6X,F6.2)') y(j),m(j),d(j),daily(j)
       ENDDO
       CLOSE(40)
       

       DEALLOCATE (daily)
       DEALLOCATE (y)
       DEALLOCATE (m)
       DEALLOCATE (d)

       
       END PROGRAM taeglich


 
 http://www.mediafire.com/file/2ndkdm2bl2acejc/poland_copy.txt
Wait a bit, sorry. Do you want to calculate an average of all wdsp1 elements except -9?

If so
1. Why wdsp1 is an INTEGER array? I see that correspondent column contains REAL values.
2. wdsp1 indicies range is 1 to z. No such element as vdsp1(0).
3. I can't understand what DO j=1,length loop calculates...

Some correction to my previous post. If you want to test reals x and y on "is equal", use a SMALL real number (called eps in my post - 1D-6 or 1E-6, for example) and use an abs difference x-y:
Code:
IF (abs(x-y) < eps) THEN ! yes, x == y (almost equal to;)
...
! or
IF (abs(x-y) > eps) THEN ! no, x != y (I'm sure;)
...

Don't add wdsp1 values -9 to sum, skip them - that's all. Calculate sum of k values then divide sum/k to get an average...
 
Hello ArkM,

it is not so easy you just described.

First of all: The first column in poland_copy.txt is the "date" in format YYYYMMDDHH. So there exists hourly measurments. I want calculate a DAILY average, not just an average of all wdsp1. Thats why i need the loop j=1,length. (It should check when a new day start so that the counter can be set to counter=1 again)

In the inputfile (poland_copy.txt) wdsp1 (column 5) is an integer. When i do calculate the DAILY average the output has to be real.

I hope it is now clear what i want to do

Cheers

 
Hallo KyrieXuX,

Your data file seems to be sorted according to date field (2.column).
If it's true, then you can use the technique called Control Break Processing.
/In german - I see some german words in your source :) - it's known as Normierte Programmierung or Gruppenwechsel/

Example::
For the given data file, sorted according to date in format YYYYMMDDhh (2.column)
control_break.dat
Code:
12100  2000010106    0.5   -0.3     -9.0     -9.0    2  -9.0    1.5    0.0   1.0
12100  2000010107    0.2   -0.6     -9.0     -9.0    4  -9.0  -99.0  -99.0  -5.0
12100  2000010108    0.2   -0.6     -9.0   1023.3    3  -9.0  -99.0  -99.0  -5.0
12100  2000010109    0.2   -0.6     -9.0     -9.0    3  -9.0  -99.0  -99.0  -5.0
12100  2000010110    0.6   -0.2     -9.0     -9.0    3  -9.0  -99.0  -99.0  -5.0
12100  2000010111    0.9   -0.1   1021.9     -9.0    3  -9.0  -99.0  -99.0  -5.0
12100  2000010112    1.1    0.1     -9.0     -9.0    4  -9.0  -99.0  -99.0  -5.0
12100  2000010113    1.2    0.0     -9.0   1023.3    4  -9.0  -99.0  -99.0  -5.0
12100  2000010114    1.2    0.0     -9.0     -9.0    2  -9.0  -99.0  -99.0  -5.0
12100  2000010115    1.0    0.3     -9.0     -9.0    3  -9.0  -99.0  -99.0  -5.0
12100  2000010116    0.8    0.0     -9.0     -9.0    3  -9.0  -99.0  -99.0  -5.0
12100  2000010117    0.6    0.1     -9.0   1019.8    3  -9.0  -99.0  -99.0  -5.0
12100  2000010118    0.5   -0.3     -9.0     -9.0    3  -9.0    1.4   -0.1  -5.0
12100  2000010206    2.4    2.2   1023.3   1022.6    2  -9.0    2.5    0.0   2.5
12100  2000010207    3.2    3.0   1023.8   1023.1    2  -9.0  -99.0  -99.0  -5.0
12100  2000010208    3.4    2.9     -9.0     -9.0    4  -9.0  -99.0  -99.0  -5.0
12100  2000010209    3.6    2.9   1024.5   1023.8    2  -9.0  -99.0  -99.0  -5.0
12100  2000010210    3.5    3.0   1024.0   1023.3    4  -9.0  -99.0  -99.0  -5.0
you have one key (i.e. the date in format YYYYMMDD as a portion of 2.column), so you will only have to program one group change (Gruppenwechsel), i.e. print the summary when this key changes. Something like this:
control_break.f95
Code:
[COLOR=#a020f0]program[/color] control_break
  [COLOR=#0000ff]! Single-Level Control Break Processing[/color]

  [COLOR=#2e8b57][b]implicit[/b][/color] [COLOR=#2e8b57][b]none[/b][/color]

  [COLOR=#2e8b57][b]integer[/b][/color] :: stat, nr_records
[COLOR=#2e8b57][b]  real[/b][/color] :: dummy
  [COLOR=#0000ff]! global variables  [/color]
  [COLOR=#2e8b57][b]integer[/b][/color] :: date, date_save, col02, nr_col06, nr_col07, tnr_col06, tnr_col07
[COLOR=#2e8b57][b]  real[/b][/color] :: col06, col07, sum_col06, sum_col07, tsum_col06, tsum_col07
  [COLOR=#2e8b57][b]common[/b][/color] date, date_save, col02, col06, col07, [COLOR=#804040][b]&[/b][/color]
         nr_col06, nr_col07, sum_col06, sum_col07, [COLOR=#804040][b]&[/b][/color]
         tnr_col06, tnr_col07, tsum_col06, tsum_col07

  [COLOR=#0000ff]! open file[/color]
  [COLOR=#804040][b]open[/b][/color] ([COLOR=#ff00ff]1[/color], [COLOR=#804040][b]file[/b][/color][COLOR=#804040][b]=[/b][/color][COLOR=#ff00ff]'control_break.dat'[/color], [COLOR=#804040][b]status[/b][/color][COLOR=#804040][b]=[/b][/color][COLOR=#ff00ff]'old'[/color], [COLOR=#804040][b]iostat[/b][/color][COLOR=#804040][b]=[/b][/color]stat)
  [COLOR=#804040][b]if[/b][/color] (stat [COLOR=#804040][b].ne.[/b][/color] [COLOR=#ff00ff]0[/color]) [COLOR=#804040][b]then[/b][/color]
    [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color],[COLOR=#804040][b]*[/b][/color]) [COLOR=#ff00ff]'File cannot be opened !'[/color]
    [COLOR=#804040][b]go to[/b][/color] [COLOR=#ff00ff]99[/color]
  [COLOR=#804040][b]end if[/b][/color]

  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color], [COLOR=#ff00ff]'(80A)'[/color]) [COLOR=#ff00ff]'*******************************************************'[/color]
  [COLOR=#0000ff]! process file[/color]
  nr_records [COLOR=#804040][b]=[/b][/color] [COLOR=#ff00ff]0[/color]
  date_save [COLOR=#804040][b]=[/b][/color] [COLOR=#ff00ff]0[/color]

  [COLOR=#804040][b]do[/b][/color] [COLOR=#804040][b]while[/b][/color] ([COLOR=#ff00ff].true.[/color])
    [COLOR=#0000ff]! read record[/color]
    [COLOR=#804040][b]read[/b][/color]([COLOR=#ff00ff]1[/color], [COLOR=#804040][b]*[/b][/color], [COLOR=#804040][b]end[/b][/color][COLOR=#804040][b]=[/b][/color][COLOR=#804040][b]99[/b][/color]) dummy, col02, dummy, dummy, dummy, col06, col07
    nr_records [COLOR=#804040][b]=[/b][/color] nr_records [COLOR=#804040][b]+[/b][/color] [COLOR=#ff00ff]1[/color]
    [COLOR=#008080]call[/color] process_record
    [COLOR=#008080]call[/color] save_keys
  [COLOR=#804040][b]enddo[/b][/color]

[COLOR=#804040][b]  99 continue[/b][/color]
  [COLOR=#0000ff]! at end print totals[/color]
  [COLOR=#008080]call[/color] print_daily_summary
  [COLOR=#008080]call[/color] print_total_summary  
  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color], [COLOR=#ff00ff]10[/color]) nr_records 
  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color], [COLOR=#ff00ff]'(80A)'[/color]) [COLOR=#ff00ff]'*******************************************************'[/color]
  [COLOR=#0000ff]! close file[/color]
  [COLOR=#804040][b]close[/b][/color]([COLOR=#ff00ff]1[/color])

  [COLOR=#6a5acd]10[/color] [COLOR=#804040][b]format[/b][/color]([COLOR=#ff00ff]'Processing of'[/color],[COLOR=#008080]1X[/color], I0, [COLOR=#008080]1X[/color], [COLOR=#ff00ff]'lines finished.'[/color])
[COLOR=#a020f0]end program[/color] control_break

[COLOR=#a020f0]subroutine[/color] process_record
  [COLOR=#2e8b57][b]implicit[/b][/color] [COLOR=#2e8b57][b]none[/b][/color]
  [COLOR=#0000ff]! global variables[/color]
  [COLOR=#2e8b57][b]integer[/b][/color] :: date, date_save, col02, nr_col06, nr_col07, tnr_col06, tnr_col07
[COLOR=#2e8b57][b]  real[/b][/color] :: col06, col07, sum_col06, sum_col07, tsum_col06, tsum_col07
  [COLOR=#2e8b57][b]common[/b][/color] date, date_save, col02, col06, col07, [COLOR=#804040][b]&[/b][/color] 
         nr_col06, nr_col07, sum_col06, sum_col07, [COLOR=#804040][b]&[/b][/color]
         tnr_col06, tnr_col07, tsum_col06, tsum_col07

  [COLOR=#0000ff]! compute date[/color]
  date [COLOR=#804040][b]=[/b][/color] col02[COLOR=#804040][b]/[/b][/color][COLOR=#ff00ff]100[/color]

  [COLOR=#0000ff]! if not on first record[/color]
  [COLOR=#804040][b]if[/b][/color] (date_save [COLOR=#804040][b].ne.[/b][/color] [COLOR=#ff00ff]0[/color]) [COLOR=#804040][b]then[/b][/color]
    [COLOR=#0000ff]! process control break[/color]
    [COLOR=#008080]call[/color] process_control_break
  [COLOR=#804040][b]end if[/b][/color]

  [COLOR=#0000ff]! print line[/color]
  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color], [COLOR=#ff00ff]10[/color]) col02, col06, col07

  [COLOR=#0000ff]! compute sum of col06[/color]
  [COLOR=#804040][b]if[/b][/color] (col06 [COLOR=#804040][b].ne.[/b][/color] [COLOR=#804040][b]-[/b][/color][COLOR=#ff00ff]9.0[/color]) [COLOR=#804040][b]then[/b][/color] 
    nr_col06 [COLOR=#804040][b]=[/b][/color] nr_col06 [COLOR=#804040][b]+[/b][/color] [COLOR=#ff00ff]1[/color]
    sum_col06 [COLOR=#804040][b]=[/b][/color] sum_col06 [COLOR=#804040][b]+[/b][/color] col06
    tnr_col06 [COLOR=#804040][b]=[/b][/color] tnr_col06 [COLOR=#804040][b]+[/b][/color] [COLOR=#ff00ff]1[/color]
    tsum_col06 [COLOR=#804040][b]=[/b][/color] tsum_col06 [COLOR=#804040][b]+[/b][/color] col06
  [COLOR=#804040][b]end if[/b][/color]

  [COLOR=#0000ff]! compute sum of col07[/color]
  [COLOR=#804040][b]if[/b][/color] (col07 [COLOR=#804040][b].ne.[/b][/color] [COLOR=#804040][b]-[/b][/color][COLOR=#ff00ff]9.0[/color]) [COLOR=#804040][b]then[/b][/color] 
    nr_col07 [COLOR=#804040][b]=[/b][/color] nr_col07 [COLOR=#804040][b]+[/b][/color] [COLOR=#ff00ff]1[/color]
    sum_col07 [COLOR=#804040][b]=[/b][/color] sum_col07 [COLOR=#804040][b]+[/b][/color] col07
    tnr_col07 [COLOR=#804040][b]=[/b][/color] tnr_col07 [COLOR=#804040][b]+[/b][/color] [COLOR=#ff00ff]1[/color]
    tsum_col07 [COLOR=#804040][b]=[/b][/color] tsum_col07 [COLOR=#804040][b]+[/b][/color] col07
  [COLOR=#804040][b]end if[/b][/color]

  [COLOR=#6a5acd]10[/color] [COLOR=#804040][b]format[/b][/color]([COLOR=#008080]5X[/color], I10, [COLOR=#008080]1X[/color], [COLOR=#008080]f8.2[/color], [COLOR=#008080]1X[/color], [COLOR=#008080]f8.2[/color])
[COLOR=#a020f0]end subroutine[/color] process_record

[COLOR=#a020f0]subroutine[/color] process_control_break
  [COLOR=#2e8b57][b]implicit[/b][/color] [COLOR=#2e8b57][b]none[/b][/color]
  [COLOR=#0000ff]! global variables[/color]
  [COLOR=#2e8b57][b]integer[/b][/color] :: date, date_save, col02, nr_col06, nr_col07, tnr_col06, tnr_col07
[COLOR=#2e8b57][b]  real[/b][/color] :: col06, col07, sum_col06, sum_col07, tsum_col06, tsum_col07
  [COLOR=#2e8b57][b]common[/b][/color] date, date_save, col02, col06, col07, [COLOR=#804040][b]&[/b][/color] 
         nr_col06, nr_col07, sum_col06, sum_col07, [COLOR=#804040][b]&[/b][/color]
         tnr_col06, tnr_col07, tsum_col06, tsum_col07

  [COLOR=#804040][b]if[/b][/color] (date [COLOR=#804040][b].ne.[/b][/color] date_save) [COLOR=#804040][b]then[/b][/color]
     [COLOR=#008080]call[/color] print_daily_summary
  [COLOR=#804040][b]end if[/b][/color]
[COLOR=#a020f0]end subroutine[/color] process_control_break

[COLOR=#a020f0]subroutine[/color] print_daily_summary
  [COLOR=#2e8b57][b]implicit[/b][/color] [COLOR=#2e8b57][b]none[/b][/color]
  [COLOR=#0000ff]! global variables[/color]
  [COLOR=#2e8b57][b]integer[/b][/color] :: date, date_save, col02, nr_col06, nr_col07, tnr_col06, tnr_col07
[COLOR=#2e8b57][b]  real[/b][/color] :: col06, col07, sum_col06, sum_col07, tsum_col06, tsum_col07
  [COLOR=#2e8b57][b]common[/b][/color] date, date_save, col02, col06, col07, [COLOR=#804040][b]&[/b][/color] 
         nr_col06, nr_col07, sum_col06, sum_col07, [COLOR=#804040][b]&[/b][/color]
         tnr_col06, tnr_col07, tsum_col06, tsum_col07

  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color], [COLOR=#804040][b]*[/b][/color])
  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color], [COLOR=#ff00ff]10[/color]) date_save
  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color], [COLOR=#ff00ff]20[/color]) sum_col06, sum_col07
  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color], [COLOR=#ff00ff]30[/color]) nr_col06, nr_col07
  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color], [COLOR=#ff00ff]40[/color]) sum_col06[COLOR=#804040][b]/[/b][/color]nr_col06, sum_col07[COLOR=#804040][b]/[/b][/color]nr_col07
  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color], [COLOR=#804040][b]*[/b][/color])

  [COLOR=#6a5acd]10[/color] [COLOR=#804040][b]format[/b][/color]([COLOR=#ff00ff]'*  Summary for date'[/color],[COLOR=#008080]1x[/color],I8,[COLOR=#ff00ff]':'[/color])
  [COLOR=#6a5acd]20[/color] [COLOR=#804040][b]format[/b][/color]([COLOR=#ff00ff]'*  sum:'[/color],[COLOR=#008080]9x[/color], [COLOR=#008080]f8.2[/color], [COLOR=#008080]1x[/color], [COLOR=#008080]f8.2[/color])
  [COLOR=#6a5acd]30[/color] [COLOR=#804040][b]format[/b][/color]([COLOR=#ff00ff]'*  count:'[/color],[COLOR=#008080]7x[/color],I8,[COLOR=#008080]1x[/color],I8)
  [COLOR=#6a5acd]40[/color] [COLOR=#804040][b]format[/b][/color]([COLOR=#ff00ff]'*  average:'[/color],[COLOR=#008080]5x[/color], [COLOR=#008080]f8.2[/color], [COLOR=#008080]1x[/color], [COLOR=#008080]f8.2[/color])

  [COLOR=#0000ff]! initialize gloabal variables[/color]
  sum_col06 [COLOR=#804040][b]=[/b][/color] [COLOR=#ff00ff]0[/color]
  sum_col07 [COLOR=#804040][b]=[/b][/color] [COLOR=#ff00ff]0[/color]
  nr_col06 [COLOR=#804040][b]=[/b][/color] [COLOR=#ff00ff]0[/color]
  nr_col07 [COLOR=#804040][b]=[/b][/color] [COLOR=#ff00ff]0[/color]
[COLOR=#a020f0]end subroutine[/color] print_daily_summary

[COLOR=#a020f0]subroutine[/color] print_total_summary
  [COLOR=#2e8b57][b]implicit[/b][/color] [COLOR=#2e8b57][b]none[/b][/color]
  [COLOR=#0000ff]! global variables[/color]
  [COLOR=#2e8b57][b]integer[/b][/color] :: date, date_save, col02, nr_col06, nr_col07, tnr_col06, tnr_col07
[COLOR=#2e8b57][b]  real[/b][/color] :: col06, col07, sum_col06, sum_col07, tsum_col06, tsum_col07
  [COLOR=#2e8b57][b]common[/b][/color] date, date_save, col02, col06, col07, [COLOR=#804040][b]&[/b][/color] 
         nr_col06, nr_col07, sum_col06, sum_col07, [COLOR=#804040][b]&[/b][/color]
         tnr_col06, tnr_col07, tsum_col06, tsum_col07

  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color], [COLOR=#ff00ff]10[/color])
  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color], [COLOR=#ff00ff]20[/color]) tsum_col06, tsum_col07
  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color], [COLOR=#ff00ff]30[/color]) tnr_col06, tnr_col07
  [COLOR=#804040][b]write[/b][/color]([COLOR=#804040][b]*[/b][/color], [COLOR=#ff00ff]40[/color]) tsum_col06[COLOR=#804040][b]/[/b][/color]tnr_col06, tsum_col07[COLOR=#804040][b]/[/b][/color]tnr_col07

  [COLOR=#6a5acd]10[/color] [COLOR=#804040][b]format[/b][/color]([COLOR=#ff00ff]'** Summary for all dates:'[/color])
  [COLOR=#6a5acd]20[/color] [COLOR=#804040][b]format[/b][/color]([COLOR=#ff00ff]'** sum:'[/color],[COLOR=#008080]9x[/color], [COLOR=#008080]f8.2[/color], [COLOR=#008080]1x[/color], [COLOR=#008080]f8.2[/color])
  [COLOR=#6a5acd]30[/color] [COLOR=#804040][b]format[/b][/color]([COLOR=#ff00ff]'** count:'[/color],[COLOR=#008080]7x[/color],I8,[COLOR=#008080]1x[/color],I8)
  [COLOR=#6a5acd]40[/color] [COLOR=#804040][b]format[/b][/color]([COLOR=#ff00ff]'** average:'[/color],[COLOR=#008080]5x[/color], [COLOR=#008080]f8.2[/color], [COLOR=#008080]1x[/color], [COLOR=#008080]f8.2[/color])
[COLOR=#a020f0]end subroutine[/color] print_total_summary

[COLOR=#a020f0]subroutine[/color] save_keys
  [COLOR=#2e8b57][b]implicit[/b][/color] [COLOR=#2e8b57][b]none[/b][/color]
  [COLOR=#0000ff]! global variables[/color]
  [COLOR=#2e8b57][b]integer[/b][/color] :: date, date_save, col02, nr_col06, nr_col07, tnr_col06, tnr_col07
[COLOR=#2e8b57][b]  real[/b][/color] :: col06, col07, sum_col06, sum_col07, tsum_col06, tsum_col07
  [COLOR=#2e8b57][b]common[/b][/color] date, date_save, col02, col06, col07, [COLOR=#804040][b]&[/b][/color] 
         nr_col06, nr_col07, sum_col06, sum_col07, [COLOR=#804040][b]&[/b][/color]
         tnr_col06, tnr_col07, tsum_col06, tsum_col07

  date_save [COLOR=#804040][b]=[/b][/color] date
[COLOR=#a020f0]end subroutine[/color] save_keys
The output is:
Code:
$ gfortran control_break.f95 -o control_break

$ control_break
*******************************************************
     2000010106    -9.00     2.00
     2000010107    -9.00     4.00
     2000010108  1023.30     3.00
     2000010109    -9.00     3.00
     2000010110    -9.00     3.00
     2000010111    -9.00     3.00
     2000010112    -9.00     4.00
     2000010113  1023.30     4.00
     2000010114    -9.00     2.00
     2000010115    -9.00     3.00
     2000010116    -9.00     3.00
     2000010117  1019.80     3.00
     2000010118    -9.00     3.00

*  Summary for date 20000101:
*  sum:          3066.40    40.00
*  count:              3       13
*  average:      1022.13     3.08

     2000010206  1022.60     2.00
     2000010207  1023.10     2.00
     2000010208    -9.00     4.00
     2000010209  1023.80     2.00
     2000010210  1023.30     4.00

*  Summary for date 20000102:
*  sum:          4092.80    14.00
*  count:              4        5
*  average:      1023.20     2.80

** Summary for all dates:
** sum:          7159.20    54.00
** count:              7       18
** average:      1022.74     3.00
Processing of 18 lines finished.
*******************************************************
However, I used common block for global variables, which is not very nice in modern fortran, so I suggest you rather to use module.
 
a subtle note i thought might be worth mentioning.

the above programs by KyrieXuX and mikrom basically have the same purpose and outcome. but, one small difference i noticed between the programs is the way in which the input data is read in -- KyrieXuX uses 'FORMATTED input' READ statements, whereas mikrom uses 'UNFORMATTED input' READ statements. for example:


FORMATTED input READ statement
READ(10,(I5,2X,I4,2X,F5.1,etc))var1,var2,var3,...


UNFORMATTED input READ statement
READ(10,*)var1,var2,var3,...



when i was taught fortran (many years ago!), i was told that, with FORMATTED input/READ, the input must be 'exactly' as you specify in your READ statement (i.e. if it's not, then it might not all get read in properly). with UNFORMATTED input, however, the input does not have to be as 'exact' (i.e. you can be sloppy with the amount of space there is between different variable values in the input data file, as long as there IS space between them).

i was also told that using UNFORMATTED input/READ is generally safer, although there may be some instances when FORMATTED input/READ should be used instead. i was also told that it is usually best to use FORMATTING with output only (i.e. FORMATTED output, using WRITE statements, like it is used in the above programs by KyrieXuX and mikrom), rather than input.


anyway, i don't know whether this could also have been affecting the results that KyrieXuX is trying to achieve.
 
Yes I used unformatted read, because I don't know exactly format of the input file, i.e. how many white spaces are between the numeric columns.

Other difference is in the processing:

Classical quick approach is first to read a file into one or more arrays and then process the arrays, but with large files this could be very memory consument, could have limitations with allocating large arrays...etc.

With Control Break Processing technique we don't need to use arrays. The file is readed and processed at naturally way - in one pass. There are not limits concerning the file size.
 
just a remark about the wording : read(10,*) is NOT an unformatted reading but a list directed reading using a default free format. There is a format represented by "*". Such reading form is sometimes called the free format reading (but "list directed" is the official name). The two forms mentioned by billgray1234 (fixed format and list directed) are both useful to read formatted files (usually human readable files).

An unformatted reading is performed when reading an unformatted file. In that case,the read statement looks like : read(10) a,b... Here there is no format at all ! And such a file is not human readable (except if you are able to understand binary coding).

François Jacq
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top