Skip to content
This repository has been archived by the owner on Apr 19, 2024. It is now read-only.

Need to append extra info in sample/file name #428

Closed
jilavsky opened this issue Nov 18, 2020 · 9 comments · Fixed by #440
Closed

Need to append extra info in sample/file name #428

jilavsky opened this issue Nov 18, 2020 · 9 comments · Fixed by #440
Assignees
Labels
enhancement New feature or request

Comments

@jilavsky
Copy link
Contributor

We will need to append some information in the sample name. In this case, for example, sx or sy value. Before each run of a sample.
We will mount sample "Sample1" and append to it specific sx position where data will be collected.
We need to be able to change this code on fly, in spec it is done by redefining the function which does the work.

@jilavsky jilavsky added the enhancement New feature or request label Nov 18, 2020
@jilavsky jilavsky added this to the 2020-11 operations milestone Nov 18, 2020
@prjemian
Copy link
Contributor

I suggest we define a standard function to modify the sample title, with default of nothing. The user can replace the standard definition from a local %run -i localfile.py and the replacement will be used.

This is wanted for data collection next week.

@prjemian
Copy link
Contributor

Will also need a reset_to_default capability. The local file will define a local function, then configure the standard handler to call it. Looks like:

from instrument.devices import sample_title_handler
from instrument.devices import temperature_signal

def mySampleTitle(user_sample_name):
    title = user_sample_name  # the default setting
    # title = f"{user_sample_name}_{temperature_signal.get()}"
    return title

# register OUR function as the sample title function now
sample_title_handler.register(mySampleTitle)

# Use default handler as the sample title function now
# sample_title_handler.register()

@prjemian
Copy link
Contributor

prjemian commented Nov 18, 2020

sample_name usage:

bash-4.2$ git grep sample_name | cat
examples/actions.txt:# action  sx  sy  thickness   sample_name
examples/custom_loop.md:def _measure_all_three(sx, sy, thickness, sample_name, md={}):
examples/custom_loop.md:    yield from FlyScan(sx, sy, thickness, sample_name, md=md)
examples/custom_loop.md:    yield from SAXS(sx, sy, thickness, sample_name, md=md)
examples/custom_loop.md:    yield from WAXS(sx, sy, thickness, sample_name, md=md)
examples/custom_loop.md:def my_custom_plan(sx, sy, thickness, sample_name, temperature, iterations=9, md={}):
examples/custom_loop.md:    yield from _measure_all_three(sx, sy, thickness, sample_name, md=md)
examples/custom_loop.md:        yield from _measure_all_three(sx, sy, thickness, sample_name, md=md)
examples/use_linkam.md:def my_temperature_sequence(sx, sy, thickness, sample_name, t_start, t_end, t_step, md={}):
examples/use_linkam.md:        yield from FlyScan(sx, sy, thickness, sample_name, md=md)
examples/use_linkam.md:        yield from SAXS(sx, sy, thickness, sample_name, md=md)
examples/use_linkam.md:        yield from WAXS(sx, sy, thickness, sample_name, md=md)

broader search ...

bash-4.2$ git grep -i sample | grep -i name | grep -v xml 
examples/actions.txt:# action  sx  sy  thickness   sample_name
examples/command_file.md:the scan/action.  The sample name should be given in "quoted text" 
examples/custom_loop.md:def _measure_all_three(sx, sy, thickness, sample_name, md={}):
examples/custom_loop.md:    yield from FlyScan(sx, sy, thickness, sample_name, md=md)
examples/custom_loop.md:    yield from SAXS(sx, sy, thickness, sample_name, md=md)
examples/custom_loop.md:    yield from WAXS(sx, sy, thickness, sample_name, md=md)
examples/custom_loop.md:def my_custom_plan(sx, sy, thickness, sample_name, temperature, iterations=9, md={}):
examples/custom_loop.md:    yield from _measure_all_three(sx, sy, thickness, sample_name, md=md)
examples/custom_loop.md:        yield from _measure_all_three(sx, sy, thickness, sample_name, md=md)
examples/use_linkam.md:def my_temperature_sequence(sx, sy, thickness, sample_name, t_start, t_end, t_step, md={}):
examples/use_linkam.md:        yield from FlyScan(sx, sy, thickness, sample_name, md=md)
examples/use_linkam.md:        yield from SAXS(sx, sy, thickness, sample_name, md=md)
examples/use_linkam.md:        yield from WAXS(sx, sy, thickness, sample_name, md=md)
profile_bluesky/startup/instrument/callbacks/nxwriter_usaxs.py:        nxentry["sample/name"] = self.get_sample_title()
profile_bluesky/startup/instrument/devices/blackfly.py:    name="_flag_save_sample_image_jpeg_",
profile_bluesky/startup/instrument/devices/sample_data.py:sample_data = SampleDataDevice(name="sample_data")
profile_bluesky/startup/instrument/devices/sample_rotator.py:pi_c867 = SampleRotator("9idcPI:c867:c0:m1", name="pi_c867")
profile_bluesky/startup/instrument/devices/stages.py:s_stage    = UsaxsSampleStageDevice('', name='s_stage')
profile_bluesky/startup/instrument/plans/command_list.py:        [4] scan    sx  sy  thickness   sample name
profile_bluesky/startup/instrument/plans/command_list.py:        # action  sx  sy  thickness   sample name
profile_bluesky/startup/instrument/plans/command_list.py:        # action  sx  sy  thickness   sample name
profile_bluesky/startup/instrument/plans/sample_imaging.py:def record_sample_image_on_demand(technique_name, title, _md):
profile_bluesky/startup/instrument/plans/sample_imaging.py:            _md["sample_image_jpeg"] = jpeg_name
user/linkam.py:    def setSampleName():
user/linkam.py:        sampleMod = setSampleName()
user/linkam.py:            sampleMod = setSampleName()
user/linkam.py:            sampleMod = setSampleName()

@prjemian
Copy link
Contributor

Also check for scan_title usage:

bash-4.2$ git grep scan_title | cat
profile_bluesky/startup/instrument/plans/scans.py:def USAXSscanStep(pos_X, pos_Y, thickness, scan_title, md=None):
profile_bluesky/startup/instrument/plans/scans.py:    _md["title"] = scan_title
profile_bluesky/startup/instrument/plans/scans.py:    scan_title_clean = cleanupText(scan_title)
profile_bluesky/startup/instrument/plans/scans.py:        user_data.sample_title, scan_title,
profile_bluesky/startup/instrument/plans/scans.py:        scan_title = scan_title,
profile_bluesky/startup/instrument/plans/scans.py:    yield from record_sample_image_on_demand("usaxs", scan_title_clean, _md)
profile_bluesky/startup/instrument/plans/scans.py:def Flyscan(pos_X, pos_Y, thickness, scan_title, md=None):
profile_bluesky/startup/instrument/plans/scans.py:    _md["title"] = scan_title
profile_bluesky/startup/instrument/plans/scans.py:    scan_title_clean = cleanupText(scan_title)
profile_bluesky/startup/instrument/plans/scans.py:        f"{scan_title_clean}"
profile_bluesky/startup/instrument/plans/scans.py:        user_data.sample_title, scan_title,
profile_bluesky/startup/instrument/plans/scans.py:        scan_title = scan_title,
profile_bluesky/startup/instrument/plans/scans.py:    yield from record_sample_image_on_demand("usaxs", scan_title_clean, _md)
profile_bluesky/startup/instrument/plans/scans.py:def SAXS(pos_X, pos_Y, thickness, scan_title, md=None):
profile_bluesky/startup/instrument/plans/scans.py:    _md["title"] = scan_title
profile_bluesky/startup/instrument/plans/scans.py:    scan_title_clean = cleanupText(scan_title)
profile_bluesky/startup/instrument/plans/scans.py:    SAXS_file_name = local_file_template % (scan_title_clean, saxs_det.hdf1.file_number.get())
profile_bluesky/startup/instrument/plans/scans.py:        saxs_det.hdf1.file_name, scan_title_clean,
profile_bluesky/startup/instrument/plans/scans.py:        user_data.sample_title, scan_title,
profile_bluesky/startup/instrument/plans/scans.py:    yield from record_sample_image_on_demand("saxs", scan_title_clean, _md)
profile_bluesky/startup/instrument/plans/scans.py:def WAXS(pos_X, pos_Y, thickness, scan_title, md=None):
profile_bluesky/startup/instrument/plans/scans.py:    _md["title"] = scan_title
profile_bluesky/startup/instrument/plans/scans.py:    scan_title_clean = cleanupText(scan_title)
profile_bluesky/startup/instrument/plans/scans.py:    WAXS_file_name = local_file_template % (scan_title_clean, waxs_det.hdf1.file_number.get())
profile_bluesky/startup/instrument/plans/scans.py:        waxs_det.hdf1.file_name, scan_title_clean,
profile_bluesky/startup/instrument/plans/scans.py:        user_data.sample_title, scan_title,
profile_bluesky/startup/instrument/plans/scans.py:    yield from record_sample_image_on_demand("waxs", scan_title_clean, _md)
user/linkam.py:def myLinkamPlan(pos_X, pos_Y, thickness, scan_title, temp1, rate1, delay1, temp2, rate2, md={}):
user/linkam.py:        return f"{scan_title}_{linkam.value:.0f}C_{(time.time()-t0)/60:.0f}min" 

@prjemian
Copy link
Contributor

Note there exists a user_data sample_title object:

bash-4.2$ git grep sample_title
profile_bluesky/startup/instrument/callbacks/nxwriter_usaxs.py:        nxentry["sample/name"] = self.get_sample_title()
profile_bluesky/startup/instrument/callbacks/nxwriter_usaxs.py:    def get_sample_title(self):
profile_bluesky/startup/instrument/callbacks/nxwriter_usaxs.py:        return self.get_stream_link("user_data_sample_title")
profile_bluesky/startup/instrument/callbacks/nxwriter_usaxs.py:                f"{cleanupText(user_data.sample_title.get())}"
profile_bluesky/startup/instrument/devices/user_data.py:    sample_title = Component(EpicsSignal,       "9idcLAX:sampleTitle", string=True)
profile_bluesky/startup/instrument/plans/scans.py:        user_data.sample_title, scan_title,
profile_bluesky/startup/instrument/plans/scans.py:        user_data.sample_title, scan_title,
profile_bluesky/startup/instrument/plans/scans.py:        user_data.sample_title, scan_title,
profile_bluesky/startup/instrument/plans/scans.py:        user_data.sample_title, scan_title,
profile_bluesky/startup/instrument/plans/tune_guard_slits.py:        user_data.sample_title, title,

@prjemian
Copy link
Contributor

The sampleTitle PV is a waveform string of 256 characters:

bash-4.2$ caget 9idcLAX:sampleTitle.RTYP
9idcLAX:sampleTitle.RTYP       waveform
bash-4.2$ caget 9idcLAX:sampleTitle.FTVL
9idcLAX:sampleTitle.FTVL       CHAR
bash-4.2$ caget 9idcLAX:sampleTitle.NORD
9idcLAX:sampleTitle.NORD       20
bash-4.2$ caget 9idcLAX:sampleTitle.NELM
9idcLAX:sampleTitle.NELM       256
bash-4.2$ caget -S 9idcLAX:sampleTitle.VAL
9idcLAX:sampleTitle.VAL AirBlank
``

prjemian added a commit that referenced this issue Nov 18, 2020
@prjemian
Copy link
Contributor

Let's head in a different direction than commit 4a98c67. Instead, create a custom EpicsSignal for the user_data.sample_title signal and override the .set() method to include the custom handler function.

This way, the .get() method will always retrieve whatever value is in the EPICS PV, the .set() method will customize the PV, based on how the user has described.

@prjemian
Copy link
Contributor

@jilavsky : Here's how it will work:

  • user_data.sample_title will be a special EpicsSampleNameDevice (instead of a simpler `EpicsSignal``)
  • user will program a handler function to modify the title supplied in the command file
  • user must register this function to be used
  • result of that handler will be written to the PV (user function does not have to do this)
  • default handler will not modify the title supplied in the command file

Example

In [8]: def handler(title):
   ...:     return f"USAXS sample: {title}"
   ...: 

In [9]: handler("test")
Out[9]: 'USAXS sample: test'

In [10]: sample_title.set("Glassy Carbon")
I Mon-13:59:35 - self._handler: None
Out[10]: Status(obj=EpicsSampleNameDevice(read_pv='sky:UPTIME.DESC', name='sample_title', value='Air Blank', timestamp=1606161523.630438, auto_monitor=True, string=True, write_pv='sky:UPTIME.DESC', limits=False, put_complete=False), done=False, success=False)

In [11]: sample_title.get()
Out[11]: 'Glassy Carbon'

In [12]: sample_title.register_handler(handler)
D Mon-13:59:52 - Accepted Sample name handler function: handler

In [13]: sample_title.set("AF1410 steel")
I Mon-14:00:12 - self._handler: <function handler at 0x7f9bf53fe280>
Out[13]: Status(obj=EpicsSampleNameDevice(read_pv='sky:UPTIME.DESC', name='sample_title', value='USAXS sample: AF1410 steel', timestamp=1606161611.63044, auto_monitor=True, string=True, write_pv='sky:UPTIME.DESC', limits=False, put_complete=False), done=False, success=False)

In [14]: sample_title.register_handler(handler)
D Mon-14:00:14 - Accepted Sample name handler function: handler

In [15]: sample_title.get()
Out[15]: 'USAXS sample: AF1410 steel'

@prjemian
Copy link
Contributor

The user would write this function in a local file and load it via %run -i ./local_file.py (for example).

# for free to subscribe to this conversation on GitHub. Already have an account? #.