source: tags/ms_r18q1/MULTI_PROBE/MP_sondentopf.cxx

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