Skip to content

Commit 5fb5ccc

Browse files
committed
WIP: Improve analyze_movie, add optimal binning strategies
1 parent 37cbf65 commit 5fb5ccc

File tree

1 file changed

+65
-27
lines changed

1 file changed

+65
-27
lines changed

UTILS/analyze_movie.f90

Lines changed: 65 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
! Simple program for analysis of bonds, angles and dihedrals
2-
! from xyz trajectories.
3-
! We pull out time evolution as well as histograms.
2+
! from XYZ trajectories.
3+
! Writes out time evolution as well as histograms.
44

5-
! Daniel Hollas 2014
6-
7-
! 2016, RDF funcionality added
5+
! Author: Daniel Hollas
86

97
module mod_analyze
108
implicit none
@@ -14,7 +12,7 @@ module mod_analyze
1412

1513
CONTAINS
1614

17-
! The following function should respect the PBC conditions
15+
! The following function also handles the PBC conditions
1816
real*8 function get_distance( at1, at2, boxx, boxy, boxz)
1917
implicit none
2018
integer,intent(in) :: at1, at2
@@ -29,8 +27,8 @@ real*8 function get_distance( at1, at2, boxx, boxy, boxz)
2927
dx = x(at1) - x(at2)
3028
dy = y(at1) - y(at2)
3129
dz = z(at1) - z(at2)
32-
3330
end if
31+
3432
if (boxx.gt.0)then
3533
dx = dx - boxx * nint(dx/boxx)
3634
dy = dy - boxy * nint(dy/boxy)
@@ -154,12 +152,6 @@ program analyze_movie
154152
call Get_cmdline(chmovie, nbin_dist, nbin_ang, nbin_dih, distmin, distmax, shiftdih, lecho, &
155153
imod, boxx, boxy, boxz)
156154

157-
! the following formats were not a good idea and are now obsolete
158-
10 format(I3)
159-
20 format(2I3)
160-
30 format(3I3)
161-
40 format(4I3)
162-
163155
! Now read from stdin, what to analyze
164156
select case (imod)
165157
case (0)
@@ -195,7 +187,7 @@ program analyze_movie
195187
end if
196188

197189
if (lecho) write(*,*)'How many dihedrals?'
198-
read(*, 10,IOSTAT = iost) ndih
190+
read(*, '(I3)', IOSTAT = iost) ndih
199191
if (iost.ne.0) call PrintInputError()
200192

201193
if (ndih.gt.0)then
@@ -361,6 +353,10 @@ program analyze_movie
361353

362354
r(idist) = get_distance(dists(1,idist), dists(2,idist), boxx, boxy, boxz)
363355

356+
! TODO: Put histograming at the end
357+
! so we can calculate optimal bin width based on Scott's rule
358+
! https://en.wikipedia.org/wiki/Histogram#Number_of_bins_and_width
359+
! and can calculate max and min data
364360
ipom = ceiling( ( (r(idist)) - distmin )/dx )
365361
if(ipom.gt.nbin_dist.or.ipom.le.0)then
366362
write(*,*)'Problems with bond distribution function'
@@ -477,7 +473,7 @@ program analyze_movie
477473
anorm=0.0d0
478474

479475
do ian=1,nbin_ang
480-
anorm=anorm+bins_ang(ian,idist)
476+
anorm = anorm + bins_ang(ian,idist)
481477
enddo
482478

483479
do ian=1,nbin_ang
@@ -533,24 +529,18 @@ program analyze_movie
533529

534530
end program
535531

536-
537-
538-
539-
540-
541-
542532

543533
subroutine Get_cmdline(chmovie, nbin_dist, nbin_ang, nbin_dih, distmin, distmax, shiftdih, lecho, &
544534
imod, boxx, boxy, boxz)
545535
implicit none
546-
real*8,intent(inout) :: distmin, distmax, boxx, boxy, boxz
547-
real*8,intent(inout) :: shiftdih
536+
real*8,intent(inout) :: distmin, distmax, boxx, boxy, boxz
537+
real*8,intent(inout) :: shiftdih
548538
integer,intent(inout) :: nbin_dist,nbin_ang,nbin_dih
549539
integer, intent(inout) :: imod
550-
character(len=100),intent(out) :: chmovie
551-
character(len=100) :: arg
552-
integer :: i
553-
logical, intent(inout) :: lecho
540+
character(len=100),intent(out) :: chmovie
541+
logical, intent(inout) :: lecho
542+
character(len=100) :: arg
543+
integer :: i, ngeom
554544

555545
i=0
556546
do while (i < command_argument_count())
@@ -587,6 +577,12 @@ subroutine Get_cmdline(chmovie, nbin_dist, nbin_ang, nbin_dih, distmin, distmax,
587577
i=i+1
588578
call get_command_argument(i, arg)
589579
read(arg,*)distmax
580+
case ('-optimal_nbin')
581+
i=i+1
582+
call get_command_argument(i, arg)
583+
read(arg,*)ngeom
584+
call print_bin_number_estimators(ngeom)
585+
stop 0
590586
case ('-box')
591587
i=i+1
592588
call get_command_argument(i, arg)
@@ -642,4 +638,46 @@ subroutine PrintInputError()
642638
stop 1
643639
end subroutine PrintInputError
644640

641+
! Various estimates to number of bins
642+
! See https://en.wikipedia.org/wiki/Histogram#Number_of_bins_and_width
643+
function square_root_bin_number(n) result(k)
644+
integer, intent(in) :: n
645+
integer :: k
646+
k = ceiling(sqrt(REAL(n)))
647+
end function square_root_bin_number
648+
649+
function sturges_bin_number(n) result(k)
650+
integer, intent(in) :: n
651+
integer :: k
652+
k = ceiling(log(REAL(n))/log(2.0d0)) + 1
653+
end function sturges_bin_number
654+
655+
function rice_bin_number(n) result(k)
656+
integer, intent(in) :: n
657+
integer :: k
658+
k = ceiling(2*(REAL(n)**(1/3.d0)))
659+
end function rice_bin_number
660+
661+
function scott_bin_width(n, sigma) result(h)
662+
integer, intent(in) :: n
663+
real*8, intent(in) :: sigma
664+
real*8 :: h
665+
h = 3.5d0 * sigma / n**(1/3.0d0)
666+
end function scott_bin_width
667+
668+
! TODO Freedman-Diaconis choice
669+
670+
671+
subroutine print_bin_number_estimators(ngeom)
672+
integer, intent(in) :: ngeom
673+
integer :: square_root_bin_number, sturges_bin_number, rice_bin_number
674+
675+
write(*,'(A)')'Printing various estimators for optimal number of bins'
676+
write(*,'(A)')'Square root estimate'
677+
write(*,'(A4,I5)')'k = ', square_root_bin_number(ngeom)
678+
write(*,'(A)')'Sturges estimate'
679+
write(*,'(A4,I5)')'k = ', sturges_bin_number(ngeom)
680+
write(*,'(A)')'Rice estimate'
681+
write(*,'(A4,I5)')'k = ', rice_bin_number(ngeom)
682+
end subroutine print_bin_number_estimators
645683

0 commit comments

Comments
 (0)