@@ -854,12 +854,153 @@ test_ftoa(void)
854
854
855
855
for (j = 0 ; j < sizeof (cases ) / sizeof (* cases ); j ++ ) {
856
856
len = vcz_ftoa (buf , cases [j ].val );
857
- /* printf("j = %d %f->%s=='%s'\n", (int) j, cases[j].val, cases[j].expected, buf); */
857
+ /* printf("j = %d %f->%s=='%s'\n", (int) j, cases[j].val, cases[j].expected,
858
+ * buf); */
858
859
CU_ASSERT_EQUAL_FATAL (len , strlen (cases [j ].expected ));
859
860
CU_ASSERT_STRING_EQUAL_FATAL (buf , cases [j ].expected );
860
861
}
861
862
}
862
863
864
+ static void
865
+ test_encode_plink_single_genotype (void )
866
+ {
867
+ struct test_case {
868
+ int8_t genotype [2 ];
869
+ char expected ;
870
+ };
871
+ // clang-format off
872
+ struct test_case cases [] = {
873
+ {{-1 , -1 }, VCZ_PLINK_MISSING },
874
+ {{-2 , -1 }, VCZ_PLINK_MISSING },
875
+ {{-1 , -2 }, VCZ_PLINK_MISSING },
876
+ {{-2 , -2 }, VCZ_PLINK_MISSING },
877
+ /* Unknown alleles are treated as missing */
878
+ {{2 , 2 }, VCZ_PLINK_MISSING },
879
+ {{-1 , 2 }, VCZ_PLINK_MISSING },
880
+ {{2 , -1 }, VCZ_PLINK_MISSING },
881
+ /* Half-calls are homozygous */
882
+ {{0 , -2 }, VCZ_PLINK_HOM_A2 },
883
+ {{1 , -2 }, VCZ_PLINK_HOM_A1 },
884
+ /* Nominal cases */
885
+ {{1 , 0 }, VCZ_PLINK_HET },
886
+ {{0 , 1 }, VCZ_PLINK_HET },
887
+ {{0 , 0 }, VCZ_PLINK_HOM_A2 },
888
+ {{1 , 1 }, VCZ_PLINK_HOM_A1 },
889
+ };
890
+ // clang-format on
891
+ size_t j ;
892
+ char buf ;
893
+ int8_t a12 [] = { 1 , 0 };
894
+
895
+ for (j = 0 ; j < sizeof (cases ) / sizeof (* cases ); j ++ ) {
896
+ vcz_encode_plink (1 , 1 , cases [j ].genotype , a12 , & buf );
897
+ /* printf("j = %d [%d,%d]->%d==%d'\n", (int) j, cases[j].genotype[0], */
898
+ /* cases[j].genotype[1], cases[j].expected, buf); */
899
+ CU_ASSERT_EQUAL_FATAL (buf , cases [j ].expected );
900
+ }
901
+ }
902
+
903
+ static void
904
+ test_encode_plink_example (void )
905
+ {
906
+
907
+ const size_t num_variants = 3 ;
908
+ const size_t num_samples = 3 ;
909
+ int j ;
910
+ // clang-format off
911
+ int8_t genotypes [] = {
912
+ 0 , 0 , 0 , 1 , 0 , 0 ,
913
+ 1 , 0 , 1 , 1 , 0 , -2 ,
914
+ 1 , 1 , 0 , 1 , -1 ,-1 ,
915
+ };
916
+ // clang-format on
917
+ int8_t a12 [] = { 1 , 0 , 1 , 0 , 1 , 0 };
918
+ int8_t expected [] = { 59 , 50 , 24 };
919
+ char buf [3 ];
920
+
921
+ vcz_encode_plink (num_variants , num_samples , genotypes , a12 , buf );
922
+ for (j = 0 ; j < 3 ; j ++ ) {
923
+ /* printf("%d\n", buf[j]); */
924
+ CU_ASSERT_EQUAL_FATAL (buf [j ], expected [j ]);
925
+ }
926
+ }
927
+
928
+ static void
929
+ test_encode_plink_single_genotype_vary_a12 (void )
930
+ {
931
+ struct test_case {
932
+ int8_t genotype [2 ];
933
+ int8_t a12 [2 ];
934
+ char expected ;
935
+ };
936
+ // clang-format off
937
+ struct test_case cases [] = {
938
+ {{-1 , -1 }, {0 , 1 }, VCZ_PLINK_MISSING },
939
+ {{0 , -2 }, {0 , 1 }, VCZ_PLINK_HOM_A1 },
940
+ {{1 , -2 }, {0 , 1 }, VCZ_PLINK_HOM_A2 },
941
+ {{0 , 0 }, {1 , 2 }, VCZ_PLINK_MISSING },
942
+ /* Allele 1 is missing */
943
+ {{0 , 0 }, {-1 , 0 }, VCZ_PLINK_HOM_A2 },
944
+ {{1 , 0 }, {-1 , 0 }, VCZ_PLINK_MISSING },
945
+ {{0 , 1 }, {-1 , 0 }, VCZ_PLINK_MISSING },
946
+ {{1 , 1 }, {-1 , 0 }, VCZ_PLINK_MISSING },
947
+ {{0 , -1 }, {-1 , 0 }, VCZ_PLINK_MISSING },
948
+ {{-1 , -1 }, {-1 , 0 }, VCZ_PLINK_MISSING },
949
+ /* Nominal cases */
950
+ {{2 , 3 }, {2 , 3 }, VCZ_PLINK_HET },
951
+ {{3 , 2 }, {2 , 3 }, VCZ_PLINK_HET },
952
+ {{3 , 3 }, {2 , 3 }, VCZ_PLINK_HOM_A2 },
953
+ {{2 , 2 }, {2 , 3 }, VCZ_PLINK_HOM_A1 },
954
+ };
955
+ // clang-format on
956
+ size_t j ;
957
+ char buf ;
958
+
959
+ for (j = 0 ; j < sizeof (cases ) / sizeof (* cases ); j ++ ) {
960
+ vcz_encode_plink (1 , 1 , cases [j ].genotype , cases [j ].a12 , & buf );
961
+ /* printf("j = %d [%d,%d]->%d==%d'\n", (int) j, cases[j].genotype[0], */
962
+ /* cases[j].genotype[1], cases[j].expected, buf); */
963
+ CU_ASSERT_EQUAL_FATAL (buf , cases [j ].expected );
964
+ }
965
+ }
966
+
967
+ static void
968
+ test_encode_plink_all_zeros_instance (size_t num_variants , size_t num_samples )
969
+ {
970
+ int8_t * genotypes = calloc (num_variants * num_samples , 2 );
971
+ int8_t * a12 = calloc (num_variants , 2 );
972
+ char * buf = malloc (num_variants * num_samples / 4 );
973
+ size_t j ;
974
+
975
+ CU_ASSERT_FATAL (num_samples % 4 == 0 );
976
+ CU_ASSERT_FATAL (genotypes != NULL );
977
+ CU_ASSERT_FATAL (a12 != NULL );
978
+ CU_ASSERT_FATAL (buf != NULL );
979
+
980
+ for (j = 0 ; j < num_variants ; j ++ ) {
981
+ a12 [2 * j ] = 1 ;
982
+ }
983
+ /* printf("variants=%d samples=%d\n", (int) num_variants, (int) num_samples); */
984
+ vcz_encode_plink (num_variants , num_samples , genotypes , a12 , buf );
985
+ for (j = 0 ; j < num_variants * num_samples / 4 ; j ++ ) {
986
+ /* printf("%d %d\n", (int) j, buf[j]); */
987
+ CU_ASSERT_EQUAL_FATAL (buf [j ], -1 );
988
+ }
989
+
990
+ free (genotypes );
991
+ free (a12 );
992
+ free (buf );
993
+ }
994
+
995
+ static void
996
+ test_encode_plink_all_zeros (void )
997
+ {
998
+ test_encode_plink_all_zeros_instance (1 , 4 );
999
+ test_encode_plink_all_zeros_instance (10 , 4 );
1000
+ test_encode_plink_all_zeros_instance (1 , 400 );
1001
+ test_encode_plink_all_zeros_instance (100 , 400 );
1002
+ }
1003
+
863
1004
/*=================================================
864
1005
Test suite management
865
1006
=================================================
@@ -972,6 +1113,11 @@ main(int argc, char **argv)
972
1113
{ "test_itoa_pow10" , test_itoa_pow10 },
973
1114
{ "test_itoa_boundary" , test_itoa_boundary },
974
1115
{ "test_ftoa" , test_ftoa },
1116
+ { "test_encode_plink_single_genotype" , test_encode_plink_single_genotype },
1117
+ { "test_encode_plink_single_genotype_vary_a12" ,
1118
+ test_encode_plink_single_genotype_vary_a12 },
1119
+ { "test_encode_plink_example" , test_encode_plink_example },
1120
+ { "test_encode_plink_all_zeros" , test_encode_plink_all_zeros },
975
1121
{ NULL , NULL },
976
1122
};
977
1123
return test_main (tests , argc , argv );
0 commit comments