Vespucci
1.0.0
|
Thank you for your interest in contributing to the Vespucci Project. These guidelines should help you make a valuable contribution to the project. They cover the process of contributing to Vespucci, the process of adding a spectral pre-processing method and the process of adding a spectral analysis method. By following these guidelines, we hope Vespucci can attain a higher degree of quality than other research code.
The issues page on GitHub includes features we would like to see added to Vespucci that we are currently not working on. If you have a contribution to make, comment on one of these issues (or start your own) and we may assign the issue to you.
If you have code to contribute to Vespucci, simply make a pull request with your changes to the VespucciProject GitHub page. The contribution should include unit tests for at least the functions added to the Vespucci::Math
namespace. The pull request will be automatically built by our build service providers, which will execute unit tests (provided you have added them to the Test.pro project). The code will be examined for style and quality by the maintainer, and if all tests pass and the contribution is deemed within the mission of the project, your contribution will be integrated into the code base and your name added to our list of contributors. Any code contributed must compile, test, and run successfully on all three of Vespucci's target platforms.
If you have already implemented a method not found in Vespucci in MATLAB or Octave, take a look at the syntax conversion table. Re-writing MATLAB code in C++ using Armadillo is fairly easy.
If you are uncomfortable with Qt, but have a meaningful math function to contribute to the library, feel free to make a contribution. The user interface can be created later. Bug fixes and code that improves performance or clarity of existing functions are also welcome.
Generally, code contributed to the Vespucci project can rely only on the following libraries:
If there is a compelling reason to use a different library than the ones listed above, please discuss it with us using the issues tab before you start writing code. Any library that is to be used in Vespucci must be regularly built and tested on Windows 7 (using MSVC and GCC), Mac OS 10.7 (Using clang), and Ubuntu 14.04 LTS (or a similar GNU/Linux distro, using GCC). If the library is not regularly tested on one of these platforms, and there is compelling reason to do so, we will set-up regular testing using Travis-CI and or Appveyor. As Vesucci is distributed under the terms of the GPL, any additional library used must use a license acceptable for GPL software.
Vespucci tries to adhere to the Google C++ Style Guide. However, none of the libraries Vespucci links to follow this guide. Armadillo uses underscore_case for all names and mlpack and Qt use camelCase for all names. The following exceptions (and perhaps others) apply:
.cpp
QDialog
class that calls the addGraph
member of a QCustomPlot
object, we name the member of the QDialog
"`addGraph()`", rather than the stylistically preferred "`AddGraph()`").name_
, spectra_
, etc).SetName()
for the setter of the name_
member).abscissa_
is named abscissa()
). Getters that return pointers to members have _ptr
appended to the end of their names. Where getters that return copies and getters that return references both exist, the getter that returns the reference is named with _ref
appended.Vespucci::Math
or BinaryImport
.Variables in Vespucci should use the following types:
To add a processing method to Vespucci, the following must be done:
VespucciDataset
to execute the analysis.Vespucci::Math
namespace in the Vespucci library.QDialog
must be created, or an existing dialog expanded to handle the new method.If a class already exists for performing a processing step substantially similar to the method to be added, the existing class should be expanded by the addition of widgets to handle user input. Widgets may also simply be reused with their QLabel
s changed. If a new form class must be created, follow the same procedure as you would for a new analysis form class, documented in the subsection "Analysis GUI Classes" of the section "Adding Analysis Methods to Vespucci".
To add an analysis method to Vespucci, the following must be done:
VespucciDataset
to execute the analysis. This member must take QString name
as its first parameter.Vespucci::Math
namespace of the VespucciLibrary.AnalysisResults
may be constructed in the VespucciDataset
member function.QDialog
to allow the user to enter parameters.GUI classes to handle the input of parameters from the user must have the following:
QModelIndex
from dataset tree view and obtains a QSharedPointer<VespucciDataset>
to the dataset the analysis is to be performed on, and calls findChild
on the required QWidget
members.data_
or dataset_
which contains a QSharedPointer<VespucciDataset>
corresponding to the active dataset.QWidget
s that interact with the user.QWidget
that is called "thingWidget" in the .ui file should have a pointer named thing_widget_
in the class. Widgets are named in the conventional Qt style within forms, but in Google-esque style within the C++ classes. The base type of the widget must be included in the name (e.g. name_line_edit_
for the QLineEdit
object that takes string representing a name from a user).VespucciDataset
member functions Member functions to perform an analysis must do the following:
analysis_results_
.QSharedPointeR<AnalysisResults>
object to analysis_results_
map containing the matrices generated by the analysis. This is obtained from the GetData()
method of the analysis handler or is initialized in the VespucciDataset
member in the case of analysis methods implemented by mlpack.A VespucciDataset
contains all analysis methods that may be called on it. Each analysis has a helper object which takes the data as a reference from the dataset. Helper objects must implement the following members:
arma::mat
type which store the results of the analysis. It is customary to use the member results_
when a matrix is returned from an analysis function, and to name these members the same as the parameters of the analysis function (remembering to add the trailing underscore used for members in Vespucci).Apply()
to which is passed spectra_
and perhaps abscissa_
, along with the parameters of the analysis that are taken in the VespucciDataset
analysis member function. This function calls the functions from the Vespucci library that are required for the analysis.GetData()
, which heap-allocates an AnalysisResults
object in a QSharedPointer
and calls the AppendResult()
method of the AnalysisResults
object to add matrices. Each matrix should have name that constitutes a unique key, and if necessary, column headings should be provided in a QStringList
for at least the first 15 columns of each matrix.Vespucci::Math
Namespace Analysis methods must be implemented in either mlpack or armadillo, or in the Vespucci::Math
namespace. A few style rules apply to this namespace that do not apply to Vespucci in general:
const arma::mat&
. If the matrix itself is to be modified, the function should return a copy or include a copy as a non-const
reference parameter.using
directive should not to be used so as to avoid confusion between functions in the std
and arma
namespaces.std::string
instead of QString
). This is in contrast to the Vespucci GUI program, where Qt types are preferred.bool
.Mat
appended to the end of the function name (e.g. QuantifyPeak
and QuantifyPeakMat
, where QuantifyPeak
returns a arma::rowvec
and QuantifyPeakMat
returns an arma::mat
).arma::vec
type should be used. If a matrix is expected to contain only one row, arma::rowvec
type should be used.arma::uword
for integers and unsigned double
for floating-point numbers.try/catch
block. The catch
block must write the function call that threw the exception to stdout
and throw the same exception again.arma::field<arma::mat>
type.All methods in the Vespucci library are unit tested to ensure code quality and reproducibility of results. The project located in the Test folder is used to run all unit tests on math functions. Example datasets are provided, including real-world and generated spectra. Unit tests written for functions in the Vespucci library should use the Boost unit test framework. Tests written for Qt classes should use QtTest. Some methods, such as Vertex Components Analysis are untestable as they produce different results each time they are run on the same data. These functions should only be tested for the validity of their output, not for the values.