source: tags/ms_r16q3/PROBE_SET/ps_convert_db.cxx

Last change on this file was 11464, checked in by westram, 10 years ago
  • un-dummy-fied transaction (renames only)
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.9 KB
Line 
1// =============================================================== //
2//                                                                 //
3//   File      : ps_convert_db.cxx                                 //
4//   Purpose   :                                                   //
5//                                                                 //
6//   Coded by Wolfram Foerster in October 2002                     //
7//   Institute of Microbiology (Technical University Munich)       //
8//   http://www.arb-home.de/                                       //
9//                                                                 //
10// =============================================================== //
11
12#include "ps_tools.hxx"
13#include "ps_database.hxx"
14#include "ps_pg_tree_functions.hxx"
15#include "ps_pg_specmap.hxx"
16
17#include <sys/times.h>
18
19
20//  GLOBALS
21
22static PS_NodePtr __ROOT;
23static int        __PROBE_LENGTH;
24static SpeciesID  __MIN_ID;
25static SpeciesID  __MAX_ID;
26
27static void PS_detect_probe_length(GBDATA *_ARB_node) {
28    //  recursively walk through database to first probe and get its length
29    __PROBE_LENGTH = -1;
30
31    // search for a probe
32    while (__PROBE_LENGTH < 0) {
33        GBDATA *ARB_group = GB_entry(_ARB_node, "group");
34        if (ARB_group) {                                    // ps_node has probes
35            GBDATA *probe = PG_get_first_probe(ARB_group);
36            __PROBE_LENGTH = strlen(PG_read_probe(probe));
37        }
38        else {                                            // ps_node has no probes .. check its children
39            GBDATA *ARB_child = PS_get_first_node(_ARB_node);
40            while (ARB_child && (__PROBE_LENGTH < 0)) {
41                PS_detect_probe_length(ARB_child);
42                ARB_child = PS_get_next_node(ARB_child);
43            }
44        }
45    }
46}
47
48PS_NodePtr PS_assert_inverse_path(const int  _max_depth, const int  _caller_ID, IDVector  *_path) {
49    //  walk down the 'inverse path' creating empty nodes as necessary
50
51    PS_NodePtr current_node = __ROOT;
52    SpeciesID  current_ID;
53
54    // handle given path
55    int c = 0;
56    for (IDVectorCIter i = _path->begin(); i != _path->end(); ++i, ++c) {
57        current_ID   = *i;
58        current_node = current_node->assertChild(current_ID);
59    }
60
61    // handle implicit path
62    c = 0;
63    for (current_ID = _caller_ID+1; current_ID <= _max_depth; ++current_ID, ++c) {
64        current_node = current_node->assertChild(current_ID);
65    }
66
67    return current_node;
68}
69
70PS_NodePtr PS_assert_path(const int  _caller_ID, IDVector *_path) {
71    //  walk down the 'path' creating empty nodes as necessary
72
73    PS_NodePtr current_node = __ROOT;
74    SpeciesID  next_path_ID;
75
76    // handle given path
77    int c = 0;
78    IDVectorCIter i = _path->begin();
79    next_path_ID = (i == _path->end()) ? -1 : *i;
80    for (SpeciesID current_ID = __MIN_ID; current_ID <= _caller_ID; ++current_ID, ++c) {
81        if (current_ID != next_path_ID) {
82            current_node = current_node->assertChild(current_ID);
83        }
84        else {
85            ++i;
86            next_path_ID = (i == _path->end()) ? -1 : *i;
87        }
88    }
89
90    return current_node;
91}
92
93void PS_extract_probe_data(GBDATA *_ARB_node,                // position in ARB database
94                               int  _max_depth,              // count of species in ARB database
95                               int  _depth,                  // current depth in tree
96                         const int  _parent_ID,              // SpeciesID of parent node
97                          IDVector *_inverse_path) {         // list with IDs of the 'inverse path'
98
99    //  recursively walk through ARB-database and extract probe-data to own tree format
100    //
101    //  * Insertion of nodes takes place after a branch is completed (that is
102    //    when ive reached a leaf in the ARB-database and im going 'back up'
103    //    out of the recursion).
104    //
105    //  * Branches below _max_depth/2 will be moved up top by inserting nodes with
106    //    'inverse' probes in the  'inverse' branch, therefore the _inverse_path
107    //    list is maintained with the SpeciesIDs of the 'inverse path'.
108    //    - SpeciesIDs between _parent_ID and current ID are 'missing' in the path
109    //      and are appended to the _inverse_path list
110    //    - SpeciesIDs greater than the current ID are implicit in the
111    //      'inverse path' list and therefore not stored
112
113    //
114    // get SpeciesID
115    //
116    GBDATA     *data   = GB_entry(_ARB_node, "num");
117    const char *buffer = GB_read_char_pntr(data);
118    SpeciesID   id     = atoi(buffer);
119
120    //
121    // get probe(s)
122    //
123    PS_ProbeSetPtr  probes    = 0;
124    GBDATA         *ARB_group = GB_entry(_ARB_node, "group"); // access probe-group
125    if (ARB_group) {
126        data = PG_get_first_probe(ARB_group);                         // get first probe if exists
127
128        if (data) probes = new PS_ProbeSet;                           // new probe set if probes exist
129
130        while (data) {
131            buffer                = PG_read_probe(data);              // get probe string
132            PS_ProbePtr new_probe(new PS_Probe);                      // make new probe
133            new_probe->length     = __PROBE_LENGTH;                   // set probe length
134            new_probe->quality    = 100;                              // set probe quality
135            new_probe->GC_content = 0;                                // eval probe for GC-content
136            for (int i=0; i < __PROBE_LENGTH; ++i) {
137                if ((buffer[i] == 'C') || (buffer[i] == 'G')) ++(new_probe->GC_content);
138            }
139            probes->insert(new_probe);                                // append probe to probe set
140            data = PG_get_next_probe(data);                           // get next probe
141        }
142    }
143
144    //
145    // enlarge inverse path
146    //
147    for (int i=_parent_ID+1; ((i < id) && (i >= 0)); ++i) {
148        _inverse_path->push_back(i);
149    }
150
151    //
152    // insertion if ARB_node had probes
153    //
154    if (probes) {
155        if (_depth <= (_max_depth >> 1)) {
156            //
157            // insert if 'above' half depth
158            //
159            PS_NodePtr current_node = PS_assert_path(id, _inverse_path);
160            current_node->addProbes(probes->begin(), probes->end());
161        }
162        else {
163            //
164            // insert if 'below' half depth
165            //
166            PS_NodePtr current_node = PS_assert_inverse_path(_max_depth, id, _inverse_path);
167            current_node->addProbesInverted(probes->begin(), probes->end());
168        }
169    }
170
171    //
172    // child(ren)
173    //
174    GBDATA *ARB_child = PS_get_first_node(_ARB_node);                 // get first child if exists
175    while (ARB_child) {
176        PS_extract_probe_data(ARB_child, _max_depth, _depth+1, id, _inverse_path);
177        ARB_child = PS_get_next_node(ARB_child);
178    }
179
180    //
181    // shrink inverse path
182    //
183    while ((_inverse_path->back() > _parent_ID) && (!_inverse_path->empty())) {
184        _inverse_path->pop_back();
185    }
186}
187
188
189int main(int  _argc,
190          char *_argv[]) {
191
192    GBDATA   *gb_main = 0;
193    GB_ERROR  error    = 0;
194
195    // open probe-group-database
196    if (_argc < 2) {
197        printf("Missing arguments\n Usage %s <input database name>\n", _argv[0]);
198        printf("output database will be named like input database but with the suffix '.wf' instead of '.arb'\n");
199        exit(1);
200    }
201
202    const char *DB_name  = _argv[1];
203
204    //
205    // open and check ARB database
206    //
207    struct tms before;
208    times(&before);
209    printf("Opening probe-group-database '%s'..\n  ", DB_name);
210    gb_main = GB_open(DB_name, "rwcN");
211    if (!gb_main) {
212        error = GB_await_error();
213        GB_warning(error);
214        exit(1);
215    }
216    printf("..loaded database (enter to continue)  ");
217    PS_print_time_diff(&before);
218
219    GB_transaction ta(gb_main);
220    GBDATA *group_tree = GB_entry(gb_main, "group_tree");
221    if (!group_tree) {
222        printf("no 'group_tree' in database\n");
223        error = GB_export_error("no 'group_tree' in database"); // @@@ error is unused
224        exit(1);
225    }
226    GBDATA *first_level_node = PS_get_first_node(group_tree);
227    if (!first_level_node) {
228        printf("no 'node' found in group_tree\n");
229        error = GB_export_error("no 'node' found in group_tree"); // @@@ error is unused
230        exit(1);
231    }
232
233    //
234    // read Name <-> ID mappings
235    //
236    times(&before);
237    printf("init Species <-> ID - Map\n");
238    PG_initSpeciesMaps(gb_main);
239    int species_count = PG_NumberSpecies();
240    printf("%i species in the map ", species_count);
241    if (species_count >= 10) {
242        printf("\nhere are the first 10 :\n");
243        int count = 0;
244        for (ID2NameMapCIter i=__ID2NAME_MAP.begin(); count<10; ++i, ++count) {
245            printf("[ %2i ] %s\n", i->first, i->second.c_str());
246        }
247    }
248    __MIN_ID = __ID2NAME_MAP.begin()->first;
249    __MAX_ID = __ID2NAME_MAP.rbegin()->first;
250    printf("IDs %i .. %i\n(enter to continue)  ", __MIN_ID, __MAX_ID);
251    PS_print_time_diff(&before);
252
253    //
254    // create output database
255    //
256    string output_DB_name(DB_name);
257    size_t suffix_pos = output_DB_name.rfind(".arb");
258    if (suffix_pos != string::npos) {
259        output_DB_name.erase(suffix_pos);
260    }
261    output_DB_name.append(".wf");
262    if (suffix_pos == string::npos) {
263        printf("cannot find suffix '.arb' in database name '%s'\n", DB_name);
264        printf("output file will be named '%s'\n", output_DB_name.c_str());
265    }
266    PS_Database *ps_db = new PS_Database(output_DB_name.c_str(), PS_Database::WRITEONLY);
267
268    //
269    // copy mappings
270    //
271    ps_db->setMappings(__NAME2ID_MAP, __ID2NAME_MAP);
272
273    //
274    // extract data from ARB database
275    //
276    times(&before);
277    printf("extracting probe-data...\n");
278    PS_detect_probe_length(group_tree);
279    printf("probe_length = %d\n", __PROBE_LENGTH);
280
281    __ROOT           = ps_db->getRootNode();
282    first_level_node = PS_get_first_node(group_tree);
283    unsigned int  c  = 0;
284    IDVector *inverse_path = new IDVector;
285    struct tms before_first_level_node;
286    for (; first_level_node; ++c) {
287        if (c % 100 == 0) {
288            times(&before_first_level_node);
289            printf("1st level node #%u  ", c+1);
290        }
291        PS_extract_probe_data(first_level_node, species_count, 0, __MIN_ID-1, inverse_path);
292        first_level_node = PS_get_next_node(first_level_node);
293        if (c % 100 == 0) {
294            PS_print_time_diff(&before_first_level_node, "this node ", "  ");
295            PS_print_time_diff(&before, "total ", "\n");
296        }
297    }
298    printf("done after %u 1st level nodes\n", c);
299    printf("(enter to continue)  ");
300    PS_print_time_diff(&before);
301
302    //
303    // write database to file
304    //
305    times(&before);
306    printf("writing probe-data to %s..\n", output_DB_name.c_str());
307    ps_db->save();
308    printf("..done saving (enter to continue)  ");
309    PS_print_time_diff(&before);
310
311    delete inverse_path;
312    delete ps_db;
313    before.tms_utime = 0;
314    before.tms_stime = 0;
315    printf("total ");
316    PS_print_time_diff(&before);
317    return 0;
318}
Note: See TracBrowser for help on using the repository browser.