@@ -2130,6 +2130,103 @@ def test_hed_annotations():
21302130 assert list (empty_ann .hed_string ) == []
21312131
21322132
2133+ def test_hed_annotations_mixed_concatenation ():
2134+ """Test concatenation of HEDAnnotations with regular Annotations."""
2135+ pytest .importorskip ("hed" )
2136+ tone = (
2137+ "Sensory-event, Experimental-stimulus, Auditory-presentation, "
2138+ "(Tone, Frequency/550 Hz)"
2139+ )
2140+ press = "Agent-action, (Experiment-participant, (Press, Mouse-button))"
2141+
2142+ hed = HEDAnnotations (
2143+ onset = [0 , 1 ],
2144+ duration = [0.1 , 0.2 ],
2145+ description = ["tone" , "press" ],
2146+ hed_string = [tone , press ],
2147+ extras = [{"run" : 1 }, {"run" : 2 }],
2148+ )
2149+ reg = Annotations (
2150+ onset = [2 , 3 ],
2151+ duration = [0.3 , 0.4 ],
2152+ description = ["plain1" , "plain2" ],
2153+ extras = [{"run" : 3 }, {}],
2154+ )
2155+
2156+ # --- Annotations += HEDAnnotations ---
2157+ combined = reg .copy ()
2158+ combined += hed
2159+ assert isinstance (combined , Annotations )
2160+ assert not isinstance (combined , HEDAnnotations )
2161+ assert len (combined ) == 4
2162+ # sorted by onset: hed(0,1) then reg(2,3)
2163+ assert combined .extras [0 ]["HED" ] == tone
2164+ assert combined .extras [1 ]["HED" ] == press
2165+ assert "HED" not in combined .extras [2 ]
2166+ assert "HED" not in combined .extras [3 ]
2167+ # pre-existing extras preserved
2168+ assert combined .extras [0 ]["run" ] == 1
2169+ assert combined .extras [1 ]["run" ] == 2
2170+ assert combined .extras [2 ]["run" ] == 3
2171+
2172+ # --- HEDAnnotations += Annotations ---
2173+ combined2 = hed .copy ()
2174+ combined2 += reg
2175+ # result is plain Annotations (rebinding semantics)
2176+ assert isinstance (combined2 , Annotations )
2177+ assert not isinstance (combined2 , HEDAnnotations )
2178+ assert len (combined2 ) == 4
2179+ # sorted by onset: hed(0,1) then reg(2,3)
2180+ assert combined2 .extras [0 ]["HED" ] == tone
2181+ assert combined2 .extras [1 ]["HED" ] == press
2182+ assert "HED" not in combined2 .extras [2 ]
2183+ assert "HED" not in combined2 .extras [3 ]
2184+ # pre-existing extras preserved
2185+ assert combined2 .extras [0 ]["run" ] == 1
2186+ assert combined2 .extras [2 ]["run" ] == 3
2187+
2188+ # --- non-mutating + operators ---
2189+ hed_orig = hed .copy ()
2190+ reg_orig = reg .copy ()
2191+
2192+ out1 = reg + hed
2193+ assert isinstance (out1 , Annotations )
2194+ assert not isinstance (out1 , HEDAnnotations )
2195+ assert len (out1 ) == 4
2196+ assert out1 .extras [0 ]["HED" ] == tone
2197+ assert out1 .extras [1 ]["HED" ] == press
2198+
2199+ out2 = hed + reg
2200+ assert isinstance (out2 , Annotations )
2201+ assert not isinstance (out2 , HEDAnnotations )
2202+ assert len (out2 ) == 4
2203+ assert out2 .extras [0 ]["HED" ] == tone
2204+ assert out2 .extras [1 ]["HED" ] == press
2205+
2206+ # originals are not mutated
2207+ assert hed == hed_orig
2208+ assert reg == reg_orig
2209+
2210+ # --- ch_names are preserved ---
2211+ hed_ch = HEDAnnotations (
2212+ onset = [0 ],
2213+ duration = [0.1 ],
2214+ description = ["x" ],
2215+ hed_string = [tone ],
2216+ ch_names = [["EEG 001" ]],
2217+ )
2218+ reg_ch = Annotations (
2219+ onset = [1 ],
2220+ duration = [0.1 ],
2221+ description = ["y" ],
2222+ ch_names = [["EEG 002" ]],
2223+ )
2224+ out3 = reg_ch + hed_ch
2225+ # sorted by onset: hed_ch(0) then reg_ch(1)
2226+ assert out3 [0 ]["ch_names" ] == ("EEG 001" ,)
2227+ assert out3 [1 ]["ch_names" ] == ("EEG 002" ,)
2228+
2229+
21332230def test_hed_annotations_to_data_frame ():
21342231 """Test HEDAnnotations.to_data_frame()."""
21352232 pytest .importorskip ("hed" )
0 commit comments