source: branches/port5/TOOLS/arb_primer.cxx

Last change on this file was 5827, checked in by westram, 16 years ago
  • GBS_hash_do_loop() and GBS_hash_do_sorted_loop() now always take a 'client_data' param
  • fixed error handling in several functions
  • fixed memory leaks in GBS_merge_tagged_strings and GBS_string_eval_tagged_string
  • removed several globals
    • gbs_save_hash_strstruct
    • g_bs_merge_result, g_bs_merge_sub_result, g_bs_collect_tags_hash
    • gbs_scan_db_data
    • isits (parsimony)
    • st_delete_species_st_ml
  • global 'nt' → GLOBAL_NT
  • global_combineCount → AP_sequence::global_combineCount
  • filter params changed from AW_CL to adfiltercbstruct* where possible
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.0 KB
Line 
1#include <stdio.h>
2#include <stdlib.h>
3// #include <malloc.h>
4#include <string.h>
5#include <arbdb.h>
6#include <arbdbt.h>
7
8#define ADD_LEN        10
9#define PRM_HASH_SIZE  1024
10#define PRM_HASH2_SIZE 512
11#define PRM_BUFFERSIZE 256
12
13
14struct arb_prm_struct {
15    char    **alignment_names;
16    int       al_len;
17    int       max_name;
18    GBDATA   *gb_main;
19    char      buffer[PRM_BUFFERSIZE];
20    char     *source;
21    int       prmanz;
22    int       prmlen;
23    int       prmsmin;
24    GB_HASH  *hash;
25    char    **data;
26    int       sp_count;
27    int       key_cnt;
28    int       one_key_cnt;
29    int       reduce;
30    FILE     *out;
31    char     *outname;
32} aprm;
33
34
35void arb_prm_menu()
36{
37    char **alignment_name;
38    int i;
39    printf(" Please select an Alignment:\n");
40    for (   alignment_name = aprm.alignment_names,i=1;
41            *alignment_name;
42            alignment_name++,i++){
43        printf("%i: %s\n",i,*alignment_name);
44    }
45    aprm.max_name = i;
46    fgets(aprm.buffer, PRM_BUFFERSIZE, stdin);
47    i = atoi(aprm.buffer);
48    if ((i<1) || (i>=aprm.max_name)) {
49        printf ("ERROR: select %i out of range\n",i);
50        exit(-1);
51    }
52    aprm.source = aprm.alignment_names[i-1];
53    printf( "This module will search for primers for all positions.\n"
54            "   The best result is one primer for all (marked) taxa , the worst case\n"
55            "   are n primers for n taxa.\n"
56            "   Please specify the maximum number of primers:\n"
57            );
58    fgets(aprm.buffer, PRM_BUFFERSIZE, stdin);
59    i = atoi(aprm.buffer);
60    aprm.prmanz = i;
61    printf( "Select minimum length of a primer, the maximum will be (minimum + %i)\n",
62            ADD_LEN);
63    fgets(aprm.buffer, PRM_BUFFERSIZE, stdin);
64    i = atoi(aprm.buffer);
65    if ((i<4) || (i>30)) {
66        printf ("ERROR: select %i out of range\n",i);
67        exit(-1);
68    }
69    aprm.prmlen = i;
70
71    printf( "There may be short sequences or/and deletes in full sequences\n"
72            "   So a primer normally does not match all sequences\n"
73            "   Specify minimum percentage of species (0-100 %%):\n");
74    fgets(aprm.buffer, PRM_BUFFERSIZE, stdin);
75    i = atoi(aprm.buffer);
76    if ((i<1) || (i>100)) {
77        printf ("ERROR: select %i out of range\n",i);
78        exit(-1);
79    }
80    aprm.prmsmin = i;
81
82    printf( "Write output to file (enter \"\" to write to screen)\n");
83    fgets(aprm.buffer, PRM_BUFFERSIZE, stdin);
84    aprm.outname = strdup(aprm.buffer);
85}
86
87char *arb_prm_read(int /*prmanz*/)
88{
89    GBDATA     *gb_presets;
90    GBDATA     *gb_source;
91    GBDATA     *gb_species;
92    GBDATA     *gb_source_data;
93    GBDATA     *gb_len;
94    int         sp_count;
95    char       *data;
96    const char *hdata;
97
98    gb_presets = GB_entry(aprm.gb_main,"presets");
99
100    gb_source = GB_find_string(gb_presets,"alignment_name",aprm.source,GB_IGNORE_CASE,down_2_level);
101    gb_len = GB_brother(gb_source,"alignment_len");
102    aprm.al_len = GB_read_int(gb_len);
103
104
105    sp_count = GBT_count_marked_species(aprm.gb_main);
106
107    aprm.data = (char **)calloc(sp_count,sizeof(char *));
108    sp_count = 0;
109    for (   gb_species = GBT_first_marked_species(aprm.gb_main);
110            gb_species;
111            gb_species = GBT_next_marked_species(gb_species) ){
112
113        gb_source = GB_entry(gb_species,aprm.source);
114        if (!gb_source) continue;
115        gb_source_data = GB_entry(gb_source,"data");
116        if (!gb_source_data) continue;
117        data = (char *)calloc(sizeof(char),aprm.al_len+1);
118        hdata = GB_read_char_pntr(gb_source_data);
119        if (!hdata) {
120            GB_print_error();
121            continue;
122        }
123        aprm.data[sp_count ++] = data;
124        if (sp_count %50 == 0)  printf("Reading taxa %i\n",sp_count);
125        {
126            int i,size;char c;
127            size = GB_read_string_count(gb_source_data);
128            for (i=0;i<size;i++) {
129                c = hdata[i];
130                if ( (c>='a') && (c<='z'))
131                    data[i] = c-'a'+'A';
132                else
133                    data[i] = c;
134            }
135            for (i=i ; i < aprm.al_len; i++) data[i] = '.';
136        }
137    }
138    printf("%i taxa read\n",sp_count);
139    aprm.sp_count = sp_count;
140    if (sp_count ==0) {
141        exit(0);
142    }
143    return 0;
144}
145
146long arb_count_keys(const char */*key*/,long val, void *)
147{
148    if (val >1) {
149        aprm.key_cnt++;
150    }else{
151        aprm.one_key_cnt++;
152    }
153    return val;
154}
155
156long arb_print_primer(const char *key,long val, void *)
157{
158    if (val <=1) return val;
159    int gc = 0;
160    const char *p;
161    for (p = key; *p; p++) {
162        if (*p == 'G' || *p== 'C') gc++;
163    }
164    fprintf(aprm.out,"  %s matching %4li taxa     GC = %3i%%\n",
165            key,val,100*gc/(int)strlen(key));
166    return val;
167}
168
169#define is_base(c) ( ((c>='a') && (c<='z')) || ( (c>='A')&&(c<='Z') ) )
170
171int primer_print(char *dest,char * source,int size)
172{
173    char c;
174    c = *(source++);
175    if (!is_base(c)) return 1;
176    while (size){
177        while (!is_base(c)) c=*(source++);
178        if ( c == 'N' || c == 'n' ) return 1;
179        *(dest++) = c;
180        size--;
181        if (!c) return 1;
182        c = 0;
183    }
184    *dest = 0;
185    return 0;
186}
187
188long arb_reduce_primer_len(const char *key,long val, void *)
189{
190    static char buffer[256];
191    int size = strlen(key)-aprm.reduce;
192    strncpy(buffer,key,size);
193    buffer[size] = 0;
194    val += GBS_read_hash(aprm.hash,buffer);
195    GBS_write_hash(aprm.hash,buffer,val);
196    return val;
197}
198
199void arb_prm_primer(int /*prmanz*/)
200{
201    GB_HASH *hash;
202    GB_HASH *mhash;
203    int      sp;
204    //  int             len;
205    char    *buffer;
206    int      pos;
207    int      prmlen;
208    int      pspecies;
209
210    int cutoff_cnt;
211
212    int *best_primer_cnt;
213    int *best_primer_new;
214    int *best_primer_swap;
215    //  int     newlen;
216
217    prmlen = aprm.prmlen + ADD_LEN;
218
219    buffer = (char *) calloc(sizeof(char), prmlen + 1);
220    best_primer_cnt = (int *)calloc(prmlen+1,sizeof(int));
221    best_primer_new = (int *)calloc(prmlen+1,sizeof(int));
222
223    for (pos = 0; pos < aprm.al_len; pos++) {
224        prmlen = aprm.prmlen + ADD_LEN;
225        mhash = GBS_create_hash(PRM_HASH_SIZE, GB_MIND_CASE);
226        pspecies = 0;
227        if (pos % 50 == 0) printf("Pos. %i (%i)\n",pos,aprm.al_len);
228        cutoff_cnt = aprm.prmanz+1;
229        for (sp = 0; sp < aprm.sp_count; sp++) {    /* build initial hash table */
230            if (!primer_print(buffer, aprm.data[sp] + pos, prmlen)) {
231                GBS_incr_hash(mhash, buffer);
232                pspecies++;
233            }
234        }
235        if (pspecies*100 >= aprm.prmsmin * aprm.sp_count ) {    /* reduce primer length */
236            for (hash = mhash; prmlen >= aprm.prmlen; prmlen-=aprm.reduce) {
237                hash = GBS_create_hash(aprm.prmanz*2, GB_MIND_CASE);
238                aprm.hash = hash;
239
240                aprm.key_cnt = 0;
241                aprm.one_key_cnt = 0;
242                GBS_hash_do_loop(mhash, arb_count_keys, NULL);
243                if ((aprm.key_cnt + aprm.one_key_cnt < cutoff_cnt) &&
244                    //  (aprm.key_cnt > aprm.one_key_cnt) &&
245                    (aprm.key_cnt<best_primer_cnt[prmlen+1])){
246                    fprintf(aprm.out,"%3i primer found len %3i(of %4i taxa) for position %i\n", aprm.key_cnt, prmlen, pspecies, pos);
247                    GBS_hash_do_loop(mhash, arb_print_primer, NULL);
248                    fprintf(aprm.out,"\n\n");
249                    cutoff_cnt = aprm.key_cnt;
250                }
251                best_primer_new[prmlen] = aprm.key_cnt;
252                aprm.reduce = 1;
253                while (aprm.key_cnt > aprm.prmanz*4){
254                    aprm.key_cnt/=4;
255                    aprm.reduce++;
256                }
257                GBS_hash_do_loop(mhash,arb_reduce_primer_len, NULL);
258                GBS_free_hash(mhash);
259                mhash = hash;
260            }
261        }else{
262            for (;prmlen>0;prmlen--) best_primer_new[prmlen] = aprm.prmanz+1;
263        }
264        GBS_free_hash(mhash);
265        best_primer_swap = best_primer_new;
266        best_primer_new = best_primer_cnt;
267        best_primer_cnt = best_primer_swap;
268        mhash = 0;
269    }
270
271}
272
273int main(int argc, char **/*argv*/)
274{
275    char *error;
276    const char *path;
277    if (argc != 1) {
278        fprintf(stderr,"no parameters\n");
279        printf(" Converts RNA or DNA Data to Pro\n");
280        exit(-1);
281    }
282    path = ":";
283    aprm.gb_main = GB_open(path,"r");
284    if (!aprm.gb_main){
285        fprintf(stderr,"ERROR cannot find server\n");
286        exit(-1);
287    }
288    GB_begin_transaction(aprm.gb_main);
289    aprm.alignment_names = GBT_get_alignment_names(aprm.gb_main);
290    GB_commit_transaction(aprm.gb_main);
291    arb_prm_menu();
292    GB_begin_transaction(aprm.gb_main);
293    error = arb_prm_read(aprm.prmanz);
294    if (error) {
295        printf("ERROR: %s\n",error);
296        exit(0);
297    }
298    GB_commit_transaction(aprm.gb_main);
299    if (strlen(aprm.outname)) {
300        aprm.out = fopen(aprm.outname,"w");
301        if (!aprm.out) {
302            printf("Cannot open outfile\n");
303            exit (-1);
304        }
305        arb_prm_primer(aprm.prmanz);
306        fclose(aprm.out);
307    }else{
308        aprm.out = stdout;
309        arb_prm_primer(aprm.prmanz);
310    }
311    return 0;
312}
Note: See TracBrowser for help on using the repository browser.