source: branches/stable/PROBE/probe.h

Last change on this file was 16763, checked in by westram, 6 years ago
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.8 KB
Line 
1#ifndef PROBE_H
2#define PROBE_H
3
4#ifndef __LIST__
5#include <list>
6#endif
7#ifndef __SET__
8#include <set>
9#endif
10
11#ifndef ARBDB_H
12#include <arbdb.h>
13#endif
14#ifndef PT_COM_H
15#include <PT_com.h>
16#endif
17#ifndef AISC_GEN_SERVER_INCLUDED
18#include <PT_server.h>
19#endif
20#ifndef PT_TOOLS_H
21#include "PT_tools.h"
22#endif
23#ifndef CACHE_H
24#include <cache.h>
25#endif
26
27#define PT_SERVER_MAGIC   0x32108765                // pt server identifier
28#define PT_SERVER_VERSION 3                         // version of pt server database (no versioning till 2009/05/13)
29
30#if defined(DEBUG)
31// # define PTM_DEBUG_NODES
32# define PTM_DEBUG_STAGE_ASSERTIONS
33// # define PTM_DEBUG_VALIDATE_CHAINS
34#endif // DEBUG
35
36#define CALCULATE_STATS_ON_QUERY
37
38#if defined(PTM_DEBUG_STAGE_ASSERTIONS)
39#define pt_assert_stage(s) pt_assert(psg.get_stage() == (s))
40#else // !defined(PTM_DEBUG_STAGE_ASSERTIONS)
41#define pt_assert_stage(s)
42#endif
43
44#if defined(PTM_DEBUG_VALIDATE_CHAINS)
45#define pt_assert_valid_chain_stage1(node) pt_assert(PT_chain_has_valid_entries<ChainIteratorStage1>(node))
46#else // !defined(PTM_DEBUG_VALIDATE_CHAINS)
47#define pt_assert_valid_chain_stage1(node)
48#endif
49
50typedef unsigned long ULONG;
51typedef unsigned int  UINT;
52typedef unsigned char uchar;
53
54#define PT_MAX_PARTITION_DEPTH 4
55
56#define PT_POS_TREE_HEIGHT 20
57#define PT_MIN_TREE_HEIGHT PT_MAX_PARTITION_DEPTH
58
59#define MIN_PROBE_LENGTH 2
60
61enum PT_MATCH_TYPE {
62    PT_MATCH_TYPE_INTEGER           = 0,
63    PT_MATCH_TYPE_WEIGHTED_PLUS_POS = 1,
64    PT_MATCH_TYPE_WEIGHTED          = -1
65};
66
67
68
69#define MATCHANSWER  50                             // private msg type: match result answer
70#define CREATEANSWER 51                             // private msg type: create result answer
71#define FINDANSWER   52                             // private msg type: find result answer
72
73extern int gene_flag;           // if 'gene_flag' == 1 -> we are a gene pt server
74struct Hs_struct;
75
76enum type_types {
77    t_int    = 1,
78    t_string = 0,
79    t_float  = 2
80};
81
82enum PT_base {
83    PT_QU = 0,
84    PT_N  = 1,
85    PT_A,
86    PT_C,
87    PT_G,
88    PT_T,
89    PT_BASES,
90    PT_B_UNDEF,
91};
92
93CONSTEXPR_INLINE bool is_std_base     (char b) { return b >= PT_A && b <= PT_T; }
94CONSTEXPR_INLINE bool is_std_base_or_N(char b) { return b >= PT_N && b <= PT_T; }
95CONSTEXPR_INLINE bool is_ambig_base   (char b) { return b == PT_QU || b == PT_N; }
96CONSTEXPR_INLINE bool is_valid_base   (char b) { return b >= PT_QU && b < PT_BASES; }
97
98CONSTEXPR_INLINE char base_2_readable(char base) {
99    return base<PT_BASES ? ".NACGU"[safeCharIndex(base)] : base;
100}
101
102inline char *probe_2_readable(char *id_string, int len) {
103    //! translate a string containing PT_base into readable characters.
104    // caution if 'id_string' contains PT_QU ( == zero == EOS).
105    // (see also: probe_compress_sequence)
106    for (int i = 0; i<len; ++i) {
107        id_string[i] = base_2_readable(id_string[i]);
108    }
109    return id_string;
110}
111
112inline void reverse_probe(char *seq, int len) {
113    int i = 0;
114    int j = len-1;
115
116    while (i<j) std::swap(seq[i++], seq[j--]);
117}
118
119struct POS_TREE1;
120struct POS_TREE2;
121
122enum Stage { STAGE1, STAGE2 };
123
124// ---------------------
125//      Probe search
126
127class probe_input_data : virtual Noncopyable { // every taxa's own data
128    int     size;       // @@@ misleading (contains 1 if no bases in sequence)
129    GBDATA *gb_species;
130    bool    group;      // probe_design: whether species is in group
131
132    typedef SmartArrayPtr(int) SmartIntPtr;
133
134    mutable cache::CacheHandle<SmartCharPtr> seq;
135    mutable cache::CacheHandle<SmartIntPtr>  rel2abs;
136
137    static cache::Cache<SmartCharPtr> seq_cache;
138    static cache::Cache<SmartIntPtr>  rel2abs_cache;
139
140    SmartCharPtr loadSeq() const {
141        GB_transaction ta(gb_species);
142        GBDATA *gb_compr = GB_entry(gb_species, "compr");
143        return SmartCharPtr(GB_read_bytes(gb_compr));
144    }
145
146public:
147
148    probe_input_data()
149        : size(0),
150          gb_species(NULp),
151          group(false)
152    {}
153    ~probe_input_data() {
154        seq.release(seq_cache);
155        rel2abs.release(rel2abs_cache);
156    }
157
158    static void set_cache_sizes(size_t seq_cache_size, size_t abs_cache_size) {
159        seq_cache.resize(seq_cache_size);
160        rel2abs_cache.resize(abs_cache_size);
161    }
162
163    GB_ERROR init(GBDATA *gb_species_);
164
165    SmartCharPtr get_dataPtr() const {
166        if (!seq.is_cached()) seq.assign(loadSeq(), seq_cache);
167        return seq.access(seq_cache);
168    }
169
170    const char *get_shortname() const {
171        GB_transaction ta(gb_species);
172
173        GBDATA *gb_name = GB_entry(gb_species, "name");
174        pt_assert(gb_name);
175        return GB_read_char_pntr(gb_name);
176    }
177    const char *get_fullname() const {
178        GB_transaction ta(gb_species);
179
180        GBDATA *gb_full = GB_entry(gb_species, "full_name");
181        return gb_full ? GB_read_char_pntr(gb_full) : "";
182    }
183
184    const char *get_acc() const {
185        GB_transaction ta(gb_species);
186
187        GBDATA *gb_acc = GB_entry(gb_species, "acc");
188        pt_assert(gb_acc);
189        return gb_acc ? GB_read_char_pntr(gb_acc) : NULp;
190    }
191    int get_start() const {
192        GB_transaction ta(gb_species);
193
194        GBDATA *gb_start = GB_entry(gb_species, "start");
195        return gb_start ? GB_read_int(gb_start) : 0;
196    }
197    int get_stop() const {
198        GB_transaction ta(gb_species);
199
200        GBDATA *gb_stop = GB_entry(gb_species, "stop");
201        return gb_stop ? GB_read_int(gb_stop) : 0;
202    }
203
204    long get_checksum() const { // @@@ change return-type -> uint32_t
205        GB_transaction ta(gb_species);
206        GBDATA *gb_cs = GB_entry(gb_species, "cs");
207        pt_assert(gb_cs);
208        uint32_t csum = uint32_t(GB_read_int(gb_cs));
209        return csum;
210    }
211    int get_size() const { return size; }
212
213    bool valid_rel_pos(int rel_pos) const { // returns true if rel_pos is inside sequence
214        return rel_pos >= 0 && rel_pos<get_size();
215    }
216
217    bool inside_group() const { return group; }
218    bool outside_group() const { return !group; }
219
220    void set_group_state(bool isGroupMember) { group = isGroupMember; }
221
222    long get_geneabspos() const {
223        pt_assert(gene_flag); // only legal in gene-ptserver
224        GBDATA *gb_pos = GB_entry(gb_species, "abspos");
225        if (gb_pos) return GB_read_int(gb_pos);
226        return -1;
227    }
228
229    void preload_rel2abs() const {
230        if (!rel2abs.is_cached()) {
231            GB_transaction ta(gb_species);
232
233            GBDATA *gb_baseoff = GB_entry(gb_species, "baseoff");
234            pt_assert(gb_baseoff);
235
236            const GB_CUINT4 *baseoff = GB_read_ints_pntr(gb_baseoff);
237
238            int *r2a = new int[size];
239
240            int abs = 0;
241            for (int rel = 0; rel<size; ++rel) {
242                abs      += baseoff[rel];
243                r2a[rel]  = abs;
244            }
245
246            rel2abs.assign(r2a, rel2abs_cache);
247        }
248    }
249    size_t get_abspos(size_t rel_pos) const {
250        pt_assert(rel2abs.is_cached()); // you need to call preload_rel2abs
251        return (&*rel2abs.access(rel2abs_cache))[rel_pos]; // @@@ brute-forced
252    }
253
254    size_t calc_relpos(int abs_pos) const { // expensive
255        preload_rel2abs();
256        SmartIntPtr  rel2abs_ptr = rel2abs.access(rel2abs_cache);
257        const int   *r2a     = &*rel2abs_ptr;
258
259        int l = 0;
260        int h = get_size()-1;
261
262        if (r2a[l] == abs_pos) return l;
263        if (r2a[h] == abs_pos) return h;
264
265        while (l<h) {
266            int m = (l+h)/2;
267            if (r2a[m]<abs_pos) {
268                l = m;
269            }
270            else if (r2a[m]>abs_pos) {
271                h = m;
272            }
273            else {
274                return m;
275            }
276        }
277        return l;
278    }
279};
280
281struct probe_statistic_struct {
282    // common
283    int cut_offs;                                   // statistic of chains
284    int single_node;
285    int short_node;
286    int long_node;
287    int longs;
288    int shorts;
289    int shorts2;
290    int chars;
291
292#ifdef ARB_64
293    // 64bit specials
294    int  int_node;
295    int  ints;
296    int  ints2;
297    long maxdiff;
298#endif
299
300    void setup();
301};
302
303class BI_ecoli_ref;
304
305class MostUsedPos : virtual Noncopyable {
306    int pos;
307    int used;
308
309    MostUsedPos *next;
310
311    void swapWith(MostUsedPos *other) {
312        std::swap(pos, other->pos);
313        std::swap(used, other->used);
314    }
315
316public:
317    MostUsedPos() : pos(0), used(0), next(NULp) { }
318    MostUsedPos(int p) : pos(p), used(1), next(NULp) { }
319    ~MostUsedPos() { delete next; }
320
321    void clear() {
322        pos  = 0;
323        used = 0;
324        delete next;
325        next = NULp;
326    }
327
328    void announce(int p) {
329        if (p == pos) used++;
330        else {
331            if (next) next->announce(p);
332            else next = new MostUsedPos(p);
333            if (next->used>used) swapWith(next);
334        }
335    }
336
337
338    int get_most_used() const { return pos; }
339};
340
341class probe_struct_global {
342    Stage stage;
343
344    union {
345        POS_TREE1 *p1;
346        POS_TREE2 *p2;
347    } pt;
348
349public:
350    GB_shell *gb_shell;
351    GBDATA   *gb_main;                              // ARBDB interface
352    char     *alignment_name;
353    GB_HASH  *namehash;                             // name to int
354
355    int                      data_count;
356    struct probe_input_data *data;                  // the internal database
357
358    char         *ecoli;                            // the ecoli sequenz
359    BI_ecoli_ref *bi_ecoli;
360
361    int  max_size;                                  // maximum sequence len
362    long char_count;                                // number of all 'acgtuACGTU'
363
364    int reversed;                                   // tell the matcher whether probe is reversed
365
366    double *pos_to_weight;                          // position to weight
367
368    MostUsedPos abs_pos;
369
370    int sort_by;
371
372    char *main_probe;
373
374    char      *server_name;                         // name of this server
375    aisc_com  *link;
376    T_PT_MAIN  main;
377    Hs_struct *com_so;                              // the communication socket
378
379    probe_statistic_struct stat;
380
381    bool big_db; // STAGE2 only (true -> uses 8 bit pointers)
382
383    void setup();
384    void cleanup();
385
386    void enter_stage(Stage stage_);
387    Stage get_stage() const { return stage; }
388
389    POS_TREE1*& TREE_ROOT1() { pt_assert(stage == STAGE1); return pt.p1; }
390    POS_TREE2*& TREE_ROOT2() { pt_assert(stage == STAGE2); return pt.p2; }
391};
392
393extern probe_struct_global psg;
394
395class gene_struct {
396    char       *gene_name;
397    const char *arb_species_name; // pointers into 'gene_name'
398    const char *arb_gene_name;
399
400    void init(const char *gene_name_, const char *arb_species_name_, const char *arb_gene_name_) {
401        int gene_name_len        = strlen(gene_name_);
402        int arb_species_name_len = strlen(arb_species_name_);
403        int arb_gene_name_len    = strlen(arb_gene_name_);
404
405        int fulllen      = gene_name_len+1+arb_species_name_len+1+arb_gene_name_len+1;
406        gene_name        = new char[fulllen];
407        strcpy(gene_name, gene_name_);
408        arb_species_name = gene_name+(gene_name_len+1);
409        strcpy((char*)arb_species_name, arb_species_name_);
410        arb_gene_name    = arb_species_name+(arb_species_name_len+1);
411        strcpy((char*)arb_gene_name, arb_gene_name_);
412    }
413
414public:
415    gene_struct(const char *gene_name_, const char *arb_species_name_, const char *arb_gene_name_) {
416        init(gene_name_, arb_species_name_, arb_gene_name_);
417    }
418    gene_struct(const gene_struct& other) {
419        if (&other != this) {
420            init(other.get_internal_gene_name(), other.get_arb_species_name(), other.get_arb_gene_name());
421        }
422    }
423    gene_struct& operator = (const gene_struct& other) {
424        if (&other != this) {
425            delete [] gene_name;
426            init(other.get_internal_gene_name(), other.get_arb_species_name(), other.get_arb_gene_name());
427        }
428        return *this;
429    }
430
431    ~gene_struct() {
432        delete [] gene_name;
433    }
434
435    const char *get_internal_gene_name() const { return gene_name; }
436    const char *get_arb_species_name() const { return arb_species_name; }
437    const char *get_arb_gene_name() const { return arb_gene_name; }
438};
439
440struct ltByArbName {
441    bool operator()(const gene_struct *gs1, const gene_struct *gs2) const {
442        int cmp           = strcmp(gs1->get_arb_species_name(), gs2->get_arb_species_name());
443        if (cmp == 0) { cmp = strcmp(gs1->get_arb_gene_name(), gs2->get_arb_gene_name()); }
444        return cmp<0;
445    }
446};
447struct ltByInternalName {
448    bool operator()(const gene_struct *gs1, const gene_struct *gs2) const {
449        int cmp = strcmp(gs1->get_internal_gene_name(), gs2->get_internal_gene_name());
450        return cmp<0;
451    }
452};
453
454typedef std::list<gene_struct>                          gene_struct_list;
455typedef std::set<const gene_struct *, ltByInternalName> gene_struct_index_internal;
456typedef std::set<const gene_struct *, ltByArbName>      gene_struct_index_arb;
457
458extern gene_struct_index_arb      gene_struct_arb2internal; // sorted by arb species+gene name
459extern gene_struct_index_internal gene_struct_internal2arb; // sorted by internal name
460
461#else
462#error probe.h included twice
463#endif
464
Note: See TracBrowser for help on using the repository browser.