@@ -276,6 +276,45 @@ def _read_nihon_header(fname):
276276 return header
277277
278278
279+ def _read_event_log_block (fid , t_block , version ):
280+ fid .seek (0x92 + t_block * 20 )
281+ data = np .fromfile (fid , np .uint32 , 1 )
282+ if data .size == 0 or data [0 ] == 0 :
283+ return
284+ t_blk_address = data [0 ]
285+
286+ fid .seek (t_blk_address + 0x1 )
287+ data = np .fromfile (fid , "|S16" , 1 ).astype ("U16" )
288+ if data .size == 0 or data [0 ] != version :
289+ return
290+
291+ fid .seek (t_blk_address + 0x12 )
292+ data = np .fromfile (fid , np .uint8 , 1 )
293+ if data .size == 0 :
294+ return
295+ n_logs = data [0 ]
296+
297+ fid .seek (t_blk_address + 0x14 )
298+ return np .fromfile (fid , "|S45" , n_logs )
299+
300+
301+ def _parse_event_log (event_log ):
302+ t_desc = event_log [:20 ]
303+ hour , minute , second = (
304+ int (event_log [20 :22 ]),
305+ int (event_log [22 :24 ]),
306+ int (event_log [24 :26 ]),
307+ )
308+ t_onset = hour * 3600 + minute * 60 + second
309+ return t_desc , t_onset
310+
311+
312+ def _parse_sub_event_log (sub_event_log ):
313+ t_sub_desc = sub_event_log [:20 ]
314+ t_sub_onset = int (sub_event_log [24 :30 ]) / 1e6
315+ return t_sub_desc , t_sub_onset
316+
317+
279318def _read_nihon_annotations (fname ):
280319 fname = _ensure_path (fname )
281320 log_fname = fname .with_suffix (".LOG" )
@@ -292,27 +331,32 @@ def _read_nihon_annotations(fname):
292331 n_logblocks = np .fromfile (fid , np .uint8 , 1 )[0 ]
293332 all_onsets = []
294333 all_descriptions = []
334+ may_have_sub_blocks = n_logblocks <= 21
295335 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 :
336+ t_logs = _read_event_log_block (fid , t_block , version )
337+ t_sub_logs = None
338+ if may_have_sub_blocks :
339+ t_sub_logs = _read_event_log_block (fid , t_block + 22 , version )
340+
341+ for li , t_log in enumerate (t_logs ):
342+ t_desc , t_onset = _parse_event_log (t_log )
343+ if t_sub_logs is not None and t_sub_logs .size == t_logs .size :
344+ t_sub_desc , t_sub_onset = _parse_sub_event_log (t_sub_logs [li ])
345+ t_desc += t_sub_desc
346+ t_onset += t_sub_onset
347+
348+ t_desc = t_desc .rstrip (b"\x00 " )
303349 for enc in _encodings :
304350 try :
305- t_log = t_log .decode (enc )
351+ t_desc = t_desc .decode (enc )
306352 except UnicodeDecodeError :
307353 pass
308354 else :
309355 break
310356 else :
311357 warn (f"Could not decode log as one of { _encodings } " )
312358 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
359+
316360 all_onsets .append (t_onset )
317361 all_descriptions .append (t_desc )
318362
0 commit comments