Testing of the @doc-json output
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

tessera-viz: implement classification_to_rgba

Add color_of_hex for parsing hex color strings and classification_to_rgba
for mapping integer class predictions to colored RGBA pixels. Unknown
classes render as black. Add unit arg to resolve optional alpha parameter.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

+78 -4
+21 -4
tessera-viz/lib/viz.ml
··· 47 47 done; 48 48 { data; width; height } 49 49 50 - let color_of_hex _s = 51 - failwith "TODO: color_of_hex" 50 + let color_of_hex s = 51 + let s = if String.length s > 0 && s.[0] = '#' then String.sub s 1 (String.length s - 1) else s in 52 + let r = int_of_string ("0x" ^ String.sub s 0 2) in 53 + let g = int_of_string ("0x" ^ String.sub s 2 2) in 54 + let b = int_of_string ("0x" ^ String.sub s 4 2) in 55 + { r; g; b } 52 56 53 - let classification_to_rgba ?alpha:_ ~predictions:_ ~colors:_ ~width:_ ~height:_ = 54 - failwith "TODO: classification_to_rgba" 57 + let classification_to_rgba ?(alpha = 200) ~predictions ~colors ~width ~height () = 58 + let n_pixels = height * width in 59 + let data = Bigarray.Array1.create Bigarray.int8_unsigned Bigarray.c_layout (n_pixels * 4) in 60 + let color_tbl = Hashtbl.create (List.length colors) in 61 + List.iter (fun (id, c) -> Hashtbl.replace color_tbl id c) colors; 62 + let black = { r = 0; g = 0; b = 0 } in 63 + for i = 0 to n_pixels - 1 do 64 + let off = i * 4 in 65 + let c = try Hashtbl.find color_tbl predictions.(i) with Not_found -> black in 66 + Bigarray.Array1.set data off c.r; 67 + Bigarray.Array1.set data (off + 1) c.g; 68 + Bigarray.Array1.set data (off + 2) c.b; 69 + Bigarray.Array1.set data (off + 3) alpha 70 + done; 71 + { data; width; height }
+1
tessera-viz/lib/viz.mli
··· 43 43 colors:(int * color) list -> 44 44 width:int -> 45 45 height:int -> 46 + unit -> 46 47 rgba_image 47 48 (** Convert class predictions to a colored RGBA image. 48 49
+56
tessera-viz/test/test_viz.ml
··· 84 84 ; Alcotest.test_case "data length" `Quick test_pca_data_length 85 85 ] 86 86 87 + (* color_of_hex tests *) 88 + 89 + let test_hex_with_hash () = 90 + let c = Viz.color_of_hex "#ff0000" in 91 + Alcotest.(check int) "r" 255 c.r; 92 + Alcotest.(check int) "g" 0 c.g; 93 + Alcotest.(check int) "b" 0 c.b 94 + 95 + let test_hex_without_hash () = 96 + let c = Viz.color_of_hex "00ff00" in 97 + Alcotest.(check int) "r" 0 c.r; 98 + Alcotest.(check int) "g" 255 c.g; 99 + Alcotest.(check int) "b" 0 c.b 100 + 101 + let color_tests = 102 + [ Alcotest.test_case "with #" `Quick test_hex_with_hash 103 + ; Alcotest.test_case "without #" `Quick test_hex_without_hash 104 + ] 105 + 106 + (* classification_to_rgba tests *) 107 + 108 + let test_classification_basic () = 109 + (* 4 pixels, 2 classes *) 110 + let predictions = [| 0; 1; 0; 1 |] in 111 + let red : Viz.color = { r = 255; g = 0; b = 0 } in 112 + let blue : Viz.color = { r = 0; g = 0; b = 255 } in 113 + let colors = [ (0, red); (1, blue) ] in 114 + let img = Viz.classification_to_rgba ~predictions ~colors ~width:2 ~height:2 () in 115 + check_pixel "pixel 0 (class 0)" 255 0 0 200 img 0; 116 + check_pixel "pixel 1 (class 1)" 0 0 255 200 img 1; 117 + check_pixel "pixel 2 (class 0)" 255 0 0 200 img 2; 118 + check_pixel "pixel 3 (class 1)" 0 0 255 200 img 3 119 + 120 + let test_classification_unknown_class () = 121 + let predictions = [| 0; 99 |] in 122 + let red : Viz.color = { r = 255; g = 0; b = 0 } in 123 + let colors = [ (0, red) ] in 124 + let img = Viz.classification_to_rgba ~predictions ~colors ~width:2 ~height:1 () in 125 + check_pixel "known class" 255 0 0 200 img 0; 126 + check_pixel "unknown class -> black" 0 0 0 200 img 1 127 + 128 + let test_classification_custom_alpha () = 129 + let predictions = [| 0 |] in 130 + let red : Viz.color = { r = 255; g = 0; b = 0 } in 131 + let colors = [ (0, red) ] in 132 + let img = Viz.classification_to_rgba ~alpha:128 ~predictions ~colors ~width:1 ~height:1 () in 133 + check_pixel "custom alpha" 255 0 0 128 img 0 134 + 135 + let classification_tests = 136 + [ Alcotest.test_case "basic 2 classes" `Quick test_classification_basic 137 + ; Alcotest.test_case "unknown class" `Quick test_classification_unknown_class 138 + ; Alcotest.test_case "custom alpha" `Quick test_classification_custom_alpha 139 + ] 140 + 87 141 let () = 88 142 Alcotest.run "tessera-viz" 89 143 [ ("percentile", percentile_tests) 90 144 ; ("pca_to_rgba", pca_tests) 145 + ; ("color_of_hex", color_tests) 146 + ; ("classification_to_rgba", classification_tests) 91 147 ]