diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..ca85a04af47df7d3935a04822dfa630be08e56eb
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+database/UIUC-propDB*
diff --git a/miss_hit.cfg b/miss_hit.cfg
new file mode 100644
index 0000000000000000000000000000000000000000..d53390c7c60595cc3c37747ef91ef857fe0fba01
--- /dev/null
+++ b/miss_hit.cfg
@@ -0,0 +1,33 @@
+# miss_hit style checker
+# (https://florianschanda.github.io/miss_hit/style_checker.html)
+#
+project_root
+
+# Ensure copyright notice is everywhere
+copyright_primary_entity: "University of Liege"
+copyright_entity: "Thomas Lambert <t.lambert@uliege.be>"
+
+# Enable miss_hit on the whole repo
+enable: 1
+enforce_encoding: "utf8"
+
+# Layout
+line_length: 100
+tab_width: 4
+
+# Regex to enforce naming convention
+regex_script_name: "[a-z](_?[a-z0-9]+)*"
+regex_function_name: "[a-z](_?[a-z0-9]+)*"
+regex_nested_name: "[a-z](_?[a-z0-9]+)*"
+regex_parameter_name: "[a-zA-Z](_?[a-zA-Z0-9]+)*"
+regex_class_name: "[A-Z]([a-zA-Z0-9]+)*"
+regex_method_name: "[a-z](_?[a-zA-Z0-9]+)*"
+
+# metrics limit for the code quality
+# (https://florianschanda.github.io/miss_hit/metrics.html)
+metric "cnest": limit 5
+metric "file_length": limit 800
+metric "cyc": limit 15
+metric "parameters": limit 10
+metric "globals": limit 0
+metric "persistent": limit 3
diff --git a/scripts/uiucdownload.m b/scripts/uiucdownload.m
new file mode 100644
index 0000000000000000000000000000000000000000..9ce287982d8e33dd39a7d49916c88e31ac239ac6
--- /dev/null
+++ b/scripts/uiucdownload.m
@@ -0,0 +1,192 @@
+function uiucdownload(varargin)
+    % UIUCDOWNLOAD Download, extract and clean the UIUC propeller database.
+    %   This function executes the following tasks:
+    %       1. Download the UIUC Propeller database into database/UIUC-propDB_YYYYMMDD.zip. It also
+    %          saves the file hash into a textfile in oder to prevent useless re-downloads.
+    %       2. Unzip the database and moves the data files found in volumeX/data/* into
+    %          database/UIUC_propDB/volumeX/*
+    %       3. The rest of the unzipped files are cleaned up
+    %       4. The zip file is either kept or removed, based on user input
+    % -----
+    %
+    % Syntax:
+    %   uiucdownload() Download the database (if needed) and its md5 checksum, extract the data
+    %   files and cleanup afterwards.
+    %
+    %   uiucdownload('force', true) Forces the redownload of the database, even if the md5 checksum
+    %   found locally matches the one present on the UIUC website. Default: false.
+    %
+    %   uiucdownload('quiet', true) Removes all verbosity from the command line. Default: false.
+    %
+    %   uiucdownload('removeZip', true) Removes the zipfile as well during cleanup. Default: true.
+    %
+    %   uiucdownload('removeSum', true) Removes the checksum file as well during cleanup.
+    %   Note that this will result in a forced download of the database if the function is run
+    %   again, even if the zip-file is still present locally. Default: false.
+    %
+    % Inputs:
+    %   'force'     : Forces redownload of the database
+    %   'quiet'     : Removes verbosity from the command line
+    %   'removeZip' : Removes the zip-file at cleanup
+    %   'removeSum' : Removes the checksum at cleanup. This will force a redownload if the function
+    %                 is run again
+    %
+    % Outputs:
+    %   UIUC-propDB : Directory containing the all useful data from the UIUC propeller database.
+    %
+    % Examples:
+    %   uiucdownload()
+    %   uiucdownload('force', true)
+    %   uiucdownload('removeZip', false, 'force', true)
+
+    % -----------------------------------------
+    % (c) Copyright 2023 University of Liege
+    % Author: Thomas Lambert <t.lambert@uliege.be>
+    % ULiege - Aeroelasticity and Experimental Aerodynamics
+    % MIT License
+    % Repo: https://gitlab.uliege.be/rotare/rotor-db
+    % Issues: https://gitlab.uliege.be/rotare/rotor-db/-/issues
+    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+    close all;
+    clc;
+
+    % Defaults and constants
+    PROP_DB_URL = 'https://m-selig.ae.illinois.edu/props/propDB.html';
+    PROP_DB_ZIP_URL = 'https://m-selig.ae.illinois.edu/props/download/UIUC-propDB.zip';
+    N_VOLUMES = 4; % Number of volumes in the database
+
+    DB_DIR = '../database/';
+    DB_NAME = 'UIUC-propDB';
+    ZIP_FILENAME = 'UIUC-propDB.zip';
+    SUM_FILENAME = 'UIUC-propDB.md5';
+
+    % Parse function options
+    [forceDownload, removeZip, removeSum, quiet] = parseoptions(varargin{:});
+
+    % Retreive the md5sum of the UIUC-propDB.zip
+    sumfilename = [DB_DIR, SUM_FILENAME];
+    currentSum = getcurrentchecksum(PROP_DB_URL); % Checksum from the website
+    oldSum = getlocalchecksum(sumfilename); % Checksum saved locally
+
+    if ~strcmp(currentSum, oldSum) || forceDownload
+        zipfilename = [DB_DIR, ZIP_FILENAME];
+        tempdir = [zipfilename, '.temp'];
+        dbname = [DB_DIR, DB_NAME];
+
+        % Download database and save corresponding checksum
+        verboseoutput(quiet, 'Downloading the database. This may take a while...\n');
+        websave([DB_DIR, ZIP_FILENAME], PROP_DB_ZIP_URL); % TODO UNCOMMENT AFTER TESTING
+        verboseoutput(quiet, 'Download completed.\n');
+        savetofile(sumfilename, currentSum);
+
+        % Unzip database and copy files
+        verboseoutput(quiet, 'Extracting database files... ');
+        unzip(zipfilename, tempdir);
+        verboseoutput(quiet, 'Done!\nCopying the database files...');
+        copydbfiles(tempdir, dbname, N_VOLUMES);
+        verboseoutput(quiet, 'Done!\n');
+
+        % Cleanup
+        verboseoutput(quiet, 'Cleaning up...\n');
+        cleanup(tempdir, zipfilename, sumfilename, removeZip, removeSum);
+        verboseoutput(quiet, 'All done!\n');
+    else
+        verboseoutput(quiet, ['It seems that the database has already been downloaded.\n'...
+                              'You can force a re-download by using '...
+                              '''uiucdownload(''force'', true)''.\n']);
+    end
+
+end
+
+% --------------------------------------------------------------------------------------------------
+function [forceDownload, removeZip, removeSum, quiet] = parseoptions(varargin)
+    % PARSEOPTIONS Parse function optional inputs
+
+    % Defaults and constants
+    DEF_FORCE_DOWNLOAD = false; % Force redownload of the full DB
+    DEF_REMOVE_ZIP = true;      % Remove the zipfile during cleanup
+    DEF_REMOVE_SUM = false;     % Remove the checksum during cleanup (not advised)
+    DEF_QUIET = false;          % Do not show any output
+
+    % Option validators
+    validLogical = @(x) validateattributes(x, {'logical'}, {'scalar'});
+
+    % Parse options
+    p = inputParser;
+    addParameter(p, 'force', DEF_FORCE_DOWNLOAD, validLogical);
+    addParameter(p, 'quiet', DEF_QUIET, validLogical);
+    addParameter(p, 'removeZip', DEF_REMOVE_ZIP, validLogical);
+    addParameter(p, 'removeSum', DEF_REMOVE_SUM, validLogical);
+    parse(p, varargin{:});
+    forceDownload = p.Results.force;
+    removeZip = p.Results.removeZip;
+    removeSum = p.Results.removeSum;
+    quiet = p.Results.quiet;
+end
+
+function checksum = getcurrentchecksum(url)
+    % GETCURRENTCHECKSUM Returns the file checksum found on the webpage
+
+    MD5_REGEX = '([a-fA-F\d]{32})';
+
+    % Read and parse webpage
+    webpage = webread(url);
+    parsedPage = textscan(webpage, '%s', 'delimiter', '\n');
+    % Get current checksum
+    checksumLine = parsedPage{1}(contains(parsedPage{1}(:), "md5sum"));
+    [md5start, md5end] = regexp(checksumLine{:}, MD5_REGEX);
+    checksum = checksumLine{:}(md5start:md5end);
+end
+
+function checksum = getlocalchecksum(file)
+    % GETLOCALCHECKSUM Retreive checksum saved locally
+
+    checksum = [];
+    if isfile(file)
+        checksum = fileread(file);
+    end
+end
+
+function savetofile(file, string)
+    % SAVETOFILE Save a string to a file
+
+    fileID = fopen(file, 'w');
+    fprintf(fileID, '%s', string);
+    fclose(fileID);
+end
+
+function copydbfiles(tempdir, dbname, nVolumes)
+    % COPYDBFILES Copy the (interesting) database files
+
+    for iVol = 1:nVolumes
+        volumeDir = [dbname, '/volume-', num2str(iVol)];
+        mkdir(volumeDir);
+        copyfile([tempdir, '/UIUC-propDB/volume-', num2str(iVol), '/data/*'], volumeDir);
+    end
+end
+
+function verboseoutput(quiet, string)
+    % VERBOSEOUTPUT Output information to the console
+
+    if ~quiet
+        fprintf(string);
+    end
+end
+
+function cleanup(tempdir, zipfilename, sumfilename, removeZip, removeSum)
+    % CLEANUP Clean-up directories, files, etc
+
+    % Remove the extracted archive
+    rmdir(tempdir, 's');
+
+    % Remove zip archive
+    if removeZip
+        delete(zipfilename);
+    end
+
+    % Remove checksum
+    if removeSum
+        delete(sumfilename);
+    end
+end