#ifndef msm_seq_desc_H #define msm_seq_desc_H /* Abstract sequence descriptors. */ /* Last edited on 2008-02-01 12:36:57 by hcgl */ #define msm_seq_H_COPYRIGHT \ "Copyright © 2005 by the State University of Campinas (UNICAMP)" #include #include #include typedef int msm_seq_id_t; /* A {msm_seq_id_t} is an internal identifier for a sequence, presently an index into a table of sequences. */ #define msm_seq_id_none -1 /* A {msm_seq_id_t} value that means "no sequence". */ typedef struct msm_seq_desc_t { msm_seq_id_t id; /* Internal identifier of the sequence. */ char *name; /* External identifier of the sequence. */ int level; /* Filtering level. */ int npos; /* Number of matching positions in the sequence. */ bool_t circ; /* Tells whether the sequence is circular. */ } msm_seq_desc_t; /* Essential parameters of a sequence to be matched. In this library, the fields {id}, {name}, and {level} are used only for I/O and consistency checks. Typically, the {id} and/or the {name} fields identify the original sequence, and {level} indicates the number of coarsening (filtering and downsampling) steps applied to the original sequences (so that {level} is zero for the original sequence). The sequence is assumed to be a function from the integers (/matching positions/) to values in some space {V} that depends on the application. The values need not be actual elements in an array; they may be generated by interpolation, or some other formula. If {circ} is FALSE, the sequence is assumed to be open; the only valid matching positions are {0..npos-1}, which may map to arbitrary values. If {circ} is TRUE, the sequence is circular; any integer is a valid position, but indices that are congruent modulo {npos} must map to the same value. In either case, the sequence has only {npos} *distinct* values, which can be found at positions {0..npos-1}. */ msm_seq_desc_t msm_seq_desc_make ( msm_seq_id_t id, /* Internal identifier of the sequence. */ char *name, /* External identifier of the sequence. */ int level, /* Filtering level. */ int npos, /* Number of distinct values in the sequence. */ bool_t circ /* Tells whether the sequence is circular. */ ); /* Assembles an {msm_seq_desc_t} from the given fields. */ bool_t msm_seq_desc_same_seq(msm_seq_desc_t *sa, msm_seq_desc_t *sb, bool_t die); /* Returns TRUE if the equence descriptors {sa} and {sb} refer to the same sequence (that is, if they have the same {name}, {id}, and {level} fields). Otherwise, if {die} is true, fails with an error message; if {die} is FALSE, returns FALSE silently. The {name} strings are compared with {strcmp}. */ bool_t msm_seq_desc_equal(msm_seq_desc_t *sa, msm_seq_desc_t *sb, bool_t die); /* Returns TRUE if sequence descriptors {sa} and {sb} are identical (refer to the same sequence and have the same {npos}). Otherwise, if {die} is true, fails with an error message; if {die} is FALSE, returns FALSE silently. The {name} strings are compared with {strcmp}. */ /* INDEX MAPPING BETWEEN SUCCESSIVE SCALES OF RESOLUTION The procedures in this section provide index mapping between a sequence {sFine} with {nFine} distinct matching positions and a filtered and downsampled version {sCoarse} of it, with {nCoarse} positions. These procedures assume that the filter performs a discrete convolution of the fine sequence with a filter kernel that spans {nwtb} sequence positions, and resamples the result with equally spaced samples. The two sequences are assumed to have the same circularity attribute. If both are circular, every position in {sFine} will have a corresponding position (possibly fractional) in {sCoarse}, and the mapping will preserve their periodicities: namely, if position {ix} of {sCoarse} is mapped to position {jx} of {sFine}, then position {ix+k*nCoarse} of {sCoarse} will be mapped to position {jx + k*nFine} of {sFine}. If both sequences are open, then positions in the range {[0 .. s]} and {[s + nFine - nwtb -1 .. nFine-1]} of {sFine}, where {s = floor((nwtb-1)/2)} will have no correspondents in {sCoarse}. In any case, the procedures assume that each integer position {ix} of {sCoarse} corresponds to position {floor(a*ix) + s} of {sFine}; where {a} is a real constant that depends on the lengths and circularities of the two sequences. These procedures do not assume any particular value for the scale factor {a}, or for the position counts {nFine} and {nCoarse}, except for {nFine >= nwtb} and {nCoarse >= 1}. In particular, {a} may be less than one; this is may occur if the {sCoarse} sequence is subsampled at a higher rate than {sFine}. In any case, the mapping between the positions of the two sequences are monotonic non-decreasing: i.e. increasing one index does not decrease the other. Note that for certain values of {nFine} and {nCoarse} there may be `hiccups' in the mapping, due to {floor()} rounding. */ int msm_seq_desc_map_index_to_coarser(int ixFine, int nFine, int nCoarse, bool_t circ, int nwtb); /* Maps a position {ixFine} of a sequence with circularity {circ} and {nFine} positions to the approximately corresponding position {ixCoarse} in a filtered and downsampled version with {nCoarse} positions, assuming a filter kernel that covers {nwtb} positions of the fine sequence. */ int msm_seq_desc_map_index_to_finer(int ixCoarse, int nCoarse, int nFine, bool_t circ, int nwtb); /* Maps a position {ixCoarse} in a filtered sequence with circularity {circ} and {nCoarse} positions to the approximately corresponding position {ixFine} in the original sequence with {nFine} positions, assuming a filter kernel that covers {nwtb} positions of the fine sequence. */ /* RANDOM SEGMENTS */ void msm_seq_desc_throw_segment(int npos, bool_t circ, int nseg, int *ini, int *fin); /* Selects initial and final sample indices {*ini,*fin} for a random segment spanning {nseg} positions, taken from a sequence with {npos} positions and circularity {circ}. */ /* PRINTOUT */ void msm_seq_desc_write ( FILE *wr, char *pre, msm_seq_desc_t *s, int idsize, int namesize, int nssize, char *suf ); /* Writes to {wr} the sequence descriptor {s}, in a format compatible with {msm_seq_desc_read}; namely, "{pre} {s.id} {s.name} {s.level} {s.npos} {s.circ} {suf}". The delimiters {pre} and {suf} will be omitted if NULL. The fields {s.id}, {s.name}, and {s.npos} will be blank-padded to {idSize}, {nameSize}, and {nposSize} characters, respectively. The field {s.circ} will be printed as "T" or "F". */ msm_seq_desc_t msm_seq_desc_read(FILE *rd, char *pre, char *suf); /* Parses from {rd} a sequence descriptor, in the format "{pre} {id} {name} {level} {npos} {circ} {suf}". If the arguments {pre} and {suf} are not NULL, they must be present in the input. In general, consecutive fields should be separated by one or more spaces. The {name} field and the {pre,suf} arguments must not contain embedded spaces or other formatting chars. The {circ} field should be "T","t","1" for TRUE, "F","f","0" for FALSE. */ #endif