@@ -168,6 +168,7 @@ struct _filter_t
168
168
#define TOK_MODULO 40 // %
169
169
#define TOK_EXT 41 // external values set before each filter_test_ext() call, can be one of {},{str},{int},{float}
170
170
#define TOK_FISHER 42
171
+ #define TOK_sCOUNT 43
171
172
172
173
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
173
174
// ( ) [ < = > ] ! | & + - * / M m a A O ~ ^ S . l f c p b P i s %
@@ -198,13 +199,15 @@ static int filters_next_token(char **str, int *len)
198
199
tmp = * str ;
199
200
}
200
201
202
+ if ( !strncasecmp (tmp ,"SMPL_COUNT(" ,11 ) ) { (* str ) += 10 ; return TOK_sCOUNT ; }
201
203
if ( !strncasecmp (tmp ,"SMPL_MAX(" ,9 ) ) { (* str ) += 8 ; return TOK_sMAX ; }
202
204
if ( !strncasecmp (tmp ,"SMPL_MIN(" ,9 ) ) { (* str ) += 8 ; return TOK_sMIN ; }
203
205
if ( !strncasecmp (tmp ,"SMPL_MEAN(" ,10 ) ) { (* str ) += 9 ; return TOK_sAVG ; }
204
206
if ( !strncasecmp (tmp ,"SMPL_MEDIAN(" ,12 ) ) { (* str ) += 11 ; return TOK_sMEDIAN ; }
205
207
if ( !strncasecmp (tmp ,"SMPL_AVG(" ,9 ) ) { (* str ) += 8 ; return TOK_sAVG ; }
206
208
if ( !strncasecmp (tmp ,"SMPL_STDEV(" ,11 ) ) { (* str ) += 10 ; return TOK_sSTDEV ; }
207
209
if ( !strncasecmp (tmp ,"SMPL_SUM(" ,9 ) ) { (* str ) += 8 ; return TOK_sSUM ; }
210
+ if ( !strncasecmp (tmp ,"sCOUNT(" ,7 ) ) { (* str ) += 6 ; return TOK_sCOUNT ; }
208
211
if ( !strncasecmp (tmp ,"sMAX(" ,5 ) ) { (* str ) += 4 ; return TOK_sMAX ; }
209
212
if ( !strncasecmp (tmp ,"sMIN(" ,5 ) ) { (* str ) += 4 ; return TOK_sMIN ; }
210
213
if ( !strncasecmp (tmp ,"sMEAN(" ,6 ) ) { (* str ) += 5 ; return TOK_sAVG ; }
@@ -1992,6 +1995,35 @@ static int func_count(filter_t *flt, bcf1_t *line, token_t *rtok, token_t **stac
1992
1995
rtok -> values [0 ] = cnt ;
1993
1996
return 1 ;
1994
1997
}
1998
+ static int func_smpl_count (filter_t * flt , bcf1_t * line , token_t * rtok , token_t * * stack , int nstack )
1999
+ {
2000
+ token_t * tok = stack [nstack - 1 ];
2001
+ if ( !tok -> nsamples ) return func_max (flt ,line ,rtok ,stack ,nstack );
2002
+ rtok -> nsamples = tok -> nsamples ;
2003
+ rtok -> nvalues = tok -> nsamples ;
2004
+ rtok -> nval1 = 1 ;
2005
+ hts_expand (double ,rtok -> nvalues ,rtok -> mvalues ,rtok -> values );
2006
+ assert (tok -> usmpl );
2007
+ if ( !rtok -> usmpl ) rtok -> usmpl = (uint8_t * ) malloc (tok -> nsamples );
2008
+ memcpy (rtok -> usmpl , tok -> usmpl , tok -> nsamples );
2009
+ int i ,j ;
2010
+ assert ( tok -> tag && tok -> nsamples );
2011
+ if ( tok -> tag && tok -> nsamples )
2012
+ {
2013
+ // raw number of values in a FMT tag, e.g. COUNT(FMT/TAG)
2014
+ if ( tok -> is_str ) error ("todo: Type=String for COUNT on FORMAT fields?\n" );
2015
+ for (i = 0 ; i < tok -> nsamples ; i ++ )
2016
+ {
2017
+ if ( !tok -> usmpl [i ] ) continue ;
2018
+ int cnt = 0 ;
2019
+ double * ptr = tok -> values + i * tok -> nval1 ;
2020
+ for (j = 0 ; j < tok -> nval1 ; j ++ )
2021
+ if ( !bcf_double_is_missing_or_vector_end (ptr [j ]) ) cnt ++ ;
2022
+ rtok -> values [i ] = cnt ;
2023
+ }
2024
+ }
2025
+ return 1 ;
2026
+ }
1995
2027
static int func_strlen (filter_t * flt , bcf1_t * line , token_t * rtok , token_t * * stack , int nstack )
1996
2028
{
1997
2029
token_t * tok = stack [nstack - 1 ];
@@ -4088,6 +4120,7 @@ static filter_t *filter_init_(bcf_hdr_t *hdr, const char *str, int exit_on_error
4088
4120
else if ( out [i ].tok_type == TOK_BINOM ) { out [i ].func = func_binom ; out [i ].tok_type = TOK_FUNC ; }
4089
4121
else if ( out [i ].tok_type == TOK_FISHER ) { out [i ].func = func_fisher ; out [i ].tok_type = TOK_FUNC ; }
4090
4122
else if ( out [i ].tok_type == TOK_PERLSUB ) { out [i ].func = perl_exec ; out [i ].tok_type = TOK_FUNC ; }
4123
+ else if ( out [i ].tok_type == TOK_sCOUNT ) { out [i ].func = func_smpl_count ; out [i ].tok_type = TOK_FUNC ; }
4091
4124
else if ( out [i ].tok_type == TOK_sMAX ) { out [i ].func = func_smpl_max ; out [i ].tok_type = TOK_FUNC ; }
4092
4125
else if ( out [i ].tok_type == TOK_sMIN ) { out [i ].func = func_smpl_min ; out [i ].tok_type = TOK_FUNC ; }
4093
4126
else if ( out [i ].tok_type == TOK_sAVG ) { out [i ].func = func_smpl_avg ; out [i ].tok_type = TOK_FUNC ; }
0 commit comments