read_mqc_file Subroutine

public subroutine read_mqc_file(filename, config, error)

Read and parse a .mqc format input file

Arguments

Type IntentOptional Attributes Name
character(len=*), intent(in) :: filename
type(mqc_config_t), intent(out) :: config
type(error_t), intent(out) :: error

Calls

proc~~read_mqc_file~~CallsGraph proc~read_mqc_file read_mqc_file interface~parse_aimd_section parse_aimd_section proc~read_mqc_file->interface~parse_aimd_section interface~parse_connectivity_section parse_connectivity_section proc~read_mqc_file->interface~parse_connectivity_section interface~parse_driver_section parse_driver_section proc~read_mqc_file->interface~parse_driver_section interface~parse_fragmentation_section parse_fragmentation_section proc~read_mqc_file->interface~parse_fragmentation_section interface~parse_fragments_section parse_fragments_section proc~read_mqc_file->interface~parse_fragments_section interface~parse_geometry_section parse_geometry_section proc~read_mqc_file->interface~parse_geometry_section interface~parse_hessian_section parse_hessian_section proc~read_mqc_file->interface~parse_hessian_section interface~parse_model_section parse_model_section proc~read_mqc_file->interface~parse_model_section interface~parse_molecules_section parse_molecules_section proc~read_mqc_file->interface~parse_molecules_section interface~parse_scf_section parse_scf_section proc~read_mqc_file->interface~parse_scf_section interface~parse_schema_section parse_schema_section proc~read_mqc_file->interface~parse_schema_section interface~parse_structure_section parse_structure_section proc~read_mqc_file->interface~parse_structure_section interface~parse_system_section parse_system_section proc~read_mqc_file->interface~parse_system_section interface~parse_xtb_section parse_xtb_section proc~read_mqc_file->interface~parse_xtb_section proc~error_add_context error_t%error_add_context proc~read_mqc_file->proc~error_add_context proc~error_has_error error_t%error_has_error proc~read_mqc_file->proc~error_has_error proc~error_set error_t%error_set proc~read_mqc_file->proc~error_set proc~skip_to_end skip_to_end proc~read_mqc_file->proc~skip_to_end proc~parse_aimd_section parse_aimd_section interface~parse_aimd_section->proc~parse_aimd_section proc~parse_connectivity_section parse_connectivity_section interface~parse_connectivity_section->proc~parse_connectivity_section proc~parse_driver_section parse_driver_section interface~parse_driver_section->proc~parse_driver_section proc~parse_fragmentation_section parse_fragmentation_section interface~parse_fragmentation_section->proc~parse_fragmentation_section proc~parse_fragments_section parse_fragments_section interface~parse_fragments_section->proc~parse_fragments_section proc~parse_geometry_section parse_geometry_section interface~parse_geometry_section->proc~parse_geometry_section proc~parse_hessian_section parse_hessian_section interface~parse_hessian_section->proc~parse_hessian_section proc~parse_model_section parse_model_section interface~parse_model_section->proc~parse_model_section proc~parse_molecules_section parse_molecules_section interface~parse_molecules_section->proc~parse_molecules_section proc~parse_scf_section parse_scf_section interface~parse_scf_section->proc~parse_scf_section proc~parse_schema_section parse_schema_section interface~parse_schema_section->proc~parse_schema_section proc~parse_structure_section parse_structure_section interface~parse_structure_section->proc~parse_structure_section proc~parse_system_section parse_system_section interface~parse_system_section->proc~parse_system_section proc~parse_xtb_section parse_xtb_section interface~parse_xtb_section->proc~parse_xtb_section proc~skip_to_end->proc~error_set proc~strip_comment strip_comment proc~skip_to_end->proc~strip_comment proc~parse_aimd_section->proc~error_set proc~parse_aimd_section->proc~strip_comment interface~parse_connectivity_generic parse_connectivity_generic proc~parse_connectivity_section->interface~parse_connectivity_generic proc~parse_driver_section->proc~error_set proc~parse_driver_section->proc~strip_comment proc~calc_type_from_string calc_type_from_string proc~parse_driver_section->proc~calc_type_from_string proc~parse_fragmentation_section->proc~error_add_context proc~parse_fragmentation_section->proc~error_has_error proc~parse_fragmentation_section->proc~error_set proc~parse_fragmentation_section->proc~strip_comment proc~validate_cutoffs validate_cutoffs proc~parse_fragmentation_section->proc~validate_cutoffs interface~parse_fragments_generic parse_fragments_generic proc~parse_fragments_section->interface~parse_fragments_generic interface~parse_geometry_generic parse_geometry_generic proc~parse_geometry_section->interface~parse_geometry_generic proc~parse_hessian_section->proc~error_set proc~parse_hessian_section->proc~strip_comment proc~parse_model_section->proc~error_set proc~parse_model_section->proc~strip_comment proc~parse_method_string parse_method_string proc~parse_model_section->proc~parse_method_string proc~parse_molecules_section->proc~error_add_context proc~parse_molecules_section->proc~error_has_error proc~parse_molecules_section->proc~error_set proc~parse_molecules_section->proc~skip_to_end proc~parse_molecules_section->proc~strip_comment proc~parse_single_molecule parse_single_molecule proc~parse_molecules_section->proc~parse_single_molecule proc~parse_scf_section->proc~error_set proc~parse_scf_section->proc~strip_comment proc~parse_schema_section->proc~error_set proc~parse_schema_section->proc~strip_comment interface~parse_structure_generic parse_structure_generic proc~parse_structure_section->interface~parse_structure_generic proc~parse_system_section->proc~error_set proc~parse_system_section->proc~strip_comment proc~parse_xtb_section->proc~error_set proc~parse_xtb_section->proc~strip_comment proc~parse_connectivity_generic parse_connectivity_generic interface~parse_connectivity_generic->proc~parse_connectivity_generic proc~parse_fragments_generic parse_fragments_generic interface~parse_fragments_generic->proc~parse_fragments_generic proc~parse_geometry_generic parse_geometry_generic interface~parse_geometry_generic->proc~parse_geometry_generic proc~parse_structure_generic parse_structure_generic interface~parse_structure_generic->proc~parse_structure_generic proc~method_type_from_string method_type_from_string proc~parse_method_string->proc~method_type_from_string proc~parse_single_molecule->proc~error_add_context proc~parse_single_molecule->proc~error_has_error proc~parse_single_molecule->proc~error_set proc~parse_single_molecule->proc~skip_to_end proc~parse_single_molecule->proc~strip_comment proc~parse_molecule_connectivity parse_molecule_connectivity proc~parse_single_molecule->proc~parse_molecule_connectivity proc~parse_molecule_fragments parse_molecule_fragments proc~parse_single_molecule->proc~parse_molecule_fragments proc~parse_molecule_geometry parse_molecule_geometry proc~parse_single_molecule->proc~parse_molecule_geometry proc~parse_molecule_structure parse_molecule_structure proc~parse_single_molecule->proc~parse_molecule_structure proc~validate_cutoffs->proc~error_set proc~parse_connectivity_generic->proc~error_set proc~parse_connectivity_generic->proc~skip_to_end proc~parse_connectivity_generic->proc~strip_comment proc~parse_fragments_generic->proc~error_add_context proc~parse_fragments_generic->proc~error_has_error proc~parse_fragments_generic->proc~error_set proc~parse_fragments_generic->proc~skip_to_end proc~parse_fragments_generic->proc~strip_comment proc~parse_fragment parse_fragment proc~parse_fragments_generic->proc~parse_fragment proc~parse_geometry_generic->proc~error_set proc~parse_geometry_generic->proc~strip_comment proc~parse_molecule_connectivity->interface~parse_connectivity_generic proc~parse_molecule_fragments->interface~parse_fragments_generic proc~parse_molecule_geometry->interface~parse_geometry_generic proc~parse_molecule_structure->interface~parse_structure_generic proc~parse_structure_generic->proc~error_set proc~parse_structure_generic->proc~strip_comment

Called by

proc~~read_mqc_file~~CalledByGraph proc~read_mqc_file read_mqc_file program~main main program~main->proc~read_mqc_file

Variables

Type Visibility Attributes Name Initial
logical, private :: file_exists
integer, private :: io_stat
character(len=MAX_LINE_LEN), private :: line
type(error_t), private :: parse_error
integer, private :: unit

Source Code

   subroutine read_mqc_file(filename, config, error)
      !! Read and parse a .mqc format input file
      character(len=*), intent(in) :: filename
      type(mqc_config_t), intent(out) :: config
      type(error_t), intent(out) :: error

      integer :: unit, io_stat
      character(len=MAX_LINE_LEN) :: line
      logical :: file_exists
      type(error_t) :: parse_error

      inquire (file=filename, exist=file_exists)
      if (.not. file_exists) then
         call error%set(ERROR_IO, "Input file not found: "//trim(filename))
         return
      end if

      open (newunit=unit, file=filename, status='old', action='read', iostat=io_stat)
      if (io_stat /= 0) then
         call error%set(ERROR_IO, "Error opening input file: "//trim(filename))
         return
      end if

      ! Set defaults
      config%log_level = "info"

      ! Read file line by line and dispatch to section parsers
      do
         read (unit, '(A)', iostat=io_stat) line
         if (io_stat /= 0) exit

         line = adjustl(line)
         if (len_trim(line) == 0) cycle
         if (line(1:1) == '#' .or. line(1:1) == '!') cycle

         ! Check for section start
         if (line(1:1) == '%') then
            select case (trim(line))
            case ('%schema')
               call parse_schema_section(unit, config, parse_error)
            case ('%model')
               call parse_model_section(unit, config, parse_error)
            case ('%driver')
               call parse_driver_section(unit, config, parse_error)
            case ('%structure')
               call parse_structure_section(unit, config, parse_error)
            case ('%geometry')
               call parse_geometry_section(unit, config, parse_error)
            case ('%fragments')
               call parse_fragments_section(unit, config, parse_error)
            case ('%connectivity')
               call parse_connectivity_section(unit, config, parse_error)
            case ('%scf')
               call parse_scf_section(unit, config, parse_error)
            case ('%xtb')
               call parse_xtb_section(unit, config, parse_error)
            case ('%hessian')
               call parse_hessian_section(unit, config, parse_error)
            case ('%aimd')
               call parse_aimd_section(unit, config, parse_error)
            case ('%fragmentation')
               call parse_fragmentation_section(unit, config, parse_error)
            case ('%system')
               call parse_system_section(unit, config, parse_error)
            case ('%molecules')
               call parse_molecules_section(unit, config, parse_error)
            case default
               ! Skip unknown sections
               call skip_to_end(unit, parse_error)
            end select

            if (parse_error%has_error()) then
               error = parse_error
               call error%add_context("mqc_config_parser:read_mqc_file")
               close (unit)
               return
            end if
         end if
      end do

      close (unit)

      ! Validate required fields
      if (.not. allocated(config%schema_name)) then
         call error%set(ERROR_VALIDATION, "Missing required section: %schema")
         return
      end if

      ! Validate geometry: required for single-molecule mode, not for multi-molecule mode
      if (config%nmol == 0) then
         ! Single molecule mode: require top-level geometry
         if (.not. allocated(config%geometry%coords) .or. config%geometry%natoms == 0) then
            call error%set(ERROR_VALIDATION, "Missing required section: %geometry")
            return
         end if
      else
         ! Multi-molecule mode: each molecule must have geometry (validated during parsing)
         ! No additional validation needed here
      end if

   end subroutine read_mqc_file