Files
fit/pgm/polcal.f
2022-08-19 15:22:33 +02:00

445 lines
11 KiB
Fortran

program polcal
c this program work, because the dat_tasmad_read routine is
c coding the polarisation information into the x-value ip.b
c where i is 1..9 for xx, yx, yz, zy, yy, zy, xz, yz, zz
c p is 1..4 for ++, +-, -+, --
c b is 0 for signal and 1 for background
implicit none
character files*1024
character bfiles*1024
character line*2048
character word*1024
integer l, pos
integer i
real xx(36), yy(36), ss(36)
real cnts(9,4,2), sigma(9,4,2)
integer n
character mukind*20
character single*1024
logical merge,bgr
integer listflag
real numor, mon, lastnumor
integer status
integer iostat
integer summary,sumx,sumy
common summary,sumx,sumy
call sys_get_cmdpar(line, l)
if (line .eq. ' ') then
print *
print *,'polcal calculates polarisation matrices from files ',
1 'measured with the'
print *,'polmat command on TASP/MuPAD'
print *
print *,'Usage:'
print *,
1 'polcal <numors> [-m] [-b <background numors>]'
print *
print *,'Options:'
print *
print *,' -m'
print *,' merge files'
print *,' without this option, for every file a polarisation'
print *,' matrix is calculated'
print *
print *,' -b'
print *,' treat numors given before -b as signal,'
print *,' numors after -b as background.'
print *,' the files are merged even without the -m option.'
print *,' without this option, polcal sorts out automatically'
print *,' signal and background files'
print *
print *,' -f'
print *,' make summary files fort.11 etc. with the'
print *,' matrix elements'
print *
print *,' -f1213'
print *,' make a summary of Pxy vs Pxz (output file fort.1)'
print *
goto 9
endif
c Argument processing
pos=1
files=' '
merge=.false.
summary=0
bgr=.false.
call str_get_word(line, pos, word)
1 do while (word .ne. ' ')
if (word .eq. '-b') then
call str_get_word(line, pos, bfiles)
bgr=.true.
merge=.true.
elseif (word .eq. '-m') then
merge=.true.
elseif (word(1:2) .eq. '-f') then
if (word(3:) .eq. ' ') then
summary=1
else
summary=2
sumx=0
sumy=0
read(word(3:4), *, iostat=iostat) sumx
read(word(5:6), *, iostat=iostat) sumy
endif
else
if (files .eq. ' ') then
files = word
else
call str_trim(files, files, l)
if (l .lt. len(files) - 1) then
l=l+1
files(l:l)=','
files(l+1:) = word
endif
endif
endif
call str_get_word(line, pos, word)
enddo
call sys_setenv('dat_defspec','TASP')
call fit_init_silent
call clr_me(cnts)
call clr_me(sigma)
if (merge) then
if (bgr) then
call fit_dat_silent
call fit_dat(files)
call fit_merge(0.2) ! merge signal and bgr
call fit_get_real('Monitor', mon)
call fit_get_array('X', xx, 36, n)
call fit_get_array('Y', yy, 36, n)
call fit_get_array('S', ss, 36, n)
call fill_me(cnts, xx, yy, n, 1) ! 1 = force to signal
call fill_me(sigma, xx, ss, n, 1)
call calc_pol(cnts, sigma, status)
if (status .eq. 0) then
print *,'NO DATA'
goto 9
else
call info_line(files, 'S', 1)
endif
call fit_dat_silent
call fit_dat(bfiles)
call fit_merge(0.2) ! merge signal and bgr
call fit_mon(mon)
call fit_get_array('X', xx, 36, n)
call fit_get_array('Y', yy, 36, n)
call fit_get_array('S', ss, 36, n)
call fill_me(cnts, xx, yy, n, 2) ! 2 = force to bgr
call fill_me(sigma, xx, ss, n, 2)
call calc_pol(cnts, sigma, status)
if (status .eq. 0) then
print *,'NO DATA'
else
call info_line(bfiles, 'B', 2)
endif
else
call fit_dat_silent
call fit_dat(files)
call fit_merge(0.01) ! do not merge signal and bgr
call fit_get_array('X', xx, 36, n)
call fit_get_array('Y', yy, 36, n)
call fit_get_array('S', ss, 36, n)
call fill_me(cnts, xx, yy, n, 0)
call fill_me(sigma, xx, ss, n, 0)
call calc_pol(cnts, sigma, status)
if (status .eq. 0) then
print *,'NO DATA'
else
call info_line(files, 'S', 1)
if (status .eq. 2) call info_line(files, 'B', 1)
endif
endif
else
listflag=0
lastnumor = -1
do i=1,99999
call fit_dat_silent
call fit_dat_next(files, listflag)
if (listflag .eq. 0) goto 9
mukind=' '
call fit_get_str('mukind', l, mukind)
if (mukind .ne. 'background') then
call clr_me(cnts)
call clr_me(sigma)
if (mukind .eq. ' ') goto 19
endif
call fit_get_array('X', xx, 36, n)
call fit_get_array('Y', yy, 36, n)
call fit_get_array('S', ss, 36, n)
call fill_me(cnts, xx, yy, n, 0)
call fill_me(sigma, xx, ss, n, 0)
call calc_pol(cnts, sigma, status)
if (status .eq. 0) goto 19
call fit_get_real('Numor', numor)
if (mukind .eq. 'background') then
if (lastnumor .eq. -1) then
print *,'WARNING: background only'
call cvtnumor(single, numor)
call info_line(single, ' ', 1)
else
call cvtnumor(single, lastnumor)
call cvtnumor(single, numor)
call info_line(single, 'B', 2)
endif
else
call cvtnumor(single, numor)
call info_line(single, ' ', 1)
lastnumor=numor
endif
19 continue
enddo
endif
9 end
subroutine cvtnumor(result, numor)
character result*(*)
real numor
integer l
write(result,'(f10.0)') numor
call str_first_nonblank(result, l)
result = result(l:9)
end
subroutine info_line(file, type, prthold)
character file*(*), type*(*)
integer prthold
character line1*132/' '/, line2*132/' '/
real vmin(5), vmax(5), mean(5), diff(5)
integer i,l
character line*132, label*4
logical secondline
if (prthold .eq. 2) then
if (line1(1:3) .eq. ' ') line1(1:3)='sig'
call str_trim(line1, line1, l)
print '(x,a)',line1(1:l)
call str_trim(line2, line2, l)
if (l .gt. 1) print '(x,a)',line2(1:l)
endif
do i=1,5
vmin(i)=0
vmax(i)=0
enddo
if (type .eq. 'B') then
call meta_real_range('QH', vmin(1), vmax(1))
call meta_real_range('QH_B', vmin(1), vmax(1))
call meta_real_range('QK', vmin(2), vmax(2))
call meta_real_range('QK_B', vmin(2), vmax(2))
call meta_real_range('QL', vmin(3), vmax(3))
call meta_real_range('QL_B', vmin(3), vmax(3))
call meta_real_range('EN', vmin(4), vmax(4))
call meta_real_range('EN_B', vmin(4), vmax(4))
call meta_real_range('TEMP', vmin(5), vmax(5))
call meta_real_range('TEMP_B', vmin(5), vmax(5))
label='bgr'
else
call meta_real_range('QH', vmin(1), vmax(1))
call meta_real_range('QH_S', vmin(1), vmax(1))
call meta_real_range('QK', vmin(2), vmax(2))
call meta_real_range('QK_S', vmin(2), vmax(2))
call meta_real_range('QL', vmin(3), vmax(3))
call meta_real_range('QL_S', vmin(3), vmax(3))
call meta_real_range('EN', vmin(4), vmax(4))
call meta_real_range('EN_S', vmin(4), vmax(4))
call meta_real_range('TEMP', vmin(5), vmax(5))
call meta_real_range('TEMP_S', vmin(5), vmax(5))
if (type .eq. 'S') then
label='sig'
else
label=' '
endif
endif
do i=1,5
mean(i) = 0.5 * (vmin(i) + vmax(i))
diff(i) = 0.5 * (vmax(i) - vmin(i))
enddo
! temperature tolerance 10 %
secondline = (diff(5) .gt. mean(5) * 0.1)
! q tolerance 0.003
do i=1,3
if (diff(i) .gt. 0.003) secondline = .true.
enddo
! en tolerance 0.01
if (diff(4) .gt. 0.01) secondline = .true.
call str_trim(file, file, l)
write(line1, '(2a,3f8.3,'' en:'',f8.2,'' T:'',f8.3,2a)')
1 label, 'q:', mean, ' file(s): ',file(1:l)
line2=' '
if (secondline) then
line=' '
do i=1,5
if (i .eq. 4) then
write(line(i*8-7:i*8), '(f8.2)') diff(i)
else
write(line(i*8-7:i*8), '(f8.3)') diff(i)
endif
enddo
write(line2,'(7a)') ' +/-',line(1:24),' +/-',line(25:32)
1 ,' +/-',line(33:40),' <-- mixed values!!!'
endif
if (prthold .gt. 0) then
call str_trim(line1, line1, l)
print '(x,a)',line1(1:l)
call str_trim(line2, line2, l)
if (l .gt. 1) print '(x,a)',line2(1:l)
endif
end
subroutine calc_pol(cnts, sigma, status)
implicit none
real cnts(9,4,2), sigma(9,4,2)
integer status
integer i,i1,i2,k,ip,im
real sum2, d2, sum, pij, dpij2, c1, c2, sq1, sq2
character line*80
real pm(3,4), sm(3,4)
logical done,bgr,matoutput
integer l
integer summary,sumx,sumy
common summary,sumx,sumy
real numor
status=0
matoutput = .false.
c k=1: normal polarity, k=2: NEG. polarity
do k=1,2
done = .false.
bgr = .false.
ip=k*2-1
im=k*2
do i1=1,3
sum2 = 0
d2 = 0
line=' '
do i2=1,3
i = (i1-1)*3 + i2
if (cnts(i,ip,2) .gt. 0 .or. cnts(i,im,2) .gt. 0) status=2
c1 = cnts(i, ip, 1) - cnts(i, ip, 2)
c2 = cnts(i, im, 1) - cnts(i, im, 2)
sq1 = sigma(i, ip, 1)**2 + sigma(i, ip, 2)**2
sq2 = sigma(i, im, 1)**2 + sigma(i, im, 2)**2
sum = c1 + c2
if (sum .eq. 0 .or.
1 cnts(i, ip, 1) .eq. 0 .and. cnts(i, im, 1) .eq. 0) then
pij=0
dpij2 = 1
else
done = .true.
pij = (c1 - c2) / sum
dpij2 = ((1-pij)/sum) ** 2 * sq1
dpij2 = dpij2 + ((1+pij)/sum) ** 2 * sq2
endif
pm(i1, i2) = pij
sm(i1, i2) = sqrt(dpij2)
sum2 = sum2 + pij*pij
d2 = d2 + dpij2 * pij * pij
enddo
pm(i1,4) = sqrt(sum2)
if (sum2 .eq. 0) then
sm(i1,4)=1
else
sm(i1,4) = sqrt(d2/sum2)
endif
enddo
if (done) then
matoutput = .true.
if (status .eq. 0) status=1
print *,
1'------------------------------------------------------'
call fit_get_str('Title', l, line)
if (k .eq. 2) then
print *,'NEG. polarity ',line(1:l)
else
print *,'normal polarity ',line(1:l)
endif
print *,' pix sigma piy sigma piz sigma'
1, ' |Pi| sigma'
do i1=1,3
line=' '
if (summary .eq. 1) call fit_get_real('numor', numor)
do i2=1,4
if (pm(i1, i2) .ne. 0 .or. sm(i1, i2) .ne. 1.0) then
write(line(i2*20-19:i2*20), '(2f7.3)') pm(i1, i2), sm(i1, i2)
endif
if (summary .eq. 1) then
write(i1*10+i2,*) numor, pm(i1,i2), sm(i1,i2)
endif
enddo
print *,line(1:78)
if (summary .eq. 2) then
write(1,*) pm(sumx/10, mod(sumx,10))
1 , pm(sumy/10, mod(sumy,10)),sm(sumy/10,mod(sumy,10))
endif
enddo
endif
enddo
if (.not. matoutput) then
print *,'WARNING: zero count matrix can not be calculated'
endif
end
subroutine clr_me(values)
real values(9,4,2)
integer i,j,k
do k=1,2
do j=1,4
do i=1,9
values(i,j,k)=0
enddo
enddo
enddo
end
subroutine fill_me(values, xx, yy, n, mode)
implicit none
integer n
integer mode
real values(9,4,2), xx(n), yy(n)
integer i,j,k,m,dbl
dbl=0
do m=1,n
i = nint(xx(m))
if (mode .ne. 0) then
k = mode
else if (abs(xx(m)-i) .lt. 0.05) then
k = 1
else
k = 2
endif
j=mod(i,10)
i=i/10
if (i .gt. 0 .and. i .le. 9 .and. j .gt. 0 .and. j .le. 4) then
if (values(i,j,k) .ne. 0) then
dbl=1
endif
values(i,j,k) = yy(m)
endif
enddo
if (dbl .ne. 0) then
print *,'WARNING: duplicate points skipped'
endif
end