source: branches/ali/MULTI_PROBE/MP_sondentopf.cxx

Last change on this file was 19297, checked in by westram, 2 years ago
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.3 KB
Line 
1// ============================================================= //
2//                                                               //
3//   File      : MP_sondentopf.cxx                               //
4//   Purpose   :                                                 //
5//                                                               //
6//   Institute of Microbiology (Technical University Munich)     //
7//   http://www.arb-home.de/                                     //
8//                                                               //
9// ============================================================= //
10
11#include "MultiProbe.hxx"
12#include "MP_probe.hxx"
13
14#include <AP_TreeColors.hxx>
15#include <aw_msg.hxx>
16#include <arbdbt.h>
17
18#include <cmath>
19
20ST_Container::ST_Container(int anz_sonden) {
21    long laenge_markierte;
22
23    Sondennamen = new List<char>;
24
25    Auswahlliste = new MO_Liste;
26    Bakterienliste = new MO_Liste;
27
28    GB_ERROR error = Bakterienliste->get_all_species(mp_gl_awars.ptserver);
29    if (error) {
30        aw_message(error);
31    }
32
33    if (pt_server_different) return;
34    laenge_markierte = Auswahlliste->fill_marked_bakts();
35
36    anz_elem_unmarked = Bakterienliste->debug_get_current()-1 - laenge_markierte;
37    // STATISTIK
38
39    anzahl_basissonden =  anz_sonden;
40
41    cachehash = GBS_create_hash(anzahl_basissonden + 1, GB_IGNORE_CASE);
42    // hashlaenge darf nicht 0 sein, groesser schadet nicht
43
44    sondentopf = new Sondentopf(Bakterienliste, Auswahlliste);
45    // Momentan wird auf diesem sondentopf gearbeitet
46}
47
48
49ST_Container::~ST_Container() {
50    char* Sname;
51    Sonde* csonde;
52
53    delete Bakterienliste;
54    delete Auswahlliste;
55    delete sondentopf;
56
57    Sname = Sondennamen->get_first();
58    while (Sname) {
59        csonde = get_cached_sonde(Sname);
60        delete csonde;
61        free(Sname);
62        Sondennamen->remove_first();
63        Sname = Sondennamen->get_first();
64    }
65
66    delete Sondennamen;
67    GBS_free_hash(cachehash);
68}
69
70
71
72Sonde* ST_Container::cache_Sonde(const char *name, int allowed_mis, double outside_mis) {
73    char*  name_for_plist = ARB_strdup(name);
74    int    num_probes     = mp_gl_awars.no_of_probes;
75    Sonde* s              = new Sonde(name, num_probes, allowed_mis, outside_mis);
76
77    Sondennamen->insert_as_first(name_for_plist);
78    s->gen_Hitliste(Bakterienliste);
79
80    GBS_write_hash(cachehash, name, (long) s);
81    // Reine Sonde plus Hitliste geschrieben, der Zeiger auf die Sonde liegt als long gecastet im Hash
82    return s;
83}
84
85Sonde* ST_Container::get_cached_sonde(const char* name) {
86    return name ? (Sonde*)GBS_read_hash(cachehash, name) : NULp;
87}
88
89// ############################################################################################
90/*
91  Zu jeder Kombination von Mehrfachsonden gehoert ein Sondentopf. Dieser enthaelt eine Liste mit
92  Sonden und eine Liste mit Kombinationen aus diesen Sonden. Die Kombinationen entstehen aus den
93  Sonden und/oder aus Kombinationen durch Verknuepfung mit der Methode Probe_AND.
94*/
95// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Methoden SONDENTOPF ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
96
97Sondentopf::Sondentopf(MO_Liste *BL, MO_Liste *AL) {
98    // @@@ use assertions here?
99    if (!BL) GBK_terminate("List of species is empty");
100    if (!AL) GBK_terminate("List of marked species is empty");
101
102    Listenliste = new List<void*>;
103    color_hash = GBS_create_hash(BL->get_laenge()*1.25+1, GB_IGNORE_CASE);
104
105    BaktList    = BL;
106    Auswahllist = AL;
107
108    Listenliste->insert_as_last((void**) new List<Sonde>);
109}
110
111
112
113Sondentopf::~Sondentopf() {
114    // darf nur delete auf die listenliste machen, nicht auf die MO_Lists, da die zu dem ST_Container gehoeren
115    Sonde *stmp = NULp;
116
117    List<Sonde> *ltmp = LIST(Listenliste->get_first());
118    if (ltmp) {
119        stmp = ltmp->get_first();
120    }
121    while (ltmp) {
122        while (stmp) {
123            ltmp->remove_first();
124            stmp = ltmp->get_first();
125        }
126        Listenliste->remove_first();
127        delete ltmp;
128        ltmp = LIST(Listenliste->get_first());
129    }
130
131    delete Listenliste;
132    GBS_free_hash(color_hash);
133}
134
135
136
137void Sondentopf::put_Sonde(const char *name, int allowed_mis, double outside_mis) {
138    if (!name) GBK_terminate("No name specified for species");
139
140    positiontype  pos;
141    ST_Container *stc         = mp_main->get_stc();
142    List<Sonde>  *Sondenliste = LIST(Listenliste->get_first());
143    Sonde        *s;
144    int           i           = 0;
145
146    if (!Sondenliste) {
147        Sondenliste = new List<Sonde>;
148        Listenliste->insert_as_last((void**) Sondenliste);
149    }
150
151    s = stc->get_cached_sonde(name);
152    if (!s) {
153        s = stc->cache_Sonde(name, allowed_mis, outside_mis);
154    }
155    pos = Sondenliste->insert_as_last(s);
156    if (! s->get_bitkennung())
157        s->set_bitkennung(new Bitvector(((int) pos)));
158    s->set_far(0);
159    s->set_mor(pos);
160    s->get_bitkennung()->setbit(pos-1);
161    // im cache steht die Mismatch info noch an Stelle 0. Hier muss sie an Stelle pos  verschoben werden
162    if (pos!=0)
163        for (i=0; i<s->get_length_hitliste(); i++)
164            if (s->get_hitdata_by_number(i))
165                s->get_hitdata_by_number(i)->set_mismatch_at_pos(pos, s->get_hitdata_by_number(i)->get_mismatch_at_pos(0));
166}
167
168
169double** Sondentopf::gen_Mergefeld() {
170    // Zaehler
171    int         i, j;
172
173    Sonde*      sonde;
174
175    List<Sonde>*    Sondenliste = LIST(Listenliste->get_first());
176    long        alle_bakterien = BaktList->debug_get_current()-1;
177    long        H_laenge, sondennummer;
178    double**        Mergefeld = new double*[alle_bakterien+1];
179
180    for (i=0; i<alle_bakterien+1; i++) {
181        Mergefeld[i] = new double[mp_gl_awars.no_of_probes];
182        for (j=0; j<mp_gl_awars.no_of_probes; j++) { // LOOP_VECTORIZED
183            Mergefeld[i][j] = 100;
184        }
185    }
186
187    sondennummer=0;
188    sonde = Sondenliste->get_first();
189    while (sonde) {
190        H_laenge = sonde->get_length_hitliste();
191        for (i=0; i<H_laenge; i++) {
192            Mergefeld[sonde->get_hitdata_by_number(i)->get_baktid()][sondennummer] =
193                sonde->get_hitdata_by_number(i)->get_mismatch_at_pos(0);
194        }
195
196        sondennummer++;
197        sonde = Sondenliste->get_next();
198    }
199
200    return Mergefeld;
201}
202
203probe_tabs* Sondentopf::fill_Stat_Arrays() {
204    // erstmal generische Felder
205    List<Sonde>*    Sondenliste = LIST(Listenliste->get_first());
206    long        feldlen = (long) pow(3.0, (int)(mp_gl_awars.no_of_probes));
207    int*        markierte = new int[feldlen];                   // MEL
208    int*        unmarkierte = new int[feldlen];                 // MEL
209    int     i=0, j=0;
210    long        alle_bakterien = BaktList->debug_get_current()-1;
211    double**    Mergefeld;
212    int*        AllowedMismatchFeld = new int[mp_gl_awars.no_of_probes];
213    Sonde*      sonde;
214
215    sonde = Sondenliste->get_first();
216    for (i=0; i<mp_gl_awars.no_of_probes; i++) {
217        AllowedMismatchFeld[i] = (int) sonde->get_Allowed_Mismatch_no(0);
218        sonde = Sondenliste->get_next();
219    }
220
221
222    for (i=0; i<feldlen; i++) { // LOOP_VECTORIZED[!>=5]
223        markierte[i] = 0;
224        unmarkierte[i] = 0;
225    }
226
227    int faktor=0;
228    Mergefeld = gen_Mergefeld();
229
230
231    for (i=0; i < alle_bakterien+1; i++) {
232        if (BaktList->get_entry_by_index(i)) {
233            long wertigkeit = 0;
234            for (j=0; j<mp_gl_awars.no_of_probes; j++) {
235                if (Mergefeld[i][j] <= ((double) AllowedMismatchFeld[j] + (double) mp_gl_awars.greyzone)) {
236                    faktor = 0;
237                }
238                else if (Mergefeld[i][j] <= ((double) AllowedMismatchFeld[j] +
239                                             (double) mp_gl_awars.greyzone +
240                                             mp_gl_awars.outside_mismatches_difference))
241                {
242                    faktor = 1;
243                }
244                else {
245                    faktor = 2;
246                }
247
248                wertigkeit += faktor * (long) pow(3, j);
249            }
250
251            if (Auswahllist->get_index_by_entry(BaktList->get_entry_by_index(i))) {
252                markierte[wertigkeit]++;
253            }
254            else {
255                unmarkierte[wertigkeit]++;
256            }
257        }
258    }
259
260    for (i=0; i<alle_bakterien+1; i++) {
261        delete [] Mergefeld[i];
262    }
263    delete [] Mergefeld;
264    delete [] AllowedMismatchFeld;
265    probe_tabs *pt = new probe_tabs(markierte, unmarkierte, feldlen);           // MEL (sollte bei Andrej passieren
266    return pt;
267}
268
269
270void Sondentopf::gen_color_hash(positiontype anz_sonden) {
271    if (!anz_sonden) return;
272
273    List<Sonde>*    Sondenliste = LIST(Listenliste->get_first());
274    double**        Mergefeld;
275    long        alle_bakterien = BaktList->debug_get_current() -1;
276    int*        AllowedMismatchFeld = new int[mp_gl_awars.no_of_probes];            // MEL
277    int*        rgb = new int[3];                               // MEL
278    Sonde*      sonde;
279    int         i=0, j=0;
280
281    sonde = Sondenliste->get_first();
282    for (i=0; i<mp_gl_awars.no_of_probes; i++) {
283        AllowedMismatchFeld[i] = (int) sonde->get_Allowed_Mismatch_no(0);
284        sonde = Sondenliste->get_next();
285    }
286
287
288    Mergefeld = gen_Mergefeld();
289
290
291    for (i=1; i < alle_bakterien+1; i++) {
292        rgb[0]=0; rgb[1]=0; rgb[2]=0;
293
294        for (j=0; j<mp_gl_awars.no_of_probes; j++) {
295            if (Mergefeld[i][j] <= ((double) AllowedMismatchFeld[j] + (double) mp_gl_awars.greyzone + mp_gl_awars.outside_mismatches_difference)) {
296                rgb[j%3]++;
297            }
298        }
299
300        int color = 0;
301
302        if      (!rgb[0] && !rgb[1] && !rgb[2]) { color = AWT_GC_BLACK; }
303        else if ( rgb[0] && !rgb[1] && !rgb[2]) { color = AWT_GC_RED; }
304        else if (!rgb[0] &&  rgb[1] && !rgb[2]) { color = AWT_GC_GREEN; }
305        else if (!rgb[0] && !rgb[1] &&  rgb[2]) { color = AWT_GC_BLUE; }
306        else if ( rgb[0] &&  rgb[1] && !rgb[2]) { color = AWT_GC_YELLOW; }
307        else if ( rgb[0] && !rgb[1] &&  rgb[2]) { color = AWT_GC_MAGENTA; }
308        else if (!rgb[0] &&  rgb[1] &&  rgb[2]) { color = AWT_GC_CYAN; }
309        else if ( rgb[0] &&  rgb[1] &&  rgb[2]) { color = AWT_GC_WHITE; }
310        else {
311            GBK_terminate("logic error: should never be reached");
312        }
313
314        GBS_write_hash(color_hash, BaktList->get_entry_by_index(i), (long)color);
315    }
316
317    for (i=0; i<alle_bakterien+1; i++)
318        delete [] Mergefeld[i];
319    delete [] Mergefeld;
320
321
322    delete [] AllowedMismatchFeld;
323    delete [] rgb;
324}
325
Note: See TracBrowser for help on using the repository browser.