From 680247792db88d073aa36a775f0e1dd66b53a044 Mon Sep 17 00:00:00 2001 From: Anthony Scemama Date: Wed, 12 Nov 2014 11:25:13 +0100 Subject: [PATCH] Add documentation to extend qp_edit --- ocaml/README.rst | 6 ++ ocaml/README_qp_edit.rst | 220 +++++++++++++++++++++++++++++++++++++++ ocaml/qp_edit.ml | 21 ++-- 3 files changed, 233 insertions(+), 14 deletions(-) create mode 100644 ocaml/README_qp_edit.rst diff --git a/ocaml/README.rst b/ocaml/README.rst index 414428dd..2f33b268 100644 --- a/ocaml/README.rst +++ b/ocaml/README.rst @@ -4,3 +4,9 @@ Ocaml scripts This directory contains all the scripts that control the input/output with the user. + +All executables start with `qp_` and all tests start with `test_`. Modules +file names start with a capital letter. + +Info on how to extend the `qp_edit` tool is given in `README_qp_edit.rst`. + diff --git a/ocaml/README_qp_edit.rst b/ocaml/README_qp_edit.rst new file mode 100644 index 00000000..4525d21a --- /dev/null +++ b/ocaml/README_qp_edit.rst @@ -0,0 +1,220 @@ +Adding a new block +================== + +In this section, we assume we will add the `New_keyword` keyword. + +Create the `Input_new_keyword.ml` file +-------------------------------------- + +Copy for example the `Input_full_ci.ml` file as a starting point. + +The template is the following, where `r_x`, `r_y`, ..., `last_r` are the records +of the block. + +.. code-block:: ocaml + + module New_keyword : sig + type t = + { r_x : Type_of_x.t + r_y : Y_type.t + ... + last_r : bool + } with sexp + ;; + val read : unit -> t + val write : t -> unit + val to_string : t -> string + val to_rst : t -> Rst_string.t + val of_rst : Rst_string.t -> t + end = struct + type t = + { r_x : Type_of_x.t + r_y : Y_type.t + ... + last_r : bool + } with sexp + ;; + + let get_default = Qpackage.get_ezfio_default "new_keyword";; + + + ... + + end + +The following functions need to be defined:: + + val read : unit -> t + val write : t -> unit + val to_rst : t -> Rst_string.t + val of_rst : Rst_string.t -> t + + +The type `t` has to be defined in a same way in the `sig` and the `struct`. + +For each record of the type `t`, use types defined in the `Qptypes.ml` file as +much as possible. + +The `get_default` function will fetch the default values in the `ezfio_defaults` file +in the `new_keyword` block. + +For each record `r_x` of the type `t`, create a `read_r_x ()` function +and a `write_r_x r_x` function that performs the I/O in the EZFIO. +To set a default value in the `read_r_x` function, use the following template +(assuming that the `Type_of_x` is built from a `double precision` value in +the EZFIO file). + +.. code-block:: ocaml + + let read_r_x () = + if not (Ezfio.has_new_keyword_r_x ()) then + get_default "r_x" + |> Float.of_string + |> Ezfio.set_new_keyword_r_x + ; + Ezfio.get_new_keyword_r_x () + |> Type_of_x.of_float + ;; + + let write_r_x r_x = + Type_of_x.to_float r_x + |> Ezfio.set_new_keyword_r_x + ;; + + +Then, create a `read` and a `write` function as + +.. code-block:: ocaml + + let read () = + { r_x = read_r_x () ; + r_y = read_r_y () ; + ... + last_r = read_last_r () ; + } + ;; + + let write { r_x ; + r_y + ... + last_r ; + } = + write_r_x r_x; + write_r_y r_y; + ... + write_last_r last_r; + ;; + +Finally, create the functions to write an RST string as + +.. code-block:: ocaml + + let to_rst b = + Printf.sprintf " + You can put here some documentation as long as there is no equal sign. + The record entries should be indented on the right with a blank line + before and a blank line after, as they would be in a rst file. + + Here is the text for r_x + + r_x = %s + + And here is the text for r_y + + r_y = %s + + ... + Finally, the text for last_r + + last_r = %s + " + (Type_of_x.to_string b.r_x) + (Y_type.to_string b.r_y) + ... + (Bool.to_string b.last_r) + ;; + + +and you can use this function to read it back: + +.. code-block:: ocaml + + let of_rst s = + let s = Rst_string.to_string s + |> String.split ~on:'\n' + |> List.filter ~f:(fun line -> + String.contains line '=') + |> List.map ~f:(fun line -> + "("^( + String.tr line ~target:'=' ~replacement:' ' + )^")" ) + |> String.concat + in + Sexp.of_string ("("^s^")") + |> t_of_sexp + ;; + + + + + +Add module to `Input.ml` file +----------------------------- + +Append module to the `Input.ml` file. Use the name of the `Input_new_keyword.ml` without the +`.ml` suffix. + +.. code-block:: ocaml + + include Input_new_keyword;; + + +In the `qp_edit.ml` file +------------------------ + +vim search strings are given in brackets. + +1. (`/type keyword`) : Add a new entry to the keyword type corresponding to the block to add: + +.. code-block:: ocaml + + type keyword = + ... + | New_keyword + ;; + + + +2. (`/keyword_to_string`) : Add a new entry to the `keyword_to_string` function for the title of the block + +.. code-block:: ocaml + + let keyword_to_string = function + ... + | New_keyword -> "My new keyword" + ;; + + +3. (`/let get s`) : Add a new call to the to_rst function of the `Input.New_keyword` module + +.. code-block:: ocaml + + let get s = + let header = (make_header s) + and rst = match s with + ... + | New_keyword -> + Input.New_keyword.(to_rst (read ())) + ... + + +4. (`/let set s`) : Add a new call to the of_rst function of the `Input.New_keyword` module + +.. code-block:: ocaml + + match s with + ... + | New_keyword -> + Input.New_keyword.(write (of_rst str)) + ;; + diff --git a/ocaml/qp_edit.ml b/ocaml/qp_edit.ml index 9d151a1c..e8c93b9f 100644 --- a/ocaml/qp_edit.ml +++ b/ocaml/qp_edit.ml @@ -86,26 +86,19 @@ let set str s = | Mo_basis -> *) | Hartree_fock -> - Input.Hartree_fock.of_rst str - |> Input.Hartree_fock.write + Input.Hartree_fock.(write (of_rst str )) | Full_ci -> - Input.Full_ci.of_rst str - |> Input.Full_ci.write + Input.Full_ci.(write (of_rst str)) | Electrons -> - Input.Electrons.of_rst str - |> Input.Electrons.write + Input.Electrons.(write (of_rst str)) | Determinants -> - Input.Determinants.of_rst str - |> Input.Determinants.write + Input.Determinants.(write (of_rst str)) | Cisd_sc2 -> - Input.Cisd_sc2.of_rst str - |> Input.Cisd_sc2.write + Input.Cisd_sc2.(write (of_rst str)) | Nuclei -> - Input.Nuclei.of_rst str - |> Input.Nuclei.write + Input.Nuclei.(write (of_rst str)) | Bielec_integrals -> - Input.Bielec_integrals.of_rst str - |> Input.Bielec_integrals.write + Input.Bielec_integrals.(write (of_rst str)) (* | Ao_basis -> *)