Coverage for /Users/Newville/Codes/xraylarch/larch/io/rixs_esrf_fame.py: 0%

75 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2023-11-09 10:08 -0600

1#!/usr/bin/env python 

2# -*- coding: utf-8 -*- 

3 

4""" 

5RIXS data reader for beamline BM16 @ ESRF 

6========================================= 

7 

8.. note: RIXS stands for Resonant Inelastic X-ray Scattering 

9 

10.. note: BM16 is FAME-UHD, French CRG beamline 

11 

12""" 

13import os 

14import time 

15import numpy as np 

16from larch.io.specfile_reader import DataSourceSpecH5, _mot2array 

17from silx.io.dictdump import dicttoh5 

18from larch.utils.logging import getLogger 

19 

20_logger = getLogger("io_rixs_bm16") 

21 

22 

23def _parse_header(fname): 

24 """Get parsed header for the RIXS_###.log file 

25 Return 

26 ------ 

27 header : dict 

28 """ 

29 with open(fname) as f: 

30 lines = f.read().splitlines() 

31 header_lines = [line[1:] for line in lines if line[0] == "#"] 

32 header = {} 

33 for line in header_lines: 

34 ls = line.split(": ") 

35 try: 

36 k, v = ls[0], ls[1] 

37 except IndexError: 

38 pass 

39 for s in ("START", "END", "STEP"): 

40 if s in k: 

41 v = float(v) 

42 header[k] = v 

43 return header 

44 

45 

46def get_rixs_bm16( 

47 rixs_logfn, 

48 sample_name=None, 

49 out_dir=None, 

50 counter_signal="absF1", 

51 counter_norm=None, 

52 interp_ene_in=True, 

53 save_rixs=False, 

54): 

55 """Build RIXS map as X,Y,Z 1D arrays 

56 Parameters 

57 ---------- 

58 rixs_logfn : str 

59 path to the RIXS_###.log file 

60 sample_name : str, optional ['UNKNOWN_SAMPLE'] 

61 out_dir : str, optional 

62 path to save the data [None -> data_dir] 

63 counter_signal : str 

64 name of the data column to use as signal 

65 counter_norm : str 

66 name of the data column to use as normaliztion 

67 interp_ene_in: bool 

68 perform interpolation ene_in to the energy step of ene_out [True] 

69 save_rixs : bool 

70 if True -> save outdict to disk (in 'out_dir') 

71 Returns 

72 ------- 

73 outdict : dict 

74 { 

75 '_x': array, energy in 

76 '_y': array, energy out 

77 '_z': array, signal 

78 'writer_name': str, 

79 'writer_version': str, 

80 'writer_timestamp': str, 

81 'filename_all' : list, 

82 'filename_root': str, 

83 'name_sample': str, 

84 'name_scan': str, 

85 'counter_all': str, 

86 'counter_signal': str, 

87 'counter_norm': str, 

88 'ene_grid': float, 

89 'ene_unit': str, 

90 } 

91 """ 

92 _writer = "get_rixs_bm16" 

93 _writer_version = "1.5.1" #: used for reading back in RixsData.load_from_h5() 

94 _writer_timestamp = "{0:04d}-{1:02d}-{2:02d}_{3:02d}{4:02d}".format( 

95 *time.localtime() 

96 ) 

97 header = _parse_header(rixs_logfn) 

98 if sample_name is None: 

99 try: 

100 sample_name = header["SAMPLE_NAME"] 

101 except Exception: 

102 sample_name = "UNKNOWN_SAMPLE" 

103 sfn = header["DATAFILE"] 

104 scntype = header["RIXS_SCAN_TYPE"] 

105 data_dir = os.path.join(os.sep, *sfn.split("/")[1:-1]) 

106 if out_dir is None: 

107 out_dir = data_dir 

108 ds = DataSourceSpecH5(sfn) 

109 

110 logobj = np.genfromtxt(rixs_logfn, delimiter=",", comments="#") 

111 scans = logobj[:, 0] # list of scan numers 

112 enes = logobj[:, 1] 

113 

114 _counter = 0 

115 for scan, estep in zip(scans, enes): 

116 scan = int(scan) 

117 try: 

118 ds.set_scan(scan) 

119 escan, sig, lab, attrs = ds.get_curve(counter_signal) 

120 except Exception: 

121 _logger.error(f"cannot load scan {scan}!") 

122 continue 

123 if scntype == "rixs_et": 

124 x = _mot2array(estep, escan) 

125 y = escan 

126 else: 

127 x = escan 

128 y = _mot2array(estep, escan) 

129 if _counter == 0: 

130 xcol = x 

131 ycol = y 

132 zcol = sig 

133 else: 

134 xcol = np.append(xcol, x) 

135 ycol = np.append(ycol, y) 

136 zcol = np.append(zcol, sig) 

137 _counter += 1 

138 _logger.info(f"Loaded scan {scan}: {estep} eV") 

139 

140 outdict = { 

141 "_x": xcol * 1000, #to eV 

142 "_y": ycol * 1000, #to eV 

143 "_z": zcol, 

144 "writer_name": _writer, 

145 "writer_version": _writer_version, 

146 "writer_timestamp": _writer_timestamp, 

147 "counter_signal": counter_signal, 

148 "counter_norm": counter_norm, 

149 "sample_name": sample_name, 

150 "ene_unit": "eV", 

151 "rixs_header": header, 

152 "data_dir": data_dir, 

153 "out_dir": out_dir, 

154 } 

155 

156 if save_rixs: 

157 fnstr = sfn.split("/")[-1].split(".")[0] 

158 fnout = "{0}_rixs.h5".format(fnstr) 

159 dicttoh5(outdict, os.path.join(out_dir, fnout)) 

160 _logger.info("RIXS saved to {0}".format(fnout)) 

161 

162 return outdict 

163 

164 

165if __name__ == "__main__": 

166 pass