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
97module mod_analyze
108implicit none
@@ -14,7 +12,7 @@ module mod_analyze
1412
1513CONTAINS
1614
17- ! The following function should respect the PBC conditions
15+ ! The following function also handles the PBC conditions
1816real * 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
154152call 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
164156select case (imod)
165157case (0 )
@@ -195,7 +187,7 @@ program analyze_movie
195187end if
196188
197189if (lecho) write (* ,* )' How many dihedrals?'
198- read (* , 10 , IOSTAT = iost) ndih
190+ read (* , ' (I3) ' , IOSTAT = iost) ndih
199191if (iost.ne. 0 ) call PrintInputError()
200192
201193if (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
534530end program
535531
536-
537-
538-
539-
540-
541-
542532
543533subroutine Get_cmdline (chmovie , nbin_dist , nbin_ang , nbin_dih , distmin , distmax , shiftdih , lecho , &
544534 imod , boxx , boxy , boxz )
545535implicit 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
548538integer ,intent (inout ) :: nbin_dist,nbin_ang,nbin_dih
549539integer , 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
555545i= 0
556546do 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
643639end 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