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