33// variantkey.h
44//
55// @category Libraries
6- // @author Nicola Asuni <nicola.asuni@genomicsplc .com>
7- // @copyright 2017-2018 GENOMICS plc
8- // @license MIT (see LICENSE)
9- // @link https://github .com/genomicsplc/variantkey
6+ // @author Nicola Asuni <info@tecnick .com>
7+ // @link https://github.com/tecnickcom/variantkey
8+ // @license MIT [LICENSE](https://raw.githubusercontent.com/tecnickcom/variantkey/main/ LICENSE)
9+ // @copyright 2017-2018 GENOMICS plc, 2018-2023 Nicola Asuni - Tecnick .com
1010//
1111// LICENSE
1212//
1313// Copyright (c) 2017-2018 GENOMICS plc
14+ // Copyright (c) 2018-2023 Nicola Asuni - Tecnick.com
1415//
1516// Permission is hereby granted, free of charge, to any person obtaining a copy
1617// of this software and associated documentation files (the "Software"), to deal
5455#define VKMASK_REFALT 0x000000007FFFFFFF //!< VariantKey binary mask for REF+ALT [ 00000000 00000000 00000000 00000000 01111111 11111111 11111111 11111111 ]
5556#define VKSHIFT_CHROM 59 //!< CHROM LSB position from the VariantKey LSB
5657#define VKSHIFT_POS 31 //!< POS LSB position from the VariantKey LSB
58+ #define MAXUINT32 0xFFFFFFFF //!< Maximum value for uint32_t
5759
5860/**
5961 * VariantKey struct.
@@ -75,16 +77,54 @@ typedef struct vkrange_t
7577 uint64_t max ; //!< Maximum VariantKey value for any given REF+ALT encoding
7678} vkrange_t ;
7779
78- /** @brief Returns chromosome numerical encoding .
80+ /** @brief Returns the encoding for a numerical chromosome input .
7981 *
8082 * @param chrom Chromosome. An identifier from the reference genome, no white-space permitted.
8183 * @param size Length of the chrom string, excluding the terminating null byte.
8284 *
8385 * @return CHROM code
8486 */
87+ static inline uint8_t encode_numeric_chrom (const char * chrom , size_t size )
88+ {
89+ size_t i ;
90+ uint8_t v = (chrom [0 ] - '0' );
91+ for (i = 1 ; i < size ; i ++ )
92+ {
93+ if ((chrom [i ] > '9' ) || (chrom [i ] < '0' ))
94+ {
95+ return 0 ; // NA: a character that is not a numebr was found.
96+ }
97+ v = ((v * 10 ) + (chrom [i ] - '0' ));
98+ }
99+ return v ;
100+ }
101+
102+
103+ /** @brief Returns a true value (1) if the input chrom has 'chr' prefix (case insensitive).
104+ *
105+ * @param chrom Chromosome. An identifier from the reference genome, no white-space permitted.
106+ * @param size Length of the chrom string, excluding the terminating null byte.
107+ *
108+ * @return True (1) if the chr prefix is present.
109+ */
110+ static inline int has_chrom_chr_prefix (const char * chrom , size_t size )
111+ {
112+ return ((size > 3 )
113+ && ((chrom [0 ] == 'c' ) || (chrom [0 ] == 'C' ))
114+ && ((chrom [1 ] == 'h' ) || (chrom [1 ] == 'H' ))
115+ && ((chrom [2 ] == 'r' ) || (chrom [2 ] == 'R' )));
116+ }
117+
118+ /** @brief Returns chromosome numerical encoding.
119+ *
120+ * @param chrom Chromosome. An identifier from the reference genome, no white-space permitted.
121+ * @param size Length of the chrom string, excluding the terminating null byte.
122+ *
123+ * @return CHROM code or 0 in case of invalid input.
124+ */
85125static inline uint8_t encode_chrom (const char * chrom , size_t size )
86126{
87- // X > 23 ; Y > 24 ; M > 25
127+ // X = 23; Y = 24; M = 25; any other letter is mapped to 0:
88128 static const uint8_t onecharmap [] =
89129 {
90130 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
@@ -98,32 +138,19 @@ static inline uint8_t encode_chrom(const char *chrom, size_t size)
98138 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
99139 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
100140 };
101- // remove "chr" prefix
102- if ((size > 3 )
103- && ((chrom [0 ] == 'c' ) || (chrom [0 ] == 'C' ))
104- && ((chrom [1 ] == 'h' ) || (chrom [1 ] == 'H' ))
105- && ((chrom [2 ] == 'r' ) || (chrom [2 ] == 'R' )))
141+ if (has_chrom_chr_prefix (chrom , size ))
106142 {
143+ // remove "chr" prefix
107144 chrom += 3 ;
108145 size -= 3 ;
109146 }
110147 if (size == 0 )
111148 {
112149 return 0 ;
113150 }
114- if ((chrom [0 ] <= '9' ) && (chrom [0 ] >= '0' )) // Number
151+ if ((chrom [0 ] <= '9' ) && (chrom [0 ] >= '0' ))
115152 {
116- size_t i ;
117- uint8_t v = (chrom [0 ] - '0' );
118- for (i = 1 ; i < size ; i ++ )
119- {
120- if ((chrom [i ] > '9' ) || (chrom [i ] < '0' ))
121- {
122- return 0 ; // NA
123- }
124- v = ((v * 10 ) + (chrom [i ] - '0' ));
125- }
126- return v ;
153+ return encode_numeric_chrom (chrom , size );
127154 }
128155 if ((size == 1 ) || ((size == 2 ) && ((chrom [1 ] == 'T' ) || (chrom [1 ] == 't' ))))
129156 {
@@ -159,10 +186,10 @@ static inline uint32_t encode_base(const uint8_t c)
159186{
160187 /*
161188 Encode base:
162- A > 0
163- C > 1
164- G > 2
165- T > 3
189+ A = 0
190+ C = 1
191+ G = 2
192+ T = 3
166193 */
167194 static const uint32_t map [] =
168195 {
@@ -205,7 +232,7 @@ static inline uint32_t encode_refalt_rev(const char *ref, size_t sizeref, const
205232 uint8_t bitpos = 23 ;
206233 if ((encode_allele (& h , & bitpos , ref , sizeref ) < 0 ) || (encode_allele (& h , & bitpos , alt , sizealt ) < 0 ))
207234 {
208- return 0 ; // error code
235+ return MAXUINT32 ; // error code
209236 }
210237 return h ;
211238}
@@ -318,7 +345,7 @@ static inline uint32_t encode_refalt(const char *ref, size_t sizeref, const char
318345 if ((sizeref + sizealt ) <= 11 )
319346 {
320347 uint32_t h = encode_refalt_rev (ref , sizeref , alt , sizealt );
321- if (h != 0 )
348+ if (h != MAXUINT32 )
322349 {
323350 return h ;
324351 }
@@ -486,7 +513,9 @@ static inline void decode_variantkey(uint64_t code, variantkey_t *vk)
486513 vk -> refalt = extract_variantkey_refalt (code );
487514}
488515
489- /** @brief Returns a 64 bit variant key based on CHROM, POS (0-based), REF, ALT.
516+ /**
517+ * Returns a 64 bit variant key based on CHROM, POS (0-based), REF, ALT.
518+ * The variant should be already normalized (see normalize_variant or use normalized_variantkey).
490519 *
491520 * @param chrom Chromosome. An identifier from the reference genome, no white-space or leading zeros permitted.
492521 * @param sizechrom Length of the chrom string, excluding the terminating null byte.
0 commit comments