Skip to content

Commit

Permalink
Add support for reading QCSchema JSON
Browse files Browse the repository at this point in the history
- allow automatic detection of jsonfortran installations via CMake
- subproject fallback support for meson
  • Loading branch information
awvwgk committed Jan 16, 2022
1 parent e401fa3 commit 97c0780
Show file tree
Hide file tree
Showing 30 changed files with 577 additions and 7 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ jobs:
if: ${{ matrix.build == 'fpm' }}
uses: fortran-lang/setup-fpm@v3
with:
fpm-version: 'v0.2.0'
fpm-version: 'v0.3.0'

- name: Prepare for cache restore
if: ${{ matrix.compiler == 'intel' }}
Expand Down
18 changes: 18 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ include(GNUInstallDirs)
# General configuration information
add_subdirectory("config")

# Dependencies
if(NOT TARGET "jsonfortran::jsonfortran" AND WITH_JSON)
find_package("jsonfortran" REQUIRED)
endif()

# Collect source of the project
set(srcs)
add_subdirectory("src")
Expand All @@ -36,6 +41,18 @@ add_library(
"${PROJECT_NAME}-lib"
"${srcs}"
)
target_compile_definitions(
"${PROJECT_NAME}-lib"
PRIVATE
"WITH_JSON=$<BOOL:${WITH_JSON}>"
)
if(WITH_JSON)
target_link_libraries(
"${PROJECT_NAME}-lib"
PRIVATE
"jsonfortran::jsonfortran"
)
endif()
set_target_properties(
"${PROJECT_NAME}-lib"
PROPERTIES
Expand All @@ -48,6 +65,7 @@ set_target_properties(
target_include_directories(
"${PROJECT_NAME}-lib"
PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/${module-dir}>
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@

To build this project from the source code in this repository you need to have
a Fortran compiler supporting Fortran 2008 and one of the supported build systems:
- [meson](https://mesonbuild.com) version 0.53 or newer, with
- [meson](https://mesonbuild.com) version 0.55 or newer, with
a build-system backend, *i.e.* [ninja](https://ninja-build.org) version 1.7 or newer
- [cmake](https://cmake.org) version 3.14 or newer, with
a build-system backend, *i.e.* [ninja](https://ninja-build.org) version 1.10 or newer
- [fpm](https://github.com/fortran-lang/fpm) version 0.2.0 or newer
- [fpm](https://github.com/fortran-lang/fpm) version 0.3.0 or newer

Currently this project supports GCC, Intel and PGI/NVHPC compilers.

Expand Down
20 changes: 20 additions & 0 deletions config/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,22 @@
option(BUILD_SHARED_LIBS "Whether the libraries built should be shared" FALSE)

option(WITH_OpenMP "Enable support for shared memory parallelisation with OpenMP" TRUE)
option(WITH_JSON "Enable support for JSON parsing via json-fortran" FALSE)

set(
module-dir
"${PROJECT_NAME}/${CMAKE_Fortran_COMPILER_ID}-${CMAKE_Fortran_COMPILER_VERSION}"
)
set(module-dir "${module-dir}" PARENT_SCOPE)

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}" PARENT_SCOPE)
install(
DIRECTORY
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
)

# Set build type as CMake does not provide defaults
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
set(
Expand Down Expand Up @@ -53,6 +62,17 @@ install(
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
)

if(BUILD_SHARED_LIBS)
set(PKG_CONFIG_REQUIRES "Requires.private")
else()
set(PKG_CONFIG_REQUIRES "Requires")
endif()
if(WITH_JSON)
set(PKG_CONFIG_REQUIREMENTS "json-fortran")
else()
set(PKG_CONFIG_REQUIREMENTS)
endif()

configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/template.pc"
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc"
Expand Down
30 changes: 30 additions & 0 deletions config/cmake/Findjsonfortran.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# This file is part of mctc-lib.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

if(NOT TARGET "jsonfortran::jsonfortran")
# json-fortran tries to make it hard to get found
string(TOLOWER "jsonfortran-${CMAKE_Fortran_COMPILER_ID}" jsonfortran)
find_package("${jsonfortran}" CONFIG)
add_library("jsonfortran::jsonfortran" IMPORTED INTERFACE)
target_link_libraries(
"jsonfortran::jsonfortran"
INTERFACE
"jsonfortran$<$<NOT:$<BOOL:${BUILD_SHARED_LIBS}>>:-static>"
)
target_include_directories(
"jsonfortran::jsonfortran"
INTERFACE
"${jsonfortran_INCLUDE_DIRS}"
)
endif()
11 changes: 11 additions & 0 deletions config/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,14 @@ if get_option('openmp')
omp_dep = dependency('openmp')
lib_deps += omp_dep
endif

jsonfortran_dep = dependency(
'json-fortran',
required: get_option('json'),
fallback: ['json-fortran-8.2.5','jsonfortran_dep'],
default_options: [
'default_library=static',
],
static: get_option('default_library') != 'dynamic',
)
lib_deps += jsonfortran_dep
5 changes: 5 additions & 0 deletions config/template.cmake
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
@PACKAGE_INIT@

set("@PROJECT_NAME@_WITH_OpenMP" @WITH_OpenMP@)
set("@PROJECT_NAME@_WITH_JSON" @WITH_JSON@)

if(NOT TARGET "@PROJECT_NAME@::@PROJECT_NAME@")
include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@-targets.cmake")
Expand All @@ -10,4 +11,8 @@ if(NOT TARGET "@PROJECT_NAME@::@PROJECT_NAME@")
if(NOT TARGET "OpenMP::OpenMP_Fortran" AND "@PROJECT_NAME@_WITH_OpenMP")
find_dependency("OpenMP")
endif()

if(NOT TARGET "jsonfortran::jsonfortran" AND "@PROJECT_NAME@_WITH_JSON")
find_dependency("jsonfortran")
endif()
endif()
1 change: 1 addition & 0 deletions config/template.pc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@

Name: @PROJECT_NAME@
Description: @PROJECT_DESCRIPTION@
@PKG_CONFIG_REQUIRES@: @PKG_CONFIG_REQUIREMENTS@
Version: @PROJECT_VERSION@
Libs: -L${libdir} -l@PROJECT_NAME@
Cflags: -I${includedir} -I${includedir}/@module-dir@
94 changes: 94 additions & 0 deletions doc/format-qcschema.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
---
title: QCSchema JSON
---

## Specification

@Note [Reference](https://molssi-qc-schema.readthedocs.io)

JSON files are identified by the extension ``json`` and parsed following the ``qcschema_molecule`` or ``qcschema_input`` format.
The ``molecule`` entry from a ``qcschema_input`` will be extracted, but there is no guarantee that the input information will be used by the program.


## Example

Caffeine molecule in ``qcschema_molecule`` format.


```json
{
"schema_version": 2,
"schema_name": "qcschema_molecule",
"provenance": {
"creator": "mctc-lib",
"version": "0.2.3",
"routine": "mctc_io_write_qcschema::write_qcschema"
},
"symbols": [
"C", "N", "C", "N", "C", "C", "C", "O", "N", "C", "O", "N",
"C", "C", "H", "H", "H", "H", "H", "H", "H", "H", "H", "H"
],
"geometry": [
2.0280536328008760E+00, 9.2407587256767454E-02,-1.4305223630546618E-01,
4.7502035191684326E+00, 2.3810543955731494E-02,-1.4324120887654343E-01,
6.3343605825088858E+00, 2.0709504064354083E+00,-1.4229634602115726E-01,
8.7286430580574415E+00, 1.3800666865770403E+00,-1.4267429116331171E-01,
8.6532430021976250E+00,-1.1931728137816557E+00,-1.4229634602115726E-01,
6.2385514889727283E+00,-2.0836115686975827E+00,-1.4210737345008001E-01,
5.6327054260991156E+00,-4.6995588701197342E+00,-1.3946175745499875E-01,
3.4493163398727531E+00,-5.4809604515240968E+00,-1.4324120887654343E-01,
7.7750874644017181E+00,-6.2442206661050452E+00,-1.3114696432760045E-01,
1.0302217657417570E+01,-5.3974345751079591E+00,-1.3681614145991747E-01,
1.2074024483837716E+01,-6.9158291837135346E+00,-1.3662716888884024E-01,
1.0700382864677302E+01,-2.7907469296685923E+00,-1.4154045573684831E-01,
1.3246032369658721E+01,-1.7697281281382971E+00,-1.4210737345008001E-01,
7.4088586216540389E+00,-8.9590006222005893E+00,-1.1640710378357619E-01,
1.3870586717068980E+00, 2.0558326007492296E+00,-1.4172942830792554E-01,
1.3462405963542154E+00,-8.6360464982295970E-01, 1.5560001502499454E+00,
1.3462405963542154E+00,-8.6133697897003281E-01,-1.8434274308584184E+00,
5.6559490523416152E+00, 4.0016831651315083E+00,-1.4135148316577109E-01,
1.4674287061860456E+01,-3.2622334945062916E+00,-1.4343018144762065E-01,
1.3508893216027154E+01,-6.0811373372653921E-01, 1.5490081651200875E+00,
1.3507759380600691E+01,-6.0622400801576681E-01,-1.8320890765937843E+00,
5.4140641613627567E+00,-9.4924701903516215E+00,-1.1017100893802745E-01,
8.3191394965330758E+00,-9.7494728870166600E+00, 1.5654487788038070E+00,
8.3151710725404531E+00,-9.7685591166954602E+00,-1.7910820286700244E+00
],
"molecular_charge": 0,
"connectivity": [
[ 0, 1, 1],
[ 1, 2, 4],
[ 2, 3, 4],
[ 3, 4, 4],
[ 1, 5, 1],
[ 4, 5, 4],
[ 5, 6, 1],
[ 6, 7, 2],
[ 6, 8, 1],
[ 8, 9, 1],
[ 9,10, 2],
[ 4,11, 1],
[ 9,11, 1],
[11,12, 1],
[ 8,13, 1],
[ 0,14, 1],
[ 0,15, 1],
[ 0,16, 1],
[ 2,17, 1],
[12,18, 1],
[12,19, 1],
[12,20, 1],
[13,21, 1],
[13,22, 1],
[13,23, 1]
]
}
```


## Missing features

The schema is not verified on completeness and not all data is stored in the final structure type.

@Note Feel free to contribute support for missing features
or bring missing features to our attention by opening an issue.
1 change: 1 addition & 0 deletions doc/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ This library supports reading and writing of the following formats:
- [a subset of PDB format](./format-pdb.html)
- [DFTB+ general format](./format-gen.html)
- [Gaussian external format](./format-ein.html)
- [QCSchema JSON format](./format-qcschema.html)
3 changes: 3 additions & 0 deletions fpm.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,6 @@ author = ["Sebastian Ehlert"]
copyright = "2020-2021 Sebastian Ehlert"
description = "Modular computation tool chain library"
keywords = ["computational-chemistry", "io"]

[dependencies]
json-fortran.git = "https://github.com/jacobwilliams/json-fortran.git"
8 changes: 8 additions & 0 deletions include/mctc/defs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#ifndef mctc_defs_fh
#define mctc_defs_fh

#ifndef WITH_JSON
#define WITH_JSON 1
#endif

#endif
1 change: 1 addition & 0 deletions man/mctc-convert.1.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ Supported formats:
- Protein Database files, only single files (pdb)
- Connection table files, molfile (mol) and structure data format (sdf)
- Gaussian's external program input (ein)
- JSON input with `qcschema_molecule` or `qcschema_input` structure (json)


== Options
Expand Down
6 changes: 5 additions & 1 deletion meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ project(
'fortran',
version: '0.2.3',
license: 'Apache-2.0',
meson_version: '>=0.53',
meson_version: '>=0.55',
default_options: [
'buildtype=debugoptimized',
'default_library=both',
Expand All @@ -38,7 +38,11 @@ mctc_lib = library(
meson.project_name(),
sources: srcs,
version: meson.project_version(),
include_directories: include_directories('include'),
dependencies: lib_deps,
fortran_args: [
'-DWITH_JSON=@0@'.format(jsonfortran_dep.found() ? '1' : '0'),
],
install: install,
)

Expand Down
8 changes: 8 additions & 0 deletions meson_options.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,11 @@ option(
yield: true,
description: 'use OpenMP parallelisation',
)

option(
'json',
type: 'feature',
value: 'auto',
yield: true,
description: 'support JSON input',
)
2 changes: 1 addition & 1 deletion src/mctc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ list(
APPEND srcs
"${dir}/env.f90"
"${dir}/io.f90"
"${dir}/version.f90"
"${dir}/version.F90"
)

set(srcs "${srcs}" PARENT_SCOPE)
4 changes: 4 additions & 0 deletions src/mctc/io/read.f90
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ module mctc_io_read
use mctc_io_read_ctfile, only : read_molfile, read_sdf
use mctc_io_read_gaussian, only : read_gaussian_external
use mctc_io_read_genformat, only : read_genformat
use mctc_io_read_qcschema, only : read_qcschema
use mctc_io_read_pdb, only : read_pdb
use mctc_io_read_turbomole, only : read_coord
use mctc_io_read_vasp, only : read_vasp
Expand Down Expand Up @@ -143,6 +144,9 @@ subroutine get_structure_reader(reader, ftype)
case(filetype%molfile)
reader => read_molfile

case(filetype%qcschema)
reader => read_qcschema

case(filetype%pdb)
reader => read_pdb

Expand Down
1 change: 1 addition & 0 deletions src/mctc/io/read/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ list(
"${dir}/ctfile.f90"
"${dir}/gaussian.f90"
"${dir}/genformat.f90"
"${dir}/qcschema.F90"
"${dir}/pdb.f90"
"${dir}/turbomole.f90"
"${dir}/vasp.f90"
Expand Down
1 change: 1 addition & 0 deletions src/mctc/io/read/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ srcs += files(
'ctfile.f90',
'gaussian.f90',
'genformat.f90',
'qcschema.F90',
'pdb.f90',
'turbomole.f90',
'vasp.f90',
Expand Down
Loading

0 comments on commit 97c0780

Please sign in to comment.