dcdfort
Modern Fortran library for analyzing DCD trajectories
Data Types | Functions/Subroutines
dcdfort_trajectory Module Reference

Module that contains Trajectory type. More...

Data Types

type  trajectory
 Trajectory class. More...
 

Functions/Subroutines

subroutine trajectory_open (this, filename, ndxfile)
 Trajectory class method which opens DCD file and optionally index file. More...
 
pure integer(kind=int32) function trajectory_get_natoms (this, group)
 Trajectory class method which gets the number of atoms in the system or an index group. More...
 
integer(kind=int32) function trajectory_skip_next (this, F)
 Trajectory class method which skips a specified number of frames. More...
 
integer(kind=int32) function trajectory_read_next (this, F, ndxgrp, every)
 Trajectory class method which reads a specified number of frames into memory after using the open() method. More...
 
pure real(kind=real32) function, dimension(3) trajectory_get_xyz (this, frame, atom, group)
 Trajectory class method which returns the coordinates of a particle. More...
 
subroutine trajectory_read (this, dcdfile, ndxfile, ndxgrp, every, skip, last)
 Trajectory class method which opens, reads, and closes a trajectory file. More...
 
pure real(kind=real64) function, dimension(6) trajectory_get_box (this, frame)
 Trajectory class method which returns the box from a simulation frame. More...
 
subroutine trajectory_close (this)
 Trajectory class method which closes a DCD file which was opened with open() More...
 
pure real(kind=real64) function trajectory_vol (this, frame)
 Trajectory class method which returns the volume of the box. More...
 

Detailed Description

Module that contains Trajectory type.

Function/Subroutine Documentation

◆ trajectory_close()

subroutine dcdfort_trajectory::trajectory_close ( class(trajectory), intent(inout)  this)
private

Trajectory class method which closes a DCD file which was opened with open()

Parameters
[in,out]thisTrajectory class
391 
392  implicit none
393  class(Trajectory), intent(inout) :: this
394 
395  call this%dcd%close()
396 

◆ trajectory_get_box()

pure real(kind=real64) function, dimension(6) dcdfort_trajectory::trajectory_get_box ( class(trajectory), intent(in)  this,
integer(kind=int32), intent(in)  frame 
)
private

Trajectory class method which returns the box from a simulation frame.

Parameters
[in,out]thisTrajectory class
[in]frameWhich frame to return the box dimensions
Returns
box dimensions of specified snapshot. Array containing 6 elements, ordered as A, B, C, alpha, beta, gamma. A = length of unit cell vector along x-axis; B = length of unit cell vector in xy-plane; C = length of unit cell vector in yz-plane; alpha = cosine of angle between B and C; beta = cosine of angle between A and C; gamma = cosine of angle between A and B;
359 
360  implicit none
361  real(kind=real64) :: trajectory_get_box(6)
362  class(Trajectory), intent(in) :: this
363  integer(kind=int32), intent(in) :: frame
364  integer(kind=int32) :: i
365 
366  call trajectory_check_frame(this, frame)
367  do i = 1, 6
368  trajectory_get_box(i) = this%frameArray(frame)%box(i)
369  end do
370 

◆ trajectory_get_natoms()

pure integer(kind=int32) function dcdfort_trajectory::trajectory_get_natoms ( class(trajectory), intent(in)  this,
character(len=*), intent(in), optional  group 
)
private

Trajectory class method which gets the number of atoms in the system or an index group.

Parameters
[in,out]thisthe Trajectory object
[in]groupname of index group
Returns
number of atoms in index group (if specified) or in system
120 
121  implicit none
122  integer(kind=int32) :: trajectory_get_natoms
123  class(Trajectory), intent(in) :: this
124  character(len=*), intent(in), optional :: group
125 
126  if (this%read_only_index_group .and. present(group)) then
127  call error_stop_program("Do not specify an index group in natoms() when already specifying an &
128  &index group with read() or read_next().")
129  end if
130 
131  trajectory_get_natoms = merge(this%ndx%get_natoms(group), this%NUMATOMS, present(group))
132 

◆ trajectory_get_xyz()

pure real(kind=real32) function, dimension(3) dcdfort_trajectory::trajectory_get_xyz ( class(trajectory), intent(in)  this,
integer(kind=int32), intent(in)  frame,
integer(kind=int32), intent(in)  atom,
character(len=*), intent(in), optional  group 
)
private

Trajectory class method which returns the coordinates of a particle.

Gets the coordinates of a particle from the read in trajectory. Returns a real array with 3 elements (x, y, and z). An optional index group can be specified; if so, the atomid is in relationship to the group.

Parameters
[in,out]thisTrajectory class
[in]frame
[in]atomatomid of particle to get
[in]groupoptional index group
Returns
coordinate of the particle
267 
268  implicit none
269  real(kind=real32) :: trajectory_get_xyz(3)
270  integer(kind=int32), intent(in) :: frame, atom
271  integer(kind=int32) :: atom_tmp, natoms
272  class(Trajectory), intent(in) :: this
273  character(len=1024) :: message
274  character(len=*), intent(in), optional :: group
275 
276  call trajectory_check_frame(this, frame)
277 
278  if (this%read_only_index_group .and. present(group)) then
279  call error_stop_program("Do not specify an index group in x() when already specifying an &
280  &index group with read() or read_next().")
281  end if
282 
283  atom_tmp = merge(this%ndx%get(group, atom), atom, present(group))
284  natoms = merge(this%natoms(group), this%natoms(), present(group))
285 
286  if (atom > natoms .or. atom < 1) then
287  write(message, "(a,i0,a,i0,a)") "Tried to access atom number ", atom_tmp, " when there are ", &
288  natoms, ". Note that Fortran uses one-based indexing."
289  call error_stop_program(trim(message))
290  end if
291 
292  ! Faster to list individually
293  trajectory_get_xyz(1) = this%frameArray(frame)%xyz(atom_tmp,1)
294  trajectory_get_xyz(2) = this%frameArray(frame)%xyz(atom_tmp,2)
295  trajectory_get_xyz(3) = this%frameArray(frame)%xyz(atom_tmp,3)
296 

◆ trajectory_open()

subroutine dcdfort_trajectory::trajectory_open ( class(trajectory), intent(inout)  this,
character(len=*), intent(in)  filename,
character(len=*), intent(in), optional  ndxfile 
)

Trajectory class method which opens DCD file and optionally index file.

Parameters
[in,out]thisthe Trajectory object
[in]filenamename of DCD file
[in]ndxfilename of GROMACS style index file
89 
90  implicit none
91  class(Trajectory), intent(inout) :: this
92  character(len=*), intent(in) :: filename
93  character(len=*), intent(in), optional :: ndxfile
94 
95  call this%dcd%open(trim(filename))
96 
97  write(error_unit,'(a)') prompt//"Opened "//trim(filename)//" for reading."
98  call this%dcd%read_header(this%nframes, this%istart, this%nevery, this%iend, this%timestep, this%NUMATOMS)
99 
100  write(error_unit,'(a,i0,a)') prompt, this%NUMATOMS, " atoms present in system."
101  write(error_unit,'(a,i0,a)') prompt, this%NFRAMES, " frames present in trajectory file."
102  write(error_unit,'(a,i0)') prompt//"First timestep in trajectory file: ", this%ISTART
103  write(error_unit,'(a,i0)') prompt//"Last timestep in strajectory file: ", this%IEND
104  write(error_unit,'(a,f12.6)') prompt//"Simulation timestep: ", this%timestep
105  write(error_unit,'(a,i0,a)') prompt//"Trajectory written every ", this%nevery, " timesteps."
106 
107  this%FRAMES_REMAINING = this%NFRAMES
108 
109  this%N = this%NUMATOMS ! Save for use when user selects just one group
110  if (present(ndxfile)) call this%ndx%read(ndxfile, this%NUMATOMS)
111 

◆ trajectory_read()

subroutine dcdfort_trajectory::trajectory_read ( class(trajectory), intent(inout)  this,
character(len=*)  dcdfile,
character(len=*), optional  ndxfile,
character(len=*), optional  ndxgrp,
integer(kind=int32), intent(in), optional  every,
integer(kind=int32), intent(in), optional  skip,
integer(kind=int32), intent(in), optional  last 
)
private

Trajectory class method which opens, reads, and closes a trajectory file.

Parameters
[in,out]thisTrajectory class
[in]dcdfileName of DCD trajectory file
[in]ndxfileName of optional index file
[in]ndxgrpName of optional group. If specified, only that group will be read into memory; otherwise, all particles read into memory.
[in]everyRead in every this many frames; default is 1
[in]skipSkip this many frames at the beginning of the trajectory file; default is 0
[in]lastLast frame to read in
309 
310  implicit none
311  class(Trajectory), intent(inout) :: this
312  character(len=*), optional :: ndxfile, ndxgrp
313  character(len=*) :: dcdfile
314  integer(kind=int32) :: nread
315  integer(kind=int32), intent(in), optional :: every, skip, last
316 
317  call this%open(dcdfile, ndxfile)
318 
319  if (present(every)) then
320  write(error_unit,'(a,i0,a)') prompt//"Saving every ", every, " snapshots into memory."
321  end if
322  if (present(skip)) then
323  write(error_unit,'(a,i0,a)') prompt//"Skipping first ", skip, " snapshots."
324  end if
325  if (present(last)) then
326  write(error_unit,'(a,i0,a)') prompt//"Limiting to ", last, " snapshots."
327  end if
328 
329  if (present(skip)) then
330  nread = this%skip_next(skip)
331  if (present(last)) then
332  nread = this%read_next(last, ndxgrp, every)
333  else
334  nread = this%read_next(this%NFRAMES-nread, ndxgrp, every)
335  end if
336  else
337  if (present(last)) then
338  nread = this%read_next(last, ndxgrp, every)
339  else
340  nread = this%read_next(this%NFRAMES, ndxgrp, every)
341  end if
342  end if
343 
344  call this%close()
345 

◆ trajectory_read_next()

integer(kind=int32) function dcdfort_trajectory::trajectory_read_next ( class(trajectory), intent(inout)  this,
integer(kind=int32), intent(in), optional  F,
character(len=*), optional  ndxgrp,
integer(kind=int32), intent(in), optional  every 
)
private

Trajectory class method which reads a specified number of frames into memory after using the open() method.

Parameters
[in,out]thisTrajectory class
[in]Fframe number to read up to; if not specified, 1 frame is read
[in]ndxgrpread only this index group into memory
[in]everyRead in every this many frames; default is to read in every frame
Returns
number of frames read in
168 
169  implicit none
170  integer(kind=int32) :: trajectory_read_next
171  class(Trajectory), intent(inout) :: this
172  integer(kind=int32), intent(in), optional :: F, every
173  character(len=*), optional :: ndxgrp
174  integer(kind=int32) :: I, J, N, S, K
175  real(kind=real32), allocatable :: xyz(:,:)
176 
177  ! If the user specified how many frames to read and it is greater than one, use it
178  n = merge(f, 1, present(f))
179  s = merge(every, 1, present(every)) - 1
180 
181  ! Are we near the end of the file?
182  n = min(this%FRAMES_REMAINING, n)
183  this%FRAMES_REMAINING = this%FRAMES_REMAINING - n
184 
185  if (present(every)) n = n / every
186 
187  if (allocated(this%frameArray)) deallocate(this%frameArray)
188  allocate(this%frameArray(n))
189 
190  write(error_unit,*)
191 
192  this%read_only_index_group = .false.
193 
194  if (present(ndxgrp)) then
195 
196  allocate(xyz(this%N,3))
197  this%NUMATOMS = this%natoms(trim(ndxgrp))
198  do i = 1, n
199 
200  if (modulo(i*(s+1), 1000) .eq. 0) call print_frames_saved(i, ndxgrp)
201 
202  allocate(this%frameArray(i)%xyz(this%NUMATOMS,3))
203  call this%dcd%skip_next(s)
204  call this%dcd%read_next(xyz, this%frameArray(i)%box)
205 
206  do j = 1, size(this%ndx%group)
207  if (trim(this%ndx%group(j)%title) .eq. trim(ndxgrp)) then
208  ! Tends to be faster to list this out individually
209  do k = 1, this%NUMATOMS
210  this%frameArray(i)%xyz(k,1) = xyz(this%ndx%group(j)%LOC(k),1)
211  this%frameArray(i)%xyz(k,2) = xyz(this%ndx%group(j)%LOC(k),2)
212  this%frameArray(i)%xyz(k,3) = xyz(this%ndx%group(j)%LOC(k),3)
213  end do
214  exit
215  end if
216  end do
217 
218  end do
219  deallocate(xyz)
220 
221  this%read_only_index_group = .true.
222 
223  else
224 
225  do i = 1, n
226 
227  if (modulo(i*(s+1), 1000) .eq. 0) call print_frames_saved(i)
228 
229  allocate(this%frameArray(i)%xyz(this%NUMATOMS,3))
230  call this%dcd%skip_next(s)
231  call this%dcd%read_next(this%frameArray(i)%xyz, this%frameArray(i)%box)
232 
233  end do
234 
235  end if
236 
237  this%frames_read = n
238  trajectory_read_next = n
239  call print_frames_saved(n, ndxgrp)
240 

◆ trajectory_skip_next()

integer(kind=int32) function dcdfort_trajectory::trajectory_skip_next ( class(trajectory), intent(inout)  this,
integer(kind=int32), intent(in), optional  F 
)
private

Trajectory class method which skips a specified number of frames.

Parameters
[in,out]thisTrajectory class
[in]Fnumber of frames to skip; if not specified, 1 frame is skipped
Returns
number of frames skipped
141 
142  implicit none
143  class(Trajectory), intent(inout) :: this
144  integer(kind=int32), intent(in), optional :: F
145  integer(kind=int32) :: trajectory_skip_next, N
146 
147  ! If the user specified how many frames to read and it is greater than one, use it
148  n = merge(f, 1, present(f))
149 
150  ! Are we near the end of the file?
151  n = min(this%FRAMES_REMAINING, n)
152  this%FRAMES_REMAINING = this%FRAMES_REMAINING - n
153 
154  call this%dcd%skip_next(n)
155  write(error_unit,'(a,i0,a)') prompt//"Skipped ", n, " frames."
156  trajectory_skip_next = n
157 

◆ trajectory_vol()

pure real(kind=real64) function dcdfort_trajectory::trajectory_vol ( class(trajectory), intent(in)  this,
integer(kind=int32), intent(in)  frame 
)
private

Trajectory class method which returns the volume of the box.

Parameters
[in,out]thisTrajectory class
[in]framesnapshot to get box volume of
Returns
the volume of the box of the frame specified
404 
405  implicit none
406  class(Trajectory), intent(in) :: this
407  integer(kind=int32), intent(in) :: frame
408  real(kind=real64) :: trajectory_vol
409 
410  trajectory_vol = vol(this%box(frame))
411