fab.beamtime

Beamtime Management

This module provides utilities for managing beamtime information at the FLASH facility. It handles beamtime identification, path resolution, and integration with the fabtrack run tracking system when available.

The main Beamtime class provides access to beamtime metadata and run information, automatically detecting the beamtime number from the current working directory when running on the GPFS filesystem. Integration with fabtrack allows viewing and querying the run table for accessing DAQ run metadata.

Usage

The beamtime object is typically imported via fab.magic which automatically detects the current beamtime:

from fab.magic import config, beamtime

print(beamtime.id)        # Beamtime number
print(beamtime.basepath)  # Path to beamtime data
print(beamtime.runs)      # Run tracker (if fabtrack is available)

Alternatively, you can create a beamtime object manually by specifying the beamtime number:

from fab.beamtime import Beamtime

bt = Beamtime(11020281)

Working with fabtrack

If fabtrack is installed and was used during the beamtime, the runs attribute provides a RunTracker instance that allows you to store, update, and query metadata for each DAQ run. This is useful for keeping track of experimental parameters, run status, and comments throughout your beamtime.

Viewing the run table

from fab.magic import beamtime

# Display interactive run table (in Jupyter)
beamtime

# Get run table as pandas DataFrame
df = beamtime.runs

# Search and filter runs interactively
beamtime.fabtrack.search()

Creating and updating run metadata

# Update metadata for an existing run
beamtime.fabtrack.update_run(run_id=2570, 
    aborted=False,
    comment='Good signal quality'
)

# Attach a figure to run metadata
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.plot(data)
beamtime.fabtrack.set_figure(run_id=2570, fig=fig)

Metadata is automatically versioned - each update creates a new version while preserving the history. Metadata files are stored as YAML in /meta/fabtrack/ within your beamtime directory.

  1'''
  2## Beamtime Management
  3
  4This module provides utilities for managing beamtime information at the FLASH facility.
  5It handles beamtime identification, path resolution, and integration with the fabtrack
  6run tracking system when available.
  7
  8The main `Beamtime` class provides access to beamtime metadata and run information,
  9automatically detecting the beamtime number from the current working directory when
 10running on the GPFS filesystem. Integration with fabtrack allows viewing and querying
 11the run table for accessing DAQ run metadata.
 12
 13## Usage
 14
 15The beamtime object is typically imported via `fab.magic` which automatically detects
 16the current beamtime:
 17
 18```python
 19from fab.magic import config, beamtime
 20
 21print(beamtime.id)        # Beamtime number
 22print(beamtime.basepath)  # Path to beamtime data
 23print(beamtime.runs)      # Run tracker (if fabtrack is available)
 24```
 25
 26Alternatively, you can create a beamtime object manually by specifying the beamtime number:
 27
 28```python
 29from fab.beamtime import Beamtime
 30
 31bt = Beamtime(11020281)
 32```
 33
 34## Working with fabtrack
 35
 36If fabtrack is installed and was used during the beamtime, the `runs` attribute provides a `RunTracker` 
 37instance that allows you to store, update, and query metadata for each DAQ run. This is useful for 
 38keeping track of experimental parameters, run status, and comments throughout your beamtime.
 39
 40### Viewing the run table
 41
 42```python
 43from fab.magic import beamtime
 44
 45# Display interactive run table (in Jupyter)
 46beamtime
 47
 48# Get run table as pandas DataFrame
 49df = beamtime.runs
 50
 51# Search and filter runs interactively
 52beamtime.fabtrack.search()
 53```
 54
 55### Creating and updating run metadata
 56
 57```python
 58# Update metadata for an existing run
 59beamtime.fabtrack.update_run(run_id=2570, 
 60    aborted=False,
 61    comment='Good signal quality'
 62)
 63
 64# Attach a figure to run metadata
 65import matplotlib.pyplot as plt
 66fig, ax = plt.subplots()
 67ax.plot(data)
 68beamtime.fabtrack.set_figure(run_id=2570, fig=fig)
 69```
 70
 71Metadata is automatically versioned - each update creates a new version while preserving
 72the history. Metadata files are stored as YAML in `/meta/fabtrack/` within your beamtime directory.
 73'''
 74
 75import os
 76import pandas as pd
 77from typing import Protocol
 78from dataclasses import dataclass
 79import glob
 80import seaborn as sns
 81
 82from .settings import cfg
 83
 84import logging
 85logger = logging.getLogger(__name__)
 86tele_log = logging.getLogger('fab.telemetry')
 87
 88try:
 89    import fabtrack
 90except ModuleNotFoundError:
 91    fabtrack = None
 92
 93def autodetect_beamtime():
 94    ''' Attempts to autodetect the beamtime number from the current working directory.'''
 95    
 96    try:
 97        return int(os.getcwd().split('/')[7])
 98    except IndexError as e:
 99        raise ValueError("Could not autodetect beamtime number from current working directory") from e
100
101def beamtime_basepath(beamtime_num):
102    ''' Attempts to find the basepath of the beamtime on the GPFS filesystem.'''
103
104    basepath = f"/asap3/*flash*/gpfs/*/*/data/{beamtime_num}"
105    basepath = glob.glob(basepath)[0]
106    
107    return basepath 
108
109class Beamtime:
110    """ Represents a beamtime at the FLASH facility
111
112        Properties:
113            id: The beamtime number
114            basepath: The basepath of the beamtime
115            fabtrack: The fabtrack tracker of the beamtime, if fabtrack is installed
116            runs: The run table of the beamtime as a pandas DataFrame, if fabtrack is installed
117    """
118
119    def __init__(self, beamtime_num):
120        self.id = beamtime_num
121        try:
122            self.basepath = beamtime_basepath(beamtime_num)
123        except IndexError as e:
124            self.basepath = "/asap3/flash/gpfs/" #placeholder
125
126        self.fabtrack = None
127        if fabtrack is not None:
128            self.fabtrack = fabtrack.RunTracker(beamtime_id=self.id)
129
130    @property
131    def runs(self):
132        if self.fabtrack is None:
133            raise ValueError("fabtrack is not installed, cannot access runs")
134        return self.fabtrack.table()
135
136    def __repr__(self):
137        return f"Beamtime {self.id} at {self.basepath}"
138
139    def _ipython_display_(self):
140        display(self.fabtrack)
logger = <Logger fab.beamtime (INFO)>
tele_log = <Logger fab.telemetry (INFO)>
def autodetect_beamtime():
 94def autodetect_beamtime():
 95    ''' Attempts to autodetect the beamtime number from the current working directory.'''
 96    
 97    try:
 98        return int(os.getcwd().split('/')[7])
 99    except IndexError as e:
100        raise ValueError("Could not autodetect beamtime number from current working directory") from e

Attempts to autodetect the beamtime number from the current working directory.

def beamtime_basepath(beamtime_num):
102def beamtime_basepath(beamtime_num):
103    ''' Attempts to find the basepath of the beamtime on the GPFS filesystem.'''
104
105    basepath = f"/asap3/*flash*/gpfs/*/*/data/{beamtime_num}"
106    basepath = glob.glob(basepath)[0]
107    
108    return basepath 

Attempts to find the basepath of the beamtime on the GPFS filesystem.

class Beamtime:
110class Beamtime:
111    """ Represents a beamtime at the FLASH facility
112
113        Properties:
114            id: The beamtime number
115            basepath: The basepath of the beamtime
116            fabtrack: The fabtrack tracker of the beamtime, if fabtrack is installed
117            runs: The run table of the beamtime as a pandas DataFrame, if fabtrack is installed
118    """
119
120    def __init__(self, beamtime_num):
121        self.id = beamtime_num
122        try:
123            self.basepath = beamtime_basepath(beamtime_num)
124        except IndexError as e:
125            self.basepath = "/asap3/flash/gpfs/" #placeholder
126
127        self.fabtrack = None
128        if fabtrack is not None:
129            self.fabtrack = fabtrack.RunTracker(beamtime_id=self.id)
130
131    @property
132    def runs(self):
133        if self.fabtrack is None:
134            raise ValueError("fabtrack is not installed, cannot access runs")
135        return self.fabtrack.table()
136
137    def __repr__(self):
138        return f"Beamtime {self.id} at {self.basepath}"
139
140    def _ipython_display_(self):
141        display(self.fabtrack)

Represents a beamtime at the FLASH facility

Properties:

id: The beamtime number basepath: The basepath of the beamtime fabtrack: The fabtrack tracker of the beamtime, if fabtrack is installed runs: The run table of the beamtime as a pandas DataFrame, if fabtrack is installed

Beamtime(beamtime_num)
120    def __init__(self, beamtime_num):
121        self.id = beamtime_num
122        try:
123            self.basepath = beamtime_basepath(beamtime_num)
124        except IndexError as e:
125            self.basepath = "/asap3/flash/gpfs/" #placeholder
126
127        self.fabtrack = None
128        if fabtrack is not None:
129            self.fabtrack = fabtrack.RunTracker(beamtime_id=self.id)
id
fabtrack
runs
131    @property
132    def runs(self):
133        if self.fabtrack is None:
134            raise ValueError("fabtrack is not installed, cannot access runs")
135        return self.fabtrack.table()