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