# How to contribute to the OMFIT project¶

There are many ways to contribute to OMFIT, which include:

1. Using OMFIT for your research

2. Submitting issues and bug reports

3. Suggesting and discussing ideas

4. Developing code

5. Providing documentation and tutorials

6. Engaging with the broader plasma community and promoting the use of OMFIT

To this end, remember that citing OMFIT in papers, talks, and posters helps increase the visibility of the project and is yet another important way to contribute to OMFIT.

# Contributing to the OMFIT source code¶

Contributing to the OMFIT source code requires having access to the OMFIT-source GitHub repository.

• Contributions to the modules source codebase can be done directly from within the OMFIT GUI (Google docs, PDF)

• A tutorial for contributing to OMFIT using git directly can be found here: (Google docs, PDF)

## Development Model¶

OMFIT relies on git for version control. Here is a nice git cheat-sheet (interactive).

The inspiration for the OMFIT development model is found here.

There are two main git branches which exist indefinitely on the OMFIT-source GitHub repository:

• The master branch exists to hold the ‘stable’ version of OMFIT

• The unstable branch is the place where new features and bugfixes come together

Features are first implemented in the unstable branch then are moved to the master branch. Most users should be running on the master branch, and use the unstable branch only upon request of the developers to test some specific feature(s). Each master release is completed with release notes that summarize the main progress since the past release.

## Continuous testing and deployment¶

No user can push changes directly to the unstable branch. Updates to the unstable branch must come either via a pull-request, or via updates of the auto_merge branch. In either case, automated regression tests are run prior to the merge into unstable. The main difference between opening a pull request and pushing to auto_merge is that the former allows code review by other OMFIT developers. Since pushing to auto_merge skips code review, only the most experienced developers are given the permissions to do so.

The details about developing regression tests in OMFIT can be found here (Google docs, PDF)

## Updating OMFIT’s environment¶

OMFIT relies on a number of external packages and applications. Should a developer need to add to this list or change package requirements such as minimum version number the developer should:

1. Edit OMFIT-source/install/omfit_dependencies.yaml. Follow the pattern in the yaml file for adding a new dependency. To cover the OMFIT install base, an entry should be made for both Conda as well as either Macports or pip. (As Macports uses pip as a backup package source.)

2. In the same file, make sure to increment the build number at the top of the file.

3. (Optional) Run OMFIT-source/installgenerate_install_files.py to regenerate the package files for different installers.

4. Commit the change to the branch omfit_env_test. This is a special branch that will do test builds of potential new OMFIT environments.

Should the tests complete successfully, the environment changes can be merged into unstable after which the newly built Conda packages and Docker images will be uploaded for distribution. (Macports portfiles are all handled locally; so while the packages are re-built, they are not uploaded to the cloud.)

# Guiding principles for scalable module integration¶

When working with modules one should pay attention that “a module should not need to know anything about its location in the OMFIT tree in order to work properly” When working with hierarchical modules, this translates into: “it’s ok for the parent module to move or modify data in the child module, but the child module should not access data outside of itself (except for dependencies described next).

The entries under root['SETTINGS']['DEPENDENCIES'] allow modules to access data outside of themselves. These entries are strings that define how certain locations in the OMFIT tree should become available as variables in the OMFIT scripts and OMFITexpressions within that module.

For example:

root['SETTINGS']['DEPENDENCIES']['gEQDSK']="OMFIT['gEQDSK']"


will make a gEQDSK variable that points to OMFIT['gEQDSK'] be available in the OMFIT scripts and expressions within the module. This would be the equivalent of setting gEQDSK=OMFIT['gEQDSK'] at the top of all the scripts and expressions within a module.

There are keywords that the DEPENDENCIES entries understand and are handy to navigate the modules hierarchy upstream while specifying relative tree locations instead of absolute tree locations. The most useful is OMFITmodules which is defined as the hierarchical list of modules to reach the module we are working on. So, OMFITmodules[-1] is the current module, while OMFITmodules[-2] is the parent module, and so on. OMFITmodules[0] is equivalent to the root of the OMFIT tree itself, that is OMFIT.

For example, to say that the submodule submod module needs to know something from the mod input namelist:

root['SETTINGS']['DEPENDENCIES']['mod_nml']="OMFITmodules[-2]['INPUTS']['mod_nml']"


Now in the scripts and dynamic expression of the submod module, we can refer to that namelist simply using the mod_nml variable.

# Module script locations¶

The scripts, settings, and files for each module are located in an OMFIT repo in OMFIT-source/modules/<name of module>. In the default mode that OMFIT starts, when a module is imported into an existing OMFIT session, OMFIT makes a copy of each file of the module in that repo for use in that OMFIT session in the directory specified by the environment variable OMFIT_TMPDIR. If the session is saved as an OMFIT project, then a copy of the scripts (and data) are made to a staging area, and then possibly zipped up together to store on disk as an OMFIT project in the OMFIT projects area.

There are three purposes of making copies:

1. it protects users from continual changes as OMFIT is updated while the session is open

2. it allows a public session of OMFIT to be used by multiple users, without each user mucking with the public version of the code

3. it allows a user to open an old project and have the same scripts as were used previously to reproduce a workflow at a later time

If changes are made to the copies in an OMFIT session, there is only one way for those changes to get back to an OMFIT repository in a robust way: using File->Export Modules…. The Export GUI allows two types of workflows:

1. Exporting to one of the repositories listed in File->Preferences->Main->Modules directories or

2. Exporting to an OMFIT controlled clone of the OMFIT-source repo (in MainSettings[‘SETUP’][‘projectsDir’]+’../.repos/OMFIT-source_<hash>’).

If the structure of a module is set, and changes are only being made to individual scripts, then it can be useful to operate a module in “Developer Mode”. This can be achieved by checking the box when importing the module, by using the -M command line argument for importing a module, or by right-clicking on a module in the tree and choosing “Convert to Developer Mode”. In developer mode, the files pointed to in the tree are those of an OMFIT repo directly, and so any changes made to the files are immediately reflected in the repo. Note that if a session with a module in developer mode is saved, then, in the saved project, there are copies of the module’s scripts as they existed at the point of saving, and these files are not pointing to the repo versions if the project is reopened. If the structure of the module is changed while in developer mode, then those changes still need to be “Exported” via “File -> Export modules…”. Only the scripts of personal installations of OMFIT can be opened in developer mode, as opposed to scripts of public installations, which cannot be opened this way.