@@ -276,6 +276,41 @@ def _read_nihon_header(fname):
276276 return header
277277
278278
279+ def _read_event_log_block (fid , t_block , device_type ):
280+ fid .seek (0x92 + t_block * 20 )
281+ t_blk_address = np .fromfile (fid , np .uint32 , 1 )[0 ]
282+ if t_blk_address == 0 :
283+ return
284+
285+ fid .seek (t_blk_address + 0x1 )
286+ data_name = np .fromfile (fid , "|S16" , 1 ).astype ("U16" )[0 ]
287+ if data_name != device_type :
288+ return
289+
290+ fid .seek (t_blk_address + 0x12 )
291+ n_logs = np .fromfile (fid , np .uint8 , 1 )[0 ]
292+ fid .seek (t_blk_address + 0x14 )
293+ t_logs = np .fromfile (fid , "|S45" , n_logs )
294+ return t_logs
295+
296+
297+ def _parse_event_log (event_log ):
298+ t_desc = event_log [:20 ]
299+ hour , minute , second = (
300+ int (event_log [20 :22 ]),
301+ int (event_log [22 :24 ]),
302+ int (event_log [24 :26 ]),
303+ )
304+ t_onset = hour * 3600 + minute * 60 + second
305+ return t_desc , t_onset
306+
307+
308+ def _parse_sub_event_log (sub_event_log ):
309+ t_sub_desc = sub_event_log [:20 ]
310+ t_sub_onset = int (sub_event_log [24 :30 ]) / 1e6
311+ return t_sub_desc , t_sub_onset
312+
313+
279314def _read_nihon_annotations (fname ):
280315 fname = _ensure_path (fname )
281316 log_fname = fname .with_suffix (".LOG" )
@@ -292,27 +327,33 @@ def _read_nihon_annotations(fname):
292327 n_logblocks = np .fromfile (fid , np .uint8 , 1 )[0 ]
293328 all_onsets = []
294329 all_descriptions = []
330+ may_have_sub_blocks = n_logblocks <= 21
295331 for t_block in range (n_logblocks ):
296- fid .seek (0x92 + t_block * 20 )
297- t_blk_address = np .fromfile (fid , np .uint32 , 1 )[0 ]
298- fid .seek (t_blk_address + 0x12 )
299- n_logs = np .fromfile (fid , np .uint8 , 1 )[0 ]
300- fid .seek (t_blk_address + 0x14 )
301- t_logs = np .fromfile (fid , "|S45" , n_logs )
302- for t_log in t_logs :
332+ t_logs = _read_event_log_block (fid , t_block , version )
333+ t_sub_logs = None
334+ if may_have_sub_blocks :
335+ t_sub_logs = _read_event_log_block (fid , t_block + 22 , version )
336+ assert t_sub_logs is None or len (t_logs ) == len (t_sub_logs )
337+
338+ for i , t_log in enumerate (t_logs ):
339+ t_desc , t_onset = _parse_event_log (t_log )
340+ if t_sub_logs is not None :
341+ t_sub_desc , t_sub_onset = _parse_sub_event_log (t_sub_logs [i ])
342+ t_desc += t_sub_desc
343+ t_onset += t_sub_onset
344+
345+ t_desc = t_desc .rstrip (b"\x00 " )
303346 for enc in _encodings :
304347 try :
305- t_log = t_log .decode (enc )
348+ t_desc = t_desc .decode (enc )
306349 except UnicodeDecodeError :
307350 pass
308351 else :
309352 break
310353 else :
311- warn (f"Could not decode log as one of { _encodings } " )
354+ warn (f"Could not decode log { t_desc } as one of { _encodings } " )
312355 continue
313- t_desc = t_log [:20 ].strip ("\x00 " )
314- t_onset = datetime .strptime (t_log [20 :26 ], "%H%M%S" )
315- t_onset = t_onset .hour * 3600 + t_onset .minute * 60 + t_onset .second
356+
316357 all_onsets .append (t_onset )
317358 all_descriptions .append (t_desc )
318359
0 commit comments