read_molfile Subroutine

public subroutine read_molfile(self, unit, error)

Arguments

Type IntentOptional Attributes Name
type(structure_type), intent(out) :: self

Instance of the molecular structure data

integer, intent(in) :: unit

File handle

type(error_type), intent(out), allocatable :: error

Error handling


Source Code

subroutine read_molfile(self, unit, error)

   !> Instance of the molecular structure data
   type(structure_type), intent(out) :: self

   !> File handle
   integer, intent(in) :: unit

   !> Error handling
   type(error_type), allocatable, intent(out) :: error

   character(len=:), allocatable :: line
   character(len=:), allocatable :: comment
   integer :: stat, lnum, pos
   integer :: number_of_atoms, number_of_bonds
   integer :: list7(7), list12(12)
   real(wp) :: x, y, z
   character(len=2) :: sdf_dim
   logical :: two_dim, v3k
   type(token_type) :: token

   lnum = 0
   two_dim = .false.

   call next_line(unit, comment, pos, lnum, stat)
   call next_line(unit, line, pos, lnum, stat)
   read(line, '(20x, a2)', iostat=stat) sdf_dim
   if (stat == 0) then
      two_dim = sdf_dim == '2D' .or. sdf_dim == '2d'
   end if
   call next_line(unit, line, pos, lnum, stat)
   call next_line(unit, line, pos, lnum, stat)
   if (stat == 0) then
      token = token_type(1, 3)
      call read_token(line, token, number_of_atoms, stat)
   end if
   if (stat == 0) then
      token = token_type(4, 6)
      call read_token(line, token, number_of_bonds, stat)
   end if
   if (stat /= 0) then
      call io_error(error, "Cannot read header of molfile", &
         & line, token, filename(unit), lnum, "expected integer value")
      return
   end if
   token = token_type(35, 39)
   stat = 1
   if (len(line) >= 39) then
      v3k = line(35:39) == 'V3000'
      if (line(35:39) == 'V2000' .or. v3k) stat = 0
   end if

   if (stat /= 0) then
      call io_error(error, "Format version not supported", &
         & line, token, filename(unit), lnum, "invalid format version")
      return
   end if
   if (.not.v3k .and. number_of_atoms < 1) then
      call io_error(error, "Invalid number of atoms", &
         & line, token_type(1, 3), filename(unit), lnum, "expected positive integer")
      return
   end if

   if (v3k) then
      call read_molfile_v3k(self, unit, error)
   else
      call read_molfile_v2k(self, unit, number_of_atoms, number_of_bonds, error)
   end if
   if (allocated(error)) return

   ! Attach additional meta data
   self%info%two_dimensional = two_dim
   if (len(comment) > 0) self%comment = comment

end subroutine read_molfile