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

find_devices() from polartools.utils #502

Closed
prjemian opened this issue Mar 17, 2021 · 8 comments · Fixed by #521
Closed

find_devices() from polartools.utils #502

prjemian opened this issue Mar 17, 2021 · 8 comments · Fixed by #521
Milestone

Comments

@prjemian
Copy link
Contributor

prjemian commented Mar 17, 2021

In discussions with 4ID-Polar today, they showed a new utility to identify ophyd devices/signals that share a common string. This tool (now) looks in the baseline stream for items which match (full or partial) a string.

Example: find m1 in the most recent run:

In [61]: find_devices(-1, db, "m1")
Out[61]: ['m1']

In [62]: find_devices(-1, db, "m")
Out[62]: ['time', 'm1']

In [63]: find_devices(-1, db, "")
Out[63]: ['time', 'm1']

Consider adding this to apstools.utils.

Thanks @strempfer & @gfabbris !

from https://github.com/APS-4ID-POLAR/polartools/blob/main/polartools/load_data.py

@prjemian
Copy link
Contributor Author

prjemian commented Mar 17, 2021

def find_devices(scan, db, name, query=None):
    # so, for instance, if you give the name "lakeshore"
    # it will return all the devices with that string.
    table = load_databroker(scan, db, stream="baseline", query=query)
    output = []
    for col in table.columns:
        if name in col:
            output.append(col)
    return output

def read_baseline(scan, db, devices, query=None):
    table = load_databroker(scan, db, stream="baseline", query=query)
    return table[devices].mean()

def read_devices(scan, db, name, query=None):
    # companion to find_devices() above
    devices = find_devices(scan, db, name, query=query)
    return read_baseline(scan, db, devices)

def load_databroker(scan_id, db, stream="primary", query=None, use_db_v1=True):
    _db = db_query(db, query) if query else db
    if use_db_v1:
        return _db.v1[scan_id].table(stream_name=stream)
    else:
        return getattr(_db.v2[scan_id], stream).read().to_dataframe()

@prjemian prjemian added this to the 1.4.3 milestone Mar 18, 2021
@prjemian
Copy link
Contributor Author

prjemian commented Jul 8, 2021

The names seem rather broad. For example, find_devices is limited to finding devices in a single scan. All of these are focused on a single scan. Planning to append _in_scan to function names.

@prjemian
Copy link
Contributor Author

prjemian commented Jul 8, 2021

Since read_baseline() uses devices as a single device, the call from read_devices() does not make much sense to me. Better to use the databroker v2 interface and get all this as a DataFrame or xarray table. Not planning to implement read_devices() without a better explanation of what it might provide that is not already available.

@prjemian
Copy link
Contributor Author

prjemian commented Jul 8, 2021

Need definition of db_query()

prjemian added a commit that referenced this issue Jul 8, 2021
prjemian added a commit that referenced this issue Jul 8, 2021
prjemian added a commit that referenced this issue Jul 8, 2021
prjemian added a commit that referenced this issue Jul 8, 2021
prjemian added a commit that referenced this issue Jul 9, 2021
prjemian added a commit that referenced this issue Jul 9, 2021
prjemian added a commit that referenced this issue Jul 9, 2021
prjemian added a commit that referenced this issue Jul 9, 2021
@prjemian
Copy link
Contributor Author

Compare with lookup_position() (from polartools) for read_devices()

@prjemian
Copy link
Contributor Author

def lookup_position(db, scan, search_string="", query=None):
    """
    Lookup positioner values in past scans.
    Parameters
    ----------
    db : databroker database
        Searcheable database
    scan : integer
        Scan numbers or uids.
    search_string : string
        Full or part of positioner name.
    query: dict
        Search parameters.
    Returns
    -------
    output: list
    """

    db_range = db_query(db, query=query) if query else db

    baseline = load_databroker(scan, db_range, "baseline", use_db_v1=True)
    if len(baseline["time"]) == 2:
        date1 = baseline["time"][1].strftime("%m/%d/%y %H:%M:%S")
        date2 = baseline["time"][2].strftime("%m/%d/%y %H:%M:%S")
        print("=".center(100, "="))
        print(f"{'Positioner':>50}{date1:>25}{date2:>25}")
        print("-".center(100, "-"))
        for key in baseline.keys():
            if search_string in key:
                if isinstance(baseline[key][1], list):
                    print(f"{key:>50}{baseline[key][1]}{baseline[key][2]}")
                else:
                    print(
                        f"{key:>50}{baseline[key][1]:>25}{baseline[key][2]:>25}"
                    )

    else:
        date1 = baseline["time"][1].strftime("%m/%d/%y %H:%M:%S")
        print("=".center(100, "="))
        print(f"{'Positioner':>50}{date1:>25}")
        print("-".center(100, "-"))
        for key in baseline.keys():
            if search_string in key:
                if isinstance(baseline[key][1], list):
                    print(f"{key:>50}{baseline[key][1]}")
                else:
                    print(f"{key:>50}{baseline[key][1]:>25}")

    print("-".center(100, "-"))

@prjemian
Copy link
Contributor Author

prjemian commented Jul 14, 2021

The index numbers 1 .. 2, ... are "sequence numbers" because baseline is a pandas DataFrame. Example:

In [1]: import databroker
d
In [2]: cat = databroker.catalog["training"]

In [3]: run = cat.v1[-1]

In [5]: baseline = run.table(stream_name="baseline")

In [6]: baseline["time"]
Out[6]: 
seq_num
1   2021-06-02 18:36:29.552511215
2   2021-06-02 18:36:34.705037355
Name: time, dtype: datetime64[ns]

In [7]: type(_)
Out[7]: pandas.core.series.Series

In [8]: 

prjemian added a commit that referenced this issue Jul 16, 2021
prjemian added a commit that referenced this issue Jul 16, 2021
prjemian added a commit that referenced this issue Jul 16, 2021
prjemian added a commit that referenced this issue Jul 16, 2021
prjemian added a commit that referenced this issue Jul 16, 2021
prjemian added a commit that referenced this issue Jul 16, 2021
@CrI3
Copy link
Collaborator

CrI3 commented Jul 21, 2021

Awesome!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants