source: tags/arb-6.0/MULTI_PROBE/MP_sondentopf.cxx

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