Newer
Older
# documentation.org -- Pamhyr developers documentation
# Copyright (C) 2023 INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# -*- coding: utf-8 -*-
#+STARTUP: indent
#+INCLUDE: ../tools/macro.org
#+INCLUDE: ../tools/latex.org
#+TITLE: Developers documentation
#+SUBTITLE: Version: {{{version}}}
#+AUTHOR: {{{INRAE}}}
#+OPTIONS: toc:t
#+LANGUAGE: UKenglish
#+NAME: attr_wrap
#+HEADER: :var width="\\textwidth"
#+HEADER: :var caption=""
#+HEADER: :var smallcaption=""
#+HEADER: :var name=""
#+HEADER: :var data=""
#+HEADER: :var float="nil"
#+BEGIN_SRC sh :results output :exports none
echo "#+CAPTION[$smallcaption]: $caption"
echo "#+NAME: $name"
echo "#+ATTR_LATEX: :width $width :float $float"
echo "$data"
#+END_SRC
#+BEGIN_abstract
This document is for the use of developers. It describes the project
architecture, the tools available to assist development and
debugging. It also describes the procedures for creating packages and
the configurations required to set up the gitlab runners. Finally,
this document explains how documentation is written and modified, and
how to contribute to the project by modifying, improving or adding
documentation, translations or code.
#+END_abstract
* Introduction
Pamhyr2 is free and open source software (FOSS) graphical user
interface (GUI) for 1D hydro-sedimentary modelling of rivers developed
in Python (with version 3.8). It use PyQt at version 5 and matplotlib
in version 3.4.1 or later for the user insterface (see
{{{file(/requirements.txt)}}} for details). The architecture of
project code follow the Qt Model/View architecture [fn:qt-arch] (see
details in section [[Architecture]]). Pamhyr2 packages can be build
manually (see section [[Building packages]]), but there are automatically
build with the gitlab-ci (see the section [[Setup the CI
environment]]). Documentation files are written with org-mode[fn:org],
let see section [[Documentation files]]. Finally, to see the contribution
rules, see the section [[How to contribute?]].
[fn:qt-arch] Qt Model/View documentation:
https://doc.qt.io/qt-5/model-view-programming.html (last access
2023-09-15)
[fn:org] The org-mode website: https://orgmode.org/ (last access
2023-09-15)
* TODO Architecture
Pamhyr2's architecture is based on Qt Model/View, see Figure
[[graph-architecture]]. It is made up of several different components: the
model (in blue), the graphical components (in red), the
actions/delegates (in green), the commands (in purple), the solvers
(in yellow) and the save file (in grey).
The model is a set of python classes and can be exported to a single
SQLite3 format backup file. The view can be made up of various
components, generally a Qt window with other view components, such as:
a table, a text box, a button, a plot, and so on. The user can view
the data using the view and interact with certain components. These
components are linked to an action (such as a Python function) or to a
delegate class. These actions or delegate can create a command (based
on Qt UndoCommand class), this command must implement two functions:
One to modify the model, one to reverte this modification and reset
the model to previous state. All model modification must be perform by
a command to be cancelled. The user can also run a solver and add some
simulation results to model data.
#+name: graph-architecture
#+header: :results drawer
#+header: :exports results
#+header: :post attr_wrap(width="9cm", data=*this*, name="graph-architecture", caption="Pamhyr2 Model/View architecture scheme (inspired by Qt Model/View architecture [[https://doc.qt.io/qt-5/model-view-programming.html]])", float="t")
#+begin_src dot :file "images/graph-architecture.png" :cache no
digraph {
node[colorscheme=set19,shape=box,style="filled",fillcolor=white];
save[label="Pamhyr save",fillcolor="9",shape=note];
model[label="Model",fillcolor="2"];
view[label="View",fillcolor="1"];
delegate[label="Delegate",fillcolor="3"];
action[label="Action",fillcolor="3"];
solver[label="Solver",fillcolor="6"];
undocommand[label="Command",fillcolor="4"];
user[label="User",shape=ellipse];
model -> save[label="Save"];
save -> model[label="Load"];
model -> view[label="Rendering"];
view -> delegate[label="Rendering"];
delegate -> undocommand[label="Create"];
action -> undocommand[label="Create"];
action -> solver[label="Run"];
solver -> model[label="Add results"];
undocommand -> model[label="Modify"];
view -> user[label="Vizualize"];
user -> delegate[label="Modify"];
All the model source code are in the directory {{{file(src/Model)}}}
(let see section [[Model]] for more details), the View components,
delegate and command are in {{{file(src/View)}}} (see section [[View]]). Solvers classes are
in {{{file(src/Solver)}}} (see section [[Solver]]).
[fn:qt-mv] The Qt Model/View documentation web page:
https://doc.qt.io/qt-5/model-view-programming.html
** TODO Model
- Model de donnée Python
- Correspond à une sauvegarde SQL
#+name: graph-model
#+header: :results drawer
#+header: :exports results
#+header: :post attr_wrap(width="16cm", data=*this*, name="graph-model", caption="Pamhyr2 model class dependencies", float="t")
#+begin_src dot :file "images/graph-model.png" :cache no
digraph {
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
node[colorscheme=set19,shape=box,style="filled",fillcolor="2"];
study[label="Study"];
river[label="River"];
subgraph cluster00 {
label="Network"
rnode[label="RiverNode"];
redge[label="RiverReach"];
}
frictionlist[label="FrictionList"];
subgraph cluster01 {
label="Stricklers";
stricklers[label="Stricklers"];
stricklerslist[label="StricklersList"];
}
subgraph cluster02 {
label="BoundaryCondition";
boundaryconditionlist[label="BoundaryConditionList"];
boundarycondition[label="BoundaryCondition"];
}
subgraph cluster03 {
label="LateralContribution";
lateralcontributionlist[label="LateralContributionList"];
lateralcontribution[label="LateralContribution"];
}
subgraph cluster04 {
label="InitialConditions";
initialconditionsdict[label="InitialConditionsDict"];
initialconditions[label="InitialConditions"];
}
solverparameterslist[label="SolverParametersList"];
subgraph cluster05 {
label="Sediment";
sedimentlayerlist[label="SedimentLayerList"];
sedimentlayer[label="SedimentLayer"];
layer[label="Layer"];
}
subgraph cluster06 {
label="Greometry"
georeach[label="Reach"];
geocrosssection[label="Cross-section"];
geopoint[label="Point"];
}
subgraph cluster07 {
label="Results"
results[label="Results"]
rriver[label="River"];
rreach[label="Reach"];
rcrosssection[label="Cross-section"];
}
study -> river;
river -> rnode;
river -> redge;
redge -> rnode;
river -> boundaryconditionlist -> boundarycondition -> rnode;
river -> lateralcontributionlist -> lateralcontribution -> redge;
river -> initialconditionsdict -> initialconditions;
initialconditions -> redge;
river -> stricklerslist -> stricklers;
river -> solverparameterslist;
river -> sedimentlayerlist -> sedimentlayer -> layer;
redge -> frictionlist -> stricklers;
redge -> georeach -> geocrosssection -> geopoint;
geocrosssection -> sedimentlayer;
geopoint -> sedimentlayer;
results -> study[style="dashed"];
results -> rriver;
rriver -> river[style="dashed"];
rriver -> rreach;
rreach -> georeach[style="dashed"];
rreach -> rcrosssection;
rcrosssection -> geocrosssection[style="dashed"];
*** TODO SQL study file
*** TODO List class
*** TODO Dict class
*** TODO Translate
*** TODO Window
*** TODO UndoCommand
*** TODO Table
*** TODO Plot
*** TODO Mainwindow
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
#+name: graph-pipeline
#+header: :results drawer
#+header: :exports results
#+header: :post attr_wrap(width="12cm", data=*this*, name="graph-pipeline", caption="Pamhyr2 solver execution pipeline architecture scheme", float="t")
#+begin_src dot :file "images/graph-pipeline.png" :cache no
digraph {
bgcolor="transparent";
node[colorscheme=set19,shape=box,style="filled",fillcolor=9];
subgraph cluster0 {
label="Pamhyr2"
config[label="Config",fillcolor=5];
model[label="Model",fillcolor=2];
obj[label="Solver",fillcolor=6];
results[label="Results",fillcolor=2];
view[label="View",fillcolor=1];
results -> model[style="dashed"];
results -> obj[style="dashed"];
}
config -> obj[label=""];
obj -> model[style="dashed"];
subgraph cluster1{
label="System";
in[label="Solver input files",shape=note];
out[label="Solver output files",shape=note];
bin[label="Solver binary",shape=note];
}
obj -> in[label="Write (1)"];
obj -> bin[label="Execute (2)"];
bin -> in[label="Read (2.1)"];
bin -> out[label="Write (2.2)"];
obj -> results[label="Create (3)"];
obj -> out[label="Read (3.1)"];
view -> model[style="dashed"];
view -> results[style="dashed"];
}
#+end_src
** TODO Unit tests
** TODO The debug mode
* TODO Build the project
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
The project uses gitlab-ci runners to build packages, but it is possible
to build packages manually.
** Building packages
If you need an hand made package, you can script available in
{{{file(packages)}}} directory.
*** GNU/Linux
On GNU/Linux building GNU/Linux packages is easy, you just need python
in version 3.8 must be installed with venv and pyinstaller packages
(see Listing [[linux-env-deb]] for Debian and derived system). Finally,
run the {{{file(linux.sh)}}} script (see Listing [[linux-pkg]]).
#+NAME: linux-env-deb
#+CAPTION: Install environment on GNU/Linux
#+begin_src shell
sudo apt install python3.8
python3 -m pip install venv
python3 -m pip install pyinstaller
#+end_src
#+NAME: linux-pkg
#+CAPTION: Build GNU/Linux package
#+begin_src shell
cd packages
./linux.sh
#+end_src
*** Windows
To make the Windows packages you have two choice: If you use Windows
you can use the script {{{file(packages/windows.bat)}}}, other else
you can use the script {{{file(packages/wine.sh)}}}. Each script need
a specific software environment.
On windows, you needs python on version 3.8, pyinstaller and
NSIS[fn:nsis] installed. On GNU/Linux you need wget, wine and
winetricks installed.
[fn:nsis] The NSIS web site: https://sourceforge.net/projects/nsis/
** TODO Setup the CI environment
* Documentation files
This document and the user documentation are org files. This text file
format is formatted so that it can be exported in different formats:
PDF (with latex), ODT, HTML, etc. It was originally designed for the
GNUEmacs[fn:emacs] text editor, but can be edited with any text editor. Here we
take a look at the different features used in these documents.
[fn:org] The org-mode website: https://orgmode.org/ (last access
2023-09-15)
[fn:emacs] The GNUEmacs project website: https://gnu.org/s/emacs/
*** Document structure
Org uses the =*= character to define a new document section. To add a
sub-section, you can add an additional =*= to the current section[fn::
See document structure documentation:
https://orgmode.org/org.html#Headlines (last access 2023-09-15)].
#+BEGIN_EXAMPLE
* Top level headline
** Second level
*** Third level
some text
*** Third level
more text
* Another top level headline
#+END_EXAMPLE
*** Format
Org-mode is a markup file, using markup in the text to modify the
appearance of a portion of text[fn:: See markup documentation:
https://orgmode.org/org.html#Emphasis-and-Monospace (last access
2023-09-15)].
| Markup | Results |
|--------------------+------------------|
| =*Bolt*= | *Bolt* |
| =/Italic/= | /Italic/ |
| =_underline_= | _underline_ |
| ==verbatim== | =verbatim= |
| =~code~= | ~code~ |
| =+strike-through+= | +strike-through+ |
*** Source code blocks
You can add some code blocks[fn:: See org-mode documentation for
source code: https://orgmode.org/org.html#Working-with-Source-Code
(last access 2023-09-15)] in the document.
Here is an example for python source code:
#+BEGIN_EXAMPLE
#+CAPTION: Get os type name in Python code
#+begin_src python
import os
print(f"Document build on system: {os.name}")
#+end_src
#+END_EXAMPLE
If you use GNUEmacs, it is also possible to run the code inside a
block and export (or not) the reuslts in the document.
#+CAPTION: Get os type name in Python code
#+begin_src python :python python3 :results output :exports both :noweb yes
import os
print(f"Document build on system: {os.name}")
#+end_src
#+RESULTS:
: Document build on system: posix
If we export the file to PDF, org-mode use {{{latex}}}. So we can add
some piece of {{{latex}}} into the document[fn:: See {{{latex}}} part
in documentation: https://orgmode.org/org.html#Embedded-LaTeX (last
access 2023-09-15)]. For exemple, we can add math formula like
=$E=mc^2$= ($E=mc^2$) or =\[E=mc^2\]=:
But we can also add every type of {{{latex}}}:
#+BEGIN_EXAMPLE
# Add latex in line
#+LATEX: <my line of latex>
# Add multiple line of LaTeX
#+BEGIN_EXPORT latex
<my latex here>
#+END_EXPORT
#+END_EXAMPLE
It is also possible to add specific {{{latex}}} file header with
=#+LATEX_HEADER=. In this document we use the file
{{{file(doc/tools/latex.org)}}} for all {{{latex}}} headers.
*** Macro
In this document, we use a few macros[fn:: See marcos documentation
https://orgmode.org/org.html#Macro-Replacement (last access
2023-09-15)] to simplify writing. They allow you to define sequences
of text to be replaced, so that the macro name is replaced by its
value. They are defined in the {{{file(doc/tools/macro.org)}}}
file. Once defined, they can be used in the document as follows:
={{{<macro-name>}}}=. You can also have macros with arguments, in this
case: ={{{<macro-name>(arg1,...)}}}=. Les macros peuvent aussi
utiliser du code emacs-lisp.
#+BEGIN_EXAMPLE
# Exemple of macro définition
#+MACRO: toto tata
#+MACRO: add \(($1 + $2)\)
#+MACRO: emacs-version (eval (nth 2 (split-string (emacs-version))))
#+END_EXAMPLE
#+MACRO: toto tata
#+MACRO: add \(($1 + $2)\)
#+MACRO: emacs-version (eval (nth 2 (split-string (emacs-version))))
Macro apply:
- Marco ={{{toto}}}=: {{{toto}}}
- Marco ={{{add(x,y)}}}=: {{{add(x,y)}}}
- Marco ={{{emacs-version}}}=: {{{emacs-version}}}
*** Footnotes
Footnote in org-mode is define with marker =[fn:...]=[fn:: Create
footnotes in org-mode documentation
https://orgmode.org/org.html#Creating-Footnotes (last access
2023-09-15)]:
#+BEGIN_EXAMPLE
The Org website[fn:1] now looks a lot better than it used to.
...
[fn:1] The link is: https://orgmode.org
#+END_EXAMPLE
or:
#+BEGIN_EXAMPLE
The Org website[fn:: The link is: https://orgmode.org] now looks
a lot better than it used to.
...
#+END_EXAMPLE
*** References
The references use the {{{latex}}} bibtex tools. The bib file is in
{{{file(/doc/tools/ref.bib)}}} and use for developers and user
documentation. In document, use ={{{cite(<name>)}}}= to cite a paper.
** Export
To export the files, a {{{file(build.sh)}}} script is available in the org
files directories. On GNU/Linux system you can build the documentation
PDF file with the command =./build.sh=. Texlive package must be
installed, you can install only needed packages or all texlive
packages, for example on Debian (and some derived system) use command
Listing [[texlive-install]].
#+CAPTION: Installation command for texlive full on Debian system
#+begin_src shell
sudo apt install texlive-full
Some org-mode configuration used in documentations files are define in
=/doc/tools/=:
- {{{file(PamhyrDoc.cls)}}}: The {{{latex}}} document class
- {{{file(macro.org)}}}: Available macro
- {{{file(latex.org)}}}: {{{latex}}} configutation for documentations
files
- {{{file(setup.el)}}}: GNUEmacs configuration to build documentations
- {{{file(ref.bib)}}}: Bibtex files for documentations files
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
Pamhyr2 is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License[fn:license], either
version 3 of the License, or any later version.
[fn:license] The GPLv3 web page:
https://www.gnu.org/licenses/gpl-3.0.en.html
** Guidelines
To contribute to Pamhyr2, we expect a minimum of respect between
contributors. We therefore ask you to respect the following rules
regarding communication and contribution content:
+ No gender, racial, religious or social discrimination
+ No insults, personal attacks or potentially offensive remarks
+ Pamhyr2 is free software, and intended to remain so, so take care
with the licensing of libraries and external content you want to add
to the project
+ Humour or hidden easter eggs are welcome if they respect the
previous rules
** Make a contribution
There are several ways to contribute: you can report a bug by creating
an issue on the project's gitlab page[fn:p2-gitlab], or you can create
a merge request on the same page with the changes you have made to the
code, translation or documentation.
The Pamhyr2 copyright is owned by INRAE[fn:inrae], but we keep a
record of each contributors. If you made a modification to pamhyr2
software, please add your name at the end of {{{file(AUTHORS)}}} file
and respect the Listing [[auth-format]] format. You can update this file
information for following contribution.
#+NAME: auth-format
#+CAPTION: =AUTHORS= file format
#+begin_src text
<first name> <last name> [(optional) email], <organisation>, <years>
#+end_src
#+CAPTION: Current =AUTHORS= file
#+INCLUDE: "../../AUTHORS" src text
[fn:p2-gitlab] The Pamhyr2 Gitlab project page:
https://gitlab.irstea.fr/theophile.terraz/pamhyr
[fn:inrae] The INRAE web site: https://www.inrae.fr/
** Translate
You can improve or add translation for the project. To contribute to
Pamhyr2 translate, you need to use Qt Linguist[fn:qt-linguist]. Open
Qt-linguist and edite the translation ({{{file(.ts)}}}) file, finally,
commit the new version of file and make a merge request.
If you want add a new language, edit the script
{{{file(src/lang/create_ts.sh)}}} like Listing [[ts-it]]. Run the script
and open the new file with Qt-linguist, setup target language (Figure
[[qt-linguist-setup]]) and complete translation. Finally, commit the new
file and make a merge request.
#+NAME: ts-it
#+CAPTION: Example of modified {{{file(src/lang/create_ts.sh)}}} to add italian (it) translate for Pamhyr2
#+begin_src shell
...
LANG="fr it"
...
#+end_src
#+NAME: qt-linguist-setup
#+ATTR_LATEX: :width 8cm
#+CAPTION: Qt linguist lang setup example with italian.
[[./images/Qt-linguist-setup-lang.png]]
[fn:qt-linguist] The Qt linguist documentation web page:
https://doc.qt.io/qt-5/qtlinguist-index.html (last access 2023-09-18)
** Code contribution
If you are developper you can improve and/or add features to
Pamhyr2. Please, follow the architecture described in section
[[Architecture]] as closely as possible. Keep the code simple, clear and
efficient as possible. The master branch is reserved for the project
maintainer; you can create a new branch or fork the project before the
request.
{{{biblio}}}