2
* UGENE - Integrated Bioinformatics Tools.
3
* Copyright (C) 2008-2011 UniPro <ugene@unipro.ru>
4
* http://ugene.unipro.ru
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License
8
* as published by the Free Software Foundation; either version 2
9
* of the License, or (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
22
#include "uhmmer3SearchTests.h"
23
#include <gobject/uHMMObject.h>
25
#include <U2Core/DocumentModel.h>
26
#include <U2Core/IOAdapter.h>
27
#include <U2Core/AppContext.h>
28
#include <U2Core/DNASequenceObject.h>
29
#include <U2Core/TextUtils.h>
31
#include <QtCore/QList>
36
/*******************************
37
* GTest_GeneralUHMM3Search
38
********************************/
40
const QString GTest_UHMM3Search::SEQ_DOC_CTX_NAME_TAG = "seqDoc";
41
const QString GTest_UHMM3Search::HMM_FILENAME_TAG = "hmm";
42
const QString GTest_UHMM3Search::HMMSEARCH_TASK_CTX_NAME_TAG = "taskCtxName";
43
const QString GTest_UHMM3Search::ALGORITHM_TYPE_OPTION_TAG = "algo";
44
const QString GTest_UHMM3Search::SW_CHUNK_SIZE_OPTION_TAG = "chunk";
46
const QString GTest_UHMM3Search::SEQ_E_OPTION_TAG = "seqE";
47
const QString GTest_UHMM3Search::SEQ_T_OPTION_TAG = "seqT";
48
const QString GTest_UHMM3Search::Z_OPTION_TAG = "z";
49
const QString GTest_UHMM3Search::DOM_E_OPTION_TAG = "domE";
50
const QString GTest_UHMM3Search::DOM_T_OPTION_TAG = "domT";
51
const QString GTest_UHMM3Search::DOM_Z_OPTION_TAG = "domZ";
52
const QString GTest_UHMM3Search::USE_BIT_CUTOFFS_OPTION_TAG = "ubc";
53
const QString GTest_UHMM3Search::INC_SEQ_E_OPTION_TAG = "incE";
54
const QString GTest_UHMM3Search::INC_SEQ_T_OPTION_TAG = "incT";
55
const QString GTest_UHMM3Search::INC_DOM_E_OPTION_TAG = "incdomE";
56
const QString GTest_UHMM3Search::INC_DOM_T_OPTION_TAG = "incdomT";
57
const QString GTest_UHMM3Search::MAX_OPTION_TAG = "max";
58
const QString GTest_UHMM3Search::F1_OPTION_TAG = "f1";
59
const QString GTest_UHMM3Search::F2_OPTION_TAG = "f2";
60
const QString GTest_UHMM3Search::F3_OPTION_TAG = "f3";
61
const QString GTest_UHMM3Search::NOBIAS_OPTION_TAG = "nobias";
62
const QString GTest_UHMM3Search::NONULL2_OPTION_TAG = "nonull2";
63
const QString GTest_UHMM3Search::SEED_OPTION_TAG = "seed";
64
const QString GTest_UHMM3Search::REMOTE_MACHINE_VAR = "MACHINE";
66
static void setDoubleOption( double& num, const QDomElement& el, const QString& optionName, TaskStateInfo& si ) {
70
QString numStr = el.attribute( optionName );
71
if( numStr.isEmpty() ) {
76
double ret = numStr.toDouble( &ok );
78
si.setError( QString( "cannot_parse_double_number_from %1. Option: %2" ).arg( numStr ).arg( optionName ) );
84
static void setUseBitCutoffsOption( int& ret, const QDomElement& el, const QString& opName, TaskStateInfo& si ) {
89
QString str = el.attribute( opName ).toLower();
93
} else if( "nc" == str ) {
95
} else if( "tc" == str ) {
97
} else if( !str.isEmpty() ) {
98
si.setError( QString( "unrecognized_value_in %1 option" ).arg( opName ) );
102
static void setBooleanOption( int& ret, const QDomElement& el, const QString& opName, TaskStateInfo& si ) {
103
if( si.hasError() ) {
106
QString str = el.attribute( opName ).toLower();
108
if( !str.isEmpty() && "n" != str && "no" != str ) {
115
static void setIntegerOption( int& num, const QDomElement& el, const QString& optionName, TaskStateInfo& si ) {
116
if( si.hasError() ) {
119
QString numStr = el.attribute( optionName );
120
if( numStr.isEmpty() ) {
125
int ret = numStr.toInt( &ok );
127
si.setError( QString( "cannot_parse_integer_number_from %1. Option: %2" ).arg( numStr ).arg( optionName ) );
133
void GTest_UHMM3Search::setSearchTaskSettings( UHMM3SearchSettings& settings, const QDomElement& el, TaskStateInfo& si ) {
134
setDoubleOption( settings.e, el, GTest_UHMM3Search::SEQ_E_OPTION_TAG, si );
135
setDoubleOption( settings.t, el, GTest_UHMM3Search::SEQ_T_OPTION_TAG, si );
136
setDoubleOption( settings.z, el, GTest_UHMM3Search::Z_OPTION_TAG, si );
137
setDoubleOption( settings.f1, el, GTest_UHMM3Search::F1_OPTION_TAG, si );
138
setDoubleOption( settings.f2, el, GTest_UHMM3Search::F2_OPTION_TAG, si );
139
setDoubleOption( settings.f3, el, GTest_UHMM3Search::F3_OPTION_TAG, si );
140
setDoubleOption( settings.domE, el, GTest_UHMM3Search::DOM_E_OPTION_TAG, si );
141
setDoubleOption( settings.domT, el, GTest_UHMM3Search::DOM_T_OPTION_TAG, si );
142
setDoubleOption( settings.domZ, el, GTest_UHMM3Search::DOM_Z_OPTION_TAG, si );
143
setDoubleOption( settings.incE, el, GTest_UHMM3Search::INC_SEQ_E_OPTION_TAG, si );
144
setDoubleOption( settings.incT, el, GTest_UHMM3Search::INC_SEQ_T_OPTION_TAG, si );
145
setDoubleOption( settings.incDomE, el, GTest_UHMM3Search::INC_DOM_E_OPTION_TAG, si );
146
setDoubleOption( settings.incDomT, el, GTest_UHMM3Search::INC_DOM_T_OPTION_TAG, si );
148
setBooleanOption( settings.doMax, el, GTest_UHMM3Search::MAX_OPTION_TAG, si );
149
setBooleanOption( settings.noBiasFilter, el, GTest_UHMM3Search::NOBIAS_OPTION_TAG, si );
150
setBooleanOption( settings.noNull2, el, GTest_UHMM3Search::NONULL2_OPTION_TAG, si );
152
setIntegerOption( settings.seed, el, GTest_UHMM3Search::SEED_OPTION_TAG, si );
154
setUseBitCutoffsOption( settings.useBitCutoffs, el, GTest_UHMM3Search::USE_BIT_CUTOFFS_OPTION_TAG, si );
157
static void setSearchAlgoType( GTest_UHMM3SearchAlgoType& alType, const QString& s ) {
158
QString str = s.toLower();
160
if( "general" == str ) {
161
alType = GENERAL_SEARCH;
162
} else if( "sw" == str ) {
163
alType = SEQUENCE_WALKER_SEARCH;
165
alType = UNKNOWN_SEARCH;
169
static P7_HMM * takeHmmFromDoc( Document * doc ) {
170
assert( NULL != doc );
171
QList< GObject* > objs = doc->getObjects();
172
assert( 1 == objs.size() );
173
UHMMObject * hmmObj = qobject_cast< UHMMObject* >( objs.at( 0 ) );
174
if( NULL == hmmObj ) {
177
return hmmObj->takeHMM();
180
void GTest_UHMM3Search::init( XMLTestFormat *tf, const QDomElement& el ) {
183
hmmFilename = el.attribute( HMM_FILENAME_TAG );
184
searchTaskCtxName = el.attribute( HMMSEARCH_TASK_CTX_NAME_TAG );
186
searchTaskToCtx = NULL;
189
seqDocCtxName = el.attribute( SEQ_DOC_CTX_NAME_TAG );
190
setSearchAlgoType( algo, el.attribute( ALGORITHM_TYPE_OPTION_TAG ) );
191
setSearchTaskSettings( settings.inner, el, stateInfo );
193
swChunk = UHMM3SWSearchTask::DEFAULT_CHUNK_SIZE;
194
QString chunkStr = el.attribute(SW_CHUNK_SIZE_OPTION_TAG);
195
if( !chunkStr.isEmpty() ) {
197
int candidate = chunkStr.toInt(&ok);
198
if(ok && candidate > 0) {
206
machinePath = env->getVar( REMOTE_MACHINE_VAR );
207
if( !machinePath.isEmpty() ) {
208
algo = SEQUENCE_WALKER_SEARCH;
212
void GTest_UHMM3Search::setAndCheckArgs() {
213
assert( !stateInfo.hasError() );
214
if( hmmFilename.isEmpty() ) {
215
stateInfo.setError( "hmm_filename_is_empty" );
218
hmmFilename = env->getVar( "COMMON_DATA_DIR" ) + "/" + hmmFilename;
220
if( searchTaskCtxName.isEmpty() ) {
221
stateInfo.setError( "task_ctx_name_is_empty" );
225
if( seqDocCtxName.isEmpty() ) {
226
stateInfo.setError( "sequence_document_ctx_name_is_empty" );
230
if( UNKNOWN_SEARCH == algo ) {
231
stateInfo.setError( "unknown_algorithm_type" );
235
Document* seqDoc = getContext<Document>( this, seqDocCtxName );
236
if( NULL == seqDoc ) {
237
stateInfo.setError( QString( "context %1 not found" ).arg( seqDocCtxName ) );
240
QList< GObject* > objsList = seqDoc->findGObjectByType( GObjectTypes::SEQUENCE );
241
if( objsList.isEmpty() ) {
242
stateInfo.setError( "no_dna_sequence_objects_in_document" );
245
DNASequenceObject* seqObj = qobject_cast< DNASequenceObject* >( objsList.first() );
246
if( NULL == seqObj ) {
247
stateInfo.setError( "cannot_cast_to_dna_object" );
250
sequence = seqObj->getDNASequence();
251
if( !sequence.length() ) {
252
stateInfo.setError( "empty_sequence_given" );
256
if( !machinePath.isEmpty() ) {
257
machinePath = env->getVar( "COMMON_DATA_DIR" ) + "/" + machinePath;
261
void GTest_UHMM3Search::prepare() {
262
assert( !hasError() );
270
searchTaskToCtx = new UHMM3LoadProfileAndSearchTask(settings, hmmFilename, sequence.seq);
271
addSubTask( searchTaskToCtx );
273
case SEQUENCE_WALKER_SEARCH:
274
if( machinePath.isEmpty() ) { /* search task on local machine */
275
searchTaskToCtx = new UHMM3SWSearchTask( hmmFilename, sequence, settings, swChunk );
276
addSubTask( searchTaskToCtx );
277
} else { /* search on remote machine */
278
addSubTask( LoadDocumentTask::getDefaultLoadDocTask( hmmFilename ) );
282
assert( 0 && "undefined_algorithm_type" );
286
QList< Task* > GTest_UHMM3Search::onSubTaskFinished( Task * sub ) {
287
assert( NULL != sub );
289
LoadDocumentTask * loadHmmTask = qobject_cast<LoadDocumentTask*>( sub );
290
if( NULL == loadHmmTask ) {
293
if( loadHmmTask->hasError() ) {
294
setError( loadHmmTask->getError() );
298
hmm = takeHmmFromDoc( loadHmmTask->getDocument() );
299
assert( NULL != hmm );
303
Task::ReportResult GTest_UHMM3Search::report() {
304
if( stateInfo.hasError() ) {
305
return ReportResult_Finished;
307
assert( NULL != searchTaskToCtx );
308
if( !searchTaskToCtx->hasError() && !searchTaskToCtx->isCanceled() ) {
309
addContext( searchTaskCtxName, searchTaskToCtx );
312
return ReportResult_Finished;
315
void GTest_UHMM3Search::cleanup() {
320
removeContext( searchTaskCtxName );
323
p7_hmm_Destroy( hmm );
328
GTest_UHMM3Search::~GTest_UHMM3Search() {
334
/**************************
335
* GTest_GeneralUHMM3SearchCompare
336
**************************/
338
const int BUF_SZ = 2048;
339
const char TERM_SYM = '\0';
341
static void readLine( IOAdapter* io, QByteArray& to, QStringList* tokens = NULL ) {
342
assert( NULL != io );
344
QByteArray buf( BUF_SZ, TERM_SYM );
348
int ret = io->readUntil( buf.data(), BUF_SZ, TextUtils::LINE_BREAKS, IOAdapter::Term_Include, &there );
350
throw QString( "read_error_occurred" );
355
to.append( QByteArray( buf.data(), ret ) );
360
throw QString( "unexpected_end_of_file_found" );
363
if( NULL != tokens ) {
364
*tokens = QString( to ).split( QRegExp( "\\s+" ), QString::SkipEmptyParts );
368
static QByteArray getNextToken( QStringList& tokens ) {
369
if( tokens.isEmpty() ) {
370
throw QString( "unexpected_end_of_line:token_is_missing" );
372
return tokens.takeFirst().toAscii();
375
static double getDouble( const QByteArray& numStr ) {
377
double ret = numStr.toDouble( &ok );
381
throw QString( GTest_UHMM3SearchCompare::tr( "cannot_parse_double_number_from_string:%1" ).arg( QString( numStr ) ) );
384
static float getFloat( const QByteArray& numStr ) {
385
return (float)getDouble( numStr );
388
static bool getSignificance( const QByteArray& str ) {
391
} else if( "?" == str ) {
394
throw QString( GTest_UHMM3SearchCompare::tr( "cannot_parse_significance:%1" ).arg( QString( str ) ) );
397
static UHMM3SearchSeqDomainResult getDomainRes( QStringList& tokens ) {
398
UHMM3SearchSeqDomainResult res;
400
getNextToken( tokens );
401
res.isSignificant = getSignificance( getNextToken( tokens ) );
402
res.score = getFloat( getNextToken( tokens ) );
403
res.bias = getFloat( getNextToken( tokens ) );
404
res.cval = getDouble( getNextToken( tokens ) );
405
res.ival = getDouble( getNextToken( tokens ) );
407
int hmmFrom = (int)getFloat( getNextToken( tokens ) );
408
int hmmTo = (int)getFloat( getNextToken( tokens ) );
409
res.queryRegion = U2Region( hmmFrom, hmmTo - hmmFrom );
410
getNextToken( tokens );
412
int aliFrom = (int)getFloat( getNextToken( tokens ) );
413
int aliTo = (int)getFloat( getNextToken( tokens ) );
414
res.seqRegion = U2Region( aliFrom - 1, aliTo - aliFrom + 1 );
415
getNextToken( tokens );
417
int envFrom = (int)getFloat( getNextToken( tokens ) );
418
int envTo = (int)getFloat( getNextToken( tokens ) );
419
res.envRegion = U2Region( envFrom, envTo - envFrom );
420
getNextToken( tokens );
422
res.acc = getDouble( getNextToken( tokens ) );
426
const double COMPARE_PERCENT_BORDER = 0.01; // 1 percent
429
static bool compareNumbers( T f1, T f2 ) {
432
ret = 0 == f2 ? true : f2 < COMPARE_PERCENT_BORDER;
433
} else if( 0 == f2 ) {
434
ret = f1 < COMPARE_PERCENT_BORDER;
436
ret = ( qAbs( f1 - f2 ) ) / f1 < COMPARE_PERCENT_BORDER;
440
qDebug() << "!!! compare numbers mismatch: " << f1 << " and " << f2 << " !!!\n";
446
void GTest_UHMM3SearchCompare::generalCompareResults( const UHMM3SearchResult& myRes, const UHMM3SearchResult& trueRes, TaskStateInfo& ti ) {
447
const UHMM3SearchCompleteSeqResult& myFull = myRes.fullSeqResult;
448
const UHMM3SearchCompleteSeqResult& trueFull = trueRes.fullSeqResult;
450
if( myFull.isReported != trueFull.isReported ) {
451
ti.setError( QString( "reported_flag_not_matched: %1 and %2" ).arg( myFull.isReported ).arg( trueFull.isReported ) );
455
if( myFull.isReported ) {
456
if( !compareNumbers<float>( myFull.bias, trueFull.bias ) ) {
457
ti.setError( QString( "full_seq_bias_not_matched: %1 and %2" ).arg( myFull.bias ).arg( trueFull.bias ) ); return;
459
if( !compareNumbers<double>( myFull.eval, trueFull.eval ) ) {
460
ti.setError( QString( "full_seq_eval_not_matched: %1 and %2" ).arg( myFull.eval ).arg( trueFull.eval ) ); return;
462
if( !compareNumbers<float>( myFull.score, trueFull.score ) ) {
463
ti.setError( QString( "full_seq_score_not_matched: %1 and %2" ).arg( myFull.score ).arg( trueFull.score ) ); return;
465
if( !compareNumbers<float>( myFull.expectedDomainsNum, trueFull.expectedDomainsNum ) ) {
466
ti.setError( QString( "full_seq_exp_not_matched: %1 and %2" ).arg( myFull.expectedDomainsNum ).arg( trueFull.expectedDomainsNum ) );
469
if( myFull.reportedDomainsNum != trueFull.reportedDomainsNum ) {
470
ti.setError( QString( "full_seq_n_not_matched: %1 and %2" ).arg( myFull.reportedDomainsNum ).arg( trueFull.reportedDomainsNum ) );
475
const QList< UHMM3SearchSeqDomainResult >& myDoms = myRes.domainResList;
476
const QList< UHMM3SearchSeqDomainResult >& trueDoms = trueRes.domainResList;
477
if( myDoms.size() != trueDoms.size() ) {
478
ti.setError( QString( "domain_res_number_not_matched: %1 and %2" ).arg( myDoms.size() ).arg( trueDoms.size() ) );
481
for( int i = 0; i < myDoms.size(); ++i ) {
482
UHMM3SearchSeqDomainResult myCurDom = myDoms.at( i );
483
UHMM3SearchSeqDomainResult trueCurDom = trueDoms.at( i );
484
if( !compareNumbers<double>( myCurDom.acc, trueCurDom.acc ) ) {
485
ti.setError( QString( "dom_acc_not_matched: %1 and %2" ).arg( myCurDom.acc ).arg( trueCurDom.acc ) ); return;
487
if( !compareNumbers<float>( myCurDom.bias, trueCurDom.bias ) ) {
488
ti.setError( QString( "dom_bias_not_matched: %1 and %2" ).arg( myCurDom.bias ).arg( trueCurDom.bias ) ); return;
490
if( !compareNumbers<double>( myCurDom.cval, trueCurDom.cval ) ) {
491
ti.setError( QString( "dom_cval_not_matched: %1 and %2" ).arg( myCurDom.cval ).arg( trueCurDom.cval ) ); return;
493
if( !compareNumbers<double>( myCurDom.ival, trueCurDom.ival ) ) {
494
ti.setError( QString( "dom_ival_not_matched: %1 and %2" ).arg( myCurDom.ival ).arg( trueCurDom.ival ) ); return;
496
if( !compareNumbers<float>( myCurDom.score, trueCurDom.score ) ) {
497
ti.setError( QString( "dom_score_not_matched: %1 and %2" ).arg( myCurDom.score ).arg( trueCurDom.score ) ); return;
499
if( myCurDom.envRegion != trueCurDom.envRegion ) {
500
ti.setError( QString( "dom_env_region_not_matched: %1---%2 and %3---%4" ).
501
arg( myCurDom.envRegion.startPos ).arg( myCurDom.envRegion.length ).arg( trueCurDom.envRegion.startPos ).
502
arg( trueCurDom.envRegion.length ) ); return;
504
if( myCurDom.queryRegion != trueCurDom.queryRegion ) {
505
ti.setError( QString( "dom_hmm_region_not_matched: %1---%2 and %3---%4" ).
506
arg( myCurDom.queryRegion.startPos ).arg( myCurDom.queryRegion.length ).arg( trueCurDom.queryRegion.startPos ).
507
arg( trueCurDom.queryRegion.length ) ); return;
509
if( myCurDom.seqRegion != trueCurDom.seqRegion ) {
510
ti.setError( QString( "dom_seq_region_not_matched: %1---%2 and %3---%4" ).
511
arg( myCurDom.seqRegion.startPos ).arg( myCurDom.seqRegion.length ).arg( trueCurDom.seqRegion.startPos ).
512
arg( trueCurDom.seqRegion.length ) ); return;
514
if( myCurDom.isSignificant != trueCurDom.isSignificant ) {
515
ti.setError( QString( "dom_sign_not_matched: %1 and %2" ).arg( myCurDom.isSignificant ).arg( trueCurDom.isSignificant ) );
522
findEqualDomain(const QList<UHMM3SWSearchTaskDomainResult>& res, const UHMM3SearchSeqDomainResult & dres, bool compareSeqRegion) {
524
for(int i = 0; i < res.size(); ++i) {
525
UHMM3SearchSeqDomainResult dom = res.at(i).generalResult;
527
if( !compareNumbers<double>( dom.acc, dres.acc ) ) { count++; }
528
if( !compareNumbers<float>( dom.bias, dres.bias ) ) { count++; }
529
if( !compareNumbers<double>( dom.cval, dres.cval ) ) { count++; }
530
if( !compareNumbers<double>( dom.ival, dres.ival ) ) { count++; }
531
if( !compareNumbers<float>( dom.score, dres.score ) ) { count++; }
532
if( dom.queryRegion != dres.queryRegion ) { count++; }
533
if( compareSeqRegion && dom.seqRegion != dres.seqRegion ) { count++; }
534
if( compareSeqRegion && dom.envRegion != dres.envRegion ) { count++; }
535
if( dom.isSignificant != dres.isSignificant ) { count++; }
541
static QString seqDomainResult2String(const UHMM3SearchSeqDomainResult & r) {
542
return QString("score=%1, eval=%2, bias=%3, acc=%4, query=%5 seq=%6").arg(r.score).arg(r.ival).arg(r.bias).arg(r.acc).
543
arg(QString("%1..%2").arg(r.queryRegion.startPos).arg(r.queryRegion.endPos())).
544
arg(QString("%1..%2").arg(r.seqRegion.startPos).arg(r.seqRegion.endPos()));
547
/* we compare here that every domain of trueResult is included in myResult */
549
GTest_UHMM3SearchCompare::swCompareResults( const QList<UHMM3SWSearchTaskDomainResult>& myR, const UHMM3SearchResult& trueR,
550
TaskStateInfo& ti, bool compareSeqRegion ) {
551
int sz = trueR.domainResList.size();
553
for( i = 0; i < sz; ++i ) {
554
const UHMM3SearchSeqDomainResult & trueDom = trueR.domainResList.at(i);
555
if(trueDom.score < 2) {
558
QList<int> diff = findEqualDomain(myR, trueDom, compareSeqRegion);
559
if(!diff.contains(0)) {
562
for(int j = 0; j < myR.size(); ++j) {
563
float d = qAbs(myR.at(j).generalResult.score - trueR.domainResList.at(i).score);
570
ti.setError( QString( "Cannot find result #%1: %2, most close result: %3" ).
572
arg(seqDomainResult2String(trueR.domainResList.at(i))).
573
arg(seqDomainResult2String(myR.at(minPos).generalResult)));
575
ti.setError( QString( "Cannot find result #%1: %2" ).
576
arg(i).arg(seqDomainResult2String(trueR.domainResList.at(i))));
583
const QString GTest_UHMM3SearchCompare::SEARCH_TASK_CTX_NAME_TAG = "searchTask";
584
const QString GTest_UHMM3SearchCompare::TRUE_OUT_FILE_TAG = "trueOut";
586
void GTest_UHMM3SearchCompare::init( XMLTestFormat *tf, const QDomElement& el ) {
589
searchTaskCtxName = el.attribute( SEARCH_TASK_CTX_NAME_TAG );
590
trueOutFilename = el.attribute( TRUE_OUT_FILE_TAG );
593
void GTest_UHMM3SearchCompare::setAndCheckArgs() {
594
assert( !hasError() );
596
if( searchTaskCtxName.isEmpty() ) {
597
stateInfo.setError( "search_task_ctx_name_is_empty" );
601
if( trueOutFilename.isEmpty() ) {
602
stateInfo.setError( "true_out_filename_is_empty" );
605
trueOutFilename = env->getVar( "COMMON_DATA_DIR" ) + "/" + trueOutFilename;
607
Task* searchTask = getContext<Task>( this, searchTaskCtxName );
608
if( NULL == searchTask ) {
609
stateInfo.setError( tr( "cannot_find_search_task_in_context" ) );
613
generalTask = qobject_cast< UHMM3LoadProfileAndSearchTask* >( searchTask );
614
swTask = qobject_cast< UHMM3SWSearchTask* >( searchTask );
616
if( NULL != generalTask ) {
617
algo = GENERAL_SEARCH;
618
} else if (NULL != swTask) {
619
algo = SEQUENCE_WALKER_SEARCH;
621
assert( 0 && "cannot_cast_task_to_search_task" );
625
bool GTest_UHMM3SearchCompare::searchResultLessThan(const UHMM3SearchSeqDomainResult & r1, const UHMM3SearchSeqDomainResult & r2) {
626
if( r1.score == r2.score ) {
627
if(r1.seqRegion == r2.seqRegion) {
630
return r1.seqRegion < r2.seqRegion;
632
return r1.score > r2.score;
635
UHMM3SearchResult GTest_UHMM3SearchCompare::getOriginalSearchResult( const QString & filename ) {
636
assert( !filename.isEmpty() );
638
IOAdapterFactory* iof = AppContext::getIOAdapterRegistry()->getIOAdapterFactoryById( BaseIOAdapters::url2io( filename ) );
639
std::auto_ptr< IOAdapter > io( iof->createIOAdapter() );
640
if( NULL == io.get() ) {
641
throw QString( "cannot_create_io_adapter_for_'%1'_file" ).arg( filename );
643
if( !io->open( filename, IOAdapterMode_Read ) ) {
644
throw QString( "cannot_open_'%1'_file" ).arg( filename );
647
UHMM3SearchResult res;
650
bool wasHeader = false;
651
bool wasFullSeqResult = false;
652
readLine( io.get(), buf ); /* the first line. starts with # search or # phmmer */
654
readLine( io.get(), buf );
655
if( buf.isEmpty() ) { /* but no error - empty line here */
658
if( buf.startsWith( "# HMMER 3" ) ) {
662
if( buf.startsWith( "Scores for complete sequences" ) ) {
664
throw QString( "hmmer_output_header_is_missing" );
666
UHMM3SearchCompleteSeqResult& fullSeqRes = res.fullSeqResult;
667
readLine( io.get(), buf );
668
readLine( io.get(), buf );
669
readLine( io.get(), buf );
670
readLine( io.get(), buf, &tokens );
671
if( buf.startsWith( "[No hits detected" ) ) {
672
fullSeqRes.isReported = false;
675
fullSeqRes.eval = getDouble( getNextToken( tokens ) );
676
fullSeqRes.score = getFloat( getNextToken( tokens ) );
677
fullSeqRes.bias = getFloat( getNextToken( tokens ) );
678
/* skip best domain res. we will check it later */
679
getNextToken( tokens );getNextToken( tokens );getNextToken( tokens );
680
fullSeqRes.expectedDomainsNum = getFloat( getNextToken( tokens ) );
681
fullSeqRes.reportedDomainsNum = (int)getFloat( getNextToken( tokens ) );
682
fullSeqRes.isReported = true;
683
wasFullSeqResult = true;
687
if( buf.startsWith( "Domain annotation for each sequence" ) ) {
688
if( !wasFullSeqResult ) {
689
throw QString( "full_seq_result_is_missing" );
691
readLine( io.get(), buf );
692
readLine( io.get(), buf );
693
readLine( io.get(), buf );
694
QList< UHMM3SearchSeqDomainResult >& domainResList = res.domainResList;
695
assert( domainResList.isEmpty() );
697
int nDomains = res.fullSeqResult.reportedDomainsNum;
699
for( i = 0; i < nDomains; ++i ) {
700
readLine( io.get(), buf, &tokens );
701
domainResList << getDomainRes( tokens );
709
Task::ReportResult GTest_UHMM3SearchCompare::report() {
710
assert( !hasError() );
713
return ReportResult_Finished;
716
UHMM3SearchResult trueRes;
718
trueRes = getOriginalSearchResult( trueOutFilename );
719
} catch( const QString& ex ) {
720
stateInfo.setError( ex );
722
stateInfo.setError( "undefined_error_occurred" );
726
return ReportResult_Finished;
731
assert( NULL != generalTask );
732
generalCompareResults( generalTask->getResult(), trueRes, stateInfo );
734
case SEQUENCE_WALKER_SEARCH:
736
QList<UHMM3SWSearchTaskDomainResult> result;
737
if( NULL != swTask ) {
738
result = swTask->getResults();
742
qSort(trueRes.domainResList.begin(), trueRes.domainResList.end(), searchResultLessThan);
743
swCompareResults( result, trueRes, stateInfo );
747
assert( 0 && "unknown_algo_type" );
750
return ReportResult_Finished;