source: tags/old_import_filter/PROBE_DESIGN/probe_design.cxx

Last change on this file was 10106, checked in by westram, 11 years ago
  • fix a bunch of compiler warnings
    • several NDEBUG warnings (variables only used in DEBUG mode)
    • wrong use of string literals as char*
    • enum type mismatches (AW_VARIABLE_TYPE vs GB_TYPES)
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 78.8 KB
Line 
1// =============================================================== //
2//                                                                 //
3//   File      : probe_design.cxx                                  //
4//   Purpose   :                                                   //
5//                                                                 //
6//   Institute of Microbiology (Technical University Munich)       //
7//   http://www.arb-home.de/                                       //
8//                                                                 //
9// =============================================================== //
10
11#include "SaiProbeVisualization.hxx"
12#include "probe_match_parser.hxx"
13
14#include <PT_com.h>
15#include <client.h>
16#include <servercntrl.h>
17#include <probe_design.hxx>
18
19#include <GEN.hxx>
20#include <TreeCallbacks.hxx>
21
22#include <iupac.h>
23#include <awt_config_manager.hxx>
24#include <awt_sel_boxes.hxx>
25
26#include <aw_awars.hxx>
27#include <aw_preset.hxx>
28#include <aw_select.hxx>
29#include <aw_msg.hxx>
30#include <arb_progress.h>
31#include <aw_root.hxx>
32#include <aw_question.hxx>
33#include <adGene.h>
34#include <arb_strbuf.h>
35#include <arb_file.h>
36
37// general awars
38
39#define AWAR_PROBE_CREATE_GENE_SERVER "tmp/probe_admin/gene_server" // whether to create a gene pt server
40
41// probe match awars
42
43// #define AWAR_PD_MATCH_ITEM     AWAR_SPECIES_NAME
44#define AWAR_PD_SELECTED_MATCH "tmp/probe_design/match"
45#define AWAR_PD_MATCH_RESOLVE  "tmp/probe_design/match_resolve" // for IUPAC resolution
46
47#define AWAR_PD_MATCH_SORTBY     "probe_match/sort_by" // weighted mismatches
48#define AWAR_PD_MATCH_COMPLEMENT "probe_match/complement" // check reverse complement too
49#define AWAR_PD_MATCH_MARKHITS   "probe_match/mark_hits" // mark hitten species in database
50#define AWAR_PD_MATCH_WRITE2TMP  "probe_match/write_2_tmp" // write result to field tmp
51#define AWAR_PD_MATCH_AUTOMATCH  "probe_match/auto_match" // auto match probes when target string changes
52
53#define AWAR_PD_MATCH_NHITS    "tmp/probe_match/nhits" // display the 'number of hits'
54
55// probe design awars
56
57#define AWAR_PD_DESIGN_CLIPRESULT "probe_design/CLIPRESULT" // 'length of output' (how many probes will get designed)
58#define AWAR_PD_DESIGN_MISHIT     "probe_design/MISHIT"     // 'non group hits'
59#define AWAR_PD_DESIGN_MAXBOND    "probe_design/MAXBOND"    // max hairpinbonds ?
60#define AWAR_PD_DESIGN_MINTARGETS "probe_design/MINTARGETS" // 'min. group hits (%)'
61
62#define AWAR_PD_DESIGN_PROBELENGTH  "probe_design/PROBELENGTH" // length of probe
63#define AWAR_PD_DESIGN_MIN_TEMP     "probe_design/MINTEMP"     // temperature (min)
64#define AWAR_PD_DESIGN_MAX_TEMP     "probe_design/MAXTEMP"     // temperature (max)
65#define AWAR_PD_DESIGN_MIN_GC       "probe_design/MINGC"       // GC content (min)
66#define AWAR_PD_DESIGN_MAX_GC       "probe_design/MAXGC"       // GC content (max)
67#define AWAR_PD_DESIGN_MIN_ECOLIPOS "probe_design/MINECOLI"    // ecolipos (min)
68#define AWAR_PD_DESIGN_MAX_ECOLIPOS "probe_design/MAXECOLI"    // ecolipos (max)
69
70#define AWAR_PD_DESIGN_GENE "probe_design/gene" // generate probes for genes ?
71
72// probe design/match (expert window)
73#define AWAR_PD_COMMON_EXP_BONDS "probe_design/bonds/pos"  // prefix for bonds
74#define AWAR_PD_COMMON_EXP_SPLIT "probe_design/SPLIT"
75
76#define AWAR_PD_DESIGN_EXP_DTEDGE "probe_design/DTEDGE"
77#define AWAR_PD_DESIGN_EXP_DT     "probe_design/DT"
78
79#define AWAR_PD_MATCH_NMATCHES   "probe_match/nmatches"
80#define AWAR_PD_MATCH_LIM_NMATCH "probe_match/lim_nmatch"
81#define AWAR_PD_MATCH_MAX_RES    "probe_match/maxres"
82
83// ----------------------------------------
84
85static saiProbeData *g_spd = 0;
86
87static struct {
88    aisc_com          *link;
89    T_PT_LOCS          locs;
90    T_PT_MAIN          com;
91    AW_window_simple  *win;
92    AW_selection_list *resultList; // @@@ replace by TypedSelectionList?
93} PD;
94
95struct ProbeMatchEventParam {
96    GBDATA            *gb_main;
97    AW_selection_list *selection_id;                // may be NULL
98    int               *counter;                     // may be NULL
99
100    ProbeMatchEventParam(GBDATA *gb_main_, int *counter_)         : gb_main(gb_main_), selection_id(NULL), counter(counter_) {}
101    ProbeMatchEventParam(GBDATA *gb_main_, AW_selection_list *id) : gb_main(gb_main_), selection_id(id),   counter(NULL)     {}
102};
103
104struct AutoMatchSettings {
105    AW_window            *aww;
106    ProbeMatchEventParam *event_param; // not owned!
107    bool                  disable;
108
109    AutoMatchSettings(AW_window *aww_, ProbeMatchEventParam *event_param_, bool disable_)
110        : aww(aww_) , event_param(event_param_) , disable(disable_)
111    {}
112    AutoMatchSettings()
113        : aww(NULL), event_param(NULL) , disable(true)
114    {}
115
116    bool initialized() const { return aww != NULL; }
117};
118
119static AutoMatchSettings auto_match_cb_settings;
120
121static void probe_match_event(AW_window *aww, AW_CL cl_ProbeMatchEventParam); // prototype
122
123static void auto_match_cb(AW_root *root) {
124    if (!auto_match_cb_settings.disable) {
125        char *ts = root->awar(AWAR_TARGET_STRING)->read_string();
126        if (strlen(ts) > 0) {
127            probe_match_event(auto_match_cb_settings.aww, (AW_CL)auto_match_cb_settings.event_param);
128        }
129        free(ts);
130    }
131}
132
133static const char *auto_match_sensitive_awars[] = {
134    AWAR_TARGET_STRING,
135    AWAR_PT_SERVER,
136    AWAR_PD_MATCH_COMPLEMENT,
137    AWAR_MAX_MISMATCHES,
138    AWAR_PD_MATCH_SORTBY,
139    0
140};
141
142static void auto_match_changed(AW_root *root) {
143    static bool callback_active = false;
144    int         autoMatch       = root->awar(AWAR_PD_MATCH_AUTOMATCH)->read_int();
145
146    if (autoMatch) {
147        if (!callback_active) {
148            for (int i = 0; auto_match_sensitive_awars[i]; ++i) {
149                root->awar(auto_match_sensitive_awars[i])->add_callback(auto_match_cb);
150            }
151        }
152    }
153    else {
154        if (callback_active) {
155            for (int i = 0; auto_match_sensitive_awars[i]; ++i) {
156                root->awar(auto_match_sensitive_awars[i])->remove_callback(auto_match_cb);
157            }
158        }
159    }
160    callback_active = bool(autoMatch);
161}
162
163static void enable_auto_match_cb(AW_root *root, AW_window *aww, ProbeMatchEventParam *event_param) {
164    if (event_param == NULL && auto_match_cb_settings.initialized()) {
165        // "partially" enable (w/o ProbeMatchEventParam) is only done
166        // if not already "fully enabled"
167        return;
168    }
169
170    auto_match_cb_settings = AutoMatchSettings(aww, event_param, false);
171    auto_match_changed(root);
172}
173
174static void popup_match_window_cb(AW_window *aww, AW_CL cl_gb_main) { // @@@ shall be called by auto_match_cb (if never opened b4)
175    AW_root   *root         = aww->get_root();
176    AW_window *match_window = create_probe_match_window(root, cl_gb_main);
177    match_window->activate();
178    root->awar(AWAR_TARGET_STRING)->touch(); // force re-match
179}
180
181// --------------------------------------------------------------------------------
182
183static void popup_probe_design_result_window(AW_window *aww, AW_CL cl_gb_main) {
184    if (!PD.win) {
185        AW_root *root = aww->get_root();
186
187        PD.win = new AW_window_simple;
188        PD.win->init(root, "PD_RESULT", "PD RESULT");
189        PD.win->load_xfig("pd_reslt.fig");
190
191        PD.win->button_length(6);
192        PD.win->auto_space(10, 10);
193
194        PD.win->at("help");
195        PD.win->callback(AW_POPUP_HELP, (AW_CL)"probedesignresult.hlp");
196        PD.win->create_button("HELP", "HELP", "H");
197
198        PD.win->at("result");
199        PD.resultList = PD.win->create_selection_list(AWAR_TARGET_STRING, 40, 5);
200        const StorableSelectionList *storable_result_list = new StorableSelectionList(TypedSelectionList("prb", PD.resultList, "designed probes", "designed")); // @@@ make member of PD ?
201
202        PD.resultList->clear();
203        PD.resultList->insert_default("No probes designed yet", "");
204
205        PD.win->at("buttons");
206       
207        PD.win->callback((AW_CB0)AW_POPDOWN);
208        PD.win->create_button("CLOSE", "CLOSE", "C");
209
210        PD.win->callback(awt_clear_selection_list_cb, (AW_CL)PD.resultList);
211        PD.win->create_button("CLEAR", "CLEAR", "R");
212       
213        PD.win->callback(AW_POPUP, (AW_CL)create_load_box_for_selection_lists, (AW_CL)storable_result_list);
214        PD.win->create_button("LOAD", "LOAD", "L");
215
216        PD.win->callback(AW_POPUP, (AW_CL)create_save_box_for_selection_lists, (AW_CL)storable_result_list);
217        PD.win->create_button("SAVE", "SAVE", "S");
218
219        PD.win->callback(create_print_box_for_selection_lists, (AW_CL)&storable_result_list->get_typedsellist());
220        PD.win->create_button("PRINT", "PRINT", "P");
221
222        PD.win->callback(popup_match_window_cb, cl_gb_main);
223        PD.win->create_button("MATCH", "MATCH", "M");
224
225        PD.win->label("Auto match");
226        PD.win->create_toggle(AWAR_PD_MATCH_AUTOMATCH);
227
228        enable_auto_match_cb(root, PD.win, 0);
229    }
230    PD.win->activate();
231}
232
233static int init_local_com_struct()
234{
235    const char *user = GB_getenvUSER();
236
237    if (aisc_create(PD.link, PT_MAIN, PD.com,
238                    MAIN_LOCS, PT_LOCS, PD.locs,
239                    LOCS_USER, user,
240                    NULL)) {
241        return 1;
242    }
243    return 0;
244}
245
246static const char *PD_probe_pt_look_for_server(AW_root *root, GB_ERROR& error) { 
247    // return PT server info string (see GBS_read_arb_tcp for details)
248    // or NULL (in this case 'error' is set)
249
250    const char *result     = 0;
251    const char *server_tag = GBS_ptserver_tag(root->awar(AWAR_PT_SERVER)->read_int());
252
253    error = arb_look_and_start_server(AISC_MAGIC_NUMBER, server_tag);
254    if (!error) {
255        result             = GBS_read_arb_tcp(server_tag);
256        if (!result) error = GB_await_error();
257    }
258    pd_assert(contradicted(result, error));
259    return result;
260}
261
262static GB_ERROR species_requires(GBDATA *gb_species, const char *whats_required) {
263    return GBS_global_string("Species '%s' needs %s", GBT_read_name(gb_species), whats_required);
264}
265
266static GB_ERROR gene_requires(GBDATA *gb_gene, const char *whats_required) {
267    GBDATA *gb_species = GB_get_grandfather(gb_gene);
268    pd_assert(gb_species);
269    return GBS_global_string("Gene '%s' of organism '%s' needs %s", GBT_read_name(gb_gene), GBT_read_name(gb_species), whats_required);
270}
271
272static GB_ERROR pd_get_the_names(GBDATA *gb_main, bytestring &bs, bytestring &checksum) {
273    GBS_strstruct *names     = GBS_stropen(1024);
274    GBS_strstruct *checksums = GBS_stropen(1024);
275    GB_ERROR       error     = 0;
276
277    GB_begin_transaction(gb_main);
278
279    char *use = GBT_get_default_alignment(gb_main);
280
281    for (GBDATA *gb_species = GBT_first_marked_species(gb_main); gb_species; gb_species = GBT_next_marked_species(gb_species)) {
282        GBDATA *gb_name = GB_entry(gb_species, "name");
283        if (!gb_name) { error = species_requires(gb_species, "name"); break; }
284
285        GBDATA *gb_data = GBT_read_sequence(gb_species, use);
286        if (!gb_data) { error = species_requires(gb_species, GBS_global_string("data in '%s'", use)); break; }
287
288        GBS_intcat(checksums, GBS_checksum(GB_read_char_pntr(gb_data), 1, ".-"));
289        GBS_strcat(names, GB_read_char_pntr(gb_name));
290        GBS_chrcat(checksums, '#');
291        GBS_chrcat(names, '#');
292    }
293
294    GBS_str_cut_tail(names, 1); // remove trailing '#'
295    GBS_str_cut_tail(checksums, 1); // remove trailing '#'
296
297    free(use);
298
299    bs.data = GBS_strclose(names);
300    bs.size = strlen(bs.data)+1;
301
302    checksum.data = GBS_strclose(checksums);
303    checksum.size = strlen(checksum.data)+1;
304
305    GB_commit_transaction(gb_main);
306
307    return error;
308}
309
310static GB_ERROR pd_get_the_gene_names(GBDATA *gb_main, bytestring &bs, bytestring &checksum) {
311    GBS_strstruct *names     = GBS_stropen(1024);
312    GBS_strstruct *checksums = GBS_stropen(1024);
313    GB_ERROR       error     = 0;
314
315    GB_begin_transaction(gb_main);
316    const char *use = GENOM_ALIGNMENT; // gene pt server is always build on 'ali_genom'
317
318    for (GBDATA *gb_species = GEN_first_organism(gb_main); gb_species && !error; gb_species = GEN_next_organism(gb_species)) {
319        const char *species_name = 0;
320        {
321            GBDATA *gb_data = GBT_read_sequence(gb_species, use);
322            if (!gb_data) { error = species_requires(gb_species, GBS_global_string("data in '%s'", use)); break; }
323
324            GBDATA *gb_name = GB_search(gb_species, "name", GB_FIND);
325            if (!gb_name) { error = species_requires(gb_species, "name"); break; }
326            species_name = GB_read_char_pntr(gb_name);
327        }
328
329        for (GBDATA *gb_gene = GEN_first_marked_gene(gb_species); gb_gene && !error; gb_gene = GEN_next_marked_gene(gb_gene)) {
330            const char *gene_name = 0;
331            {
332                GBDATA *gb_gene_name = GB_entry(gb_gene, "name");
333                if (!gb_gene_name) { error = gene_requires(gb_gene, "name"); break; }
334                gene_name = GB_read_char_pntr(gb_gene_name);
335            }
336
337            {
338                char *gene_seq       = GBT_read_gene_sequence(gb_gene, false, 0);
339                if (!gene_seq) error = GB_await_error();
340                else {
341                    long        CheckSum = GBS_checksum(gene_seq, 1, ".-");
342                    const char *id       = GBS_global_string("%s/%s", species_name, gene_name);
343
344                    GBS_intcat(checksums, CheckSum);
345                    GBS_strcat(names, id);
346                    GBS_chrcat(checksums, '#');
347                    GBS_chrcat(names, '#');
348
349                    free(gene_seq);
350                }
351            }
352        }
353    }
354
355    GBS_str_cut_tail(names, 1); // remove trailing '#'
356    GBS_str_cut_tail(checksums, 1); // remove trailing '#'
357
358    if (error) {
359        GBS_strforget(names);
360        GBS_strforget(checksums);
361    }
362    else {
363        bs.size = GBS_memoffset(names)+1;
364        bs.data = GBS_strclose(names);
365
366        checksum.size = GBS_memoffset(checksums)+1;
367        checksum.data = GBS_strclose(checksums);
368    }
369    error = GB_end_transaction(gb_main, error);
370    return error;
371}
372
373static int probe_common_send_data(AW_root *root) {
374    // send data common to probe-design AND -match
375    if (aisc_put(PD.link, PT_LOCS, PD.locs,
376                 LOCS_SPLIT,   (double)root->awar(AWAR_PD_COMMON_EXP_SPLIT)->read_float(),
377                 NULL))
378        return 1;
379
380    for (int i=0; i<16; i++) {
381        char buffer[256];
382        sprintf(buffer, AWAR_PD_COMMON_EXP_BONDS "%i", i);
383        if (aisc_put(PD.link, PT_LOCS, PD.locs,
384                     PT_INDEX,  i,
385                     LOCS_BONDVAL, (double)root->awar(buffer)->read_float(),
386                     NULL))
387            return 1;
388    }
389    return 0;
390}
391static int probe_design_send_data(AW_root *root, const T_PT_PDC& pdc) {
392    if (aisc_put(PD.link, PT_PDC, pdc,
393                 PDC_DTEDGE,     (double)root->awar(AWAR_PD_DESIGN_EXP_DTEDGE)->read_float()*100.0,
394                 PDC_DT,         (double)root->awar(AWAR_PD_DESIGN_EXP_DT)->read_float()*100.0,
395                 PDC_CLIPRESULT, root->awar(AWAR_PD_DESIGN_CLIPRESULT)->read_int(),
396                 NULL))
397        return 1;
398
399    return probe_common_send_data(root);
400}
401static int probe_match_send_data(AW_root *root) {
402    if (aisc_put(PD.link, PT_LOCS, PD.locs,
403                 LOCS_MATCH_N_ACCEPT, root->awar(AWAR_PD_MATCH_NMATCHES)->read_int(), 
404                 LOCS_MATCH_N_LIMIT,  root->awar(AWAR_PD_MATCH_LIM_NMATCH)->read_int(),
405                 LOCS_MATCH_MAX_HITS, root->awar(AWAR_PD_MATCH_MAX_RES)->read_int(),
406                 NULL))
407        return 1;
408
409    return probe_common_send_data(root);
410}
411
412static int ecolipos2int(const char *awar_val) {
413    int i = atoi(awar_val);
414    return i>0 ? i : -1;
415}
416
417static void probe_design_event(AW_window *aww, AW_CL cl_gb_main) {
418    AW_root     *root    = aww->get_root();
419    T_PT_PDC     pdc;
420    T_PT_TPROBE  tprobe;
421    bytestring   bs;
422    bytestring   check;
423    GB_ERROR     error   = 0;
424    GBDATA      *gb_main = (GBDATA*)cl_gb_main;
425
426    arb_progress progress("Probe design");
427    progress.subtitle("Connecting PT-server");
428
429    {
430        const char *servername = PD_probe_pt_look_for_server(root, error);
431        if (servername) {
432            PD.link = aisc_open(servername, PD.com, AISC_MAGIC_NUMBER);
433            if (!PD.link) error = "can't contact PT server";
434            PD.locs.clear();
435        }
436    }
437
438    if (!error && init_local_com_struct()) {
439        error = "Cannot contact to probe server: Connection Refused";
440    }
441
442    bool design_gene_probes = root->awar(AWAR_PD_DESIGN_GENE)->read_int();
443    if (design_gene_probes) {
444        GB_transaction ta(gb_main);
445        if (!GEN_is_genome_db(gb_main, -1)) design_gene_probes = false;
446    }
447
448    if (!error) {
449        if (design_gene_probes) { // design probes for genes
450            error = pd_get_the_gene_names(gb_main, bs, check);
451        }
452        else {
453            error = pd_get_the_names(gb_main, bs, check);
454        }
455    }
456
457    if (error) {
458        aw_message(error);
459        return;
460    }
461
462    progress.subtitle("probe design running");
463
464    if (aisc_create(PD.link, PT_LOCS, PD.locs,
465                    LOCS_PROBE_DESIGN_CONFIG, PT_PDC, pdc,
466                    PDC_PROBELENGTH,  root->awar(AWAR_PD_DESIGN_PROBELENGTH)->read_int(),
467                    PDC_MINTEMP,      (double)root->awar(AWAR_PD_DESIGN_MIN_TEMP)->read_float(),
468                    PDC_MAXTEMP,      (double)root->awar(AWAR_PD_DESIGN_MAX_TEMP)->read_float(),
469                    PDC_MINGC,        (double)root->awar(AWAR_PD_DESIGN_MIN_GC)->read_float()/100.0,
470                    PDC_MAXGC,        (double)root->awar(AWAR_PD_DESIGN_MAX_GC)->read_float()/100.0,
471                    PDC_MAXBOND,      (double)root->awar(AWAR_PD_DESIGN_MAXBOND)->read_int(),
472                    PDC_MIN_ECOLIPOS, (long)ecolipos2int(root->awar(AWAR_PD_DESIGN_MIN_ECOLIPOS)->read_char_pntr()),
473                    PDC_MAX_ECOLIPOS, (long)ecolipos2int(root->awar(AWAR_PD_DESIGN_MAX_ECOLIPOS)->read_char_pntr()),
474                    PDC_MISHIT,       root->awar(AWAR_PD_DESIGN_MISHIT)->read_int(),
475                    PDC_MINTARGETS,   (double)root->awar(AWAR_PD_DESIGN_MINTARGETS)->read_float()/100.0,
476                    NULL))
477    {
478        aw_message ("Connection to PT_SERVER lost (1)");
479        return;
480    }
481   
482    if (probe_design_send_data(root, pdc)) {
483        aw_message ("Connection to PT_SERVER lost (1)");
484        return;
485    }
486
487    aisc_put(PD.link, PT_PDC, pdc,
488             PDC_NAMES, &bs,
489             PDC_CHECKSUMS, &check,
490             NULL);
491
492
493    // Get the unknown names
494    bytestring unknown_names;
495    if (aisc_get(PD.link, PT_PDC, pdc,
496                 PDC_UNKNOWN_NAMES, &unknown_names,
497                 NULL)) {
498        aw_message ("Connection to PT_SERVER lost (1)");
499        return;
500    }
501
502    char *unames = unknown_names.data;
503    bool  abort  = false;
504
505    if (unknown_names.size>1) {
506        if (design_gene_probes) { // updating sequences of missing genes is not possible with gene PT server
507            aw_message(GBS_global_string("Your PT server is not up to date or wrongly chosen.\n"
508                                         "The following genes are new to it: %s\n"
509                                         "You'll have to re-build the PT server.", unames));
510            abort = true;
511        }
512        else if (aw_question("ptserver_add_unknown",
513                             GBS_global_string("Your PT server is not up to date or wrongly chosen\n"
514                                               "  The following names are new to it:\n"
515                                               "  %s\n"
516                                               "  This version allows you to quickly add the unknown sequences\n"
517                                               "  to the pt_server\n",
518                                               unames),
519                             "Add and Continue,Abort"))
520        {
521            abort = true;
522        }
523        else {
524            GB_transaction dummy(gb_main);
525
526            char *h;
527            char *ali_name = GBT_get_default_alignment(gb_main);
528
529            for (; unames && !abort; unames = h) {
530                h = strchr(unames, '#');
531                if (h) *(h++) = 0;
532                GBDATA *gb_species = GBT_find_species(gb_main, unames);
533                if (!gb_species) {
534                    aw_message(GBS_global_string("Species '%s' not found", unames));
535                    abort = true;
536                }
537                else {
538                    GBDATA *data = GBT_read_sequence(gb_species, ali_name);
539                    if (!data) {
540                        aw_message(GB_export_errorf("Species '%s' has no sequence belonging to alignment '%s'", unames, ali_name));
541                        abort = true;
542                    }
543                    else {
544                        T_PT_SEQUENCE pts;
545                        bytestring    bs_seq;
546                        bs_seq.data = (char*)GB_read_char_pntr(data);
547                        bs_seq.size = GB_read_string_count(data)+1;
548                        aisc_create(PD.link, PT_PDC, pdc,
549                                    PDC_SEQUENCE, PT_SEQUENCE, pts,
550                                    SEQUENCE_SEQUENCE, &bs_seq,
551                                    NULL);
552                    }
553                }
554            }
555        }
556        free(unknown_names.data);
557    }
558
559    if (!abort) {
560        aisc_put(PD.link, PT_PDC, pdc,
561                 PDC_GO, 0,
562                 NULL);
563
564        progress.subtitle("Reading results from server");
565        {
566            char *locs_error = 0;
567            if (aisc_get(PD.link, PT_LOCS, PD.locs,
568                         LOCS_ERROR, &locs_error,
569                         NULL))
570            {
571                aw_message ("Connection to PT_SERVER lost (1)");
572                abort = true;
573            }
574            else if (*locs_error) {
575                aw_message(locs_error);
576                abort = true;
577            }
578            else {
579                free(locs_error);
580            }
581        }
582    }
583
584    if (!abort) {
585        aisc_get(PD.link, PT_PDC, pdc,
586                 PDC_TPROBE, tprobe.as_result_param(),
587                 NULL);
588
589        popup_probe_design_result_window(aww, cl_gb_main);
590        PD.resultList->clear();
591
592        if (tprobe.exists()) {
593            char *match_info = 0;
594            aisc_get(PD.link, PT_TPROBE, tprobe,
595                     TPROBE_INFO_HEADER,   &match_info,
596                     NULL);
597
598            char *s = strtok(match_info, "\n");
599            while (s) {
600                PD.resultList->insert(s, "");
601                s = strtok(0, "\n");
602            }
603            free(match_info);
604        }
605        else {
606            PD.resultList->insert("There are no results", "");
607        }
608
609        // #define TEST_PD
610#if defined(TEST_PD)
611        int     my_TPROBE_KEY;
612        char   *my_TPROBE_KEYSTRING;
613        int     my_TPROBE_CNT;
614        int     my_TPROBE_PARENT;
615        int     my_TPROBE_LAST;
616        char   *my_TPROBE_IDENT;
617        char   *my_TPROBE_SEQUENCE;
618        double  my_TPROBE_QUALITY;
619        int     my_TPROBE_GROUPSIZE;
620        int     my_TPROBE_HAIRPIN;
621        int     my_TPROBE_WHAIRPIN;
622        double  my_TPROBE_TEMPERATURE;
623        int     my_TPROBE_MISHIT;
624        int     my_TPROBE_APOS;
625        int     my_TPROBE_ECOLI_POS;
626
627#endif // TEST_PD
628
629        while (tprobe.exists()) {
630            T_PT_TPROBE  tprobe_next;
631            char        *match_info = 0;
632
633            if (aisc_get(PD.link, PT_TPROBE, tprobe,
634                         TPROBE_NEXT,      tprobe_next.as_result_param(),
635                         TPROBE_INFO,      &match_info,
636
637#if defined(TEST_PD)
638                         TPROBE_KEY,       &my_TPROBE_KEY,
639                         TPROBE_KEYSTRING, &my_TPROBE_KEYSTRING,
640                         TPROBE_CNT,       &my_TPROBE_CNT,
641                         TPROBE_PARENT,    &my_TPROBE_PARENT,
642                         TPROBE_LAST,      &my_TPROBE_LAST,
643                         TPROBE_IDENT,     &my_TPROBE_IDENT,
644                         TPROBE_SEQUENCE,  &my_TPROBE_SEQUENCE,  // encoded probe sequence (2=A 3=C 4=G 5=U)
645                         TPROBE_QUALITY,   &my_TPROBE_QUALITY,   // quality of probe ?
646#endif // TEST_PD
647                         
648                         NULL)) break;
649
650
651#if defined(TEST_PD)
652            if (aisc_get(PD.link, PT_TPROBE, tprobe,
653                         TPROBE_GROUPSIZE,   &my_TPROBE_GROUPSIZE,   // groesse der Gruppe,  die von Sonde getroffen wird?
654                         TPROBE_HAIRPIN,     &my_TPROBE_HAIRPIN,
655                         TPROBE_WHAIRPIN,    &my_TPROBE_WHAIRPIN,
656                         // TPROBE_PERC,     &my_TPROBE_PERC,
657                         TPROBE_TEMPERATURE, &my_TPROBE_TEMPERATURE,
658                         TPROBE_MISHIT,      &my_TPROBE_MISHIT,      // Treffer ausserhalb von Gruppe ?
659                         TPROBE_APOS,        &my_TPROBE_APOS,        // Alignment-Position
660                         TPROBE_ECOLI_POS,   &my_TPROBE_ECOLI_POS,
661                         NULL)) break;
662#endif // TEST_PD
663           
664            tprobe.assign(tprobe_next);
665
666            char *probe, *space;
667            probe = strpbrk(match_info, "acgtuACGTU");
668            if (probe) space = strchr(probe, ' ');
669            if (probe && space) {
670                *space = 0; probe = strdup(probe); *space=' ';
671            }
672            else {
673                probe = strdup("");
674            }
675            PD.resultList->insert(match_info, probe);
676            free(probe);
677            free(match_info);
678        }
679        PD.resultList->insert_default("default", "");
680        PD.resultList->update();
681    }
682
683    aisc_close(PD.link, PD.com); PD.link = 0;
684    return;
685}
686
687static bool allow_probe_match_event = true;
688
689static void probe_match_event(AW_window *aww, AW_CL cl_ProbeMatchEventParam) {
690    if (allow_probe_match_event) {
691        ProbeMatchEventParam *event_param  = (ProbeMatchEventParam*)cl_ProbeMatchEventParam;
692        AW_selection_list    *selection_id = event_param ? event_param->selection_id : NULL;
693        int                  *counter      = event_param ? event_param->counter : NULL;
694        GBDATA               *gb_main      = event_param ? event_param->gb_main : NULL;
695        AW_root              *root         = aww->get_root();
696        int                   show_status  = 0;
697        int                   extras       = 1;     // mark species and write to temp fields
698        GB_ERROR              error        = 0;
699
700        if (!gb_main) { error = "Please open probe match window once to enable auto-match"; }
701
702        SmartPtr<arb_progress> progress;
703       
704        if (!error) {
705            const char *servername = PD_probe_pt_look_for_server(root, error);
706
707            if (!error) {
708                if (selection_id) {
709                    selection_id->clear();
710                    pd_assert(!counter);
711                    show_status = 1;
712                }
713                else if (counter) {
714                    extras = 0;
715                }
716
717                if (show_status) {
718                    progress = new arb_progress("Probe match");
719                    progress->subtitle("Connecting PT-server");
720                }
721
722                PD.link = aisc_open(servername, PD.com, AISC_MAGIC_NUMBER);
723                if (!PD.link) error = "Cannot contact PT-server";
724                PD.locs.clear();
725            }
726        }
727
728        if (!error && init_local_com_struct())     error = "Cannot contact PT-server (2)";
729        if (!error && probe_match_send_data(root)) error = "Connection to PT_SERVER lost (2)";
730
731        char *probe = root->awar(AWAR_TARGET_STRING)->read_string();
732
733        if (!error) {
734            if (show_status) progress->subtitle("Probe match running");
735
736            if (aisc_nput(PD.link, PT_LOCS, PD.locs,
737                          LOCS_MATCH_REVERSED,       root->awar(AWAR_PD_MATCH_COMPLEMENT)->read_int(),
738                          LOCS_MATCH_SORT_BY,        root->awar(AWAR_PD_MATCH_SORTBY)->read_int(),
739                          LOCS_MATCH_COMPLEMENT,     0,
740                          LOCS_MATCH_MAX_MISMATCHES, root->awar(AWAR_MAX_MISMATCHES)->read_int(),
741                          LOCS_SEARCHMATCH,          probe,
742                          NULL))
743            {
744                error = "Connection to PT_SERVER lost (2)";
745            }
746            else {
747                delete(g_spd);              // delete previous probe data
748                g_spd = new saiProbeData;
749                transferProbeData(g_spd);
750
751                if (selection_id) {
752                    g_spd->setProbeTarget(probe);
753                }
754            }
755        }
756
757        bytestring bs;
758        bs.data = 0;
759
760        long matches_truncated = 0;
761        if (!error) {
762            if (show_status) progress->subtitle("Reading results");
763
764            T_PT_MATCHLIST  match_list;
765            long            match_list_cnt    = 0;
766            char           *locs_error        = 0;
767
768            if (aisc_get(PD.link, PT_LOCS, PD.locs,
769                         LOCS_MATCH_LIST,        match_list.as_result_param(),
770                         LOCS_MATCH_LIST_CNT,    &match_list_cnt,
771                         LOCS_MATCH_STRING,      &bs,
772                         LOCS_MATCHES_TRUNCATED, &matches_truncated,
773                         LOCS_ERROR,             &locs_error,
774                         NULL))
775            {
776                error = "Connection to PT_SERVER lost (3)";
777            }
778            else {
779                if (locs_error) {
780                    if (*locs_error) error = GBS_global_string("%s", locs_error);
781                    free(locs_error);
782                }
783                else {
784                    error = "Missing status from server (connection aborted?)";
785                }
786            }
787
788            root->awar(AWAR_PD_MATCH_NHITS)->write_string(GBS_global_string(matches_truncated ? "[more than %li]" : "%li", match_list_cnt));
789            if (matches_truncated) {
790                aw_message("Too many matches, displaying a random digest.\n"
791                           "Increase the limit in the expert window.");
792            }
793        }
794
795        long mcount                = 0;
796        long unknown_species_count = 0;
797        long unknown_gene_count    = 0;
798
799        if (!error) {
800            char        toksep[2]  = { 1, 0 };
801            char       *strtok_ptr = 0; // stores strtok position
802            const char *hinfo      = strtok_r(bs.data, toksep, &strtok_ptr);
803
804            bool              gene_flag = false;
805            ProbeMatchParser *parser    = 0;
806            char             *result    = (char*)malloc(1024);
807
808
809            if (hinfo) {
810                g_spd->setHeadline(hinfo);
811                parser = new ProbeMatchParser(probe, hinfo);
812                error  = parser->get_error();
813                if (!error) gene_flag = parser->is_gene_result();
814            }
815
816            if (selection_id) {
817                int width         = 0;
818                if (parser && !error) width = parser->get_probe_region_offset()+2+10; // 2 cause headline is shorter and 10 for match prefix region
819
820                const char *searched = GBS_global_string("%-*s%s", width, "Searched for ", probe);
821                selection_id->insert(searched, probe);
822                if (hinfo) selection_id->insert(hinfo, "");
823            }
824
825
826            // clear all marks and delete all 'tmp' entries
827
828            int mark        = extras && (int)root->awar(AWAR_PD_MATCH_MARKHITS)->read_int();
829            int write_2_tmp = extras && (int)root->awar(AWAR_PD_MATCH_WRITE2TMP)->read_int();
830
831            GB_push_transaction(gb_main);
832
833            GBDATA *gb_species_data = GBT_get_species_data(gb_main);
834            if (mark && !error) {
835                if (show_status) progress->subtitle(gene_flag ? "Unmarking all species and genes" : "Unmarking all species");
836                for (GBDATA *gb_species = GBT_first_marked_species_rel_species_data(gb_species_data);
837                     gb_species;
838                     gb_species = GBT_next_marked_species(gb_species))
839                {
840                    GB_write_flag(gb_species, 0);
841                }
842
843                if (gene_flag) {
844                    // unmark genes of ALL species
845                    for (GBDATA *gb_species = GBT_first_species_rel_species_data(gb_species_data);
846                         gb_species;
847                         gb_species = GBT_next_species(gb_species))
848                    {
849                        GBDATA *genData = GEN_find_gene_data(gb_species);
850                        if (genData) {
851                            for (GBDATA *gb_gene = GEN_first_marked_gene(gb_species);
852                                 gb_gene;
853                                 gb_gene = GEN_next_marked_gene(gb_gene))
854                            {
855                                GB_write_flag(gb_gene, 0);
856                            }
857                        }
858                    }
859                }
860            }
861            if (write_2_tmp && !error) {
862                if (show_status) progress->subtitle("Deleting old 'tmp' fields");
863                for (GBDATA *gb_species = GBT_first_species_rel_species_data(gb_species_data);
864                     gb_species;
865                     gb_species = GBT_next_species(gb_species))
866                {
867                    GBDATA *gb_tmp = GB_entry(gb_species, "tmp");
868                    if (gb_tmp) GB_delete(gb_tmp);
869                    if (gene_flag) {
870                        for (GBDATA *gb_gene = GEN_first_gene(gb_species);
871                             gb_gene;
872                             gb_gene = GEN_next_gene(gb_species))
873                        {
874                            gb_tmp = GB_entry(gb_gene, "tmp");
875                            if (gb_tmp) GB_delete(gb_tmp);
876                        }
877                    }
878                }
879            }
880
881            // read results from pt-server :
882
883            if (!error) {
884                if (show_status) progress->subtitle("Parsing results");
885
886                g_spd->probeSpecies.clear();
887                g_spd->probeSeq.clear();
888
889                if (gene_flag) {
890                    if (!GEN_is_genome_db(gb_main, -1)) {
891                        error = "Wrong PT-Server chosen (selected one is built for genes)";
892                    }
893                }
894            }
895
896            const char *match_name = 0;
897            while (hinfo && !error && (match_name = strtok_r(0, toksep, &strtok_ptr))) {
898                const char *match_info = strtok_r(0, toksep, &strtok_ptr);
899                if (!match_info) break;
900
901                pd_assert(parser);
902                ParsedProbeMatch  ppm(match_info, *parser);
903                char             *gene_str = 0;
904
905                if (gene_flag) {
906                    gene_str = ppm.get_column_content("genename", true);
907                }
908
909                if (!error) {
910                    char flags[]       = "xx";
911                    GBDATA *gb_species = GBT_find_species_rel_species_data(gb_species_data, match_name);
912
913                    if (gb_species) {
914                        GBDATA *gb_gene = 0;
915                        if (gene_flag && strncmp(gene_str, "intergene_", 10) != 0) { // real gene
916                            gb_gene = GEN_find_gene(gb_species, gene_str);
917                            if (!gb_gene) {
918                                aw_message(GBS_global_string("Gene '%s' not found in organism '%s'", gene_str, match_name));
919                            }
920                        }
921
922                        if (mark) {
923                            GB_write_flag(gb_species, 1);
924                            flags[0] = '*';
925                            if (gb_gene) {
926                                GB_write_flag(gb_gene, 1);
927                                flags[1] = '*';
928                            }
929                            else {
930                                flags[1] = '?'; // no gene
931                            }
932                        }
933                        else {
934                            flags[0] = " *"[GB_read_flag(gb_species)];
935                            flags[1] = " *?"[gb_gene ? GB_read_flag(gb_gene) : 2];
936                        }
937
938                        if (write_2_tmp) {
939                            // write or append to field 'tmp'
940                       
941                            GBDATA   *gb_tmp = 0;
942                            GB_ERROR  error2 = 0;
943                            bool      append = true;
944                            {
945                                GBDATA *gb_parent = gene_flag ? gb_gene : gb_species;
946                                gb_tmp            = GB_search(gb_parent, "tmp", GB_FIND);
947                                if (!gb_tmp) {
948                                    append              = false;
949                                    gb_tmp              = GB_search(gb_parent, "tmp", GB_STRING);
950                                    if (!gb_tmp) error2 = GB_await_error();
951                                }
952                            }
953
954                            if (!error2) {
955                                pd_assert(gb_tmp);
956                                if (append) {
957                                    char *prevContent = GB_read_string(gb_tmp);
958                                    if (!prevContent) {
959                                        error2 = GB_await_error();
960                                    }
961                                    else {
962                                        char *concatenatedContent = (char *)malloc(strlen(prevContent)+1+strlen(match_info)+1);
963                                        sprintf(concatenatedContent, "%s\n%s", prevContent, match_info);
964                                        error2 = GB_write_string(gb_tmp, concatenatedContent);
965                                        free(concatenatedContent);
966                                        free(prevContent);
967                                    }
968                                }
969                                else {
970                                    error2 = GB_write_string(gb_tmp, match_info);
971                                }
972                            }
973
974                            if (error2) aw_message(error2);
975                        }
976                    }
977                    else {
978                        flags[0] = flags[1] = '?'; // species does not exist
979                        unknown_species_count++;
980                    }
981
982
983                    if (gene_flag) {
984                        sprintf(result, "%s %s", flags, match_info+1); // both flags (skip 1 space from match info to keep alignment)
985                        char *gene_match_name = new char[strlen(match_name) + strlen(gene_str)+2];
986                        sprintf(gene_match_name, "%s/%s", match_name, gene_str);
987                        if (selection_id) selection_id->insert(result, gene_match_name);   // @@@ wert fuer awar eintragen
988                    }
989                    else {
990                        sprintf(result, "%c %s", flags[0], match_info); // only first flag ( = species related)
991                        if (selection_id) selection_id->insert(result, match_name);   // @@@ wert fuer awar eintragen
992
993                        if (selection_id) {  // storing probe data into linked lists
994                            g_spd->probeSeq.push_back(strdup(match_info));
995                            g_spd->probeSpecies.push_back(strdup(match_name));
996                        }
997                    }
998                    mcount++;
999                }
1000
1001                free(gene_str);
1002            }
1003
1004            if (error) error = GBS_global_string("%s", error); // make static copy (error may be freed by delete parser)
1005            delete parser;
1006            free(result);
1007
1008            GB_pop_transaction(gb_main);
1009        }
1010
1011        if (error) {
1012            root->awar(AWAR_PD_MATCH_NHITS)->write_string("[none]"); // clear hits
1013            aw_message(error);
1014        }
1015        else {
1016            if (unknown_species_count>0) {
1017                aw_message(GBS_global_string("%li matches hit unknown species -- PT-server is out-of-date or build upon a different database", unknown_species_count));
1018            }
1019            if (unknown_gene_count>0) {
1020                aw_message(GBS_global_string("%li matches hit unknown genes -- PT-server is out-of-date or build upon a different database", unknown_gene_count));
1021            }
1022
1023            if (selection_id) {     // if !selection_id then probe match window is not opened
1024                pd_assert(g_spd);
1025                root->awar(AWAR_SPV_DB_FIELD_NAME)->touch(); // force refresh of SAI/Probe window
1026            }
1027        }
1028
1029        if (counter) *counter = mcount;
1030
1031        aisc_close(PD.link, PD.com);
1032        PD.link = 0;
1033
1034        if (selection_id) {
1035            const char *last_line                 = 0;
1036            if (error) last_line                  = GBS_global_string("****** Error: %s *******", error);
1037            else if (matches_truncated) last_line = "****** List is truncated *******";
1038            else        last_line                 = "****** End of List *******";
1039
1040            selection_id->insert_default(last_line, "");
1041            selection_id->update();
1042        }
1043
1044        free(bs.data);
1045        free(probe);
1046
1047        LocallyModify<bool> flag(allow_probe_match_event, false);
1048        root->awar(AWAR_TREE_REFRESH)->touch();
1049    }
1050
1051    return;
1052}
1053
1054static void probe_match_all_event(AW_window *aww, AW_CL cl_iselection_id, AW_CL cl_gb_main) {
1055    auto_match_cb_settings.disable = true;
1056
1057    AW_selection_list *iselection_id = (AW_selection_list*)cl_iselection_id;
1058    AW_root           *root          = aww->get_root();
1059    char              *target_string = root->awar(AWAR_TARGET_STRING)->read_string();
1060
1061    AW_selection_list_iterator selentry(iselection_id);
1062   
1063    arb_progress progress("Matching all resolved strings", iselection_id->size());
1064
1065    bool got_result = false;
1066    while (selentry) {
1067        const char *entry = selentry.get_value();
1068        root->awar(AWAR_TARGET_STRING)->write_string(entry); // probe match
1069        int counter = -1;
1070        ProbeMatchEventParam match_event((GBDATA*)cl_gb_main, &counter);
1071        probe_match_event(aww, (AW_CL)&match_event);
1072        if (counter==-1) break;
1073
1074        {
1075            char *buffer = new char[strlen(entry)+10]; // write # of matched to list entries
1076            sprintf(buffer, "%5i %s", counter, entry);
1077            selentry.set_displayed(buffer);
1078            got_result   = true;
1079            delete [] buffer;
1080        }
1081
1082        ++selentry;
1083        progress.inc();
1084       
1085    }
1086
1087    if (got_result) {
1088        iselection_id->sort(true, true);
1089        iselection_id->update();
1090        root->awar(AWAR_TARGET_STRING)->write_string(target_string);
1091    }
1092
1093    auto_match_cb_settings.disable = false;
1094}
1095
1096static void resolved_probe_chosen(AW_root *root) {
1097    char *string = root->awar(AWAR_PD_MATCH_RESOLVE)->read_string();
1098    root->awar(AWAR_TARGET_STRING)->write_string(string);
1099}
1100
1101static void selected_match_changed_cb(AW_root *root) {
1102    // this gets called when ever the selected probe match changes
1103    char *temp;
1104    char *selected_match = root->awar(AWAR_PD_SELECTED_MATCH)->read_string();
1105
1106    if (strchr(selected_match, '/')) { // "organism/gene"
1107        temp = strtok(selected_match, "/");
1108        root->awar(AWAR_SPECIES_NAME)->write_string(temp);
1109        temp = strtok(NULL, " /\n");
1110        root->awar(AWAR_GENE_NAME)->write_string(temp);
1111    }
1112    else {
1113        root->awar(AWAR_SPECIES_NAME)->write_string(selected_match);
1114    }
1115
1116    {
1117        LocallyModify<bool> flag(allow_probe_match_event, false); // avoid recursion
1118        root->awar(AWAR_TARGET_STRING)->touch(); // forces editor to jump to probe match in gene
1119    }
1120
1121    free(selected_match);
1122}
1123
1124void create_probe_design_variables(AW_root *root, AW_default props, AW_default db)
1125{
1126    char buffer[256]; memset(buffer, 0, 256);
1127    int  i;
1128    PD.win = 0;        // design result window not created
1129    root->awar_string(AWAR_SPECIES_NAME,         "", props);
1130    root->awar_string(AWAR_PD_SELECTED_MATCH,    "", props)->add_callback(selected_match_changed_cb);
1131    root->awar_float (AWAR_PD_DESIGN_EXP_DTEDGE, .5, props);
1132    root->awar_float (AWAR_PD_DESIGN_EXP_DT,     .5, props);
1133
1134
1135    double default_bonds[16] = {
1136        0.0, 0.0, 0.5, 1.1,
1137        0.0, 0.0, 1.5, 0.0,
1138        0.5, 1.5, 0.4, 0.9,
1139        1.1, 0.0, 0.9, 0.0
1140    };
1141
1142    for (i=0; i<16; i++) {
1143        sprintf(buffer, AWAR_PD_COMMON_EXP_BONDS "%i", i);
1144        root->awar_float(buffer, default_bonds[i], props);
1145        root->awar(buffer)->set_minmax(0, 3.0);
1146    }
1147    root->awar_float(AWAR_PD_COMMON_EXP_SPLIT,  .5, props);
1148    root->awar_float(AWAR_PD_DESIGN_EXP_DTEDGE, .5, props);
1149    root->awar_float(AWAR_PD_DESIGN_EXP_DT,     .5, props);
1150
1151    root->awar_int  (AWAR_PD_DESIGN_CLIPRESULT, 50,   props)->set_minmax(0, 1000);
1152    root->awar_int  (AWAR_PD_DESIGN_MISHIT,     0,    props)->set_minmax(0, 100000);
1153    root->awar_int  (AWAR_PD_DESIGN_MAXBOND,    4,    props)->set_minmax(0, 20);
1154    root->awar_float(AWAR_PD_DESIGN_MINTARGETS, 50.0, props)->set_minmax(0, 100);
1155
1156    root->awar_int  (AWAR_PD_DESIGN_PROBELENGTH,  18,     props)->set_minmax(10, 100);
1157    root->awar_float(AWAR_PD_DESIGN_MIN_TEMP,     30.0,   props)->set_minmax(0,  1000);
1158    root->awar_float(AWAR_PD_DESIGN_MAX_TEMP,     100.0,  props)->set_minmax(0,  1000);
1159    root->awar_float(AWAR_PD_DESIGN_MIN_GC,       50.0,   props)->set_minmax(0,  100);
1160    root->awar_float(AWAR_PD_DESIGN_MAX_GC,       100.0,  props)->set_minmax(0,  100);
1161
1162    root->awar_string(AWAR_PD_DESIGN_MIN_ECOLIPOS, "", props);
1163    root->awar_string(AWAR_PD_DESIGN_MAX_ECOLIPOS, "", props);
1164
1165    root->awar_int(AWAR_PT_SERVER,      0, props);
1166    root->awar_int(AWAR_PD_DESIGN_GENE, 0, props);
1167
1168    root->awar_int   (AWAR_PD_MATCH_MARKHITS,   1,       props);
1169    root->awar_int   (AWAR_PD_MATCH_SORTBY,     0,       props);
1170    root->awar_int   (AWAR_PD_MATCH_WRITE2TMP,  0,       props);
1171    root->awar_int   (AWAR_PD_MATCH_COMPLEMENT, 0,       props);
1172
1173    root->awar_int   (AWAR_MIN_MISMATCHES,      0,       db);
1174    root->awar_int   (AWAR_MAX_MISMATCHES,      0,       db);
1175    root->awar_string(AWAR_TARGET_STRING,       0,       db);
1176
1177    root->awar_string(AWAR_PD_MATCH_NHITS,      "[none]",props);
1178    root->awar_int   (AWAR_PD_MATCH_NMATCHES,   1,       props);
1179    root->awar_int   (AWAR_PD_MATCH_LIM_NMATCH, 4,       props);
1180    root->awar_int   (AWAR_PD_MATCH_MAX_RES,    1000000, props);
1181
1182    root->awar_int   (AWAR_PD_MATCH_AUTOMATCH,  0,    props)->add_callback(auto_match_changed);
1183
1184    root->awar_string(AWAR_PD_MATCH_RESOLVE, "", props)->add_callback(resolved_probe_chosen);
1185    root->awar_string(AWAR_ITARGET_STRING, "", db);
1186
1187    root->awar_int   (AWAR_PROBE_ADMIN_PT_SERVER,    0,  db);
1188    root->awar_int   (AWAR_PROBE_CREATE_GENE_SERVER, 0,  db);
1189
1190    root->awar_string(AWAR_SPV_SAI_2_PROBE,    "",     db); // name of SAI selected in list
1191    root->awar_string(AWAR_SPV_DB_FIELD_NAME,  "name", db); // name of displayed species field
1192    root->awar_int   (AWAR_SPV_DB_FIELD_WIDTH, 10,     db); // width of displayed species field
1193    root->awar_string(AWAR_SPV_ACI_COMMAND,    "",     db); // User defined or pre-defined ACI command to display
1194    root->awar_string(AWAR_SPV_SELECTED_PROBE, "",     db); // For highlighting the selected PROBE
1195}
1196
1197static AW_window *create_probe_expert_window(AW_root *root, AW_CL for_design) {
1198    AW_window_simple *aws = new AW_window_simple;
1199    if (for_design) {
1200        aws->init(root, "PD_exp", "Probe Design (Expert)");
1201        aws->load_xfig("pd_spec.fig");
1202    }
1203    else {
1204        aws->init(root, "PM_exp", "Probe Match (Expert)");
1205        aws->load_xfig("pm_spec.fig");
1206    }
1207   
1208    aws->label_length(30);
1209    aws->button_length(10);
1210
1211    aws->callback((AW_CB0)AW_POPDOWN);
1212    aws->at("close");
1213    aws->create_button("CLOSE", "CLOSE", "C");
1214
1215    aws->callback(AW_POPUP_HELP, (AW_CL)(for_design ? "pd_spec_param.hlp" : "pm_spec_param.hlp")); // uses_hlp_res("pm_spec_param.hlp", "pd_spec_param.hlp"); see ../SOURCE_TOOLS/check_ressources.pl@uses_hlp_res
1216    aws->at("help");
1217    aws->create_button("HELP", "HELP", "C");
1218
1219    for (int i=0; i<16; i++) { // bond matrix
1220        char buffer[256];
1221        sprintf(buffer, "%i", i);
1222        aws->at(buffer);
1223        sprintf(buffer, AWAR_PD_COMMON_EXP_BONDS "%i", i);
1224        aws->create_input_field(buffer, 4);
1225    }
1226
1227    aws->sens_mask(AWM_EXP);
1228    aws->at("split"); aws->create_input_field(AWAR_PD_COMMON_EXP_SPLIT,  6);
1229
1230    if (for_design) {
1231        aws->at("dt_edge"); aws->create_input_field(AWAR_PD_DESIGN_EXP_DTEDGE, 6);
1232        aws->at("dt");      aws->create_input_field(AWAR_PD_DESIGN_EXP_DT,     6);
1233        aws->sens_mask(AWM_ALL);
1234    }
1235    else {
1236        aws->at("nmatches");   aws->create_input_field(AWAR_PD_MATCH_NMATCHES,   3);
1237        aws->at("lim_nmatch"); aws->create_input_field(AWAR_PD_MATCH_LIM_NMATCH, 3);
1238        aws->sens_mask(AWM_ALL);
1239        aws->at("max_res");    aws->create_input_field(AWAR_PD_MATCH_MAX_RES,    14);
1240    }
1241   
1242    return aws;
1243}
1244
1245static AWT_config_mapping_def probe_design_mapping_def[] = {
1246    { AWAR_PD_DESIGN_CLIPRESULT,   "clip" },
1247    { AWAR_PD_DESIGN_MISHIT,       "mishit" },
1248    { AWAR_PD_DESIGN_MAXBOND,      "maxbond" },
1249    { AWAR_PD_DESIGN_MINTARGETS,   "mintarget" },
1250    { AWAR_PD_DESIGN_PROBELENGTH,  "probelen" },
1251    { AWAR_PD_DESIGN_MIN_TEMP,     "mintemp" },
1252    { AWAR_PD_DESIGN_MAX_TEMP,     "maxtemp" },
1253    { AWAR_PD_DESIGN_MIN_GC,       "mingc" },
1254    { AWAR_PD_DESIGN_MAX_GC,       "maxgc" },
1255    { AWAR_PD_DESIGN_MIN_ECOLIPOS, "minecoli" },
1256    { AWAR_PD_DESIGN_MAX_ECOLIPOS, "maxecoli" },
1257    { AWAR_PD_DESIGN_GENE,         "gene" },
1258    { AWAR_PD_COMMON_EXP_SPLIT,    "split" }, 
1259    { AWAR_PD_DESIGN_EXP_DTEDGE,   "dtedge" },
1260    { AWAR_PD_DESIGN_EXP_DT,       "dt" },
1261    { 0, 0 }
1262};
1263
1264static void probe_design_init_config(AWT_config_definition& cdef) {
1265    cdef.add(probe_design_mapping_def);
1266    for (int i = 0; i<16; ++i) {
1267        cdef.add(GBS_global_string(AWAR_PD_COMMON_EXP_BONDS "%i", i), "bond", i);
1268    }
1269}
1270
1271static char *probe_design_store_config(AW_window *aww, AW_CL, AW_CL) {
1272    AWT_config_definition cdef(aww->get_root());
1273    probe_design_init_config(cdef);
1274    return cdef.read();
1275}
1276static void probe_design_restore_config(AW_window *aww, const char *stored_string, AW_CL, AW_CL) {
1277    AWT_config_definition cdef(aww->get_root());
1278    probe_design_init_config(cdef);
1279    cdef.write(stored_string);
1280}
1281
1282AW_window *create_probe_design_window(AW_root *root, AW_CL cl_gb_main) {
1283    AW_window_simple *aws     = new AW_window_simple;
1284    GBDATA           *gb_main = (GBDATA*)cl_gb_main;
1285    bool              is_genom_db;
1286    {
1287        GB_transaction ta(gb_main);
1288        is_genom_db = GEN_is_genome_db(gb_main, -1);
1289    }
1290    aws->init(root, "PROBE_DESIGN", "PROBE DESIGN");
1291
1292    aws->load_xfig("pd_main.fig");
1293
1294    aws->callback((AW_CB0)AW_POPDOWN);
1295    aws->at("close");
1296    aws->create_button("CLOSE", "CLOSE", "C");
1297
1298    aws->at("help");
1299    aws->callback(AW_POPUP_HELP, (AW_CL)"probedesign.hlp");
1300    aws->create_button("HELP", "HELP", "H");
1301
1302    aws->callback(probe_design_event, cl_gb_main);
1303    aws->at("design");
1304    aws->highlight();
1305    aws->create_button("GO", "GO", "G");
1306
1307    aws->callback(popup_probe_design_result_window, (AW_CL)gb_main);
1308    aws->at("result");
1309    aws->create_button("RESULT", "RESULT", "S");
1310
1311    aws->callback(AW_POPUP, (AW_CL)create_probe_expert_window, (AW_CL)1);
1312    aws->at("expert");
1313    aws->create_button("EXPERT", "EXPERT", "S");
1314
1315    aws->at("pt_server");
1316    aws->label("PT-Server:");
1317    awt_create_selection_list_on_pt_servers(aws, AWAR_PT_SERVER, true);
1318
1319    aws->at("lenout"); aws->create_input_field(AWAR_PD_DESIGN_CLIPRESULT, 6);
1320    aws->at("mishit"); aws->create_input_field(AWAR_PD_DESIGN_MISHIT,       6);
1321    aws->sens_mask(AWM_EXP);
1322    aws->at("maxbonds"); aws->create_input_field(AWAR_PD_DESIGN_MAXBOND,    6);
1323    aws->sens_mask(AWM_ALL);
1324    aws->at("minhits"); aws->create_input_field(AWAR_PD_DESIGN_MINTARGETS, 6);
1325
1326    aws->at("minlen"); aws->create_input_field(AWAR_PD_DESIGN_PROBELENGTH,  5);
1327    aws->at("mint"); aws->create_input_field(AWAR_PD_DESIGN_MIN_TEMP,       5);
1328    aws->at("maxt"); aws->create_input_field(AWAR_PD_DESIGN_MAX_TEMP,       5);
1329    aws->at("mingc"); aws->create_input_field(AWAR_PD_DESIGN_MIN_GC,        5);
1330    aws->at("maxgc"); aws->create_input_field(AWAR_PD_DESIGN_MAX_GC,        5);
1331    aws->at("minpos"); aws->create_input_field(AWAR_PD_DESIGN_MIN_ECOLIPOS, 5);
1332    aws->at("maxpos"); aws->create_input_field(AWAR_PD_DESIGN_MAX_ECOLIPOS, 5);
1333
1334    if (is_genom_db) {
1335        aws->at("gene");
1336        aws->label("Gene probes?");
1337        aws->create_toggle(AWAR_PD_DESIGN_GENE);
1338    }
1339
1340    aws->at("save");
1341    AWT_insert_config_manager(aws, AW_ROOT_DEFAULT, "probe_design", probe_design_store_config, probe_design_restore_config, 0, 0);
1342
1343    return aws;
1344}
1345
1346// -------------------------------------------------------------------
1347
1348inline void my_strupr(char *s) {
1349    pd_assert(s);
1350    for (int i=0; s[i]; i++) {
1351        s[i] = toupper(s[i]);
1352    }
1353}
1354
1355static GB_alignment_type ali_used_for_resolvement = GB_AT_UNKNOWN;
1356
1357static void resolve_IUPAC_target_string(AW_root *, AW_CL cl_aww, AW_CL cl_selid) {
1358    AW_window         *aww          = (AW_window*)cl_aww;
1359    AW_selection_list *selection_id = (AW_selection_list*)cl_selid;
1360
1361    selection_id->clear();
1362
1363    if (ali_used_for_resolvement != GB_AT_RNA && ali_used_for_resolvement!=GB_AT_DNA) {
1364        selection_id->insert_default("Wrong alignment type!", "");
1365        selection_id->update();
1366        return;
1367    }
1368
1369    int       index   = ali_used_for_resolvement==GB_AT_RNA ? 1 : 0;
1370    AW_root  *root    = aww->get_root();
1371    char     *istring = root->awar(AWAR_ITARGET_STRING)->read_string();
1372    GB_ERROR  err     = 0;
1373
1374    if (istring && istring[0]) { // contains sth?
1375        my_strupr(istring);
1376
1377        int bases_to_resolve = 0;
1378        char *istr = istring;
1379        int istring_length = strlen(istring);
1380
1381        for (;;) {
1382            char i = *istr++;
1383            if (!i) break;
1384            if (i=='?') continue; // ignore '?'
1385
1386            int idx = i-'A';
1387            if (idx<0 || idx>=26 || iupac::nuc_group[idx][index].members==0) {
1388                err = GB_export_errorf("Illegal character '%c' in IUPAC-String", i);
1389                break;
1390            }
1391
1392            if (iupac::nuc_group[idx][index].count>1) {
1393                bases_to_resolve++;
1394            }
1395        }
1396
1397        if (!err) {
1398            int *offsets_to_resolve = new int[bases_to_resolve];
1399            int resolutions = 1;
1400            {
1401                istr = istring;
1402                int offset = 0;
1403                int offset_count = 0;
1404                for (;;) {
1405                    char i = *istr++;
1406                    if (!i) break;
1407
1408                    if (i!='?') {
1409                        int idx = iupac::to_index(i);
1410                        pd_assert(iupac::nuc_group[idx][index].members);
1411
1412                        if (iupac::nuc_group[idx][index].count>1) {
1413                            offsets_to_resolve[offset_count++] = offset; // store string offsets of non-unique base-codes
1414                            resolutions *= iupac::nuc_group[idx][index].count; // calc # of resolutions
1415                        }
1416                    }
1417                    offset++;
1418                }
1419            }
1420
1421            { 
1422                int *resolution_idx = new int[bases_to_resolve];
1423                int *resolution_max_idx = new int[bases_to_resolve];
1424                {
1425                    int i;
1426                    for (i=0; i<bases_to_resolve; i++) {
1427                        resolution_idx[i] = 0;
1428                        int idx = iupac::to_index(istring[offsets_to_resolve[i]]);
1429                        resolution_max_idx[i] = iupac::nuc_group[idx][index].count-1;
1430                    }
1431                }
1432
1433                char *buffer = new char[istring_length+1];
1434                int not_last = resolutions-1;
1435
1436                for (;;) {
1437                    // create string according to resolution_idx[]:
1438                    int i;
1439
1440                    memcpy(buffer, istring, istring_length+1);
1441                    for (i=0; i<bases_to_resolve; i++) {
1442                        int off = offsets_to_resolve[i];
1443                        int idx = iupac::to_index(istring[off]);
1444
1445                        pd_assert(iupac::nuc_group[idx][index].members);
1446                        buffer[off] = iupac::nuc_group[idx][index].members[resolution_idx[i]];
1447                    }
1448
1449                    selection_id->insert(buffer, buffer);
1450                    not_last--;
1451
1452                    // permute indices:
1453                    int nidx = bases_to_resolve-1;
1454                    int done = 0;
1455                    while (!done && nidx>=0) {
1456                        if (resolution_idx[nidx]<resolution_max_idx[nidx]) {
1457                            resolution_idx[nidx]++;
1458                            done = 1;
1459                            break;
1460                        }
1461                        nidx--;
1462                    }
1463                    if (!done) break; // we did all permutations!
1464
1465                    nidx++; // do not touch latest incremented index
1466                    while (nidx<bases_to_resolve) resolution_idx[nidx++] = 0; // zero all other indices
1467                }
1468
1469                delete [] buffer;
1470                delete [] resolution_max_idx;
1471                delete [] resolution_idx;
1472
1473                selection_id->insert_default("", "");
1474                selection_id->update();
1475            }
1476
1477            delete [] offsets_to_resolve;
1478        }
1479    }
1480
1481    if (err) {
1482        aw_message(err);
1483    }
1484}
1485
1486enum ModMode { TS_MOD_CLEAR, TS_MOD_REV_COMPL, TS_MOD_COMPL };
1487
1488static void modify_target_string(AW_window *aww, AW_CL cl_gb_main, AW_CL cl_mod_mode) {
1489    ModMode   mod_mode      = ModMode(cl_mod_mode);
1490    AW_root  *root          = aww->get_root();
1491    char     *target_string = root->awar(AWAR_TARGET_STRING)->read_string();
1492    GB_ERROR  error         = 0;
1493
1494    if (mod_mode == TS_MOD_CLEAR) target_string[0] = 0;
1495    else {
1496        GBDATA            *gb_main  = (GBDATA*)cl_gb_main;
1497        GB_transaction     ta(gb_main);
1498        GB_alignment_type  ali_type = GBT_get_alignment_type(gb_main, GBT_get_default_alignment(gb_main));
1499        if (mod_mode == TS_MOD_REV_COMPL) {
1500            char T_or_U;
1501            error = GBT_determine_T_or_U(ali_type, &T_or_U, "reverse-complement");
1502            if (!error) GBT_reverseComplementNucSequence(target_string, strlen(target_string), T_or_U);
1503        }
1504        else if (mod_mode == TS_MOD_COMPL) {
1505            char T_or_U;
1506            error = GBT_determine_T_or_U(ali_type, &T_or_U, "complement");
1507            if (!error) freeset(target_string, GBT_complementNucSequence(target_string, strlen(target_string), T_or_U));
1508        }
1509    }
1510
1511    if (error) aw_message(error);
1512    else root->awar(AWAR_TARGET_STRING)->write_string(target_string);
1513    free(target_string);
1514}
1515
1516static AW_window *create_IUPAC_resolve_window(AW_root *root, AW_CL cl_gb_main) {
1517    GBDATA           *gb_main = (GBDATA*)cl_gb_main;
1518    AW_window_simple *aws     = new AW_window_simple;
1519
1520    aws->init(root, "PROBE_MATCH_RESOLVE_IUPAC", "Resolve IUPAC for Probe Match");
1521    aws->load_xfig("pd_match_iupac.fig");
1522
1523    aws->callback((AW_CB0)AW_POPDOWN);
1524    aws->at("close");
1525    aws->create_button("CLOSE", "CLOSE", "C");
1526
1527    aws->callback(AW_POPUP_HELP, (AW_CL)"pd_match_iupac.hlp");
1528    aws->at("help");
1529    aws->create_button("HELP", "HELP", "C");
1530
1531    AW_selection_list *iselection_id;
1532    aws->at("iresult");
1533    iselection_id = aws->create_selection_list(AWAR_PD_MATCH_RESOLVE, 32, 15);
1534    iselection_id->insert_default("---empty---", "");
1535
1536    aws->at("istring");
1537    aws->create_input_field(AWAR_ITARGET_STRING, 32);
1538
1539
1540    // automatically resolve AWAR_ITARGET_STRING:
1541    {
1542        GB_transaction dummy(gb_main);
1543        ali_used_for_resolvement = GBT_get_alignment_type(gb_main, GBT_get_default_alignment(gb_main));
1544    }
1545    root->awar(AWAR_ITARGET_STRING)->add_callback(resolve_IUPAC_target_string, AW_CL(aws), AW_CL(iselection_id));
1546
1547    aws->callback(probe_match_all_event, (AW_CL)iselection_id, (AW_CL)gb_main);
1548    aws->at("match_all");
1549    aws->create_button("MATCH_ALL", "MATCH ALL", "A");
1550
1551    return aws;
1552}
1553
1554static void popupSaiProbeMatchWindow(AW_window *aw, AW_CL cl_gb_main) {
1555    static AW_window *aw_saiProbeMatch = 0;
1556
1557    if (!aw_saiProbeMatch) aw_saiProbeMatch = createSaiProbeMatchWindow(aw->get_root(), (GBDATA*)cl_gb_main);
1558    if (g_spd) transferProbeData(g_spd); // transferring probe data to saiProbeMatch function
1559
1560    aw_saiProbeMatch->activate();
1561}
1562
1563AW_window *create_probe_match_window(AW_root *root, AW_CL cl_gb_main) {
1564    static AW_window_simple *aws = 0; // the one and only probe match window
1565    if (!aws) {
1566        GBDATA *gb_main = (GBDATA*)cl_gb_main;
1567        aws             = new AW_window_simple;
1568
1569        aws->init(root, "PROBE_MATCH", "PROBE MATCH");
1570
1571        aws->load_xfig("pd_match.fig");
1572
1573        aws->callback((AW_CB0)AW_POPDOWN);
1574        aws->at("close");
1575        aws->create_button("CLOSE", "CLOSE", "C");
1576
1577        aws->callback(AW_POPUP_HELP, (AW_CL)"probematch.hlp");
1578        aws->at("help");
1579        aws->create_button("HELP", "HELP", "H");
1580
1581        aws->at("string");
1582        aws->create_input_field(AWAR_TARGET_STRING, 32);
1583
1584        AW_selection_list *selection_id;
1585        aws->at("result");
1586        selection_id = aws->create_selection_list(AWAR_PD_SELECTED_MATCH, 110, 15);
1587        selection_id->insert_default("****** No results yet *******", "");  // if list is empty -> crashed if new species was selected in ARB_EDIT4
1588
1589        TypedSelectionList *typed_selection = new TypedSelectionList("match", selection_id, "probe match", "probe_match");
1590        aws->at("print");
1591        aws->callback(create_print_box_for_selection_lists, (AW_CL)typed_selection);
1592        aws->create_button("PRINT", "PRINT", "P");
1593
1594        aws->at("matchSai");
1595        aws->callback(popupSaiProbeMatchWindow, (AW_CL)gb_main);
1596        aws->create_button("MATCH_SAI", "Match SAI", "S");
1597
1598        aws->callback(AW_POPUP, (AW_CL)create_probe_expert_window, (AW_CL)0);
1599        aws->at("expert");
1600        aws->create_button("EXPERT", "EXPERT", "X");
1601
1602        aws->at("pt_server");
1603        awt_create_selection_list_on_pt_servers(aws, AWAR_PT_SERVER, true);
1604
1605        aws->at("complement");
1606        aws->create_toggle(AWAR_PD_MATCH_COMPLEMENT);
1607
1608        aws->at("mark");
1609        aws->create_toggle(AWAR_PD_MATCH_MARKHITS);
1610
1611        aws->at("weighted");
1612        aws->create_toggle(AWAR_PD_MATCH_SORTBY);
1613
1614        aws->at("mismatches");
1615        aws->create_option_menu(AWAR_MAX_MISMATCHES);
1616        aws->insert_default_option("Search up to zero mismatches", "", 0);
1617        for (int mm = 1; mm <= 20; ++mm) {
1618            aws->insert_option(GBS_global_string("Search up to %i mismatches", mm), "", mm);
1619        }
1620        aws->update_option_menu();
1621
1622        aws->at("tmp");
1623        aws->create_toggle(AWAR_PD_MATCH_WRITE2TMP);
1624
1625        aws->at("nhits");
1626        aws->create_button(0, AWAR_PD_MATCH_NHITS);
1627
1628        ProbeMatchEventParam *event_param = new ProbeMatchEventParam(gb_main, selection_id);
1629        aws->callback(probe_match_event, (AW_CL)event_param);
1630        aws->at("match");
1631        aws->create_button("MATCH", "MATCH", "D");
1632
1633        aws->at("auto");
1634        aws->label("Auto");
1635        aws->create_toggle(AWAR_PD_MATCH_AUTOMATCH);
1636        enable_auto_match_cb(root, aws, event_param);
1637
1638        aws->callback(modify_target_string, (AW_CL)gb_main, (AW_CL)TS_MOD_CLEAR);
1639        aws->at("clear");
1640        aws->create_button("CLEAR", "Clear", "0");
1641
1642        aws->callback(modify_target_string, (AW_CL)gb_main, (AW_CL)TS_MOD_REV_COMPL);
1643        aws->at("revcompl");
1644        aws->create_button("REVCOMPL", "RevCompl", "R");
1645
1646        aws->callback(modify_target_string, (AW_CL)gb_main, (AW_CL)TS_MOD_COMPL);
1647        aws->at("compl");
1648        aws->create_button("COMPL", "Compl", "C");
1649
1650        aws->callback(AW_POPUP, (AW_CL)create_IUPAC_resolve_window, (AW_CL)gb_main);
1651        aws->at("iupac");
1652        aws->create_button("IUPAC", "IUPAC", "I");
1653    }
1654    return aws;
1655}
1656
1657static void pd_start_pt_server(AW_window *aww) {
1658    const char *server_tag = GBS_ptserver_tag(aww->get_root()->awar(AWAR_PROBE_ADMIN_PT_SERVER)->read_int());
1659    arb_progress progress("Connecting PT-server");
1660    GB_ERROR error = arb_look_and_start_server(AISC_MAGIC_NUMBER, server_tag);
1661    if (error) aw_message(error);
1662}
1663
1664static void pd_kill_pt_server(AW_window *aww, AW_CL kill_all)
1665{
1666    if (aw_ask_sure("kill_ptserver",
1667                    GBS_global_string("Are you sure to stop %s", kill_all ? "all servers" : "that server"))) {
1668        long min = 0;
1669        long max = 0;
1670
1671        if (kill_all) {
1672            const char * const *pt_servers = GBS_get_arb_tcp_entries("ARB_PT_SERVER*");
1673            while (pt_servers[max]) max++;
1674        }
1675        else {
1676            min = max = aww->get_root()->awar(AWAR_PROBE_ADMIN_PT_SERVER)->read_int(); // selected server
1677        }
1678
1679        arb_progress progress("Stopping PT-servers..", max-min+1);
1680        GB_ERROR     error = NULL;
1681
1682        for (int i = min; i <= max && !error;  i++) {
1683            char *choice = GBS_ptserver_id_to_choice(i, 0);
1684            if (!choice) {
1685                error = GB_await_error();
1686            }
1687            else {
1688                progress.subtitle(GBS_global_string("Trying to stop '%s'", choice));
1689
1690                const char *server_tag = GBS_ptserver_tag(i);
1691                GB_ERROR    kill_error = arb_look_and_kill_server(AISC_MAGIC_NUMBER, server_tag);
1692
1693                if (kill_error) aw_message(GBS_global_string("Could not stop '%s' (Reason: %s)", choice, kill_error));
1694                else aw_message(GBS_global_string("Stopped '%s'", choice));
1695
1696                free(choice);
1697            }
1698            progress.inc_and_check_user_abort(error);
1699        }
1700        progress.done();
1701        if (error) aw_message(error);
1702    }
1703}
1704
1705static void pd_query_pt_server(AW_window *aww) {
1706    const char *server_tag = GBS_ptserver_tag(aww->get_root()->awar(AWAR_PROBE_ADMIN_PT_SERVER)->read_int());
1707
1708    GBS_strstruct *strstruct = GBS_stropen(1024);
1709    GBS_strcat(strstruct,   "echo Contents of directory ARBHOME/lib/pts:;echo;"
1710               "(cd $ARBHOME/lib/pts; ls -l);"
1711               "echo; echo Disk space for PT_server files:; echo;"
1712               "df $ARBHOME/lib/pts;");
1713    GBS_strcat(strstruct, "echo;echo 'Running ARB programs:';");
1714
1715    {
1716        const char *server  = GBS_read_arb_tcp(server_tag);
1717        char       *arb_who = prefixSSH(server, "$ARBHOME/bin/arb_who", 0);
1718        GBS_strcat(strstruct, arb_who);
1719        free(arb_who);
1720    }
1721
1722    char *sys = GBS_strclose(strstruct);
1723    GB_xcmd(sys, true, false);
1724    free(sys);
1725}
1726
1727static void pd_export_pt_server(AW_window *aww, AW_CL cl_gb_main) {
1728    GBDATA   *gb_main = (GBDATA*)cl_gb_main;
1729    AW_root  *awr     = aww->get_root();
1730    GB_ERROR  error   = 0;
1731
1732    bool create_gene_server = awr->awar(AWAR_PROBE_CREATE_GENE_SERVER)->read_int();
1733    {
1734        GB_transaction ta(gb_main);
1735        if (create_gene_server && !GEN_is_genome_db(gb_main, -1)) create_gene_server = false;
1736
1737        // check alignment first
1738        if (create_gene_server) {
1739            GBDATA *gb_ali     = GBT_get_alignment(gb_main, GENOM_ALIGNMENT);
1740            if (!gb_ali) error = GB_await_error();
1741        }
1742        else { // normal pt server
1743            char              *use     = GBT_get_default_alignment(gb_main);
1744            GB_alignment_type  alitype = GBT_get_alignment_type(gb_main, use);
1745            if (alitype == GB_AT_AA) error = "The PT-server does only support RNA/DNA sequence data";
1746            free(use);
1747        }
1748    }
1749
1750    long        server_num = awr->awar(AWAR_PROBE_ADMIN_PT_SERVER)->read_int();
1751    const char *server_tag  = GBS_ptserver_tag(server_num);
1752
1753    if (!error &&
1754        aw_question("update_ptserver",
1755                    "This function will send your loaded database to the pt_server,\n"
1756                    "which will need a long time (up to several hours) to analyse the data.\n"
1757                    "Until the new server has analyzed all data, no server functions are available.\n\n"
1758                    "Note 1: You must have the write permissions to do that ($ARBHOME/lib/pts/xxx))\n"
1759                    "Note 2: The server will do the job in background,\n"
1760                    "        quitting this program won't affect the server",
1761                    "Cancel,Do it"))
1762    {
1763        arb_progress progress("Updating PT-server");
1764        progress.subtitle("Stopping PT-server");
1765        arb_look_and_kill_server(AISC_MAGIC_NUMBER, server_tag);
1766
1767        const char *ipPort = GBS_read_arb_tcp(server_tag);
1768        const char *file   = GBS_scan_arb_tcp_param(ipPort, "-d");
1769
1770        GBS_add_ptserver_logentry(GBS_global_string("Started build of '%s'", file));
1771        {
1772            char *db_name = awr->awar(AWAR_DB_PATH)->read_string();
1773            GBS_add_ptserver_logentry(GBS_global_string("Exporting DB '%s'", db_name));
1774            free(db_name);
1775        }
1776
1777        progress.subtitle("Exporting the database");
1778        {
1779            const char *mode = "bfm"; // save PT-server database with Fastload file
1780
1781            if (create_gene_server) {
1782                char *temp_server_name = GBS_string_eval(file, "*.arb=*_temp.arb", 0);
1783                error = GB_save_as(gb_main, temp_server_name, mode);
1784
1785                if (!error) {
1786                    // convert database (genes -> species)
1787                    progress.subtitle("Preparing DB for gene PT server");
1788                    GBS_add_ptserver_logentry("Preparing DB for gene PT server");
1789                    char *command = GBS_global_string_copy("$ARBHOME/bin/arb_gene_probe %s %s", temp_server_name, file);
1790                    printf("Executing '%s'\n", command);
1791                    int result = system(command);
1792                    if (result != 0) {
1793                        error = GBS_global_string("Couldn't convert database for gene pt server (arb_gene_probe failed, see console for reason)");
1794                    }
1795                    free(command);
1796                }
1797                free(temp_server_name);
1798            }
1799            else { // normal pt_server
1800                error = GB_save_as(gb_main, file, mode);
1801            }
1802        }
1803
1804        if (!error) { // set pt-server database file to same permissions as pts directory
1805            char *dir = const_cast<char*>(strrchr(file, '/'));
1806            if (dir) {
1807                *dir = 0;
1808                long modi = GB_mode_of_file(file);
1809                *dir = '/';
1810                modi &= 0666;
1811                error = GB_set_mode_of_file(file, modi);
1812            }
1813        }
1814
1815        if (!error) {
1816            progress.subtitle("Start PT-server (builds in background)");
1817            error = arb_start_server(server_tag, 1);
1818        }
1819    }
1820    if (error) aw_message(error);
1821}
1822
1823AW_window *create_probe_admin_window(AW_root *root, AW_CL cl_gb_main) {
1824    GBDATA           *gb_main = (GBDATA*)cl_gb_main;
1825    AW_window_simple *aws     = new AW_window_simple;
1826    bool              is_genom_db;
1827
1828    {
1829        GB_transaction ta(gb_main);
1830        is_genom_db = GEN_is_genome_db(gb_main, -1);
1831    }
1832
1833    aws->init(root, "PT_SERVER_ADMIN", "PT_SERVER ADMIN");
1834
1835    aws->load_xfig("pd_admin.fig");
1836
1837
1838    aws->callback(AW_POPUP_HELP, (AW_CL)"probeadmin.hlp");
1839    aws->at("help");
1840    aws->create_button("HELP", "HELP", "H");
1841
1842    aws->callback((AW_CB0)AW_POPDOWN);
1843    aws->at("close");
1844    aws->create_button("CLOSE", "CLOSE", "C");
1845
1846    aws->button_length(18);
1847
1848    aws->at("pt_server");
1849    awt_create_selection_list_on_pt_servers(aws, AWAR_PROBE_ADMIN_PT_SERVER, false);
1850
1851    aws->at("start");
1852    aws->callback(pd_start_pt_server);
1853    aws->create_button("START_SERVER", "Start server");
1854
1855    aws->at("kill");
1856    aws->callback(pd_kill_pt_server, 0);
1857    aws->create_button("KILL_SERVER", "Stop server");
1858
1859    aws->at("query");
1860    aws->callback(pd_query_pt_server);
1861    aws->create_button("CHECK_SERVER", "Check server");
1862
1863    aws->at("kill_all");
1864    aws->callback(pd_kill_pt_server, 1);
1865    aws->create_button("KILL_ALL_SERVERS", "Stop all servers");
1866
1867    aws->at("edit");
1868    aws->callback(awt_edit_arbtcpdat_cb, (AW_CL)gb_main);
1869    aws->create_button("CREATE_TEMPLATE", "Configure");
1870
1871    aws->at("export");
1872    aws->callback(pd_export_pt_server, (AW_CL)gb_main);
1873    aws->create_button("UPDATE_SERVER", "Build server");
1874
1875    if (is_genom_db) {
1876        aws->at("gene_server");
1877        aws->label("Gene server?");
1878        aws->create_toggle(AWAR_PROBE_CREATE_GENE_SERVER);
1879    }
1880
1881    return aws;
1882}
1883
1884// --------------------------------------------------------------------------------
1885// Probe group result visualization
1886
1887#define AWAR_PG_SELECTED_RESULT "tmp/pg_result/selected"
1888
1889static struct pg_global_struct {
1890    char              *awar_pg_result_filename;     // awar containing result filename
1891    AW_window_simple  *pg_groups_window;            // window showing groups
1892    AW_selection_list *selList;                     // list containing groups
1893    AW_root           *aw_root;
1894    AWT_canvas        *ntw;                         // canvas of main window
1895
1896    char   *pg_filename;                            // database containing results (from one result file)
1897    GBDATA *pg_main;                                // root-handle of probe-group-database
1898} pg_global;
1899
1900
1901static void pg_result_selected(AW_window * /* aww */, AW_CL cl_gb_main) {
1902
1903    AW_root *aw_root = pg_global.aw_root;
1904    long position = aw_root->awar(AWAR_PG_SELECTED_RESULT)->read_int();
1905
1906    if (position) { // ignore headline
1907        long i = 1;
1908
1909        GBDATA         *gb_main = (GBDATA*)cl_gb_main;
1910        GB_transaction  dummy(pg_global.pg_main);
1911        GB_transaction  dummy2(gb_main);
1912
1913        GBT_mark_all(gb_main, 0); // unmark all species
1914
1915        GBDATA *gb_species_data = GBT_get_species_data(gb_main);
1916        GBDATA *pg_group = GB_search(pg_global.pg_main, "probe_groups/group", GB_FIND);
1917        long count = 0;
1918        long marked = 0;
1919        for (; pg_group; pg_group=GB_nextChild(pg_group), ++i) {
1920            if (i==position) {
1921                GBDATA *pg_species = GB_search(pg_group, "species/name", GB_FIND);
1922                for (; pg_species; pg_species=GB_nextChild(pg_species), count++) {
1923                    const char *name           = GB_read_char_pntr(pg_species);
1924                    GBDATA     *gb_speciesname = GB_find_string(gb_species_data, "name", name, GB_IGNORE_CASE, SEARCH_GRANDCHILD);
1925                    if (gb_speciesname) {
1926                        GBDATA *gb_species = GB_get_father(gb_speciesname);
1927                        pd_assert(gb_species);
1928                        GB_write_flag(gb_species, 1); // mark species
1929                        if (!marked) { // select first species
1930                            aw_root->awar(AWAR_SPECIES_NAME)->write_string(name);
1931                        }
1932                        marked++;
1933                    }
1934                    else {
1935                        aw_message(GBS_global_string("No species '%s' in current DB", name));
1936                    }
1937                }
1938                break;
1939            }
1940        }
1941
1942        if (marked!=count) {
1943            aw_message(GBS_global_string("%li species were in group - %li species marked in database", count, marked));
1944        }
1945
1946        NT_group_not_marked_cb(0, pg_global.ntw);
1947    }
1948}
1949
1950static void create_probe_group_result_awars(AW_root *aw_root) {
1951    aw_root->awar_int(AWAR_PG_SELECTED_RESULT, 0);
1952}
1953
1954static void create_probe_group_result_sel_box(AW_root *aw_root, AW_window *aws, GBDATA *gb_main) {
1955    char *file_name = aw_root->awar(pg_global.awar_pg_result_filename)->read_string();
1956
1957    AW_selection_list *selList = pg_global.selList;
1958
1959    static bool awars_created;
1960    if (!awars_created) {
1961        create_probe_group_result_awars(aw_root);
1962        awars_created = 1;
1963    }
1964    aw_root->awar(AWAR_PG_SELECTED_RESULT)->write_int(0); // reset to element #0
1965
1966    if (selList==0) {
1967        aws->at("box");
1968        aws->callback(pg_result_selected, (AW_CL)gb_main);
1969        selList = pg_global.selList = aws->create_selection_list(AWAR_PG_SELECTED_RESULT, 2, 2);
1970    }
1971    else {
1972        selList->clear();
1973    }
1974
1975    GB_ERROR error = 0;
1976
1977    if (pg_global.pg_main) {
1978        GB_close(pg_global.pg_main);
1979        pg_global.pg_main = 0;
1980        freenull(pg_global.pg_filename);
1981    }
1982
1983    pg_global.aw_root = aw_root;
1984    pg_global.pg_filename = strdup(file_name);
1985    pg_global.pg_main = GB_open(file_name, "r");
1986
1987    if (pg_global.pg_main) {
1988        const char *reason = 0;
1989        int32_t i = 0;
1990        selList->insert("members | probes | fitness | quality | mintarget | mishit | probelen | birth", i++);
1991
1992        GB_transaction dummy(pg_global.pg_main);
1993        GBDATA *pg_group = GB_search(pg_global.pg_main, "probe_groups/group", GB_FIND);
1994        if (pg_group) {
1995            for (; pg_group; pg_group=GB_nextChild(pg_group), ++i) {
1996
1997                double fitness=-1, quality=-1, min_targets=-1;
1998                int mishit=-1, probelength=-1, birth=-1;
1999                int member_count = 0;
2000                int probe_count = 0;
2001
2002                GBDATA *field;
2003
2004                field = GB_entry(pg_group, "fitness");        if (field) fitness     = GB_read_float(field);
2005                field = GB_entry(pg_group, "quality");        if (field) quality     = GB_read_float(field);
2006                field = GB_entry(pg_group, "min_targets");    if (field) min_targets = GB_read_float(field);
2007                field = GB_entry(pg_group, "mishit");         if (field) mishit      = GB_read_int(field);
2008                field = GB_entry(pg_group, "probelength");    if (field) probelength = GB_read_int(field);
2009                field = GB_entry(pg_group, "birth");          if (field) birth       = GB_read_int(field);
2010
2011                GBDATA *species = GB_search(pg_group, "species/name", GB_FIND);
2012                for (; species; species=GB_nextChild(species)) member_count++;
2013
2014                GBDATA *probe = GB_search(pg_group, "probes/data", GB_FIND);
2015                for (; probe; probe=GB_nextChild(probe)) probe_count++;
2016
2017                char entry[200];
2018
2019                sprintf(entry, "%7i | %6i | %7.5f | %7.1f | %9.2f | %6i | %8i | %5i",
2020                        member_count,
2021                        probe_count,
2022                        fitness,
2023                        quality,
2024                        min_targets,
2025                        mishit,
2026                        probelength,
2027                        birth);
2028
2029                selList->insert(entry, i);
2030            }
2031        }
2032        else {
2033            reason = "probe_group/group - no such entry";
2034        }
2035
2036        if (reason) {
2037            error = GB_export_errorf("Error in database format (reason: %s)", reason);
2038            selList->insert(error, (int32_t)0);
2039        }
2040
2041        selList->update();
2042    }
2043    else {
2044        error = GB_export_errorf("Can't open database '%s'", file_name);
2045        freenull(pg_global.pg_filename);
2046    }
2047
2048    free(file_name);
2049
2050    if (error) {
2051        aw_message(error);
2052    }
2053}
2054
2055static void create_probe_group_groups_window(AW_window *aww, AW_CL) {
2056    AW_root *aw_root = aww->get_root();
2057    GBDATA  *gb_main = pg_global.ntw->gb_main;
2058
2059    if (pg_global.pg_groups_window==0) { // window was not created yet
2060        AW_window_simple *aws = new AW_window_simple;
2061
2062        aws->init(aw_root, "PG_RESULT_SELECTION", "Probe group results");
2063        aws->load_xfig("pg_select.fig");
2064
2065        aws->at("close");
2066        aws->callback((AW_CB0)AW_POPDOWN);
2067        aws->create_button("CLOSE", "CLOSE", "C");
2068
2069        aws->at("help");
2070        aws->callback(AW_POPUP_HELP, (AW_CL)"");
2071        aws->create_button("HELP", "HELP");
2072
2073        create_probe_group_result_sel_box(aw_root, aws, gb_main);
2074
2075        pg_global.pg_groups_window = aws;
2076    }
2077    else { // window already created -> refresh selection box
2078        create_probe_group_result_sel_box(aw_root, pg_global.pg_groups_window, gb_main);
2079    }
2080
2081    pg_global.pg_groups_window->show();
2082}
2083
2084AW_window *create_probe_group_result_window(AW_root *awr, AW_default cl_AW_canvas_ntw) {
2085    freenull(pg_global.awar_pg_result_filename);
2086    pg_global.ntw = (AWT_canvas*)cl_AW_canvas_ntw;
2087
2088    return awt_create_load_box(awr, "Load", "arb_probe_group result", ".", "arb", &pg_global.awar_pg_result_filename,
2089                               create_probe_group_groups_window, NULL, NULL, NULL, 0);
2090}
2091
Note: See TracBrowser for help on using the repository browser.