Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proof of concept implementation: Tiled as DataSource in PyMca #1064

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions PyMca5/PyMcaCore/SpecFileDataSource.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,9 @@ def __getScanInfo(self, scankey):
sourceObject = self._sourceObjectList[index]
scandata= sourceObject.select(scankey)

_logger.info("__getScanInfo %s", scandata)


info={}
info["SourceType"] = SOURCE_TYPE
#doubts about if refer to the list or to the individual file
Expand Down
107 changes: 107 additions & 0 deletions PyMca5/PyMcaCore/TiledTools.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
from tiled.client import from_uri,from_profile

from databroker.queries import TimeRange
from tiled.queries import In

##fixme ... needs arg to connect to corret service
#def get_tiled_connection():
# return from_uri("https://tiled-demo.blueskyproject.io")

class TiledAdaptor(object):
@classmethod
def get_nested(cls,d, keys):
#FIXME to be done more efficient
for k in keys:
d = d[k]
return d

def __init__(self,host,prefix=None):
print("init TiledAdaptor",host)
if "http" in host:
self._client = from_uri(host)
else:
self._client = from_profile(host)

#specific hack for shen beamtime
if host=="opls":
#specific hack for shen beamtime, just to reduce the scope
from tiled.queries import FullText
#self._client = self._client.search(TimeRange(since='2024-03-02 01:00', until='2024-03-02 02:00'))
self._client = self._client.search(In("plan_name",["reflection_scan","rel_scan"])).search(TimeRange(since='2024-03-01', until='2024-03-02 07:00'))

elif prefix:
self._client = TiledAdaptor.get_nested(self._client,prefix.split("/"))

self.__prefix=prefix
print(self._client)

def get_node(self,path=None,scan_id=None):

if not scan_id is None:
if path and "/" in path:
return self.get_nested(self._client[scan_id],path.split("/"))
elif not path:
return self._client[scan_id]
else:
return self._client[scan_id][path]
else:
if "/" in path:
return self.get_nested(self._client,path.split("/"))
elif not path:
return self._client
else:
return self._client[path]


@property
def client(self):
return self._client

# @property
# def _sourceName(self):
# return self.__sourceName

# @_sourceName.setter
# def _sourceName(self,sn):
# self.__sourceName = sn

# def close(self):
# #not sure if there is anything that needs to happen here
# return

# def getSourceInfo(self):
# """
# Returns a dictionary with the key "KeyList" (list of all available keys
# in this source). Each element in "KeyList" has the form 'n1.n2' where
# n1 is the source number and n2 entry number in file both starting at 1.
# """
# print("TiledAdaptor getSourceInfo")
# return {"KeyList":["1.1"]}

# @property
# def name(self):
# return "/"

# @property
# def filename(self):
# return "toto"

#very simplistic and "bad" coding ... just going global tiled connection for now

#just to be a little quicker ... only work against fxi first
_TILED_CLIENT_opls=TiledAdaptor("opls")
_TILED_CLIENT_fxi=TiledAdaptor("https://tiled-demo.blueskyproject.io","fxi/raw")


def get_sessions_list():
return ["opls","demo:fxi"]

def get_node(path):
#path ... to be resolved from tiled...
if path=="opls":
return _TILED_CLIENT_opls
if path=="demo:fxi":
return _TILED_CLIENT_fxi
else:
print(">>> trying to access: ",path)
raise
56 changes: 30 additions & 26 deletions PyMca5/PyMcaGui/io/QSourceSelector.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,17 @@
from PyMca5 import PyMcaDirs
from PyMca5.PyMcaGui.io import PyMcaFileDialogs

BLISS = False
if sys.version_info > (3, 5):
try:
from PyMca5.PyMcaCore import RedisTools
BLISS = True
except Exception:
_logger.info("Bliss data file direct support not available")

#Fixme just a quick fix ... dropin replacement of bliss with tiled/bluesky
BLISS = True
# if sys.version_info > (3, 5):
# try:
# from PyMca5.PyMcaCore import RedisTools
# BLISS = True
# except Exception:
# _logger.info("Bliss data file direct support not available")

from PyMca5.PyMcaCore import TiledTools
#from PyMca5.PyMcaCore import RedisTools

class QSourceSelector(qt.QWidget):
sigSourceSelectorSignal = qt.pyqtSignal(object)
Expand Down Expand Up @@ -156,7 +159,7 @@ def openSource(self, sourcename, specsession=None):
if specsession is None:
if sourcename in sps.getspeclist():
specsession=True
elif BLISS and sourcename in RedisTools.get_sessions_list():
elif BLISS and sourcename in TiledTools.get_sessions_list():
specsession = "bliss"
else:
specsession=False
Expand All @@ -168,25 +171,26 @@ def openFile(self, filename=None, justloaded=None, specsession=False):
if specsession == "bliss":
specsession = False
session = filename
node = RedisTools.get_node(session)
node = TiledTools.get_node(session)
if not node:
txt = "No REDIS information retrieved from session %s" % \
session
raise IOError(txt)
filename = RedisTools.get_session_filename(node)
if not len(filename):
txt = "Cannot retrieve last output filename from session %s" % \
session
raise IOError(txt)
if not os.path.exists(filename):
txt = "Last output file <%s> does not exist" % filename
raise IOError(txt)
filename = [filename]
key = os.path.basename(filename[0])
try:
self._emitSourceSelectedOrReloaded(filename, key)
except Exception:
_logger.error("Problem opening %s" % filename[0])
#NOT GOING HERE AS WE DON'T WANT TO BE HYBRID FILE+DB FOR TILED
#
# if not len(filename):
# txt = "Cannot retrieve last output filename from session %s" % \
# session
# raise IOError(txt)
# if not os.path.exists(filename):
# txt = "Last output file <%s> does not exist" % filename
# raise IOError(txt)
# filename = [filename]
# key = os.path.basename(filename[0])
# try:
# self._emitSourceSelectedOrReloaded(filename, key)
# except Exception:
# _logger.error("Problem opening %s" % filename[0])
key = "%s" % session
self._emitSourceSelectedOrReloaded([session], key)
return
Expand Down Expand Up @@ -289,12 +293,12 @@ def closeFile(self):
def openBlissOrSpec(self):
if not BLISS:
return self.openSpec()
sessionList = RedisTools.get_sessions_list()
sessionList = TiledTools.get_sessions_list()
if not len(sessionList):
return self.openSpec()
activeList = []
for session in sessionList:
node = RedisTools.get_node(session)
node = TiledTools.get_node(session)
if node:
activeList.append(session)
if not len(activeList):
Expand Down
4 changes: 4 additions & 0 deletions PyMca5/PyMcaGui/io/QSpecFileWidget.py
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,10 @@ def __selectionChanged(self):
if not len(sel):
return
info = self.data.getKeyInfo(sel[0])
_logger.info("__selectionChanged info data %s",self.data)
_logger.info("__selectionChanged info %s",info)
_logger.info("__selectionChanged sel %s",sel)
_logger.info("__selectionChanged sel[0] %s",sel[0])
self.mcaTable.build(info)
if False:
# This does not work properly yet
Expand Down
40 changes: 38 additions & 2 deletions PyMca5/PyMcaGui/plotting/PyMca_Icons.py
Original file line number Diff line number Diff line change
Expand Up @@ -3585,7 +3585,43 @@
"..##################..",
"......................"]


bluesky = [
"32 32 2 1 ",
" c None",
"B c #87CEEB",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" BBBBBBB ",
" BBBBBBB ",
" BBBBBBBBBBBBBB ",
" BBBBBBBBBBBBBB ",
" BBBBBBBBBBBBBBBBBB ",
" BBBBBBBBBBBBBBBBBBB BBB ",
" BBBBBBBBBBBBBBBBBBB BBB ",
" BBBBBBBBBBBBBBBBBBBB BBBBBBBB ",
" BBBBBBBBBBBBBBBBBBBB BBBBBBBB ",
" BBBBBBBBBBBBBBBBBBBB BBBB BB",
" BBBBBBBBBBBBBBBBBBBB BBBB BB",
" BBBBBBBBBBBBBBBBBBBB BBBBBB BB",
" BBBBBBBBBBBBBBBBBBBB BBBBBB BB",
" BBBBBBBBBBBBBBBBBBBB BBBB BB ",
" BBBBBBBBBBBBBBBBBBBB BBBB BB ",
" BBBBBBBBBBBBBBBBBBBBBBBBB ",
" BBBBBBBBBBBBBBBBBBBBBBBBB ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
" ",
]

IconDict0 = {
"derive": derive,
Expand All @@ -3596,7 +3632,7 @@
"filesave": file_save,
"fileprint": image_print_data,
"spec": spec,
"bliss": bliss,
"bliss": bluesky,
"normal": normal,
"normalize16": normalize16,
"reload": reload_,
Expand Down
9 changes: 9 additions & 0 deletions PyMca5/PyMcaGui/pymca/QDataSource.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@
from PyMca5.PyMcaGui.io import QEdfFileWidget
from PyMca5.PyMcaGui.io import QSpecFileWidget

import logging
_logger = logging.getLogger(__name__)

if sys.platform == "win32":
source_types = { SpecFileDataSource.SOURCE_TYPE: SpecFileDataSource.SpecFileDataSource,
EdfFileDataSource.SOURCE_TYPE: EdfFileDataSource.EdfFileDataSource}
Expand Down Expand Up @@ -81,6 +84,10 @@ def getSourceType(sourceName0):
else:
sourceName = sourceName0

#FIXME: just a quick and dirty fix to get going with tiled
if sourceName == "opls" or sourceName == "demo:fxi":
return SpecFileDataSource.SOURCE_TYPE

if BlissSpecFile.isBlissSpecFile(sourceName):
# wrapped as SpecFile
return SpecFileDataSource.SOURCE_TYPE
Expand Down Expand Up @@ -167,6 +174,8 @@ def QDataSource(name=None, source_type=None):
except KeyError:
#ERROR invalid source type
raise TypeError("Invalid Source Type, source type should be one of %s" % source_types.keys())
_logger.debug("source_types %s", source_types, )
_logger.debug("sourceClass %s, name %s", sourceClass, name)
return sourceClass(name)


Expand Down
Loading