Modifying OMEGA source code =========================== Adding built-in algorithms -------------------------- The process of adding new built-in algorithms into OMEGA is actually quite straightforward. In most cases, you only need to do some C++ coding in order to enable GPU support for both CUDA and OpenCL. This means that most of the time you don't need to do actual GPU coding to implement algorithms on the GPU. The following points explain the general process of adding new algorithms. The list assumes that the algorithm is a reconstruction algorithm and not a regularizer, but the below can also be used to implement regularizers, many of the steps are simply omitted. 1. Add a suitable boolean variable to the ``structs.h file`` in the ``RecMethods_`` struct. Generally the organization is that first is non-regularized ones, next priors, then regularized algorithms and lastly miscellanious ones 2. Next modify ``subiterStep.h`` and add the new algorithm to the end. While you can directly add all the required functions here, it is recommended to implement separate function for the algorithm. These are stored in ``algorithms.h`` and will be handled later 3. This step applies only if the algorithm supports regularization, or if the added algorithm is a regularizer. The ``applyPrior`` function in ``priors.h`` handles regularization. In general, the regularization is ADDED to the backprojection. There is a possibility to save the regularization itself and some algorithms already use that. That way you can input the regularization to variable other than the backprojection (or subtract it). If you are adding a new regularizer, you should add it to this function. 4. Add the algorithm-specific operations to ``algorithms.h`` as a new function. Note that these need to be operations that are computed AFTER the backprojection. The backprojection is saved in ``std::vector`` ``vec.rhs_os``. Each element is one multi-resolution volume. If no multi-resolution reconstruction is used, then the vector only contains one element. Same applies to the current image estimate saved in ``vec.im_os`` 5. If you need to use helper variables specific to the algorithm, you can input them into ``AF_im_vectors_`` struct in ``structs.h`` 6. Built-in preconditioning can be applied with ``applyImagePreconditioning`` 7. Since we are proceeding backwards, next step is adding any computations before backprojection. This is applied in ``computeForwardProject.h`` 8. Measurement-based preconditioners can be applied with ``applyMeasPreconditioning`` 9. Some algorithms require specific initialization phases. This can be simply preallocating memory for algorithm-specific variables or some initial computations. This can be done at each iteration or only at the first one. These operations can be done in ``initializationStep``-function. The "``if (curIter == 0) {``" line specifies section for operations that are done only at the first iteration (such as preallocation) 10. Next you'll need to copy necessary variables from either MATLAB/Python or from both. For MATLAB/Octave, you'll need to modify ``mfunctions.h`` and for Python ``libHeader.h``. The latter is also used in dynamic library settings. At minimum, you'll need to load the boolean variable for the algorithm, i.e. if it's true, the algorithm is used 11. For some algorithms, the last step includes adding the name of the algorithm in ``recNames`` for MATLAB/Octave or the boolean in ``proj.py`` in Python. For MATLAB/Octave, general functionality should be guaranteed as long as ``varMAP`` or ``OS``, ``varProj1``, and ``varPriorFull`` are modified (i.e. your one is added). Other functionality can be enabled with the other variables. Note that these are used merely in error checking, i.e. if you want to use preconditioners, you'll get an error when trying to use one if the algorithm is not added to the supported list. For Python, you'll only need to add an initial value for the algorithm. You'll also need to make sure that the boolean variable is correctly transfered to the C++-library. This means adding a new variable both the list at the beginning of ``proj.py`` (``class projectorClass``) as well as to the list at the end (``class parameters``). The first used for Python-specific tasks, while the latter is for the library. Lastly, the transfer of the boolean to the C++-library is done in ``recomain.py`` (``transferData``). For "``class parameters``" the order should be identical with ``libHeader.h``! 12. Depending on the algorithm, you might need to do some additional adjustments. If some variables need to be precomputed, you'll need to take care of this yourself. One possible location is the ``prepass_phase.m`` file for MATLAB/Octave and ``prepassPhase`` in ``prepass.py`` for Python.