RCTab is a free, open-source application designed to quickly and accurately tabulate a wide variety of ranked choice voting (RCV) elections, including both single-winner contests and various multi-winner formats (e.g. single transferable vote, a.k.a. STV). It allows users to:
- Create contest configuration files using a graphical user interface (GUI)
- Validate contest configuration files to ensure they are well-formed, and all values are within expected ranges
- Tabulate a contest
A contest configuration file specifies:
- Which tabulation rule variations to use
- A list of registered candidates
- Paths to one or more cast vote record (CVR) files
- Output formatting options (contest name, date, jurisdiction, etc.)
The Tabulator produces the following as output:
- A summary .csv file containing round-by-round vote totals for each candidate and the eventual winner(s)
- A summary .json file containing additional information which can be used by external tools for visualizing contest results
- A detailed audit .log file describing how every ballot was counted in each round over the course of the tabulation
-
Download the pre-compiled Tabulator for your OS from the GitHub releases page.
Note: this download is a "jlink package", which means you don't even need to have Java installed on your machine to run it!
-
Unzip the file, navigate to the
bin
directory, and launch the RCV Tabulator GUI by running thercv
script if using MacOS or Linux, orrcv.bat
if using Windows.
On Linux, you may install the .deb file, then run /opt/rcv/bin/RCTab
to launch the tabulator GUI.
-
Install JDK 20, and make sure your Java path is picking it up properly by verifying that the following command returns the expected version:
$ java -version
If the expected version isn't returned, you'll need to follow the instructions here on how to set your Java path.
If you are using Linux or MacOS and need to regularly switch between Java versions, consider installing jEnv. For a list of the Java versions installed on your machine, run
/usr/libexec/java_home -V
on MacOS orupdate-alternatives --config java
on Linux. -
Download the zip of the source code from GitHub and unzip it, or install git and use the following command at the terminal / command prompt to clone a local copy on your machine:
$ git clone https://github.com/BrightSpots/rcv.git
-
Use the provided version of Gradle to build and run the code from the terminal / command prompt to start the RCV Tabulator GUI:
$ cd rcv-master
(or, if you cloned the repo using git:cd rcv
)$ ./gradlew run
(or, if you're on Windows:gradlew run
)If you get a "permission denied" error in Linux or MacOS, you need to mark the script as executable with:
$ chmod 777 gradlew
- Download Gradle from https://gradle.org/releases/ and place it in your path.
- Download and extract the source code from the releases page.
- Alongside the release you just downloaded, you will find corresponding cache files (cache.[OS].zip). Download this file too.
- Stop the Gradle daemon with
gradle --stop
. - Delete the directory ~/.gradle/caches if it exists.
- Extract the appropriate caches/[filename].zip to ~/.gradle/caches so that the "caches" directory is in ~/.gradle.
- Alongside these extracted caches is a file named checksums.csv. In the extracted directory, you may manually verify each dependency using checksums.csv in accordance with your own policies.
- Run
gradle assemble --offline
and ensure you get no errors. - Run
gradle run --offline
to launch RCTab, orgradle jpackage --offline
to generate an executable file specific to the OS you are using (a .dmg, .exe, or .deb).
For security purposes, we strongly recommend applying password encryption (e.g. 256-bit SHA) to the directory containing the Tabulator, config files, CVR files, and any other related files.
We recommend using open-source utilities such as 7-Zip for Windows or EncFS, gocryptfs, etc. for Linux (see this comparison).
Mac OS has built-in encryption capability that allows users to create encrypted disk images from folders using Disk Utility (see "Create a secure disk image").
The GUI can be used to easily create, save, and load contest configuration files (which are in .json format). These files can also be created manually using any basic text editor, but this method isn't recommended.
In either case, please reference the config file documentation when configuring a contest.
Warning: Using shortcuts, aliases, or symbolic links to launch the Tabulator is not supported; doing so may result in unexpected behavior. Also, please avoid clicking in the command prompt / terminal window when starting the Tabulator GUI, as it may halt the startup process.
The Tabulator includes several example contest configuration files and associated CVR files.
- Click "File > Load..." in the menu and navigate to the
sample_input
folder (if you used Method 2 to install the Tabulator, navigate to thetest_data
folder). - Open one of the folders listed here and select the config file (it will have the
_config.json
suffix). - Click on the configuration tabs (Output, CVR Files, Candidates, Required Rules, Optional Rules) to see how this contest is configured.
- Click "Tabulation > Validate" in the menu to check if this configuration is valid. You will see the results in the console at the bottom of the main window.
- Click "Tabulation > Tabulate" in the menu to tabulate the election. You will see the results in the console, including the location of the output files.
Alternatively, you can run the Tabulator using the command-line interface by including the flag --cli
and then supplying a path to an existing config file, e.g.:
$ rcv --cli path/to/config
Or, if you're compiling and running using Gradle:
$ gradlew run --args="--cli path/to/config"
You can also activate a special convert-to-cdf
function via the command line to export the CVR as a NIST common data
format (CDF) .json instead of tabulating the results, e.g.:
$ rcv --cli path/to/config --convert-to-cdf
This option is available in the GUI by selecting the "Conversion > Convert CVRs in Current Config to CDF" menu option.
Or, again, if you're compiling and running using Gradle:
$ gradlew run --args="--cli path/to/config --convert-to-cdf"
Note: if you convert a source to CDF and that source uses an overvoteLabel or an undeclaredWriteInLabel, the label will be represented differently in the generated CDF source file than it was in the original CVR source. When you create a new config using this generated CDF source file and you need to set overvoteLabel, you should use "overvote". If you need to set undeclaredWriteInLabel, you should use "Undeclared Write-ins".
Tabulator output filenames automatically include the current date and time,
e.g. 2019-06-25_17-19-28_summary.csv
. This keeps them separate if you tabulate the same contest
multiple times.
Look in the console window to see where the output spreadsheet was written, e.g.
2019-06-25 17:19:28 PDT INFO: Generating summary spreadsheet: /rcv/test_data/2018_maine_gov_primary_dem/output/2019-06-25_17-19-28_summary.csv...
The summary spreadsheet (in .csv format), summary .json, and audit .log files are all readable using a basic text editor.
Note: If you intend to print any of the output files, we strongly recommend adding headers / footers with page numbers, the filename, the date and time of printing, who is doing the printing, and any other desired information.
- Jonathan Moldover
- Louis Eisenberg
- Hylton Edingfield