Loading pysen/inout/__init__.py +2 −2 Original line number Diff line number Diff line Loading @@ -5,8 +5,8 @@ from .hdf import HdfConverter, convert_to_hdf # NOQA from .reader import ( read_echo, read_magnetic, read_xyz, # NOQA read_detimage, read_datfile, read_diffrun, # NOQA read_datreat , read_transmission ) # NOQA from .writer import EchoWriter, DiffractionWriter # NOQA from .scans import EchoScan, DiffractionScan, XYZScan # NOQA from .writer import EchoWriter, DiffractionWriter, TransmissionWriter # NOQA from .scans import EchoScan, DiffractionScan, TransmissionScan, XYZScan # NOQA from .utils import get_nsefiletype # from .legacy_writer import write_csv, generate_echo # NOQA # from .legacy_history import extract_data, list_variables, parse_date # NOQA pysen/inout/nexus.py +41 −2 Original line number Diff line number Diff line Loading @@ -37,7 +37,7 @@ Y0_PIX = 518 XWID2 = 813//2 # 410 # half-width YWID2 = 821//2 # 410 LTOT_P2 = Ltot.get('p2') LTOT_P2 = Ltot.get('p2') # default value if mo_l not found MOTORS = ('mophi', 'mopsi', 'mo_z', 'moana', 'mo_l', 'moatt') Loading Loading @@ -92,6 +92,8 @@ def get_run_info(nxsfile): res['notes'] = nxsfile['/entry/notes'][0].decode('ascii') res['duration'] = nxsfile['/entry/duration'][0] res['proton_charge'] = nxsfile['/entry/proton_charge'][0] res['ipts'] = nxsfile['/entry/experiment_identifier'][0].decode('ascii') res['experiment'] = nxsfile['/entry/experiment_title'][0].decode('ascii') log.info("%s: %s, duration=%.1f min", base, res['time'], res['duration']/60) log.info("%s: %s %s", base, res['title'], res['notes']) Loading Loading @@ -152,6 +154,20 @@ def get_slice_average(key, val, begin, end=np.inf): return last_val def process_events(events, pcharge, ltot): "process nexus events" res = {} # get the proton charge for the phase res['pcharge'] = np.sum(pcharge[:]['value']) # event_time_offset is in usec lam = tof2lambda(events['event_time_offset'][:]*MICRO, ltot)/ANGSTROM pix = pixel_decompose(events['event_id'][:]) res['lambda'] = lam res['pixel'] = pix res['neutron'] = np.vstack((lam,pix)) return res def process_scan_point(events, pcharge, ltot, begin=None, end=None, values=None): "get data for one phase point" ev_t0 = events['event_time_zero'] Loading Loading @@ -180,12 +196,13 @@ def process_scan_point(events, pcharge, ltot, begin=None, end=None, values=None) res['neutron'] = np.vstack((lam,pix)) return res def _dummy_callback(*_args, **_kwargs): """dummy process scan point (for testing) a caller to process scan should override it""" return True # process scan # process nexus scan def process_nexus_scan(filename, **kwargs): "process nexus file (scan indices)" scan_type = kwargs.pop('scan_type', None) Loading Loading @@ -247,4 +264,26 @@ def process_nexus_scan(filename, **kwargs): i = k k = k + 1 return info # process nexus plain def process_nexus_plain(filename, **kwargs): "process nexus file (scan indices)" scan_type = kwargs.pop('scan_type', None) data = kwargs.pop('data', None) # log = logging.getLogger('nexus') base = os.path.basename(filename) nxsfile = h5py.File(filename, 'r') # get file info info = get_run_info(nxsfile) if scan_type and scan_type not in info.get('notes','').lower(): log.warning('not an %s scan (%s)', scan_type, info['notes']) return None if info['proton_charge']<=0.0: log.warning("%s: empty run (pcharge=%g)", base, info['proton_charge']) return None if data is not None: res = process_events(nxsfile['entry/bank1_events'], timevalue_array(nxsfile, 'proton_charge'), info['mo_l']) data.update(res) return info # EOF pysen/inout/nxs2echo.py +4 −4 Original line number Diff line number Diff line Loading @@ -7,7 +7,7 @@ import os.path import logging import argparse from pysen.inout import EchoWriter, DiffractionWriter, get_nsefiletype from pysen.inout import EchoWriter, DiffractionWriter, TransmissionWriter, get_nsefiletype def main(): "the main" Loading @@ -29,7 +29,6 @@ def main(): const=logging.WARNING, help='suppress info messages') args = parser.parse_args() logging.basicConfig(format='%(levelname)s %(message)s', level=args.loglevel) log = logging.getLogger() Loading @@ -40,6 +39,7 @@ def main(): file_type = get_nsefiletype(file_name) writer_class = { 'application/nexus-nse-echo' : EchoWriter, 'application/nexus-diffraction' : DiffractionWriter, 'application/nexus-transmission' : TransmissionWriter, }.get(file_type, None) if not isinstance(writer_class, type): log.warning("file '%s' unknown file type %s", file_name, file_type) Loading pysen/inout/scans.py +4 −10 Original line number Diff line number Diff line Loading @@ -8,7 +8,7 @@ import logging import numpy as np from ..config import NXCHAN as NPIX, NTCHAN as NTOF from .nexus import process_nexus_scan, print_nexus_info, X0_PIX, Y0_PIX, XWID2, YWID2 from .nexus import process_nexus_scan, process_nexus_plain, print_nexus_info, X0_PIX, Y0_PIX, XWID2, YWID2 # BUNCH OF HARD CODED CONSTANTS Loading Loading @@ -61,14 +61,9 @@ class BaseScan: self.log.debug("nexus info: %s", print_nexus_info(self.info)) return True class TransmissionScan: class TransmissionScan(BaseScan): """Read SNS-NSE EPICS/NeXus transmission scan file """ def __init__(self): "the constructor" self.log = logging.getLogger() self.data = {} self.info = None def read_nexus(self, nxsfile, **kwargs): """read nexus file""" Loading @@ -76,10 +71,9 @@ class TransmissionScan: # kwargs.setdefault('npix', NPIX) kwargs.setdefault('ntof', NTOF) scan_type = kwargs.setdefault('scan_type', None) kwargs.setdefault('scan_type', None) # self.info = process_nexus_scan(nxsfile, scanpoint_cb=self.phasepoint_callback, scan_type=scan_type) self.info = process_nexus_plain(nxsfile, data=self.data) if self.info is None: return False self.info.update(**kwargs) Loading pysen/inout/writer.py +53 −1 Original line number Diff line number Diff line Loading @@ -13,7 +13,7 @@ from ..config import ( XDET, YDET, DEFAULT_PROTON_ENERGY as PROTON_ENERGY, PROTON_CHARGE_UNIT, get_attenuator_pos) from ..constants import PICO, NANO, MICRO, ANGSTROM, GAUSS from .nexus import MOTORS, B_SENSORS from .scans import EchoScan, DiffractionScan from .scans import EchoScan, DiffractionScan, TransmissionScan # BUNCH OF HARD CODED CONSTANTS # TO DO: some of this is repeated in nexus.py file (merge!) Loading @@ -33,6 +33,58 @@ def get_phase_index(scan_index, offset=0): class TransmissionWriter(TransmissionScan): "Convert EPICS/ADARA/NeXus file to transmission .dat file" @staticmethod def make_filename(base): "make diffraction filename" root, _ = os.path.splitext(os.path.basename(base)) # remove h5 root, _ = os.path.splitext(root) # remove nxs numor = int(root.split('_')[-1]) return f"transmission_{numor}.dat" def save(self, outdir='.'): "convert read nexus file to diffrun .dat file" transmission_run = self.make_filename(self.info['base']) with open(os.path.join(outdir, transmission_run), 'wt', encoding='ascii') as fd: # self.log.info("%s: creating transmission .dat file", transmission_run) lmax = self.info.get('lmax', 8.0)*ANGSTROM ipts = self.info.get('ipts',' ').lower().replace('ipts-','') fd.write(f"\n\"Transmission for IPTS \" {ipts}") fd.write(f" \", sample \" {self.info.get('title','')}") fd.write(f" \", wavelength \" {lmax} \n") # detector data res = self.data #qmin = res.get('qmin') pcharge = res['pcharge']*PICO/PROTON_CHARGE_UNIT # convert to echo units neutrons = res['neutron'] xbin = self.info['xbin'] ybin = self.info['ybin'] tbin = self.info['tbin'] h3,_ = np.histogramdd((neutrons[0], neutrons[1], neutrons[2]), bins=(tbin, ybin, xbin)) detsum = neutrons.shape[-1] tofdet = h3.sum(axis=(1,2)) fd.write( "\"detector.sum anode strobe mon1 mon2 proton_charge det.sum/proton_charge\"\n") fd.write(f"{detsum} {detsum} {detsum} 0 0 {pcharge:.0f} {detsum/pcharge}\n") fd.write( "\n\"detector array\"\n") fd.write("\n".join([f"{val:.0f}" for val in tofdet])) fd.write( "\n\"mon1 array\"\n") fd.write("\n".join(["0" for _ in tofdet])) fd.write( "\n\"mon2 array\"\n") fd.write("\n".join(["0" for _ in tofdet])) fd.write( "\n") # #fd.write(f"\"Det sum/proton charge\" {detsum/pcharge:g} ") #fd.write(f"\"Det win/proton charge\" {detwin/pcharge:g} ") #fd.write( "\n") self.log.info("%s: done", transmission_run) return transmission_run class DiffractionWriter(DiffractionScan): "Convert EPICS/ADARA/NeXus file to diffrun .dat file" Loading Loading
pysen/inout/__init__.py +2 −2 Original line number Diff line number Diff line Loading @@ -5,8 +5,8 @@ from .hdf import HdfConverter, convert_to_hdf # NOQA from .reader import ( read_echo, read_magnetic, read_xyz, # NOQA read_detimage, read_datfile, read_diffrun, # NOQA read_datreat , read_transmission ) # NOQA from .writer import EchoWriter, DiffractionWriter # NOQA from .scans import EchoScan, DiffractionScan, XYZScan # NOQA from .writer import EchoWriter, DiffractionWriter, TransmissionWriter # NOQA from .scans import EchoScan, DiffractionScan, TransmissionScan, XYZScan # NOQA from .utils import get_nsefiletype # from .legacy_writer import write_csv, generate_echo # NOQA # from .legacy_history import extract_data, list_variables, parse_date # NOQA
pysen/inout/nexus.py +41 −2 Original line number Diff line number Diff line Loading @@ -37,7 +37,7 @@ Y0_PIX = 518 XWID2 = 813//2 # 410 # half-width YWID2 = 821//2 # 410 LTOT_P2 = Ltot.get('p2') LTOT_P2 = Ltot.get('p2') # default value if mo_l not found MOTORS = ('mophi', 'mopsi', 'mo_z', 'moana', 'mo_l', 'moatt') Loading Loading @@ -92,6 +92,8 @@ def get_run_info(nxsfile): res['notes'] = nxsfile['/entry/notes'][0].decode('ascii') res['duration'] = nxsfile['/entry/duration'][0] res['proton_charge'] = nxsfile['/entry/proton_charge'][0] res['ipts'] = nxsfile['/entry/experiment_identifier'][0].decode('ascii') res['experiment'] = nxsfile['/entry/experiment_title'][0].decode('ascii') log.info("%s: %s, duration=%.1f min", base, res['time'], res['duration']/60) log.info("%s: %s %s", base, res['title'], res['notes']) Loading Loading @@ -152,6 +154,20 @@ def get_slice_average(key, val, begin, end=np.inf): return last_val def process_events(events, pcharge, ltot): "process nexus events" res = {} # get the proton charge for the phase res['pcharge'] = np.sum(pcharge[:]['value']) # event_time_offset is in usec lam = tof2lambda(events['event_time_offset'][:]*MICRO, ltot)/ANGSTROM pix = pixel_decompose(events['event_id'][:]) res['lambda'] = lam res['pixel'] = pix res['neutron'] = np.vstack((lam,pix)) return res def process_scan_point(events, pcharge, ltot, begin=None, end=None, values=None): "get data for one phase point" ev_t0 = events['event_time_zero'] Loading Loading @@ -180,12 +196,13 @@ def process_scan_point(events, pcharge, ltot, begin=None, end=None, values=None) res['neutron'] = np.vstack((lam,pix)) return res def _dummy_callback(*_args, **_kwargs): """dummy process scan point (for testing) a caller to process scan should override it""" return True # process scan # process nexus scan def process_nexus_scan(filename, **kwargs): "process nexus file (scan indices)" scan_type = kwargs.pop('scan_type', None) Loading Loading @@ -247,4 +264,26 @@ def process_nexus_scan(filename, **kwargs): i = k k = k + 1 return info # process nexus plain def process_nexus_plain(filename, **kwargs): "process nexus file (scan indices)" scan_type = kwargs.pop('scan_type', None) data = kwargs.pop('data', None) # log = logging.getLogger('nexus') base = os.path.basename(filename) nxsfile = h5py.File(filename, 'r') # get file info info = get_run_info(nxsfile) if scan_type and scan_type not in info.get('notes','').lower(): log.warning('not an %s scan (%s)', scan_type, info['notes']) return None if info['proton_charge']<=0.0: log.warning("%s: empty run (pcharge=%g)", base, info['proton_charge']) return None if data is not None: res = process_events(nxsfile['entry/bank1_events'], timevalue_array(nxsfile, 'proton_charge'), info['mo_l']) data.update(res) return info # EOF
pysen/inout/nxs2echo.py +4 −4 Original line number Diff line number Diff line Loading @@ -7,7 +7,7 @@ import os.path import logging import argparse from pysen.inout import EchoWriter, DiffractionWriter, get_nsefiletype from pysen.inout import EchoWriter, DiffractionWriter, TransmissionWriter, get_nsefiletype def main(): "the main" Loading @@ -29,7 +29,6 @@ def main(): const=logging.WARNING, help='suppress info messages') args = parser.parse_args() logging.basicConfig(format='%(levelname)s %(message)s', level=args.loglevel) log = logging.getLogger() Loading @@ -40,6 +39,7 @@ def main(): file_type = get_nsefiletype(file_name) writer_class = { 'application/nexus-nse-echo' : EchoWriter, 'application/nexus-diffraction' : DiffractionWriter, 'application/nexus-transmission' : TransmissionWriter, }.get(file_type, None) if not isinstance(writer_class, type): log.warning("file '%s' unknown file type %s", file_name, file_type) Loading
pysen/inout/scans.py +4 −10 Original line number Diff line number Diff line Loading @@ -8,7 +8,7 @@ import logging import numpy as np from ..config import NXCHAN as NPIX, NTCHAN as NTOF from .nexus import process_nexus_scan, print_nexus_info, X0_PIX, Y0_PIX, XWID2, YWID2 from .nexus import process_nexus_scan, process_nexus_plain, print_nexus_info, X0_PIX, Y0_PIX, XWID2, YWID2 # BUNCH OF HARD CODED CONSTANTS Loading Loading @@ -61,14 +61,9 @@ class BaseScan: self.log.debug("nexus info: %s", print_nexus_info(self.info)) return True class TransmissionScan: class TransmissionScan(BaseScan): """Read SNS-NSE EPICS/NeXus transmission scan file """ def __init__(self): "the constructor" self.log = logging.getLogger() self.data = {} self.info = None def read_nexus(self, nxsfile, **kwargs): """read nexus file""" Loading @@ -76,10 +71,9 @@ class TransmissionScan: # kwargs.setdefault('npix', NPIX) kwargs.setdefault('ntof', NTOF) scan_type = kwargs.setdefault('scan_type', None) kwargs.setdefault('scan_type', None) # self.info = process_nexus_scan(nxsfile, scanpoint_cb=self.phasepoint_callback, scan_type=scan_type) self.info = process_nexus_plain(nxsfile, data=self.data) if self.info is None: return False self.info.update(**kwargs) Loading
pysen/inout/writer.py +53 −1 Original line number Diff line number Diff line Loading @@ -13,7 +13,7 @@ from ..config import ( XDET, YDET, DEFAULT_PROTON_ENERGY as PROTON_ENERGY, PROTON_CHARGE_UNIT, get_attenuator_pos) from ..constants import PICO, NANO, MICRO, ANGSTROM, GAUSS from .nexus import MOTORS, B_SENSORS from .scans import EchoScan, DiffractionScan from .scans import EchoScan, DiffractionScan, TransmissionScan # BUNCH OF HARD CODED CONSTANTS # TO DO: some of this is repeated in nexus.py file (merge!) Loading @@ -33,6 +33,58 @@ def get_phase_index(scan_index, offset=0): class TransmissionWriter(TransmissionScan): "Convert EPICS/ADARA/NeXus file to transmission .dat file" @staticmethod def make_filename(base): "make diffraction filename" root, _ = os.path.splitext(os.path.basename(base)) # remove h5 root, _ = os.path.splitext(root) # remove nxs numor = int(root.split('_')[-1]) return f"transmission_{numor}.dat" def save(self, outdir='.'): "convert read nexus file to diffrun .dat file" transmission_run = self.make_filename(self.info['base']) with open(os.path.join(outdir, transmission_run), 'wt', encoding='ascii') as fd: # self.log.info("%s: creating transmission .dat file", transmission_run) lmax = self.info.get('lmax', 8.0)*ANGSTROM ipts = self.info.get('ipts',' ').lower().replace('ipts-','') fd.write(f"\n\"Transmission for IPTS \" {ipts}") fd.write(f" \", sample \" {self.info.get('title','')}") fd.write(f" \", wavelength \" {lmax} \n") # detector data res = self.data #qmin = res.get('qmin') pcharge = res['pcharge']*PICO/PROTON_CHARGE_UNIT # convert to echo units neutrons = res['neutron'] xbin = self.info['xbin'] ybin = self.info['ybin'] tbin = self.info['tbin'] h3,_ = np.histogramdd((neutrons[0], neutrons[1], neutrons[2]), bins=(tbin, ybin, xbin)) detsum = neutrons.shape[-1] tofdet = h3.sum(axis=(1,2)) fd.write( "\"detector.sum anode strobe mon1 mon2 proton_charge det.sum/proton_charge\"\n") fd.write(f"{detsum} {detsum} {detsum} 0 0 {pcharge:.0f} {detsum/pcharge}\n") fd.write( "\n\"detector array\"\n") fd.write("\n".join([f"{val:.0f}" for val in tofdet])) fd.write( "\n\"mon1 array\"\n") fd.write("\n".join(["0" for _ in tofdet])) fd.write( "\n\"mon2 array\"\n") fd.write("\n".join(["0" for _ in tofdet])) fd.write( "\n") # #fd.write(f"\"Det sum/proton charge\" {detsum/pcharge:g} ") #fd.write(f"\"Det win/proton charge\" {detwin/pcharge:g} ") #fd.write( "\n") self.log.info("%s: done", transmission_run) return transmission_run class DiffractionWriter(DiffractionScan): "Convert EPICS/ADARA/NeXus file to diffrun .dat file" Loading