8080}
8181
8282
83- def blue_to_sigmf_type_str (h_fixed ) :
83+ def blue_to_sigmf_type_str (h_fixed : dict ) -> str :
8484 """
8585 Convert BLUE format code to SigMF datatype string.
8686
@@ -121,7 +121,7 @@ def blue_to_sigmf_type_str(h_fixed):
121121 return datatype
122122
123123
124- def detect_endian (data ) :
124+ def detect_endian (data : bytes ) -> str :
125125 """
126126 Detect endianness of a Bluefile header.
127127
@@ -149,15 +149,15 @@ def detect_endian(data):
149149 raise SigMFConversionError (f"Unsupported endianness: { endianness } " )
150150
151151
152- def read_hcb (file_path ):
152+ def read_hcb (file_path : Path ) -> ( dict , dict ):
153153 """
154154 Read Header Control Block (HCB) from BLUE file.
155155
156156 First 256 bytes contains fixed header, followed by 256 bytes of adjunct header.
157157
158158 Parameters
159159 ----------
160- file_path : str
160+ file_path : Path
161161 Path to the Blue file.
162162
163163 Returns
@@ -166,8 +166,6 @@ def read_hcb(file_path):
166166 Fixed Header
167167 h_adjunct : dict
168168 Adjunct Header
169- h_keywords : dict
170- Custom User Keywords parsed from fixed header.
171169
172170 Raises
173171 ------
@@ -198,6 +196,8 @@ def read_hcb(file_path):
198196 if "=" in field :
199197 key , value = field .split ("=" , 1 )
200198 h_keywords [key ] = value
199+ # place parsed keywords back into fixed header
200+ h_fixed ["keywords" ] = h_keywords
201201
202202 # variable (adjunct) header parsing
203203 if h_fixed ["type" ] in (1000 , 1001 ):
@@ -225,10 +225,10 @@ def read_hcb(file_path):
225225 validate_fixed (h_fixed )
226226 validate_adjunct (h_adjunct )
227227
228- return h_fixed , h_adjunct , h_keywords
228+ return h_fixed , h_adjunct
229229
230230
231- def read_extended_header (file_path , h_fixed ) :
231+ def read_extended_header (file_path : Path , h_fixed : dict ) -> list :
232232 """
233233 Read Extended Header from a BLUE file.
234234
@@ -382,13 +382,13 @@ def _get_data_boundaries(blue_path: Path, h_fixed: dict) -> (int, int):
382382 return header_bytes , data_bytes , trailing_bytes
383383
384384
385- def _description (h_fixed : dict , h_keywords : dict ) -> str :
385+ def _description (h_fixed : dict ) -> str :
386386 """
387387 Construct a human-readable description of the BLUE file.
388388 """
389389 try :
390390 spec_str = "Unknown"
391- version = Version (h_keywords .get ("VER" , "0.0" ))
391+ version = Version (h_fixed . get ( "keywords" ) .get ("VER" , "0.0" ))
392392 if version .major == 1 :
393393 spec_str = f"BLUE { version } "
394394 elif version .major == 2 :
@@ -406,7 +406,6 @@ def _description(h_fixed: dict, h_keywords: dict) -> str:
406406
407407def _build_common_metadata (
408408 h_fixed : dict ,
409- h_keywords : dict ,
410409 h_adjunct : dict ,
411410 h_extended : list ,
412411 is_ncd : bool = False ,
@@ -420,8 +419,6 @@ def _build_common_metadata(
420419 ----------
421420 h_fixed : dict
422421 Fixed Header
423- h_keywords : dict
424- Custom User Keywords
425422 h_adjunct : dict
426423 Adjunct Header
427424 h_extended : list of dict
@@ -472,7 +469,7 @@ def get_tag(tag):
472469 SigMFFile .NUM_CHANNELS_KEY : num_channels ,
473470 SigMFFile .SAMPLE_RATE_KEY : sample_rate_hz ,
474471 SigMFFile .EXTENSIONS_KEY : [{"name" : "blue" , "version" : "0.0.1" , "optional" : True }],
475- SigMFFile .DESCRIPTION_KEY : _description (h_fixed , h_keywords ),
472+ SigMFFile .DESCRIPTION_KEY : _description (h_fixed ),
476473 }
477474
478475 # add NCD-specific fields
@@ -482,7 +479,6 @@ def get_tag(tag):
482479
483480 # merge HCB values into metadata
484481 global_info ["blue:fixed" ] = h_fixed
485- global_info ["blue:keywords" ] = h_keywords
486482 global_info ["blue:adjunct" ] = h_adjunct
487483
488484 # merge extended header fields, handling duplicate keys
@@ -507,7 +503,7 @@ def get_tag(tag):
507503 # calculate blue start time
508504 blue_start_time = float (h_fixed .get ("timecode" , 0 ))
509505 blue_start_time += h_adjunct .get ("xstart" , 0 )
510- blue_start_time += float (h_keywords .get ("TC_PREC" , 0 ))
506+ blue_start_time += float (h_fixed . get ( "keywords" ) .get ("TC_PREC" , 0 ))
511507
512508 capture_info = {}
513509
@@ -565,7 +561,7 @@ def validate_fixed(h_fixed: dict) -> None:
565561 SigMFConversionError
566562 If required fields are missing or invalid.
567563 """
568- required = ["version" , "data_start" , "data_size" , "data_rep" , "head_rep" , "detached" , "format" , "type" ]
564+ required = ["version" , "data_start" , "data_size" , "data_rep" , "head_rep" , "detached" , "format" , "type" , "keywords" ]
569565 for field in required :
570566 if field not in h_fixed :
571567 raise SigMFConversionError (f"Missing required Fixed Header field: { field } " )
@@ -619,7 +615,6 @@ def validate_extended(entries: list) -> None:
619615def construct_sigmf (
620616 filenames : dict ,
621617 h_fixed : dict ,
622- h_keywords : dict ,
623618 h_adjunct : dict ,
624619 h_extended : list ,
625620 is_metadata_only : bool = False ,
@@ -634,8 +629,6 @@ def construct_sigmf(
634629 Mapping returned by get_sigmf_filenames containing destination paths.
635630 h_fixed : dict
636631 Fixed Header
637- h_keywords : dict
638- Custom User Keywords
639632 h_adjunct : dict
640633 Adjunct Header
641634 h_extended : list of dict
@@ -651,7 +644,7 @@ def construct_sigmf(
651644 SigMF object.
652645 """
653646 # use shared helper to build common metadata
654- global_info , capture_info = _build_common_metadata (h_fixed , h_keywords , h_adjunct , h_extended )
647+ global_info , capture_info = _build_common_metadata (h_fixed , h_adjunct , h_extended )
655648
656649 # set metadata-only flag for zero-sample files (only for non-NCD files)
657650 if is_metadata_only :
@@ -694,7 +687,6 @@ def construct_sigmf(
694687def construct_sigmf_ncd (
695688 blue_path : Path ,
696689 h_fixed : dict ,
697- h_keywords : dict ,
698690 h_adjunct : dict ,
699691 h_extended : list ,
700692) -> SigMFFile :
@@ -707,8 +699,6 @@ def construct_sigmf_ncd(
707699 Path to the original BLUE file.
708700 h_fixed : dict
709701 Fixed Header
710- h_keywords : dict
711- Custom User Keywords
712702 h_adjunct : dict
713703 Adjunct Header
714704 h_extended : list of dict
@@ -724,7 +714,6 @@ def construct_sigmf_ncd(
724714 # use shared helper to build common metadata, with NCD-specific additions
725715 global_info , capture_info = _build_common_metadata (
726716 h_fixed ,
727- h_keywords ,
728717 h_adjunct ,
729718 h_extended ,
730719 is_ncd = True ,
@@ -790,7 +779,7 @@ def blue_to_sigmf(
790779 validate_file (blue_path )
791780
792781 # read Header control block (HCB) to determine how to process the rest of the file
793- h_fixed , h_adjunct , h_keywords = read_hcb (blue_path )
782+ h_fixed , h_adjunct = read_hcb (blue_path )
794783
795784 # read extended header
796785 h_extended = read_extended_header (blue_path , h_fixed )
@@ -802,7 +791,7 @@ def blue_to_sigmf(
802791 # handle NCD case
803792 if create_ncd :
804793 # create metadata-only SigMF for NCD pointing to original file
805- ncd_meta = construct_sigmf_ncd (blue_path , h_fixed , h_keywords , h_adjunct , h_extended )
794+ ncd_meta = construct_sigmf_ncd (blue_path , h_fixed , h_adjunct , h_extended )
806795
807796 # write NCD metadata to specified output path if provided
808797 if out_path is not None :
@@ -828,7 +817,6 @@ def blue_to_sigmf(
828817 meta = construct_sigmf (
829818 filenames = filenames ,
830819 h_fixed = h_fixed ,
831- h_keywords = h_keywords ,
832820 h_adjunct = h_adjunct ,
833821 h_extended = h_extended ,
834822 is_metadata_only = metadata_only ,
@@ -839,9 +827,6 @@ def blue_to_sigmf(
839827 for key , _ , _ , _ , desc in FIXED_LAYOUT :
840828 log .debug (f"{ key :10s} : { h_fixed [key ]!r} # { desc } " )
841829
842- log .debug (">>>>>>>>> User Keywords" )
843- log .debug (h_keywords )
844-
845830 log .debug (">>>>>>>>> Adjunct Header" )
846831 log .debug (h_adjunct )
847832
0 commit comments