centrifugeR: Non-Trivial Balance of Centrifuge Rotors

Loading tubes in opposite buckets has been used universally, yet intuitively to balance centrifuge rotors. Most rotors support tube distributions with rotational symmetry of order not only 2 but also other prime divisors of the total bucket number. This potential allows rotors to be balanced by the non-trivial placement of tubes, which offers users greater flexibility and more safety in centrifuge operation. Based on linear combinations and random samples, centrifugeR finds the numbers of tubes that can be loaded in centrifuge rotors in a single operation and shows how to balance these tubes in cases of equal or unequal masses.


Introduction
Centrifuges are essential laboratory devices for particle fractionation. The improper use of centrifuges poses many associated hazards (Clark 2001). To reduce the risks, it is crucial to balance centrifuge rotors before the operation. A rotor is balanced when the centers of gravity of the rotor and the tube collection coincide. For rotors that employ single-tube buckets, common practices are distributing tubes in opposite buckets, adding a blank tube to counterweight if the odd numbers of tubes need to be centrifuged, placing tubes at 120 degrees to each other if the number of tubes is divisible by three (Peil and Hauryliuk 2010), and splitting tubes into smaller groups to centrifuge in turn. These practices could be time-consuming and possibly risky. For example, pure water in the blank tube which may not have the same density as the samples will alter the balance.
The balance of centrifuge rotors, however, can be achieved by the non-trivial placement of tubes. It has been proved for a rotor with buckets that balancing identical tubes (0 ≤ ≤ ) is perfectly possible "if and only if both and − are expressible as linear combinations of prime factors of with nonnegative coefficients" (Sivek 2010). In other words, the distribution of loaded buckets in a balanced rotor is fundamentally a superposition of individual sets whose number of elements is a prime divisor of and whose position in the rotor is exclusive (Peil and Hauryliuk 2010). Because rotors normally have an even number of buckets with 2 being its smallest prime divisor, tube distribution with rotational symmetry of order 2 (i.e. tubes in opposite buckets) always works. Other tube distributions with rotational symmetry of order 3, 5, 7, etc. could also be valid, which allows users more flexibility in operating centrifuges.
Notwithstanding its advantage, the non-trivial placement of tubes is difficult to be constructed and also perceived by the human mind. This issue is fully addressed by the centrifugeR package which yields informative results and visualizations. Given a centrifuge, the user will be informed about possible numbers of tubes that can be balanced at one time of operation, their corresponding positions in the rotor, and their required masses in case tubes are not initially identical.

Availability
The centrifugeR package is written in R (R Core Team 2019) and is available on CRAN (https://CRAN.Rproject.org/package=centrifugeR). To install and use centrifugeR:

Illustrative Example
To demonstrate the functionality of centrifugeR, a typical centrifuge rotor with 30 buckets is considered ( = 30). Three prime divisors of are 2, 3, and 5. A certain number of tubes ( ) can be loaded in the rotor if and only if and − are linear combinations of 2, 3, and 5. Function rotorCheck() filters values that meet this condition.
Users dealing with 19 tubes, for instance, tend to add a blank tube (increase from 19 to 20) or split tubes into two turns of centrifugation (break into 16 and 3). Function rotorEqual() can find a non-trivial way to balance 19 tubes. There are more than one possibility to express 19 as a linear combination of 2, 3, and 5 (e.g. 19 = 8 × 2 + 1 × 3 + 0 × 5 and 19 = 2 × 2 + 0 × 3 + 3 × 5). Not all of them work since the position of individual sets in the rotor must be exclusive. rotorEqual() performs random sampling to provide users with a solution (Figure 1).

Rotor with 30 buckets
19 loaded buckets in blue In the case of 19 tubes of unequal initial mass, it is not necessary to increase the mass of 18 tubes to the mass of the heaviest tube. The only requirement is that tubes in the same set must have the same mass. Function rotorUnequal() returns the required masses and the positions of tubes (Figure 2  Due to random sampling, both rotorEqual() and rotorUnequal() can give different results each time given the same input. Users who find it undesirable may use set.seed() before calling the functions.