1 /****************************************************************\
2 *                                                                *
3 *  C4 dynamic programming library - code for models              *
4 *                                                                *
5 *  Guy St.C. Slater..   mailto:guy@ebi.ac.uk                     *
6 *  Copyright (C) 2000-2009.  All Rights Reserved.                *
7 *                                                                *
8 *  This source code is distributed under the terms of the        *
9 *  GNU General Public License, version 3. See the file COPYING   *
10 *  or http://www.gnu.org/licenses/gpl.txt for details            *
11 *                                                                *
12 *  If you use this code, please keep this notice intact.         *
13 *                                                                *
14 \****************************************************************/
15 
16 #ifndef INCLUDED_C4_H
17 #define INCLUDED_C4_H
18 
19 #ifdef __cplusplus
20 extern "C" {
21 #endif /* __cplusplus */
22 
23 #include <glib.h>
24 
25 #include "region.h"
26 #include "threadref.h"
27 
28 typedef gint C4_Score;
29 #define C4_IMPOSSIBLY_LOW_SCORE -987654321
30 #define C4_IMPOSSIBLY_HIGH_SCORE -(C4_IMPOSSIBLY_LOW_SCORE)
31 
32 /**/
33 
34 typedef C4_Score (*C4_CalcFunc)(gint query_pos, gint target_pos,
35                                 gpointer user_data);
36 /* Receives the position at the transition source */
37 
38 typedef void (*C4_PrepFunc)(Region *region, gpointer user_data);
39 /* To prepare subject region before starting DP */
40 
41 typedef C4_Score (*C4_StartFunc)(gint query_pos, gint target_pos,
42                                  gpointer user_data);
43 /* Receives the position at the transition source */
44 
45 typedef void (*C4_EndFunc)(C4_Score score,
46                            gint query_pos, gint target_pos,
47                            gpointer user_data);
48 /* Receives the position at the transition end */
49 
50 typedef C4_Score *(*C4_CellStartFunc)(gint query_pos, gint target_pos,
51                                       gpointer user_data);
52 /* Receives the position at the transition source */
53 
54 typedef void (*C4_CellEndFunc)(C4_Score *cell, gint cell_size,
55                                gint query_pos, gint target_pos,
56                                gpointer user_data);
57 /* Receives the position at the transition end */
58 
59 /**/
60 
61 typedef struct {
62          gchar *name;
63           gint  id;            /* Only set once the model is closed */
64      GPtrArray *input_transition_list;
65      GPtrArray *output_transition_list;
66      GPtrArray *src_shadow_list; /* Shadows starting at this state */
67 } C4_State;
68 
69 typedef enum {
70     C4_Protect_NONE      = (0<<0),
71     C4_Protect_OVERFLOW  = (1<<0),
72     C4_Protect_UNDERFLOW = (1<<1)
73 } C4_Protect;
74 
75 typedef struct {
76           gchar *name;
77            gint  id;         /* Only set once the model is closed */
78        C4_Score  max_score;
79     C4_CalcFunc  calc_func;  /* If NULL, use max_score     */
80           gchar *calc_macro; /* If NULL, use calc_func     */
81     C4_PrepFunc  init_func;  /* If NULL, no initialisation */
82           gchar *init_macro; /* If NULL, use init_func     */
83     C4_PrepFunc  exit_func;  /* If NULL, no initialisation */
84           gchar *exit_macro; /* If NULL, use exit_func     */
85      C4_Protect  protect;
86 } C4_Calc;
87 /* When {calc,init,exit}_macro is supplied,
88  * {calc,init,exit}_func must be set.
89  */
90 
91 typedef enum {
92     C4_Scope_ANYWHERE, /* Anywhere        */
93     C4_Scope_EDGE,     /* Query || Target */
94     C4_Scope_QUERY,    /* Query only      */
95     C4_Scope_TARGET,   /* Target only     */
96     C4_Scope_CORNER    /* Query && Target */
97 } C4_Scope;
98 
99 typedef struct {
100              C4_State *state;
101              C4_Scope  scope;
102      C4_CellStartFunc  cell_start_func;
103                 gchar *cell_start_macro;
104 } C4_StartState;
105 /* Start cell will be set to zero if cell_start_func is NULL */
106 
107 typedef struct {
108           C4_State *state;
109           C4_Scope  scope;
110     C4_CellEndFunc  cell_end_func;
111              gchar *cell_end_macro;
112 } C4_EndState;
113 
114 typedef enum {
115     C4_Label_NONE,
116     C4_Label_MATCH,
117     C4_Label_GAP,
118     C4_Label_NER,
119     C4_Label_5SS,
120     C4_Label_3SS,
121     C4_Label_INTRON,
122     C4_Label_SPLIT_CODON,
123     C4_Label_FRAMESHIFT
124 } C4_Label;
125 
126 typedef struct {
127             gchar *name;
128              gint  id;          /* Only set once the model is closed */
129          C4_State *input;
130          C4_State *output;
131           C4_Calc *calc; /* Zero scores are emitted for a NULL calc */
132              gint  advance_query;
133              gint  advance_target;
134          C4_Label  label;
135          gpointer  label_data;
136         GPtrArray *dst_shadow_list; /* Shadows ending on transition */
137 } C4_Transition;
138 
139 typedef struct {
140          gint  id;          /* Only set once the model is closed */
141         gchar *name;
142     GPtrArray *src_state_list;
143     GPtrArray *dst_transition_list;
144  C4_StartFunc  start_func;
145         gchar *start_macro;
146    C4_EndFunc  end_func;
147         gchar *end_macro;
148          gint  designation;  /* Only set once the model is closed */
149 } C4_Shadow;
150 
151 typedef struct {
152        gchar *name;
153         gint  id;
154         gint  advance_query;
155         gint  advance_target;
156      C4_Calc *calc;
157    GPtrArray *transition_list; /* Transitions using this portal */
158 } C4_Portal;
159 
160 typedef struct {
161             gchar *name;
162              gint  id;
163          C4_State *span_state;
164              gint  min_query;
165              gint  max_query;
166              gint  min_target;
167              gint  max_target;
168     C4_Transition *query_loop;  /* May be NULL */
169     C4_Transition *target_loop; /* May be NULL */
170 } C4_Span;
171 
172 typedef struct {
173             gchar  *name;
174         GPtrArray  *global_code_list;
175         GPtrArray  *local_code_list;
176         GPtrArray  *cflags_add_list;
177       C4_PrepFunc  init_func;  /* If NULL, no initialisation */
178             gchar *init_macro; /* If NULL, use init_func     */
179       C4_PrepFunc  exit_func;  /* If NULL, no initialisation */
180             gchar *exit_macro; /* If NULL, use exit_func     */
181         ThreadRef *thread_ref;
182          gboolean   is_open;
183         GPtrArray  *state_list;
184         GPtrArray  *transition_list;
185         GPtrArray  *shadow_list;
186         GPtrArray  *calc_list;
187         GPtrArray  *portal_list;
188         GPtrArray  *span_list;
189     C4_StartState  *start_state;
190       C4_EndState  *end_state;
191              gint   max_query_advance;  /* For convenience */
192              gint   max_target_advance; /* For convenience */
193              gint   total_shadow_designations;
194 } C4_Model;
195 
196 /**/
197 
198 C4_Model *C4_Model_create(gchar *name);
199           /* Model is created open */
200     void  C4_Model_destroy(C4_Model *model);
201 C4_Model *C4_Model_share(C4_Model *model);
202 
203 C4_State **C4_Model_build_state_map(C4_Model *src, C4_Model *dst);
204 C4_Transition **C4_Model_build_transition_map(C4_Model *src,
205                                               C4_Model *dst);
206 
207 /**/
208 
209 void C4_Model_make_stereo(C4_Model *model, gchar *suffix_a,
210                                            gchar *suffix_b);
211 void C4_Model_insert(C4_Model *target, C4_Model *insert,
212                      C4_State *src, C4_State *dst);
213 /* Inserts <insert> into <target> between <src> and <dst> */
214 
215 /**/
216 
217 void C4_Model_rename(C4_Model *model, gchar *name);
218 
219 C4_State *C4_Model_add_state(C4_Model *model, gchar *name);
220 
221  C4_Calc *C4_Model_add_calc(C4_Model *model, gchar *name,
222                        C4_Score max_score,
223                        C4_CalcFunc calc_func, gchar *calc_macro,
224                        C4_PrepFunc init_func, gchar *init_macro,
225                        C4_PrepFunc exit_func, gchar *exit_macro,
226                        C4_Protect protect);
227 /* calc_macro may contain %[QT][SPRE]
228  * which are expanded to {query,target}_{start,position,region_pos,end}
229  * in the generated code.
230  */
231 
232 C4_Transition *C4_Model_add_transition(C4_Model *model, gchar *name,
233                        C4_State *input, C4_State *output,
234                        gint advance_query, gint advance_target,
235                        C4_Calc *calc, C4_Label label,
236                        gpointer label_data);
237 /* NULL input implies START state, NULL output implies END state */
238 
239 GPtrArray *C4_Model_select_transitions(C4_Model *model, C4_Label label);
240 C4_Transition *C4_Model_select_single_transition(C4_Model *model,
241                                                  C4_Label label);
242 
243 #define C4_Transition_is_match(transition)            \
244           (transition->label == C4_Label_MATCH)
245 
246 #define C4_Transition_is_span(transition)             \
247           ((transition->input == transition->output)  \
248            &&  (!transition->calc))
249 /* Transition advance or target must be set, otherwise would be cyclic
250  */
251 
252 C4_Shadow *C4_Model_add_shadow(C4_Model *model, gchar *name,
253                     C4_State *src, C4_Transition *dst,
254                     C4_StartFunc start_func, gchar *start_macro,
255                     C4_EndFunc end_func, gchar *end_macro);
256 /* NULL src state implies START state,
257  * NULL output transition implies all transitions to the END state
258  */
259 void C4_Shadow_add_src_state(C4_Shadow *shadow, C4_State *src);
260 void C4_Shadow_add_dst_transition(C4_Shadow *shadow,
261                                   C4_Transition *dst);
262 
263 C4_Portal *C4_Model_add_portal(C4_Model *model, gchar *name,
264            C4_Calc *calc, gint advance_query, gint advance_target);
265 /* If terminal_range or join_range are NULL, a default is used.
266  */
267 
268 C4_Span *C4_Model_add_span(C4_Model *model, gchar *name,
269                            C4_State *span_state,
270                            gint min_query, gint max_query,
271                            gint min_target, gint max_target);
272 /* If range is NULL, a default is used.
273  */
274 
275 void C4_Model_append_codegen(C4_Model *model,
276                              gchar *global_code, gchar *local_code,
277                              gchar *cflags_add);
278 void C4_Model_clear_codegen(C4_Model *model);
279 
280 void C4_Model_configure_extra(C4_Model *model,
281                               C4_PrepFunc init_func, gchar *init_macro,
282                               C4_PrepFunc exit_func, gchar *exit_macro);
283 /* init_{func,macro} is called/included at start of DP functions,
284  * (after variable declarations, before anything else)
285  * exit_{func,macro} is called/included at the end of DP functions.
286  *
287  * {init,exit}_{func,macro} will be stripped from derived models,
288  * but {global,local}_code will not.
289  */
290 
291 void C4_Model_configure_start_state(C4_Model *model, C4_Scope scope,
292         C4_CellStartFunc cell_start_func, gchar *cell_start_macro);
293 void C4_Model_configure_end_state(C4_Model *model, C4_Scope scope,
294         C4_CellEndFunc cell_end_func, gchar *cell_end_macro);
295 /* C4_Model_configure_{start,end}_state()
296  *     will work on open or closed models.
297  */
298 
299 void C4_Model_print(C4_Model *model);
300 void C4_Model_dump_graphviz(C4_Model *model);
301 
302 void C4_Model_open(C4_Model *model);
303 void C4_Model_close(C4_Model *model);
304 
305 /**/
306 
307 /* Utility functions */
308 
309 gchar *C4_Scope_get_name(C4_Scope scope);
310 gchar *C4_Label_get_name(C4_Label label);
311 
312 gboolean C4_Model_path_is_possible(C4_Model *model, C4_State *src,
313                                                     C4_State *dst);
314 
315 void C4_Calc_init(C4_Calc *calc, Region *region,
316                   gpointer user_data);
317 
318 void C4_Calc_exit(C4_Calc *calc, Region *region,
319                   gpointer user_data);
320 
321 C4_Score C4_Calc_score(C4_Calc *calc, gint query_pos, gint target_pos,
322                        gpointer user_data);
323 
324 C4_Model *C4_Model_copy(C4_Model *model);
325 /* Returns a closed copy of the model */
326 
327 void C4_Model_remove_state(C4_Model *model, C4_State *state);
328 void C4_Model_remove_transition(C4_Model *model,
329                                 C4_Transition *transition);
330 
331 gboolean C4_Model_is_global(C4_Model *model);
332 gboolean C4_Model_is_local(C4_Model *model);
333 void C4_Model_remove_all_shadows(C4_Model *model);
334 
335 /**/
336 
337 typedef struct {
338          C4_Model  *original;
339          C4_Model  *derived;
340     C4_Transition **transition_map;
341 } C4_DerivedModel;
342 /* The transition_map maps derived_model transitions
343  * back to original_model transitions.
344  */
345 
346 C4_DerivedModel *C4_DerivedModel_create(C4_Model *original_model,
347                 C4_State *src, C4_State *dst,
348                 C4_Scope start_scope, C4_CellStartFunc cell_start_func,
349                 gchar *cell_start_macro,
350                 C4_Scope end_scope, C4_CellEndFunc cell_end_func,
351                 gchar *cell_end_macro);
352 /* A C4_DerivedModel will be created closed
353  */
354 
355 void  C4_DerivedModel_destroy(C4_DerivedModel *derived_model);
356 
357 #ifdef __cplusplus
358 }
359 #endif /* __cplusplus */
360 
361 #endif /* INCLUDED_C4_H */
362 
363