Files
sicspsi/tecs/conv.f

736 lines
17 KiB
Fortran

program conv
include 'conv.inc'
logical init
integer i,j,l,lin,iostat
character*128 line
character*2048 input
data lun/0/,pos/0/,nlist/0/
path=' '
lp=0
verbose=.false.
call sys_get_cmdpar(input, l)
if (input .eq. ' ') then
verbose=.true.
print '(a,$)',
1' File(s) (separated with space): '
read(*,'(a)',end=99) input
if (input .eq. ' ') goto 99
endif
i=index(input, '-p')
if (i .ne. 0) then ! first path option valid from start
j=index(input(i+1:), ' ')
call str_trim(path, input(i+2:i+j), lp)
endif
i=0
do while (input(i+1:) .ne. ' ')
j=index(input(i+1:), ' ')
if (j .le. 1) then
i=i+1
else if (input(i+1:i+2) .eq. '-p') then
call str_trim(path, input(i+3:i+j), lp)
i=i+j
else if (input(i+1:i+1) .eq. '-') then
print *,'unknown option: ',input(i+1:i+j)
i=i+j
else
call str_trim(file, input(i+1:i+j), lf)
i=i+j
if (verbose) print *
open(1,name=file(1:lf),status='old',iostat=iostat)
if (iostat .ne. 0) then
if (verbose) then
print *,'can not open ',file(1:lf)
print "(x,60('-'))"
endif
nlist=nlist+1
list(nlist)='can not open '//file(1:lf)
else
lin=0
do
call lsc_errinit(1) ! 1=lun
call lsc_convert_table(lin)
if (lin .lt. 0) goto 19
if (verbose) print "(x,60('-'))"
enddo
19 continue
close(1)
endif
endif
enddo
do i=1,nlist
call str_trim(list(i), list(i), l)
print *,list(i)(1:l)
enddo
99 continue
end
subroutine pack(line, l, x, y, offset, m)
character line*(*)
integer l, offset, m
real x(m), y(m)
integer j,p
p=0
do j=1,m
call str_append(line, p, '#0,')
call cvt_real_str(line(p+1:), l, 1.0*(offset+j), 1, 0, 6, 3)
p=p+l
call str_append(line, p, ':')
call cvt_real_str(line(p+1:), l, x(j), 1, 0, 6, 3)
p=p+l
call str_append(line, p, ',')
call cvt_real_str(line(p+1:), l, y(j), 1, 0, 6, 3)
p=p+l
call str_append(line, p, ';')
enddo
line(p:p)=' '
l=p-1
end
subroutine lsc_convert_table(lin)
implicit none
include 'conv.inc'
integer lin
integer ntypes,nvolts, namps
parameter (ntypes=12, nvolts=12, namps=12)
integer np
real x(200), y(200), ex, ey
integer i,j,l,p,li,crc,form,iostat
character name*15, sensor*10, header*64, line*128, old*128, intype*16
character crcmp*3, filnam*128, cfgdir*128
character c40*40/'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ$+-&'/
integer unit, stype, excit, irange, coef, iunit, stdcurv
! codes
character types(0:ntypes)*12/'Special','Si Diode','GaAlAs Diode'
1 ,'Pt250 Ohm','Pt500 Ohm','Pt2500 Ohm','RhFe','C-Glass'
1 ,'Cernox','RuOx','Ge','Cap','Tc'/
integer nunits
parameter (nunits=3)
character units(nunits)*5/'mV','V','Ohm'/
integer nexcits
parameter (nexcits=12)
character excits(0:nexcits)*8/'Off','30nA','100nA','300nA','1uA','3uA'
1 ,'10uA','30uA','100uA','300uA','1mA','10mV','1mV'/
integer nforms
parameter (nforms=5)
character forms(nforms)*6/'ill','ill','lin','log','loglog'/
! default values
integer defu(ntypes)/ 1, 1, 2, 2,2, 2, 2, 2, 2, 2, 3, 1/ ! unit
integer defe(ntypes)/ 6, 6,10,10,8,10,11,11,11,12, 0, 0/ ! excit
integer defr(ntypes)/11,12, 8, 9,8, 8, 4, 4, 4, 1, 1, 6/ ! range
integer defc(ntypes)/ 1, 1, 2, 2,2, 2, 1, 1, 1, 1, 2, 2/ ! coef
real volts(nvolts)/1E-3,2.5E-3,5E-3,1E-2,2.5E-2,5E-2
1 ,1E-1,2.5E-1,5E-1,1E-0,2.5E-0,5E-0/
real amps(namps)/3E-8,1E-7,3E-7,1E-6,3E-6,1E-5,3E-5,1E-4,3E-4,1E-3
1 ,3E-8,3E-8/ ! minimal values are for voltage excitation
integer stdmax
parameter (stdmax=10)
character*40 stdhdr(stdmax)/
1 'DT-470 ,Standard ,2,+475.000E+0,1',
1 'DT-500-D ,Standard ,2,+365.000E+0,1',
1 'DT-500-E1 ,Standard ,2,+330.000E+0,1',
1 'PT-100 ,Standard ,3,+800.000E+0,2',
1 'PT-1000 ,Standard ,3,+800.000E+0,2',
1 'TYPE K ,Standard ,1,+1645.00E+0,2',
1 'TYPE E ,Standard ,1,+1188.50E+0,2',
1 'TYPE T ,Standard ,1,+673.000E+0,2',
1 'CrAuFe.03%,Standard ,1,+500.000E+0,2',
1 'CrAuFe.07%,Standard ,1,+610.000E+0,2'/
integer stdtype(stdmax)/1,1,1,4,5,12,12,12,12,12/
real tlim, range, xmax, ymax, curr, rl
real x1,x2,xi,y1,y2,yi,sum,sum1,sum2,mum,mum1,mum2,d,at,at1,at2
logical eof, first, inverted
! functions
integer lsc_getno
external lsc_getno, pack
first=.true.
eof=.false.
np=0
name=' '
sensor=' '
unit=0
tlim=0
stype=0
excit=0
form=0
range=-1.0
stdcurv=0
1 read(1,'(a)',err=97,end=97) line
call str_trim(line, line, l)
lin=lin+1
call str_first_nonblank(line, i)
if (i .eq. 0) goto 1
if (line(i:i) .eq. '!') goto 1
first=.false.
call str_upcase(line(1:l),line(i:l))
i=index(line(1:l),'!')
if (i .ne. 0) line=line(1:i-1)
call str_trim(line(1:l),line(1:l),l)
if (line(1:4) .ne. 'CURV') then
i=index(line,'=')
if (i .eq. 0) then
call lsc_error(lin, 'missing "="')
goto 1
endif
if (i .eq. l) then
call lsc_error(lin, 'missing value')
goto 1
endif
call str_first_nonblank(line(i+1:l), j)
i=i+j
if (line(1:4) .eq. 'SENS') then
sensor=line(i:l)
name=sensor
elseif (line(1:4) .eq. 'UNIT') then
unit=lsc_getno(units, nunits, line(i:l))
if (unit .le. 0) call lsc_error(lin, 'illegal unit')
elseif (line(1:4) .eq. 'TLIM') then
read(line(i:l),*,err=92,end=92) tlim
elseif (line(1:4) .eq. 'TYPE') then
stype=lsc_getno(types, ntypes+1, line(i:l))-1
if (stype .lt. 0) call lsc_error(lin, 'illegal type')
elseif (line(1:4) .eq. 'EXCI') then
call str_substitute(line(1:8),line(i:l),' ',char(0))
excit=lsc_getno(excits, nexcits, line(1:8))-1
if (excit .lt. 0) call lsc_error(lin, 'illegal excitation')
elseif (line(1:4) .eq. 'RANG') then
read(line(i:l),*,err=93,end=93) range
if (range .lt. 0) goto 93
elseif (line(1:4) .eq. 'FORM') then
form=lsc_getno(forms, nforms, line(i:l))
if (form .lt. 3) call lsc_error(lin, 'illegal format')
else
call lsc_error(lin, 'unknown parameter name')
endif
goto 1
endif
if (sensor .eq. ' ') call lsc_error(lin, 'missing sensor name')
i=index(line,'=')
if (i .ne. 0) then
read(line(i+1:l), *, err=2,end=2) stdcurv
2 continue
if (stdcurv .lt. 0 .or. stdcurv .gt. stdmax) then
call lsc_error(lin, 'illegal standard curve no.')
goto 101
endif
if (unit .ne. 0 .or. stype .ne. 0 .or.
1 excit .ne. 0 .or. tlim .ne. 0) then
if (verbose) then
print *,'Warning: all parameters except "sens"'
1 ,', "range" and "curv" are ignored',char(7)
endif
errstat=max(errstat,1)
endif
line=stdhdr(stdcurv)
i=index(line, ',')
if (i .eq. 0) goto 96 ! illegal stdhdr
j=index(line(i+1:), ',')
if (j .eq. 0) goto 96 ! illegal stdhdr
read(line(i+j+1:), *, err=96, end=96) unit, ymax, coef
stype=stdtype(stdcurv)
! if (range .lt. 0) then
! range=stdrange(stdcurv)
! end if
xmax=0
excit=0
tlim=0
goto 100
endif
if (line(5:) .ne. ' ') then
call lsc_error(lin, 'missing "="')
goto 101
end if
! user curve
if (unit .eq. 0) call lsc_error(lin, 'missing unit')
if (stype .eq. 0) then
if (excit .le. 0) call lsc_error(lin, 'missing excitation')
if (range .lt. 0) call lsc_error(lin, 'missing range')
else
if (excit .eq. 0) excit=defe(stype)
endif
3 np=np+1
read(1,'(a)',err=98,end=98) line
lin=lin+1
if (line .eq. ' ') goto 9
read(line, *, err=94, end=94) x(np), y(np)
goto 3
92 call lsc_error(lin,'illegal tlim')
goto 1
93 call lsc_error(lin,'illegal range')
goto 1
94 call lsc_error(lin,'illegal datapoint')
goto 101
95 call lsc_error(lin,'illegal table no')
goto 1
96 stop 'internal error: illegal stdhdr'
97 if (.not. first) then
call lsc_error(lin,'unexpected end of file')
endif
lin=-1
RETURN
98 eof=.true.
9 np=np-1 ! point (np) is not valid
if (np .lt. 2) call lsc_error(lin+np, 'not enough data points')
if (x(np) .lt. x(1)) then ! inverse order
j=np
do i=1,np/2
ex=x(i)
ey=y(i)
x(i)=x(j)
y(i)=y(j)
x(j)=ex
y(j)=ey
j=j-1
enddo
inverted=.true.
else
inverted=.false.
endif
do i=2,np
if (x(i) .le. x(i-1)) then
j=i
if (inverted) j=np-i+1
call lsc_error(lin+j, 'table not ordered')
goto 101
endif
enddo
xmax=x(np)
if (y(np) .lt. y(1)) then
coef=1
do i=2,np
if (y(i) .ge. y(i-1)) then
j=i
if (inverted) j=np-i+1
call lsc_error(lin+j, 'table not ordered')
goto 101
endif
enddo
ymax=y(1)
else
coef=2
do i=2,np
if (y(i) .le. y(i-1)) then
j=i
if (inverted) j=np-i+1
call lsc_error(lin+j, 'table not ordered')
goto 101
endif
enddo
ymax=y(np)
endif
101 continue
do i=1,np
if (x(i) .eq. 0.0) then
j=i
if (inverted) j=np-i+1
call lsc_error(lin+j, 'illegal sensor value')
endif
if (y(i) .le. 0.0) then
j=i
if (inverted) j=np-i+1
call lsc_error(lin+j, 'illegal temperature')
endif
enddo
if (errstat .gt. 1) goto 999
sum=0
sum1=0
sum2=0
mum=0
mum1=0
mum2=0
do i=2,np-1
xi=x(i)
x1=x(i-1)
x2=x(i+1)
yi=log(y(i))
y1=y(i-1)
y2=y(i+1)
d=abs(yi-log(y1+(xi-x1)/(x2-x1)*(y2-y1)))
sum=sum+d*d
if (d .gt. mum) then
mum=d
at=y(i)
endif
xi=log(abs(xi))
x1=log(abs(x1))
x2=log(abs(x2))
d=abs(yi-log(y1+(xi-x1)/(x2-x1)*(y2-y1)))
sum1=sum1+d*d
if (d .gt. mum1) then
mum1=d
at1=y(i)
endif
y1=log(y1)
y2=log(y2)
d=abs(yi-(y1+(xi-x1)/(x2-x1)*(y2-y1)))
sum2=sum2+d*d
if (d .gt. mum2) then
mum2=d
at2=y(i)
endif
enddo
if (np .gt. 2) then
sum=sqrt(sum/(np-1))*25
sum1=sqrt(sum1/(np-1))*25
sum2=sqrt(sum2/(np-1))*25
if (verbose) then
print '(x,a)','Interpolation accuracy mean worst at'
print '(13x,a,3(f8.2,a))','linear ',sum, '%',mum *25,'%',at,' K'
print '(13x,a,3(f8.2,a))','log/lin ',sum1,'%',mum1*25,'%',at1,' K'
print '(13x,a,3(f8.2,a))','log/log ',sum2,'%',mum2*25,'%',at2,' K'
endif
if (unit .eq. 3) then
sum1=(sum1/sum)**2+(mum1/mum)**2
sum2=(sum2/sum)**2+(mum2/mum)**2
if (form .eq. 0 .and. (sum1 .lt. 1.0 .or. sum2 .lt. 1.0)
1 .or. form .gt. 3) then
if (form .eq. 0 .and. sum2 .lt. sum1 .or. form .eq. 5) then
unit=5
do i=1,np
y(i)=log10(y(i))
enddo
else
unit=4
endif
do i=1,np
x(i)=log10(x(i))
enddo
endif
else
if (form .gt. 3 .and. verbose)
1 print *,'FORM ignored (not unit Ohm)'
endif
endif
100 continue
if (unit .eq. 1) then ! check for mV / V consistency
if (xmax .gt. 990) then
unit=2
do i=1,np
x(i)=x(i)/1000.0
enddo
endif
xmax=xmax/1000.0
range=range/1000.0
elseif (unit .eq. 2) then
if (xmax .lt. 0.5) then
unit=1
do i=1,np
x(i)=x(i)*1000.0
enddo
endif
endif
if (range .eq. 0) range=xmax
if (tlim .eq. 0 .or. tlim .gt. ymax) tlim=ymax
irange=0
if (range .gt. 0) then
if (unit .ge. 3) then ! Ohm
curr=amps(excit)
rl=range*curr ! convert Ohm to V
if (rl .gt. 5.0) then
! print *,'Warning: maximum range exceeded: '
! 1 , range,'>',5/curr,' Ohm',char(7)
! errstat=max(errstat,1)
irange=12
endif
else
rl=range ! V
endif
if (irange .eq. 0) then
if (stype.eq.12) then
j=6
else
j=nvolts
end if
do i=1,j
if (rl .le. volts(i)) then
irange=i
goto 150
endif
enddo
! print *,'Warning: maximum range exceeded: ', range,' > ',volts(j),' V',char(7)
! errstat=max(errstat,1)
irange=j
150 continue
if (excit .eq. 11) then ! 10 mV excit -> min. 10 mV range
if (irange .lt. 4) irange=4
endif
endif
else
irange=defr(stype)
range=xmax
endif
if (stdcurv.eq.0) then
if (unit .ge. 3) then
if (range*amps(excit) .gt. volts(irange)) then
print *,'Warning: max. range exceeded: '
1 ,range,' > ',volts(irange)/amps(excit),' Ohm',char(7)
errstat=max(errstat,1)
endif
else if (range .gt. volts(irange)) then
print *,'Warning: max. range exceeded: '
1 ,range,' > ',volts(irange), ' V',char(7)
errstat=max(errstat,1)
endif
endif
if (stype .gt. 0) then
if (excit .le. 0) excit=defe(stype)
if (irange .eq. 0) irange=defr(stype)
endif
if (verbose) then
print *,'Sensor type: ',types(stype)
print *,'Excitation: ',excits(excit)
if (unit .eq. 1) then
print *,'Sensor Range: ',volts(irange)*1000,' mV'
elseif (unit .eq. 2) then
print *,'Sensor Range: ',volts(irange),' V'
else
print *,'Sensor Range: ',volts(irange)/amps(excit),' Ohm'
if (unit .eq. 5) then
print *,'table double logarithmic'
elseif (unit .eq. 4) then
print *,'table logarithmic'
else
print *,'table linear'
endif
endif
if (coef .eq. 1) then
print *,'negative characteristic'
else
print *,'positive characteristic'
endif
print *
endif
if (stype .eq. 0) then
if (unit .ge. 3) then
iunit=2
else
iunit=1
endif
else
if (unit .le. 2) then ! mV / V
iunit=1
else ! Ohm
iunit=2
endif
if (iunit .ne. defu(stype) .or.
1 coef .ne. defc(stype) .or.
1 excit .ne. defe(stype) .or.
1 irange.ne. defr(stype)) then
if (stype .ne. 12) stype=0
endif
endif
if (stype .eq. 12) then
l=5
write (line(1:l), '(a,i1)') ',,,,',max(0,irange-5)
elseif (stype .eq. 0) then
l=14
write (line(1:l), '(i2,4(a,i2.0))')
1 stype,',',iunit,',',coef,',',excit,',',irange
else
l=2
write(line(1:l), '(i2)') stype
endif
call str_substitute(intype, line(1:l), ' ', char(0))
call str_trim(intype, intype, li)
if (tlim .gt. 1500) tlim=1500
if (tlim .lt. 0) tlim=0
if (stdcurv.eq.0) then
! calculate crc of table
crc=0
do i=1,np
call pack(line, l, x(i), y(i), i-1, 1)
call str_crc(crc, line(1:l))
enddo
call str_crc_comp(crc, crcmp)
write (header, "(a,x,a,',',a,',',i1,',',f8.3,',',i1)")
1 name(1:11), crcmp,sensor,unit,tlim,coef
else
crc=0
header=stdhdr(stdcurv)
endif
! compare with old file
call str_trim(filnam, sensor, l)
call str_lowcase(filnam, filnam)
filnam(l+1:)='.crv'
if (path(1:lp) .ne. ' ') then
filnam=path(1:lp)//filnam
endif
open(unit=2, file=filnam, status='old', iostat=iostat)
if (iostat .ne. 0) goto 198
read(2, '(a)',end=199) old
if (old .ne. header) goto 199
read(2, '(a)', end=199) old
if (old .ne. intype) goto 199
if (stdcurv .ne. 0) then
write(line, '(a, i2)') '$',stdcurv
read(2, '(a)', end=199) old
if (line .ne. old) goto 199
read(2, '(a)', end=197) old ! goto end (o.k.) if no more line
goto 199
endif
do i=1,np,ncolumn
read(2, '(a)', end=199) old
call pack(line, l, x(i), y(i), i-1, min(ncolumn,np-i+1))
if (line .ne. old) goto 199
enddo
read(2, '(a)', end=199) old
call pack(line, l, 0.0, 0.0, np, 1)
if (line .ne. old) goto 199
read(2, '(a)', end=197) old ! goto end (o.k.) if no more line
goto 199
197 close(2)
if (verbose) print *,'curve file has not changed: ',filnam
goto 200
! goto 999
198 if (verbose) print *,'create new curve file: ',filnam
nlist=nlist+1
list(nlist)='created '//filnam
goto 200
199 close(2)
if (verbose) print *,'modify curve file: ',filnam
nlist=nlist+1
list(nlist)='modified '//filnam
200 continue
open(unit=2, file=filnam, status='unknown', iostat=iostat)
if (iostat .ne. 0) then
call str_trim(filnam, filnam, l)
print *,'can not open ',filnam(1:l)
nlist=nlist-1
lin=-1
return
endif
call str_trim(header, header, l)
write(2, '(a)') header(1:l)
write(2, '(a)') intype(1:li)
if (stdcurv .ne. 0) then
write(2, '(a,i2)') '$',stdcurv
else
do i=1,np,ncolumn
call pack(line, l, x(i), y(i), i-1, min(ncolumn,np-i+1))
write(2,'(a)') line(1:l)
enddo
call pack(line, l, 0.0, 0.0, np, 1)
write(2,'(a)') line(1:l)
endif
close(2)
999 continue
if (errstat .gt. 0) then
if (name.eq.' ') name='<unknown>'
nlist=nlist+1
if (errstat .gt. 1) then
list(nlist)='error in '//file(1:lf)//', curve '//name
if (verbose) print *,'no curve file written'
lin=-1
else
list(nlist)='warning in '//file(1:lf)//', curve '//name
endif
endif
if (eof) lin=-1
return
end
integer function lsc_getno(list, n, name)
integer n
character list(n)*(*), name*(*)
character str*32
integer i,l
call str_trim(name, name, l)
l=min(l,len(str))
do i=1,n
call str_upcase(str(1:l), list(i))
if (name(1:l) .eq. str(1:l)) then
lsc_getno=i
RETURN
endif
enddo
lsc_getno=0
end
subroutine lsc_errinit(lunit)
include 'conv.inc'
integer lunit
lun=lunit
pos=0
errstat=0
end
subroutine lsc_error(lin, text)
include 'conv.inc'
integer lin
character text*(*)
integer i,l
character line*132
if (pos .eq. 0) then
print *
endif
if (lin .gt. pos) then
rewind lun
do i=1,lin-1
read(lun, '(a)', end=8) line
call str_trim(line, line, l)
if (i .gt. max(pos,lin-3)) then
print '(5x,a)',line(1:l)
endif
enddo
read(lun, '(a)', end=8) line
call str_trim(line, line, l)
print '(x,2a)','>>> ',line(1:l)
8 pos=lin
errstat=2
endif
9 print '(x,a)', text
end