-
Notifications
You must be signed in to change notification settings - Fork 2
/
MG-TK.pl
7484 lines (6508 loc) · 321 KB
/
MG-TK.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#!/usr/bin/env perl
#The Metagenomic Assembly, Genomic Recovery and Assembly Independent Mapping Tool (formerly MATAFILER, now mg-tk)
#main mg-tk routine
# (c) Falk Hildebrand, 2016-2024
#examples
#./mg-tk.pl map2tar test/refCtg.fasta,test/refCtg.fasta test1,test2
#./mg-tk.pl map2tar test/TEC2/v5/TEC2.MM4.BEE.GF.rn.fa TEC2
#./mg-tk.pl -map dir/map
use warnings;
use strict;
use File::Basename;
use Cwd 'abs_path';
use POSIX;
use Getopt::Long qw( GetOptions );
use vars qw($CONFIG_FILE);
#load MF specific modules
use Mods::GenoMetaAss qw(readMap getDirsPerAssmblGrp lcp readFastHD prefixFAhd prefix_find gzipopen fileGZe
readFasta writeFasta systemW getAssemblPath filsizeMB
iniCleanSeqSetHR checkSeqTech is3rdGenSeqTech hasSuppRds
getRawSeqsAssmGrp getCleanSeqsAssmGrp addFileLocs2AssmGrp);
use Mods::IO_Tamoc_progs qw(getProgPaths setConfigFile jgi_depth_cmd inputFmtSpades inputFmtMegahit createGapFillopt
buildMapperIdx mapperDBbuilt decideMapper checkMapsDoneSH greaterComputeSpace);
use Mods::SNP qw(SNPconsensus_vcf );
use Mods::TamocFunc qw (cram2bsam getSpecificDBpaths getFileStr displayPOTUS bam2cram checkMF checkMFFInstall);
use Mods::phyloTools qw(fixHDs4Phylo);
#use Mods::Binning qw (runMetaBat runCheckM runSemiBin runMetaDecoder );
use Mods::Subm qw (qsubSystemWaitMaxJobs qsubSystem emptyQsubOpt findQsubSys qsubSystemJobAlive MFnext add2SampleDeps numUserJobs);
#some useful HPC commands..
#bjobs | awk '$3=="CDDB" {print $1}' |xargs bkill
#bjobs | grep 'dWXmOT' | cut -f11 -d' ' | xargs -t -i bkill {}
#squ | grep 'r' | cut -f11 -d' ' | xargs -t -i scontrol update TimeLimit=84:00:00 jobid={}
#squ | grep 'dencyNev' | cut -f11 -d' ' | xargs -t -i scancel {}
#bhosts | cut -f1 -d' ' | grep -v HOST_NAME | xargs -t -i ssh {} 'killall -u hildebra'
#hosts=`bhosts | grep ok | cut -d" " -f 1 | grep compute | tr "\\n" ","`; pdsh -w $hosts "rm -rf /tmp/hildebra"
#local subs
sub announce_MGTK;
sub smplStats; sub checkDrives;
sub isLastSampleInAssembly;
sub uploadRawFilePrep; sub unploadRawFilePostprocess;
sub seedUnzip2tmp; sub cleanInput; #unzipping reads; removing these at later stages ; remove tmp dirs
sub manageFiles;sub clean_tmp;
sub sdmClean; sub sdmOptSet; #qual filter reads
sub mergeReads; #merge reads via flash
sub krakHSap; sub krakenTaxEst;sub prepKraken;
sub metagAssemblyRun;
sub createPsAssLongReads; #pseudo assembler
sub prepPreAssmbl; #hybrid pacbio/ill assemblies
sub genePredictions; sub run_prodigal; #gene prediction
sub mapReadsToRef; sub scndMap2Genos;
sub runContigStats;#sub bam2cram;
sub mocat_reorder; sub postSubmQsub;
sub detectRibo; sub RiboMeta;sub riboSummary;
sub runOrthoPlacement;
sub runDiamond; sub DiaPostProcess; sub IsDiaRunFinished;
sub nopareil; sub calcCoverage;sub d2metaDist;
sub metphlanMapping; sub mergeMP2Table;
sub mOTU2Mapping; sub mergeMotu2Table; sub prepMOTU2;
sub genoSize; sub check_map_done; sub check_depth_done;
sub postprocess;
sub setDefaultMFconfig;
sub getCmdLineOptions;
sub setupHPC;
#------- version history MATAFILER --------
#.22: fixing of assembly.txt paths, if output folders were later copied around
#.23: upgrade to metaphlan3 & motus3 & general update to workflow that these no longer need sdm filtered reads
#.24: new sdm version, better HDD space usage control, reworked EBIupload routines, sdm cores back to 4, bug fixes..
#.25: added SemiBin and MetaDecoder
#.26: added pprodigal, MUSCLE5, addapted cc.bin resource usage, semibin integration in MGS.pl, checkM2 by default used
#.27: added "loopTillComplete" functionality
#.28: extended loopTillComplete, better sq control
#.29: added more control of tmp node space, better reporting on scratch usage & paired samples
#.30: changed installer massively, now split into 3 packs: matafiler.yml, gtdbtk.yml, Rbase.yml. motus.yml is only for motus, as massive dep problems with this one..
#.31 further cleanup to installer, sdm does now trimmomatic job (saves 1 step), sdm v2.07, tmp_space refinements, SNP calling performance improved, flow improved
#.32: more automatation to ssd & RAM usage
#.33: fixes metagStats, phylotools, cc.bin and strainWithin.pl
#.34: cut5PR1 and cut5PR2 mapping headers added. sdm 2.10
#.35: bugfixes to flow control (should be less iteration MF now), replaced bedtools with mosdetph
#.36: rm mosdepth, replaced with samtools depth; integrated kma, but bowtie2 remains default aligner
#.37: bug fix rmDup correctly activated
#.38: first implementation of automatic sample lock; furthermore bam->fastq functionality (single end) implemented
#.39: smplLock improvements, genecat improvements, prevent rm bwt idx
#.40: refactor how internally file paths are transferred and kept up-to-date between different subfunctions
#.41: 31.1.24: bugfixes related to refactor. full implementation of eggNOGmapper. bugfixes in MGS and genecat workflows
#.42: 2.3.24: reworked how nodeTmpSpace & Ram are denoted internally; starting binner now in same round as other steps (one less round of starting MF)
#.43: 17.3.24: first version of hybrid ill-PB assemblies working! also reworked getProgPaths to be faster
#.44: 20.3.24: hybrid ill-PB implemented for assembly groups. PB assembler implemented for assembly group. added proper subfunction to manage assembly mode
#.45: 13.4.24: reactivated ribofinder module
#.46: 23.4.24: hybrid assembly reworked. refactor code. less false subm dependencies.
#.47: 24.4.24: gene coverage by default gz'd, more safety checks that related files are gz'd. semiBin2 by default used now. SemiBin2 can use support read coverage profiles in addition to primary reads (increases MAG recovery).
#.48: stabilized hybrid assm. Contigstats uses .gz as input.
#.49: 17.5.24: tentative strobealign added
#.50: 18.5.24: bugfixes workflow, autodetect to rm locks, code cleanups
#.51: code refactor
#.52: 6.6.24: start implementation (.3di). more checks on correct pipe excecution.
#,53: 27.7.24: routine to check if some essential programs have been correctly installed and are avaialble. added flag -checkInstall. Moved geneCat.pl and MGS.pl to secScripts/ dir to avoid confusion on where to start..
#.54: 15.8.24: renamed MATAFILER to mg-tk
#.55: 23.10.24: integrated -getAssemblConsSNPsuppRds -SNPconsMinDepth flags and functionalities
#.56: 25.10.24: small bugfixes to submission logic, to submit less jobs that would fail in any case
#.57:26.10.24: enabled multi-input files for minimap2/strobealign, added "-mapperLargeRef" flag
my $MATFILER_ver = 0.57;
#operation mode?
my $ARGV0 = "";$ARGV0 = $ARGV[0] if (@ARGV > 0);
#----------------- defaults -----------------
my %jmp=();
my $logDir = ""; #this is the local logdir
my $sharedTmpDirP = ""; #e.g. /scratch/MG-TK/
my $nodeTmpDirBase = "";#/tmp/MG-TK/
my $baseDir = ""; my $baseOut = "";
#control broad flow
my $FROM1=0; my $TO1=999999999999;
#counter on where MF is in map
my $JNUM=0;
my $doSubmit=1;
my $rewrite=0;
my $baseID = "";
my $loop2completion = "0" ; #
my $loop2c_winsize=0;
my $loop2completion_ini=0;
#config is more overall configuration for MATAFILER
my %MFconfig;
#MFcontstants: object to store essential paths/file endings
my %MFcontstants;
#MFopt: global object with options for MG-TK. Added in MF v0.5, slowly rebuild MF around this system
my %MFopt;
#keep track of DBs that the metagenome will be filtered against..
my @filterHostDB = ();
#track secondary mapping and ref DBs
my %map2ndTogRefDB;my %make2ndMapDecoy;
my @bwt2outD =(); my @DBbtRefX = (); my @DBbtRefGFF=(); my @bwt2ndMapNmds;
my @scaffTarExternalOLib1; my @scaffTarExternalOLib2;
my @EBIjobs = (); #keeps track of $MFconfig{uploadRawRds} jobs, submits postprocessing (md5)
#----------- map all reads to a specific reference - options ---------
#progStats: object to track progress of programs/submissions
my %progStats;#count up progress of submitted jobs in current run
#HDDspace: object to handle HDD usage: Always format as "XXG" XX = space requirements in Gb. Excecption: "-1"
my %HDDspace;
my %inputFileSizeMB; #stores file size/sample
my %locStats; #keeps statistics of samples in hash (from already finished samples
#say hello to user
announce_MGTK();
setDefaultMFconfig();
getCmdLineOptions;
checkMF(1);
#set up further dependencies for MF
if ($loop2completion =~ m/(\d+):(\d+)/){
$loop2c_winsize = int($2);$loop2completion=$1;$loop2completion_ini=$1;
print "Loop2completion=$loop2completion; Window size=$loop2c_winsize\n";
} elsif ($loop2completion ne "0") {
$loop2completion = 6 ;$loop2completion_ini=6; #set to std number of iterations..
}
#dirs from config file--------------------------
#can be overwritten by $map{opt}{GlbTmpD} $map{opt}{NodeTmpD}
$sharedTmpDirP = getProgPaths("globalTmpDir",0) unless ($sharedTmpDirP ne "");
$nodeTmpDirBase = getProgPaths("nodeTmpDir",0) unless ($nodeTmpDirBase ne "");
#programs of global (pun) importance --------------------------
my $smtBin = getProgPaths("samtools");#
my $pigzBin = getProgPaths("pigz");
my $avx2Constr = getProgPaths("avx2_constraint",0);
#set up link to submission system on cluster
my $QSBoptHR = setupHPC();
# the map and some base parameters (base ID, in path, out path) can be (re)set
my %map; my %AsGrps; my %DOs;#DOs only required for metabat, to use all mappings within an assembly group
my ($hr,$hr2) = readMap($MFconfig{mapFile},0,\%map,\%AsGrps,$MFconfig{oldStylFolders});
%AsGrps = %{$hr2}; %map = %{$hr};
if ($MFopt{DoMetaBat2}){
my ($hrD,$hrM) = getDirsPerAssmblGrp(\%map,\%AsGrps);
%DOs = %{$hrD};
}
#$baseDir = $map{inDir} if (exists($map{inDir} ));
$baseOut = $map{opt}{outDir} if (exists($map{opt}{outDir} ) && $map{opt}{outDir} ne "");
$baseID = $map{opt}{baseID} if (exists($map{opt}{baseID} ) && $map{opt}{baseID} ne "");
die "provide an outdir in the mapping file\n" if ($baseOut eq "");
die "provide a baseID in the mapping file\n" if ($baseID eq "");
#overwrite tmp dirs??
if ($map{opt}{GlbTmpD} ne ""){print "Taking Global temp dir from map: $map{opt}{GlbTmpD} \n";$sharedTmpDirP = $map{opt}{GlbTmpD} ;}
if ($map{opt}{NodeTmpD} ne ""){print "Taking Node temp dir from map: $map{opt}{NodeTmpD} \n";$nodeTmpDirBase = $map{opt}{NodeTmpD} ;}
my $runTmpDirGlobal = "$sharedTmpDirP/$baseID/";
my $runTmpDBDirGlobal = "$runTmpDirGlobal/DB/";
unless (-d $runTmpDBDirGlobal){
system "mkdir -p $runTmpDBDirGlobal" ;
#and check that this dir exists...
sleep(1);
die "Can't create $runTmpDBDirGlobal\n" unless (-d $runTmpDBDirGlobal);
}
my $globaldDiaDBdir = $runTmpDBDirGlobal."DiamDB/";
system "mkdir -p $globaldDiaDBdir" unless (-d $globaldDiaDBdir);
#----------- map all reads to a specific reference, preparation ---------
my $map2ndMpde=0;#0=map2tar;2=map2DB;3=map2GC
#----------- scaffolding external contigs parameters
my $scaffTarExternal = "";my $scaffTarExternalName = "";
my $scaffTarExtLibTar = ""; my $bwt2ndMapDep = "";
map2ndPrep();
#some base stats kept in vars
my $sequencer = "hiSeq";#plattform the algos have to deal with
#my $DBpath="";
my $assDir="";
my $continue_JNUM = 0; #debug, set to 0 for full run
my $prevAssembly = ""; my $shortAssembly = "";#files with full length and short length assemblies
#my $mmpuOutTab = "";
#fixed stones
my $STOpreAssmblDone = "preassmblDone.sto"; #marks preAssebmly (hybrid assemblies etc) is done
my $STOassmbleDone = "ass.done.sto"; #marks assembly is done
#fixed dirs for specific set of samples
my $dir_MP2 = $baseOut."pseudoGC/Phylo/MP2/"; #metaphlan 2 dir
my $dir_mOTU2 = $baseOut."pseudoGC/Phylo/mOTU2/"; #mOUT 2 dir
my $dir_TaxTar = $baseOut."pseudoGC/Phylo/TaxaTarget/"; #taxaTar dir
my $dir_ContigStats = "/assemblies/metag/ContigStats/";
my $dir_RibFind = $baseOut."pseudoGC/Phylo/RiboFind/"; #ribofinder dir
my $dir_KrakFind = $baseOut."pseudoGC/Phylo/KrakenTax/$MFopt{globalKraTaxkDB}/"; #kraken dir
system("mkdir -p $baseOut") unless (-d $baseOut);
my $globalLogDir = $baseOut."LOGandSUB/"; #this is the gloabl logdir (across all samples in current run)
system("mkdir -p $globalLogDir/sdm") unless (-d "$globalLogDir/sdm");
open $QSBoptHR->{LOG},">",$globalLogDir."qsub.log";# unless ($doSubmit == 0);
my $collectFinished = $baseOut."runFinished.log\n";
my $globalNPD = $baseOut."NonPareil/";
system "mkdir -p $globalNPD" unless (-d "$globalNPD");
system "cp $MFconfig{mapFile} $globalLogDir/inmap.txt";
print $globalLogDir."qsub.log\n";
my $presentAssemblies = 0; my $totalChecked=0;
my @samples = @{$map{opt}{smpl_order}}; my @allSmplNames;
my @allFilter1; my @allFilter2; my @inputRawFQs;
my @EmptySample;
my $statStr = ""; my $statStr5 = "";
my %sampleSDMs;
my $curSmpl = "";
#my %assmblGrpLog; #security that no assmblGrp exists twice.. #actually not needed..
my $baseSDMopt = getProgPaths("baseSDMopt_rel"); #"/g/bork3/home/hildebra/dev/Perl/reAssemble2Spec/data/sdm_opt_inifilter_relaxed.txt";
if ($MFopt{useSDM} ==2 ){$baseSDMopt = getProgPaths("baseSDMopt");}#"/g/bork3/home/hildebra/dev/Perl/reAssemble2Spec/data/sdm_opt_inifilter.txt";}
my $baseSDMoptMiSeq = getProgPaths("baseSDMoptMiSeq_rel");#"/g/bork3/home/hildebra/dev/Perl/reAssemble2Spec/data/sdm_opt_miSeq.txt";
if ($MFopt{useSDM} ==2 ){$baseSDMoptMiSeq = getProgPaths("baseSDMoptMiSeq");}#"/g/bork3/home/hildebra/dev/Perl/reAssemble2Spec/data/sdm_opt_miSeq_relaxed.txt"; }
my @unzipjobs;
my $sdmjNamesAll = "";
my $waitTime = 0;
my @grandDeps; #used for loop2completion , collects dependencies
my $emptCmd = "sleep 333";
#qsubSystem($globalLogDir."emptyrun.sh","sleep 333",1,"1G",0,"empty","","",1);
#set up kraken human filter
my $krakDeps = ""; my $krakenDBDirGlobal = $runTmpDirGlobal;
if ($MFopt{DoKraken} && $MFopt{globalKraTaxkDB} eq ""){die "Kraken tax specified, but no DB specified\n";}
$krakDeps = prepKraken() if ($MFopt{humanFilter} || ($MFopt{DoKraken}) || $MFopt{DoEukGenePred});
#profiling prep
my $mOTU2Deps = prepMOTU2(); prepMetaphlan();
#redo d2s intersample distance?
if ($MFopt{DoCalcD2s}) {$MFopt{DoCalcD2s} = !-e "$baseOut/d2StarComp/d2meta.stone";}
my $from = $FROM1; my $to = $TO1;
if ($to > @samples){
print "Reset range of samples to ". @samples."\n";
$to = @samples;
}
if ($loop2c_winsize > 0){
$to = $from + $loop2c_winsize; $to = $TO1 if ($to > $TO1);
}
#--------------------------------------------------------------------------------
#--------------------------------------------------------------------------------
#--------------------------------------------------------------------------------
#--------------------------------------------------------------------------------
#die $to."\n";
#for loop that goes over every single sample in the .map
for ($JNUM=$from; $JNUM<$to;$JNUM++){
#local flow control
next if (exists($jmp{$JNUM}));
qsubSystemWaitMaxJobs($MFconfig{checkMaxNumJobs}, $MFconfig{killDepNever});
#set up initial local paths for a given sample
my $dir2rd=""; my $curDir = "";my $curOutDir = "";
$curSmpl = $samples[$JNUM];
$dir2rd = $map{$curSmpl}{dir};
$dir2rd = $map{$curSmpl}{prefix} if ($dir2rd eq "");
#print "$curSmpl $map{$curSmpl}{dir} $map{$curSmpl}{rddir} $map{$curSmpl}{wrdir}\n"; next;
my $SmplName = $map{$curSmpl}{SmplID};
if ($dir2rd eq "" ){#very specific read dir..
if ($map{$curSmpl}{SupportReads} ne ""){
$curDir = ""; $curOutDir = "$baseOut$SmplName/";
} else {
die "Can;t find valid path for $SmplName\n";
}
$dir2rd = $SmplName;
} else {
$curDir = $map{$curSmpl}{rddir}; $curOutDir = $map{$curSmpl}{wrdir};
}
$logDir = "$curOutDir/LOGandSUB/";
#ignore samples .. for various reasons ------------------------------------------------------------------------------------
if ($MFconfig{ignoreSmpl} ne ""){if ($MFconfig{ignoreSmpl} =~ m/$SmplName/){print "\n ======= Ignoring sample $SmplName =======\n";next;}}
my $smplLockF = "$logDir/$MFcontstants{DefaultSampleLock}";
if (-e $smplLockF){
if ($MFconfig{rmSmplLocks}){ system "rm -f $smplLockF";
} else {print "\n >>>>>>>>>> Sample $SmplName is locked! <<<<<<<<<< \n";next;}
}
$QSBoptHR->{LOCKfile} = $smplLockF; #set lockfile to be created if any job is submitted
push (@allSmplNames,$SmplName);
#die "$curDir\n$curOutDir\n$baseOut\n";
my $samplReadLength = $MFconfig{defaultReadLength}; #some default value
if (exists $map{$curSmpl}{readLength} && $map{$curSmpl}{readLength} != 0){
$samplReadLength = $map{$curSmpl}{readLength};
}
my $samplReadLengthX = $MFconfig{defaultReadLengthX}; #for any supplementary reads (eg PacBio)
if (exists $map{$curSmpl}{readLengthX} && $map{$curSmpl}{readLengthX} != 0){
$samplReadLengthX = $map{$curSmpl}{readLengthX};
}
#key IDs for sample
my $cAssGrp = $curSmpl;
my $cMapGrp = $map{$curSmpl}{MapGroup};
if ($map{$curSmpl}{AssGroup} ne "-1"){ $cAssGrp = $map{$curSmpl}{AssGroup};}
my $contigStatsUsed = 0;
%locStats = ();
$locStats{hasPaired} = 0; $locStats{hasSingle} = 0;
$totalChecked++;
#die $SmplName." $samplReadLength\n";
print "\n======= $SmplName - $JNUM - $dir2rd =======\n" unless($MFconfig{silent});
#set up dirs ------------------------------------------------------------------------------------
my $smplTmpDir = "$runTmpDirGlobal$SmplName/"; #curTmpDir
my $nodeSpTmpD = "$nodeTmpDirBase/$SmplName";
my @checkLocs = ($smplTmpDir);
push(@checkLocs,$curDir) if ($curDir ne "");
my $mapOut = "$smplTmpDir/mapping/";
#$DBpath="$curOutDir/readDB/";
my $finalCommAssDir = "$curOutDir/assemblies/metag/";
my $finalCommAssDirSingle = $finalCommAssDir; #this is only used for checking..
my $finalMapDir = "$curOutDir/mapping/";
my $KrakenOD = $curOutDir."Tax/kraken/$MFopt{globalKraTaxkDB}/";
$AsGrps{$cAssGrp}{AssemblSmplDirs} .= $curOutDir."\n";
my $AssemblyGo=0; my $MappingGo=0; #controls if assemblies / mappings are done in respective groups
#complicated flow control for multi sample assemblies
die "cAssGrp eq \"$cAssGrp\" ".$baseID."\n" if ($cAssGrp eq "");
my $assmGrpTag = "AssmblGrp_$cAssGrp";
#die "AssemblGrp exists already!!: \"$assmGrpTag\"\n" if (exists($assmblGrpLog{$assmGrpTag}));
#$assmblGrpLog{$assmGrpTag} = 1;
$assDir="$runTmpDirGlobal/$assmGrpTag/";
$finalCommAssDir = "$baseOut/$assmGrpTag/metag/" if ( !exists($AsGrps{$cAssGrp}{CntAimAss}) || $AsGrps{$cAssGrp}{CntAimAss}>1);
#my $metaGpreAssmblDir = "$runTmpDirGlobal/pre$assmGrpTag/";
my $metaGpreAssmblDir = "$smplTmpDir/pre$assmGrpTag/"; #needs to be sample specific (to allow for different coverage)
#assign job name (dependency) only ONCE
if ( !exists($AsGrps{$cAssGrp}{CntAss}) || $AsGrps{$cAssGrp}{CntAss} == 0){
$AsGrps{$cAssGrp}{AssemblJobName} = "";#"_XXASpl$cAssGrp"."XX_" ;
$AsGrps{$cAssGrp}{CSfinJobName} = "";#"_XXCSpl$cAssGrp"."XX_" ;
}
my @sampleDeps = ();
$AsGrps{$cAssGrp}{CntAss} ++;
print "AssmblyGrp: " . $AsGrps{$cAssGrp}{CntAss} .":".$AsGrps{$cAssGrp}{CntAimAss}. "; " if ($AsGrps{$cAssGrp}{CntAimAss} > 1 && !$MFconfig{silent});
if ($AsGrps{$cAssGrp}{CntAss} >= $AsGrps{$cAssGrp}{CntAimAss} ){
#print "running assembluy\n";
$AssemblyGo = 1;
if ($AsGrps{$cAssGrp}{CntAimAss}<=1){
$assDir="$smplTmpDir/assemblies/";
}
}
#mapping groups?
$AsGrps{$cMapGrp}{CntMap} ++;
print "MapGroup: ".$AsGrps{$cMapGrp}{CntMap} .":".$AsGrps{$cMapGrp}{CntAimMap}.";\n" unless ($MFconfig{silent});
if (!exists($AsGrps{$cMapGrp}{CntMap})){ die "Can;t find CntMap for $cMapGrp";}
if ($AsGrps{$cMapGrp}{CntMap} >= $AsGrps{$cMapGrp}{CntAimMap} ) {
#print "running mapping";
$MappingGo = 1;
}
#die "MG: $MappingGo\n";
if ($MFopt{DoAssembly} ==0 ){$AssemblyGo=0;}
#mapping related
my $cramthebam = 1;
my $bamcramMap = "bam"; if ($cramthebam){$bamcramMap = "cram";}
#---------------------------- 2 ----------------------------------
#set up dirs for this sample
my $metagAssDir = $assDir."metag/";
my $geneDir = $metagAssDir."genePred/";
#system("mkdir -p $metagAssDir $geneDir");
my $metaGassembly=$metagAssDir."scaffolds.fasta.filt";
my $finalCommScaffDir = "$finalCommAssDir/scaffolds/";
my $metaGscaffDir = "$metagAssDir/scaffolds/";
my $STOfinScaff = "$finalCommScaffDir/scaffDone.sto";
my $pseudoAssFile = "$metagAssDir/longReads.fasta.filt";
my $pseudoAssFileFinal = "$finalCommAssDir/longReads.fasta.filt";
my $finAssLoc = "$finalCommAssDir/scaffolds.fasta.filt";
my $ContigStatsDir = "$curOutDir/$dir_ContigStats/";
my $coveragePerCtg = "$ContigStatsDir/Coverage.percontig.gz";
my $suppCoveragePerCtg = "$ContigStatsDir/Cov.sup.percontig.gz";
my $nonParDir = $curOutDir."nonpareil/";
#SNP calling on assembly related files
my $SNPdir = "$curOutDir/SNP/";
my $contigsSNP = "$SNPdir/contig.SNPc.$MFopt{SNPcallerFlag}.fna"; #keep without gz, although will be gz'd
my $genePredSNP = "$SNPdir/genes.shrtHD.SNPc.$MFopt{SNPcallerFlag}.fna.gz";
my $genePredAASNP = "$SNPdir/proteins.shrtHD.SNPc.$MFopt{SNPcallerFlag}.faa.gz";
my $vcfSNP = "$SNPdir/allSNP.$MFopt{SNPcallerFlag}.vcf"; $vcfSNP = "" if (!$MFopt{saveVCF});
my $vcfSNPsupp = "$SNPdir/allSNP.$MFopt{SNPcallerFlag}-sup.vcf"; $vcfSNPsupp = "" if (!$MFopt{saveVCF});
my $CRAMmap = "$finalMapDir/$SmplName-smd.cram";
my $SupCRAMmap = "$finalMapDir/$SmplName.sup-smd.cram";
my $inputRawFile = "$curOutDir/input_raw.txt";
my $binningDir = "$finalCommAssDir/Binning/";
my @smplIDs = ("");#smpls in current assembly group
if ($MFopt{DoMetaBat2}){
@smplIDs = @{$DOs{$cAssGrp}{SmplID}};
}
my $BinningOut = "$binningDir/MB2/$smplIDs[-1]";
$BinningOut = "$binningDir/SB/$smplIDs[-1]" if ($MFopt{DoMetaBat2} == 2);
$BinningOut = "$binningDir/MD/$smplIDs[-1]" if ($MFopt{DoMetaBat2} == 3);
#stones
my $STOcram = "$CRAMmap.sto";
my $STOsupCram = "$SupCRAMmap.sto";
my $STOmapFinal="$finalMapDir/done.sto";
my $STOsnpCons = "$contigsSNP.SNP.cons.stone"; # my $SNPstone = $ofasConsDir."SNP.cons.stone";
my $STOsnpSuppCons = "$contigsSNP.SNP.supp.cons.stone";
# collect stats on seq qual, assembly etc
if ($MFconfig{alwaysDoStats}){
my ($statsHD,$curStats,$statsHD5,$curStats5) = smplStats($curOutDir,$assDir,$SmplName);
#add to global string that is later written
if ($statStr eq ""){
$statStr.="SMPLID\tDIR\t".$statsHD."\n".$curSmpl."\t$dir2rd\t".$curStats."\n";
$statStr5.="SMPLID\tDIR\t".$statsHD5."\n".$curSmpl."\t$dir2rd\t".$curStats5."\n";
} else {$statStr.=$curSmpl."\t$dir2rd\t".$curStats."\n"; $statStr5.=$curSmpl."\t$dir2rd\t".$curStats5."\n";}
}
#die;
#detect what already exists..
my $efinAssLoc = 0; $efinAssLoc = 1 if (-s $finAssLoc && -e "$finalCommAssDir/$STOassmbleDone");
#activate if two assemblies for single sample required, e.g. hybrid assemblies
my $ePreAssmbly = 0; $ePreAssmbly = 1 if (-s $finAssLoc && -e "$finalCommAssDir/$STOpreAssmblDone");
my $ePreAssmblPck = 0; $ePreAssmblPck = 1 if (-s $finAssLoc && -e "$metaGpreAssmblDir/moved.sto");
my $doPreAssmFlag = 0; my $postPreAssmblGo =0 ;
($doPreAssmFlag,$postPreAssmblGo,$ePreAssmblPck) = prepPreAssmbl($finalCommAssDir,$metaGpreAssmblDir,$finalMapDir, "$smplTmpDir/preAssmblData/",
$ContigStatsDir, $curSmpl, $cAssGrp, $efinAssLoc, $ePreAssmblPck);#moves files to new locations
my $eCovAsssembly = 0; $eCovAsssembly = 1 if (-e $coveragePerCtg);
my $eSuppCovAsssembly = 0; $eSuppCovAsssembly = 1 if (-e $suppCoveragePerCtg);
#will be created in contigstats step (not related to bowtie & sortbam)
my $emetaGassembly = 0; $emetaGassembly = 1 if (-e $metaGassembly && -e "$metagAssDir/$STOassmbleDone");
my $eFinMapCovGZ = 0; $eFinMapCovGZ = 1 if (-e $STOcram && -e "$finalMapDir/$SmplName-smd.bam.coverage.gz");#"$finalMapDir/$SmplName-smd.bam.coverage.gz";
#$MFopt{mapSupport2Assembly}
my $locMapSup2Assembly =0; $locMapSup2Assembly =1 if ($MFopt{mapSupport2Assembly} && $map{$curSmpl}{"SupportReads"} ne "");
my $eFinSupMapCovGZ = 0; $eFinSupMapCovGZ = 1 if ($locMapSup2Assembly && -e $STOsupCram && -e "$finalMapDir/$SmplName.sup-smd.bam.coverage.gz");
#die "$eFinSupMapCovGZ $finalMapDir\n";
my $dfinalCommAssDir = 0 ; $dfinalCommAssDir = 1 if (-d $finalCommAssDir);
my $eFinalMapDir = 0; $eFinalMapDir = 1 if (-s $STOmapFinal);
#upload2EBI
my $DoUploadRawReads = 0; $DoUploadRawReads = 1 if ($MFconfig{uploadRawRds} ne "");
#print "$emetaGassembly XX";
#die "$eFinMapCovGZ $STOcram && -e $finalMapDir/$SmplName-smd.bam.coverage.gz\n";
#first take care of moving finished assemblies..
if (!$efinAssLoc && $emetaGassembly){
print "moving finished assembly to final location\n";
#print "$metaGassembly\n";
systemW "mkdir -p $finalCommAssDir" unless ($dfinalCommAssDir);
systemW "rsync -r --remove-source-files $metagAssDir/* $finalCommAssDir/";
$efinAssLoc = 1; $emetaGassembly = 0;
}
my $locRedoSNPcalling =0;
my $locRedoAssMapping = $MFopt{redoAssMapping};
#check if current assembly group is the same as before!
my $locRewrite = 0; my $locRedoAssembl = 0;
if ($efinAssLoc && -e "$finalCommAssDir/smpls_used.txt"){
my $currAssmlCnt = 0;#`cat $finalCommAssDir/smpls_used.txt | grep -v '^\\\$' | wc -l`;
open I,"<$finalCommAssDir/smpls_used.txt " or die "Smple used: $!\n"; while (<I>){$currAssmlCnt++ unless m/^$/;} close I;
chomp $currAssmlCnt; $currAssmlCnt = int($currAssmlCnt);
if ($currAssmlCnt < $AsGrps{$cAssGrp}{CntAimAss}){
print "$cAssGrp assembl count has changed! (from $currAssmlCnt to $AsGrps{$cAssGrp}{CntAimAss})\n$finalCommAssDir\nRemoving assembly and all processed reads\n";
unless ($MFconfig{OKtoRWassGrps}) {print "Stopping MATAFILER, human intervention needed.. use the flag \"-OKtoRWassGrps 1\" to allow MATAFILER to delete files\n"; die;}
$locRewrite=1;
}
}
if ($eFinMapCovGZ && (!$ePreAssmblPck && !$ePreAssmbly && !$efinAssLoc && !$emetaGassembly) ){#impossible, so reason must be severe!
print "Mapping exists, but no assembly, removing mapping..\n$finalMapDir\n$finAssLoc\n$metaGassembly\n";
die unless ($MFconfig{OKtoRWassGrps});
$locRewrite = 0; $locRedoAssembl = 0;
}
if ($efinAssLoc && $finAssLoc ne "$finalCommAssDirSingle/scaffolds.fasta.filt" && -s "$finalCommAssDirSingle/scaffolds.fasta.filt"){
print "Something wrong.. assembly group assembly and single assembly present:\n$finAssLoc\n$finalCommAssDirSingle/scaffolds.fasta.filt\n";
#die;
$locRedoAssMapping=1;$locRedoSNPcalling=1;
system "rm -fr $finalCommAssDirSingle; mkdir -p $finalCommAssDirSingle;\n";
$eCovAsssembly=0;$eFinMapCovGZ=0;$eFinalMapDir=0;$eFinSupMapCovGZ=0;$eSuppCovAsssembly=0;$eSuppCovAsssembly=0;
}
if ($locStats{totRds}==0 && !defined($locStats{uniqAlign}) && -e $inputRawFile && $eFinMapCovGZ){ #do a deeper look
my $line = getFileStr("$inputRawFile",0); #open I,"<$inputRawFile"; my $line = <I>; close I; chomp($line);
#my @spl = split /,/,$line; my $inFileSize = -s $spl[0];
print "weird empty: $locStats{totRds} $line \nredoing..\n";
die;
$locRewrite = 1;$locRedoAssembl = 1;
}
if ( ($MFconfig{skipWrongPairedSmpls} || $MFconfig{OKtoRWassGrps}) && -e "$logDir/sdmReadCleaner.sh.etxt" && `tail -n 70 $logDir/sdmReadCleaner.sh.etxt | grep 'invalid paired read' ` ne ""){
print "$logDir/sdmReadCleaner.sh.etxt problems! Delete outdir\n";
if ($MFconfig{OKtoRWassGrps}){
$locRewrite=1 ;
}elsif ($MFconfig{skipWrongPairedSmpls}){
next ;
}
}
#-------------------------- DELETION SECTION -----------------------------------
#DELETION SECTION
#redo run - or parts thereof
if ($MFconfig{OKtoRWassGrps} && ($rewrite || $locRewrite)){
print "Deleting previous results.. rerun MATAFILER for sample\n";
system ("rm -r -f $assDir $finalCommAssDir");
system("rm -f -r $curOutDir $smplTmpDir $collectFinished ");
#next; #too deep, needs a complete new round over dir..
#$efinAssLoc = 0; $eFinMapCovGZ = 0; $emetaGassembly = 0;
$efinAssLoc =0 ;$emetaGassembly = 0; $dfinalCommAssDir =0;
$eCovAsssembly = 0; $eSuppCovAsssembly=0; $eFinSupMapCovGZ=0; $eFinMapCovGZ = 0;$eFinalMapDir = 0;$locRewrite = 0; $locRedoAssembl = 0;$eSuppCovAsssembly=0;
}
#automatically delete mapping, if assembly no longer exists..
#print "locRedoAssMapping : $locRedoAssMapping\n";
if ($MFopt{map2Assembly} ){
if ($eFinMapCovGZ && !$eFinalMapDir){$locRedoAssMapping = 1 ; print "R0 ";}
if (!$efinAssLoc && !$ePreAssmbly && !$emetaGassembly ){$locRedoAssMapping = 1 ;}#print "R1";}
if (!$MappingGo && $eFinalMapDir){$locRedoAssMapping = 1 ;print "R2 ";}
if (-e $STOcram && !-e "$finalMapDir/$SmplName-smd.bam.coverage.gz" && !-e "$finalMapDir/$SmplName-smd.bam.coverage"){$locRedoAssMapping = 1 ;print "R3 ";}
if ($eFinMapCovGZ && (exists($locStats{uniqAlign}) && $locStats{uniqAlign} > 20) && -s $CRAMmap <300){$locRedoAssMapping = 1 ;print "R4";}
#print "$CRAMmap :: $locRedoAssMapping\n";
print "redo assem mapping!" . " -s $CRAMmap \n" if ($locRedoAssMapping && -e $CRAMmap); #. (-s $CRAMmap)
#die "$STOcram && !-e $finalMapDir/$SmplName-smd.bam.coverage.gz";
}
#die "locRedoAssMapping : $locRedoAssMapping $finalMapDir : !$efinAssLoc && !$emetaGassembly\n" if ($locRedoAssMapping);
my $sizemap = -s $CRAMmap;
#print "size map: " . $sizemap . "\n";
#delete assembly
if ($MFopt{redoAssembly} || $locRedoAssembl){
print "Removing assembly ... \n" if ($emetaGassembly);
system "rm -fr $finalCommAssDir";
$efinAssLoc = 0;
$locRedoAssMapping=1;
}
#delete mapping to assembly
if ($locRedoAssMapping){
#die "locDel\n";
print "Deleting previous assembly mapping, size map: ". (-s $CRAMmap) . "\n$CRAMmap\n" if ($MappingGo && $eFinalMapDir);
#die "$finAssLoc && !-e $metaGassembly\n";
system "rm -fr $finalMapDir $mapOut $ContigStatsDir/Coverage.* $ContigStatsDir/Cov.sup.*";
$eFinMapCovGZ = 0; $emetaGassembly = 0;
$eCovAsssembly = 0; $eSuppCovAsssembly=0; $eFinSupMapCovGZ=0; $eFinalMapDir = 0;
#are there SNPs called? remove as well..
$locRedoSNPcalling=1;
}
#Case: primary assembly mapping was done, support reads were not yet mapped.. need to redo binning
#print "$locMapSup2Assembly && !$eFinSupMapCovGZ) && ($MFopt{map2Assembly} && $eFinMapCovGZ \n";
if ( ($locMapSup2Assembly && !$eFinSupMapCovGZ) && ($MFopt{map2Assembly} && $eFinMapCovGZ ) ){
print "redoing binning due to support mapping not included..\n";
system("rm -rf $binningDir/");
}
#debug case: binning was empty
if ($MFopt{DoMetaBat2} && ( $MFopt{BinnerRedoAll} || ($MFopt{BinnerRedoEmpty} && -e $BinningOut && !-s $BinningOut) ) ){
#die;
print "redoing binning due to empty bins (flag -redoEmptyBins 1) ..\n";
system "rm -rf $binningDir";
}
if ((!$eFinMapCovGZ && $eCovAsssembly) #redo only contigstats related to coverage..
|| ($eSuppCovAsssembly && !$eFinSupMapCovGZ) || $MFconfig{redoCS}){
print "redoing contig stats global..\n";
system("rm -rf $finalCommAssDir/ContigStats/ $ContigStatsDir $binningDir/");
$eCovAsssembly = 0; $eSuppCovAsssembly=0; #contigstats needs redoing..
}
system "rm -r $KrakenOD" if ($MFopt{RedoKraken} && -d $KrakenOD);
if ($MFopt{RedoRiboFind}){system "rm -rf $curOutDir/ribos";}
if ($MFopt{RedoRiboAssign}){system "rm -rf $curOutDir/ribos//ltsLCA";}
if ($MFopt{DoRibofind} && -e "$curOutDir/LOGandSUB/RiboLCA.sh.etxt"){
#my $LCAetxt = `cat $curOutDir/LOGandSUB/RiboLCA.sh.etxt`;
#if ($LCAetxt =~ m/ParseError thrown: Unexpected character .\@. found/){system "rm -rf $curOutDir/ribos";}
}
if ($locRedoSNPcalling){system "rm -fr $SNPdir";}
if ($MFopt{redoSNPcons}){ system "rm -rf $genePredSNP* $contigsSNP* $genePredAASNP* $smplTmpDir/SNP $logDir/SNP";
} elsif ($MFopt{redoSNPgene}){ system "rm -rf $genePredSNP* $genePredAASNP* ";
}
my $boolGenePredOK=0;
if ($MFopt{DoEukGenePred}){
$boolGenePredOK = 1 if (-s "$finalCommAssDir/genePred/proteins.bac.shrtHD.faa" || ($MFopt{pseudoAssembly} && -e "$finalCommAssDir/genePred/proteins.bac.shrtHD.faa"));
} else {
$boolGenePredOK = 1 if (-s "$finalCommAssDir/genePred/proteins.shrtHD.faa" || ($MFopt{pseudoAssembly} && -e "$finalCommAssDir/genePred/proteins.shrtHD.faa") );
}
#central flag
my $boolAssemblyOK=0;
$boolAssemblyOK=1 if ($boolGenePredOK && $efinAssLoc );#&& (!$MFopt{map2Assembly} || $eFinMapCovGZ ) );
#die "$boolGenePredOK && $efinAssLoc && (!$MFopt{map2Assembly} || $eFinMapCovGZ ) $locRedoAssMapping\n";
#&& (-s "$finalMapDir/$SmplName-smd.bam" || -s "$finalMapDir/$SmplName-smd.cram")
#die "$boolAssemblyOK\n$finalCommAssDir/genePred/proteins.shrtHD.faa\n$finalMapDir/$SmplName-smd.bam.coverage.gz\n";
if ( ( !$boolAssemblyOK && $MFconfig{unfiniRew}==1 ) ){
die "Deleting previous results..\n";
system("rm -f -r $curOutDir $smplTmpDir $collectFinished");
$efinAssLoc = 0; $eFinMapCovGZ = 0; $emetaGassembly = 0;
} elsif ($boolAssemblyOK && $eCovAsssembly) {
#check that assembly path fits..
getAssemblPath($curOutDir,$finalCommAssDir);
}
#--------------------- secondary map deletions & flags --------------------------
my $boolScndMappingOK = 1; my $iix =0;
my $boolScndCoverageOK = 1;
if ($MFopt{MapRewrite2nd}){
print "rewriting secondary map\n";
foreach my $bwt2outDTT (@bwt2outD){
my $expectedMapCovGZ = "$bwt2outDTT/$bwt2ndMapNmds[$iix]"."_".$SmplName."-0-smd.bam.coverage.gz"; #$bamcramMap : 2nd map only has .bam output
system "rm -f $expectedMapCovGZ*";
$eFinMapCovGZ = 0;
}
}
#die "eFinMapCovGZ $eFinMapCovGZ\n";
foreach my $bwt2outDTT (@bwt2outD){
my $expectedMapCovGZ = "$bwt2outDTT/$bwt2ndMapNmds[$iix]"."_".$SmplName."-0-smd.bam.coverage.gz";
my $expectedMapBam = "$bwt2outDTT/$bwt2ndMapNmds[$iix]"."_".$SmplName."-0-smd.bam";
$iix++;
#print $expectedMapCovGZ."\n";
if ( -e "$expectedMapCovGZ" && -e $expectedMapBam && $MappingGo ){
$boolScndMappingOK=1;
}else{
$boolScndMappingOK=0; $boolScndCoverageOK=0;
#be clean
system "rm -f $expectedMapBam*";
last;
}
if ($MFopt{mapModeCovDo} && (!-e $expectedMapCovGZ.".median.percontig" || !-e $expectedMapCovGZ.".percontig"|| !-e $expectedMapCovGZ.".pergene")){
$boolScndCoverageOK=0;
system "rm -f $expectedMapCovGZ.*";
}
}
if (@bwt2outD == 0 ){$boolScndMappingOK = 1 ; $boolScndCoverageOK=1;}#|| !$MappingGo);
#die "$boolScndMappingOK\n";
#print $boolScndMappingOK."\n$boolAssemblyOK\n";
#--------------------- other flags --------------------------
#contamination flag: redo/do contaminant removal to eg make sure human contamination is correctly logged
my $calcContamination = 0;
$calcContamination = 1 if ($locStats{contamination} eq "?\t" && $efinAssLoc && $MFopt{completeContaStats});
#print "Conta: $calcContamination \"$locStats{contamination}\"\n";
#Kraken flag
my $calcKraken =0;
$calcKraken = 1 if ($MFopt{DoKraken} && (!-d $KrakenOD || !-e "$KrakenOD/krakDone.sto"));
if (!$calcKraken && $MFopt{DoKraken}){
opendir D, $KrakenOD; my @krkF = grep {/krak\./} readdir(D); closedir D;
foreach my $kf (@krkF){
$kf =~ m/krak\.(.*)\.cnt\.tax/; my $thr = $1;# die $thr." $kf\n";
system "mkdir -p $dir_KrakFind/$thr" unless (-d "$dir_KrakFind/$thr"); #system "mkdir -p $dir_RibFind/SSU/" unless (-d "$dir_RibFind/SSU/"); system "mkdir -p $dir_RibFind/LSU/" unless (-d "$dir_RibFind/LSU/");
system "cp $KrakenOD/$kf $dir_KrakFind/$thr/$SmplName.$thr.krak.txt";
}
} else {$progStats{KrakTaxFailCnts}++;}
#system "rm -f $curOutDir/ribos//ltsLCA/LSU_ass.sto $curOutDir/ribos//ltsLCA/Assigned.sto"; fix for new LSU assignments
my $calcGenoSize=0; $calcGenoSize=1 if ($MFopt{DoGenoSizeEst} && !-e "$curOutDir/MicroCens/MC.0.result");
my $calcRibofind = 0; my $calcRiboAssign = 0;
$calcRibofind = 1 if ($MFopt{DoRibofind} && (!-e "$curOutDir/ribos//SSU_pull.sto"|| !-e "$curOutDir/ribos//LSU_pull.sto" || ($MFopt{doRiboAssembl} && !-e "$curOutDir/ribos/Ass/allAss.sto" ))); #!-e "$curOutDir/ribos//ITS_pull.sto"||
$calcRiboAssign = 1 if ($MFopt{DoRibofind} && ( !-e "$curOutDir/ribos//ltsLCA/Assigned.sto" || !-e "$curOutDir/ribos//ltsLCA/SSU_ass.sto") ); #!-e "$curOutDir/ribos//ltsLCA/ITS_ass.sto"|| #ITS no longer required.. unreliable imo
#die "$calcRibofind\n\n";
#die "$calcRibofind $calcRiboAssign\n";
RiboMeta($calcRibofind,$calcRiboAssign,$curOutDir,$SmplName);
my ($calcDiamond,$calcDiaParse) = IsDiaRunFinished($curOutDir);
#die "XX $calcDiamond $calcDiaParse\n";
my $calcMetaPhlan=0;
#die $dir_MP2."$SmplName.MP2.sto";
if ($MFopt{DoMetaPhlan}){
if (!-e $dir_MP2."$SmplName.MP2.sto"){
$calcMetaPhlan=1 ;
$progStats{metaPhl2FailCnts}++;
} else { $progStats{metaPhl2ComplCnts}++;}
}
my $calcMOTU2=0;
if ($MFopt{DoMOTU2}){
if (!-e $dir_mOTU2."$SmplName.Motu2.sto"){
$calcMOTU2=1;
$progStats{mOTU2FailCnts}++;
} else { $progStats{mOTU2ComplCnts}++;}
}
my $calcTaxaTar = 0;
if ($MFopt{DoTaxaTarget}){
if (!-e $dir_TaxTar."$SmplName.TaxTar.sto"){
$calcTaxaTar=1 ;
$progStats{taxTarFailCnts}++;
} else { $progStats{taxTarComplCnts}++;}
}
#TODO
my $allMapDone =0;#used for SNP calling and Binning - but binning requires info if all maps are finished from all samples
$allMapDone = 1 if (-e "$finalMapDir/$SmplName-smd.$bamcramMap" && $eCovAsssembly && !$ePreAssmbly && ($eSuppCovAsssembly || !$locMapSup2Assembly) && $AsGrps{$cAssGrp}{MapDeps} !~ m/[^;]/ );
if ( ($boolAssemblyOK || ($doPreAssmFlag && $ePreAssmbly && !$ePreAssmblPck)) && !$locRedoAssMapping ){#causes a lot of overhead but mainly to avoid unpacking reads again..
print "present: $curOutDir \n"; $presentAssemblies ++;#= $AsGrps{$cAssGrp}{CntAimAss};
#base is present, but is the additions?
if ($MFopt{map2Assembly} && $MFopt{doBam2Cram} && #.cram.sto to check that everything went well
$AssemblyGo && $MappingGo && $eFinMapCovGZ && $allMapDone ){
#(-e "$finalCommAssDir/scaffolds.fasta.filt.$MFcontstants{mini2IdxFileSuffix}" || -e "$finalCommAssDir/scaffolds.fasta.filt${bwt2IdxFileSuffix}.1.bt2") &&
#delete bwt2 index to save some space..
#need to ensure that all mapping in mapping group are fine..
system "rm -f $finalCommAssDir/scaffolds.fasta.filt$MFcontstants{bwt2IdxFileSuffix}* $finalCommAssDir/scaffolds.fasta.filt.fai $finalCommAssDir/scaffolds.fasta.filt.$MFcontstants{mini2IdxFileSuffix} $finalCommAssDir/scaffolds.fasta.filt.$MFcontstants{kmaIdxFileSuffix}";
system "rm -f $finalMapDir/${SmplName}*smd.bam.bai $finalMapDir/${SmplName}*smd.bam.coverage.c* $finalMapDir/${SmplName}*smd.bam.coverage.gen* $finalMapDir/${SmplName}*smd.bam.coverage.m* $finalMapDir/${SmplName}*smd.bam.coverage.p*";
}
my $subprts = $MFconfig{defaultContigSubs}; my $CSthre = 1;
if ($AssemblyGo ){
$subprts = $MFconfig{defaultContigSubs}."gFG";$CSthre = 6; $subprts .= "m" if ($MFopt{DoBinning});
$subprts .= "4" if ($MFopt{kmerPerGene} ); $subprts .= "k" if ($MFopt{kmerAssembly} );
} #k
#call contigStats only from 1 (actually two) places: end of for loop
#my ($tmpCSj,$tmpCSc,$tmpCSd) = runContigStats($curOutDir ,"",$finalCommAssDir,$subprts,1,$samplReadLength,$nodeSpTmpD,$AssemblyGo,$CSthre, $curSmpl);
#add2SampleDeps(\@sampleDeps, [$tmpCSj]);
#$contigStatsUsed = $tmpCSd;
#print "SmplDps: @sampleDeps\n";
#die "$boolScndMappingOK && !$MFopt{DoCalcD2s} && !$calcRibofind && !$calcDiamond && !$calcMetaPhlan && !$calcKraken\n";
}
my $calcMetaBat2 = 0;
if ($MFopt{DoMetaBat2} && $boolAssemblyOK && $AssemblyGo && $AsGrps{$cAssGrp}{MapDeps} !~ m/[^;]/ && (!-e "$BinningOut.cm" && !-s "$BinningOut.cm2")) {
$calcMetaBat2=$MFopt{DoMetaBat2};
}
#die "Binner: $calcMetaBat2 :: $MFopt{DoMetaBat2} && $boolAssemblyOK && $AssemblyGo (!-e $BinningOut.cm && !-s $BinningOut.cm2)\n$BinningOut\n" ;
#not complete yet? Then delete..
if ($MFconfig{redoFails} && ($calcRibofind||$calcDiamond || $calcDiaParse ||$calcMOTU2 || $calcMetaPhlan || $calcTaxaTar)){
die "now recalc $curSmpl\n";
system ("rm -r -f $assDir $finalCommAssDir");
system("rm -f -r $curOutDir $smplTmpDir $collectFinished ");
}
system("mkdir -p $logDir") unless (-d $logDir);
$QSBoptHR->{LocationCheckStrg} = checkDrives(\@checkLocs);
#die "$metaGassembly\n$finAssLoc\n$nodeSpTmpD\n";
# #----------------------- FLAGS ------------------------
# #and some more flags for subprocesses
my $nonPareilFlag = !-s "$nonParDir/$SmplName.npo" && $MFopt{DoNonPareil} ;
my $scaffoldFlag = 0; if ( !-e $STOfinScaff && $map{$curSmpl}{"SupportReads"} =~ m/mate/i ){$scaffoldFlag = 1 ;}# print "SUPP:: $map{$curSmpl}{SupportReads}\n";}
my $assemblyFlag = 0; $assemblyFlag = 1 if ( $MFopt{DoAssembly} && !$boolAssemblyOK && !$efinAssLoc && !$emetaGassembly);
#die "$assemblyFlag = 1 if ( $MFopt{DoAssembly} && !$boolAssemblyOK && !$efinAssLoc && !-e $metaGassembly\n $doPreAssmFlag\n";
my $calcReadMerge = 0;
$calcReadMerge = 1 if ($MFopt{doReadMerge} && ($MFopt{calcOrthoPlacement} || $calcDiamond || $calcGenoSize));
my $mapAssFlag = 0; $mapAssFlag = 1 if ($MFopt{map2Assembly} && !$eFinMapCovGZ );
my $calcCoverage = 0; $calcCoverage =1 if (!$eCovAsssembly && $MFopt{map2Assembly});
#only for support reads (from hybrid assemblies)
my $mapSuppAssFlag =0;$mapSuppAssFlag = 1 if ($locMapSup2Assembly && !$eFinSupMapCovGZ && $efinAssLoc );#hasSuppRds(\%AsGrps,$cAssGrp,$curSmpl ) );
my $calcSuppCoverage = 0; $calcSuppCoverage =1 if ($MFopt{mapSupport2Assembly} && !$eSuppCovAsssembly && $map{$curSmpl}{"SupportReads"} ne "");
#die "$mapSuppAssFlag = 1 if ($locMapSup2Assembly && !$eFinSupMapCovGZ && $efinAssLoc \n";
my $assemblyBuildIndexFlag=0;
$assemblyBuildIndexFlag=1 if ($MFopt{DoAssembly} && !$assemblyFlag && $MFopt{map2Assembly} && ($mapAssFlag || $mapSuppAssFlag )
# && $AssemblyGo -> do already in first round, store dependency
&& ! mapperDBbuilt($finAssLoc,$MFopt{MapperProg}) );
#die "$assemblyBuildIndexFlag $MFopt{DoAssembly} && !$assemblyFlag && $MFopt{map2Assembly} && ($mapAssFlag || $mapSuppAssFlag ) \n". mapperDBbuilt($finAssLoc,$MFopt{MapperProg}) ."\n";
#print "build $assemblyBuildIndexFlag $MFopt{DoAssembly} && !$assemblyFlag && $MFopt{map2Assembly} && $mapAssFlag && $MFopt{MapperProg}\n";
#requires only bam/cram && assembly
my $calcConsSNP=0; $calcConsSNP =1 if ($MFopt{DoConsSNP} && (!-e $genePredSNP || -s $genePredSNP < 100 || ($MFopt{saveVCF} && ! fileGZe($vcfSNP) )));
my $calcSuppConsSNP=0; $calcSuppConsSNP =1 if ($MFopt{DoSuppConsSNP} && (!-e $STOsnpSuppCons ));
#die "genePredSNP $genePredSNP\n";
my $calc2ndMapSNP = 0; $calc2ndMapSNP = 1 if ($MFopt{Do2ndMapSNP});
my $pseudAssFlag = 0; $pseudAssFlag = 1 if ($MFopt{pseudoAssembly} && $map{$curSmpl}{ExcludeAssem} eq "0" && (!-e $pseudoAssFileFinal.".sto" || !$boolGenePredOK));
my $dowstreamAnalysisFlag = 0;
#$unpackZip simulates dowstreamAnalysisFlag, just to get sdm running..
$dowstreamAnalysisFlag=1 if ( $MFconfig{unpackZip} || $calcContamination || $MFopt{calcOrthoPlacement} || $scaffTarExternal ne "" || $assemblyFlag
|| $pseudAssFlag || $scaffoldFlag || $nonPareilFlag || $calcGenoSize || $calcDiamond || $calcDiaParse
|| $MFopt{DoCalcD2s} || $calcKraken || $calcRibofind || $calcRiboAssign || $calcMOTU2 || $calcMetaPhlan || $calcTaxaTar );
my $requireRawReadsFlag = 0;#only list modules that really need raw reads
$requireRawReadsFlag = 1 if ( !$boolScndMappingOK || $calcContamination);
my $seqCleanFlag = 0; $seqCleanFlag =1 if ($dowstreamAnalysisFlag && !-e "$smplTmpDir/seqClean/filterDone.stone" );
my $porechopFlag = 0;
$porechopFlag = 1 if ($MFopt{usePorechop} && $dowstreamAnalysisFlag && !-e "$smplTmpDir/rawRds/poreChopped.stone");
#die "$assemblyFlag\t$seqCleanFlag\t$boolScndMappingOK\n";
my $calcUnzip=0;
$calcUnzip=1 if ($calcDiamond || $porechopFlag || $seqCleanFlag || $mapAssFlag || $mapSuppAssFlag || (!$MFopt{useUnmapped} && !$boolScndMappingOK));
#print "chk1 $mapSuppAssFlag $calcSuppCoverage $eSuppCovAsssembly\n" ;
# #----------------------- END FLAGS ------------------------
#some more flow control..
if (
!$DoUploadRawReads && $boolScndMappingOK && !$MFopt{DoCalcD2s} &&
!$calcConsSNP && !$calcSuppConsSNP && !$calcMetaBat2 && !$calc2ndMapSNP && $boolAssemblyOK && $boolScndCoverageOK
&& !$calcCoverage && !$calcSuppCoverage && !$dowstreamAnalysisFlag
#&& !$calcRibofind && !$calcRiboAssign && !$MFopt{calcOrthoPlacement} && !$calcGenoSize && !$calcDiamond && !$calcDiaParse &&
#!$calcMetaPhlan && !$calcTaxaTar && !$calcMOTU2 && !$calcKraken && $scaffTarExternal eq ""
){
#free some scratch
system "rm -rf $smplTmpDir &" if ($MFconfig{rmScratchTmp} );
#system "rm -f $smplLockF" if (-e $smplLockF);
print "next due to sample finished";
MFnext($smplLockF,\@sampleDeps,$JNUM ,$QSBoptHR); next;
}
#report for debugging:
#print "!$calcConsSNP && !$calcMetaBat2 && !$calc2ndMapSNP && $boolAssemblyOK && $boolScndCoverageOK \n && $boolScndMappingOK && !$MFopt{DoCalcD2s} && !$DoUploadRawReads \n && !$calcRibofind && !$calcRiboAssign && !$MFopt{calcOrthoPlacement} && !$calcGenoSize && !$calcDiamond && !$calcDiaParse && \n !$calcMetaPhlan && !$calcTaxaTar && !$calcMOTU2 && !$calcKraken && $scaffTarExternal eq \n $allMapDone\n $eFinMapCovGZ && $eCovAsssembly && $calcCoverage\n";
if (!$assemblyFlag && $AssemblyGo && !$efinAssLoc && $emetaGassembly){
die "assem copy\n"; #should actually never be here..
push(@{$AsGrps{$cAssGrp}{AssCopies}}, $assDir."/metag/*",$finalCommAssDir);
}
#die "$pseudAssFlag\n$boolGenePredOK\n$pseudoAssFileFinal\n";
if ($scaffTarExternal ne "" && $map{$curSmpl}{"SupportReads"} !~ /mate/i && $scaffTarExtLibTar ne $curSmpl ){print"scNxt\n";next;}
#has this sample extra reads (e.g. long reads?)
#die "$assemblyFlag || !$boolScndMappingOK || $nonPareilFlag || $calcDiamond || $MFopt{DoCalcD2s} || $calcKraken\n";
#die "$curDir\n";
#-----------------------------------------------------------------------------------------
# actual job submissions starts from here
#-----------------------------------------------------------------------------------------
#unzipping & sorting of files into scratch dir..
#also does either trimomatic or porechop..
#die "calcUnzip $calcUnzip\n" ;#if ($calcUnzip);
# my ($jdep,$cfp1ar,$cfp2ar,$cfpsar,$WT,$rawFiles, $mmpuNum, $libInfoRef, $inputRawSize) =
#my %seqSet = (pa1 => \@pa1, pa2 => \@pa2, pas => \@pas, paX1 => \@paX1, paX2 => \@paX2, paXs => \@paXs, libInfo => \@libInfo, libInfoX => \@libInfoX,
# totalInputSizeMB => $totalInputSizeMB,rawReads => $rawReads,mmpu => $mmpu, WT => $WT);
#unzip and change ifastap & cfp1/cfp2
my $curUnzipDep = "";
if ($MFconfig{maxUnzpJobs} >0 && @unzipjobs > $MFconfig{maxUnzpJobs}){#only run X jobs in parallel, lest the cluster IO breaks down..
$curUnzipDep = $unzipjobs[-($MFconfig{maxUnzpJobs})];#join(";",@last_n);
$waitTime=0;
}
my ($jdep,$hrefSeqSet) =
seedUnzip2tmp($curDir,$curSmpl,$curUnzipDep,$nodeSpTmpD,
$smplTmpDir,$waitTime,$MFconfig{importMocat},$AsGrps{$cMapGrp}{CntMap},$calcUnzip,$finalMapDir,
$porechopFlag,$inputRawFile);
my %seqSet = %{$hrefSeqSet};
push (@unzipjobs,$jdep) unless ($jdep eq "");
$seqSet{samplReadLength} = $samplReadLength; $seqSet{samplReadLengthX} = $samplReadLengthX;
#die "@{$seqSet{pa1}}\n@{$seqSet{pas}}\n";
#$seqSet{"curSDMopt"} = $curSDMopt; $seqSet{"curSDMoptSingl"} = $curSDMoptSingl;
if ($jdep eq "EMPTY_DO_NEXT"){push(@EmptySample,$curSmpl);next;}
push(@inputRawFQs,$seqSet{"rawReads"});
if($scaffTarExtLibTar eq $curSmpl){
@scaffTarExternalOLib1 = @{$seqSet{"pa1"}}; @scaffTarExternalOLib2 = @{$seqSet{"pa2"}};
next unless ($map{$curSmpl}{"SupportReads"} =~ /mate/i );
#print "@scaffTarExternalOLib1\n";
#die;
}
#$mmpuOutTab .= $dir2rd."\t".$seqSet{"mmpu"}."\n";
$waitTime = $seqSet{"WT"};
$AsGrps{$cMapGrp}{SeqUnZDeps} .= $jdep.";";$AsGrps{$cAssGrp}{UnzpDeps} .= $jdep.";";$AsGrps{$cAssGrp}{readDeps} = $AsGrps{$cAssGrp}{UnzpDeps};
my $UZdep = $jdep;
#my @cfp1 = @{$seqSet{"pa1"}}; my @cfp2 = @{$seqSet{"pa2"}}; #stores the read files used plus which library they come from
#if (@cfp1!=@cfp2){print "Fastap path not of equal length:\n@@cfp1\n@@cfp2\n"; die();}
#push(@{$AsGrps{$cMapGrp}{RawSeq1}},@{$seqSet{"pa1"}}); push(@{$AsGrps{$cMapGrp}{RawSeq2}},@{$seqSet{"pa2"}});
#push(@{$AsGrps{$cMapGrp}{RawSeqS}},@{$seqSet{"pas"}});push(@{$AsGrps{$cMapGrp}{Libs}},@{$seqSet{"libInfo"}});
#empty links for assembler and nonpareil
#my($arp1,$arp2,$singAr,$matAr,$sdmjN) = ([],[],[],[],"");
my $sdmjN = ""; #job on main reads
my $cleanSeqSetHR = iniCleanSeqSetHR(\%seqSet);
#my($arp1,$arp2,$singAr,$matAr,$sdmjN) = ($seqSet{"pa1"},$seqSet{"pa2"},$seqSet{"pas"},[],$jdep);
#empty links and objects for merging of reads
my($mergJbN) = ("");
# punsh the whole thing through sdm..
if ( (!$boolAssemblyOK||$calcContamination) && $MFopt{useSDM}!=0 ){#&& !$is3rdGen) {
#$ifastp
#($cleanSeqSet{arp1},$cleanSeqSet{arp2},$cleanSeqSet{singAr},$cleanSeqSet{matAr},$sdmjN) = sdmClean($curOutDir,\%seqSet,
($cleanSeqSetHR,$sdmjN) = sdmClean($curOutDir,\%seqSet, $cleanSeqSetHR,
$smplTmpDir."mateCln/",$smplTmpDir."seqClean/",$jdep,$dowstreamAnalysisFlag,0) ;
# check for support reads as well..