1 // TAB_MM_PRMFIT.CPP
2
3 // Copyright (C) 1998 Tommi Hassinen.
4
5 // This package is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2 of the License, or
8 // (at your option) any later version.
9
10 // This package is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14
15 // You should have received a copy of the GNU General Public License
16 // along with this package; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
19 /*################################################################################################*/
20
21 #include "libghemicalconfig2.h"
22 #include "tab_mm_prmfit.h"
23
24 #include "typerule.h"
25 #include "utility.h"
26
27 #include "local_i18n.h"
28
29 #include <cstring>
30 #include <iomanip>
31 #include <fstream>
32 #include <sstream>
33 #include <algorithm>
34 using namespace std;
35
36 /*################################################################################################*/
37
prmfit_tables(const char * p1)38 prmfit_tables::prmfit_tables(const char * p1)
39 {
40 path = new char[strlen(p1) + 1];
41 strcpy(path, p1);
42
43 ifstream file;
44 file.unsetf(ios::dec | ios::oct | ios::hex);
45
46 ostringstream fns;
47 char buffer[1024];
48
49 ostream * ostr = NULL; // do not print output.
50 // ostream * ostr = & cout; // print output to cout.
51
52 /*##############################################*/
53 /*##############################################*/
54
55 fns.str(""); // blank the filename!
56 fns << path << "/atomtypes.txt" << ends;
57
58 file.open(fns.str().c_str(), ios::in);
59
60 if (ostr != NULL) (* ostr) << _("reading file \"") << fns.str() << "\": ";
61
62 while (file.peek() != '#') // #end
63 {
64 if (file.peek() == '0') // 0x????
65 {
66 prmfit_at newat;
67 file >> newat.atomtype[0];
68 file >> newat.atomtype[1];
69
70 file >> newat.vdw_R >> newat.vdw_E;
71 file >> newat.formal_charge;
72 file >> newat.flags;
73
74 while (file.peek() != '(') file.get();
75 newat.tr = new typerule(& file, ostr);
76
77 while (file.get() != '\"');
78 file.getline(buffer, sizeof(buffer), '\"');
79 newat.description = new char[strlen(buffer) + 1];
80 strcpy(newat.description, buffer);
81
82 at2_vector.push_back(newat);
83 }
84
85 file.getline(buffer, sizeof(buffer));
86 }
87
88 file.close();
89
90 if (ostr != NULL) (* ostr) << _("found ") << at2_vector.size() << _(" atomtypes.") << endl;
91
92 /*##############################################*/
93 /*##############################################*/
94
95 fns.str(""); // blank the filename!
96 fns << path << "/parameters1.txt" << ends;
97
98 file.open(fns.str().c_str(), ios::in);
99
100 if (ostr != NULL) (* ostr) << _("reading file \"") << fns.str() << "\": ";
101
102 while (file.peek() != '#') // #end
103 {
104 if (file.peek() == '0') // 0x????
105 {
106 prmfit_bs tmp; char bt[16];
107 file >> tmp.atmtp[0] >> tmp.atmtp[1] >> bt;
108 file >> tmp.opt >> tmp.fc >> tmp.ci;
109
110 tmp.bndtp = bondtype(bt[0]);
111 bs_vector.push_back(tmp);
112 }
113
114 file.getline(buffer, sizeof(buffer));
115 }
116
117 file.close();
118
119 if (ostr != NULL) (* ostr) << _("found ") << bs_vector.size() << _(" bs-terms.") << endl;
120
121 /*##############################################*/
122 /*##############################################*/
123
124 fns.str(""); // blank the filename!
125 fns << path << "/parameters2.txt" << ends;
126
127 file.open(fns.str().c_str(), ios::in);
128
129 if (ostr != NULL) (* ostr) << _("reading file \"") << fns.str() << "\": ";
130
131 while (file.peek() != '#') // #end
132 {
133 if (file.peek() == '0') // 0x????
134 {
135 prmfit_ab tmp; char bt[16];
136 file >> tmp.atmtp[0] >> tmp.atmtp[1] >> tmp.atmtp[2] >> bt;
137 file >> tmp.opt >> tmp.fc;
138
139 for (i32s n1 = 0;n1 < 2;n1++) tmp.bndtp[n1] = bondtype(bt[n1]);
140 ab_vector.push_back(tmp);
141 }
142
143 file.getline(buffer, sizeof(buffer));
144 }
145
146 file.close();
147
148 if (ostr != NULL) (* ostr) << _("found ") << ab_vector.size() << _(" ab-terms.") << endl;
149
150 /*##############################################*/
151 /*##############################################*/
152
153 fns.str(""); // blank the filename!
154 fns << path << "/parameters3.txt" << ends;
155
156 file.open(fns.str().c_str(), ios::in);
157
158 if (ostr != NULL) (* ostr) << _("reading file \"") << fns.str() << "\": ";
159
160 while (file.peek() != '#') // #end
161 {
162 if (file.peek() == '0') // 0x????
163 {
164 prmfit_tr tmp; char bt[16];
165 file >> tmp.atmtp[0] >> tmp.atmtp[1] >> tmp.atmtp[2] >> tmp.atmtp[3] >> bt;
166 file >> tmp.fc1 >> tmp.fc2 >> tmp.fc3;
167
168 for (i32s n1 = 0;n1 < 3;n1++) tmp.bndtp[n1] = bondtype(bt[n1]);
169 tr_vector.push_back(tmp);
170 }
171
172 file.getline(buffer, sizeof(buffer));
173 }
174
175 file.close();
176
177 if (ostr != NULL) (* ostr) << _("found ") << tr_vector.size() << _(" tr-terms.") << endl;
178
179 /*##############################################*/
180 /*##############################################*/
181
182 fns.str(""); // blank the filename!
183 fns << path << "/parameters4.txt" << ends;
184
185 file.open(fns.str().c_str(), ios::in);
186
187 if (ostr != NULL) (* ostr) << _("reading file \"") << fns.str() << "\": ";
188
189 while (file.peek() != '#') // #end
190 {
191 if (file.peek() == '0') // 0x????
192 {
193 prmfit_op tmp; char bt[16];
194 file >> tmp.atmtp[0] >> tmp.atmtp[1] >> tmp.atmtp[2] >> tmp.atmtp[3] >> bt;
195 file >> tmp.opt >> tmp.fc;
196
197 for (i32s n1 = 0;n1 < 3;n1++) tmp.bndtp[n1] = bondtype(bt[n1]);
198 op_vector.push_back(tmp);
199 }
200
201 file.getline(buffer, sizeof(buffer));
202 }
203
204 file.close();
205
206 if (ostr != NULL) (* ostr) << _("found ") << op_vector.size() << _(" op-terms.") << endl;
207
208 /*##############################################*/
209 /*##############################################*/
210
211 fns.str(""); // blank the filename!
212 }
213
~prmfit_tables(void)214 prmfit_tables::~prmfit_tables(void)
215 {
216 for (i32u n1 = 0;n1 < at2_vector.size();n1++)
217 {
218 delete at2_vector[n1].tr;
219 delete[] at2_vector[n1].description;
220 }
221
222 delete[] path;
223 }
224
PrintAllTypeRules(ostream & p1)225 void prmfit_tables::PrintAllTypeRules(ostream & p1)
226 {
227 for (i32u n1 = 0;n1 < at2_vector.size();n1++)
228 {
229 p1 << (n1 + 1) << ": 0x" << hex << setw(4) << setfill('0') << at2_vector[n1].atomtype << dec;
230 p1 << " (" << (* at2_vector[n1].tr) << ") \"" << at2_vector[n1].description << "\"" << endl;
231 }
232
233 p1 << at2_vector.size() << _(" entries.") << endl;
234 }
235
UpdateTypes(setup * su)236 i32u prmfit_tables::UpdateTypes(setup * su)
237 {
238 model * mdl = su->GetModel();
239
240 if (mdl->verbosity >= 3)
241 {
242 ostringstream str;
243 str << _("Setting up atom types and formal charges...") << endl << ends;
244
245 mdl->PrintToLog(str.str().c_str());
246 }
247
248 i32u errors = 0;
249
250 // determine the atomtypes for all atoms, not just MM atoms (might need to skip the virtual atoms of SF if eng2???).
251 // determine the atomtypes for all atoms, not just MM atoms (might need to skip the virtual atoms of SF if eng2???).
252 // determine the atomtypes for all atoms, not just MM atoms (might need to skip the virtual atoms of SF if eng2???).
253
254 for (iter_al it1 = mdl->GetAtomsBegin();it1 != mdl->GetAtomsEnd();it1++)
255 {
256 i32u at_range[2];
257
258 at_range[0] = 0;
259 while (true)
260 {
261 if (at_range[0] == at2_vector.size()) break;
262 if ((at2_vector[at_range[0]].atomtype[0] >> 8) == (* it1).el.GetAtomicNumber()) break;
263
264 at_range[0]++;
265 }
266
267 at_range[1] = at_range[0];
268 while (true)
269 {
270 if (at_range[1] == at2_vector.size()) break;
271 if ((at2_vector[at_range[1]].atomtype[0] >> 8) != (* it1).el.GetAtomicNumber()) break;
272
273 at_range[1]++;
274 }
275
276 i32s index = NOT_DEFINED;
277 for (i32u n1 = at_range[0];n1 < at_range[1];n1++)
278 {
279 bool flag = at2_vector[n1].tr->Check(mdl, & (* it1), 0);
280 if (flag) index = n1;
281
282 // above, the LAST matching type will be selected???
283 }
284
285 if (index != NOT_DEFINED)
286 {
287 (* it1).atmtp = at2_vector[index].atomtype[0];
288 (* it1).charge = at2_vector[index].formal_charge;
289 }
290 else
291 {
292 if (mdl->verbosity >= 2)
293 {
294 ostringstream str;
295 str << _("WARNING : could not determine atomtype (atom index = ") << (* it1).index << ")." << endl << ends;
296
297 mdl->PrintToLog(str.str().c_str());
298 }
299
300 (* it1).atmtp = NOT_DEFINED;
301 (* it1).charge = 0.0;
302
303 (* it1).flags |= ATOMFLAG_USER_SELECTED;
304 errors++;
305 }
306 }
307
308 return errors;
309 }
310
UpdateCharges(setup * su)311 i32u prmfit_tables::UpdateCharges(setup * su)
312 {
313 model * mdl = su->GetModel();
314
315 if (mdl->verbosity >= 3)
316 {
317 ostringstream str;
318 str << _("Setting up partial charges...") << endl << ends;
319 mdl->PrintToLog(str.str().c_str());
320 }
321
322 i32u errors = 0;
323
324 // atom ** atmtab = su->GetMMAtoms();
325 bond ** bndtab = su->GetMMBonds();
326
327 for (i32s n1 = 0;n1 < su->GetMMBondCount();n1++)
328 {
329 prmfit_bs_query query; query.strict = false;
330 query.atmtp[0] = bndtab[n1]->atmr[0]->atmtp;
331 query.atmtp[1] = bndtab[n1]->atmr[1]->atmtp;
332 query.bndtp = bndtab[n1]->bt.GetValue();
333
334 DoParamSearch(& query, mdl);
335 if (query.index == NOT_DEFINED) errors++;
336
337 f64 delta = query.ci; // here we also determine...
338 if (query.dir) delta = -delta; // ...the effect of direction!!!
339
340 bndtab[n1]->atmr[0]->charge -= delta;
341 bndtab[n1]->atmr[1]->charge += delta;
342 }
343
344 return errors;
345 }
346
GetAtomType(i32s p1)347 const prmfit_at * prmfit_tables::GetAtomType(i32s p1)
348 {
349 i32u index = 0;
350 while (index < at2_vector.size())
351 {
352 if (at2_vector[index].atomtype[0] == p1) return (& at2_vector[index]);
353 else index++;
354 }
355
356 // could not find the requested type -> return a NULL pointer instead...
357
358 return NULL;
359 }
360
DoParamSearch(prmfit_bs_query * query,model * mdl)361 void prmfit_tables::DoParamSearch(prmfit_bs_query * query, model * mdl)
362 {
363 for (i32u n1 = 0;n1 < bs_vector.size();n1++)
364 {
365 if (bs_vector[n1].bndtp.GetValue() != query->bndtp.GetValue()) continue;
366
367 bool flag = false; i32s dir;
368 for (dir = 0;dir < 2;dir++)
369 {
370 i32s index[2];
371 index[0] = (!dir ? 0 : 1);
372 index[1] = (!dir ? 1 : 0);
373
374 bool test1 = (bs_vector[n1].atmtp[0] == query->atmtp[index[0]]);
375 bool test2 = (bs_vector[n1].atmtp[1] == query->atmtp[index[1]]);
376
377 if (test1 && test2) flag = true;
378
379 if (flag) break;
380 }
381
382 if (flag)
383 {
384 query->index = n1;
385 query->dir = dir;
386
387 query->opt = bs_vector[n1].opt;
388 query->fc = bs_vector[n1].fc;
389
390 query->ci = bs_vector[n1].ci;
391
392 return; // success, return the parameters...
393 }
394 }
395
396 // recursive search?!?!?! DO IT BY CALLING AGAIN USING SECONDARY TYPES!!! NOT RECURSIVELY!!!
397 // recursive search?!?!?! DO IT BY CALLING AGAIN USING SECONDARY TYPES!!! NOT RECURSIVELY!!!
398 // recursive search?!?!?! DO IT BY CALLING AGAIN USING SECONDARY TYPES!!! NOT RECURSIVELY!!!
399
400 if (mdl != NULL && mdl->verbosity >= 2)
401 {
402 ostringstream str;
403 str << _("WARNING : unknown bs: ");
404 str << "0x" << hex << setw(4) << setfill('0') << query->atmtp[0] << dec << " ";
405 str << "0x" << hex << setw(4) << setfill('0') << query->atmtp[1] << dec << " ";
406 str << query->bndtp.GetValue() << " ";
407 str << endl << ends;
408
409 mdl->PrintToLog(str.str().c_str());
410 }
411
412 // the search failed, return default parameters...
413
414 query->index = NOT_DEFINED;
415 query->dir = false;
416
417 query->opt = 0.140;
418 query->fc = 60.0e+03;
419
420 query->ci = 0.0;
421 }
422
DoParamSearch(prmfit_ab_query * query,model * mdl)423 void prmfit_tables::DoParamSearch(prmfit_ab_query * query, model * mdl)
424 {
425 for (i32u n1 = 0;n1 < ab_vector.size();n1++)
426 {
427 if (ab_vector[n1].atmtp[1] != query->atmtp[1]) continue;
428
429 bool flag = false; i32s dir;
430 for (dir = 0;dir < 2;dir++)
431 {
432 i32s btind[2];
433 btind[0] = (!dir ? 0 : 1);
434 btind[1] = (!dir ? 1 : 0);
435
436 bool bttest1 = (ab_vector[n1].bndtp[0].GetValue() != query->bndtp[btind[0]].GetValue());
437 bool bttest2 = (ab_vector[n1].bndtp[1].GetValue() != query->bndtp[btind[1]].GetValue());
438 if (bttest1 || bttest2) continue; // bond type mismatch detected...
439
440 i32s index[2];
441 index[0] = (!dir ? 0 : 2);
442 index[1] = (!dir ? 2 : 0);
443
444 bool test1 = (ab_vector[n1].atmtp[0] == query->atmtp[index[0]]);
445 bool test2 = (ab_vector[n1].atmtp[2] == query->atmtp[index[1]]);
446
447 if (test1 && test2) flag = true;
448
449 if (query->strict == false)
450 {
451 bool wc1 = (ab_vector[n1].atmtp[0] == 0xffff);
452 bool wc2 = (ab_vector[n1].atmtp[2] == 0xffff);
453
454 if (wc1 && test2) flag = true;
455 if (test1 && wc2) flag = true;
456 if (wc1 && wc2) flag = true;
457 }
458
459 if (flag) break;
460 }
461
462 if (flag)
463 {
464 query->index = n1;
465 query->dir = dir;
466
467 query->opt = ab_vector[n1].opt;
468 query->fc = ab_vector[n1].fc;
469
470 return; // success, return the parameters...
471 }
472 }
473
474 // recursive search?!?!?! DO IT BY CALLING AGAIN USING SECONDARY TYPES!!! NOT RECURSIVELY!!!
475 // recursive search?!?!?! DO IT BY CALLING AGAIN USING SECONDARY TYPES!!! NOT RECURSIVELY!!!
476 // recursive search?!?!?! DO IT BY CALLING AGAIN USING SECONDARY TYPES!!! NOT RECURSIVELY!!!
477
478 if (mdl != NULL && mdl->verbosity >= 2)
479 {
480 ostringstream str;
481 str << _("WARNING : unknown ab: ");
482 str << "0x" << hex << setw(4) << setfill('0') << query->atmtp[0] << dec << " ";
483 str << "0x" << hex << setw(4) << setfill('0') << query->atmtp[1] << dec << " ";
484 str << "0x" << hex << setw(4) << setfill('0') << query->atmtp[2] << dec << " ";
485 str << query->bndtp[0].GetValue() << " ";
486 str << query->bndtp[1].GetValue() << " ";
487 str << endl << ends;
488
489 mdl->PrintToLog(str.str().c_str());
490 }
491
492 // the search failed, return default parameters...
493
494 query->index = NOT_DEFINED;
495 query->dir = false;
496
497 query->opt = 2.10;
498 query->fc = 250.0;
499 }
500
DoParamSearch(prmfit_tr_query * query,model * mdl)501 void prmfit_tables::DoParamSearch(prmfit_tr_query * query, model * mdl)
502 {
503 for (i32u n1 = 0;n1 < tr_vector.size();n1++)
504 {
505 if (tr_vector[n1].bndtp[1].GetValue() != query->bndtp[1].GetValue()) continue;
506
507 bool flag = false; i32s dir;
508 for (dir = 0;dir < 2;dir++)
509 {
510 i32s btind[2];
511 btind[0] = (!dir ? 0 : 2);
512 btind[1] = (!dir ? 2 : 0);
513
514 bool bttest1 = (tr_vector[n1].bndtp[0].GetValue() != query->bndtp[btind[0]].GetValue());
515 bool bttest2 = (tr_vector[n1].bndtp[2].GetValue() != query->bndtp[btind[1]].GetValue());
516 if (bttest1 || bttest2) continue; // bond type mismatch detected...
517
518 i32s index[4];
519 index[0] = (!dir ? 0 : 3);
520 index[1] = (!dir ? 1 : 2);
521 index[2] = (!dir ? 2 : 1);
522 index[3] = (!dir ? 3 : 0);
523
524 bool test1 = (tr_vector[n1].atmtp[0] == query->atmtp[index[0]]);
525 bool test2 = (tr_vector[n1].atmtp[1] == query->atmtp[index[1]]);
526 bool test3 = (tr_vector[n1].atmtp[2] == query->atmtp[index[2]]);
527 bool test4 = (tr_vector[n1].atmtp[3] == query->atmtp[index[3]]);
528
529 if (test1 && test2 && test3 && test4) flag = true;
530
531 if (query->strict == false)
532 {
533 bool wc1 = (tr_vector[n1].atmtp[0] == 0xffff);
534 bool wc2 = (tr_vector[n1].atmtp[3] == 0xffff);
535
536 if (wc1 && test2 && test3 && test4) flag = true;
537 if (test1 && test2 && test3 && wc2) flag = true;
538 if (wc1 && test2 && test3 && wc2) flag = true;
539 }
540
541 if (flag) break;
542 }
543
544 if (flag)
545 {
546 query->index = n1;
547 query->dir = dir;
548
549 query->fc1 = tr_vector[n1].fc1;
550 query->fc2 = tr_vector[n1].fc2;
551 query->fc3 = tr_vector[n1].fc3;
552
553 return; // success, return the parameters...
554 }
555 }
556
557 // recursive search?!?!?! DO IT BY CALLING AGAIN USING SECONDARY TYPES!!! NOT RECURSIVELY!!!
558 // recursive search?!?!?! DO IT BY CALLING AGAIN USING SECONDARY TYPES!!! NOT RECURSIVELY!!!
559 // recursive search?!?!?! DO IT BY CALLING AGAIN USING SECONDARY TYPES!!! NOT RECURSIVELY!!!
560
561 if (mdl != NULL && mdl->verbosity >= 2)
562 {
563 ostringstream str;
564 str << _("WARNING : unknown tr: ");
565 str << "0x" << hex << setw(4) << setfill('0') << query->atmtp[0] << dec << " ";
566 str << "0x" << hex << setw(4) << setfill('0') << query->atmtp[1] << dec << " ";
567 str << "0x" << hex << setw(4) << setfill('0') << query->atmtp[2] << dec << " ";
568 str << "0x" << hex << setw(4) << setfill('0') << query->atmtp[3] << dec << " ";
569 str << query->bndtp[0].GetValue() << " ";
570 str << query->bndtp[1].GetValue() << " ";
571 str << query->bndtp[2].GetValue() << " ";
572 str << endl << ends;
573
574 mdl->PrintToLog(str.str().c_str());
575 }
576
577 // the search failed, return default parameters...
578
579 query->index = NOT_DEFINED;
580 query->dir = false;
581
582 query->fc1 = 0.0;
583 query->fc2 = 0.0;
584 query->fc3 = 0.0;
585 }
586
DoParamSearch(prmfit_op_query * query,model * mdl)587 void prmfit_tables::DoParamSearch(prmfit_op_query * query, model * mdl)
588 {
589 for (i32u n1 = 0;n1 < op_vector.size();n1++)
590 {
591 // the atomtypes are defined in the following way:
592 // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
593 //
594 // 3 the idea is to measure how much atom 3
595 // | is bend from the plane defined by atoms
596 // 1 0, 1 and 2.
597 // / \
598 // 0 2 order of atoms 0 and 2 is not relevant,
599 // but atoms 1 and 3 must match exactly.
600
601 if (op_vector[n1].atmtp[1] != query->atmtp[1]) continue;
602 if (op_vector[n1].atmtp[3] != query->atmtp[3]) continue;
603 if (op_vector[n1].bndtp[2].GetValue() != query->bndtp[2].GetValue()) continue;
604
605 // proper bondtype checking not yet implemented....
606 // it will be basically similar to the above, but must be moved into the dir-loop!!!
607 // it will be basically similar to the above, but must be moved into the dir-loop!!!
608 // it will be basically similar to the above, but must be moved into the dir-loop!!!
609
610 bool flag = false; i32s dir;
611 for (dir = 0;dir < 2;dir++)
612 {
613 i32s btind[2];
614 btind[0] = (!dir ? 0 : 1);
615 btind[1] = (!dir ? 1 : 0);
616
617 bool bttest1 = (op_vector[n1].bndtp[0].GetValue() != query->bndtp[btind[0]].GetValue());
618 bool bttest2 = (op_vector[n1].bndtp[1].GetValue() != query->bndtp[btind[1]].GetValue());
619 if (bttest1 || bttest2) continue; // bond type mismatch detected...
620
621 i32s index[2];
622 index[0] = (!dir ? 0 : 2);
623 index[1] = (!dir ? 2 : 0);
624
625 bool test1 = (op_vector[n1].atmtp[0] == query->atmtp[index[0]]);
626 bool test2 = (op_vector[n1].atmtp[2] == query->atmtp[index[1]]);
627
628 if (test1 && test2) flag = true;
629
630 if (query->strict == false)
631 {
632 bool wc1 = (op_vector[n1].atmtp[0] == 0xffff);
633 bool wc2 = (op_vector[n1].atmtp[2] == 0xffff);
634
635 if (wc1 && test2) flag = true;
636 if (test1 && wc2) flag = true;
637 if (wc1 && wc2) flag = true;
638 }
639
640 if (flag) break;
641 }
642
643 if (flag)
644 {
645 query->index = n1;
646
647 query->opt = op_vector[n1].opt;
648 query->fc = op_vector[n1].fc;
649
650 return; // success, return the parameters...
651 }
652 }
653
654 // recursive search?!?!?! DO IT BY CALLING AGAIN USING SECONDARY TYPES!!! NOT RECURSIVELY!!!
655 // recursive search?!?!?! DO IT BY CALLING AGAIN USING SECONDARY TYPES!!! NOT RECURSIVELY!!!
656 // recursive search?!?!?! DO IT BY CALLING AGAIN USING SECONDARY TYPES!!! NOT RECURSIVELY!!!
657
658 if (mdl != NULL && mdl->verbosity >= 2)
659 {
660 ostringstream str;
661 str << _("WARNING : unknown op: ");
662 str << "0x" << hex << setw(4) << setfill('0') << query->atmtp[0] << dec << " ";
663 str << "0x" << hex << setw(4) << setfill('0') << query->atmtp[1] << dec << " ";
664 str << "0x" << hex << setw(4) << setfill('0') << query->atmtp[2] << dec << " ";
665 str << "0x" << hex << setw(4) << setfill('0') << query->atmtp[3] << dec << " ";
666 str << query->bndtp[0].GetValue() << " ";
667 str << query->bndtp[1].GetValue() << " ";
668 str << query->bndtp[2].GetValue() << " ";
669 str << endl << ends;
670
671 mdl->PrintToLog(str.str().c_str());
672 }
673
674 // the search failed, return default parameters...
675
676 query->index = NOT_DEFINED;
677
678 query->opt = 0.0;
679 query->fc = 0.0;
680 }
681
682 /*################################################################################################*/
683
684 // eof
685