-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcommon.py
124 lines (100 loc) · 4.33 KB
/
common.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import glob
import os.path as op
from functools import lru_cache
import numpy as np
import h5py
from constants import ADU_PER_PHOTON, MODULE_SHAPE, PREFIX, GAIN_FNAME
@lru_cache(maxsize=1000)
def get_relevant_dark_run(run_num):
'''Get dark run corresponding to given data run
Currently returning the latest processed dark run before the given run
'''
dark_files = sorted(glob.glob(PREFIX + 'dark/r????_dark.h5'))
dark_runs = np.array([int(op.splitext(op.basename(fname))[0][1:5]) for fname in dark_files])
# Get nearest dark run *before* given run
return dark_runs[dark_runs < run_num][-1]
def calibrate(raw, offset, output=None):
'''Calibrate raw data given offsets to photon counts
Can calibrate individual module or whole detector
If output is specified, that array will be updated
'''
assert raw.shape == offset.shape, (raw.shape, offset.shape)
if raw.shape == MODULE_SHAPE:
return _calibrate_module(raw, offset, output=output)
elif raw.shape == (16,) + MODULE_SHAPE:
if output is not None:
[_calibrate_module(raw[i], offset[i], output=output[i]) for i in range(16)]
return output
else:
return np.array([_calibrate_module(raw[i], offset[i]) for i in range(16)])
else:
raise ValueError('Unknown data shape: %s' % (raw.shape))
def _calibrate_module(raw, offset, output=None):
if output is not None:
output[:] = raw - offset
else:
output = raw - offset
# ASIC-wide common mode correction
output[:] = (output.reshape(128, 2, 256) - np.median(output.reshape(128, 2, 256), axis=(0,2), keepdims=True)).reshape(MODULE_SHAPE)
# Photon conversion with 0.7-photon threshold
output[:] = np.rint(output/ADU_PER_PHOTON - 0.2)
output[output < 0] = 0
return output
def calibrate2(raw, offset, thresh, output=None):
'''Calibrate raw data to photon counts, give offsets and pixel-wise thresholds
Can calibrate individual module or whole detector
If output is specified, that array will be updated
'''
assert raw.shape == offset.shape, (raw.shape, offset.shape)
assert raw.shape == thresh.shape
if raw.shape == MODULE_SHAPE:
return _calibrate_module(raw, offset, output=output)
elif raw.shape == (16,) + MODULE_SHAPE:
if output is not None:
[_calibrate_module2(raw[i], offset[i], thresh[i], output=output[i]) for i in range(16)]
return output
else:
return np.array([_calibrate_module2(raw[i], offset[i], thresh[i]) for i in range(16)])
else:
raise ValueError('Unknown data shape: %s' % (raw.shape))
def _calibrate_module2(raw, offset, thresh, output=None):
if output is not None:
output[:] = raw - offset
else:
output = raw - offset
# ASIC-wide common mode correction
output[:] = (output.reshape(128, 2, 256) - np.median(output.reshape(128, 2, 256), axis=(0,2), keepdims=True)).reshape(MODULE_SHAPE)
# Photon conversion with 0.7-photon threshold
output[:] = np.floor(output/ADU_PER_PHOTON - thresh)
output[output < 0] = 0
return output
@lru_cache(maxsize=2)
def _get_dark_data(dark_run):
with h5py.File(PREFIX + 'dark/r%.4d_dark.h5' % dark_run, 'r') as f:
offset = f['data/mean'][:]
noise = f['data/sigma'][:]
return offset, noise
@lru_cache(maxsize=1)
def _get_gain(gain_fname):
return np.load(gain_fname)
def _calibrate_module3(raw, offset, noise, output=None):
if output is not None:
output[:] = raw - offset
else:
output = raw - offset
relthresh = 0.5 - noise**2/5**2 * (-6.907755)
gain = _get_gain(GAIN_FNAME)[0]
output[:] = np.clip(np.ceil(output/gain - relthresh), 0, np.inf)
return output
def calibrate3(raw, cid, run_num, output=None):
'''Calibrate raw data to photon counts for whole detector
Uses run number and cellId to get relevant constants
If output is specified, that array will be updated
'''
offset, noise = _get_dark_data(get_relevant_dark_run(run_num))
assert raw.shape == offset[:,0].shape, (raw.shape, offset[:,0].shape)
if output is not None:
[_calibrate_module3(raw[m], offset[m,cid], noise[m,cid], output=output[m]) for m in range(16)]
return output
else:
return np.array([_calibrate_module3(raw[m], offset[m,cid], noise[m,cid]) for m in range(16)])