source: tags/arb_5.3/MULTI_PROBE/MP_sonde.cxx

Last change on this file was 6139, checked in by westram, 15 years ago
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.9 KB
Line 
1#include <MultiProbe.hxx>
2#include <stdlib.h>
3#include <string.h>
4#include <arbdbt.h>
5#include <aw_root.hxx>
6#include <awt_tree.hxx>
7#include <math.h>
8
9extern int MP_probe_design_send_data(T_PT_PDC  pdc);
10
11
12
13//###########################################################################
14//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Methoden Sonde ~~~~~~~~~~~~~~~~~~~~~~
15
16Sonde::Sonde(char* bezeichner, int allowed_mis, double outside_mis)
17{
18    kennung = strdup(bezeichner);
19    bitkennung = NULL;
20    // fuer Basissonden haben die Bitvektoren noch nicht die Volle laenge, da noch nicht bekannt ist, wieviele Sonden eingetragen werden
21    hitliste = NULL;
22    length_hitliste = 0;
23    minelem = 0;
24    maxelem = 0;
25    int anzahl_sonden = mp_gl_awars.no_of_probes;
26
27    Allowed_Mismatch = new long[anzahl_sonden];
28    Outside_Mismatch = new double[anzahl_sonden];
29    for (int i=0; i<anzahl_sonden; i++)
30    {
31        Allowed_Mismatch[i]=0;
32        Outside_Mismatch[i]=0;
33    }
34
35    Allowed_Mismatch[0] = allowed_mis;
36    Outside_Mismatch[0] = outside_mis;
37
38
39}
40
41Sonde::~Sonde()
42{
43    int i;
44
45    free(kennung);
46
47    for (i=0; i<length_hitliste ; i++) {
48        delete hitliste[i];             // Hits loeschen
49    }
50    delete [] hitliste;
51
52    delete [] Allowed_Mismatch;
53    delete [] Outside_Mismatch;
54    delete bitkennung;
55}
56
57void Sonde::print()
58{
59    printf("\nSonde %s\n------------------------------------------------\n", kennung);
60    bitkennung->print();
61    printf("Laenge hitliste %ld mit minelem %ld und maxelem %ld\n",length_hitliste,minelem, maxelem);
62    printf("Far %ld, Mor %ld, AllMM %ld, OutMM %f\n\n",kombi_far, kombi_mor, *Allowed_Mismatch, *Outside_Mismatch);
63}
64
65
66MO_Mismatch** Sonde::get_matching_species(BOOL match_kompl, int match_weight, int match_mis, char *match_seq, MO_Liste *convert, long *number_of_species)
67{
68    MO_Mismatch **ret_list   = NULL;
69    const char   *servername = MP_probe_pt_look_for_server();
70   
71    if (servername) {
72        char           *match_name, *match_mismatches, *match_wmismatches;
73        char            toksep[2];
74        T_PT_PDC        pdc;
75        T_PT_MATCHLIST  match_list;
76        char           *probe    = NULL;
77        char           *locs_error;
78        long            match_list_cnt;
79        bytestring      bs;
80        int             i        = 0;
81
82        mp_pd_gl.link = (aisc_com *)aisc_open(servername, &mp_pd_gl.com,AISC_MAGIC_NUMBER);
83
84        if (!mp_pd_gl.link) {
85            aw_message("Cannot contact Probe bank server ");
86            return NULL;
87        }
88        if (MP_init_local_com_struct() ) {
89            aw_message ("Cannot contact Probe bank server (2)");
90            return NULL;
91        }
92
93        aisc_create(mp_pd_gl.link,PT_LOCS, mp_pd_gl.locs,LOCS_PROBE_DESIGN_CONFIG, PT_PDC,  &pdc,   NULL);
94
95        if (MP_probe_design_send_data(pdc)) {
96            aw_message ("Connection to PT_SERVER lost (3)");
97            return NULL;
98        }
99
100        //aw_message("Running DB-query");
101
102        if (aisc_put(mp_pd_gl.link,PT_LOCS, mp_pd_gl.locs,
103                     LOCS_MATCH_REVERSED,       match_kompl,        // Komplement
104                     LOCS_MATCH_SORT_BY,        match_weight,       // Weighted
105                     LOCS_MATCH_COMPLEMENT,     0,              // ???
106                     LOCS_MATCH_MAX_MISMATCHES,     match_mis,      // Mismatches
107                     LOCS_MATCH_MAX_SPECIES,        100000,         // ???
108                     LOCS_SEARCHMATCH,          match_seq,      // Sequence
109                     NULL)){
110            free(probe);
111            aw_message ("Connection to PT_SERVER lost (4)");
112            return NULL;
113        }
114
115        bs.data = 0;
116        aisc_get( mp_pd_gl.link, PT_LOCS, mp_pd_gl.locs,
117                  LOCS_MATCH_LIST,  &match_list,
118                  LOCS_MATCH_LIST_CNT,  &match_list_cnt,
119                  LOCS_MP_MATCH_STRING, &bs,
120                  LOCS_ERROR,       &locs_error,
121                  NULL);
122        if (*locs_error) {
123            aw_message(locs_error);
124        }
125        free(locs_error);
126
127        toksep[0] = 1;
128        toksep[1] = 0;
129        if (bs.data)
130        {
131            ret_list = new MO_Mismatch*[match_list_cnt];
132
133            match_name = strtok(bs.data, toksep);
134            match_mismatches = strtok(0, toksep);
135            match_wmismatches = strtok(0, toksep);
136
137            while (match_name && match_mismatches && match_wmismatches)
138            {
139                ret_list[i] = new MO_Mismatch;
140                ret_list[i]->nummer = convert->get_index_by_entry(match_name);
141                if (match_weight == NON_WEIGHTED)
142                    ret_list[i]->mismatch = atof(match_mismatches);
143                else                            // WEIGHTED und WEIGHTED_PLUS_POS
144                    ret_list[i]->mismatch = atof(match_wmismatches);
145
146
147                match_name = strtok(0, toksep);
148                match_mismatches = strtok(0, toksep);
149                match_wmismatches = strtok(0, toksep);
150
151                i++;
152            }
153        }
154        else
155            aw_message("No matching species found.");
156
157        *number_of_species = match_list_cnt;
158
159        aisc_close(mp_pd_gl.link);
160        free(bs.data);
161
162    }
163    return ret_list;
164}
165
166
167double Sonde::check_for_min(long k, MO_Mismatch** probebacts,long laenge)
168{
169    long    i = k+1;
170    double  min;
171
172    min = probebacts[k]->mismatch;                  // min ist gleich mismatch des ersten MOs
173    while ( (i<laenge) && (probebacts[k]->nummer == probebacts[i]->nummer))
174    {
175        if (min > probebacts[i]->mismatch)              // wenn min groesser ist als mismatch des naechsten MOs
176            min = probebacts[i]->mismatch;              // setze min uf groesse des naechsten
177        i++;                                // checke naechsten MO
178    }
179    return min;
180}
181
182
183
184int Sonde::gen_Hitliste(MO_Liste *Bakterienliste)
185    // Angewandt auf eine frische Sonde generiert diese Methode die Hitliste durch eine Anfrage an die Datenbank, wobei
186    // der Name der Sonde uebergeben wird
187{
188    MO_Mismatch**   probebacts;
189    long        i,k;            // Zaehlervariable
190    long        laenge = 0;
191    double      mm_to_search = 0;
192    int         mm_int_to_search = 0;
193
194
195    // DATENBANKAUFRUF
196    mm_to_search = mp_gl_awars.greyzone + mp_gl_awars.outside_mismatches_difference + get_Allowed_Mismatch_no(0);
197    if (mm_to_search > (int) mm_to_search)
198        mm_int_to_search = (int) mm_to_search + 1;
199    else
200        mm_int_to_search = (int) mm_to_search;
201
202    probebacts = get_matching_species(mp_gl_awars.complement,
203                                      mp_gl_awars.weightedmismatches,
204                                      mm_int_to_search,
205                                      kennung,
206                                      Bakterienliste,
207                                      &laenge);
208
209
210    // ACHTUNG probebacts mit laenge enthaelt nur laenge-1 Eintraege von 0 bis laenge -2
211    if (!laenge || !probebacts)
212    {
213        if (!laenge)
214            aw_message("This probe matches no species!");
215        if (!probebacts)
216        {
217            aw_message("This probe matches no species!");
218            return 11;
219        }
220        return 1;
221    }
222
223    //Ptrliste ist Nullterminiert
224    //Sortieren des Baktnummernfeldes:
225
226    heapsort(laenge,probebacts);
227
228    double min_mm;          //Minimaler Mismatch
229    // laenge ist die Anzahl der Eintraege in probebact
230    // Korrekturschleife, um Mehrfachtreffer auf das gleiche Bakterium abzufangen
231
232    for (k=0 ; k < laenge-1 ; k++ )
233    {
234        if (probebacts[k]->nummer == probebacts[k+1]->nummer)
235        {
236            min_mm = check_for_min(k,probebacts,laenge);
237            probebacts[k]->mismatch = min_mm;
238            while ( (k<laenge-1) && (probebacts[k]->nummer == probebacts[k+1]->nummer))
239            {
240                probebacts[k+1]->mismatch = min_mm;
241                k++;
242            }
243        }
244    }
245
246    // Das hier funktioniert, da Liste sortiert ist
247    minelem = probebacts[0]->nummer;
248    maxelem = probebacts[laenge-1]->nummer;
249
250    // Probebacts besteht aus eintraegen der Art (Nummer, Mismatch)
251    hitliste = new Hit*[laenge+1];
252    for (i=0; i<laenge+1; i++)
253        hitliste[i]=NULL;
254
255    for (i=0; i<laenge; i++)
256    {
257        hitliste[i] = new Hit( probebacts[i]->nummer);
258        hitliste[i]->set_mismatch_at_pos(0, probebacts[i]->mismatch);
259    }
260    length_hitliste = laenge;
261
262    // Loesche hitflags wieder
263    long bl_index = 0;
264    Bakt_Info** baktliste = Bakterienliste->get_mo_liste();
265    Bakt_Info** bl_elem = baktliste+1;
266    while ( bl_elem[bl_index] )
267    {
268        bl_elem[bl_index]->kill_flag();
269        bl_index++;
270    }
271    // Loeschen der Temps
272    for (i=0;i<laenge;i++)
273    {
274        delete probebacts[i];
275    }
276    delete [] probebacts;
277    return 0;
278}
279
280
281
282Hit* Sonde::get_hitdata_by_number(long index)
283{
284    // Gibt Zeiger auf ein Hit Element zurueck, welches an Stelle index steht, vorerst nur zur Ausgabe gedacht
285    if (hitliste && (index < length_hitliste))
286        return hitliste[index];
287    else
288        return NULL;
289}
290
291
292
293
294void Sonde::heapsort(long feldlaenge, MO_Mismatch** Nr_Mm_Feld)
295    // Heapsortfunktion, benutzt sink(), sortiert Feld von longs
296{
297    long        m=0,i=0;
298    MO_Mismatch*    tmpmm;
299
300    for (i=(feldlaenge-1)/2;i>-1;i--)
301        sink(i,feldlaenge-1,Nr_Mm_Feld);
302    for (m=feldlaenge-1;m>0;m--)
303    {
304        tmpmm =  Nr_Mm_Feld[0];
305        Nr_Mm_Feld[0] =  Nr_Mm_Feld[m];
306        Nr_Mm_Feld[m] = tmpmm;
307
308        sink(0,m-1,Nr_Mm_Feld);
309    }
310}
311
312void Sonde::sink(long i,long t,MO_Mismatch** A)
313    // Algorithmus fuer den Heapsort
314{
315    long        j,k;
316    MO_Mismatch*    tmpmm;
317
318    j = 2*i;
319    k = j+1;
320    if (j <= t)
321    {
322        if (A[i]->nummer >= A[j]->nummer)
323            j = i;
324        if (k <= t)
325            if (A[k]->nummer > A[j]->nummer)
326                j = k;
327        if (i != j)
328        {
329            tmpmm = A[i]; A[i] = A[j]; A[j] = tmpmm;
330            sink(j,t,A);
331        }
332    }
333}
334
335void Sonde::set_bitkennung(Bitvector* bv)
336{
337    bitkennung = bv;
338}
339
340
341
342//########################################################################################################
343/* Bakt_Info haengt in der MO_Liste drinnen. Hier werden u.a. die Hitflags gespeichert
344 */
345//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Methoden Bakt_Info~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
346
347Bakt_Info::Bakt_Info(const char* n)
348{
349    name = strdup(n);                       //MEL  (match_name in mo_liste)
350    hit_flag = 0;
351}
352
353Bakt_Info::~Bakt_Info()
354{
355    free(name);
356    hit_flag = 0;
357}
358
359
360//##########################################################################################################
361// Hit speichert die  Trefferinformation
362//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Methoden Hit
363
364Hit::Hit(long baktnummer)
365{
366    // Mismatch Array mit Laenge = anzahl Sonden in Experiment
367    int i=0;
368    mismatch = new double[mp_gl_awars.no_of_probes+1];
369    for (i=0; i<mp_gl_awars.no_of_probes+1; i++)
370        mismatch[i]=101;
371
372    baktid = baktnummer;
373}
374
375Hit::~Hit()
376{
377    delete [] mismatch;
378}
379
380//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Note: See TracBrowser for help on using the repository browser.