subroutine dat_table c -------------------- external dat_table_desc external dat_table_opts external dat_table_read integer dtype/0/ call dat_init_desc(dtype, dat_table_desc) call dat_init_opts(dtype, dat_table_opts) call dat_init_read(dtype, dat_table_read) end subroutine dat_table_desc(text) c ------------------------------- character*(*) text ! (out) description text='TABLE table format (XY, XYS, XYSM ... see options)' end subroutine dat_table_opts c -------------------------- print '(x,a)' 1,'x: column to be used as x-axis' 1,'y: column to be used as y-axis' 1,'s: column to be used as sigma' 1,'m: column to be used as monitor' 1,' any column may be specified as' 1,' - an integer (column number starting from 1)' 1,' - as a name (if a header is present)' 1,' - as a float (containing a decimal point)' 1,' for x, this is a step between equidistant x-values' 1,' else it is a constant value' 1,' - an asterisk (*) for a special meaning' 1,' for x, this is (1,2,3,....)' 1,' for y, this is 0.0' 1,' for s, this is sqrt(y)' 1,' for m, this is 1.0' 1,' the defaults are' 1,' x=*,y=1,s=*,m=* for 1 column' 1,' x=1,y=2,s=*,m=* for 2 columns' 1,' x=1,y=2,s=3,m=* for 3 columns or more' ! 1,' ' ! 1,'n: n=0 y and s are already normalized (default)' ! 1,' n=1 y and s are not yet normalized by monitor' end subroutine dat_table_read 1 (lun, forced, nread, putval, nmax, xx, yy, ss, ww) ! ---------------------------------------------------- implicit none integer lun ! (in) logical unit number (file will be closed if successful) integer forced ! 0: read only if type is sure; 1: forced read integer nread ! (out) >=0: = number of points read, file closed ! -1: not correct type, file rewinded ! -2: correct type, but unreadable, file rewinded external putval ! (in) subroutine to put name/value pairs. ! for numeric data: call putval('name', value) ! value must be real ! for character data: call putval('name=text', 0.0) integer nmax ! max. number of points real xx(*) ! x-values real yy(*) ! y-values real ss(*) ! sigma real ww(*) ! weights (original monitor) ! local integer mcol, rows parameter (mcol=64, rows=30) character header*1024, elem*64 character line*1024 character labx*80, laby*80, labs*80, labw*80 real values(mcol), ymon integer i, j, pos ! integer normalize integer nrows, njunk, n, ncol, lin, lin0, lin1, iostat integer ncolmax integer ncolx, ncoly, ncols, ncolw integer colx(mcol), coly(mcol), cols(mcol), colw(mcol) real valx, valy, vals, valw, x, y, s, w integer errcnt, errlin, errcol, s0cnt integer nset, lastcol ! a table block should appear before (rows=30) junk lines ! junk lines are lines that does contain something else than numbers, ! comment lines and empty lines not counted. ! if a the file does not contain more junk lines than the last table block, ! it is considered as a table file. The last table block is used, or the ! first block with at least (rows=30) lines. ! the column header line is the last line before the used table block ! this may also be a comment line ! check the above conditions nread=0 lin=0 lin0=0 lin1=0 ncol=0 ncolmax=0 nrows=0 njunk=0 ymon=0 1 read(lun,'(a)',err=98,end=19) line lin=lin+1 if (line(1:1) .eq. '#') then if (forced .lt. 0) goto 100 lin1=lin goto 1 endif if (line .eq. ' ') goto 1 j=nread+1 pos=1 iostat=0 n=0 i=0 do while (iostat .eq. 0) call str_get_elem(line, pos, elem) if (elem .eq. ' ') then n=i iostat=1 else if (line(1:1) .gt. '9') then iostat=1 else read(elem, *, iostat=iostat) valx i=i+1 endif enddo if (n .eq. 0) then ! a junk line if (forced .lt. 0) goto 100 if (nrows .gt. 3 .and. forced .le. 0) goto 100 njunk=njunk+nrows+1 if (njunk .gt. rows .and. forced .le. 0) goto 100 nrows=0 lin0=lin lin1=0 else if (lin1 .ne. 0) then lin0=lin1 lin1=0 endif nrows=nrows+1 if (n .ne. ncol) then if (ncol .ne. 0 .and. nrows .gt. 3 .and. forced .le. 0) 1 goto 100 ncol=n endif if (nrows .gt. 3 .and. n .gt. ncolmax) ncolmax=n if (nrows .gt. rows) goto 20 endif goto 1 19 if (nrows .lt. njunk .and. forced .le. 0) goto 100 20 continue rewind lun if (ncolmax .eq. 0) then ncolmax = n endif if (ncolmax .gt. mcol) then print *,'DAT_TABLE: use only the first',mcol,' columns' ncolmax=mcol endif do i=1,lin0 read(lun,'(a)',err=98,end=98) line enddo lin=lin0 if (line(1:1) .eq. '#') then line(1:1)=' ' endif header=line call dat_start_options call dat_table_col_options(header 1 , 'x', colx, mcol, ncolx, valx, labx) call dat_table_col_options(header 1 , 'y', coly, mcol, ncoly, valy, laby) call dat_table_col_options(header 1 , 's', cols, mcol, ncols, vals, labs) call dat_table_col_options(header 1 , 'm', colw, mcol, ncolw, valw, labw) if (ncolx .lt. 0 .or. ncoly .lt. 0 .or. 1 ncols .lt. 0 .or. ncolw .lt. 0) goto 99 ! normalize=0 ! call dat_int_option('n', normalize) if (ncolx .eq. 0) then ncolx=1 if (ncolmax .eq. 1) then colx(1)=-1 labx='linear' else colx(1)=1 labx='col1' endif endif if (ncoly .eq. 0) then ncoly=1 if (ncolmax .lt. 2) then coly(1)=1 laby='col1' else coly(1)=2 laby='col2' endif endif if (ncols .eq. 0) then ncols=1 if (ncolmax .lt. 3) then cols(1)=-1 labs='sqrt' else cols(1)=3 labs='col3' endif endif if (ncolw .eq. 0) then ncolw=1 colw(1)=-1 ! monitor 1.0 labw=' ' endif lastcol=0 do i=1,ncolx lastcol=max(lastcol,colx(i)) enddo do i=1,ncoly lastcol=max(lastcol,coly(i)) enddo do i=1,ncols lastcol=max(lastcol,cols(i)) enddo do i=1,ncolw lastcol=max(lastcol,colw(i)) enddo if (lastcol .gt. ncolmax) then print *,'DAT_TABLE: column ',lastcol,' does not exist' goto 99 endif if (lastcol .eq. 0) then print *,'DAT_TABLE: ignoring all columns' endif call putval('XAxis='//labx, 0.0) call putval('YAxis='//laby, 0.0) call putval('Sigma='//labs, 0.0) call putval('Weight='//labw, 0.0) nset=max(ncolx,ncoly,ncols,ncolw) do i=ncolx+1,nset colx(i)=colx(ncolx) enddo do i=ncoly+1,nset coly(i)=coly(ncoly) enddo do i=ncols+1,nset cols(i)=cols(ncols) enddo do i=ncolw+1,nset colw(i)=colw(ncolw) enddo ! call dat_group(2, putval) ! call putval('XAxis='//xaxis, 0.0) ! call putval('YAxis='//yaxis, 0.0) call dat_group(1, putval) nrows=0 errcnt=0 s0cnt=0 4 continue read(lun,'(a)',err=99,end=90) line lin=lin+1 if (line(1:1) .eq. '#') goto 4 if (line .eq. ' ') goto 4 pos=1 do j=1,lastcol call str_get_elem(line, pos, elem) values(j)=0.0 read(elem, *, iostat=iostat) values(j) if (iostat .ne. 0) then if (errcnt .eq. 0) then errlin=lin errcol=j endif errcnt=errcnt+1 endif enddo nrows=nrows+1 do i=1,nset if (colx(i) .eq. -1) then ! linear starting from 1 x=nrows else if (colx(i) .eq. 0) then x=(nrows-1)*valx else x=values(colx(i)) endif if (coly(i) .eq. -1) then ! not really useful: constant 0 y=0.0 else if (coly(i) .eq. 0) then y=valy else y=values(coly(i)) endif if (cols(i) .eq. -1) then ! sqrt(y) if (y .lt. 1.0) then s=1.0 else s=sqrt(y) ! statistical counting error endif else if (cols(i) .eq. 0) then s=vals else s=values(cols(i)) endif if (colw(i) .eq. -1) then ! fixed weight w=1.0 else if (colw(i) .eq. 0) then w=valw else w=values(colw(i)) endif if (w .le. 0) w=1.0 if (ymon .eq. 0) ymon=w if (nread .ge. nmax) goto 29 if (s .le. 0) then s0cnt=s0cnt+1 else nread=nread+1 xx(nread)=x yy(nread)=y*ymon/w ss(nread)=s*ymon/w ww(nread)=w endif enddo goto 4 90 close(lun) if (s0cnt .gt. 0) then print *,'DAT_TABLE: skipped',s0cnt 1 ,' lines with sigma = 0' endif if (errcnt .gt. 0) then print *,'DAT_TABLE: found',errcnt,'errors, first at line ' 1 ,errlin ,' column ', errcol endif call putval('Monitor', ymon) if (nset .gt. 1) then call fit_dat_table(1, nset, nrows) endif return 29 print *,'DAT_TABLE: too many points' goto 100 98 if (forced .le. 0) goto 100 99 print *,'DAT_TABLE: error during read' rewind lun nread=-2 return 100 nread=-1 rewind lun end subroutine dat_table_col_options(header, name, cols, mcols, ncols 1 , val, axlabel) integer mcols, ncols integer cols(mcols) character name*(*), header*(*), axlabel*(*) real val character colname*64, axname*64 integer idx, l, iax, iostat, ll integer str_find_elem external str_find_elem colname=' ' ncols=0 iax=0 axlabel=' ' ll=0 call dat_str_option(name, colname) if (colname .eq. ' ') then iax=1 write(axname, '(a,i1)') name, iax call dat_str_option(axname, colname) endif do while (colname .ne. ' ') call str_trim(colname, colname, l) if (colname .eq. '*') then ncols=ncols+1 cols(ncols)=-1 ! special meaning if (name .eq. 'x') then colname='linear' l=6 else if (name .eq. 'y') then colname='0.0' l=3 else if (name .eq. 's') then colname='sqrt(y)' l=7 else if (name .eq. 'm') then colname='1.0' l=3 endif goto 10 endif idx=0 if (index(colname, '.') .ne. 0) then read(colname, *, iostat=iostat) val ! try to get colname as a real if (iostat .eq. 0) then ncols=ncols+1 cols(ncols)=0 ! special value goto 10 endif else read(colname, *, iostat=iostat) idx ! try to get colname as an int endif if (iostat .ne. 0) then idx=str_find_elem(header, colname) else colname='col'//colname(1:l) l=l+3 endif if (idx .eq. 0) then print *,'DAT_TABLE: column ',colname(1:l),' not found' goto 9 endif ncols=ncols+1 cols(ncols)=idx 10 continue call str_append(axlabel, ll, colname(1:l)//',') colname=' ' if (iax .ne. 0) then iax=iax+1 if (iax .le. 9) then write(axname, '(a,i1)') name, iax call dat_str_option(axname, colname) else if (iax .le. 99) then write(axname, '(a,i2)') name, iax call dat_str_option(axname, colname) endif endif enddo if (ll .gt. 1) then axlabel(ll:ll)=' ' endif RETURN 9 ncols=-1 end