Skip to content

Commit

Permalink
Additions to CREGEN, --ohess rruntype (crest-lab#263)
Browse files Browse the repository at this point in the history
  • Loading branch information
pprcht authored Feb 13, 2024
2 parents 3e14397 + 0e2e5bf commit 095514e
Show file tree
Hide file tree
Showing 22 changed files with 719 additions and 432 deletions.
246 changes: 179 additions & 67 deletions src/algos/ConfSolv.F90
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,18 @@ module ConfSolv_module
!> ConfSolv teardown instruction
logical :: cs_teardown = .false.
!> Keeping track of setup. Has it been called already?
logical :: cs_setup = .false.
logical :: cs_setup = .false.

!> ConfSolv parameter location
character(len=:),allocatable :: cs_param
!> ConfSolv solvent & smiles
character(len=:),allocatable :: cs_solvent
character(len=:),allocatable :: cs_solvfile
character(len=:),allocatable :: cs_smiles

!> n_threshold_mols
integer :: cs_n_threshold_mols = 1

!========================================================================================!
!========================================================================================!
contains !> MODULE PROCEDURES START HERE
Expand Down Expand Up @@ -96,9 +100,36 @@ subroutine cs_shutdown(io)
call kill(cs_pid,9,io)
deallocate (cs_pid)
end if
call cs_shutdown2(io)

end subroutine cs_shutdown

!=================================================!
subroutine cs_shutdown2(io)
use iomod
implicit none
integer,intent(out) :: io
integer :: ich,ro,pids
character(len=100) :: str
character(len=50) :: str2
call command('lsof confsolv.out > tmpcs 2>/dev/null',io)

open(newunit=ich,file='tmpcs')
do
read(ich,'(a)',iostat=ro) str
if(ro < 0 ) exit
!write(*,*) trim(str)
read(str,*,iostat=ro) str2,pids
if(ro == 0)then
! write(*,*) pids
call kill(pids,9,io)
endif
enddo
close(ich)

call remove('tmpcs')
end subroutine cs_shutdown2

!=================================================!

subroutine cs_deploy()
Expand All @@ -108,31 +139,31 @@ subroutine cs_deploy()
character(len=50) :: atmp
logical :: ex

if(.not.allocated(cs_bin)) cs_bin = 'confsolvserver'
call remove('confsolv.out')
if (.not.allocated(cs_bin)) cs_bin = 'confsolvserver'
!call remove('confsolv.out')
call remove('config_template.toml')

job = 'nohup '//trim(cs_bin)//' -l '//'> confsolv.out 2>/dev/null'//' &'

write(stdout,'(2x,a,a)') 'Hosting command: ',trim(job)
write (stdout,'(2x,a,a)') 'Hosting command: ',trim(job)
call command(job,io)

if(io /= 0) error stop '**ERROR** failed to host ConfSolv server'
if (io /= 0) error stop '**ERROR** failed to host ConfSolv server'
!call sleep(3)
do
do
call sleep(1)
inquire(file='config_template.toml',exist=ex)
if(ex) exit
enddo
inquire (file='config_template.toml',exist=ex)
if (ex) exit
end do

!> read port and pid
open(newunit=ich,file='confsolv.out')
read(ich,*) atmp,cs_pid
read(ich,*) atmp,cs_port
close(ich)
open (newunit=ich,file='confsolv.out')
read (ich,*) atmp,cs_pid
read (ich,*) atmp,cs_port
close (ich)
cs_teardown = .true.
cs_setup = .false.
write(stdout,'(2x,2(a,i0))') 'ConfSolv server will be running at http://localhost:',cs_port,' with PID ',cs_pid
write (stdout,'(2x,2(a,i0))') 'ConfSolv server will be running at http://localhost:',cs_port,' with PID ',cs_pid
end subroutine cs_deploy

!=================================================!
Expand All @@ -152,11 +183,15 @@ subroutine cs_write_config(ensname,threads)
if (allocated(cs_param)) then
call wrtoml(ich,'model_path',cs_param)
end if

call wrtoml(ich,'xyz_file',trim(atmp)//'/'//trim(ensname))
call wrtoml(ich,'solvent_file',trim(atmp)//'/'//'crest_solvents.csv')
if (allocated(cs_solvfile)) then
call wrtoml(ich,'solvent_file',trim(atmp)//'/'//cs_solvfile)
else
call wrtoml(ich,'solvent_file',trim(atmp)//'/'//'crest_solvents.csv')
end if

call wrtoml_int(ich,'n_threshold_mols',1)
call wrtoml_int(ich,'n_threshold_mols',cs_n_threshold_mols)
close (ich)
contains
subroutine wrtoml(ch,key,val)
Expand Down Expand Up @@ -314,13 +349,69 @@ subroutine cs_write_solvent_csv(solvent,smiles,ch)
case ('urea')
write (ich,'(a,",",a)') solvent,'NC(=O)N'
case default
write(stderr,'(2a)') '**ERROR** failed to find matching solvent SMILES for: ',solvent
write (stderr,'(2a)') '**ERROR** failed to find matching solvent SMILES for: ',solvent
error stop
end select
end if
close (ich)
end subroutine cs_write_solvent_csv

!========================================================================================!

subroutine confsolv_select_gsoln(nall,ncol,data,gsoln,mapping)
!************************************************
!* From the matrix of ΔΔGsoln, select the best
!* for each conformer and document which solvent
!* that corresponds to
!************************************************
implicit none
integer,intent(in) :: nall,ncol
real(wp),intent(in) :: data(ncol,nall)
real(wp),intent(out) :: gsoln(nall)
integer,intent(out) :: mapping(nall)
integer :: i,j,k,l,mink
real(wp) :: dum
mapping(:) = 0
gsoln(:) = huge(dum)
if (ncol < 3) then
!>--- ConfSolv should put out at least 3 csv columns. The first two are just IDs
write (stderr,'(a)') '**ERROR** dimension mismatch in ConfSolv data processing'
error stop
end if
do i = 1,nall
do j = 3,ncol
k = j-2
if (data(j,i) < gsoln(i)) then
mink = k
gsoln(i) = data(j,i)
end if
end do
mapping(i) = mink
end do
end subroutine confsolv_select_gsoln


subroutine confsolv_dump_gsoln(nall,ncol,gsoln,mapping,headers)
!****************************************************
!* Dump the selected ΔΔGsoln, and the corresponding
!* solvent for each conformer
!****************************************************
implicit none
integer,intent(in) :: nall,ncol
real(wp),intent(in) :: gsoln(nall)
integer,intent(in) :: mapping(nall)
character(len=*),intent(in) :: headers(ncol)
integer :: i,j,k,l,mink,ich
real(wp) :: dum
open(newunit=ich,file='confsolv.dat')
do i = 1,nall
k = mapping(i)+2
write(ich,'(f15.8,1x,a)') gsoln(i),trim(headers(k))
end do
close(ich)
end subroutine confsolv_dump_gsoln


!========================================================================================!
!========================================================================================!
end module ConfSolv_module
Expand All @@ -338,7 +429,7 @@ subroutine confsolv_request(ensname,nall,ncpus,gsoln,io)
!* nall - number of structures in ensemble
!* ncpus - number on cores to run on
!* gsoln - ΔΔGsoln for each structure
!* io - exit status
!* io - exit status
!***********************************************
use crest_parameters
use crest_data
Expand All @@ -359,103 +450,124 @@ subroutine confsolv_request(ensname,nall,ncpus,gsoln,io)
logical :: pr,wr
character(len=:),allocatable :: job
real(wp),allocatable :: column(:)
real(wp),allocatable :: data(:,:)
integer,allocatable :: mapping(:)
character(len=:),allocatable :: headers(:)
integer :: ncol,nrow
real(wp) :: avg

io = 0
gsoln(:) = 0.0_wp

!>--- setup
if (allocated(cs_pid).and.allocated(cs_port)) then
!> user-provided PID and port (no automatic teardown)
!> user-provided PID and port (no automatic teardown)
write (stdout,'(2x,a,i0,a,i0)') 'Looking for ConfSolv server (PID: ',cs_pid,') running at '//&
& 'http://localhost:',cs_port
!cs_teardown = .false.
!cs_teardown = .false.
else
!> fallback: automatic host (not recommended)
allocate(cs_pid,cs_port)
call cs_deploy()
!> fallback: automatic host (not recommended)
allocate (cs_pid,cs_port)
call cs_deploy()
end if
if (allocated(cs_param)) then
write (stdout,'(2x,a,/,3x,a)') 'pyTorch checkpoint files located at ',cs_param
else
write (stderr,*) '**ERROR** cannot run ConfSolv without defining checkpoint file location!'
error stop
end if
if (allocated(cs_solvent).and.allocated(cs_smiles)) then
write (stdout,'(2x,a,a,3a)') 'Requested ΔΔGsoln for ',cs_solvent,' (SMILES: ',trim(cs_smiles),')'
call cs_write_solvent_csv(cs_solvent,smiles=cs_smiles)
else if(allocated(cs_solvent))then
write (stdout,'(2x,a,a,a)') 'Requested ΔΔGsoln for ',cs_solvent,' (trying to find SMILES ...)'
call cs_write_solvent_csv(cs_solvent)
!> pass the user-defined solvents-csv, or do a single solvent
if (allocated(cs_solvfile)) then
write (stdout,'(2x,a,a)') 'Requested ΔΔGsoln for solvents in ',cs_solvfile
else
if (allocated(cs_solvent).and.allocated(cs_smiles)) then
write (stdout,'(2x,a,a,3a)') 'Requested ΔΔGsoln for ',cs_solvent,' (SMILES: ',trim(cs_smiles),')'
call cs_write_solvent_csv(cs_solvent,smiles=cs_smiles)
else if (allocated(cs_solvent)) then
write (stdout,'(2x,a,a,a)') 'Requested ΔΔGsoln for ',cs_solvent,' (trying to find SMILES ...)'
call cs_write_solvent_csv(cs_solvent)
end if
end if
write (stdout,'(2x,a,a)') 'Processing ensemble file ',trim(ensname)

!>---- creating the request configuration
write (stdout,'(2x,a)',advance='no') 'Writing config.toml file ...'
flush(stdout)
flush (stdout)
call cs_write_config(ensname,ncpus)
write(stdout,*) 'done.'

write (stdout,*) 'done.'

job = ''
job = trim(job)//' '//cs_bin//' -c config.toml'
!>----- this should only be called once:
if(.not.cs_setup)then
write(stdout,'(2x,a)',advance='no') 'Instructing ConfSolv model setup ...'
flush(stdout)
if (.not.cs_setup) then
write (stdout,'(2x,a)',advance='no') 'Instructing ConfSolv model setup ...'
flush (stdout)
call command(trim(job)//' -s >> confsolv.out 2>/dev/null',io)
if(io/=0)then
write(stdout,*)
write(stderr,'(a)')"**ERROR** failed request to ConfSolv server"
if (io /= 0) then
write (stdout,*)
write (stderr,'(a)') "**ERROR** failed request to ConfSolv server"
call cs_shutdown(io)
error stop
endif
end if
cs_setup = .true.
write(stdout,*) 'done.'
endif
write (stdout,*) 'done.'
end if

!>---- and then the actual evaluation
call remove('confsolv.csv')
call remove('confsolv_uncertainty.csv')
write(stdout,'(2x,a)',advance='no') 'Evaluation of ConfSolv D-MPNN ...'
flush(stdout)
write (stdout,'(2x,a)',advance='no') 'Evaluation of ConfSolv D-MPNN ...'
flush (stdout)
call command(trim(job)//' -r >> confsolv.out 2>/dev/null',io)
write(stdout,*) 'done.'
if(io/=0)then
write(stdout,*)
write(stderr,'(a)')"**ERROR** failed request to ConfSolv server"
write (stdout,*) 'done.'
if (io /= 0) then
write (stdout,*)
write (stderr,'(a)') "**ERROR** failed request to ConfSolv server"
call cs_shutdown(io)
error stop
endif
end if

!>--- read ΔΔGsoln
write(stdout,'(2x,a)',advance='no') 'Reading confsolv.csv ...'
flush(stdout)
call parse_csv_column_real('confsolv.csv',cs_solvent,column)
write(stdout,*) 'done.'
if(size(column,1) == nall)then
gsoln(:) = column(:)
write (stdout,'(2x,a)',advance='no') 'Reading confsolv.csv ...'
flush (stdout)
call parse_csv_allcolumns('confsolv.csv',data,cols=ncol,rows=nrow)
write (stdout,*) 'done.'
if (nrow == nall) then
allocate(mapping(nall))
call confsolv_select_gsoln(nall,ncol,data,gsoln,mapping)
call parse_csv_file_row('confsolv.csv',1,headers)
call confsolv_dump_gsoln(nall,ncol,gsoln,mapping,headers)
else
write(stdout,'(a)') '**ERROR** dimension mismatch in confsolv_request'
write (stdout,'(a)') '**ERROR** dimension mismatch in confsolv_request'
call cs_shutdown(io)
error stop
endif
end if

!>--- read uncertainty
write(stdout,'(2x,a)',advance='no') 'Reading confsolv_uncertainty.csv ...'
flush(stdout)
call parse_csv_column_real('confsolv_uncertainty.csv',cs_solvent,column)
write(stdout,*) 'done.'
if(size(column,1) == nall)then
avg = sum(column(:))/real(nall,wp)
write(stdout,'(2x,a,f25.15)') 'Average uncertainty of ConfSolv prediction:',avg
write (stdout,'(2x,a)',advance='no') 'Reading confsolv_uncertainty.csv ...'
flush (stdout)
call parse_csv_allcolumns('confsolv_uncertainty.csv',data)
write (stdout,*) 'done.'
if (size(data,2) == nall) then
avg = 0.0_wp
do i=1,nall
k=mapping(i) + 2
avg=avg+data(k,i)
enddo
avg = avg / real(nall,wp)
write (stdout,'(2x,a,f25.15)') 'Average uncertainty of ConfSolv prediction:',avg
else
write(stdout,'(a)') '**ERROR** dimension mismatch in confsolv_request'
write (stdout,'(a)') '**ERROR** dimension mismatch in confsolv_request'
call cs_shutdown(io)
error stop
endif
end if

if(allocated(column)) deallocate(column)
!call cs_shutdown2(i)

if (allocated(headers)) deallocate(headers)
if (allocated(data)) deallocate(data)
if (allocated(mapping)) deallocate(mapping)
if (allocated(column)) deallocate (column)
return
end subroutine confsolv_request

Expand Down
9 changes: 9 additions & 0 deletions src/algos/optimization.f90
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,15 @@ subroutine crest_optimization(env,tim)
deallocate (grad)
!========================================================================================!
call tim%stop(14)

!========================================================================================!
!>--- append numerical hessian calculation
if( io == 0 .and. env%crest_ohess )then
call env%ref%load(molnew) !> load the optimized geometry
call crest_numhess(env,tim) !> run the numerical hessian
endif

!========================================================================================!
return
end subroutine crest_optimization

Expand Down
Loading

0 comments on commit 095514e

Please sign in to comment.