Langmuir Trough\n\nThis software is a custom controller and GUI for the research Langmuir trough \nin the Gutow Lab at UW Oshkosh. It is written in Python and expects to run in a\nJupyter notebook environment. However, all of the parts that are not elements\nof the user interface should work in a vanilla Python environment.
\n\nHardware requirements:\nRaspberry Pi compatible system with a Pi-Plates \nDAQC2 data acquisition plate \nand a trough controlled by the DAQC2 plate. This software could be used with \na trough controlled some other way by rewriting the routines in trough_util.\npy
. The GUI front end would need no rewriting to use with a different \ntrough if a custom backend controlling the barriers, reading the temperature \nand Whilhelmy balance is written. The backend needs to continually monitor \nthe trough and respond to the following commands: Stop, Send, Start, \nDirection, Speed, MoveTo, MotorCal, ConstPi, DataLabels, ShutDown
.
\n\nIf you do not have compatible hardware the GUI will run with a simulated \ntrough, allowing you to see how it works.
\n\nUsage
\n\nOnce installed:
\n\n\n- Turn on the power supply for the trough.
\n- In a terminal navigate to the directory containing the trough software.
\n- Start the virtual environment
pipenv shell
. \n- Launch Jupyter
jupyter notebook
(jupyter lab
also works and is now \nmore stable). \n- Create a folder for the new day using the New menu near the top right \nof the Jupyter browser page. Give it an appropriate name.
\n- Switch to that folder by clicking on it.
\n- Start a new ipython notebook using the New menu. Give it a\nname that describes the experiment.
\n- In the first cell initialize the trough by running the command
from \nTrough import Trough_GUI
. This will take a while to run the first time \nit is run each day because it needs to check the movement of the barriers. \n- To control and monitor the trough or do calibrations run the command \n
Trough_GUI.Controls(Trough_GUI.calibrations)
\n- Do not do any real runs without making sure the calibrations are correct.
\n- To start data collection (a run) run the command \n
Trough_GUI.Collect_data.Run(\"name_for_run\")
, \nwhere you replace name_for_run with the text for the name of the run (no \nspaces). \n- Set the run conditions.
\n- You can start data collection by clicking the green \"Run\" button.
\n- If you set the speed to zero the data collection will be displayed \nversus time and will not stop until you click the red \"Stop\" button.
\n
\n\nInstallation
\n\nOS setup - Ubuntu on Pi
\n\nBy default in Ubuntu 20.04 for Pis the gpio and spi groups do not exist.\nThe i2c group does (not always).
\n\n\n- Make sure that the following packages are installed
rpi.gpio-common \npython3-pigpio python3-gpiozero python3-rpi.gpio
. \n- You can avoid having to create a gpio group, by assigning users who need\n gpio access to the dialout group. Check that /dev/gpiomem is part of that \ngroup and that the dialout group has rw access. If not you will need to set\n it.
\n- Users also need to be members of the i2c group. If it does not exist create \n it and then make that the group for /dev/i2c-1 with group rw permissions. \nTHIS MAY NOT BE NECESSARY.
\n- The spi group needs to be created (addgroup?).
\n- Additionally the spi group needs to be given rw access to the spi devices\nat each boot. To do this create a one line rule in a file named \n
/etc/udev/rules.d/50-spidev.rules
containing SUBSYSTEM==\"spidev\", \nGROUP=\"spi\", MODE=\"0660\"
. The file should have rw permission for root \nand read permission for everyone else. \n- Make sure you have pip installed for \npython 3:
python3 -m pip --version
or pip3 --version
. If you do not, \ninstall using apt \ninstall python3-pip
. \n
\n\nTrough Software Installation
\n\nTo avoid library conflicts the software should be installed into a virtual environment.\nInstructions for doing this using pipenv\nfollow.
\n\nLog into your chosen user account:
\n\n\n- Install pipenv:
pip3 install \n--user pipenv
. You may\nneed to add ~/.local/bin
to your PATH
to make pipenv
\navailable in your command shell. More discussion: \nThe Hitchhiker's Guide to\nPython. \n- Create a directory for the virtual environment you will be installing\ninto (example:
$ mkdir Trough
). \n- Navigate into the directory
$ cd Trough
. \n- Create the virtual environment and enter it
$ pipenv shell
. To get out of\nthe environment you can issue the $ exit
command on the command line. \n- While still in the shell install the latest trough software and all its\nrequirements\n
$ pip install -U langmuir_trough
. \n- Still within the environment shell test\nthis by starting jupyter
$ jupyter notebook
. Jupyter should launch in your \nbrowser.\n\n- Open a new notebook using the default (Python 3) kernel.
\n- In the first cell import the Trough_GUI: \n
from Trough import Trough_GUI
.\n When run this cell sets things up and tries to talk to the trough. \n
\n- If you wish, you can make this environment available to an alternate Jupyter\ninstall as a special kernel when you are the user.\n
\n- Make sure you are running in your virtual environment
$ pipenv shell
\nin the directory for virtual environment will do that. \n- Issue the command to add this as a kernel to your personal space: \n
$ python -m ipykernel install --user --name=<name-you-want-for-kernel>
. \n- More information is available in the Jupyter/Ipython documentation. \nA simple tutorial from Nikolai Jankiev (_Parametric Thoughts_) can be\nfound here.
\n
\n
\n\nChange Log
\n\n\n- 0.6.0dev\n
\n- Documentation updates including Gutow Lab Standard Operating Procedures \n(SOPs).
\n- Refactored everything to underneath the module
Trough
. \n
\n- 0.5.2 (Mar. 16, 2023) Now works in Jupyter Lab.\n
\n- Adjusted widget updating/clearing to work in Jupyter lab.
\n- Added JupyterLab >= 3.6.1 to requirements.
\n
\n- 0.5.1 (Mar. 9, 2023) \n
\n- Include
spidev
package in requirements. \n- More details reported when unable to \"find trough\".
\n
\n- 0.5.0 (Mar. 4, 2023) First version with working GUI
\n- 0.1.0 First pypi compatible package version.
\n
\n\nKnown issues
\n\n\n- 0.5.0 - 0.5.2 The estimated error on values converted to metric units \nbased on calibration fits appears to be too pessimistic.
\n
\n\nDevelopment
\n\n\n\n\n- For development purposes clone the GIT repository.
\n- Create the virtual environment to run it in within the development \ndirectory
pipenv shell
. \n- Within the shell pip install for development
pip install -e .
. \n
\n\nConstructing the Documentation
\n\n\n- Make sure pdoc is installed and updated in the virtual environment
pip \ninstall -U pdoc
. \n- Update any
.md
files included in _init_.py
.\n\n- Generally URLs should be absolute, not relative.
\n
\n- At the root level run pdoc
pdoc --logo-link\nhttps://gutow.github.io/Langmuir_Trough/ --footer-text \"Langmuir_Trough vX.X.X\" \n--math -html -o docs Trough
where X.X.X
is the version number. \n- Because of the way the document building process works the background tasks \nwill be started. You will have to stop the document build after the \ndocumentation is done building (watch the
doc
folder) with a ^C
to \nterminate it. \n
\n\nReleasing on PyPi
\n\nProceed only if testing of the build is successful.
\n\n\n- Update packaging software
pip install -U setuptools wheel twine
\n- Double check the version number in
setup.py
. \n- Rebuild the release:
python -m setup sdist bdist_wheel
. \n- Upload it:
python -m twine upload dist/*
\n- Make sure it works by installing it in a clean virtual environment.
pip \ninstall -U ...
. Copy the actual link from pypi.org.\n`. If it does not work, pull the release. \n
\n\nIdeas/Things to do
\n\n\n- Make more robust by wrapping data collection in
try ...
so that it can \nexit more gracefully and give up barrier monitoring? \n- Add explanation of how to use the barrier watch deamon to prevent barrier \ncrashing if software fails.
\n
\n\nLangmuir Trough Standard Operating Procedures for the Gutow Lab
\n\nInitialization
\n\n\n- Check that recirculating temperature controller is connected to the \ntrough. Then turn it on and verify that the temperature is set to what \nyou want. Stabilization time is about 20 minutes for temperatures near \nroom temperature.
\n- Turn on power to the trough.
\n- Open a terminal and navigate to the
Trough
directory of the user \nTrough
. \n- Activate the trough python environment
pipenv shell
\n- Launch Jupyter Lab
jupyter lab
. \n- Within Jupyter Lab create a new folder for the Day. Name it something \nlike \"DescriptiveWord_MMM_DD_YYYY\", where MMM = three letter month \nabbreviation, DD = day of the month and YYYY = the year.
\n- Open the folder by clicking on it.
\n- Open a new Notebook. Give it a descriptive name.
\n- In the first cell run the command
from Trough import Trough_GUI
. If the \ntrough has not been started in the last 12 hours this will take a while \nas it checks the motor calibration for moving the barriers. \n
\n\nChecking Trough and Subphase Cleanliness
\n\nThis need to be done before each experiment.
\n\n\n- We usually use high-purity water as the subphase. Primarily this is \n18+ MΩ de-ionized water mixed with KMnO4 and redistilled.\nDepending on the status of the water polishers, it is sometimes possible \nto use 18+ MΩ water from these directly.
\n- If the trough is already filled with subphase (1 - 1.5 mm above trough \nedges) and the Wilhelmy plate is installed skip steps 3 - 6.
\n- Calibrate the Wilhelmy balance\nif necessary.
\n- Hang a clean filter paper Wilhelmy plate from a fine wire on the balance. \nMake sure that you know the circumference of the plate in mm. This should be \nrecorded in the Jupyter Notebook you are running. Our default \ncircumference is 21.5 mm.
\n- The subphase should fill the trough so that it rises 1 - 1.5 mm above the \nedges of the trough. To add subphase use the clean glass funnel in the trough \nisolation box to pour through (pouring directly from a bottle splashes). \nThe funnel makes it much easier to add subphase when the polycarbonate lid \nwith just a small opening is in use. Always add subphase between the \nbarriers to trap any surface active species between them for easier removal.
\n- Adjust the height of the Wilhelmy balance so the plate is partially \nsubmerged in the subphase. The balance settling time is long. You will \nhave to wait at least 1 minute before any measurements will be valid. \nWith a reasonably clean trough and subphase the unzeroed balance should \nsettle to a surface pressure < 10 mN/m. If it does not or shows no noise, \nthere may be a problem.
\n- If necessary initialize the trough then start the \ntrough control and calibration tool by running the command \n
Trough_GUI.Controls(Trough_GUI.calibrations)
in an empty cell of the \nnotebook. \n- Expand the \"Manual Barrier Control\" accordian. Set the direction to \n\"open\". Set the speed to maximum (~10 cm/min). Click the start button. \nWatch the surface pressure indicator. When the barriers stop (~12.7 cm \nseparation), wait to make sure the surface pressure has stabilized.
\n- Switch the direction to \"close\". Set the speed to the maximum closing \nspeed (~6.8 cm/min). Click the start button. Watch the surface pressure \nindicator.
\n- Once the barriers are fully closed (~2.8 cm separation), check the \nsurface pressure. If it is greater than it was when fully open carefully \naspirate the surface between the barriers without catching the Wilhelmy \nplate until the surface pressure is slightly less than observed for the \nopen barriers.
\n- Repeat steps 8 - 10 up to 4X to get the surface clean. If it is still \nnot clean:\n
\n- Raise the Wilhelmy balance carefully and rotate it aside. Make \nsure to lock it in place.
\n- Remove the polycarbonate lid if it is in place. Store it so that it \ndoes not get contaminated.
\n- Aspirate all the subphase out of the trough and try again.
\n
\n- If after a second try the trough and subphase are still not clean the \ntrough probably needs to be cleaned.
\n- When it appears clean test:\n
\n- Manually open the barriers all the way.
\n- Set up a run by executing the command \n
Trough_GUI.Collect_Data.Run(\"XXX\")
, where XXX is replaced with a \nname for the run (e.g. \"clean_test_MMM_DD_YYYYa\") in an empty cell. \n- Set the units to cm separation. Set the speed to 1 cm/min. Set the \nfinal separation to the minimum for the trough (~2.86 cm).
\n- When the surface pressure is stable click on the \"zero pressure\" \nbutton to tare the Wilhelmy balance.
\n- Click start. The run will stop when the barriers reach the target \nseparation. You can also stop the collection by clicking the \"stop\" \nbutton.
\n- If the surface pressure stays between -0.2 and +0.2 mN/m the trough \nis adequately clean.
\n
\n
\n\nStorage of Trough Between Runs
\n\n\n- If the trough is being used regularly (1X/week or more): store the trough \nwith clean subphase in it. If the subphase is water make sure that the \nhumidification beaker in the isolation box is kept about 50% full.
\n- If the trough will be unused for a significant time:\n
\n- After verifying the trough and subphase cleanliness\naspirate off all the subphase.
\n- Empty the humidification beaker.
\n- Cover the trough with the polycarbonate lid.
\n- Make sure the isolation box is closed.
\n- Make sure the power supply is off.
\n- Shut down the computer.
\n
\n
\n\nHandling Spreading Solvent(s)
\n\nIt is extremely easy to contaminate the solvents with surface active \ncompounds at a level that will ruin experiments
\n\n\n- Generally HPLC grade solvents are adequately clean. We most commonly use \nHPLC grade hexanes and absolute ethanol.
\n- All glassware must be carefully cleaned before using to transfer or \ncontain spreading solvents.\n
\n- If unsure of basic cleanliness wash well with soap and water. Rinse \nfive (5) times with warm tap water. Rinse three (3) times with \nde-ionized water.
\n- Rinse two (2) times with absolute ethanol (10% - 20% container volume per \nrinse).
\n- Rinse six (6) times with the spreading solvent (10% - 20% container volume \nper rinse).
\n
\n- Do not stick anything into the clean spreading solvent stock bottle. Get \nsamples to work with by pouring into properly cleaned intermediate containers.
\n
\n\nChecking Spreading Solvent Cleanliness
\n\n\n- Transfer < 1 mL of spreading solvent to a\nproperly cleaned vial.
\n- Initialize the trough and \nverify that the subphase is clean.
\n- Using the \"Manual Barrier Controls\" open the barriers all the way.
\n- Rinse the positive displacement microdispenser 3X with absolute ethanol \nfrom a TFE squeeze bottle and then 3X with HPLC grade hexanes from a TFE \nsqueeze bottle.
\n- Rinse with the solvent sample being tested 6X by sucking up 90 µL \nof the solvent sample and dispensing it into a waste beaker.
\n- Dispense 90 µL of the solvent sample onto the surface between the \nbarriers.
\n- Allow to evaporate (15 min is adequate for hexanes).
\n- Perform a compression at 1 cm/min from fully \nopen to fully closed.
\n- The solvent is clean if the surface pressure stays between -0.2 and +0.2 \nmN/m.
\n
\n\nMaking a Spreading Solution
\n\nFor most molecules we want to spread about 3.00 X 10-8 moles of \nmolecules on our trough to get a range of roughly 60 to 15 square Angstroms per \nmolecule during a compression.
\n\n\n- The ideal volume to spread is 50 µL of solution. Thus we want a \nconcentration near (3.00 X 10-8 moles)/(50.0 X 10-6 L)\n= 6 X 10-4 M. It is practical to spread anywhere between 20 \nand 90 µL. So, you can adapt to concentrations that vary between 1.00 \nx 10-3 M and 3.3 X 10-4 M.
\n- Ideally your molecule will dissolve in pure hexanes at a concentration of \n6 X 10-4 M. If it is not soluble you can put a few percent (up \nto 5% v/v) of ethanol in with the hexanes. This solvent mixture works for \nmany surfactants, without significantly impacting the surface tension of \na water subphase.
\n- Experiments take very little solution, so make as small volumes of \nsolution as possible. Note that you should not try to measure out \nsurfactant in amounts that produce less than three significant figures on \na standard analytical balance (e.g. at least 10 mg, preferably 50 mg or \nmore.) This may mean that you will have to make a stock solution and \ndilute it to get in the correct concentration range.
\n- All solutions must be made using \nproperly cleaned glassware and spreading \nsolvents that have been\nverified to be clean. Use \nvolumetric flasks with ground glass stoppers to avoid contamination by \nthe plasticizers found in most polymer caps.
\n- Because the solvents are very volatile the solutions will not keep long \nin the volumetric flasks with ground glass stoppers. They can be \ntransferred for somewhat longer term storage to sealed brown bottles \nif the bottles are \nproperly washed \nand you have verified that a little solvent stored in the bottle \novernight and shaken stays clean.
\n
\n\nSpreading a Sample
\n\n\n- Rinse a small vial 2X with absolute ethanol from a TFE squeeze bottle \nthen 3X with hexanes from a TFE squeeze bottle.
\n- If you need to use a pipette or funnel (the funnel is a better choice as \nyou are less likely to contaminate the stock spreading solution) to transfer \nthe spreading solution to the vial rinse the pipette or funnel 2X with \nabsolute ethanol from a TFE squeeze bottle and then 3X with hexanes from \na TFE squeeze bottle.
\n- Rinse the transfer tool with the spreading solution 6X.
\n- Rinse the vial 6X (10-20% of vial volume) with the spreading solution.
\n- Use the transfer tool to transfer about 1 mL of the spreading solution to \nthe small vial.
\n- Set the positive displacement dispenser to the volume you will be \ndispensing.
\n- Rinse the dispenser 2X with absolute ethanol from a TFE squeeze bottle \nthen 3X with hexanes from a TFE squeeze bottle. Make sure you move the \nplunger through its dispensing motion while doing this.
\n- When the dispenser is dry, rinse 6X with the spreading solution making \nsure to take up the full amount to be dispensed on each rinse.
\n- With the barriers fully open dispense the spreading solution drop wise \nonto the surface between the barriers. Avoid the Wilhelmy plate.
\n- Allow time for the solvent to evaporate (~ 15 minutes for hexanes) \nbefore doing a compression.
\n
\n\nRunning a Compression
\n\n\n- Trough must first be\nverified to be clean.
\n- Spread the surfactant solution on the trough with the barriers open. \nAllow sufficient time for the solvent to evaporate (~15 min for hexanes). \nThe amount to spread will depend on your target range for area per \nmolecule and the concentration of your solution (10-4 - \n10-3 M is typical).
\n- In a new notebook cell execute the command \n
Trough_GUI.Collect_Data.Run(\"XXX\")
, where XXX is replaced with a \n name for the run (e.g. \"CompoundName_MMM_DD_YYYYa\") \n- Adjust the moles of molecules to the moles of surfactant you spread. \nAdjust the units to Angstroms squared per molecule. Choose your desired \nfinal target area and compression speed.
\n- When the solvent is fully evaporated zero the balance.
\n- Store the settings.
\n- When ready click the \"Start\" button. The collection will stop when the \ndesired area is reached. You can also stop the run by clicking the \"Stop\" \nbutton.
\n
\n\nCalibrating the Wilhelmy Balance
\n\nThis should be done at the beginning of any day real data is collected
\n\n\n- If it is not already running launch the trough control and calibration \ntool by running the command
Trough_GUI.Controls(Trough_GUI.calibrations)\n
in an empty notebook cell. \n- Expand the \"Calibrate Balance\" accordian and follow the on screen \ninstructions.
\n
\n\nCalibrating Barrier Position and Speed
\n\nThis only needs to be done if a check of the measured barrier separation \nis off by more than \u00b10.03 mm
\n\n\n- If it is not already running launch the trough control and calibration \ntool by running the command
Trough_GUI.Controls(Trough_GUI.calibrations)\n
in an empty notebook cell. \n- Expand the \"Calibrate Barriers\" accordian and follow the on screen \ninstructions.
\n
\n\nCalibrating the Temperature Probe.
\n\nThis is very stable so should not need to be done often
\n\n\n- If it is not already running launch the trough control and calibration \ntool by running the command
Trough_GUI.Controls(Trough_GUI.calibrations)\n
in an empty notebook cell. \n- Expand the \"Calibrate Temperature\" accordian and follow the on screen \ninstructions.
\n- A good source of known temperatures is the thermostat recirculator.
\n
\n\nCleaning the Trough
\n\n\n- The cleaning solution 1:1 concentrated nitric acid:concentrated sulfuric \nacid is extremely dangerous and also has potential to damage parts of the \ntrough. Do not perform this cleaning procedure until Dr. Guto has \ncertified you for the process.
\n- The trough can be powered down during this procedure.
\n- The Wilhelmy balance should be locked in position out of the way.
\n- The polycarbonate lid should be removed (store it so that does not get \ncontaminated).
\n- Fill the trough with the 1:1 concentrated nitric:sulfuric acid solution. \nAllow to sit 10 + minutes.
\n- While the cleaning solution sits in the trough make sure the aspirator \ntrap is dry.
\n- Aspirate off the cleaning solution. \n
\n- Unless the trough is extremely dirty the collected cleaning \nsolution may be returned to the cleaning solution storage bottle.
\n- If disposing of the cleaning solution treat it as strong acid waste and \nneutralize properly.
\n
\n- Rinse the trough twice with clean water subphase.
\n- Check the cleanliness of the trough
\n
\n"}, {"fullname": "Trough.Trough_Control", "modulename": "Trough.Trough_Control", "kind": "module", "doc": "\n"}, {"fullname": "Trough.Trough_Control.message_utils", "modulename": "Trough.Trough_Control.message_utils", "kind": "module", "doc": "\n"}, {"fullname": "Trough.Trough_Control.message_utils.extract_messages", "modulename": "Trough.Trough_Control.message_utils", "qualname": "extract_messages", "kind": "function", "doc": "Parameters
\n\ndatapkg: list\nlist of lists containing trough data bundle, messages in the last list.
\n\nReturns
\n\nlist\nlist of strings consisting of the messages.
\n", "signature": "(datapkg):", "funcdef": "def"}, {"fullname": "Trough.Trough_Control.simulation", "modulename": "Trough.Trough_Control.simulation", "kind": "module", "doc": "\n"}, {"fullname": "Trough.Trough_Control.simulation.simulated_troughctl", "modulename": "Trough.Trough_Control.simulation", "qualname": "simulated_troughctl", "kind": "function", "doc": "Will run as separate process taking in commands through a pipe and\nreturning data on demand through a second pipe.
\n\nParameters
\n\nCTLPipe: Pipe\n commands come in on and messages go out on.
\n\nDATAPipe: Pipe\n data is sent out on
\n", "signature": "(CTLPipe, DATAPipe):", "funcdef": "def"}, {"fullname": "Trough.Trough_Control.trough_util", "modulename": "Trough.Trough_Control.trough_util", "kind": "module", "doc": "\n"}, {"fullname": "Trough.Trough_Control.trough_util.isnumber", "modulename": "Trough.Trough_Control.trough_util", "qualname": "isnumber", "kind": "function", "doc": "Parameters
\n\n\n- obj: object to be tested
\n
\n\nReturns
\n\n\n True is a number.
\n
\n", "signature": "(obj):", "funcdef": "def"}, {"fullname": "Trough.Trough_Control.trough_util.etol_call", "modulename": "Trough.Trough_Control.trough_util", "qualname": "etol_call", "kind": "function", "doc": "Wrapping a callable object in this function will cause it to be called until\nit either returns without an error or the maximum recursion depth is reached.\nThis should only be used on calls that occasionally return errors because they\nare reading sensors or something like that.
\n\nParameters
\n\nobj: callable
\n\nparam: list\n a list containing the parameters in the function call
\n\nReturns
\n\nresult: any\n result of function call
\n", "signature": "(obj, param):", "funcdef": "def"}, {"fullname": "Trough.Trough_Control.trough_util.is_trough_initialized", "modulename": "Trough.Trough_Control.trough_util", "qualname": "is_trough_initialized", "kind": "function", "doc": "Checks for a running Trough process and good connections to it.
\n\nReturns
\n\nbool\nTRUE if initialized
\n", "signature": "():", "funcdef": "def"}, {"fullname": "Trough.Trough_Control.trough_util.init_trough", "modulename": "Trough.Trough_Control.trough_util", "qualname": "init_trough", "kind": "function", "doc": "This initializes the trough control subprocess and creates the pipes to communicate\nwith it.
\n\nReturns
\n\npipe\ncmdsend: the end of the pipe to sent commands to the trough.
\n\npipe\ndatarcv: the end of the pipe the trough uses to send back data and messages.
\n\nProcess\nTROUGH: the process handle for the trough.
\n", "signature": "():", "funcdef": "def"}, {"fullname": "Trough.Trough_Control.trough_util.troughctl", "modulename": "Trough.Trough_Control.trough_util", "qualname": "troughctl", "kind": "function", "doc": "Will run as separate process taking in commands through a pipe and\nreturning data on demand through a second pipe.\nIteration 1, collects data into a fifo and watches barrier position.
\n\nParameters
\n\n\n- Pipe CTLPipe: pipe commands come in on and messages go out on.
\n- Pipe DATAPipe: pipe data is sent out on
\n
\n", "signature": "(CTLPipe, DATAPipe):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI", "modulename": "Trough.Trough_GUI", "kind": "module", "doc": "\n"}, {"fullname": "Trough.Trough_GUI.Collect_data", "modulename": "Trough.Trough_GUI.Collect_data", "kind": "module", "doc": "\n"}, {"fullname": "Trough.Trough_GUI.Collect_data.trough_run", "modulename": "Trough.Trough_GUI.Collect_data", "qualname": "trough_run", "kind": "class", "doc": "\n"}, {"fullname": "Trough.Trough_GUI.Collect_data.trough_run.__init__", "modulename": "Trough.Trough_GUI.Collect_data", "qualname": "trough_run.__init__", "kind": "function", "doc": "Create a new run object
\n\nParameters
\n\nid: int\n 0 based index of run in current notebook\nfilename: str\n String representation of the filename used to store the data,\n with not type extension. This probably should not contain a path.\ntitle: str\n User friendly title (suggested default is same as filename).\nunits: str\n Units for the displayed barrier positions (cm, cm^2 or Ang^2/molec).\ntarget: float\n Numerical value in units for the targeted final trough area.\nspeed: float\n Numerical value in units for the speed to move the barriers.\nmoles: float\n moles of molecules initially spread in the trough.\nplate_circ: float\n circumference of the Whilhelmy plate in mm.\ndataframe: DataFrame or None\ntimestamp: float or None
\n", "signature": "(\tid,\tfilename,\ttitle,\tunits,\ttarget,\tspeed,\tmoles,\tplate_circ,\tdataframe=None,\ttimestamp=None)"}, {"fullname": "Trough.Trough_GUI.Collect_data.trough_run.from_html", "modulename": "Trough.Trough_GUI.Collect_data", "qualname": "trough_run.from_html", "kind": "function", "doc": "Create a run from an html representation
\n\nParameters
\n\nhtml: str\n The html to be parsed to create the run object
\n\nReturns
\n\ntrough_run: trough_run\n A trough_run object
\n", "signature": "(self, html):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.Collect_data.trough_run.run_caption", "modulename": "Trough.Trough_GUI.Collect_data", "qualname": "trough_run.run_caption", "kind": "function", "doc": "Returns an html table with info about the run to use as a caption
\n", "signature": "(self):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.Collect_data.trough_run.init_collect_control", "modulename": "Trough.Trough_GUI.Collect_data", "qualname": "trough_run.init_collect_control", "kind": "function", "doc": "This initializes the collection control widgets and VBox that\ncontains them. The VBox may be accessed as self.collect_control
\n", "signature": "(self):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.Collect_data.trough_run.close_collect_control", "modulename": "Trough.Trough_GUI.Collect_data", "qualname": "trough_run.close_collect_control", "kind": "function", "doc": "This closes self.collect_control
which also minimizes\nthe objects maintained on the Python side.
\n", "signature": "(self):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.Collect_data.trough_run.to_html", "modulename": "Trough.Trough_GUI.Collect_data", "qualname": "trough_run.to_html", "kind": "function", "doc": "Create an html string representing a run
\n", "signature": "(self):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.Collect_data.trough_run.write_run", "modulename": "Trough.Trough_GUI.Collect_data", "qualname": "trough_run.write_run", "kind": "function", "doc": "Writes a run file with the base filename run.filename
into the\ndirectory specified. If a file with the current name exists\nattempts to make the name unique by appending self.timestamp\nto the filename. Currently only produces\nan html file that is also human-readable. Other file formats may be\navailable in the future through the use of key word arguments.
\n\nParameters
\n\ndirpath:\n pathlike object or string. Empty string means the current working\n directory.
\n\nkwargs:\n optional key word arguments for future adaptability
\n", "signature": "(self, dirpath, **kwargs):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.Collect_data.Run", "modulename": "Trough.Trough_GUI.Collect_data", "qualname": "Run", "kind": "function", "doc": "This routine creates a GUI for initializing, starting, collecting and\ncompleting a run. If the run has been completed it will simply reload it\nfrom the local datafile.
\n\nParameters
\n\nrun_name: str or Path\nThis should generally be the name for the file the data will be stored in\nwithout a file type extension. Recommend a naming scheme that produces\nUnique filenames, such as Trough_run_<username>_<timestamp>
. The file\nname will be run_name.trh.run.html
.
\n", "signature": "(run_name):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.Collect_data.collect_data_updater", "modulename": "Trough.Trough_GUI.Collect_data", "qualname": "collect_data_updater", "kind": "function", "doc": "This is run in a separate thread and will update the figure and\nall status widgets at an interval of 2 seconds or a little longer. While\nthis is running nothing else will be able to talk to the trough.
\n\nParameters
\n\ntrough_lock: threading.lock\n When acquired this routine will talk to the trough. It is not\n released until the routine exits to avoid any data loss. It does\n call the status_widgets updater as often as it can while collecting\n the data.
\n\ncmdsend: Pipe\n End of Pipe to send commands to the Trough.
\n\ndatarcv: Pipe\n End of Pipe to receive data from the Trough.
\n\ncals: Trough_GUI.calibrations\n Used to convert the data to user units.
\n\nlastdirection: multiprocessing.Value\n Of type 'i' to indicate last direction the barriers moved.
\n\nrun_updater: multiprocessing.Value\n Of type 'c_bool'. True if this updater should keep running.
\n\nupdater_running: multiprocessing.Value\n Of type 'c_bool'. Set to True by this process when it starts\n and set to False before exiting.
\n\nrun: trough_run\n This object contains the live figure and the place to store the data.
\n", "signature": "(\ttrough_lock,\tcmdsend,\tdatarcv,\tcals,\tlastdirection,\trun_updater,\tupdater_running,\trun):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.Collect_data.update_collection", "modulename": "Trough.Trough_GUI.Collect_data", "qualname": "update_collection", "kind": "function", "doc": "Updates the graph and the data storage
\n", "signature": "(datapkg, cals, lastdirection, run_updater, updater_running, run):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.Monitor_Calibrate", "modulename": "Trough.Trough_GUI.Monitor_Calibrate", "kind": "module", "doc": "\n"}, {"fullname": "Trough.Trough_GUI.Monitor_Calibrate.Monitor_Setup_Trough", "modulename": "Trough.Trough_GUI.Monitor_Calibrate", "qualname": "Monitor_Setup_Trough", "kind": "function", "doc": "This produces a user interface in jupyter notebooks using ipywidgets. The\ninterface allows monitoring of the trough barrier positions, balance\nsignal, and temperature signal. The barrier positions can be\nadjusted using this interface. Calibrations of all the signals are\nperformed using this interface.
\n\nCalibrations are stored in the calibration files in the .Trough/calibrations\ndirectory of the current user. The latest file is used. If none exists\none is created using default parameters. Users should calibrate all\nsignals before using the trough.
\n\nNOTE: some objects used here are global and created by importing from\nstatus_widgets.py and command_widgets.py.
\n\nParameters
\n\ncalibrations: Calibrations\n The object containing the calibrations be used and modified. See\n Trough_GUI.calibration_utils
.
\n", "signature": "(calibrations):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.calibration_utils", "modulename": "Trough.Trough_GUI.calibration_utils", "kind": "module", "doc": "Utilities for:
\n\n\n- writing and reading calibration files stored in the local\nuser directory
.Trough/calibrations
. \n- fitting calibration data to generate calibration parameters.
\n- converting between raw signal and user-friendly values.
\n
\n"}, {"fullname": "Trough.Trough_GUI.calibration_utils.Calibration", "modulename": "Trough.Trough_GUI.calibration_utils", "qualname": "Calibration", "kind": "class", "doc": "\n"}, {"fullname": "Trough.Trough_GUI.calibration_utils.Calibration.__init__", "modulename": "Trough.Trough_GUI.calibration_utils", "qualname": "Calibration.__init__", "kind": "function", "doc": "Defines a calibration of type name
.
\n\nParameters
\n\nname: str\n calibration name.
\n\nunits: str\n string representation of the units the calibration yields.
\n\ntimestamp: float\n Unix floating point timestamp.
\n\nparam:list\n list of the numerical parameters for the fit yielding the\n calibration.
\n\nparam_stdev: list\n list of the numerical values for the estimated standard\n deviation of the parameters from the fit.\nparam_inv: list\n list of the numerical values for the fit (or equation) yielding the\n inverse of the calibration (return to the raw value).\nparam_inv_stdev: list\n list of the numerical values for the estimated standard deviation of\n the parameters for the inversion.\ncal_data_x: list\n x-data used for the calibration fit.
\n\ncal_data_y: list\n y-data used for the calibration fit.
\n\nfit_type: str\n string name for the fit type. Defaults to \"polynomial\"
\n\nfit_eqn_str: str\n string representation of the fit equation. Defaults to\n \"y = C0 + C1x + C2xx + C3xxx + ...\"
\n\nfit_ceof_lbls: list\n list of string labels for the coefficients, which should\n correlate to symbols in the fit_eqn_str. Defaults to [\"C0\", \"C1\",\n ...]. Automatically, truncated to the actual number of\n coefficients determined by the order of the polynomial.
\n\nadditional_data:dict\n a dictionary of key:value pairs where the keys are a short\n descriptive string. They can contain any additional data\n necessary for doing calculations on the data.
\n", "signature": "(\tname,\tunits,\ttimestamp,\tparam,\tparam_stdev,\tparam_inv,\tparam_inv_stdev,\tcal_data_x,\tcal_data_y,\tfit_type='polynomial',\tfit_eqn_str='y = C0 + C1*x + C2*x*x + C3*x*x*x + ...',\tfit_ceof_lbls=['C0', 'C1', 'C2', 'C3', 'C4', 'C5', 'C6', 'C7'],\tadditional_data={})"}, {"fullname": "Trough.Trough_GUI.calibration_utils.Calibration.cal_from_html", "modulename": "Trough.Trough_GUI.calibration_utils", "qualname": "Calibration.cal_from_html", "kind": "function", "doc": "This takes in an html str, parses it and returns a new\ncalibration.
\n\nParameters
\n\nhtml: str\n The html to be parsed to create the calibration object
\n\nReturns
\n\ncalibration: calibration\n a calibration object.
\n", "signature": "(cls, html):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.calibration_utils.Calibration.cal_to_html", "modulename": "Trough.Trough_GUI.calibration_utils", "qualname": "Calibration.cal_to_html", "kind": "function", "doc": "This routine creates an html str that would be human-readable in a\nbrowser detailing the calibration. This can be written to a file to\nstore the calibration.
\n\nReturns
\n\ncalib_div: str\n string containing the html detailing the calibration.
\n", "signature": "(self):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.calibration_utils.Calibration.cal_apply", "modulename": "Trough.Trough_GUI.calibration_utils", "qualname": "Calibration.cal_apply", "kind": "function", "doc": "\n", "signature": "(self, data, stdev):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.calibration_utils.Calibration.cal_inv", "modulename": "Trough.Trough_GUI.calibration_utils", "qualname": "Calibration.cal_inv", "kind": "function", "doc": "\n", "signature": "(self, data, stdev):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.calibration_utils.Calibrations", "modulename": "Trough.Trough_GUI.calibration_utils", "qualname": "Calibrations", "kind": "class", "doc": "\n"}, {"fullname": "Trough.Trough_GUI.calibration_utils.Calibrations.read_cal", "modulename": "Trough.Trough_GUI.calibration_utils", "qualname": "Calibrations.read_cal", "kind": "function", "doc": "This routine reads in a calibration file. If it is the standard\nhtml file it uses calibration.cal_from_html()
operation to convert\nit to a calibration.
\n\nParameters
\n\nname: str\n either the basename (current options: 'balance', 'barriers_open',\n 'barriers_close', 'speed_open', 'speed_close' or\n 'temperature') or a string representation of the path to the\n calibration file to be read. If one of the basenames is used\n this code will look for the most recent calibration of that type\n in the directory '~.Trough\\calibrations'.
\n\nReturns
\n\nCalibration
\n", "signature": "(self, name):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.calibration_utils.Calibrations.write_cal", "modulename": "Trough.Trough_GUI.calibration_utils", "qualname": "Calibrations.write_cal", "kind": "function", "doc": "Writes a calibration file with the base filename cal.name + int(\ncal.timestamp)
into the directory specified. Currently only produces\nan html file that is also human-readable. Other file formats may be\navailable in the future through the use of key word arguments.
\n\nParameters
\n\ndirpath:\n pathlike object or string
\n\ncal: Calibration\n a calibration object containing the information about the\n calibration to write to the file.
\n\nkwargs:\n optional key word arguments for future adaptability
\n", "signature": "(self, dirpath, cal, **kwargs):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.calibration_utils.Calibrations.poly_fit", "modulename": "Trough.Trough_GUI.calibration_utils", "qualname": "Calibrations.poly_fit", "kind": "function", "doc": "Does a polynomial fit of the specified order using the x and y\nvalues provided.
\n\nParameters
\n\ndata_x: list\n of numerical x values.
\n\ndata_y: list\n of numerical y values.
\n\norder: int\n the order of the polynomical used for fitting.
\n\nyerr: float or iterable of float\n absolute error(s) in the y-value. Used to weight the fit. If no\n values are provided the assumption is equal weighting.
\n\nReturns
\n\nparam: list\n of fitted parameters.
\n\nparam_stdev: list\n of estimated standard deviation in the parameters.
\n", "signature": "(self, data_x, data_y, order, yerr=None):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.command_widgets", "modulename": "Trough.Trough_GUI.command_widgets", "kind": "module", "doc": "\n"}, {"fullname": "Trough.Trough_GUI.command_widgets.on_change_Barr_Units", "modulename": "Trough.Trough_GUI.command_widgets", "qualname": "on_change_Barr_Units", "kind": "function", "doc": "\n", "signature": "(change):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.command_widgets.on_change_Barr_Direction", "modulename": "Trough.Trough_GUI.command_widgets", "qualname": "on_change_Barr_Direction", "kind": "function", "doc": "\n", "signature": "(changed):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.command_widgets.on_Barr_Target_change", "modulename": "Trough.Trough_GUI.command_widgets", "qualname": "on_Barr_Target_change", "kind": "function", "doc": "Updates the speed settings since open and close are different.
\n", "signature": "(change):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.command_widgets.on_click_Start", "modulename": "Trough.Trough_GUI.command_widgets", "qualname": "on_click_Start", "kind": "function", "doc": "\n", "signature": "(change):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.command_widgets.on_click_Stop", "modulename": "Trough.Trough_GUI.command_widgets", "qualname": "on_click_Stop", "kind": "function", "doc": "\n", "signature": "(change):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.conversions", "modulename": "Trough.Trough_GUI.conversions", "kind": "module", "doc": "This file contains unit conversion utility functions for use in the GUI
\n\n\n- To nest these functions replace the
value, err
part of the call with\n*func(...)
. For example sqcm_to_angpermolec(*cm_to_sqcm(9.2, 0.1, cals),\ncals)
\n
\n"}, {"fullname": "Trough.Trough_GUI.conversions.cm_to_sqcm", "modulename": "Trough.Trough_GUI.conversions", "qualname": "cm_to_sqcm", "kind": "function", "doc": "convert barrier separation in cm to trough area in sqcm
\n", "signature": "(value, err, cals):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.conversions.sqcm_to_cm", "modulename": "Trough.Trough_GUI.conversions", "qualname": "sqcm_to_cm", "kind": "function", "doc": "convert trough area in sqcm to barrier separation in cm
\n", "signature": "(value, err, cals):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.conversions.sqcm_to_angpermolec", "modulename": "Trough.Trough_GUI.conversions", "qualname": "sqcm_to_angpermolec", "kind": "function", "doc": "convert trough area in sqcm to square angstroms per molecules
\n", "signature": "(value, err, moles):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.conversions.angpermolec_to_sqcm", "modulename": "Trough.Trough_GUI.conversions", "qualname": "angpermolec_to_sqcm", "kind": "function", "doc": "convert trough area in sqcm to square angstroms per molecules
\n", "signature": "(value, err, moles):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.conversions.mg_to_mNperm", "modulename": "Trough.Trough_GUI.conversions", "qualname": "mg_to_mNperm", "kind": "function", "doc": "convert balance measurement in mg to milliNewtons per meter
\n", "signature": "(value, err, pi_tare, plate_circ):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.conversions.nNperm_to_mg", "modulename": "Trough.Trough_GUI.conversions", "qualname": "nNperm_to_mg", "kind": "function", "doc": "convert surface pressure in milliNewtons per meter to mg
\n", "signature": "(value, err, pi_tare, plate_circ):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.status_widgets", "modulename": "Trough.Trough_GUI.status_widgets", "kind": "module", "doc": "This file contains widgets that display updating trough information and\ncan be used in multiple ipywidget panels within the same notebook.
\n"}, {"fullname": "Trough.Trough_GUI.status_widgets.set_zero_pressure", "modulename": "Trough.Trough_GUI.status_widgets", "qualname": "set_zero_pressure", "kind": "function", "doc": "\n", "signature": "(change):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.status_widgets.update_status", "modulename": "Trough.Trough_GUI.status_widgets", "qualname": "update_status", "kind": "function", "doc": "Call this routine to update the contents of all the status widgets.
\n\nParameters
\n\nraw_data: dict\n dictionary of latest raw data values for each\n sensor and their standard deviation\n (e.g. {'bal_raw':3.20,'bal_dev':0.005,'barr_raw':0.5,'barr_dev':0.002,\n 'temp_raw':2.24, 'temp_dev':0.01, 'messages':''})
\n\ncalibrations: Calibrations\n Object containing the calibrations for the trough (currently\n .balance
, .barriers
and .temperature
). A call to\n .balance.cal_apply(raw_data['bal_raw'],raw_data['bal_dev'])
\n will return the balance reading in the calibration units (.balance.units
).
\n", "signature": "(raw_data: dict, calibrations, lastdirection):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.status_widgets.status_updater", "modulename": "Trough.Trough_GUI.status_widgets", "qualname": "status_updater", "kind": "function", "doc": "This is run in a separate thread and will update the status widgets\nevery 2 seconds or when it can get access to the pipes to talk to the\ntrough.
\n\nParameters
\n\ntrough_lock: threading.lock\n When acquired this routine will talk to the trough. Releases it for\n other processes after every update.
\n\ncmdsend: Pipe\n End of Pipe to send commands to the Trough.
\n\ndatarcv: Pipe\n End of Pipe to receive data from the Trough.
\n\ncals: Trough_GUI.calibrations\n Used to convert the data to user units.
\n\nlastdirection: multiprocessing.Value\n Of type 'i' to indicate last direction the barriers moved.
\n\nrun_updater: multiprocessing.Value\n Of type 'c_bool'. True if this updater should keep running.
\n\nupdater_running: multiprocessing.Value\n Of type 'c_bool'. Set to True by this process when it starts\n and set to False before exiting.
\n", "signature": "(\ttrough_lock,\tcmdsend,\tdatarcv,\tcals,\tlastdirection,\trun_updater,\tupdater_running):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.status_widgets.start_status_updater", "modulename": "Trough.Trough_GUI.status_widgets", "qualname": "start_status_updater", "kind": "function", "doc": "\n", "signature": "():", "funcdef": "def"}];
+ /** pdoc search index */const docs = [{"fullname": "Trough", "modulename": "Trough", "kind": "module", "doc": "Langmuir Trough
\n\nThis software is a custom controller and GUI for the research Langmuir trough \nin the Gutow Lab at UW Oshkosh. It is written in Python and expects to run in a\nJupyter notebook environment. However, all of the parts that are not elements\nof the user interface should work in a vanilla Python environment.
\n\nHardware requirements:\nRaspberry Pi compatible system with a Pi-Plates \nDAQC2 data acquisition plate \nand a trough controlled by the DAQC2 plate. This software could be used with \na trough controlled some other way by rewriting the routines in trough_util.\npy
. The GUI front end would need no rewriting to use with a different \ntrough if a custom backend controlling the barriers, reading the temperature \nand Whilhelmy balance is written. The backend needs to continually monitor \nthe trough and respond to the following commands: Stop, Send, Start, \nDirection, Speed, MoveTo, MotorCal, ConstPi, DataLabels, ShutDown
.
\n\nIf you do not have compatible hardware the GUI will run with a simulated \ntrough, allowing you to see how it works.
\n\nUsage
\n\nOnce installed:
\n\n\n- Turn on the power supply for the trough.
\n- In a terminal navigate to the directory containing the trough software.
\n- Start the virtual environment
pipenv shell
. \n- Launch Jupyter
jupyter notebook
(jupyter lab
also works and is now \nmore stable). \n- Create a folder for the new day using the New menu near the top right \nof the Jupyter browser page. Give it an appropriate name.
\n- Switch to that folder by clicking on it.
\n- Start a new ipython notebook using the New menu. Give it a\nname that describes the experiment.
\n- In the first cell initialize the trough by running the command
from \nTrough import Trough_GUI
. This will take a while to run the first time \nit is run each day because it needs to check the movement of the barriers. \n- To control and monitor the trough or do calibrations run the command \n
Trough_GUI.Controls(Trough_GUI.calibrations)
\n- Do not do any real runs without making sure the calibrations are correct.
\n- To start data collection (a run) run the command \n
Trough_GUI.Collect_data.Run(\"name_for_run\")
, \nwhere you replace name_for_run with the text for the name of the run (no \nspaces). \n- Set the run conditions.
\n- You can start data collection by clicking the green \"Run\" button.
\n- If you set the speed to zero the data collection will be displayed \nversus time and will not stop until you click the red \"Stop\" button.
\n
\n\nInstallation
\n\nOS setup - Ubuntu on Pi
\n\nBy default in Ubuntu 20.04 for Pis the gpio and spi groups do not exist.\nThe i2c group does (not always).
\n\n\n- Make sure that the following packages are installed
rpi.gpio-common \npython3-pigpio python3-gpiozero python3-rpi.gpio
. \n- You can avoid having to create a gpio group, by assigning users who need\n gpio access to the dialout group. Check that /dev/gpiomem is part of that \ngroup and that the dialout group has rw access. If not you will need to set\n it.
\n- Users also need to be members of the i2c group. If it does not exist create \n it and then make that the group for /dev/i2c-1 with group rw permissions. \nTHIS MAY NOT BE NECESSARY.
\n- The spi group needs to be created (addgroup?).
\n- Additionally the spi group needs to be given rw access to the spi devices\nat each boot. To do this create a one line rule in a file named \n
/etc/udev/rules.d/50-spidev.rules
containing SUBSYSTEM==\"spidev\", \nGROUP=\"spi\", MODE=\"0660\"
. The file should have rw permission for root \nand read permission for everyone else. \n- Make sure you have pip installed for \npython 3:
python3 -m pip --version
or pip3 --version
. If you do not, \ninstall using apt \ninstall python3-pip
. \n
\n\nTrough Software Installation
\n\nTo avoid library conflicts the software should be installed into a virtual environment.\nInstructions for doing this using pipenv\nfollow.
\n\nLog into your chosen user account:
\n\n\n- Install pipenv:
pip3 install \n--user pipenv
. You may\nneed to add ~/.local/bin
to your PATH
to make pipenv
\navailable in your command shell. More discussion: \nThe Hitchhiker's Guide to\nPython. \n- Create a directory for the virtual environment you will be installing\ninto (example:
$ mkdir Trough
). \n- Navigate into the directory
$ cd Trough
. \n- Create the virtual environment and enter it
$ pipenv shell
. To get out of\nthe environment you can issue the $ exit
command on the command line. \n- While still in the shell install the latest trough software and all its\nrequirements\n
$ pip install -U langmuir_trough
. \n- Still within the environment shell test\nthis by starting jupyter
$ jupyter notebook
. Jupyter should launch in your \nbrowser.\n\n- Open a new notebook using the default (Python 3) kernel.
\n- In the first cell import the Trough_GUI: \n
from Trough import Trough_GUI
.\n When run this cell sets things up and tries to talk to the trough. \n
\n- If you wish, you can make this environment available to an alternate Jupyter\ninstall as a special kernel when you are the user.\n
\n- Make sure you are running in your virtual environment
$ pipenv shell
\nin the directory for virtual environment will do that. \n- Issue the command to add this as a kernel to your personal space: \n
$ python -m ipykernel install --user --name=<name-you-want-for-kernel>
. \n- More information is available in the Jupyter/Ipython documentation. \nA simple tutorial from Nikolai Jankiev (_Parametric Thoughts_) can be\nfound here.
\n
\n
\n\nChange Log
\n\n\n- 0.6.0 (Mar. 29, 2023)\n
\n- Documentation updates including Gutow Lab Standard Operating Procedures \n(SOPs).
\n- Refactored everything to inside the module
Trough
. \n
\n- 0.5.2 (Mar. 16, 2023) Now works in Jupyter Lab.\n
\n- Adjusted widget updating/clearing to work in Jupyter lab.
\n- Added JupyterLab >= 3.6.1 to requirements.
\n
\n- 0.5.1 (Mar. 9, 2023) \n
\n- Include
spidev
package in requirements. \n- More details reported when unable to \"find trough\".
\n
\n- 0.5.0 (Mar. 4, 2023) First version with working GUI
\n- 0.1.0 First pypi compatible package version.
\n
\n\nKnown issues
\n\n\n- 0.5.0 - 0.6.0 The estimated error on values converted to metric units \nbased on calibration fits appears to be too pessimistic.
\n- Inconsistent rendering of Latex ipywidget labels with ipywidgets >= 8.0. \nUntil figured out requiring ipywidgets < 8.0.
\n- Runs don't label graph axes reliably for x-axis units other than cm.
\n
\n\nDevelopment
\n\n\n\n\n- For development purposes clone the GIT repository.
\n- Create the virtual environment to run it in within the development \ndirectory
pipenv shell
. \n- Within the shell pip install for development
pip install -e .
. \n
\n\nConstructing the Documentation
\n\n\n- Make sure pdoc is installed and updated in the virtual environment
pip \ninstall -U pdoc
. \n- Update any
.md
files included in _init_.py
.\n\n- Generally URLs should be absolute, not relative.
\n
\n- At the root level run pdoc
pdoc --logo-link\nhttps://gutow.github.io/Langmuir_Trough/ --footer-text \"Langmuir_Trough vX.X.X\" \n--math -html -o docs Trough
where X.X.X
is the version number. \n- Because of the way the document building process works the background tasks \nwill be started. You will have to stop the document build after the \ndocumentation is done building (watch the
doc
folder) with a ^C
to \nterminate it. \n
\n\nReleasing on PyPi
\n\nProceed only if testing of the build is successful.
\n\n\n- Update packaging software
pip install -U setuptools wheel twine
\n- Double check the version number in
setup.py
. \n- Rebuild the release:
python -m setup sdist bdist_wheel
. \n- Upload it:
python -m twine upload dist/*
\n- Make sure it works by installing it in a clean virtual environment.
pip \ninstall -U ...
. Copy the actual link from pypi.org.\n`. If it does not work, pull the release. \n
\n\nIdeas/Things to do
\n\n\n- Make more robust by wrapping data collection in
try ...
so that it can \nexit more gracefully and give up barrier monitoring? \n- Add explanation of how to use the barrier watch deamon to prevent barrier \ncrashing if software fails.
\n
\n\nLangmuir Trough Standard Operating Procedures for the Gutow Lab
\n\nInitialization
\n\n\n- Check that recirculating temperature controller is connected to the \ntrough. Then turn it on and verify that the temperature is set to what \nyou want. Stabilization time is about 20 minutes for temperatures near \nroom temperature.
\n- Turn on power to the trough.
\n- Open a terminal and navigate to the
Trough
directory of the user \nTrough
. \n- Activate the trough python environment
pipenv shell
\n- Launch Jupyter Lab
jupyter lab
. \n- Within Jupyter Lab create a new folder for the Day. Name it something \nlike \"DescriptiveWord_MMM_DD_YYYY\", where MMM = three letter month \nabbreviation, DD = day of the month and YYYY = the year.
\n- Open the folder by clicking on it.
\n- Open a new Notebook. Give it a descriptive name.
\n- In the first cell run the command
from Trough import Trough_GUI
. If the \ntrough has not been started in the last 12 hours this will take a while \nas it checks the motor calibration for moving the barriers. \n
\n\nChecking Trough and Subphase Cleanliness
\n\nThis need to be done before each experiment.
\n\n\n- We usually use high-purity water as the subphase. Primarily this is \n18+ MΩ de-ionized water mixed with KMnO4 and redistilled.\nDepending on the status of the water polishers, it is sometimes possible \nto use 18+ MΩ water from these directly.
\n- If the trough is already filled with subphase (1 - 1.5 mm above trough \nedges) and the Wilhelmy plate is installed skip steps 3 - 6.
\n- Calibrate the Wilhelmy balance\nif necessary.
\n- Hang a clean filter paper Wilhelmy plate from a fine wire on the balance. \nMake sure that you know the circumference of the plate in mm. This should be \nrecorded in the Jupyter Notebook you are running. Our default \ncircumference is 21.5 mm.
\n- The subphase should fill the trough so that it rises 1 - 1.5 mm above the \nedges of the trough. To add subphase use the clean glass funnel in the trough \nisolation box to pour through (pouring directly from a bottle splashes). \nThe funnel makes it much easier to add subphase when the polycarbonate lid \nwith just a small opening is in use. Always add subphase between the \nbarriers to trap any surface active species between them for easier removal.
\n- Adjust the height of the Wilhelmy balance so the plate is partially \nsubmerged in the subphase. The balance settling time is long. You will \nhave to wait at least 1 minute before any measurements will be valid. \nWith a reasonably clean trough and subphase the unzeroed balance should \nsettle to a surface pressure < 10 mN/m. If it does not or shows no noise, \nthere may be a problem.
\n- If necessary initialize the trough then start the \ntrough control and calibration tool by running the command \n
Trough_GUI.Controls(Trough_GUI.calibrations)
in an empty cell of the \nnotebook. \n- Expand the \"Manual Barrier Control\" accordian. Set the direction to \n\"open\". Set the speed to maximum (~10 cm/min). Click the start button. \nWatch the surface pressure indicator. When the barriers stop (~12.7 cm \nseparation), wait to make sure the surface pressure has stabilized.
\n- Switch the direction to \"close\". Set the speed to the maximum closing \nspeed (~6.8 cm/min). Click the start button. Watch the surface pressure \nindicator.
\n- Once the barriers are fully closed (~2.8 cm separation), check the \nsurface pressure. If it is greater than it was when fully open carefully \naspirate the surface between the barriers without catching the Wilhelmy \nplate until the surface pressure is slightly less than observed for the \nopen barriers.
\n- Repeat steps 8 - 10 up to 4X to get the surface clean. If it is still \nnot clean:\n
\n- Raise the Wilhelmy balance carefully and rotate it aside. Make \nsure to lock it in place.
\n- Remove the polycarbonate lid if it is in place. Store it so that it \ndoes not get contaminated.
\n- Aspirate all the subphase out of the trough and try again.
\n
\n- If after a second try the trough and subphase are still not clean the \ntrough probably needs to be cleaned.
\n- When it appears clean test:\n
\n- Manually open the barriers all the way.
\n- Set up a run by executing the command \n
Trough_GUI.Collect_Data.Run(\"XXX\")
, where XXX is replaced with a \nname for the run (e.g. \"clean_test_MMM_DD_YYYYa\") in an empty cell. \n- Set the units to cm separation. Set the speed to 1 cm/min. Set the \nfinal separation to the minimum for the trough (~2.86 cm).
\n- When the surface pressure is stable click on the \"zero pressure\" \nbutton to tare the Wilhelmy balance.
\n- Click start. The run will stop when the barriers reach the target \nseparation. You can also stop the collection by clicking the \"stop\" \nbutton.
\n- If the surface pressure stays between -0.2 and +0.2 mN/m the trough \nis adequately clean.
\n
\n
\n\nStorage of Trough Between Runs
\n\n\n- If the trough is being used regularly (1X/week or more): store the trough \nwith clean subphase in it. If the subphase is water make sure that the \nhumidification beaker in the isolation box is kept about 50% full.
\n- If the trough will be unused for a significant time:\n
\n- After verifying the trough and subphase cleanliness\naspirate off all the subphase.
\n- Empty the humidification beaker.
\n- Cover the trough with the polycarbonate lid.
\n- Make sure the isolation box is closed.
\n- Make sure the power supply is off.
\n- Shut down the computer.
\n
\n
\n\nHandling Spreading Solvent(s)
\n\nIt is extremely easy to contaminate the solvents with surface active \ncompounds at a level that will ruin experiments
\n\n\n- Generally HPLC grade solvents are adequately clean. We most commonly use \nHPLC grade hexanes and absolute ethanol.
\n- All glassware must be carefully cleaned before using to transfer or \ncontain spreading solvents.\n
\n- If unsure of basic cleanliness wash well with soap and water. Rinse \nfive (5) times with warm tap water. Rinse three (3) times with \nde-ionized water.
\n- Rinse two (2) times with absolute ethanol (10% - 20% container volume per \nrinse).
\n- Rinse six (6) times with the spreading solvent (10% - 20% container volume \nper rinse).
\n
\n- Do not stick anything into the clean spreading solvent stock bottle. Get \nsamples to work with by pouring into properly cleaned intermediate containers.
\n
\n\nChecking Spreading Solvent Cleanliness
\n\n\n- Transfer < 1 mL of spreading solvent to a\nproperly cleaned vial.
\n- Initialize the trough and \nverify that the subphase is clean.
\n- Using the \"Manual Barrier Controls\" open the barriers all the way.
\n- Rinse the positive displacement microdispenser 3X with absolute ethanol \nfrom a TFE squeeze bottle and then 3X with HPLC grade hexanes from a TFE \nsqueeze bottle.
\n- Rinse with the solvent sample being tested 6X by sucking up 90 µL \nof the solvent sample and dispensing it into a waste beaker.
\n- Dispense 90 µL of the solvent sample onto the surface between the \nbarriers.
\n- Allow to evaporate (15 min is adequate for hexanes).
\n- Perform a compression at 1 cm/min from fully \nopen to fully closed.
\n- The solvent is clean if the surface pressure stays between -0.2 and +0.2 \nmN/m.
\n
\n\nMaking a Spreading Solution
\n\nFor most molecules we want to spread about 3.00 X 10-8 moles of \nmolecules on our trough to get a range of roughly 60 to 15 square Angstroms per \nmolecule during a compression.
\n\n\n- The ideal volume to spread is 50 µL of solution. Thus we want a \nconcentration near (3.00 X 10-8 moles)/(50.0 X 10-6 L)\n= 6 X 10-4 M. It is practical to spread anywhere between 20 \nand 90 µL. So, you can adapt to concentrations that vary between 1.00 \nx 10-3 M and 3.3 X 10-4 M.
\n- Ideally your molecule will dissolve in pure hexanes at a concentration of \n6 X 10-4 M. If it is not soluble you can put a few percent (up \nto 5% v/v) of ethanol in with the hexanes. This solvent mixture works for \nmany surfactants, without significantly impacting the surface tension of \na water subphase.
\n- Experiments take very little solution, so make as small volumes of \nsolution as possible. Note that you should not try to measure out \nsurfactant in amounts that produce less than three significant figures on \na standard analytical balance (e.g. at least 10 mg, preferably 50 mg or \nmore.) This may mean that you will have to make a stock solution and \ndilute it to get in the correct concentration range.
\n- All solutions must be made using \nproperly cleaned glassware and spreading \nsolvents that have been\nverified to be clean. Use \nvolumetric flasks with ground glass stoppers to avoid contamination by \nthe plasticizers found in most polymer caps.
\n- Because the solvents are very volatile the solutions will not keep long \nin the volumetric flasks with ground glass stoppers. They can be \ntransferred for somewhat longer term storage to sealed brown bottles \nif the bottles are \nproperly washed \nand you have verified that a little solvent stored in the bottle \novernight and shaken stays clean.
\n
\n\nSpreading a Sample
\n\n\n- Rinse a small vial 2X with absolute ethanol from a TFE squeeze bottle \nthen 3X with hexanes from a TFE squeeze bottle.
\n- If you need to use a pipette or funnel (the funnel is a better choice as \nyou are less likely to contaminate the stock spreading solution) to transfer \nthe spreading solution to the vial rinse the pipette or funnel 2X with \nabsolute ethanol from a TFE squeeze bottle and then 3X with hexanes from \na TFE squeeze bottle.
\n- Rinse the transfer tool with the spreading solution 6X.
\n- Rinse the vial 6X (10-20% of vial volume) with the spreading solution.
\n- Use the transfer tool to transfer about 1 mL of the spreading solution to \nthe small vial.
\n- Set the positive displacement dispenser to the volume you will be \ndispensing.
\n- Rinse the dispenser 2X with absolute ethanol from a TFE squeeze bottle \nthen 3X with hexanes from a TFE squeeze bottle. Make sure you move the \nplunger through its dispensing motion while doing this.
\n- When the dispenser is dry, rinse 6X with the spreading solution making \nsure to take up the full amount to be dispensed on each rinse.
\n- With the barriers fully open dispense the spreading solution drop wise \nonto the surface between the barriers. Avoid the Wilhelmy plate.
\n- Allow time for the solvent to evaporate (~ 15 minutes for hexanes) \nbefore doing a compression.
\n
\n\nRunning a Compression
\n\n\n- Trough must first be\nverified to be clean.
\n- Spread the surfactant solution on the trough with the barriers open. \nAllow sufficient time for the solvent to evaporate (~15 min for hexanes). \nThe amount to spread will depend on your target range for area per \nmolecule and the concentration of your solution (10-4 - \n10-3 M is typical).
\n- In a new notebook cell execute the command \n
Trough_GUI.Collect_Data.Run(\"XXX\")
, where XXX is replaced with a \n name for the run (e.g. \"CompoundName_MMM_DD_YYYYa\") \n- Adjust the moles of molecules to the moles of surfactant you spread. \nAdjust the units to Angstroms squared per molecule. Choose your desired \nfinal target area and compression speed.
\n- When the solvent is fully evaporated zero the balance.
\n- Store the settings.
\n- When ready click the \"Start\" button. The collection will stop when the \ndesired area is reached. You can also stop the run by clicking the \"Stop\" \nbutton.
\n
\n\nCalibrating the Wilhelmy Balance
\n\nThis should be done at the beginning of any day real data is collected
\n\n\n- If it is not already running launch the trough control and calibration \ntool by running the command
Trough_GUI.Controls(Trough_GUI.calibrations)\n
in an empty notebook cell. \n- Expand the \"Calibrate Balance\" accordian and follow the on screen \ninstructions.
\n
\n\nCalibrating Barrier Position and Speed
\n\nThis only needs to be done if a check of the measured barrier separation \nis off by more than \u00b10.03 mm
\n\n\n- If it is not already running launch the trough control and calibration \ntool by running the command
Trough_GUI.Controls(Trough_GUI.calibrations)\n
in an empty notebook cell. \n- Expand the \"Calibrate Barriers\" accordian and follow the on screen \ninstructions.
\n
\n\nCalibrating the Temperature Probe.
\n\nThis is very stable so should not need to be done often
\n\n\n- If it is not already running launch the trough control and calibration \ntool by running the command
Trough_GUI.Controls(Trough_GUI.calibrations)\n
in an empty notebook cell. \n- Expand the \"Calibrate Temperature\" accordian and follow the on screen \ninstructions.
\n- A good source of known temperatures is the thermostat recirculator.
\n
\n\nCleaning the Trough
\n\n\n- The cleaning solution 1:1 concentrated nitric acid:concentrated sulfuric \nacid is extremely dangerous and also has potential to damage parts of the \ntrough. Do not perform this cleaning procedure until Dr. Guto has \ncertified you for the process.
\n- The trough can be powered down during this procedure.
\n- The Wilhelmy balance should be locked in position out of the way.
\n- The polycarbonate lid should be removed (store it so that does not get \ncontaminated).
\n- Fill the trough with the 1:1 concentrated nitric:sulfuric acid solution. \nAllow to sit 10 + minutes.
\n- While the cleaning solution sits in the trough make sure the aspirator \ntrap is dry.
\n- Aspirate off the cleaning solution. \n
\n- Unless the trough is extremely dirty the collected cleaning \nsolution may be returned to the cleaning solution storage bottle.
\n- If disposing of the cleaning solution treat it as strong acid waste and \nneutralize properly.
\n
\n- Rinse the trough twice with clean water subphase.
\n- Check the cleanliness of the trough
\n
\n"}, {"fullname": "Trough.Trough_Control", "modulename": "Trough.Trough_Control", "kind": "module", "doc": "\n"}, {"fullname": "Trough.Trough_Control.message_utils", "modulename": "Trough.Trough_Control.message_utils", "kind": "module", "doc": "\n"}, {"fullname": "Trough.Trough_Control.message_utils.extract_messages", "modulename": "Trough.Trough_Control.message_utils", "qualname": "extract_messages", "kind": "function", "doc": "Parameters
\n\ndatapkg: list\nlist of lists containing trough data bundle, messages in the last list.
\n\nReturns
\n\nlist\nlist of strings consisting of the messages.
\n", "signature": "(datapkg):", "funcdef": "def"}, {"fullname": "Trough.Trough_Control.simulation", "modulename": "Trough.Trough_Control.simulation", "kind": "module", "doc": "\n"}, {"fullname": "Trough.Trough_Control.simulation.simulated_troughctl", "modulename": "Trough.Trough_Control.simulation", "qualname": "simulated_troughctl", "kind": "function", "doc": "Will run as separate process taking in commands through a pipe and\nreturning data on demand through a second pipe.
\n\nParameters
\n\nCTLPipe: Pipe\n commands come in on and messages go out on.
\n\nDATAPipe: Pipe\n data is sent out on
\n", "signature": "(CTLPipe, DATAPipe):", "funcdef": "def"}, {"fullname": "Trough.Trough_Control.trough_util", "modulename": "Trough.Trough_Control.trough_util", "kind": "module", "doc": "\n"}, {"fullname": "Trough.Trough_Control.trough_util.isnumber", "modulename": "Trough.Trough_Control.trough_util", "qualname": "isnumber", "kind": "function", "doc": "Parameters
\n\n\n- obj: object to be tested
\n
\n\nReturns
\n\n\n True is a number.
\n
\n", "signature": "(obj):", "funcdef": "def"}, {"fullname": "Trough.Trough_Control.trough_util.etol_call", "modulename": "Trough.Trough_Control.trough_util", "qualname": "etol_call", "kind": "function", "doc": "Wrapping a callable object in this function will cause it to be called until\nit either returns without an error or the maximum recursion depth is reached.\nThis should only be used on calls that occasionally return errors because they\nare reading sensors or something like that.
\n\nParameters
\n\nobj: callable
\n\nparam: list\n a list containing the parameters in the function call
\n\nReturns
\n\nresult: any\n result of function call
\n", "signature": "(obj, param):", "funcdef": "def"}, {"fullname": "Trough.Trough_Control.trough_util.is_trough_initialized", "modulename": "Trough.Trough_Control.trough_util", "qualname": "is_trough_initialized", "kind": "function", "doc": "Checks for a running Trough process and good connections to it.
\n\nReturns
\n\nbool\nTRUE if initialized
\n", "signature": "():", "funcdef": "def"}, {"fullname": "Trough.Trough_Control.trough_util.init_trough", "modulename": "Trough.Trough_Control.trough_util", "qualname": "init_trough", "kind": "function", "doc": "This initializes the trough control subprocess and creates the pipes to communicate\nwith it.
\n\nReturns
\n\npipe\ncmdsend: the end of the pipe to sent commands to the trough.
\n\npipe\ndatarcv: the end of the pipe the trough uses to send back data and messages.
\n\nProcess\nTROUGH: the process handle for the trough.
\n", "signature": "():", "funcdef": "def"}, {"fullname": "Trough.Trough_Control.trough_util.troughctl", "modulename": "Trough.Trough_Control.trough_util", "qualname": "troughctl", "kind": "function", "doc": "Will run as separate process taking in commands through a pipe and\nreturning data on demand through a second pipe.\nIteration 1, collects data into a fifo and watches barrier position.
\n\nParameters
\n\n\n- Pipe CTLPipe: pipe commands come in on and messages go out on.
\n- Pipe DATAPipe: pipe data is sent out on
\n
\n", "signature": "(CTLPipe, DATAPipe):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI", "modulename": "Trough.Trough_GUI", "kind": "module", "doc": "\n"}, {"fullname": "Trough.Trough_GUI.Collect_data", "modulename": "Trough.Trough_GUI.Collect_data", "kind": "module", "doc": "\n"}, {"fullname": "Trough.Trough_GUI.Collect_data.trough_run", "modulename": "Trough.Trough_GUI.Collect_data", "qualname": "trough_run", "kind": "class", "doc": "\n"}, {"fullname": "Trough.Trough_GUI.Collect_data.trough_run.__init__", "modulename": "Trough.Trough_GUI.Collect_data", "qualname": "trough_run.__init__", "kind": "function", "doc": "Create a new run object
\n\nParameters
\n\nid: int\n 0 based index of run in current notebook\nfilename: str\n String representation of the filename used to store the data,\n with not type extension. This probably should not contain a path.\ntitle: str\n User friendly title (suggested default is same as filename).\nunits: str\n Units for the displayed barrier positions (cm, cm^2 or Ang^2/molec).\ntarget: float\n Numerical value in units for the targeted final trough area.\nspeed: float\n Numerical value in units for the speed to move the barriers.\nmoles: float\n moles of molecules initially spread in the trough.\nplate_circ: float\n circumference of the Whilhelmy plate in mm.\ndataframe: DataFrame or None\ntimestamp: float or None
\n", "signature": "(\tid,\tfilename,\ttitle,\tunits,\ttarget,\tspeed,\tmoles,\tplate_circ,\tdataframe=None,\ttimestamp=None)"}, {"fullname": "Trough.Trough_GUI.Collect_data.trough_run.from_html", "modulename": "Trough.Trough_GUI.Collect_data", "qualname": "trough_run.from_html", "kind": "function", "doc": "Create a run from an html representation
\n\nParameters
\n\nhtml: str\n The html to be parsed to create the run object
\n\nReturns
\n\ntrough_run: trough_run\n A trough_run object
\n", "signature": "(self, html):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.Collect_data.trough_run.run_caption", "modulename": "Trough.Trough_GUI.Collect_data", "qualname": "trough_run.run_caption", "kind": "function", "doc": "Returns an html table with info about the run to use as a caption
\n", "signature": "(self):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.Collect_data.trough_run.init_collect_control", "modulename": "Trough.Trough_GUI.Collect_data", "qualname": "trough_run.init_collect_control", "kind": "function", "doc": "This initializes the collection control widgets and VBox that\ncontains them. The VBox may be accessed as self.collect_control
\n", "signature": "(self):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.Collect_data.trough_run.close_collect_control", "modulename": "Trough.Trough_GUI.Collect_data", "qualname": "trough_run.close_collect_control", "kind": "function", "doc": "This closes self.collect_control
which also minimizes\nthe objects maintained on the Python side.
\n", "signature": "(self):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.Collect_data.trough_run.to_html", "modulename": "Trough.Trough_GUI.Collect_data", "qualname": "trough_run.to_html", "kind": "function", "doc": "Create an html string representing a run
\n", "signature": "(self):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.Collect_data.trough_run.write_run", "modulename": "Trough.Trough_GUI.Collect_data", "qualname": "trough_run.write_run", "kind": "function", "doc": "Writes a run file with the base filename run.filename
into the\ndirectory specified. If a file with the current name exists\nattempts to make the name unique by appending self.timestamp\nto the filename. Currently only produces\nan html file that is also human-readable. Other file formats may be\navailable in the future through the use of key word arguments.
\n\nParameters
\n\ndirpath:\n pathlike object or string. Empty string means the current working\n directory.
\n\nkwargs:\n optional key word arguments for future adaptability
\n", "signature": "(self, dirpath, **kwargs):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.Collect_data.Run", "modulename": "Trough.Trough_GUI.Collect_data", "qualname": "Run", "kind": "function", "doc": "This routine creates a GUI for initializing, starting, collecting and\ncompleting a run. If the run has been completed it will simply reload it\nfrom the local datafile.
\n\nParameters
\n\nrun_name: str or Path\nThis should generally be the name for the file the data will be stored in\nwithout a file type extension. Recommend a naming scheme that produces\nUnique filenames, such as Trough_run_<username>_<timestamp>
. The file\nname will be run_name.trh.run.html
.
\n", "signature": "(run_name):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.Collect_data.collect_data_updater", "modulename": "Trough.Trough_GUI.Collect_data", "qualname": "collect_data_updater", "kind": "function", "doc": "This is run in a separate thread and will update the figure and\nall status widgets at an interval of 2 seconds or a little longer. While\nthis is running nothing else will be able to talk to the trough.
\n\nParameters
\n\ntrough_lock: threading.lock\n When acquired this routine will talk to the trough. It is not\n released until the routine exits to avoid any data loss. It does\n call the status_widgets updater as often as it can while collecting\n the data.
\n\ncmdsend: Pipe\n End of Pipe to send commands to the Trough.
\n\ndatarcv: Pipe\n End of Pipe to receive data from the Trough.
\n\ncals: Trough_GUI.calibrations\n Used to convert the data to user units.
\n\nlastdirection: multiprocessing.Value\n Of type 'i' to indicate last direction the barriers moved.
\n\nrun_updater: multiprocessing.Value\n Of type 'c_bool'. True if this updater should keep running.
\n\nupdater_running: multiprocessing.Value\n Of type 'c_bool'. Set to True by this process when it starts\n and set to False before exiting.
\n\nrun: trough_run\n This object contains the live figure and the place to store the data.
\n", "signature": "(\ttrough_lock,\tcmdsend,\tdatarcv,\tcals,\tlastdirection,\trun_updater,\tupdater_running,\trun):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.Collect_data.update_collection", "modulename": "Trough.Trough_GUI.Collect_data", "qualname": "update_collection", "kind": "function", "doc": "Updates the graph and the data storage
\n", "signature": "(datapkg, cals, lastdirection, run_updater, updater_running, run):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.Monitor_Calibrate", "modulename": "Trough.Trough_GUI.Monitor_Calibrate", "kind": "module", "doc": "\n"}, {"fullname": "Trough.Trough_GUI.Monitor_Calibrate.Monitor_Setup_Trough", "modulename": "Trough.Trough_GUI.Monitor_Calibrate", "qualname": "Monitor_Setup_Trough", "kind": "function", "doc": "This produces a user interface in jupyter notebooks using ipywidgets. The\ninterface allows monitoring of the trough barrier positions, balance\nsignal, and temperature signal. The barrier positions can be\nadjusted using this interface. Calibrations of all the signals are\nperformed using this interface.
\n\nCalibrations are stored in the calibration files in the .Trough/calibrations\ndirectory of the current user. The latest file is used. If none exists\none is created using default parameters. Users should calibrate all\nsignals before using the trough.
\n\nNOTE: some objects used here are global and created by importing from\nstatus_widgets.py and command_widgets.py.
\n\nParameters
\n\ncalibrations: Calibrations\n The object containing the calibrations be used and modified. See\n Trough_GUI.calibration_utils
.
\n", "signature": "(calibrations):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.calibration_utils", "modulename": "Trough.Trough_GUI.calibration_utils", "kind": "module", "doc": "Utilities for:
\n\n\n- writing and reading calibration files stored in the local\nuser directory
.Trough/calibrations
. \n- fitting calibration data to generate calibration parameters.
\n- converting between raw signal and user-friendly values.
\n
\n"}, {"fullname": "Trough.Trough_GUI.calibration_utils.Calibration", "modulename": "Trough.Trough_GUI.calibration_utils", "qualname": "Calibration", "kind": "class", "doc": "\n"}, {"fullname": "Trough.Trough_GUI.calibration_utils.Calibration.__init__", "modulename": "Trough.Trough_GUI.calibration_utils", "qualname": "Calibration.__init__", "kind": "function", "doc": "Defines a calibration of type name
.
\n\nParameters
\n\nname: str\n calibration name.
\n\nunits: str\n string representation of the units the calibration yields.
\n\ntimestamp: float\n Unix floating point timestamp.
\n\nparam:list\n list of the numerical parameters for the fit yielding the\n calibration.
\n\nparam_stdev: list\n list of the numerical values for the estimated standard\n deviation of the parameters from the fit.\nparam_inv: list\n list of the numerical values for the fit (or equation) yielding the\n inverse of the calibration (return to the raw value).\nparam_inv_stdev: list\n list of the numerical values for the estimated standard deviation of\n the parameters for the inversion.\ncal_data_x: list\n x-data used for the calibration fit.
\n\ncal_data_y: list\n y-data used for the calibration fit.
\n\nfit_type: str\n string name for the fit type. Defaults to \"polynomial\"
\n\nfit_eqn_str: str\n string representation of the fit equation. Defaults to\n \"y = C0 + C1x + C2xx + C3xxx + ...\"
\n\nfit_ceof_lbls: list\n list of string labels for the coefficients, which should\n correlate to symbols in the fit_eqn_str. Defaults to [\"C0\", \"C1\",\n ...]. Automatically, truncated to the actual number of\n coefficients determined by the order of the polynomial.
\n\nadditional_data:dict\n a dictionary of key:value pairs where the keys are a short\n descriptive string. They can contain any additional data\n necessary for doing calculations on the data.
\n", "signature": "(\tname,\tunits,\ttimestamp,\tparam,\tparam_stdev,\tparam_inv,\tparam_inv_stdev,\tcal_data_x,\tcal_data_y,\tfit_type='polynomial',\tfit_eqn_str='y = C0 + C1*x + C2*x*x + C3*x*x*x + ...',\tfit_ceof_lbls=['C0', 'C1', 'C2', 'C3', 'C4', 'C5', 'C6', 'C7'],\tadditional_data={})"}, {"fullname": "Trough.Trough_GUI.calibration_utils.Calibration.cal_from_html", "modulename": "Trough.Trough_GUI.calibration_utils", "qualname": "Calibration.cal_from_html", "kind": "function", "doc": "This takes in an html str, parses it and returns a new\ncalibration.
\n\nParameters
\n\nhtml: str\n The html to be parsed to create the calibration object
\n\nReturns
\n\ncalibration: calibration\n a calibration object.
\n", "signature": "(cls, html):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.calibration_utils.Calibration.cal_to_html", "modulename": "Trough.Trough_GUI.calibration_utils", "qualname": "Calibration.cal_to_html", "kind": "function", "doc": "This routine creates an html str that would be human-readable in a\nbrowser detailing the calibration. This can be written to a file to\nstore the calibration.
\n\nReturns
\n\ncalib_div: str\n string containing the html detailing the calibration.
\n", "signature": "(self):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.calibration_utils.Calibration.cal_apply", "modulename": "Trough.Trough_GUI.calibration_utils", "qualname": "Calibration.cal_apply", "kind": "function", "doc": "\n", "signature": "(self, data, stdev):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.calibration_utils.Calibration.cal_inv", "modulename": "Trough.Trough_GUI.calibration_utils", "qualname": "Calibration.cal_inv", "kind": "function", "doc": "\n", "signature": "(self, data, stdev):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.calibration_utils.Calibrations", "modulename": "Trough.Trough_GUI.calibration_utils", "qualname": "Calibrations", "kind": "class", "doc": "\n"}, {"fullname": "Trough.Trough_GUI.calibration_utils.Calibrations.read_cal", "modulename": "Trough.Trough_GUI.calibration_utils", "qualname": "Calibrations.read_cal", "kind": "function", "doc": "This routine reads in a calibration file. If it is the standard\nhtml file it uses calibration.cal_from_html()
operation to convert\nit to a calibration.
\n\nParameters
\n\nname: str\n either the basename (current options: 'balance', 'barriers_open',\n 'barriers_close', 'speed_open', 'speed_close' or\n 'temperature') or a string representation of the path to the\n calibration file to be read. If one of the basenames is used\n this code will look for the most recent calibration of that type\n in the directory '~.Trough\\calibrations'.
\n\nReturns
\n\nCalibration
\n", "signature": "(self, name):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.calibration_utils.Calibrations.write_cal", "modulename": "Trough.Trough_GUI.calibration_utils", "qualname": "Calibrations.write_cal", "kind": "function", "doc": "Writes a calibration file with the base filename cal.name + int(\ncal.timestamp)
into the directory specified. Currently only produces\nan html file that is also human-readable. Other file formats may be\navailable in the future through the use of key word arguments.
\n\nParameters
\n\ndirpath:\n pathlike object or string
\n\ncal: Calibration\n a calibration object containing the information about the\n calibration to write to the file.
\n\nkwargs:\n optional key word arguments for future adaptability
\n", "signature": "(self, dirpath, cal, **kwargs):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.calibration_utils.Calibrations.poly_fit", "modulename": "Trough.Trough_GUI.calibration_utils", "qualname": "Calibrations.poly_fit", "kind": "function", "doc": "Does a polynomial fit of the specified order using the x and y\nvalues provided.
\n\nParameters
\n\ndata_x: list\n of numerical x values.
\n\ndata_y: list\n of numerical y values.
\n\norder: int\n the order of the polynomical used for fitting.
\n\nyerr: float or iterable of float\n absolute error(s) in the y-value. Used to weight the fit. If no\n values are provided the assumption is equal weighting.
\n\nReturns
\n\nparam: list\n of fitted parameters.
\n\nparam_stdev: list\n of estimated standard deviation in the parameters.
\n", "signature": "(self, data_x, data_y, order, yerr=None):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.command_widgets", "modulename": "Trough.Trough_GUI.command_widgets", "kind": "module", "doc": "\n"}, {"fullname": "Trough.Trough_GUI.command_widgets.on_change_Barr_Units", "modulename": "Trough.Trough_GUI.command_widgets", "qualname": "on_change_Barr_Units", "kind": "function", "doc": "\n", "signature": "(change):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.command_widgets.on_change_Barr_Direction", "modulename": "Trough.Trough_GUI.command_widgets", "qualname": "on_change_Barr_Direction", "kind": "function", "doc": "\n", "signature": "(changed):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.command_widgets.on_Barr_Target_change", "modulename": "Trough.Trough_GUI.command_widgets", "qualname": "on_Barr_Target_change", "kind": "function", "doc": "Updates the speed settings since open and close are different.
\n", "signature": "(change):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.command_widgets.on_click_Start", "modulename": "Trough.Trough_GUI.command_widgets", "qualname": "on_click_Start", "kind": "function", "doc": "\n", "signature": "(change):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.command_widgets.on_click_Stop", "modulename": "Trough.Trough_GUI.command_widgets", "qualname": "on_click_Stop", "kind": "function", "doc": "\n", "signature": "(change):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.conversions", "modulename": "Trough.Trough_GUI.conversions", "kind": "module", "doc": "This file contains unit conversion utility functions for use in the GUI
\n\n\n- To nest these functions replace the
value, err
part of the call with\n*func(...)
. For example sqcm_to_angpermolec(*cm_to_sqcm(9.2, 0.1, cals),\ncals)
\n
\n"}, {"fullname": "Trough.Trough_GUI.conversions.cm_to_sqcm", "modulename": "Trough.Trough_GUI.conversions", "qualname": "cm_to_sqcm", "kind": "function", "doc": "convert barrier separation in cm to trough area in sqcm
\n", "signature": "(value, err, cals):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.conversions.sqcm_to_cm", "modulename": "Trough.Trough_GUI.conversions", "qualname": "sqcm_to_cm", "kind": "function", "doc": "convert trough area in sqcm to barrier separation in cm
\n", "signature": "(value, err, cals):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.conversions.sqcm_to_angpermolec", "modulename": "Trough.Trough_GUI.conversions", "qualname": "sqcm_to_angpermolec", "kind": "function", "doc": "convert trough area in sqcm to square angstroms per molecules
\n", "signature": "(value, err, moles):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.conversions.angpermolec_to_sqcm", "modulename": "Trough.Trough_GUI.conversions", "qualname": "angpermolec_to_sqcm", "kind": "function", "doc": "convert trough area in sqcm to square angstroms per molecules
\n", "signature": "(value, err, moles):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.conversions.mg_to_mNperm", "modulename": "Trough.Trough_GUI.conversions", "qualname": "mg_to_mNperm", "kind": "function", "doc": "convert balance measurement in mg to milliNewtons per meter
\n", "signature": "(value, err, pi_tare, plate_circ):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.conversions.nNperm_to_mg", "modulename": "Trough.Trough_GUI.conversions", "qualname": "nNperm_to_mg", "kind": "function", "doc": "convert surface pressure in milliNewtons per meter to mg
\n", "signature": "(value, err, pi_tare, plate_circ):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.status_widgets", "modulename": "Trough.Trough_GUI.status_widgets", "kind": "module", "doc": "This file contains widgets that display updating trough information and\ncan be used in multiple ipywidget panels within the same notebook.
\n"}, {"fullname": "Trough.Trough_GUI.status_widgets.set_zero_pressure", "modulename": "Trough.Trough_GUI.status_widgets", "qualname": "set_zero_pressure", "kind": "function", "doc": "\n", "signature": "(change):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.status_widgets.update_status", "modulename": "Trough.Trough_GUI.status_widgets", "qualname": "update_status", "kind": "function", "doc": "Call this routine to update the contents of all the status widgets.
\n\nParameters
\n\nraw_data: dict\n dictionary of latest raw data values for each\n sensor and their standard deviation\n (e.g. {'bal_raw':3.20,'bal_dev':0.005,'barr_raw':0.5,'barr_dev':0.002,\n 'temp_raw':2.24, 'temp_dev':0.01, 'messages':''})
\n\ncalibrations: Calibrations\n Object containing the calibrations for the trough (currently\n .balance
, .barriers
and .temperature
). A call to\n .balance.cal_apply(raw_data['bal_raw'],raw_data['bal_dev'])
\n will return the balance reading in the calibration units (.balance.units
).
\n", "signature": "(raw_data: dict, calibrations, lastdirection):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.status_widgets.status_updater", "modulename": "Trough.Trough_GUI.status_widgets", "qualname": "status_updater", "kind": "function", "doc": "This is run in a separate thread and will update the status widgets\nevery 2 seconds or when it can get access to the pipes to talk to the\ntrough.
\n\nParameters
\n\ntrough_lock: threading.lock\n When acquired this routine will talk to the trough. Releases it for\n other processes after every update.
\n\ncmdsend: Pipe\n End of Pipe to send commands to the Trough.
\n\ndatarcv: Pipe\n End of Pipe to receive data from the Trough.
\n\ncals: Trough_GUI.calibrations\n Used to convert the data to user units.
\n\nlastdirection: multiprocessing.Value\n Of type 'i' to indicate last direction the barriers moved.
\n\nrun_updater: multiprocessing.Value\n Of type 'c_bool'. True if this updater should keep running.
\n\nupdater_running: multiprocessing.Value\n Of type 'c_bool'. Set to True by this process when it starts\n and set to False before exiting.
\n", "signature": "(\ttrough_lock,\tcmdsend,\tdatarcv,\tcals,\tlastdirection,\trun_updater,\tupdater_running):", "funcdef": "def"}, {"fullname": "Trough.Trough_GUI.status_widgets.start_status_updater", "modulename": "Trough.Trough_GUI.status_widgets", "qualname": "start_status_updater", "kind": "function", "doc": "\n", "signature": "():", "funcdef": "def"}];
// mirrored in build-search-index.js (part 1)
// Also split on html tags. this is a cheap heuristic, but good enough.
diff --git a/setup.py b/setup.py
index 3b9fc11..c88860d 100644
--- a/setup.py
+++ b/setup.py
@@ -5,7 +5,7 @@
setuptools.setup(
name="langmuir_trough",
- version="0.6.0dev",
+ version="0.6.0",
description="Controls and collects data from Gutow Lab Langmuir Trough.",
long_description=long_description,
long_description_content_type="text/markdown",