Skip to content

Commit

Permalink
Add get_spectrum to FormatXTC (#484)
Browse files Browse the repository at this point in the history
Supports older and newer spectrometer formats

Also adds delta_k, an older correction parameter needed for legacy XFEL data
  • Loading branch information
phyy-nx authored Feb 23, 2022
1 parent a7e2404 commit 8d9a462
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 14 deletions.
1 change: 1 addition & 0 deletions newsfragments/484.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add get_spectrum to FormatXTC
54 changes: 40 additions & 14 deletions src/dxtbx/format/FormatXTC.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@

import numpy as np

from cctbx import factor_ev_angstrom
from libtbx.phil import parse

from scitbx.array_family import flex
from dxtbx import IncorrectFormatError
from dxtbx.format.Format import Format, abstract
from dxtbx.format.FormatMultiImage import Reader
from dxtbx.format.FormatMultiImageLazy import FormatMultiImageLazy
from dxtbx.format.FormatStill import FormatStill
from dxtbx.model import Spectrum

try:
import psana
Expand Down Expand Up @@ -48,9 +49,15 @@
use_ffb = False
.type = bool
.help = Run on the ffb if possible. Only for active users!
wavelength_delta_k = None
.type = float
.help = Correction factor, needed during 2014
wavelength_offset = None
.type = float
.help = Optional constant shift to apply to each wavelength
spectrum_address = FEE-SPEC0
.type = str
.help = Address for incident beam spectrometer
spectrum_eV_per_pixel = None
.type = float
.help = If not None, use the FEE spectrometer to determine the wavelength. \
Expand Down Expand Up @@ -265,20 +272,13 @@ def _beam(self, index=None):
if self._beam_index != index:
self._beam_index = index
evt = self._get_event(index)
if self.params.spectrum_eV_per_pixel is not None:
if self._fee is None:
self._fee = psana.Detector("FEE-SPEC0")
fee = self._fee.get(evt)
if fee is None:
wavelength = cspad_tbx.evt_wavelength(evt)
else:
x = (
self.params.spectrum_eV_per_pixel
* np.array(range(len(fee.hproj())))
) + self.params.spectrum_eV_offset
wavelength = factor_ev_angstrom / np.average(x, weights=fee.hproj())
spectrum = self.get_spectrum(index)
if spectrum:
wavelength = spectrum.get_weighted_wavelength()
else:
wavelength = cspad_tbx.evt_wavelength(evt)
wavelength = cspad_tbx.evt_wavelength(
evt, delta_k=self.params.wavelength_delta_k
)
if wavelength is None:
self._beam_cache = None
else:
Expand All @@ -295,6 +295,32 @@ def _beam(self, index=None):

return self._beam_cache

def get_spectrum(self, index=None):
if index is None:
index = 0
if self.params.spectrum_eV_per_pixel is None:
return None

evt = self._get_event(index)
if self._fee is None:
self._fee = psana.Detector(self.params.spectrum_address)
if self._fee is None:
return None
try:
fee = self._fee.get(evt)
y = fee.hproj()
except AttributeError: # Handle older spectometers without the hproj method
img = self._fee.image(evt)
x = (
self.params.spectrum_eV_per_pixel * np.array(range(img.shape[1]))
) + self.params.spectrum_eV_offset
y = img.mean(axis=0) # Collapse 2D image to 1D trace
else:
x = (
self.params.spectrum_eV_per_pixel * np.array(range(len(y)))
) + self.params.spectrum_eV_offset
return Spectrum(flex.double(x), flex.double(y))

def get_goniometer(self, index=None):
return None

Expand Down

0 comments on commit 8d9a462

Please sign in to comment.