00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <qdir.h>
00016 #include <qfileinfo.h>
00017 #include <qwidget.h>
00018 #include <qmsgbox.h>
00019 #include <qfiledialog.h>
00020 #include <qdom.h>
00021 #include <qxml.h>
00022
00023 #include <iostream>
00024 #include <list>
00025 #include <vector>
00026 #include <string>
00027 #include <ostream>
00028
00029 #include "trapperdoc.h"
00030 #include "trapper.h"
00031 #include "trapperview.h"
00032 #include "generaldata.h"
00033 #include "algo.h"
00034 #include "trdb.h"
00035 #include "featuredata.h"
00036 #include "readdata.h"
00037 #include "generalmaker.h"
00038 #include "chromatparser.h"
00039 #include "mateparser.h"
00040 #include "phdparser.h"
00041 using namespace std;
00042
00043 TrapperDoc::TrapperDoc(DbEnv * dbenv_): dbenv( dbenv_ )
00044 {
00045 qDebug("in TrapperDoc::TrapperDoc()");
00046 pViewList = new QList<TrapperView>;
00047
00048 pViewList->setAutoDelete(true);
00049 pAlgoList = new QList<Algo>;
00050 pAlgoList->setAutoDelete(false);
00051 setModified(true );
00052 }
00053
00054 TrapperDoc::~TrapperDoc()
00055 {
00056 cerr<<"closing doc"<<endl;
00057 delete pViewList;
00058 delete pAlgoList;
00059 closeDbs();
00060 }
00061
00062 void TrapperDoc::addView(TrapperView *view)
00063 {
00064 pViewList->append(view);
00065 changedViewList();
00066 }
00067
00068 void TrapperDoc::addAlgorithm(Algo *algo)
00069 {
00070 pAlgoList->append(algo);
00071 changedAlgoList();
00072 }
00073
00074 void TrapperDoc::removeView(TrapperView *view)
00075 {
00076 pViewList->remove
00077 (view);
00078 if(!pViewList->isEmpty() || !pAlgoList->isEmpty() )
00079 changedViewList();
00080 else
00081 deleteContents();
00082 }
00083
00084 void TrapperDoc::removeAlgorithm(Algo *algo)
00085 {
00086 pAlgoList->remove
00087 (algo);
00088 if(!pViewList->isEmpty() || !pAlgoList->isEmpty() )
00089 changedAlgoList();
00090 else
00091 deleteContents();
00092 }
00093
00094 void TrapperDoc::changedViewList()
00095 {
00096
00097 TrapperView *w;
00098 if((int)pViewList->count() == 1)
00099 {
00100 w=pViewList->first();
00101 QString mode = w->mode();
00102 w->setCaption(QString(m_title+" mode=%2").arg(mode));
00103 }
00104 else
00105 {
00106 int i;
00107 for( i=1,w=pViewList->first(); w!=0; i++, w=pViewList->next())
00108 {
00109 QString mode = w->mode();
00110 w->setCaption(QString(m_title+" :%1 mode=%2").arg(i).arg(mode));
00111 }
00112 }
00113 }
00114
00115 void TrapperDoc::changedAlgoList()
00116 {
00117 }
00118
00119 bool TrapperDoc::isLastView()
00120 {
00121 return ((int) pViewList->count() == 1);
00122 }
00123
00124 void TrapperDoc::updateAllViews(TrapperView *sender)
00125 {
00126 TrapperView *w;
00127 for(w=pViewList->first(); w!=0; w=pViewList->next())
00128 {
00129 w->update(sender);
00130 }
00131 }
00132
00133 void TrapperDoc::setPathName(const QString &name)
00134 {
00135 m_contigDir=name;
00136 m_title=QFileInfo(name).fileName();
00137 }
00138
00139 const QString& TrapperDoc::pathName() const
00140 {
00141 return m_contigDir;
00142 }
00143
00144 void TrapperDoc::setTitle(const QString &title)
00145 {
00146 m_title=title;
00147 }
00148
00149 const QString &TrapperDoc::title() const
00150 {
00151 return m_title;
00152 }
00153
00154 void TrapperDoc::closeDocument()
00155 {
00156 cerr<<"closeDocument()"<<endl;
00157 TrapperView *w;
00158 if(!isLastView()) {
00159 for(w=pViewList->first(); w!=0; w=pViewList->next()) {
00160 if(!w->close())
00161 break;
00162 }
00163 }
00164 if(isLastView()) {
00165 w = pViewList->first();
00166 w->close();
00167 }
00168 }
00169
00170 bool TrapperDoc::newDocument()
00171 {
00172
00173
00174
00175 modified=false;
00176 return true;
00177 }
00178
00179 bool TrapperDoc::openDocument(const QString &dirname, const char* format )
00180 {
00181 cerr<<"openDocument() "<<endl;
00182 m_contigDir=dirname;
00183 QDir dir( m_contigDir );
00184
00185 if ( !dir.exists() ) {
00186 QDir dir2;
00187 if ( !dir2.mkdir( m_contigDir, true ) ) {
00188
00189 cerr << "creating new dir failed, dir name=" << m_contigDir << endl;
00190 exit(1);
00191
00192
00193 }
00194 }
00195
00196
00197
00198 modified=false;
00199 m_title=dirname;
00200
00201 openDbs();
00202 return true;
00203 }
00204
00205 bool TrapperDoc::saveDocument(const QString &filename, const char * )
00206 {
00207
00208
00209
00210
00211
00212 return false;
00213
00214
00215
00216
00217
00218 modified=false;
00219 m_contigDir=filename;
00220 m_title=filename;
00221 return true;
00222 }
00223
00224 void TrapperDoc::deleteContents()
00225 {
00226
00227
00228
00229
00230 }
00231
00232 bool TrapperDoc::canCloseFrame(TrapperView* pFrame)
00233 {
00234 if(!isLastView())
00235 return true;
00236
00237 bool ret=false;
00238 if(isModified())
00239 {
00240 QString saveName;
00241 switch(QMessageBox::information(pFrame, title(), tr("The current file has been modified.\n"
00242 "Do you want to save it?"),QMessageBox::Yes, QMessageBox::No, QMessageBox::Cancel ))
00243 {
00244 case QMessageBox::Yes:
00245 if(title().contains(tr("Untitled")))
00246 {
00247 saveName=QFileDialog::getSaveFileName(0, 0, pFrame);
00248 if(saveName.isEmpty())
00249 return false;
00250 }
00251 else
00252 saveName=pathName();
00253
00254 if(!saveDocument(saveName))
00255 {
00256 switch(QMessageBox::critical(pFrame, tr("I/O Error !"), tr("Could not save the current document !\n"
00257 "Close anyway ?"),QMessageBox::Yes ,QMessageBox::No))
00258
00259 {
00260 case QMessageBox::Yes:
00261 ret=true;
00262 case QMessageBox::No:
00263 ret=false;
00264 }
00265 }
00266 else
00267 ret=true;
00268 break;
00269 case QMessageBox::No:
00270 ret=true;
00271 break;
00272 case QMessageBox::Cancel:
00273 default:
00274 ret=false;
00275 break;
00276 }
00277 }
00278 else
00279 ret=true;
00280
00281 return ret;
00282 }
00283
00284 void TrapperDoc::saveExport(ostream& stream)
00285 {
00286
00287
00288 int offset(-1);
00289 if ( pathName()[pathName().length() -1] == '/' ) {
00290 --offset;
00291 }
00292
00293 stream<<"<contig name=\""<<pathName().section('/', offset)<<"\">\n";
00294
00295 Database::PrimaryIterator<ReadData> iter( this, "ReadData" );
00296
00297 if ( iter.first() == 0 ) {
00298 do {
00299
00300 iter.answer()->writeXml(stream);
00301
00302
00303 list<string> alist = GeneralMaker::listRegistered();
00304 for ( list<string>::iterator it = alist.begin(); it != alist.end(); ++it ) {
00305 if ( *it == "ReadData") {
00306 continue;
00307 }
00308 Database::SecondaryIterator<FeatureData> f_it( "readRecno", this, *it );
00309
00310 f_it.key()->setReadRecno( iter.answer()->getRecno() );
00311
00312 if ( f_it.set() == 0 ) {
00313 do {
00314 f_it.answer()->writeXml(stream);
00315
00316 }while(f_it.nextdup() == 0);
00317 }
00318 }
00319
00320
00321 stream<<"</ReadData>\n";
00322
00323 }while( iter.next() == 0 );
00324
00325
00326 }
00327
00328 stream<<"</contig>\n";
00329
00330 }
00331
00332 bool TrapperDoc::import(QDomElement & elem1)
00333 {
00334 QDomNode node2 = elem1.firstChild();
00335
00336 while ( !node2.isNull() )
00337 {
00338 if ( node2.isElement() )
00339 {
00340 QString generalDataName = node2.nodeName();
00341 QDomElement elem2 = node2.toElement();
00342
00343 Database::Creator<GeneralData> creator( this, generalDataName.ascii() );
00344
00345 QDomNode node3 = elem2.firstChild();
00346
00347 while ( !node3.isNull() )
00348 {
00349 if ( node3.isElement() && node3.nodeName() == "record" )
00350 {
00351 QDomElement elem3 = node3.toElement();
00352
00353 creator.data()->readDom( elem3 );
00354 creator.create( true );
00355 }
00356 node3 = node3.nextSibling();
00357 }
00358 }
00359 node2 = node2.nextSibling();
00360 }
00361 return true;
00362 }
00363
00364 void TrapperDoc::importChromat(const QString& dirname)
00365 {
00366
00367
00368 vector<string> names = all_readnames();
00369
00370
00371
00372 for( size_t i = 0; i < names.size(); i++ ) {
00373
00374
00375 vector<TrapperVector<Q_UINT32> > chromat_array;
00376 ChromatParser handler;
00377 handler.set_result_array( &chromat_array );
00378 QFile xmlFile( dirname + '/' + names[i] + ".xml" );
00379 QXmlInputSource source( &xmlFile );
00380 QXmlSimpleReader reader;
00381 reader.setContentHandler( &handler );
00382 if ( !reader.parse( source ) ) {
00383 cerr<<"Error, couldn't find chromatogram for "<<names[i]<<endl;
00384 continue;
00385 }
00386
00387 Database::SecondaryIterator<ReadData> name_it( "name", this, "ReadData" );
00388 name_it.key()->setName( names[i] );
00389 if ( name_it.set() != 0 ) {
00390 cerr<<"Error, couldn't find "<<names[i]<<" in db"<<endl;
00391 continue;
00392 }
00393
00394 Database::SecondaryIterator<ChromatData>* chr_it =
00395 new Database::SecondaryIterator<ChromatData>( "readRecno", this, "ChromatData" );
00396
00397 chr_it->key()->setReadRecno( name_it.answer()->getRecno() );
00398
00399 if ( chr_it->set() != 0 ) {
00400 cerr<<"Error, couldn't find recno "<<name_it.answer()->getRecno()<<" of read "<<names[i]<<endl;
00401 delete chr_it;
00402 continue;
00403 }
00404
00405
00406 Database::Creator<ChromatData> creator( this, "ChromatData" );
00407
00408 creator.data()->copy(chr_it->answer());
00409
00410
00411
00412
00413
00414
00415 creator.data()->cagt_vec.clear();
00416 if ( name_it.answer()->strand() == "C" ) {
00417
00418 creator.data()->cagt_vec.push_back(TrapperVector<Q_UINT32>());
00419 creator.data()->cagt_vec.push_back(TrapperVector<Q_UINT32>());
00420 creator.data()->cagt_vec.push_back(TrapperVector<Q_UINT32>());
00421 creator.data()->cagt_vec.push_back(TrapperVector<Q_UINT32>());
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437 creator.data()->cagt_vec[0].stlVector().clear();
00438 creator.data()->cagt_vec[0].stlVector().insert(creator.data()->cagt_vec[0].stlVector().begin(),
00439 chromat_array[2].stlVector().rbegin(), chromat_array[2].stlVector().rend());
00440 creator.data()->cagt_vec[1].stlVector().clear();
00441 creator.data()->cagt_vec[1].stlVector().insert(creator.data()->cagt_vec[1].stlVector().begin(),
00442 chromat_array[3].stlVector().rbegin(), chromat_array[3].stlVector().rend());
00443 creator.data()->cagt_vec[2].stlVector().clear();
00444 creator.data()->cagt_vec[2].stlVector().insert(creator.data()->cagt_vec[2].stlVector().begin(),
00445 chromat_array[0].stlVector().rbegin(), chromat_array[0].stlVector().rend());
00446 creator.data()->cagt_vec[3].stlVector().clear();
00447 creator.data()->cagt_vec[3].stlVector().insert(creator.data()->cagt_vec[3].stlVector().begin(),
00448 chromat_array[1].stlVector().rbegin(), chromat_array[1].stlVector().rend());
00449
00450 }
00451 else {
00452
00453
00454
00455
00456
00457 creator.data()->cagt_vec = chromat_array;
00458 }
00459
00460 delete chr_it;
00461
00462 creator.create(true);
00463 }
00464
00465
00466 }
00467
00468 void TrapperDoc::importPhd(const QString& dirname)
00469 {
00470
00471
00472 vector<string> names = all_readnames();
00473
00474
00475
00476 for( size_t i = 0; i < names.size(); i++ ) {
00477
00478 TrapperVector<Q_UINT32> phd_array;
00479
00480 PhdParser parser(dirname + '/' + names[i] + ".phd.1");
00481 phd_array = parser.parse();
00482
00483 if ( phd_array.size() == 0 ) {
00484 cerr<<"Error, couldn't find phd file for "<<names[i]<<endl;
00485 continue;
00486 }
00487
00488 Database::SecondaryIterator<ReadData> name_it( "name", this, "ReadData" );
00489 name_it.key()->setName( names[i] );
00490 if ( name_it.set() != 0 ) {
00491 cerr<<"Error, couldn't find "<<names[i]<<" in db"<<endl;
00492 continue;
00493 }
00494
00495 Database::SecondaryIterator<ChromatData>* chr_it =
00496 new Database::SecondaryIterator<ChromatData>( "readRecno", this, "ChromatData" );
00497
00498 chr_it->key()->setReadRecno( name_it.answer()->getRecno() );
00499
00500 if ( chr_it->set() != 0 ) {
00501 cerr<<"Error, couldn't find recno "<<name_it.answer()->getRecno()<<" of read "<<names[i]<<endl;
00502 delete chr_it;
00503 continue;
00504 }
00505 if ( chr_it->answer()->cagt_vec[0].stlVector().size() == 0 ) {
00506 cerr<<"Chromat file for "<<names[i]<<" not imported, skipping phd file"<<endl;
00507 delete chr_it;
00508 continue;
00509 }
00510
00511
00512 Database::Creator<ChromatData> creator( this, "ChromatData" );
00513
00514 creator.data()->copy(chr_it->answer());
00515
00516 if ( name_it.answer()->strand() == "C" ) {
00517 creator.data()->phd_vec.stlVector().clear();
00518 creator.data()->phd_vec.stlVector().insert(creator.data()->phd_vec.stlVector().begin(),
00519 phd_array.stlVector().rbegin(), phd_array.stlVector().rend());
00520 for( size_t i = 0; i < creator.data()->phd_vec.stlVector().size(); i++ ) {
00521 creator.data()->phd_vec.stlVector()[i] = creator.data()->cagt_vec[0].stlVector().size() - 1 - creator.data()->phd_vec.stlVector()[i];
00522 }
00523 }
00524 else {
00525
00526 creator.data()->phd_vec = phd_array;
00527 }
00528
00529
00530 delete chr_it;
00531
00532
00533 Database::SecondaryIterator<DnaStrData>* dna_it =
00534 new Database::SecondaryIterator<DnaStrData>( "readRecno", this, "DnaStrData" );
00535 dna_it->key()->setReadRecno( name_it.answer()->getRecno() );
00536
00537 if ( dna_it->set() != 0 ) {
00538 cerr<<"Error, couldn't find recno "<<name_it.answer()->getRecno()<<" of read "<<names[i]<<endl;
00539 delete dna_it;
00540 continue;
00541 }
00542 creator.data()->gap_vec.stlVector().clear();
00543 size_t numgap(0);
00544 for( size_t i = 0; i < dna_it->answer()->dnaVector.size(); i++ ) {
00545 if (dna_it->answer()->dnaVector.stlVector()[i] == '*' ) {
00546 numgap++;
00547 }
00548 creator.data()->gap_vec.stlVector().push_back(numgap);
00549 }
00550
00551 if ( creator.data()->gap_vec.stlVector().size() != creator.data()->endPos() + 1) {
00552 cerr<<"creator.data()->gap_vec.stlVector().size(): "<<
00553 creator.data()->gap_vec.stlVector().size()<<endl;
00554 cerr<<"creator.data()->endPos(): "<<creator.data()->endPos()<<endl;
00555 }
00556
00557 assert( creator.data()->gap_vec.stlVector().size() == creator.data()->endPos() + 1 );
00558 delete dna_it;
00559
00560
00561
00562 creator.create(true);
00563
00564 }
00565
00566
00567 }
00568
00569 void TrapperDoc::importMates(const QString& filename)
00570 {
00571
00572
00573 vector<string> names = all_readnames();
00574
00575
00576 MateParser parser;
00577 parser.set_file(filename);
00578
00579 string read_name, mate_name;
00580 size_t mate_length;
00581
00582 while( parser.parse_line( read_name, mate_name, mate_length ) ) {
00583
00584
00585
00586
00587
00588
00589
00590
00591 Database::Creator<ReadData> creator( this, "ReadData" );
00592
00593
00594 Database::SecondaryIterator<ReadData>* name_it =
00595 new Database::SecondaryIterator<ReadData>( "name", this, "ReadData" );
00596 name_it->key()->setName( read_name );
00597 if ( name_it->set() != 0 ) {
00598 delete name_it;
00599 continue;
00600 }
00601
00602 creator.data()->copy( name_it->answer() );
00603
00604 creator.data()->setMate( mate_name );
00605 creator.data()->setMateLength( mate_length );
00606
00607
00608 delete name_it;
00609
00610 creator.create(true);
00611
00612
00613
00614
00615 name_it = new Database::SecondaryIterator<ReadData>( "name", this, "ReadData" );
00616 name_it->key()->setName( mate_name );
00617 if ( name_it->set() != 0 ) {
00618 delete name_it;
00619 continue;
00620 }
00621 creator.data()->copy( name_it->answer() );
00622
00623 creator.data()->setMate( read_name );
00624 creator.data()->setMateLength( mate_length );
00625
00626
00627 delete name_it;
00628
00629 creator.create(true);
00630
00631 }
00632
00633 }
00634
00635
00636 vector<string> TrapperDoc::all_readnames()
00637 {
00638 vector<string> names;
00639
00640 Database::SecondaryIterator<ReadData> name_it( "name", this, "ReadData" );
00641 assert(name_it.first() == 0);
00642 string name;
00643
00644 do {
00645 name = name_it.answer()->name().c_str();
00646 names.push_back(name);
00647 }while( name_it.next() == 0 );
00648
00649 return names;
00650
00651 }
00652
00653
00654 void TrapperDoc::openDbs()
00655 {
00656
00657 list<string> alist = GeneralMaker::listRegistered();
00658
00659 for ( list<string>::iterator it = alist.begin(); it != alist.end(); ++it )
00660 {
00661 GeneralData * data = GeneralMaker::newData( *it );
00662 if ( data )
00663 {
00664 QString directoryName( m_contigDir );
00665 directoryName += "/";
00666 directoryName += it->c_str() ;
00667
00668 QDir dir;
00669 dir.mkdir( directoryName , true );
00670
00671 TrDb * trdb = new TrDb( dbenv, directoryName.ascii() , data->getIndexMap() );
00672 trDbMap.insert( make_pair( it->c_str(), trdb ) );
00673
00674
00675
00676
00677
00678 delete data;
00679 trdb->open();
00680
00681
00682 }
00683 }
00684
00685 }
00686
00687 TrDb * TrapperDoc::findTrDb( string generalDataName )
00688 {
00689 TrDb * trdb = NULL;
00690 TrDbMap::iterator it;
00691 it = trDbMap.find( generalDataName );
00692 if (it != trDbMap.end())
00693 {
00694 trdb = it->second;
00695 }
00696 else
00697 {
00698 cerr << "TrDb for generalData type=\""
00699 << generalDataName << "\" and contig=\""
00700 << m_contigDir << "\" not found" << endl;
00701 }
00702 return trdb;
00703 }
00704
00705 void TrapperDoc::closeDbs()
00706 {
00707
00708 TrDbMap::iterator it;
00709 it = trDbMap.begin();
00710
00711 while (it != trDbMap.end()) {
00712 Q_CHECK_PTR( it->second );
00713 it->second->close();
00714 delete it->second;
00715 ++it;
00716 }
00717 trDbMap.clear();
00718 }
00719
00720 QString TrapperDoc::getStatistics()
00721 {
00722 QString res;
00723 TrDbMap::iterator it;
00724 it = trDbMap.begin();
00725 while (it != trDbMap.end())
00726 {
00727 Q_CHECK_PTR( it->second );
00728 res += it->second->statistics();
00729 ++it;
00730 }
00731 return res;
00732 }