1/*
2 *  This file contains some utility functions required by both, MFE and
3 *  partition function version of hairpin loop evaluation
4 */
5
6struct hc_hp_def_dat {
7  int                       n;
8  unsigned char             *mx;
9  unsigned char             **mx_window;
10  unsigned int              *sn;
11  int                       *hc_up;
12  void                      *hc_dat;
13  vrna_callback_hc_evaluate *hc_f;
14};
15
16
17PRIVATE unsigned char
18hc_hp_cb_def(int            i,
19             int            j,
20             int            k,
21             int            l,
22             unsigned char  d,
23             void           *data);
24
25
26PRIVATE unsigned char
27hc_hp_cb_def_window(int           i,
28                    int           j,
29                    int           k,
30                    int           l,
31                    unsigned char d,
32                    void          *data);
33
34
35PRIVATE unsigned char
36hc_hp_cb_def_user(int           i,
37                  int           j,
38                  int           k,
39                  int           l,
40                  unsigned char d,
41                  void          *data);
42
43
44PRIVATE unsigned char
45hc_hp_cb_def_user_window(int            i,
46                         int            j,
47                         int            k,
48                         int            l,
49                         unsigned char  d,
50                         void           *data);
51
52
53PRIVATE INLINE vrna_callback_hc_evaluate *
54prepare_hc_hp_def(vrna_fold_compound_t  *fc,
55                  struct hc_hp_def_dat  *dat);
56
57
58PRIVATE INLINE vrna_callback_hc_evaluate *
59prepare_hc_hp_def_window(vrna_fold_compound_t *fc,
60                         struct hc_hp_def_dat *dat);
61
62
63/*
64 #################################
65 # BEGIN OF FUNCTION DEFINITIONS #
66 #################################
67 */
68PRIVATE unsigned char
69hc_hp_cb_def(int            i,
70             int            j,
71             int            k,
72             int            l,
73             unsigned char  d,
74             void           *data)
75{
76  int                   u, p, q;
77  unsigned char         eval;
78  struct hc_hp_def_dat  *dat = (struct hc_hp_def_dat *)data;
79
80  eval = (char)0;
81
82  if (j > i) {
83    /* linear case */
84    p = i;
85    q = j;
86    u = q - p - 1;
87  } else {
88    /* circular case */
89    p = j;
90    q = i;
91    u = dat->n - q + p - 1;
92  }
93
94  if (dat->mx[dat->n * p + q] & VRNA_CONSTRAINT_CONTEXT_HP_LOOP) {
95    eval = (unsigned char)1;
96    if (dat->hc_up[i + 1] < u)
97      eval = (unsigned char)0;
98  }
99
100  return eval;
101}
102
103
104PRIVATE unsigned char
105hc_hp_cb_def_window(int           i,
106                    int           j,
107                    int           k,
108                    int           l,
109                    unsigned char d,
110                    void          *data)
111{
112  int                   u;
113  unsigned char         eval;
114  struct hc_hp_def_dat  *dat = (struct hc_hp_def_dat *)data;
115
116  eval = (unsigned char)0;
117
118  u = j - i - 1;
119
120  if (dat->mx_window[i][j - i] & VRNA_CONSTRAINT_CONTEXT_HP_LOOP) {
121    eval = (unsigned char)1;
122    if (dat->hc_up[i + 1] < u)
123      eval = (unsigned char)0;
124  }
125
126  return eval;
127}
128
129
130PRIVATE unsigned char
131hc_hp_cb_def_user(int           i,
132                  int           j,
133                  int           k,
134                  int           l,
135                  unsigned char d,
136                  void          *data)
137{
138  unsigned char         eval;
139  struct hc_hp_def_dat  *dat = (struct hc_hp_def_dat *)data;
140
141  eval  = hc_hp_cb_def(i, j, k, l, d, data);
142  eval  = (dat->hc_f(i, j, k, l, d, dat->hc_dat)) ? eval : (unsigned char)0;
143
144  return eval;
145}
146
147
148PRIVATE unsigned char
149hc_hp_cb_def_user_window(int            i,
150                         int            j,
151                         int            k,
152                         int            l,
153                         unsigned char  d,
154                         void           *data)
155{
156  unsigned char         eval;
157  struct hc_hp_def_dat  *dat = (struct hc_hp_def_dat *)data;
158
159  eval  = hc_hp_cb_def_window(i, j, k, l, d, data);
160  eval  = (dat->hc_f(i, j, k, l, d, dat->hc_dat)) ? eval : (unsigned char)0;
161
162  return eval;
163}
164
165
166PRIVATE INLINE vrna_callback_hc_evaluate *
167prepare_hc_hp_def(vrna_fold_compound_t  *fc,
168                  struct hc_hp_def_dat  *dat)
169{
170  dat->mx     = fc->hc->mx;
171  dat->hc_up  = fc->hc->up_hp;
172  dat->n      = fc->length;
173  dat->sn     = fc->strand_number;
174
175  if (fc->hc->f) {
176    dat->hc_f   = fc->hc->f;
177    dat->hc_dat = fc->hc->data;
178    return &hc_hp_cb_def_user;
179  }
180
181  return &hc_hp_cb_def;
182}
183
184
185PRIVATE INLINE vrna_callback_hc_evaluate *
186prepare_hc_hp_def_window(vrna_fold_compound_t *fc,
187                         struct hc_hp_def_dat *dat)
188{
189  dat->mx_window  = fc->hc->matrix_local;
190  dat->hc_up      = fc->hc->up_hp;
191  dat->n          = fc->length;
192  dat->sn         = fc->strand_number;
193
194  if (fc->hc->f) {
195    dat->hc_f   = fc->hc->f;
196    dat->hc_dat = fc->hc->data;
197    return &hc_hp_cb_def_user_window;
198  }
199
200  return &hc_hp_cb_def_window;
201}
202