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