source: tags/ms_r16q2/MULTI_PROBE/MP_sondentopf.cxx

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