mixsol package

Submodules

mixsol.components module

class mixsol.components.Powder(formula: str, molar_mass: Optional[float] = None, alias: Optional[str] = None)

Bases: object

class mixsol.components.Solution(solvent: str, solutes: str = '', molarity: float = 0, alias: Optional[str] = None)

Bases: object

mixsol.digraph module

class mixsol.digraph.DirectedGraph(adjacency_matrix)

Bases: object

Given an adjacency matrix, allows for some operations on a directed graph.

Specifically, this is used to get the hierarchy/order of solution mixing, and to backpropagate solution needs for all downstream mixing.

children(node: int) list

return list of node indices that a given node is outgoing to

Parameters

node (int) – index of the node from which to get outgoing nodes

Returns

list of node indices outgoing from given node

Return type

list

hierarchy(reverse: bool = False) list

returns generations of the graph hierarchy

Parameters

reverse (bool, optional) – whether to return inner->outer generations (True) or outer->inner(False). Defaults to False.

Returns

nested list of node indices in each generation

Return type

list

indegree(node: int) int

return the number of nodes that are directed in to a given node

Parameters

node (int) – index of the node for which to calculate incoming degree

Returns

incoming degree of node

Return type

int

propagate_load(load: list) list
propagates the final desired load of each node upstream the mixing order.

returns the initial load of each node needed for downstream mixing, such that we end with the desired load at each node.

Parameters

load (list) – list of loads (ending amounts) desired at each node

Raises

ValueError – if the list of loads is a different length than the number of nodes in the graph

Returns

list of starting loads (initial amounts) needed for each node to supply enough load to downstream nodes

Return type

list

mixsol.helpers module

mixsol.helpers.calculate_molar_mass(formula, delimiter='_') float

Given a formula string, try to get the molar mass using the molmass package

Parameters
  • formula (str) – chemical formula to get molar mass for

  • delimiter (str, optional) – delimiter character/string to remove from formula, since molmass does not expect a delimiter. Defaults to “_”.

Raises

ValueError – molmass could not return a molar mass. Often this is because the formula contains non-elemental units (ie MA for methylammonium, which is actually C,N,and H’s)

Returns

molar mass (g/mol)

Return type

float

mixsol.helpers.components_to_name(components: dict, delimiter: str = '_', factor: float = 1) str

Convert a dictionary of components into a string

Parameters
  • components (dict) – {component(str):amount(float)}

  • delimiter (str, optional) – will be inserted between each component. Defaults to “_”.

  • factor (float, optional) – factor to multiply all amounts by. Defaults to 1

Returns

string of (component)(amount)(delimiter) repeat units

Return type

str

mixsol.helpers.name_to_components(name: str, factor: float = 1, delimiter: str = '_') dict

given a chemical formula, returns dictionary with individual components/amounts expected name format = ‘MA0.5_FA0.5_Pb1_I2_Br1’. would return dictionary with keys [‘MA, FA’, ‘Pb’, ‘I’, ‘Br’] and values [0.5,.05,1,2,1]*factor

Parameters
  • name (str) – formula string

  • factor (float) – factor to multiply all amount values in the string by. Defaults to 1.

  • delimiter (str) – indicator string to split the formula into components. Defaults to “_”

Returns

{component:amount}

Return type

dict

mixsol.mix module

class mixsol.mix.Mixer(stock_solutions: list, targets: Optional[dict] = None)

Bases: object

class to calculate mixing paths from a set of stock solutions -> set of target solutions

mix(target: mixsol.components.Solution, volume: float, solution_indices: Optional[list] = None, tolerance: float = 1e-05, min_volume: float = 0, verbose: bool = False, max_inputs: Optional[int] = None) numpy.ndarray

Calculate mixture of stock solutions to achieve target solution

Parameters
  • target (Solution) – target solution

  • volume (float) – volume of target solution desired

  • solution_indices (list, optional) – list of solution (row) indices to consider for mixing. If None (default), assumes all solutions are valid.

  • tolerance (float, optional) – error threhold for target solution. Defaults to 1e-2.

  • min_volume (float, optional) – minimum volume that can be mixed from any single solution (useful for pipettes with a minimum aspiration volume). Defaults to 0.

  • verbose (bool, optional) – if True, returns all plausible mixture vectors. If False (default), only returns the best (largest minimum single volume transfer) vector.

  • max_inputs (int, optional) – maximum number of solutions to mix into the given target. Defaults to None (no limit).

Returns

vector of solution volumes corresponding to rows in the solution matrix (self.solutions). If verbose=True, this will be a list of such vectors that all reach the target solution

Return type

np.ndarray

plot(ax=None)

Plots the pipetting instructions as a directed graph, layered by generation. Will substitute solution names with their .alias if present.

print()

Prints the pipetting instructions in proper order to console in plain english. Will substitute solution names with their .alias if present

solve(min_volume: float, max_inputs: Optional[int] = None, max_generations: int = inf, tolerance: float = 1e-05)

user-facing method to solve mixing strategy for all target solutions

Parameters
  • min_volume (float) – minimum volume for single liquid transfer. useful for pipettes with a minimum aspiration volume

  • max_inputs (int) – maximum number of solutions that can be mixed to achieve a target solution. Default is None.

  • max_generations (int) – maximum generations/rounds of mixing that are allowed. Default is np.inf (ie no limit)

class mixsol.mix.Weigher(powders: list)

Bases: object

class to calculate weights of solute powders from a set of stock powders -> target solution of defined volume+molarity

get_weights(target: mixsol.components.Solution, volume: float, tolerance: float = 1e-10) dict

calculate the weights of stock powders necessary to make a target Solution

Parameters
  • target (Solution) – target solution. molarity will be defined in the Solution object.

  • volume (float) – volume (L) of solution to make

  • tolerance (float, optional) – error in solution molarities to tolerate. This number is a bit arbitrary for now. Defaults to 1e-10.

Raises

Exception – No plausible mix of weights to make this solution

Returns

dictionary of {powder:mass (g)} that should be dissolved to make the target solution.

Return type

dict

weights_to_solution(weights: dict, volume: float, solvent: str, norm=None) mixsol.components.Solution

Returns a Solution object generated by mixing the powder weights and solvent

Parameters
  • weights (dict) – {powder:mass(g)} dictionary. Powders must be present in this Weigher, and can be referred to by the Powder.alias or Powder.formula attributes

  • volume (float) – volume (L) of solvent powder is dispersed into

  • solvent (str) – Formula string for the solvent. ie “IPA”, “DMF9_DMSO1”, “EtOH0.5_IPA0.5”.

  • norm (str/float, optional) – Value to normalize the molarities by. This can be a float value, or the name of a single component of the resulting Solution. Note that this only affects the string representation of the Solution.solutes.

Returns

solution object resulting from the powder mixing

Return type

Solution

Module contents