@@ -276,6 +276,41 @@ def _read_nihon_header(fname):
276
276
return header
277
277
278
278
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
+
279
314
def _read_nihon_annotations (fname ):
280
315
fname = _ensure_path (fname )
281
316
log_fname = fname .with_suffix (".LOG" )
@@ -292,27 +327,33 @@ def _read_nihon_annotations(fname):
292
327
n_logblocks = np .fromfile (fid , np .uint8 , 1 )[0 ]
293
328
all_onsets = []
294
329
all_descriptions = []
330
+ may_have_sub_blocks = n_logblocks <= 21
295
331
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 " )
303
346
for enc in _encodings :
304
347
try :
305
- t_log = t_log .decode (enc )
348
+ t_desc = t_desc .decode (enc )
306
349
except UnicodeDecodeError :
307
350
pass
308
351
else :
309
352
break
310
353
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 } " )
312
355
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
+
316
357
all_onsets .append (t_onset )
317
358
all_descriptions .append (t_desc )
318
359
0 commit comments