1/* 2 * This file contains soft constraints wrappers for exterior loop evaluation (partition function version) 3 */ 4struct sc_ext_exp_dat; 5 6typedef FLT_OR_DBL (sc_ext_exp_cb)(int i, 7 int j, 8 int k, 9 int l, 10 struct sc_ext_exp_dat *data); 11 12typedef FLT_OR_DBL (sc_ext_exp_red_up)(int i, 13 int j, 14 struct sc_ext_exp_dat *data); 15 16typedef FLT_OR_DBL (sc_ext_exp_split)(int i, 17 int j, 18 int k, 19 struct sc_ext_exp_dat *data); 20 21struct sc_ext_exp_dat { 22 FLT_OR_DBL **up; 23 24 sc_ext_exp_cb *red_ext; 25 sc_ext_exp_cb *red_stem; 26 sc_ext_exp_red_up *red_up; 27 sc_ext_exp_split *split; 28 29 vrna_callback_sc_exp_energy *user_cb; 30 void *user_data; 31 32 /* below attributes are for comparative structure prediction */ 33 int n_seq; 34 unsigned int **a2s; 35 FLT_OR_DBL ***up_comparative; 36 37 vrna_callback_sc_exp_energy **user_cb_comparative; 38 void **user_data_comparative; 39}; 40 41 42PRIVATE INLINE FLT_OR_DBL 43sc_ext_exp_cb_red(int i, 44 int j, 45 int k, 46 int l, 47 struct sc_ext_exp_dat *data); 48 49 50PRIVATE INLINE FLT_OR_DBL 51sc_ext_exp_cb_red_comparative(int i, 52 int j, 53 int k, 54 int l, 55 struct sc_ext_exp_dat *data); 56 57 58PRIVATE INLINE FLT_OR_DBL 59sc_ext_exp_cb_red_user_to_ext(int i, 60 int j, 61 int k, 62 int l, 63 struct sc_ext_exp_dat *data); 64 65 66PRIVATE INLINE FLT_OR_DBL 67sc_ext_exp_cb_red_user_to_ext_comparative(int i, 68 int j, 69 int k, 70 int l, 71 struct sc_ext_exp_dat *data); 72 73 74PRIVATE INLINE FLT_OR_DBL 75sc_ext_exp_cb_red_user_def_to_ext(int i, 76 int j, 77 int k, 78 int l, 79 struct sc_ext_exp_dat *data); 80 81 82PRIVATE INLINE FLT_OR_DBL 83sc_ext_exp_cb_red_user_def_to_ext_comparative(int i, 84 int j, 85 int k, 86 int l, 87 struct sc_ext_exp_dat *data); 88 89 90PRIVATE INLINE FLT_OR_DBL 91sc_ext_exp_cb_red_user_to_stem(int i, 92 int j, 93 int k, 94 int l, 95 struct sc_ext_exp_dat *data); 96 97 98PRIVATE INLINE FLT_OR_DBL 99sc_ext_exp_cb_red_user_to_stem_comparative(int i, 100 int j, 101 int k, 102 int l, 103 struct sc_ext_exp_dat *data); 104 105 106PRIVATE INLINE FLT_OR_DBL 107sc_ext_exp_cb_red_user_def_to_stem(int i, 108 int j, 109 int k, 110 int l, 111 struct sc_ext_exp_dat *data); 112 113 114PRIVATE INLINE FLT_OR_DBL 115sc_ext_exp_cb_red_user_def_to_stem_comparative(int i, 116 int j, 117 int k, 118 int l, 119 struct sc_ext_exp_dat *data); 120 121 122PRIVATE INLINE FLT_OR_DBL 123sc_ext_exp_cb_up(int i, 124 int j, 125 struct sc_ext_exp_dat *data); 126 127 128PRIVATE INLINE FLT_OR_DBL 129sc_ext_exp_cb_up_comparative(int i, 130 int j, 131 struct sc_ext_exp_dat *data); 132 133 134PRIVATE INLINE FLT_OR_DBL 135sc_ext_exp_cb_up_user(int i, 136 int j, 137 struct sc_ext_exp_dat *data); 138 139 140PRIVATE INLINE FLT_OR_DBL 141sc_ext_exp_cb_up_user_comparative(int i, 142 int j, 143 struct sc_ext_exp_dat *data); 144 145 146PRIVATE INLINE FLT_OR_DBL 147sc_ext_exp_cb_up_user_def(int i, 148 int j, 149 struct sc_ext_exp_dat *data); 150 151 152PRIVATE INLINE FLT_OR_DBL 153sc_ext_exp_cb_up_user_def_comparative(int i, 154 int j, 155 struct sc_ext_exp_dat *data); 156 157 158PRIVATE INLINE FLT_OR_DBL 159sc_ext_exp_cb_split_user(int i, 160 int j, 161 int k, 162 struct sc_ext_exp_dat *data); 163 164 165PRIVATE INLINE FLT_OR_DBL 166sc_ext_exp_cb_split_user_comparative(int i, 167 int j, 168 int k, 169 struct sc_ext_exp_dat *data); 170 171 172PRIVATE INLINE void 173init_sc_ext_exp(vrna_fold_compound_t *fc, 174 struct sc_ext_exp_dat *sc_wrapper); 175 176 177PRIVATE INLINE void 178free_sc_ext_exp(struct sc_ext_exp_dat *sc_wrapper); 179 180 181PRIVATE INLINE FLT_OR_DBL 182sc_ext_exp_cb_red(int i, 183 int j, 184 int k, 185 int l, 186 struct sc_ext_exp_dat *data) 187{ 188 unsigned int start_2, length_1, length_2; 189 FLT_OR_DBL q_sc, **sc_up; 190 191 sc_up = data->up; 192 193 q_sc = 1.; 194 195 length_1 = k - i; 196 start_2 = l + 1; 197 length_2 = j - l; 198 199 if (length_1 != 0) 200 q_sc *= sc_up[i][length_1]; 201 202 if (length_2 != 0) 203 q_sc *= sc_up[start_2][length_2]; 204 205 return q_sc; 206} 207 208 209PRIVATE INLINE FLT_OR_DBL 210sc_ext_exp_cb_red_comparative(int i, 211 int j, 212 int k, 213 int l, 214 struct sc_ext_exp_dat *data) 215{ 216 unsigned int s, start_2, length_1, length_2, **a2s; 217 FLT_OR_DBL q_sc, ***sc_up; 218 219 sc_up = data->up_comparative; 220 a2s = data->a2s; 221 222 q_sc = 1.; 223 224 for (s = 0; s < data->n_seq; s++) { 225 if (sc_up[s]) { 226 length_1 = a2s[s][k] - a2s[s][i]; 227 start_2 = a2s[s][l] + 1; 228 length_2 = a2s[s][j] - a2s[s][l]; 229 230 if (length_1 != 0) 231 q_sc *= sc_up[s][a2s[s][i]][length_1]; 232 233 if (length_2 != 0) 234 q_sc *= sc_up[s][start_2][length_2]; 235 } 236 } 237 238 return q_sc; 239} 240 241 242PRIVATE INLINE FLT_OR_DBL 243sc_ext_exp_cb_red_user_to_ext(int i, 244 int j, 245 int k, 246 int l, 247 struct sc_ext_exp_dat *data) 248{ 249 return data->user_cb(i, j, k, l, VRNA_DECOMP_EXT_EXT, data->user_data); 250} 251 252 253PRIVATE INLINE FLT_OR_DBL 254sc_ext_exp_cb_red_user_to_ext_comparative(int i, 255 int j, 256 int k, 257 int l, 258 struct sc_ext_exp_dat *data) 259{ 260 unsigned int s; 261 FLT_OR_DBL q_sc; 262 263 q_sc = 1.; 264 265 for (s = 0; s < data->n_seq; s++) 266 q_sc *= 267 data->user_cb_comparative[s](i, j, k, l, VRNA_DECOMP_EXT_EXT, data->user_data_comparative[s]); 268 269 return q_sc; 270} 271 272 273PRIVATE INLINE FLT_OR_DBL 274sc_ext_exp_cb_red_user_def_to_ext(int i, 275 int j, 276 int k, 277 int l, 278 struct sc_ext_exp_dat *data) 279{ 280 return sc_ext_exp_cb_red(i, j, k, l, data) * 281 sc_ext_exp_cb_red_user_to_ext(i, j, k, l, data); 282} 283 284 285PRIVATE INLINE FLT_OR_DBL 286sc_ext_exp_cb_red_user_def_to_ext_comparative(int i, 287 int j, 288 int k, 289 int l, 290 struct sc_ext_exp_dat *data) 291{ 292 return sc_ext_exp_cb_red_comparative(i, j, k, l, data) * 293 sc_ext_exp_cb_red_user_to_ext_comparative(i, j, k, l, data); 294} 295 296 297PRIVATE INLINE FLT_OR_DBL 298sc_ext_exp_cb_red_user_to_stem(int i, 299 int j, 300 int k, 301 int l, 302 struct sc_ext_exp_dat *data) 303{ 304 return data->user_cb(i, j, k, l, VRNA_DECOMP_EXT_STEM, data->user_data); 305} 306 307 308PRIVATE INLINE FLT_OR_DBL 309sc_ext_exp_cb_red_user_to_stem_comparative(int i, 310 int j, 311 int k, 312 int l, 313 struct sc_ext_exp_dat *data) 314{ 315 unsigned int s; 316 FLT_OR_DBL q_sc; 317 318 q_sc = 1.; 319 320 for (s = 0; s < data->n_seq; s++) 321 q_sc *= 322 data->user_cb_comparative[s](i, j, k, l, VRNA_DECOMP_EXT_STEM, 323 data->user_data_comparative[s]); 324 325 return q_sc; 326} 327 328 329PRIVATE INLINE FLT_OR_DBL 330sc_ext_exp_cb_red_user_def_to_stem(int i, 331 int j, 332 int k, 333 int l, 334 struct sc_ext_exp_dat *data) 335{ 336 return sc_ext_exp_cb_red(i, j, k, l, data) * 337 sc_ext_exp_cb_red_user_to_stem(i, j, k, l, data); 338} 339 340 341PRIVATE INLINE FLT_OR_DBL 342sc_ext_exp_cb_red_user_def_to_stem_comparative(int i, 343 int j, 344 int k, 345 int l, 346 struct sc_ext_exp_dat *data) 347{ 348 return sc_ext_exp_cb_red_comparative(i, j, k, l, data) * 349 sc_ext_exp_cb_red_user_to_stem_comparative(i, j, k, l, data); 350} 351 352 353PRIVATE INLINE FLT_OR_DBL 354sc_ext_exp_cb_up(int i, 355 int j, 356 struct sc_ext_exp_dat *data) 357{ 358 unsigned int length; 359 FLT_OR_DBL q_sc, **sc_up; 360 361 sc_up = data->up; 362 length = j - i + 1; 363 q_sc = 1.; 364 365 if (length != 0) 366 q_sc *= sc_up[i][length]; 367 368 return q_sc; 369} 370 371 372PRIVATE INLINE FLT_OR_DBL 373sc_ext_exp_cb_up_comparative(int i, 374 int j, 375 struct sc_ext_exp_dat *data) 376{ 377 unsigned int length, s, **a2s; 378 FLT_OR_DBL q_sc, ***sc_up; 379 380 a2s = data->a2s; 381 sc_up = data->up_comparative; 382 383 q_sc = 1.; 384 385 for (s = 0; s < data->n_seq; s++) { 386 length = a2s[s][j - 1] - a2s[s][i]; 387 388 if (length != 0) 389 q_sc *= sc_up[s][a2s[s][i]][length]; 390 } 391 392 return q_sc; 393} 394 395 396PRIVATE INLINE FLT_OR_DBL 397sc_ext_exp_cb_up_user(int i, 398 int j, 399 struct sc_ext_exp_dat *data) 400{ 401 return data->user_cb(i, j, i, j, VRNA_DECOMP_EXT_UP, data->user_data); 402} 403 404 405PRIVATE INLINE FLT_OR_DBL 406sc_ext_exp_cb_up_user_comparative(int i, 407 int j, 408 struct sc_ext_exp_dat *data) 409{ 410 unsigned int s; 411 FLT_OR_DBL q_sc; 412 413 q_sc = 1.; 414 for (s = 0; s < data->n_seq; s++) 415 q_sc *= 416 data->user_cb_comparative[s](i, j, i, j, VRNA_DECOMP_EXT_UP, data->user_data_comparative[s]); 417 418 return q_sc; 419} 420 421 422PRIVATE INLINE FLT_OR_DBL 423sc_ext_exp_cb_up_user_def(int i, 424 int j, 425 struct sc_ext_exp_dat *data) 426{ 427 return sc_ext_exp_cb_up(i, j, data) * 428 sc_ext_exp_cb_up_user(i, j, data); 429} 430 431 432PRIVATE INLINE FLT_OR_DBL 433sc_ext_exp_cb_up_user_def_comparative(int i, 434 int j, 435 struct sc_ext_exp_dat *data) 436{ 437 return sc_ext_exp_cb_up_comparative(i, j, data) * 438 sc_ext_exp_cb_up_user_comparative(i, j, data); 439} 440 441 442PRIVATE INLINE FLT_OR_DBL 443sc_ext_exp_cb_split_user(int i, 444 int j, 445 int k, 446 struct sc_ext_exp_dat *data) 447{ 448 return data->user_cb(i, j, k - 1, k, VRNA_DECOMP_EXT_EXT_EXT, data->user_data); 449} 450 451 452PRIVATE INLINE FLT_OR_DBL 453sc_ext_exp_cb_split_user_comparative(int i, 454 int j, 455 int k, 456 struct sc_ext_exp_dat *data) 457{ 458 unsigned int s; 459 FLT_OR_DBL q_sc; 460 461 q_sc = 1.; 462 463 for (s = 0; s < data->n_seq; s++) 464 q_sc *= 465 data->user_cb_comparative[s](i, j, k - 1, k, VRNA_DECOMP_EXT_EXT_EXT, 466 data->user_data_comparative[s]); 467 468 return q_sc; 469} 470 471 472PRIVATE INLINE void 473init_sc_ext_exp(vrna_fold_compound_t *fc, 474 struct sc_ext_exp_dat *sc_wrapper) 475{ 476 vrna_sc_t *sc, **scs; 477 478 sc_wrapper->up = NULL; 479 sc_wrapper->user_cb = NULL; 480 sc_wrapper->user_data = NULL; 481 sc_wrapper->n_seq = 1; 482 sc_wrapper->a2s = NULL; 483 sc_wrapper->up_comparative = NULL; 484 sc_wrapper->user_cb_comparative = NULL; 485 sc_wrapper->user_data_comparative = NULL; 486 487 /* no soft constraints by default */ 488 sc_wrapper->red_ext = NULL; 489 sc_wrapper->red_stem = NULL; 490 sc_wrapper->red_up = NULL; 491 sc_wrapper->split = NULL; 492 493 switch (fc->type) { 494 case VRNA_FC_TYPE_SINGLE: 495 sc = fc->sc; 496 497 if (sc) { 498 sc_wrapper->up = sc->exp_energy_up; 499 sc_wrapper->user_cb = sc->exp_f; 500 sc_wrapper->user_data = sc->data; 501 502 /* bind correct wrapper functions */ 503 if (sc->exp_energy_up) { 504 if (sc->exp_f) { 505 sc_wrapper->red_ext = &sc_ext_exp_cb_red_user_def_to_ext; 506 sc_wrapper->red_stem = &sc_ext_exp_cb_red_user_def_to_stem; 507 sc_wrapper->red_up = &sc_ext_exp_cb_up_user_def; 508 sc_wrapper->split = &sc_ext_exp_cb_split_user; 509 } else { 510 sc_wrapper->red_ext = &sc_ext_exp_cb_red; 511 sc_wrapper->red_stem = &sc_ext_exp_cb_red; 512 sc_wrapper->red_up = &sc_ext_exp_cb_up; 513 } 514 } else if (sc->exp_f) { 515 sc_wrapper->red_ext = &sc_ext_exp_cb_red_user_to_ext; 516 sc_wrapper->red_stem = &sc_ext_exp_cb_red_user_to_stem; 517 sc_wrapper->red_up = &sc_ext_exp_cb_up_user; 518 sc_wrapper->split = &sc_ext_exp_cb_split_user; 519 } 520 } 521 522 break; 523 524 case VRNA_FC_TYPE_COMPARATIVE: 525 scs = fc->scs; 526 sc_wrapper->n_seq = fc->n_seq; 527 sc_wrapper->a2s = fc->a2s; 528 529 if (scs) { 530 unsigned int s; 531 532 sc_wrapper->up_comparative = (FLT_OR_DBL ***)vrna_alloc( 533 sizeof(FLT_OR_DBL * *) * fc->n_seq); 534 sc_wrapper->user_cb_comparative = 535 (vrna_callback_sc_exp_energy **)vrna_alloc( 536 sizeof(vrna_callback_sc_exp_energy *) * fc->n_seq); 537 sc_wrapper->user_data_comparative = (void **)vrna_alloc(sizeof(void *) * fc->n_seq); 538 539 int provides_sc_up = 0; 540 int provides_sc_user_cb = 0; 541 542 for (s = 0; s < fc->n_seq; s++) { 543 if (scs[s]) { 544 sc_wrapper->up_comparative[s] = scs[s]->exp_energy_up; 545 sc_wrapper->user_cb_comparative[s] = scs[s]->exp_f; 546 sc_wrapper->user_data_comparative[s] = scs[s]->data; 547 if (scs[s]->exp_energy_up) 548 provides_sc_up = 1; 549 550 if (scs[s]->exp_f) 551 provides_sc_user_cb = 1; 552 553 /* bind the correct wrapper functions */ 554 if (provides_sc_up) { 555 if (provides_sc_user_cb) { 556 sc_wrapper->red_ext = &sc_ext_exp_cb_red_user_def_to_ext_comparative; 557 sc_wrapper->red_stem = &sc_ext_exp_cb_red_user_def_to_stem_comparative; 558 sc_wrapper->red_up = &sc_ext_exp_cb_up_user_def_comparative; 559 sc_wrapper->split = &sc_ext_exp_cb_split_user_comparative; 560 } else { 561 sc_wrapper->red_ext = &sc_ext_exp_cb_red_comparative; 562 sc_wrapper->red_stem = &sc_ext_exp_cb_red_comparative; 563 sc_wrapper->red_up = &sc_ext_exp_cb_up_comparative; 564 } 565 } else if (provides_sc_user_cb) { 566 sc_wrapper->red_ext = &sc_ext_exp_cb_red_user_to_ext_comparative; 567 sc_wrapper->red_stem = &sc_ext_exp_cb_red_user_to_stem_comparative; 568 sc_wrapper->red_up = &sc_ext_exp_cb_up_user_comparative; 569 sc_wrapper->split = &sc_ext_exp_cb_split_user_comparative; 570 } 571 } 572 } 573 } 574 575 break; 576 } 577} 578 579 580PRIVATE INLINE void 581free_sc_ext_exp(struct sc_ext_exp_dat *sc_wrapper) 582{ 583 free(sc_wrapper->up_comparative); 584 free(sc_wrapper->user_cb_comparative); 585 free(sc_wrapper->user_data_comparative); 586} 587