Skip to content
Etienne SENIGOUT edited this page Oct 7, 2024 · 5 revisions

Introduction

Holovibes is designed for real-time computation of holograms from high-bitrate interferograms. It is developed using C++/CUDA and supports various cameras and file formats. This tutorial will guide you through the process of setting up your development environment, understanding the codebase, and contributing effectively to the project.

3. Project Structure

3.1 File structure

  • build/: Contains build-related files.
  • Camera/: Contains interface for using cameras. And specific implementation and configs file for each camera.
  • docs/: Contains documentation files (doxygen, diagram).
  • Holovibes/convolution_kernels: txt files containing numbers for the different kernel (sobel, gaussian blur).
  • Holovibes/includes/: Contains header files.
  • Holobives/sources/: Contains source code of the project.
  • Preset: Contains different parameters preset for holovibes stored as .json files.
  • tests/: Contains test cases.
  • CHANGELOG.md: Keep track of all user related changes (UI, features) for each version.

3.2 Code interaction: UI and API

The UI calls API functions and listens to a notifier using a subscriber/observer pattern to synchronize changes between different UIs.

  • UI Calls API Functions: The UI elements trigger actions and request data by calling corresponding API functions.
  • Notifier and Subscriber: The notifier mechanism is used to alert subscribers (UI components) about changes. This ensures that any update in the data or state is reflected across all UI components consistently. (Refer to Updating the UI from the API)

6. Advanced Topics

6.2 Logging

We have 5 levels of log:

  • Trace (LOG_TRACE)
  • Debug (LOG_DEBUG)
  • Infos (LOG_INFO)
  • Warnings (LOG_WARN)
  • Errors (LOG_ERROR)

And 7 loggers that log on std::cerr and in a log file in appdata:

  • main
  • setup
  • cuda
  • information_worker
  • record_worker
  • compute_worker
  • frame_read_worker

Usage:

LOG_ERROR(logger_name, formated_string [,args]);

Format:

[${log_level}] [${timestamp}] [${Thread ID}] ${logger_name} >> ${message}

6.3 Assertions

Usage:

CHECK(condition)
CHECK(condition, formated_string [,args]); // Up to 14 varags

Format:

[${log_level}] [${timestamp}] [${Thread ID}] ${logger_name} >> ${filename}:${line} ${message}

6.4 Adding Elements to Front with QtCreator

  • In QtCreator, load a .ui file
  • Add a widget and change its name in the right column.
  • Open as plain text the .ui file and add in the <slots> element at the end of the file a slot with the prototype of the function (ex: <slot>functionName(args)</slot>).
  • Add a new slot in QtCreator cliking on the green '+' on the middle.
  • Fill the 4 columns with the name of your function in the last column.
  • Add the prototype in MainWindow.hh and implement it in MainWindow.cc.

If you want to use a custom widget, you can change its class in the .ui file directly if it doesn't work in QtCreator.

6.5 Updating the UI from the API

  1. Create a new notifier in the API.

    • Choose a name that reflects the information being sent.
    • Choose a type for the information sent.
      • You must send at least one argument. If you don't need to send any information, use a boolean.
      • If you want to send multiple arguments, either use a struct or a tuple.
    NotifierManager::notify<type>("notifier_name", data);
  2. Create a new subscriber in the UI.

    • Add it in the constructor.
    // In the .hh
    void on_notifier_name(const type& data);
    Subscriber<type> notifier_name_subscriber;
    // In the .cc
    Class::Constructor()
       : notifier_name_subscriber("notifier_name",
          std::bind(&Class::on_notifier_name, this, std::placeholders::_1))
    • Implement the function that will be called when the notifier is triggered.

9. Test

The framework used is PyTest. Integration testing is done using the CLI mode of Holovibes.

9.1 Add a test

Create a folder with the name of your test in the tests/data/ folder. Then put:

  • an optional input.holo (if you provide no input, the default one in the input folder will be chosen. You can provide different default inputs by making the name of the input match a part of your test name).
  • a ref.holo file as intended output.
  • an optional holovibes.json containing parameters.
  • an oprional cli_argument.json containing CLI arguments.

9.2 Build Reference Outputs

At the root of a stable branch run:

./dev.py build_ref [test_name]

If no test_name is given, all refs will be built. It will generate a ref.holo or a error.txt and a ref_time.txt for each test. CAREFULL : this command should only be runned in a stable branch and for newly-added tests for which the behavior has been verified and validated by hand, or when the software's output has improved, and if you know for sure that it's stable.

9.3 Run tests

Build the project in Release or Debug mode. If you want all tests run:

$ python -m pytest -v

OR

$ ./dev.py build pytest

If you want to run one or specific tests run:

./dev.py build pytest --specific-tests=names

Where names is a comma separated list of folders

Both will generate a last_generated_output.holo, or an output_error.txt.