1 /****************************************************************\
2 * *
3 * Module for various affine gapped 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 #include <string.h> /* For strlen() */
17 #include "affine.h"
18
Affine_ArgumentSet_create(Argument * arg)19 Affine_ArgumentSet *Affine_ArgumentSet_create(Argument *arg){
20 register ArgumentSet *as;
21 static Affine_ArgumentSet aas;
22 if(arg){
23 as = ArgumentSet_create("Affine Model Options");
24 ArgumentSet_add_option(as, 'o', "gapopen", "penalty",
25 "Affine gap open penalty", "-12",
26 Argument_parse_int, &aas.gap_open);
27 ArgumentSet_add_option(as, 'e', "gapextend", "penalty",
28 "Affine gap extend penalty", "-4",
29 Argument_parse_int, &aas.gap_extend);
30 ArgumentSet_add_option(as, '\0', "codongapopen", "penalty",
31 "Codon affine gap open penalty", "-18",
32 Argument_parse_int, &aas.codon_gap_open);
33 ArgumentSet_add_option(as, '\0', "codongapextend", "penalty",
34 "Codon affine gap extend penalty", "-8",
35 Argument_parse_int, &aas.codon_gap_extend);
36 Argument_absorb_ArgumentSet(arg, as);
37 if(aas.gap_open > 0)
38 g_warning("Gap open penalty [%d] should be negative",
39 aas.gap_open);
40 if(aas.gap_extend > 0)
41 g_warning("Gap extend penalty [%d] should be negative",
42 aas.gap_extend);
43 if(aas.codon_gap_open > 0)
44 g_warning("Codon gap open penalty [%d] should be negative",
45 aas.codon_gap_open);
46 if(aas.codon_gap_extend > 0)
47 g_warning("Codon gap extend penalty [%d] should be negative",
48 aas.codon_gap_extend);
49 }
50 return &aas;
51 }
52
53 /**/
54
Affine_Data_init(Affine_Data * ad,Sequence * query,Sequence * target,gboolean translate_both)55 void Affine_Data_init(Affine_Data *ad,
56 Sequence *query, Sequence *target,
57 gboolean translate_both){
58 register Match_Type match_type
59 = Match_Type_find(query->alphabet->type,
60 target->alphabet->type,
61 translate_both);
62 Ungapped_Data_init(&ad->ud, query, target, match_type);
63 if(!ad->aas)
64 ad->aas = Affine_ArgumentSet_create(NULL);
65 return;
66 }
67
Affine_Data_create(Sequence * query,Sequence * target,gboolean translate_both)68 Affine_Data *Affine_Data_create(Sequence *query, Sequence *target,
69 gboolean translate_both){
70 register Affine_Data *ad = g_new0(Affine_Data, 1);
71 Affine_Data_init(ad, query, target, translate_both);
72 return ad;
73 }
74
Affine_Data_clear(Affine_Data * ad)75 void Affine_Data_clear(Affine_Data *ad){
76 Ungapped_Data_clear(&ad->ud);
77 return;
78 }
79
Affine_Data_destroy(Affine_Data * ad)80 void Affine_Data_destroy(Affine_Data *ad){
81 Affine_Data_clear(ad);
82 g_free(ad);
83 return;
84 }
85
86 /**/
87
affine_gap_open_calc_func(gint query_pos,gint target_pos,gpointer user_data)88 static C4_Score affine_gap_open_calc_func(gint query_pos,
89 gint target_pos,
90 gpointer user_data){
91 register Affine_Data *ad = (Affine_Data*)user_data;
92 return ad->aas->gap_open;
93 }
94
95 static gchar *affine_gap_open_calc_macro = "(ad->aas->gap_open)";
96
affine_gap_extend_calc_func(gint query_pos,gint target_pos,gpointer user_data)97 static C4_Score affine_gap_extend_calc_func(gint query_pos,
98 gint target_pos,
99 gpointer user_data){
100 register Affine_Data *ad = (Affine_Data*)user_data;
101 return ad->aas->gap_extend;
102 }
103
104 static gchar *affine_gap_extend_calc_macro = "(ad->aas->gap_extend)";
105
106 /**/
107
affine_codon_gap_open_calc_func(gint query_pos,gint target_pos,gpointer user_data)108 static C4_Score affine_codon_gap_open_calc_func(gint query_pos,
109 gint target_pos,
110 gpointer user_data){
111 register Affine_Data *ad = (Affine_Data*)user_data;
112 return ad->aas->codon_gap_open;
113 }
114
115 static gchar *affine_codon_gap_open_calc_macro = "(ad->aas->codon_gap_open)";
116
affine_codon_gap_extend_calc_func(gint query_pos,gint target_pos,gpointer user_data)117 static C4_Score affine_codon_gap_extend_calc_func(gint query_pos,
118 gint target_pos,
119 gpointer user_data){
120 register Affine_Data *ad = (Affine_Data*)user_data;
121 return ad->aas->codon_gap_extend;
122 }
123
124 static gchar *affine_codon_gap_extend_calc_macro = "(ad->aas->codon_gap_extend)";
125
126 /**/
127
Affine_Model_Type_get_name(Affine_Model_Type type)128 gchar *Affine_Model_Type_get_name(Affine_Model_Type type){
129 register gchar *model_name = NULL;
130 switch(type){
131 case Affine_Model_Type_GLOBAL:
132 model_name = "global";
133 break;
134 case Affine_Model_Type_BESTFIT:
135 model_name = "bestfit";
136 break;
137 case Affine_Model_Type_LOCAL:
138 model_name = "local";
139 break;
140 case Affine_Model_Type_OVERLAP:
141 model_name = "overlap";
142 break;
143 default:
144 g_error("Unknown affine model type [%d]", type);
145 break;
146 }
147 return model_name;
148 }
149
Affine_create(Affine_Model_Type type,Alphabet_Type query_type,Alphabet_Type target_type,gboolean translate_both)150 C4_Model *Affine_create(Affine_Model_Type type,
151 Alphabet_Type query_type,
152 Alphabet_Type target_type,
153 gboolean translate_both){
154 register C4_Scope scope = C4_Scope_ANYWHERE;
155 register C4_Model *affine;
156 register C4_State *insert_state, *delete_state;
157 register C4_Transition *match_transition;
158 register C4_Calc *gap_open_calc, *gap_extend_calc;
159 register Affine_ArgumentSet *aas = Affine_ArgumentSet_create(NULL);
160 register Match_Type match_type = Match_Type_find(query_type,
161 target_type, translate_both);
162 register C4_CalcFunc gap_open_calc_func = NULL,
163 gap_extend_calc_func = NULL;
164 register gchar *gap_open_calc_macro = NULL,
165 *gap_extend_calc_macro = NULL;
166 register gchar *model_name = Affine_Model_Type_get_name(type);
167 affine = Ungapped_create(match_type);
168 switch(type){
169 case Affine_Model_Type_GLOBAL:
170 scope = C4_Scope_CORNER;
171 break;
172 case Affine_Model_Type_BESTFIT:
173 scope = C4_Scope_QUERY;
174 break;
175 case Affine_Model_Type_LOCAL:
176 scope = C4_Scope_ANYWHERE;
177 break;
178 case Affine_Model_Type_OVERLAP:
179 scope = C4_Scope_EDGE;
180 break;
181 default:
182 g_error("Unknown affine model type [%d]", type);
183 break;
184 }
185 g_assert(model_name);
186 model_name = g_strdup_printf("affine:%s:%s", model_name,
187 Match_Type_get_name(match_type));
188 C4_Model_rename(affine, model_name);
189 g_free(model_name);
190 C4_Model_configure_start_state(affine, scope, NULL, NULL);
191 C4_Model_configure_end_state(affine, scope, NULL, NULL);
192 C4_Model_open(affine);
193 insert_state = C4_Model_add_state(affine, "insert");
194 delete_state = C4_Model_add_state(affine, "delete");
195 match_transition = C4_Model_select_single_transition(affine,
196 C4_Label_MATCH);
197 g_assert(match_transition);
198 if(MAX(match_transition->advance_query,
199 match_transition->advance_target) == 3){
200 gap_open_calc_func = affine_codon_gap_open_calc_func;
201 gap_extend_calc_func = affine_codon_gap_extend_calc_func;
202 gap_open_calc_macro = affine_codon_gap_open_calc_macro;
203 gap_extend_calc_macro = affine_codon_gap_extend_calc_macro;
204 } else {
205 gap_open_calc_func = affine_gap_open_calc_func;
206 gap_extend_calc_func = affine_gap_extend_calc_func;
207 gap_open_calc_macro = affine_gap_open_calc_macro;
208 gap_extend_calc_macro = affine_gap_extend_calc_macro;
209 }
210 gap_open_calc = C4_Model_add_calc(affine, "gap open",
211 aas->gap_open,
212 gap_open_calc_func, gap_open_calc_macro,
213 NULL, NULL, NULL, NULL, C4_Protect_NONE);
214 gap_extend_calc = C4_Model_add_calc(affine, "gap extend",
215 aas->gap_extend,
216 gap_extend_calc_func, gap_extend_calc_macro,
217 NULL, NULL, NULL, NULL, C4_Protect_NONE);
218 /**/
219 /* Transitions from match */
220 C4_Model_add_transition(affine, "match to insert",
221 match_transition->input, insert_state,
222 match_transition->advance_query, 0,
223 gap_open_calc, C4_Label_GAP, NULL);
224 C4_Model_add_transition(affine, "match to delete",
225 match_transition->input, delete_state,
226 0, match_transition->advance_target,
227 gap_open_calc, C4_Label_GAP, NULL);
228 /* Transitions from insert */
229 C4_Model_add_transition(affine, "insert",
230 insert_state, insert_state,
231 match_transition->advance_query, 0,
232 gap_extend_calc, C4_Label_GAP, NULL);
233 C4_Model_add_transition(affine, "insert to match",
234 insert_state, match_transition->output, 0, 0,
235 NULL, C4_Label_NONE, NULL);
236 /* Transitions from delete */
237 C4_Model_add_transition(affine, "delete",
238 delete_state, delete_state,
239 0, match_transition->advance_target,
240 gap_extend_calc, C4_Label_GAP, NULL);
241 C4_Model_add_transition(affine, "delete to match",
242 delete_state, match_transition->output, 0, 0,
243 NULL, C4_Label_NONE, NULL);
244 /**/
245 C4_Model_add_portal(affine, "match portal",
246 match_transition->calc,
247 match_transition->advance_query,
248 match_transition->advance_target);
249 /**/
250 C4_Model_append_codegen(affine,
251 "#include \"affine.h\"\n",
252 "register Affine_Data *ad = (Affine_Data*)user_data;\n", NULL);
253 C4_Model_close(affine);
254 return affine;
255 }
256
257