Coverage for src/km3dq_common/detector_status_library.py: 0%

83 statements  

« prev     ^ index     » next       coverage.py v7.9.1, created at 2025-06-16 14:13 +0000

1#!/usr/bin/env python3 

2import sys 

3import re 

4import datetime 

5import pandas 

6import tomli 

7import urllib.request 

8 

9from .common_library import get_run_properties_from_db 

10 

11 

12############################################################################### 

13def date_to_datetime(d): 

14 """ 

15 Convert a date-string "yyyy-mm-dd hh:mm" into a datetime 

16 """ 

17 re_time = re.compile(r"(\d\d\d\d)-(\d\d)-(\d\d)\s(\d\d):(\d\d)") 

18 

19 spl_time = re_time.match(d) 

20 if spl_time: 

21 output = datetime.datetime(int(spl_time.group(1)), 

22 int(spl_time.group(2)), 

23 int(spl_time.group(3)), 

24 int(spl_time.group(4)), 

25 int(spl_time.group(5))) 

26 else: 

27 print(f"Wrong datetime format {d}") 

28 sys.exit() 

29 

30 return output 

31 

32 

33############################################################################### 

34def get_det_run_timerange(site, dq_tag="operation"): 

35 """ 

36 Return all the start/end of time/run for all detectors of a site 

37 Data read from the lw_db/Common sftp area 

38 This script is mainly used: 

39 - to bypass the request to KM3DB that can be problematic for nicegui website 

40 - to define the extended ranges for the operation plots 

41  

42 NB: this can be tag dependant when an analysis tag does not contain the 

43 whole detector 

44 """ 

45 

46 tr = {} 

47 

48 tr["Any"] = {"det_start": "", 

49 "first_run": 0} 

50 

51 with urllib.request.urlopen(f"https://sftp.km3net.de/data/km3dq_lw_db/{site}/detector_status_config.toml") as s_f: 

52 toml = tomli.loads(s_f.read().decode("utf-8")) 

53 

54 for i_det in toml.keys(): 

55 # det_start: detector start - A priori equal to the previous-detector end 

56 # This is the only mandatory characteristics 

57 tr[i_det] = {"det_start": toml[i_det]["det_start"]} 

58 # det_end: detector end - Undefined only for the current detector 

59 try: 

60 tr[i_det]["det_end"] = toml[i_det]["det_end"] 

61 except KeyError: 

62 tr[i_det]["det_end"] = "2035-01-01 00:00" 

63 # det_id: detector id 

64 try: 

65 tr[i_det]["det_id"] = toml[i_det]["det_id"] 

66 except KeyError: 

67 tr[i_det]["det_id"] = "Unknown" 

68 

69 # first_run / last_run: First/last run 

70 try: 

71 tr[i_det]["first_run"] = toml[i_det]["first_run"] 

72 try: 

73 tr[i_det]["last_run"] = toml[i_det]["last_run"] 

74 except KeyError: 

75 tr[i_det]["last_run"] = 1e6 

76 except KeyError: 

77 tr[i_det]["first_run"] = 1e6 

78 tr[i_det]["last_run"] = 0 

79 # first_comm_run / last_comm_run: First/last commissioning run 

80 try: 

81 tr[i_det]["first_comm_run"] = toml[i_det]["first_comm_run"] 

82 try: 

83 tr[i_det]["last_comm_run"] = toml[i_det]["last_comm_run"] 

84 except KeyError: 

85 tr[i_det]["last_comm_run"] = 1e6 

86 except KeyError: 

87 tr[i_det]["first_comm_run"] = 1e6 

88 tr[i_det]["last_comm_run"] = 0 

89 # first_phys_run / last_phys_run: First/last commissioning run 

90 try: 

91 tr[i_det]["first_phys_run"] = toml[i_det]["first_phys_run"] 

92 try: 

93 tr[i_det]["last_phys_run"] = toml[i_det]["last_phys_run"] 

94 except KeyError: 

95 tr[i_det]["last_phys_run"] = 1e6 

96 except KeyError: 

97 tr[i_det]["first_phys_run"] = 1e6 

98 tr[i_det]["last_phys_run"] = 0 

99 

100 # first/last (any) run now defined explicitly  

101 # tr[i_det]["first_run"] = min(tr[i_det]["first_comm_run"], tr[i_det]["first_phys_run"]) 

102 # tr[i_det]["last_run"] = max(tr[i_det]["last_comm_run"], tr[i_det]["last_phys_run"]) 

103 

104 # Reminder: the detector facts are chronologically ordered 

105 if tr["Any"]["first_run"] == 0: 

106 tr["Any"]["first_run"] = tr[i_det]["first_run"] 

107 if tr["Any"]["det_start"] == "": 

108 tr["Any"]["det_start"] = tr[i_det]["det_start"] 

109 

110 tr["Any"]["last_run"] = tr[i_det]["last_run"] 

111 tr["Any"]["det_end"] = tr[i_det]["det_end"] 

112 

113 if ("D0ORCA018" in tr.keys()) and ("mp1" in dq_tag): 

114 tr["D0ORCA018"]["det_end"] = "2023-09-01 00:00" 

115 tr["D0ORCA018"]["last_run"] = 18298 

116 

117 return tr 

118 

119 

120############################################################################### 

121def get_det_run_from_date(site, date_str): 

122 """ 

123 Input: 

124 - site: ARCA/ORCA 

125 - date/time with the format "yyyy-mm-dd hh:mm" 

126 Output: 

127 - Detector name / run number corresponding to this date/time. 

128 """ 

129 out = {"detector": "", 

130 "run": 1e5} 

131 tr = get_det_run_timerange(site) 

132 

133 date_time = date_to_datetime(date_str) 

134 date_time_epoch = date_time.replace(tzinfo=datetime.timezone.utc).timestamp() 

135 

136 for i_det in tr.keys(): 

137 d_t_0 = date_to_datetime(tr[i_det]["start"]) 

138 d_t_1 = date_to_datetime(tr[i_det]["end"]) 

139 

140 if d_t_0 <= date_time < d_t_1: 

141 out["detector"] = i_det 

142 continue 

143 run_prop = get_run_properties_from_db(out["detector"], "PHYS") 

144 

145 for i_run in run_prop.keys(): 

146 if all((date_time_epoch < float(run_prop[i_run]['UNIXSTARTTIME'])/1000., 

147 i_run < out["run"])): 

148 out["run"] = i_run 

149 

150 return out