Giter Club home page Giter Club logo

mxcubeweb's Introduction

MXCuBE

License: LGPL v3

MXCuBE stands for Macromolecular Xtallography Customized Beamline Environment. The project started in 2005 at ESRF, since then it has been adopted by other institutes in Europe. In 2010, a collaboration agreement has been signed for the development of MXCuBE with the following partners:

Latest information about the MXCuBE project can be found in the project webpage.

MXCuBE is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

MXCuBE is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with MXCuBE. If not, see https://www.gnu.org/licenses/.

Information for developers

Information for users

Oscarsson, M. et al. 2019. “MXCuBE2: The Dawn of MXCuBE Collaboration.” Journal of Synchrotron Radiation 26 (Pt 2): 393–405.

Gabadinho, J. et al. (2010). MxCuBE: a synchrotron beamline control environment customized for macromolecular crystallography experiments. J. Synchrotron Rad. 17, 700-707

mxcubeweb's People

Contributors

amilan avatar axelboc avatar bamartos avatar beenje avatar beteva avatar ddesanctis avatar dependabot[bot] avatar dominikatrojanowska avatar elmjag avatar fabcor-maxiv avatar fhernandezvivanco avatar henquist avatar jbflo avatar jienanmaxiv avatar laispc avatar marcus-oscarsson avatar mattclarke avatar meguiraun avatar megyaz avatar mguijarr avatar nah-maxiv avatar olofsvensson avatar rhfogh avatar spirit1317 avatar vrey01 avatar walesch-yan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mxcubeweb's Issues

Characterization

  • Ability to configure a characterization and add it to the queue.
  • Display the characterization results and create a new collection according to those.

Adding many samples to the Sample Queue is slow

When adding a lot of samples from the Sample Grid (e.g. 50 samples or more), the UI sends a
request per sample and waits for server reply before actually adding the sample to the queue, which gives impression of a slow UI - we need to improve that, there are 2 ways (can be combined...):

  • doing optimistic rendering, as Frederik proposed : updating the queue before having the answer from server, then displaying an error message if an answer is bad
  • changing API to be able to send all samples in one go

This is not a first priority task so the milestone is pushed to March.

Documentation as github pages?

I was thinking on using the gh_pages branch for the sphinx generated documentation. Specifically for the rest api. Right now the api is documented (ejem ejem, it must be improved) at with several people working on this we need proper documentation.

What do you think? I still need to add usefull docstrings but I you want I can prepare something like the following image and commit to the gh_pages and we see if it serve as doc place.

On the other hand... gh_pages might also serve as the project page, but at this moment it think doc is more important.

image

two issues about running queue

  1. When running a single task, one will get the error msg "'RootNode' object has no attribute 'lims_id'"
    The problem is when the server calls to execute the child entry directly, the lims_id is not provided, which otherwise would be assigned with the sample.lims_id when running a queue.
  2. When running a queue, one will get error msg "Sample' object has no attribute 'lims_group_id' ",
    This is because the Taskgroup node, which contains lims_group_id, is missing in the queue created by the server.

To temporarily avoid this error, one solution is to add the following line in the queue_model_objects_v1.py, line 214, where Sample obj is initialized
self.lims_group_id = None,

Ispyb

  • An user-ready solution for Ispyb is needed. A basic connection will be done in the session management though.
  • Read back the results stored in Ispyb after the collection.

Sample Centring

Manage the sample positioning. In a manual or automatic way.

  • Manual centring:
    • Usage of javascript mouse events for retrieving the three click points
    • Link to diff for rotating sample after every click
    • During the centring procedure messages will be passed between the server and the interface (actually the user)
  • Semi-automatic centring
  • Automatic centring

Login page

Move login form to a proper page on its own, like samples, data collection or logging. This is the first page user should see when landing on MXCuBE 3. Other pages should be disabled as long as user didn't do the login.

Using a module bundler, ES6 and other philosophical questions about front-end development

I studied a lot the way front-end developers are working in general with newest tools that exist in the Javascript and web development world, and lately lines have moved a lot to improve code organization, automatic processes (including testing) and even code writing itself so I wanted to share my findings with you guys, so we can decide which direction to go. Of course I have an opinion :) But before doing any pull request I prefer to explain first.

MXCuBE 3 client-side code is depending on React, Bootstrap, and many other little libraries. There is going to be more and more dependencies as features grow, which is normal. On the server dependencies are handled in requirements.txt and distutils in general, that's great - I always wanted to have a similar mechanism for Javascript code. I realized it exists, in different forms... It turns out people are setting up tool chains to handle dependencies (and much more), mixing tools like bower, grunt, gulp, yeoman, browserify, webpack...

Whatever the tool chain is, the idea is always the same:

  • to make it easy to download Javascript libraries (possibly with CSS and images) and have them integrated in the project
  • to maintain a registry of library versions
  • to do some processing on the code (syntax checking, transpiling, minifying, etc.) in order to produce a final .js file
  • the final .js file is highly optimized, "production-ready" and contains all dependencies inline

In order to do all this, my personal choice is webpack since it does the job of browserify + gulp (or grunt), using "standard" tools (like Node and npm) for package download and versions management.

So in my MXCuBE 3 repository I configured webpack and node modules to work with our code base.

There is more... I think we should write our Javascript code in ES6 syntax ; this is the syntax for the upcoming versions of Javascript, it is a standard that just needs to be implemented in all browsers.
It makes code much more readable, in particular when working with React components if we decide to follow the principle of having "1 .jsx file === 1 component" since it becomes possible to use ES6 modules syntax to import code from other modules just like we do in... Python. Thanks to the webpack installation it is the same for third-party dependencies too :) So one can write "import React" or "import { Button } from Bootstrap" for example.

Babel is a tool that converts ES6 code to ES5, to make it runnable on all web browsers. I added it to the webpack configuration, so it becomes transparent : we can write ES6 code and the final .js file is in ES5.

I followed guides on the net and I also configured webpack-dev-server : it allows to test the UI without starting the "real" MXCuBE 3 server. So the front-end developer can focus on the user interface, not worrying about real hardware or whatever. A very interesting feature of webpack is hot reloading ; it allows code changes to be immediately visible in the web browser during development.

I would like to get your opinion on all this, as soon as possible in order to see if we can merge a
PR from my repository and to continue development on good rails, or if you disagree we can
see how to organize all this differently.

Let's try it !

You can clone my repository be careful to use branch webpack:

git clone git://github.com/mguijarr/mxcube3 -b webpack

How to use webpack ?

  • first install Node and npm, required version is 0.12 at least ; for Debian-based systems I recommend doing this:

    # Note the new setup script name for Node.js v0.12
    curl -sL https://deb.nodesource.com/setup_0.12 | sudo bash -
    
    # Then install with:
    sudo apt-get install -y nodejs
    
  • then just install MXCuBE 3 dependencies:

    cd mxcube3-repo
    npm install
    
  • finally, run webpack in development mode:

    npm start
    

Open a web browser to http://localhost:8090 and see what I am working on...

What do you think ?

Redux

Assess the usefulness of Redux for handling all the logic in MXCuBE 3 in state reducers.

Data collection:Standard

  • Ability to configure a standard data collection and add it to the queue.
  • Display the results of any data collection.

MDCameraMockup test XML contains path to specific jpeg file

The md_camera.xml file that is shipped with MXCuBE 3 in test/HardwareObjectsMockup.xml directory specifies a path to an undistributed jpeg file:

<device class="MDCameraMockup">
  [...]
  <image_path>/mxn/home/mikegu/mxcube_sample_snapshot.jpeg</image_path>
</device>

It would be great if the sample snapshot jpeg file could be shipped with MXCuBE 3, and if the path could be fixed, so everybody can test MXCuBE 3 without changing test XML files.

Experiment Queue - Frontend Side

Develop the react components for the experiment queue.

  • add buttons:
    • run queue
    • stop queue
    • checkbox for running or not running a given element
  • Todo list
  • History list (possibility to add again to the todo list)
  • Current sample must be clearly visible at the top of the queue
    collapsable
  • Search bar
  • drag and drop for reordering
    history:

image

HardwareObjects submodule update

Hello :)
I just updated the HardwareObjects submodule with the latest version from master branch.
Almost all changes from ESRF have been merged, as well as updates from 2.1 branch so we can
say it's a clean start for MXCuBE 3 now, relatively to Hardware Objects.
I also changed MXCuBE repository to rely on the new HardwareObjects repository, closing MXCuBE
project issue #100.
I did the update without a PR because it's part of the set up of the MXCuBE 3 repository, it is not
a new development.

Data collection:Helical

  • Ability to configure an helical data collection and add it to the queue.
  • Display the results of the data collection.

Python 2.6 compatibility

At the moment MXCuBE 3 is not compatible with Python 2.6, at least because of the dependency
on the socketio library, indeed it is using dict comprehensions which only exist for Python >= 2.7:

Traceback (most recent call last):
  File "/usr/local/bin/mxcube3", line 5, in <module>
    from mxcube3 import app, socketio
  File "/usr/local/lib/python2.6/dist-packages/mxcube3/__init__.py", line 2, in <module>
    from flask.ext.socketio import SocketIO
  File "/usr/local/lib/python2.6/dist-packages/flask/exthook.py", line 62, in load_module
    __import__(realname)
  File "/usr/local/lib/python2.6/dist-packages/flask_socketio/__init__.py", line 3, in <module>
    import socketio
  File "/usr/local/lib/python2.6/dist-packages/socketio/__init__.py", line 2, in <module>
    from .server import Server
  File "/usr/local/lib/python2.6/dist-packages/socketio/server.py", line 7, in <module>
    from . import packet
  File "/usr/local/lib/python2.6/dist-packages/socketio/packet.py", line 115
    for key, value in six.iteritems(data)}
      ^
SyntaxError: invalid syntax

Not sure if it is important, though.

At ESRF at the moment our default installation comes with Python 2.6 but we can change that I guess.

Web interface design

  • Component skeleton, for using as a basic building block but also for making easy future enhancements or additions from non developers
  • Define a naming convention for the elements of the interface?
  • Define the experiment layout:
    • Blocks/components treated as current bricks
    • Some actions generated in a component may cause new actions in other components as well as in the server/equipment/etc.
  • Web technology to be used:
    • React: to populate the page as new elements are required
    • Javascript to handle:
      • Actions on user interactions
      • Receive events and messages from the server and update the corresponding element on the interface (a data field, experiment finished, etc.)

The main idea is of the new layout is to simplify the sample tree design:

  • Connect to ispyb and show only the samples available in the sample changer (can de done automatically or triggered by the user)
  • Some kind of filtering is needed due to the high number of samples that could be available for the experiment, by name, protein, etc.
  • Synchronization capabilities between Ispyb and the sample changer

The interface layout is split into different views (web pages), therefore decoupling the sample lists and experiment configuration (in a kind of batch mode) from the sample centring. The latter shows an experiment tree but only for a single sample, basically the one that is mounted. The transition between the pages/views must display a status message for the user (e.g “Mounting sample” message with a progress bar). More pages will be needed such as one for the optimisation, for the energy scan, etc.

There have been defined the first views that are required in the beginning, which are considered as a first approach and prone to change in the future:

  • The sample centring page: issue #9
  • The sample list view: additional issue needs to be created

web-layout

BeamLine Management

Manage parameters of the beamline such as energy, transmission, resolution, etc.

Queue entry id in the how message?

Hi mxcubers,

I am refining the sending of the ho messages to the web client, right now I only forward the message itself (i.e. centringSuccesfull, collectStarted, ...). I was wondering if there is any method/whatever to see who is the queue entry that has sent a given message (without changing the ho).

I see that there there is the get_current_entry method but it only works during the execution of such entry.

thanks for any hint,

Data collection:Mesh

  • Ability to configure a Mesh data collection and add it to the queue.
  • Display the results of the data collection.

User interface and server message handler

Extend the existing messaging system to the web. Flask-socketIO (websockets) can be used to send the pydispatcher’s signals to Javascript functions. It is also possible to define different namespaces over a single websocket. Flask-SocketIO transparently downgrades itself for older browsers that don’t have WebSocket, SocketIO emulates the connection using one of the older solutions, the best one available for each given client.

Two kind of signals:

  • Signal from HO to HO (hidden for the user, so no action is required)
  • Signals from HO to User interface

In any case, whenever a signal is intercepted for sending to the ui, it must fulfill a generic structure (to be defined), in order to ease the data retrieval in the web interface.

Code example:

from flask.ext.socketio import emit
#generic and unfiltered callback, it just will send all messages to the web interface
def signalCallback(signal, sender, *args): 
    socketio.emit('test',{'data':'A signal', 'signal': signal, \
        'sender':str(sender.__class__).split('.')[0]}, \
        namespace='/test')
#in the init code of the resolution hardware object (as example) we link the 'DeviceReady' message with the callback function
self.resolution.connect(self.resolution,'deviceReady', signalCallback)

We need to add self.someHO.connect(hw_obj, 'aSignal', 'aCallback') for each message we want to propagate to the user interface. For that, we need the lists of messages for each hw_obj, such as the following:

MaxLabMicrodiff_signals = ['diffractometerMoved', 'minidiffReady', 'minidiffNotReady',
'phiMotorStateChanged' ......]

BL9113MultiCollect_signals = ['collectReady', 'collectImageTaken', 'collectReady',
'collectStarted', ....]

And add these lists to a config.py (or config/messages.py or whatever)

Experiment Queue - Server Side

Use the QueueModel of the v2.1 for the sample/experiment queue management. There are some qt dependencies to be resolved though. In this way, all the required data structures for making collections is already defined. A new queue view must be programmed for the web interface (not in this issue). Note that the sample list must be retrieved from somewhere, or provide tools when manual mounting is selected.

This issue is about adapting/refactoring/testing the existing queue model in the new mxcube3 backend, new methods&routes will be required in the server.

Prop issues

When starting the webpage I immediately get this in my console.

"
main.js:11050 Warning: Failed propType: Required prop onHide was not specified in Modal. Check the render method of ErrorNotificationPanel.warning @ main.js:11050checkPropTypes @ main.js:27803validatePropTypes @ main.js:27822ReactElementValidator.createElement @ main.js:27856render @ main.js:80960(anonymous function) @ main.js:8274ReactCompositeComponentMixin._renderValidatedComponentWithoutOwnerOrContext @ main.js:14524ReactCompositeComponentMixin.renderValidatedComponent @ main.js:14544wrapper @ main.js:11319ReactCompositeComponentMixin.mountComponent @ main.js:14157wrapper @ main.js:11319ReactReconciler.mountComponent @ main.js:12467ReactMultiChild.Mixin.mountChildren @ main.js:22569ReactDOMComponent.Mixin.createContentMarkup @ main.js:19747ReactDOMComponent.Mixin.mountComponent @ main.js:19635ReactReconciler.mountComponent @ main.js:12467ReactCompositeComponentMixin.mountComponent @ main.js:14162wrapper @ main.js:11319ReactReconciler.mountComponent @ main.js:12467ReactCompositeComponentMixin.mountComponent @ main.js:14162wrapper @ main.js:11319ReactReconciler.mountComponent @ main.js:12467ReactCompositeComponentMixin.mountComponent @ main.js:14162wrapper @ main.js:11319ReactReconciler.mountComponent @ main.js:12467ReactCompositeComponentMixin.mountComponent @ main.js:14162wrapper @ main.js:11319ReactReconciler.mountComponent @ main.js:12467ReactCompositeComponentMixin.mountComponent @ main.js:14162wrapper @ main.js:11319ReactReconciler.mountComponent @ main.js:12467mountComponentIntoNode @ main.js:8838Mixin.perform @ main.js:13574batchedMountComponentIntoNode @ main.js:8854Mixin.perform @ main.js:13574ReactDefaultBatchingStrategy.batchedUpdates @ main.js:19146batchedUpdates @ main.js:13079ReactMount.renderNewRootComponent @ main.js:9048wrapper @ main.js:11319ReactMount.renderSubtreeIntoContainer @ main.js:9122ReactMount.render @ main.js:9142wrapper @ main.js:11319(anonymous function) @ main.js:8136(anonymous function) @ main.js:8152(anonymous function) @ main.js:8153__webpack_require @ main.js:521fn @ main.js:76(anonymous function) @ main.js:553__webpack_require @ main.js:521(anonymous function) @ main.js:544(anonymous function) @ main.js:547
main.js:11050 Warning: Failed propType: Required prop logOut was not specified in LoginForm. Check the render method of Connect(LoginForm).warning @ main.js:11050checkPropTypes @ main.js:27803validatePropTypes @ main.js:27822ReactElementValidator.createElement @ main.js:27856render @ main.js:38583(anonymous function) @ main.js:8274ReactCompositeComponentMixin._renderValidatedComponentWithoutOwnerOrContext @ main.js:14524ReactCompositeComponentMixin._renderValidatedComponent @ main.js:14544wrapper @ main.js:11319ReactCompositeComponentMixin.mountComponent @ main.js:14157wrapper @ main.js:11319ReactReconciler.mountComponent @ main.js:12467ReactMultiChild.Mixin.mountChildren @ main.js:22569ReactDOMComponent.Mixin._createContentMarkup @ main.js:19747ReactDOMComponent.Mixin.mountComponent @ main.js:19635ReactReconciler.mountComponent @ main.js:12467ReactCompositeComponentMixin.mountComponent @ main.js:14162wrapper @ main.js:11319ReactReconciler.mountComponent @ main.js:12467ReactMultiChild.Mixin.mountChildren @ main.js:22569ReactDOMComponent.Mixin._createContentMarkup @ main.js:19747ReactDOMComponent.Mixin.mountComponent @ main.js:19635ReactReconciler.mountComponent @ main.js:12467ReactCompositeComponentMixin.mountComponent @ main.js:14162wrapper @ main.js:11319ReactReconciler.mountComponent @ main.js:12467ReactMultiChild.Mixin.mountChildren @ main.js:22569ReactDOMComponent.Mixin._createContentMarkup @ main.js:19747ReactDOMComponent.Mixin.mountComponent @ main.js:19635ReactReconciler.mountComponent @ main.js:12467ReactCompositeComponentMixin.mountComponent @ main.js:14162wrapper @ main.js:11319ReactReconciler.mountComponent @ main.js:12467ReactMultiChild.Mixin.mountChildren @ main.js:22569ReactDOMComponent.Mixin.createContentMarkup @ main.js:19747ReactDOMComponent.Mixin.mountComponent @ main.js:19635ReactReconciler.mountComponent @ main.js:12467ReactMultiChild.Mixin.mountChildren @ main.js:22569ReactDOMComponent.Mixin.createContentMarkup @ main.js:19747ReactDOMComponent.Mixin.mountComponent @ main.js:19635ReactReconciler.mountComponent @ main.js:12467ReactCompositeComponentMixin.mountComponent @ main.js:14162wrapper @ main.js:11319ReactReconciler.mountComponent @ main.js:12467ReactCompositeComponentMixin.mountComponent @ main.js:14162wrapper @ main.js:11319ReactReconciler.mountComponent @ main.js:12467ReactCompositeComponentMixin.mountComponent @ main.js:14162wrapper @ main.js:11319ReactReconciler.mountComponent @ main.js:12467ReactCompositeComponentMixin.mountComponent @ main.js:14162wrapper @ main.js:11319ReactReconciler.mountComponent @ main.js:12467ReactCompositeComponentMixin.mountComponent @ main.js:14162wrapper @ main.js:11319ReactReconciler.mountComponent @ main.js:12467mountComponentIntoNode @ main.js:8838Mixin.perform @ main.js:13574batchedMountComponentIntoNode @ main.js:8854Mixin.perform @ main.js:13574ReactDefaultBatchingStrategy.batchedUpdates @ main.js:19146batchedUpdates @ main.js:13079ReactMount.renderNewRootComponent @ main.js:9048wrapper @ main.js:11319ReactMount.renderSubtreeIntoContainer @ main.js:9122ReactMount.render @ main.js:9142wrapper @ main.js:11319(anonymous function) @ main.js:8136(anonymous function) @ main.js:8152(anonymous function) @ main.js:8153__webpack_require @ main.js:521fn @ main.js:76(anonymous function) @ main.js:553__webpack_require @ main.js:521(anonymous function) @ main.js:544(anonymous function) @ main.js:547
main.js:11050 Warning: Failed propType: Invalid prop samples_list of type object supplied to SampleGrid, expected array. Check the render method of SampleGridContainer.warning @ main.js:11050checkPropTypes @ main.js:27803validatePropTypes @ main.js:27822ReactElementValidator.createElement @ main.js:27856render @ main.js:49402ReactCompositeComponentMixin._renderValidatedComponentWithoutOwnerOrContext @ main.js:14524ReactCompositeComponentMixin._renderValidatedComponent @ main.js:14544wrapper @ main.js:11319ReactCompositeComponentMixin.mountComponent @ main.js:14157wrapper @ main.js:11319ReactReconciler.mountComponent @ main.js:12467ReactCompositeComponentMixin.mountComponent @ main.js:14162wrapper @ main.js:11319ReactReconciler.mountComponent @ main.js:12467ReactMultiChild.Mixin.mountChildren @ main.js:22569ReactDOMComponent.Mixin._createContentMarkup @ main.js:19747ReactDOMComponent.Mixin.mountComponent @ main.js:19635ReactReconciler.mountComponent @ main.js:12467ReactMultiChild.Mixin.mountChildren @ main.js:22569ReactDOMComponent.Mixin.createContentMarkup @ main.js:19747ReactDOMComponent.Mixin.mountComponent @ main.js:19635ReactReconciler.mountComponent @ main.js:12467ReactMultiChild.Mixin.mountChildren @ main.js:22569ReactDOMComponent.Mixin.createContentMarkup @ main.js:19747ReactDOMComponent.Mixin.mountComponent @ main.js:19635ReactReconciler.mountComponent @ main.js:12467ReactCompositeComponentMixin.mountComponent @ main.js:14162wrapper @ main.js:11319ReactReconciler.mountComponent @ main.js:12467ReactCompositeComponentMixin.mountComponent @ main.js:14162wrapper @ main.js:11319ReactReconciler.mountComponent @ main.js:12467ReactCompositeComponentMixin.mountComponent @ main.js:14162wrapper @ main.js:11319ReactReconciler.mountComponent @ main.js:12467ReactCompositeComponentMixin.mountComponent @ main.js:14162wrapper @ main.js:11319ReactReconciler.mountComponent @ main.js:12467ReactCompositeComponentMixin.mountComponent @ main.js:14162wrapper @ main.js:11319ReactReconciler.mountComponent @ main.js:12467mountComponentIntoNode @ main.js:8838Mixin.perform @ main.js:13574batchedMountComponentIntoNode @ main.js:8854Mixin.perform @ main.js:13574ReactDefaultBatchingStrategy.batchedUpdates @ main.js:19146batchedUpdates @ main.js:13079ReactMount.renderNewRootComponent @ main.js:9048wrapper @ main.js:11319ReactMount.renderSubtreeIntoContainer @ main.js:9122ReactMount.render @ main.js:9142wrapper @ main.js:11319(anonymous function) @ main.js:8136(anonymous function) @ main.js:8152(anonymous function) @ main.js:8153__webpack_require @ main.js:521fn @ main.js:76(anonymous function) @ main.js:553__webpack_require @ main.js:521(anonymous function) @ main.js:544(anonymous function) @ main.js:547
main.js:11050 Warning: Failed propType: Invalid prop selected of type object supplied to SampleGrid, expected array. Check the render method of SampleGridContainer.warning @ main.js:11050checkPropTypes @ main.js:27803validatePropTypes @ main.js:27822ReactElementValidator.createElement @ main.js:27856render @ main.js:49402ReactCompositeComponentMixin._renderValidatedComponentWithoutOwnerOrContext @ main.js:14524ReactCompositeComponentMixin._renderValidatedComponent @ main.js:14544wrapper @ main.js:11319ReactCompositeComponentMixin.mountComponent @ main.js:14157wrapper @ main.js:11319ReactReconciler.mountComponent @ main.js:12467ReactCompositeComponentMixin.mountComponent @ main.js:14162wrapper @ main.js:11319ReactReconciler.mountComponent @ main.js:12467ReactMultiChild.Mixin.mountChildren @ main.js:22569ReactDOMComponent.Mixin._createContentMarkup @ main.js:19747ReactDOMComponent.Mixin.mountComponent @ main.js:19635ReactReconciler.mountComponent @ main.js:12467ReactMultiChild.Mixin.mountChildren @ main.js:22569ReactDOMComponent.Mixin.createContentMarkup @ main.js:19747ReactDOMComponent.Mixin.mountComponent @ main.js:19635ReactReconciler.mountComponent @ main.js:12467ReactMultiChild.Mixin.mountChildren @ main.js:22569ReactDOMComponent.Mixin.createContentMarkup @ main.js:19747ReactDOMComponent.Mixin.mountComponent @ main.js:19635ReactReconciler.mountComponent @ main.js:12467ReactCompositeComponentMixin.mountComponent @ main.js:14162wrapper @ main.js:11319ReactReconciler.mountComponent @ main.js:12467ReactCompositeComponentMixin.mountComponent @ main.js:14162wrapper @ main.js:11319ReactReconciler.mountComponent @ main.js:12467ReactCompositeComponentMixin.mountComponent @ main.js:14162wrapper @ main.js:11319ReactReconciler.mountComponent @ main.js:12467ReactCompositeComponentMixin.mountComponent @ main.js:14162wrapper @ main.js:11319ReactReconciler.mountComponent @ main.js:12467ReactCompositeComponentMixin.mountComponent @ main.js:14162wrapper @ main.js:11319ReactReconciler.mountComponent @ main.js:12467mountComponentIntoNode @ main.js:8838Mixin.perform @ main.js:13574batchedMountComponentIntoNode @ main.js:8854Mixin.perform @ main.js:13574ReactDefaultBatchingStrategy.batchedUpdates @ main.js:19146batchedUpdates @ main.js:13079ReactMount.renderNewRootComponent @ main.js:9048wrapper @ main.js:11319ReactMount.renderSubtreeIntoContainer @ main.js:9122ReactMount.render @ main.js:9142wrapper @ main.js:11319(anonymous function) @ main.js:8136(anonymous function) @ main.js:8152(anonymous function) @ main.js:8153__webpack_require @ main.js:521fn @ main.js:76(anonymous function) @ main.js:553__webpack_require @ main.js:521(anonymous function) @ main.js:544(anonymous function) @ main.js:547
main.js:11050 Warning: Failed propType: The prop 'id' is required to make 'Dropdown' accessible for users using assistive technologies such as screen readers Check the render method of Uncontrolled(Dropdown).warning @ main.js:11050checkPropTypes @ main.js:27803validatePropTypes @ main.js:27822ReactElementValidator.createElement @ main.js:27856render @ main.js:65455ReactCompositeComponentMixin._renderValidatedComponentWithoutOwnerOrContext @ main.js:14524ReactCompositeComponentMixin._renderValidatedComponent @ main.js:14544wrapper @ main.js:11319ReactCompositeComponentMixin.mountComponent @ main.js:14157wrapper @ main.js:11319ReactReconciler.mountComponent @ main.js:12467ReactCompositeComponentMixin.mountComponent @ main.js:14162wrapper @ main.js:11319ReactReconciler.mountComponent @ main.js:12467ReactMultiChild.Mixin.mountChildren @ main.js:22569ReactDOMComponent.Mixin._createContentMarkup @ main.js:19747ReactDOMComponent.Mixin.mountComponent @ main.js:19635ReactReconciler.mountComponent @ main.js:12467ReactCompositeComponentMixin.mountComponent @ main.js:14162wrapper @ main.js:11319ReactReconciler.mountComponent @ main.js:12467ReactMultiChild.Mixin.mountChildren @ main.js:22569ReactDOMComponent.Mixin._createContentMarkup @ main.js:19747ReactDOMComponent.Mixin.mountComponent @ main.js:19635ReactReconciler.mountComponent @ main.js:12467ReactMultiChild.Mixin.mountChildren @ main.js:22569ReactDOMComponent.Mixin._createContentMarkup @ main.js:19747ReactDOMComponent.Mixin.mountComponent @ main.js:19635ReactReconciler.mountComponent @ main.js:12467ReactMultiChild.Mixin.mountChildren @ main.js:22569ReactDOMComponent.Mixin._createContentMarkup @ main.js:19747ReactDOMComponent.Mixin.mountComponent @ main.js:19635ReactReconciler.mountComponent @ main.js:12467ReactCompositeComponentMixin.mountComponent @ main.js:14162wrapper @ main.js:11319ReactReconciler.mountComponent @ main.js:12467ReactCompositeComponentMixin.mountComponent @ main.js:14162wrapper @ main.js:11319ReactReconciler.mountComponent @ main.js:12467ReactMultiChild.Mixin.mountChildren @ main.js:22569ReactDOMComponent.Mixin._createContentMarkup @ main.js:19747ReactDOMComponent.Mixin.mountComponent @ main.js:19635ReactReconciler.mountComponent @ main.js:12467ReactMultiChild.Mixin.mountChildren @ main.js:22569ReactDOMComponent.Mixin.createContentMarkup @ main.js:19747ReactDOMComponent.Mixin.mountComponent @ main.js:19635ReactReconciler.mountComponent @ main.js:12467ReactMultiChild.Mixin.mountChildren @ main.js:22569ReactDOMComponent.Mixin.createContentMarkup @ main.js:19747ReactDOMComponent.Mixin.mountComponent @ main.js:19635ReactReconciler.mountComponent @ main.js:12467ReactCompositeComponentMixin.mountComponent @ main.js:14162wrapper @ main.js:11319ReactReconciler.mountComponent @ main.js:12467ReactCompositeComponentMixin.mountComponent @ main.js:14162wrapper @ main.js:11319ReactReconciler.mountComponent @ main.js:12467ReactCompositeComponentMixin.mountComponent @ main.js:14162wrapper @ main.js:11319ReactReconciler.mountComponent @ main.js:12467ReactCompositeComponentMixin.mountComponent @ main.js:14162wrapper @ main.js:11319ReactReconciler.mountComponent @ main.js:12467ReactCompositeComponentMixin.mountComponent @ main.js:14162wrapper @ main.js:11319ReactReconciler.mountComponent @ main.js:12467mountComponentIntoNode @ main.js:8838Mixin.perform @ main.js:13574batchedMountComponentIntoNode @ main.js:8854Mixin.perform @ main.js:13574ReactDefaultBatchingStrategy.batchedUpdates @ main.js:19146batchedUpdates @ main.js:13079ReactMount.renderNewRootComponent @ main.js:9048wrapper @ main.js:11319ReactMount.renderSubtreeIntoContainer @ main.js:9122ReactMount.render @ main.js:9142wrapper @ main.js:11319(anonymous function) @ main.js:8136(anonymous function) @ main.js:8152(anonymous function) @ main.js:8153__webpack_require @ main.js:521fn @ main.js:76(anonymous function) @ main.js:553__webpack_require @ main.js:521(anonymous function) @ main.js:544(anonymous function) @ main.js:547
main.js:11050 Warning: Failed propType: Invalid prop pullRight of type string supplied to Dropdown, expected boolean. Check the render method of Uncontrolled(Dropdown).warning @ main.js:11050checkPropTypes @ main.js:27803validatePropTypes @ main.js:27822ReactElementValidator.createElement @ main.js:27856render @ main.js:65455ReactCompositeComponentMixin._renderValidatedComponentWithoutOwnerOrContext @ main.js:14524ReactCompositeComponentMixin._renderValidatedComponent @ main.js:14544wrapper @ main.js:11319ReactCompositeComponentMixin.mountComponent @ main.js:14157wrapper @ main.js:11319ReactReconciler.mountComponent @ main.js:12467ReactCompositeComponentMixin.mountComponent @ main.js:14162wrapper @ main.js:11319ReactReconciler.mountComponent @ main.js:12467ReactMultiChild.Mixin.mountChildren @ main.js:22569ReactDOMComponent.Mixin._createContentMarkup @ main.js:19747ReactDOMComponent.Mixin.mountComponent @ main.js:19635ReactReconciler.mountComponent @ main.js:12467ReactCompositeComponentMixin.mountComponent @ main.js:14162wrapper @ main.js:11319ReactReconciler.mountComponent @ main.js:12467ReactMultiChild.Mixin.mountChildren @ main.js:22569ReactDOMComponent.Mixin._createContentMarkup @ main.js:19747ReactDOMComponent.Mixin.mountComponent @ main.js:19635ReactReconciler.mountComponent @ main.js:12467ReactMultiChild.Mixin.mountChildren @ main.js:22569ReactDOMComponent.Mixin._createContentMarkup @ main.js:19747ReactDOMComponent.Mixin.mountComponent @ main.js:19635ReactReconciler.mountComponent @ main.js:12467ReactMultiChild.Mixin.mountChildren @ main.js:22569ReactDOMComponent.Mixin._createContentMarkup @ main.js:19747ReactDOMComponent.Mixin.mountComponent @ main.js:19635ReactReconciler.mountComponent @ main.js:12467ReactCompositeComponentMixin.mountComponent @ main.js:14162wrapper @ main.js:11319ReactReconciler.mountComponent @ main.js:12467ReactCompositeComponentMixin.mountComponent @ main.js:14162wrapper @ main.js:11319ReactReconciler.mountComponent @ main.js:12467ReactMultiChild.Mixin.mountChildren @ main.js:22569ReactDOMComponent.Mixin._createContentMarkup @ main.js:19747ReactDOMComponent.Mixin.mountComponent @ main.js:19635ReactReconciler.mountComponent @ main.js:12467ReactMultiChild.Mixin.mountChildren @ main.js:22569ReactDOMComponent.Mixin.createContentMarkup @ main.js:19747ReactDOMComponent.Mixin.mountComponent @ main.js:19635ReactReconciler.mountComponent @ main.js:12467ReactMultiChild.Mixin.mountChildren @ main.js:22569ReactDOMComponent.Mixin.createContentMarkup @ main.js:19747ReactDOMComponent.Mixin.mountComponent @ main.js:19635ReactReconciler.mountComponent @ main.js:12467ReactCompositeComponentMixin.mountComponent @ main.js:14162wrapper @ main.js:11319ReactReconciler.mountComponent @ main.js:12467ReactCompositeComponentMixin.mountComponent @ main.js:14162wrapper @ main.js:11319ReactReconciler.mountComponent @ main.js:12467ReactCompositeComponentMixin.mountComponent @ main.js:14162wrapper @ main.js:11319ReactReconciler.mountComponent @ main.js:12467ReactCompositeComponentMixin.mountComponent @ main.js:14162wrapper @ main.js:11319ReactReconciler.mountComponent @ main.js:12467ReactCompositeComponentMixin.mountComponent @ main.js:14162wrapper @ main.js:11319ReactReconciler.mountComponent @ main.js:12467mountComponentIntoNode @ main.js:8838Mixin.perform @ main.js:13574batchedMountComponentIntoNode @ main.js:8854Mixin.perform @ main.js:13574ReactDefaultBatchingStrategy.batchedUpdates @ main.js:19146batchedUpdates @ main.js:13079ReactMount.renderNewRootComponent @ main.js:9048wrapper @ main.js:11319ReactMount.renderSubtreeIntoContainer @ main.js:9122ReactMount.render @ main.js:9142wrapper @ main.js:11319(anonymous function) @ main.js:8136(anonymous function) @ main.js:8152(anonymous function) @ main.js:8153__webpack_require @ main.js:521fn @ main.js:76(anonymous function) @ main.js:553__webpack_require @ main.js:521(anonymous function) @ main.js:544(anonymous function) @ main.js:547
main.js:11050 Warning: Failed propType: Invalid prop pullRight of type string supplied to DropdownMenu, expected boolean. Check the render method of Dropdown.

"

Sample Video

Display the sample centring view. With the following features:

  • Display the sample video from the diffractometer
  • Ability to take snapshots of the image
  • Ability to control the motors, light, etc.
  • Tools to measure distance/angles and draw lines/angles (not needed in the beginning)
  • Draw beam position
  • It should also display the queue for the current mounted sample (getting the pre-configured experiment from the mxcube3-queue), but also must provide tools for modifying parameters, collections...
  • All these features needs code in the server as well

Preliminary layout from https://github.com/meguiraun/WebLayoutTests:

sampleview

Note: modified slightly after the discussion about the web layout and assigned to MaxIV (which means to me...) as we spoke in the meeting.

[Queue] Enhanced design

The needs to be redesigned:

  • Methods should be attached to centring positions
    • So… redesign both the server and the client, additional queue level needed
    • A design review of the queue (VIEW) is needed, what we have been working on does not seem to fulfil the requirements of the experiment
  • In the server side methods should hang from TaskGroupNode? (currently from SampleNode)

Sample Changer

Communicate with and manage the sample changer, in order to start using it from the beginning.

The Sample Grid already gets samples from sample changer.

Missing for 1st version:

  • dedicated UI for sample changer with basic control (select basket, move to sample, read datamatrices etc)

Web server

Split the code into a pure server code and HO management. The later is affected by the features that are exposed to the user and the characteristics of the beamline. However, and generic and general rest api can still be defined.
A bigger issue is the python backend to use, although the benefits of bottle rely on its simplicity, that is also a drawback. As soon as we need more advance features it becomes much easier to use Flask, due to the extensions already developed (socketio, login, restful, etc.)

  • Rest API?: define the required methods as they are needed. The syntax is very be dependent on the function/experiment so a preliminary syntax guidelines should be developed. Data interchange should also be defined, #5.
  • We will use flask

User interface and server data interchange

Define the structure of the messages (a dictionary) to be exchanged and provide a common api for both the backend and the interface.

As a preliminary draft:

{
  "Data": {
      DATA_STRUCTURE,
  },
  "Origin": aClass.aMethod, #who is sending the data
  "HTTP request": PUT/GET, # is this really useful?
  "Debug": True, #to print or not to print
  "Time": YY:MM:DD, HH:MM:SS,
  "Username": username,
  "Proposal": proposal
}

The data structure is very dependant on the request or action to be executed, for example for getting the status of a motor.

 "Data": { "kappa":{'Status': 'DeviceReady', 'Position': 3.14}  }

same for several:

 "Data": { "kappa":{'Status': 'DeviceReady', 'Position': 3.14},
         { "omega":{'Status': 'Moving', 'Position': 42.0} ,
         { "phi":{'Status': 'Unknown', 'Position': 2.72} 
}

We need to define the general structure and wherever we can the internal 'Data' field.

Another approach when sending data/commands from the client to the server could be to define everything in the url:

$.ajax({
      url: '/mxcube/api/v0.1/samplecentring/zoom/move?newpos='+newZoom, //where newZoom is e.g. 'Zoom 3'
      contentType: 'application/json;charset=UTF-8',
      type: 'PUT',
      success: function(res) {  :-)    },
      error: function(error) {  :-(    },
    });

And then in the server, get the argument

@mxcube.route("/mxcube/api/v0.1/samplecentring/<id>/move", methods=['PUT'])
def moveSampleCentringMotor(id):
    new_pos = request.args.get('newpos','')
    try:
        motor_hwobj = mxcube.diffractometer.getObjectByRole(id.lower()) # id would be 'zoom' in this example
        return 'True'
    except:
        return 'False' # or better a well formed dict

Queue operation

Hi,

I have created a wiki page explaining the queue hardware object (or trying to...) here. Could you have a look at it and check if have not ruined the queue model operation? It works for me but I am not sure if this is the intended way of working with the queue.

I will continue with the queue backend based on what it is in that wiki page, and of course, I will continue updating the wiki (how to configure a datacollection for example...)

thanks,

Local/remote mode

Ability to gain experiment control from a ~local gui over a remote user, it is not mandatory in the beginning, however it will be required at long term so the initial development must take this into account and an initial environment for this characteristic must be set.

[Queue] Serialization

Investigate the serialization of the queue, so the queue object it can be easily stored and retrieved

Related to #58

HardwareObjects submodule

At the moment the HardwareObjects submodule points to commit 96cae8 of the HardwareObjects repository. This commit is from the master branch of MXCuBE 2. I think we should not build MXCuBE 3
on top of the master branch versions of Hardware Objects, since it is unstable and some changes may be untested.
In particular, I wanted to test latest MXCuBE 3 in "real situation" yesterday but I couldn't because the signature of a function changed in MiniDiff.py in master branch compared to 2.1.
My question is : would you agree to use 2.1 versions of Hardware Objects as our HardwareObjects submodule ?
If you are ok I can make a pull request for this, yesterday evening I created a 2.1 branch in the HardwareObjects repository.

Manual Sample (un)load

Ability to manage sample(s) manually and launching collections. This is specially useful in the beginning and in commis- sioning/testing stages, thus avoiding ispyb connections.

Readme file

create the readme file for mxcube3

  • aim of the project, history?
  • structure
  • links to doc, wiki, mxcube2
  • etc

mockup hardware objects xml files

As pointed out in discussion from PR #42, a common set of mockup hardware objects has to be integrated within the repository in order to make basic testing much easier (and uniform across institutes).

Session management

The session history must be kept in the web server, in case the client crashes we could be able to redraw the client interface at the same state as it was. Note that this requires an study on the available and useful web tools.
It must be saved automatically and with the possibility of save it manually.

User login

Login into ISPyB and retrieve the sample list and the relevant data for all the samples involved in the experiment. In the beginning it can be a single proposal with a single crystal defined in the database. The ISPyB integration is already done in existing HardwareObjects therefore it should not involve too much extra work.

User login

By means of the flask-session (or an additional llibrary e.g. flask-login) keep track of the user currently logged in (the authentication is done through the IspybClient)

  • Store the current user
  • Provide a way of blocking some api calls if not logged in (to be decided later which calls should be blocked, all of them?); sth like mxlogin_required
  • Remember the user
  • Related to #58

Sample grid

The sample grid displays available samples from ISPyB or contents of the Sample Changer, and also a "Manually mounted" sample.

Selecting items on this grid is the first step to add samples to be collected to the Queue.

The Sample Grid items show a summary of the sample information, including sample changer
location, protein acronym, data matrix code, etc.
It shows the foreseen data collections to be applied on the sample, or those that already happened with some color code.

Message Logger

The browser’s console does not work properly as a message logger system. An extra browser tab and a file could be enough, the idea is to have the same information as the current mxcube in addition to any message related to the web communication.

Store session data

Save relevant session data into a database (redis?), with some kind of expiry date.
We need to store two queues: sample_changer and manual mounting queues
Related to #113 and #58

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.