{ "cells": [ { "cell_type": "raw", "metadata": {}, "source": [ "---\n", "title: Test Design\n", "description: Determines the required parameters to formulate the test procedure\n", "show-code: False\n", "params:\n", " pumps_per_rig:\n", " input: numeric\n", " label: Number of pumps per rig\n", " value: 5\n", " number_of_rigs:\n", " input: numeric\n", " label: Number of rigs\n", " value: 2\n", " ml_per_dispense:\n", " input: numeric\n", " label: Approximate volume per dispense (ml)\n", " value: 0.5\n", " step: 0.1\n", " limonene_batch: \n", " input: numeric\n", " label: Available quantity of limonene solution (ml)\n", " value: 2000\n", " step: 500\n", " lifetime:\n", " input: numeric\n", " label: Required lifetime (dispenses per pump)\n", " value: 10000\n", " step: 1000\n", " number_of_batches:\n", " input: numeric\n", " label: Number of batches to divide the solution into (per rig)\n", " value: 4\n", " dispenses_per_set:\n", " input: numeric\n", " label: Dispenses in a set (inc. ref.)\n", " value: 11\n", " sets_per_day:\n", " input: numeric\n", " label: Number of sets to be completed in a day\n", " value: 3\n", "---" ] }, { "cell_type": "code", "execution_count": 58, "metadata": {}, "outputs": [], "source": [ "pumps_per_rig = 5\n", "number_of_rigs = 2\n", "ml_per_dispense = 0.5\n", "limonene_batch = 2000\n", "lifetime = 10000\n", "number_of_batches = 4\n", "dispenses_per_set = 11\n", "sets_per_day = 3" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "from IPython.display import Latex, Markdown\n", "import numpy as np" ] }, { "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "# Limonene Testing Test 2\n", "\n", "The previous test that investigated the lifetime performance of peristaltic pumps recycled the limonene solution back into the reservoir \\\n", "from which the dispenses were taken. In this test, the pumps performed well, all remaining within $\\pm$10% of their initial doses over \\\n", "the full lifetime of dispenses. This test demonstrates good performance from the perspective of cyclical stress on the tubing when in \\\n", "contact with a limonene solution. However, since the limonene is recycled and the timeframe of the 10000 dispenses is condensed from several \\\n", " months to just a couple of weeks, it does not assess the time-dependent impact of any chemical interaction of limonene with the tubing. Hence \\\n", " this additional test has been proposed in which the limonene solution is split into batches and replaced at intervals throughout the test. \\\n", " By using fresh batches incrementally throughout the test, we can observe any influence on the freshness of the solution on the accuracy. \\\n", " To ensure the complete proposed lifetime of dispenses can be measured from the limited quantity of limonene solution, parameters of the \\\n", " proposed test can be determined as follows:\n" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "sizeA = '20px'\n", "sizeB = '30px'\n", "sizeC = '40px'" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ " Limonene Testing Test 2
" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "

The previous test that investigated the lifetime performance of peristaltic pumps recycled the limonene solution back into the reservoir from which the dispenses were taken. In this test, the pumps performed well, all remaining within $\\pm$10% of their initial doses over the full lifetime of dispenses. This test demonstrates good performance from the perspective of cyclical stress on the tubing when in contact with a limonene solution. However, since the limonene is recycled and the timeframe of the 10000 dispenses is condensed from several months to just a couple of weeks, it does not assess the time-dependent impact of any chemical interaction of limonene with the tubing. Hence this additional test has been proposed in which the limonene solution is split into batches and replaced at intervals throughout the test. By using fresh batches incrementally throughout the test, we can observe any influence on the freshness of the solution on the accuracy. To ensure the complete proposed lifetime of dispenses can be measured from the limited quantity of limonene solution, parameters of the proposed test can be determined as follows:

" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "display(Markdown(f\" Limonene Testing Test 2
\"))\n", "\n", "display(Markdown(f\"

\\\n", " The previous test that investigated the lifetime performance of peristaltic pumps recycled the limonene solution back into the reservoir \\\n", " from which the dispenses were taken. In this test, the pumps performed well, all remaining within $\\pm$10% of their initial doses over \\\n", " the full lifetime of dispenses. This test demonstrates good performance from the perspective of cyclical stress on the tubing when in \\\n", " contact with a limonene solution. However, since the limonene is recycled and the timeframe of the 10000 dispenses is condensed from several \\\n", " months to just a couple of weeks, it does not assess the time-dependent impact of any chemical interaction of limonene with the tubing. Hence \\\n", " this additional test has been proposed in which the limonene solution is split into batches and replaced at intervals throughout the test. \\\n", " By using fresh batches incrementally throughout the test, we can observe any influence on the freshness of the solution on the accuracy. \\\n", " To ensure the complete proposed lifetime of dispenses can be measured from the limited quantity of limonene solution, parameters of the \\\n", " proposed test can be determined as follows:

\"))" ] }, { "cell_type": "code", "execution_count": 61, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "Input Parameters

" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "

Number of pumps in a rig = 5

" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "

Number of rigs used = 2

" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "

Approximate dispense volume = 0.5

" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "

Total volume of limonene solution available = 2000

" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "

Required number of dispenses per pump (i.e. required lifetime) = 10000

" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "

Number of batches to divide the limonene solution into (per rig) = 4

" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "

Number of dispenses in a set (including the reference dispense = 11

" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "display(Markdown(f\"

Input Parameters

\"))\n", "\n", "display(Markdown(f\"

Number of pumps in a rig = {pumps_per_rig}

\"))\n", "\n", "display(Markdown(f\"

Number of rigs used = {number_of_rigs}

\"))\n", "\n", "display(Markdown(f\"

Approximate dispense volume = {ml_per_dispense}

\"))\n", "\n", "display(Markdown(f\"

Total volume of limonene solution available = {limonene_batch}

\"))\n", "\n", "display(Markdown(f\"

Required number of dispenses per pump (i.e. required lifetime) = {lifetime}

\"))\n", "\n", "display(Markdown(f\"

Number of batches to divide the limonene solution into (per rig) = {number_of_batches}

\"))\n", "\n", "display(Markdown(f\"

Number of dispenses in a set (including the reference dispense = {dispenses_per_set}

\"))\n", "\n" ] }, { "cell_type": "code", "execution_count": 83, "metadata": {}, "outputs": [], "source": [ "volume_per_pump = lifetime * ml_per_dispense\n", "dispensed_vol_per_rig = volume_per_pump * pumps_per_rig\n", "allocated_vol_per_rig = limonene_batch / number_of_rigs\n", "refills_per_batch = dispensed_vol_per_rig / allocated_vol_per_rig\n", "total_number_refills = refills_per_batch * number_of_batches\n", "min_number_dispenses_per_refill = lifetime / total_number_refills\n", "sets_per_refill = min_number_dispenses_per_refill / dispenses_per_set\n", "r_sets_per_refill = np.floor(sets_per_refill)\n", "frequency_of_sets = 24 / sets_per_day\n", "ml_per_batch = allocated_vol_per_rig / number_of_batches\n", "frequency_of_reloads = frequency_of_sets * r_sets_per_refill\n", "frequency_of_batch_replacement = frequency_of_reloads * refills_per_batch / 24\n", "total_dispenses = dispenses_per_set * r_sets_per_refill * total_number_refills\n", "additional_sets = np.ceil((lifetime - total_dispenses) / dispenses_per_set)" ] }, { "cell_type": "code", "execution_count": 73, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "Calculated Parameters

" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "

Approximate total volume dispensed by each pump over its lifetime.

" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/latex": [ " $$ \\large volume \\, per \\, pump = lifetime \\, dispenses \\, \\times ml \\, per \\, dispense = 10000 \\times 0.5 = 5000.0ml$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "

Approximate total volume dispensed by a rig of 5 pumps.

" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/latex": [ " $$ \\large volume \\, per \\, rig = volume \\, per \\, pump \\times pumps \\, per \\, rig = 5000.0 \\times 5 = 25000.0ml$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "

Volume of limonene solution allocated to a rig.

" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/latex": [ " $$ \\large solution \\, per \\, rig = \\frac{total \\, solution}{number \\, of \\, rigs} =\\frac{2000}{2} = 1000.0$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "

The number of times a batch of solution needs to be reloaded into a rig's reservoir.

" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/latex": [ " $$ \\large refills \\, per \\, batch = \\frac{volume \\, per \\, rig}{solution \\, per \\, rig}= \\frac{25000.0}{1000.0} = 25.0$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "

The total number of times a reservoir needs to be refilled.

" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/latex": [ " $$ \\large total \\, reservoir \\, refills = refills \\, per \\, batch \\times number \\, of \\, batches = 25.0 \\times 4 = 100.0$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "

The maximum number of dispenses allowed for each pump for each refill of a batch.

" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/latex": [ " $$ \\large dispenses \\, per \\, refill = \\frac{lifetime \\, dispenses}{total \\, reservoir \\, refills}= \\frac{10000}{100.0} = 100.0$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "

The number of sets that need to be completed per refill to ensure the maximum number of dispenses per refill is not exceeded.

" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/latex": [ " $$ \\large required \\, sets \\, per \\, refill = \\huge\\lfloor \\large \\frac{dispenses \\, per \\, refill}{dispenses \\, per \\, refill} \\huge\\rfloor \\large= \\huge\\lfloor \\large \\frac{100.0}{11} \\huge\\rfloor \\large = \\lfloor 9.09 \\rfloor = 9.0$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "

Frequency of the sets.

" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/latex": [ " $$ \\large frequency \\, of \\, sets = \\frac{24}{sets \\, per \\, day}= \\frac{24}{3} = 8.0 \\, hours$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "

The number of hours between reservoir refills.

" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/latex": [ " $$ \\large frequency \\, of \\, refills = required \\, sets \\, per \\, refill \\times frequency \\, of \\, sets = 8.0 \\times 9.0 = 72.0 \\, hours$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/markdown": [ "

The number of days between batch replacement.

" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/latex": [ " $$ \\large frequency \\, of \\, bacth \\, replacement = \\frac{refills \\, per \\, batch \\times frequency \\, of \\, refills}{24} = 72.0 \\times 25.0 \\div 24 = 75.0 \\, days$$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "display(Markdown(f\"

Calculated Parameters

\"))\n", "\n", "display(Markdown(f\"

Approximate total volume dispensed by each pump over its lifetime.

\"))\n", "display(Latex(r\" $$ \\large volume \\, per \\, pump = lifetime \\, dispenses \\, \\times ml \\, per \\, dispense = {} \\times {} = {}ml$$\".format(lifetime, ml_per_dispense, volume_per_pump)))\n", "\n", "display(Markdown(f\"

Approximate total volume dispensed by a rig of {pumps_per_rig} pumps.

\"))\n", "display(Latex(r\" $$ \\large volume \\, per \\, rig = volume \\, per \\, pump \\times pumps \\, per \\, rig = {} \\times {} = {}ml$$\".format(volume_per_pump, pumps_per_rig, dispensed_vol_per_rig)))\n", "\n", "display(Markdown(f\"

Volume of limonene solution allocated to a rig.

\"))\n", "display(Latex(r\" $$ \\large solution \\, per \\, rig = \\frac{total \\, solution}{number \\, of \\, rigs} =\" + r\"\\frac{{{}}}{{{}}} = {}$$\".format(limonene_batch, number_of_rigs, allocated_vol_per_rig)))\n", "\n", "display(Markdown(f\"

The number of times a batch of solution needs to be reloaded into a rig's reservoir.

\"))\n", "display(Latex(r\" $$ \\large refills \\, per \\, batch = \\frac{volume \\, per \\, rig}{solution \\, per \\, rig}\" + r\"= \\frac{{{}}}{{{}}} = {}$$\".format(dispensed_vol_per_rig, allocated_vol_per_rig, refills_per_batch)))\n", "\n", "display(Markdown(f\"

The total number of times a reservoir needs to be refilled.

\"))\n", "display(Latex(r\" $$ \\large total \\, reservoir \\, refills = refills \\, per \\, batch \\times number \\, of \\, batches = {} \\times {} = {}$$\".format(refills_per_batch, number_of_batches, total_number_refills)))\n", "\n", "display(Markdown(f\"

The maximum number of dispenses allowed for each pump for each refill of a batch.

\"))\n", "display(Latex(r\" $$ \\large dispenses \\, per \\, refill = \\frac{lifetime \\, dispenses}{total \\, reservoir \\, refills}\" + r\"= \\frac{{{}}}{{{}}} = {:.1f}$$\".format(lifetime, total_number_refills, min_number_dispenses_per_refill)))\n", "\n", "display(Markdown(f\"

The number of sets that need to be completed per refill to ensure the maximum number of dispenses per refill is not exceeded.

\"))\n", "display(Latex(r\" $$ \\large required \\, sets \\, per \\, refill = \\huge\\lfloor \\large \\frac{dispenses \\, per \\, refill}{dispenses \\, per \\, set} \\huge\\rfloor \\large\" + r\"= \\huge\\lfloor \\large \\frac{{{}}}{{{}}} \\huge\\rfloor \\large = \\lfloor {:.2f} \\rfloor = {}$$\".format(min_number_dispenses_per_refill, dispenses_per_set, sets_per_refill, r_sets_per_refill)))\n", "\n", "\n", "\n", "\n", "display(Markdown(f\"

Frequency of the sets.

\"))\n", "display(Latex(r\" $$ \\large frequency \\, of \\, sets = \\frac{24}{sets \\, per \\, day}\" + r\"= \\frac{{{}}}{{{}}} = {} \\, hours$$\".format(24, sets_per_day, frequency_of_sets)))\n", "\n", "display(Markdown(f\"

The number of hours between reservoir refills.

\"))\n", "display(Latex(r\" $$ \\large frequency \\, of \\, refills = required \\, sets \\, per \\, refill \\times frequency \\, of \\, sets = {} \\times {} = {} \\, hours$$\".format(frequency_of_sets, r_sets_per_refill, frequency_of_reloads)))\n", "\n", "display(Markdown(f\"

The number of days between batch replacement.

\"))\n", "display(Latex(r\" $$ \\large frequency \\, of \\, bacth \\, replacement = \\frac{refills \\, per \\, batch \\times frequency \\, of \\, refills}{24} \" + r\"= {} \\times {} \\div {} = {} \\, days$$\".format(frequency_of_reloads, refills_per_batch, 24, frequency_of_batch_replacement)))\n", "\n" ] }, { "cell_type": "code", "execution_count": 82, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "

The limonene solution needs to be split into batches of 250.0ml. Sets of 11 dispenses, all recorded by the csv file, should be completed every 8.0 hours until 9.0 sets have been completed. At which point, the test should be halted, the batch reloaded into the reservoir and then resumed. Hence, each batch should be reloaded into the reservoir every 72.0 hours for a total of 25.0 times and be replaced with a fresh batch every 75.0 days. With 4 batches per rig, this results in a total test duration of 288.0 days.

10.0 additional sets are required with the final batch of solution to ensure the total number of dispenses exceeds 10000, thereby accommodating for rounding discrepanies.

" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "display(Markdown(f\"

Test Procedure

\"))\n", "\n", "display(Markdown(f\"

The limonene solution needs to be split into batches of {ml_per_batch}ml. \\\n", " Sets of {dispenses_per_set} dispenses, all recorded by the csv file, should be completed every {frequency_of_sets} hours until {r_sets_per_refill} sets have been completed. \\\n", " At which point, the test should be halted, the batch reloaded into the reservoir and then resumed. \\\n", " Hence, each batch should be reloaded into the reservoir every {frequency_of_reloads} hours for a total of {refills_per_batch} times and be replaced with a fresh batch every {frequency_of_batch_replacement} days.\\\n", " With {number_of_batches} batches per rig, this results in a total test duration of {number_of_batches * frequency_of_reloads} days.

\\\n", " {additional_sets} additional sets are required with the final batch of solution to ensure the total number of dispenses exceeds {lifetime}, thereby accommodating for rounding discrepanies. \\\n", "

\"))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.10" }, "orig_nbformat": 4 }, "nbformat": 4, "nbformat_minor": 2 }