~ubuntu-branches/ubuntu/trusty/mira/trusty-proposed

« back to all changes in this revision

Viewing changes to src/modules/mod_memestim.C

  • Committer: Package Import Robot
  • Author(s): Thorsten Alteholz, Thorsten Alteholz, Andreas Tille
  • Date: 2014-02-02 22:51:35 UTC
  • mfrom: (7.1.1 sid)
  • Revision ID: package-import@ubuntu.com-20140202225135-nesemzj59jjgogh0
Tags: 4.0-1
[ Thorsten Alteholz ]
* New upstream version 
* debian/rules: add boost dir in auto_configure (Closes: #735798)

[ Andreas Tille ]
* cme fix dpkg-control
* debian/patches/{make.patch,spelling.patch}: applied upstream (thus removed)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Written by Bastien Chevreux (BaCh)
 
3
 *
 
4
 * Copyright (C) 1997-2000 by the German Cancer Research Center (Deutsches
 
5
 *   Krebsforschungszentrum, DKFZ Heidelberg) and Bastien Chevreux
 
6
 * Copyright (C) 2000 and later by Bastien Chevreux
 
7
 *
 
8
 * All rights reserved.
 
9
 *
 
10
 * This program is free software; you can redistribute it and/or
 
11
 * modify it under the terms of the GNU General Public License
 
12
 * as published by the Free Software Foundation; either version 2
 
13
 * of the License, or (at your option) any later version.
 
14
 *
 
15
 * This program is distributed in the hope that it will be useful,
 
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
18
 * GNU General Public License for more details.
 
19
 *
 
20
 * You should have received a copy of the GNU General Public License
 
21
 * along with this program; if not, write to the
 
22
 * Free Software Foundation, Inc.,
 
23
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
 
24
 *
 
25
 */
 
26
 
 
27
#include <iostream>
 
28
#include <iterator>
 
29
#include <string>
 
30
 
 
31
 
 
32
#include "modules/mod_memestim.H"
 
33
#include "modules/misc.H"
 
34
 
 
35
 
 
36
#include "mira/assembly.H"
 
37
#include "version.H"
 
38
 
 
39
 
 
40
using namespace std;
 
41
 
 
42
 
 
43
void mme_askChar(const string & question, const string & possibilities, char & answer, const char defchar)
 
44
{
 
45
  bool doloop=true;
 
46
  while(doloop){
 
47
    cout << question << ' ';
 
48
    if(!possibilities.empty()){
 
49
      cout <<"(";
 
50
      std::copy(possibilities.begin(),
 
51
                possibilities.end(),
 
52
                ostream_iterator<char> (cout, "/"));
 
53
      cout << ") ";
 
54
    }
 
55
    if(defchar!=0){
 
56
      cout << "[" << defchar << "] ";
 
57
    }
 
58
    string input;
 
59
    getline(cin,input);
 
60
 
 
61
    // empty input, try to get defchar from possibilities if it exists
 
62
    if(input.empty() && defchar!=0) input=defchar;
 
63
    input.resize(1);
 
64
    for(uint32 i=0; i<possibilities.size(); i++){
 
65
      if(input[0] == possibilities[i]) {
 
66
        doloop=false;
 
67
        answer=input[0];
 
68
        break;
 
69
      }
 
70
    }
 
71
  }
 
72
  cout << answer << endl;
 
73
}
 
74
 
 
75
void mme_askDoubleNP(const string & question, double & answer, const string & defd)
 
76
{
 
77
  bool doloop=true;
 
78
  while(doloop){
 
79
    cout << question << ' ';
 
80
    if(!defd.empty()){
 
81
      cout << "[" << defd << "] ";
 
82
    }
 
83
    string input;
 
84
    getline(cin,input);
 
85
 
 
86
    // empty input, try to get def from possibilities if it exists
 
87
    if(input.empty() && !defd.empty()) {
 
88
      input=defd;
 
89
    }
 
90
    char * pend;
 
91
    answer=strtod(input.c_str(),&pend);
 
92
    doloop=false;
 
93
 
 
94
    // try to parse kilo, mega, giga
 
95
    while(*pend != 0 && isspace(*pend)) pend++;
 
96
    switch(toupper(*pend)){
 
97
    case 0 : break;
 
98
    case 'K' :{
 
99
      answer*=1000;
 
100
      break;
 
101
    }
 
102
    case 'M' :{
 
103
      answer*=1000000;
 
104
      break;
 
105
    }
 
106
    case 'G' :{
 
107
      answer*=1000000000;
 
108
      break;
 
109
    }
 
110
    default : {
 
111
      cout << "Please only use k, m, g as modifiers.\n";
 
112
      doloop=true;
 
113
    }
 
114
    }
 
115
  }
 
116
}
 
117
 
 
118
void mme_askDouble(const string & question, double & answer, const string & defd)
 
119
{
 
120
  mme_askDoubleNP(question, answer, defd);
 
121
  cout << answer << endl;
 
122
}
 
123
 
 
124
void mme_askInt(const string & question, int64 & answer, const string & defint)
 
125
{
 
126
  double tmp;
 
127
  mme_askDoubleNP(question, tmp, defint);
 
128
  answer=static_cast<int64>(tmp);
 
129
  cout << answer << endl;
 
130
}
 
131
 
 
132
 
 
133
void miraMemEstimate(int argc, char ** argv)
 
134
{
 
135
  int c;
 
136
  extern char *optarg;
 
137
  extern int optind;
 
138
 
 
139
  while (1){
 
140
    c = getopt(argc, argv, "v");
 
141
    if(c == -1) break;
 
142
 
 
143
    switch (c) {
 
144
    case 'v':
 
145
      cout << MIRAVERSION << endl;
 
146
      exit(0);
 
147
    default : {}
 
148
    }
 
149
  }
 
150
 
 
151
 
 
152
  cout << "This is MIRA " MIRAVERSION ".\n\n";
 
153
 
 
154
  cout << "Please cite: Chevreux, B., Wetter, T. and Suhai, S. (1999), Genome Sequence\nAssembly Using Trace Signals and Additional Sequence Information.\nComputer Science and Biology: Proceedings of the German Conference on\nBioinformatics (GCB) 99, pp. 45-56.\n\n";
 
155
  dumpStdMsg();
 
156
 
 
157
  cout << "\n\nmiraMEM helps you to estimate the memory needed to assemble a project.\n"
 
158
    "Please answer the questions below.\n\n"
 
159
    "Defaults are give in square brackets and chosen if you just press return.\n"
 
160
    "Hint: you can add k/m/g modifiers to your numbers to say kilo, mega or giga.\n\n";
 
161
 
 
162
  char yesno;
 
163
  char ptype=' ';
 
164
  char denovomapping;
 
165
  int64 seqsize=0;
 
166
 
 
167
  int64 numsanreads=0;
 
168
  int64 num454gs20reads=0;
 
169
  int64 num454flxreads=0;
 
170
  int64 num454titaniumreads=0;
 
171
  int64 numsxareads=0;
 
172
  int64 avgsxalen=0;
 
173
  int64 numpbsreads=0;
 
174
  int64 avgpbslen=0;
 
175
  int64 largestcontigexpected=0;
 
176
 
 
177
  // computed
 
178
  int64 totalexpectedbases=0;
 
179
  int64 totalreads=0;
 
180
  int64 readsinlargestcontig=0;
 
181
  int64 readbasesinlargestcontig=0;
 
182
 
 
183
  mme_askChar("Is it a genome or transcript (EST/tag/etc.) project?",
 
184
              "ge",
 
185
              ptype,
 
186
              'g');
 
187
  if(ptype=='g'){
 
188
    mme_askInt("Size of genome?",
 
189
               seqsize,
 
190
               "4.5m");
 
191
    if(seqsize<100) {
 
192
      cout << "A sequence size of less than 100 bases is pretty improbable.\n"
 
193
           << "Did you forget a modifier (k, m or g) to the number you gave?\n";
 
194
      exit(10);
 
195
    }
 
196
    largestcontigexpected=seqsize;
 
197
    if(largestcontigexpected>30*1000*1000){
 
198
      cout << "Looks like a larger eukaryote, guessing largest chromosome size: 30m\nChange if needed!\n";
 
199
      largestcontigexpected=30*1000*1000;
 
200
    }
 
201
 
 
202
    {
 
203
      string tmplc;
 
204
      ostringstream ostr;
 
205
      ostr << largestcontigexpected;
 
206
      tmplc=ostr.str();
 
207
      mme_askInt("Size of largest chromosome?",
 
208
                 largestcontigexpected,
 
209
                 tmplc);
 
210
    }
 
211
 
 
212
    mme_askChar("Is it a denovo or mapping assembly?",
 
213
                "dm",
 
214
                denovomapping,
 
215
                'd');
 
216
  }
 
217
 
 
218
 
 
219
  mme_askInt("Number of Sanger reads?",
 
220
             numsanreads,
 
221
             "0");
 
222
  mme_askChar("Are there 454 reads?",
 
223
              "yn",
 
224
              yesno,
 
225
              'n');
 
226
  if(yesno=='y'){
 
227
    mme_askInt("Number of 454 GS20 reads?",
 
228
               num454gs20reads,
 
229
               "0");
 
230
    mme_askInt("Number of 454 FLX reads?",
 
231
               num454flxreads,
 
232
               "0");
 
233
    mme_askInt("Number of 454 Titanium reads?",
 
234
               num454titaniumreads,
 
235
               "0");
 
236
  }
 
237
  mme_askChar("Are there PacBio reads?",
 
238
              "yn",
 
239
              yesno,
 
240
              'n');
 
241
  if(yesno=='y'){
 
242
    mme_askInt("Number of PacBio reads?",
 
243
               numpbsreads,
 
244
               "0");
 
245
    mme_askInt("Average PacBio length?",
 
246
               avgpbslen,
 
247
               "1100");
 
248
  }
 
249
  mme_askChar("Are there Solexa reads?",
 
250
              "yn",
 
251
              yesno,
 
252
              'n');
 
253
  if(yesno=='y'){
 
254
    mme_askInt("Number of Solexa reads?",
 
255
               numsxareads,
 
256
               "0");
 
257
    mme_askInt("Average Solexe length?",
 
258
               avgsxalen,
 
259
               "75");
 
260
  }
 
261
 
 
262
  totalexpectedbases=numsanreads*1000;
 
263
  totalexpectedbases+=num454gs20reads*120;
 
264
  totalexpectedbases+=num454flxreads*260;
 
265
  totalexpectedbases+=num454titaniumreads*460;
 
266
  totalexpectedbases+=numsxareads*avgsxalen;
 
267
  totalexpectedbases+=numpbsreads*avgpbslen;
 
268
 
 
269
  totalreads=numsanreads;
 
270
  totalreads+=num454gs20reads;
 
271
  totalreads+=num454flxreads;
 
272
  totalreads+=num454titaniumreads;
 
273
  totalreads+=numsxareads;
 
274
  totalreads+=numpbsreads;
 
275
 
 
276
  if(ptype=='g'){
 
277
    if(denovomapping=='d'){
 
278
      readsinlargestcontig=totalreads/2;
 
279
      readbasesinlargestcontig=totalexpectedbases/2;
 
280
    }else{
 
281
      largestcontigexpected=seqsize;
 
282
      readsinlargestcontig=totalreads;
 
283
      readbasesinlargestcontig=totalexpectedbases;
 
284
 
 
285
      // if solexa is mapped, there are less reads due to
 
286
      //  coverage equivalent mapping and virtual long reads
 
287
      // be conservative, reduce only by 50%
 
288
      if(numsxareads>0){
 
289
        readsinlargestcontig-=numsxareads/2;
 
290
      }
 
291
    }
 
292
  }else{
 
293
    seqsize=50000;
 
294
    largestcontigexpected=seqsize;
 
295
    readsinlargestcontig=50000;
 
296
    readbasesinlargestcontig=readsinlargestcontig*1000; //10k reads times sanger length
 
297
  }
 
298
 
 
299
  // account for gaps with 454 reads
 
300
  if(num454flxreads>0 || num454gs20reads>0){
 
301
    largestcontigexpected+=largestcontigexpected/10;
 
302
    readbasesinlargestcontig+=readbasesinlargestcontig/10;
 
303
  }
 
304
 
 
305
  //cout << "totalreads: " << totalreads
 
306
  //     << "\nreadsinlargestcontig: " << readsinlargestcontig
 
307
  //     << "\ntotalexpectedbases: " << totalexpectedbases
 
308
  //     << "\nreadbasesinlargestcontig: " << readbasesinlargestcontig
 
309
  //     << endl;
 
310
 
 
311
  int64 livereads=totalreads+readsinlargestcontig;
 
312
  int64 livebases=totalexpectedbases+readbasesinlargestcontig;
 
313
 
 
314
  //cout << "livereads: " << livereads
 
315
  //     << "\nlivebases: " << livebases << endl;
 
316
 
 
317
  double avgcov=static_cast<double>(totalexpectedbases/seqsize);
 
318
  avgcov-=avgcov/8; // in general we have 12% loss of usable data
 
319
 
 
320
  int64 numskimhits=static_cast<int64>(avgcov*850000);  // estimate skim hits, very rough
 
321
 
 
322
  int64 memneeded=0;
 
323
 
 
324
  // what do the reads need?
 
325
  memneeded=
 
326
    livereads*sizeof(Read)       // class size
 
327
    +livereads*200               // additional strings etc.
 
328
    +livereads*4*sizeof(tag_t)   // on average 4 tags per read
 
329
    +livebases*8;                // sequences, qualities, adjustments, base flags
 
330
 
 
331
  // new: solexa reads don't have adjustments
 
332
  // yeah, but estimate is already small enough, keep it
 
333
  //memneeded-=(numsxareads*avgsxalen) * 2;
 
334
 
 
335
 
 
336
  // what does a contig need?
 
337
  //  (note: the needs for the reads themselves are already
 
338
  //   accounted for in the section above)
 
339
  memneeded+=
 
340
    //readsinlargestcontig*sizeof(Contig::contigread_t)
 
341
    //+readsinlargestcontig*sizeof(Contig::out_order_t)
 
342
 
 
343
    readsinlargestcontig*40       // 40 == rough guesstimate for PlacedContigReads
 
344
    +totalreads*9                              /* templates, mapping
 
345
                                                 allowedrefids */
 
346
    +largestcontigexpected*sizeof(Contig::consensus_counts_t)
 
347
    +largestcontigexpected*10;              // adjustments and some reserve
 
348
 
 
349
  int64 memforlargetables=0;
 
350
  // some more overhead by the assembly class
 
351
  memforlargetables+= totalreads*20;
 
352
 
 
353
  // get the skim edges accounted
 
354
  int64 skimhitsmem=numskimhits*2*sizeof(skimedges_t);
 
355
  // since 2.9.40 there's the possibility to cap that memory
 
356
  // use default value
 
357
  if(skimhitsmem>1024L*1024*1024){
 
358
    skimhitsmem=2LL*1024*1024*1024;
 
359
    if(numsxareads>0) skimhitsmem*=2;
 
360
  }
 
361
 
 
362
  // mem needed for temporary skim need
 
363
  int64 tmpskim=500*1000*1000;
 
364
 
 
365
  memforlargetables+=max(skimhitsmem,tmpskim);
 
366
 
 
367
  // possible vector leftover clip
 
368
  int64 memforpvlc=0;
 
369
  {
 
370
    // AS_readhitmiss & AS_readhmcovered
 
371
    memforpvlc=totalexpectedbases*8;
 
372
    // overhead of the structures above
 
373
    memforpvlc+=sizeof(vector<uint32>)*totalreads*2;
 
374
 
 
375
    // AS_count_rhm
 
376
    memforpvlc+=totalreads*4;
 
377
  }
 
378
 
 
379
  // ok, 1MB of additional small things
 
380
  int64 memneededfordata=memneeded+(1024*1024);
 
381
 
 
382
  // experience shows that not all has been accounted for
 
383
  //  and internal mem caching of memory allocators add another
 
384
  //  layer of RAM needs
 
385
  //
 
386
  // add 40% to estimates
 
387
  //  but not if whe have mapping with Solexas
 
388
  if(denovomapping!='m' && numsxareads==0){
 
389
    memneededfordata+=memneededfordata/100*40;
 
390
    memforlargetables+=memforlargetables/100*40;
 
391
  }
 
392
 
 
393
  cout.setf(ios::fixed, ios::floatfield);
 
394
  //cout.setf(ios::showpoint);
 
395
  cout.precision(1);
 
396
 
 
397
  cout << "\n\n************************* Estimates *************************\n\n";
 
398
  // last, if it's an EST assembly, there is no seqsize
 
399
 
 
400
  if(ptype=='e'){
 
401
    cout << "EST assembly, cannot give coverage estimate. Also, estimates"
 
402
      "\nmay be way off for pathological cases.\n";
 
403
 
 
404
  }else{
 
405
    cout << "The contigs will have an average coverage of ~ " << avgcov
 
406
         << " (+/- 10%)"
 
407
      "\nEstimates may be way off for pathological cases.\n";
 
408
  }
 
409
 
 
410
  cout << "\nRAM estimates:"
 
411
    "\n" << setw(40) << "reads+contigs (unavoidable): ";
 
412
  byteToHumanReadableSize(memneededfordata,cout);
 
413
  cout << "\n" << setw(40) << "large tables (tunable): ";
 
414
  byteToHumanReadableSize(memforlargetables,cout);
 
415
  cout << "\n" << setw(40) << "" << "---------"
 
416
    "\n" << setw(40) << "total (peak): ";
 
417
  byteToHumanReadableSize(memforlargetables+memneededfordata,
 
418
                          cout);
 
419
  cout << "\n\n" << setw(40) << "add if using -CL:pvlc=yes : ";
 
420
  byteToHumanReadableSize(memforpvlc,cout);
 
421
  if(denovomapping=='m' && numsxareads>0){
 
422
    int64 notusingmerge=memneededfordata/100*40;
 
423
    cout << "\n" << setw(40) << "add if setting -CO:msr=no : ";
 
424
    byteToHumanReadableSize(notusingmerge,cout);
 
425
  }
 
426
  cout << "\n\n"
 
427
    "Note that some algorithms might try to grab more memory if"
 
428
    "\nthe need arises and the system has enough RAM. The options"
 
429
    "\nfor automatic memory management control this:"
 
430
    "\n  -AS:amm, -AS:kpmf, -AS:mps"
 
431
    "\nFurther switches that might reduce RAM (at cost of run time"
 
432
    "\nor accuracy):"
 
433
    "\n  -SK:mhim, -SK:mchr (both runtime); -SK:mhpr (accuracy)\n"
 
434
    "*************************************************************\n";
 
435
 
 
436
}
 
437
 
 
438