Skip to content

Commit

Permalink
Web app
Browse files Browse the repository at this point in the history
  • Loading branch information
paul-freeman committed Jan 12, 2017
1 parent fd7c899 commit 701a91d
Show file tree
Hide file tree
Showing 11 changed files with 1,172 additions and 1,125 deletions.
4 changes: 3 additions & 1 deletion CHANGES.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
V0.1.2a, Dec 14, 2014 -- First Conda Package
V0.2.1, Jan 12, 2017 -- Added place_server
V0.2.0, Jan 12, 2017 -- Web Inerface Added
V0.1.2a, Dec 14, 2016 -- First Conda Package
V0.1.0, May 28, 2014 -- Initial release
37 changes: 30 additions & 7 deletions README.txt → README.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,44 @@

=====
PLACE
=====
# PLACE

PLACE is an open-source Python package for laboratory automation, control, and experimentation.

It provides driver modules for automating laboratory instruments, example implementation scripts, and modules for visualizing and processing waveform data (available with PALplots: https://github.com/PALab/PALplots).

A goal of PLACE is to develop a repository of instrument drivers for laboratory automation. In addition, rapid development of compatible processing software will streamline laboratory activity from acquisition through data analysis.

To install PLACE from the source:
Download the source code and unzip `PLACE-master.zip`. From the `PLACE-master` folder, run the following from the command line to install:
## Installation

python setup.py install
### Install PLACE via conda

```
conda install -c defaults -c conda-forge -c freemapa place
pip install obspyh5 websockets
```

## Running PLACE

### Control PLACE via the command-line interface

```
place_scan [options]
```

Run ```scan --help``` for options.

### Control PLACE via web app (requires Python >= 3.5)

```
place_server
```

Then open place/web/place.html in any web browser.

## Authors

Authors:
Jami L Johnson

Henrik tom Wörden

Kasper van Wijk

6 changes: 3 additions & 3 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,9 @@
# built documents.
#
# The short X.Y version.
version = u'0.1'
version = u'0.2'
# The full version, including alpha/beta/rc tags.
release = u'0.1.2a'
release = u'0.2.1'

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
Expand Down Expand Up @@ -139,7 +139,7 @@
# The name for this set of Sphinx documents.
# "<project> v<release> documentation" by default.
#
# html_title = u'PLACE v0.1.2a'
# html_title = u'PLACE v0.2.1'

# A shorter title for the navigation bar. Default is the same as html_title.
#
Expand Down
6 changes: 3 additions & 3 deletions meta.yaml
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
package:
name: place
version: "0.1.2a"
version: "0.2.1"

source:
path: .

requirements:
build:
- python >=2.7
- python
- setuptools

run:
- python >=2.7
- python
- httplib2
- obspy
- numpy >=1.0.0
Expand Down
2 changes: 1 addition & 1 deletion place/automate/scan/scanFunctions.py
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ def options(self,opts,args):
for o, a in opts:
if o in ('-h', '--help'):
print(__doc__)
sys.exit(0)
return
if o in ("--n"):
filename = a + '.h5'
if o in ("--n2"):
Expand Down
140 changes: 67 additions & 73 deletions place/scripts/scan.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@

import sys
import os
import time
from math import ceil, log
import signal
import getopt
import re
import shlex
import functools

# set permissions of RS-232 serial port for vibrometer control
# (removed in favour of using proper permissions -Paul Freeman)
Expand All @@ -28,19 +35,14 @@
#os.system('sudo chmod -R 0777 /dev/ttyUSB0') # laser
#os.system('sudo chmod a+rw /dev/ttyUSB0')

from math import ceil, log
import matplotlib.pyplot as plt
import matplotlib.pyplot as plt
import numpy as np
from numpy import matrix
import getopt
import time
from obspy import read, Trace, UTCDateTime
from obspy.core.trace import Stats
from obspy.core import AttribDict
import re
import h5py
import obspyh5
from time import sleep

# PLACE modules
import place.automate.osci_card.controller as card
Expand All @@ -61,60 +63,64 @@
import pickle

from place.automate.quanta_ray.QRay_driver import QuantaRay
from place.automate.scan.scanFunctions import Initialize, Execute, Scan
from place.automate.scan.scanFunctions import Initialize, Execute, Scan

def main():
global instruments, par
instruments = []
par = []

def main(args_in=sys.argv):
try:
process_args(args_in)
except KeyboardInterrupt:
print('Keyboard Interrupt! Instrument connections closing...')
Execute().close(instruments,par)

def process_args(args_in):
# -----------------------------------------------------
# process command line options
# -----------------------------------------------------

# check if server-mode has been requested
if sys.argv[1] == "--serve":
scan_server()

try:

opts,args = getopt.getopt(sys.argv[1:], 'h',['help','s1=','s2=','scan=','dm=','sr=','tm=','ch=','ch2=','av=','wt=','rv=','ret=','sl=','vch=','tl=','tr=','cr=','cr2=','cp=','cp2=','ohm=','ohm2=','i1=','d1=','f1=','i2=','d2=','f2=','n=','n2=','dd=','rg=','map=','en=','lm=','rr=','pp=','bp=','so=','comments='])
opts,args = getopt.getopt(args_in[1:], 'h',['help','s1=','s2=','scan=','dm=','sr=','tm=','ch=','ch2=','av=','wt=','rv=','ret=','sl=','vch=','tl=','tr=','cr=','cr2=','cp=','cp2=','ohm=','ohm2=','i1=','d1=','f1=','i2=','d2=','f2=','n=','n2=','dd=','rg=','map=','en=','lm=','rr=','pp=','bp=','so=','comments='])

except getopt.error as msg:
print(msg)
print('for help use --help')
sys.exit(_SCAN_FAILURE_INVALID_ARUGMENTS)

global instruments, par
sys.exit(1)

par = Initialize().options(opts, args)

if par == None:
return

# -----------------------------------------------------
# Initialize instruments
# -----------------------------------------------------

instruments = []

# Initialize stage or mirrors for each dimension

if par['SCAN'] == '1D':
if par['GROUP_NAME_1'] == 'PICOMOTOR-X' or par['GROUP_NAME_1'] == 'PICOMOTOR-Y':
par = Initialize().picomotor_controller('130.216.58.155',23,par)

else:
par = Initialize().controller('130.216.58.154',par,1)
instruments.append(par['GROUP_NAME_1'])

elif par['SCAN'] == '2D' or par['SCAN'] == 'dual':
if par['GROUP_NAME_1'] in ['PICOMOTOR-X','PICOMOTOR-Y']:
par = Initialize().picomotor_controller('130.216.58.155',23,par)
else:
par = Initialize().controller('130.216.58.154',par,1)
instruments.append(par['GROUP_NAME_1'])
if par['GROUP_NAME_2'] in ['PICOMOTOR-X','PICOMOTOR-Y']:
instruments.append(par['GROUP_NAME_1'])
if par['GROUP_NAME_2'] in ['PICOMOTOR-X','PICOMOTOR-Y']:
par = Initialize().picomotor_controller('130.216.58.155',23,par)
else:
par = Initialize().controller('130.216.58.154',par,2)
par = Initialize().controller('130.216.58.154',par,2)
print(par['GROUP_NAME_2'])
instruments.append(par['GROUP_NAME_2'])

# Initialize and set header information for receiver
if par['RECEIVER'] == 'polytec':
par = Initialize().polytec(par)
Expand Down Expand Up @@ -167,7 +173,7 @@ def main():
# -----------------------------------------------------
# Perform scan
# -----------------------------------------------------

if par['SCAN'] == '1D':
Scan().oneD(par, header)
elif par['SCAN'] == '2D':
Expand All @@ -183,22 +189,19 @@ def main():
# close instrument connections
# -----------------------------------------------------
Execute().close(instruments,par)
sys.exit(_SCAN_SUCCESS)

sys.exit(0)



# wait for requests
def scan_server():
"""*In development.* Starts a websocket server to listen for scan requests.
def scan_server(port=9130):
"""Starts a websocket server to listen for scan requests.
This function will be used to initiate a special scan process. Rather
This function is used to initiate a special scan process. Rather
than specify the parameters via the command-line, this mode waits
for scan commands to arrive via a websocket.
Currently, the function will simply print the message it received
locally and return a message to the sender.
Once this server is started, it will need to be killed via ctrl-c or
similar.
Expand All @@ -213,58 +216,49 @@ def scan_server():
print()
print(" pip install websockets")
print()
sys.exit(_SCAN_FAILURE_MISSING_MODULE)

sys.exit(1)
try:
import asyncio
except ImportError:
print("Running as server requires the asyncio module")
print("but asyncio cannot be imported.")
print()
sys.exit(_SCAN_FAILURE_MISSING_MODULE)

async def scan_socket(websocket, path):
"""Creates an asyncronous websocket to listen for scans.
sys.exit(1)

Use of this function is handled internally by the application.
def ask_exit():
"""Signal handler to catch ctrl-c (SIGINT) or SIGTERM"""
loop.stop()

Note:
This function is created dynamically due to the fact that it
makes use of Python 3.5 libraries.
"""
async def scan_socket(websocket, path):
"""Creates an asyncronous websocket to listen for scans."""
print("Starting websockets server on port {}".format(port))
# get a scan command from the webapp
request = await websocket.recv()

#TODO make this actually call the main function
print("This is what I would like to run:")
print("This is what I am running:")
print(request)

process_args(shlex.split(request))
# send message back to the webapp
await websocket.send("Scan received")

scan_server_port = 9130
start_server = websockets.serve(
scan_socket,
'localhost',
scan_server_port)
print("Starting websockets server at ws://localhost:{}"
.format(scan_server_port))

asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()
loop = asyncio.get_event_loop()
# set up signal handlers
for signame in ('SIGINT', 'SIGTERM'):
loop.add_signal_handler(getattr(signal, signame), ask_exit)
coroutine = websockets.server.serve(scan_socket, 'localhost', port)
# run websocket server
server = loop.run_until_complete(coroutine)
loop.run_forever()
# cleanup
server.close()
loop.run_until_complete(server.wait_closed())
loop.close()



if __name__ == "__main__":
try:
while(True):
main()
except KeyboardInterrupt:
print('Keyboard Interrupt! Instrument connections closing...')
Execute().close(instruments,par)

# exit codes
_SCAN_SUCCESS = 0
_SCAN_FAILURE_MISSING_MODULE = 1
_SCAN_FAILURE_INVALID_ARUGMENTS = 2
# check if server-mode has been requested
if sys.argv[1] == "--serve":
scan_server()
else:
main(sys.argv)

2 changes: 1 addition & 1 deletion place/web/elm-package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "0.1.0",
"version": "0.2.1",
"summary": "webapp for interfacing with PLACE",
"repository": "https://github.com/PALab/place.git",
"license": "LGPLv3",
Expand Down
Loading

0 comments on commit 701a91d

Please sign in to comment.