1 #include "IncludeDefine.h"
2 #include "Parameters.h"
3 #include "ErrorWarning.h"
4 #include "SequenceFuns.h"
5 #include "OutSJ.h"
6 #include "sysRemoveDir.h"
7 #include "stringSubstituteAll.h"
8 #include SAMTOOLS_BGZF_H
9 #include "GlobalVariables.h"
10 #include "signalFromBAM.h"
11 #include "bamRemoveDuplicates.h"
12 #include "streamFuns.h"
13 
14 //for mkfifo
15 #include <sys/stat.h>
16 
17 #define PAR_NAME_PRINT_WIDTH 30
18 
Parameters()19 Parameters::Parameters() {//initalize parameters info
20 
21     inOut = new InOutStreams;
22 
23     //versions
24     parArray.push_back(new ParameterInfoScalar <string> (-1, -1, "versionGenome", &versionGenome));
25 
26     //parameters
27     parArray.push_back(new ParameterInfoVector <string> (-1, 2, "parametersFiles", &parametersFiles));
28 
29     //system
30     parArray.push_back(new ParameterInfoScalar <string> (-1, -1, "sysShell", &sysShell));
31 
32     //run
33     parArray.push_back(new ParameterInfoVector <string> (-1, -1, "runMode", &runModeIn));
34     parArray.push_back(new ParameterInfoScalar <int> (-1, -1, "runThreadN", &runThreadN));
35     parArray.push_back(new ParameterInfoScalar <string> (-1, -1, "runDirPerm", &runDirPermIn));
36     parArray.push_back(new ParameterInfoScalar <int> (-1, -1, "runRNGseed", &runRNGseed));
37 
38     //genome
39     parArray.push_back(new ParameterInfoScalar <string> (-1, -1, "genomeType", &pGe.gTypeString));
40     parArray.push_back(new ParameterInfoScalar <string> (-1, -1, "genomeDir", &pGe.gDir));
41     parArray.push_back(new ParameterInfoScalar <string> (-1, -1, "genomeLoad", &pGe.gLoad));
42     parArray.push_back(new ParameterInfoVector <string> (-1, -1, "genomeFastaFiles", &pGe.gFastaFiles));
43     parArray.push_back(new ParameterInfoVector <string> (-1, -1, "genomeChainFiles", &pGe.gChainFiles));
44     parArray.push_back(new ParameterInfoScalar <uint> (-1, -1, "genomeSAindexNbases", &pGe.gSAindexNbases));
45     parArray.push_back(new ParameterInfoScalar <uint> (-1, -1, "genomeChrBinNbits", &pGe.gChrBinNbits));
46     parArray.push_back(new ParameterInfoScalar <uint> (-1, -1, "genomeSAsparseD", &pGe.gSAsparseD));
47     parArray.push_back(new ParameterInfoScalar <uint> (-1, -1, "genomeSuffixLengthMax", &pGe.gSuffixLengthMax));
48     parArray.push_back(new ParameterInfoVector <uint> (-1, -1, "genomeFileSizes", &pGe.gFileSizes));
49     //parArray.push_back(new ParameterInfoScalar <string> (-1, -1, "genomeConsensusFile", &pGe.gConsensusFile)); DEPRECATED
50     parArray.push_back(new ParameterInfoScalar <string> (-1, -1, "genomeTransformType", &pGe.transform.typeString));
51     parArray.push_back(new ParameterInfoScalar <string> (-1, -1, "genomeTransformVCF", &pGe.transform.vcfFile));
52     parArray.push_back(new ParameterInfoVector <string> (-1, -1, "genomeTransformOutput", &pGe.transform.output));
53 
54     //read
55     parArray.push_back(new ParameterInfoVector <string> (-1, -1, "readFilesType", &readFilesType));
56     parArray.push_back(new ParameterInfoVector <string> (-1, -1, "readFilesIn", &readFilesIn));
57     parArray.push_back(new ParameterInfoScalar <string> (-1, -1, "readFilesPrefix", &readFilesPrefix));
58     parArray.push_back(new ParameterInfoVector <string> (-1, -1, "readFilesCommand", &readFilesCommand));
59 
60     parArray.push_back(new ParameterInfoScalar <string> (-1, -1, "readMatesLengthsIn", &readMatesLengthsIn));
61     parArray.push_back(new ParameterInfoScalar <uint> (-1, -1, "readMapNumber", &readMapNumber));
62     parArray.push_back(new ParameterInfoVector <string> (-1, -1, "readNameSeparator", &readNameSeparator));
63     parArray.push_back(new ParameterInfoScalar <uint32> (-1, -1, "readQualityScoreBase", &readQualityScoreBase));
64     parArray.push_back(new ParameterInfoVector <string> (-1, -1, "readFilesManifest", &readFilesManifest));
65     parArray.push_back(new ParameterInfoVector <string> (-1, -1, "readFilesSAMattrKeep", &readFiles.samAttrKeepIn));
66 
67     //parArray.push_back(new ParameterInfoScalar <string> (-1, -1, "readStrand", &pReads.strandString));
68 
69 
70     //input from BAM
71     parArray.push_back(new ParameterInfoScalar <string> (-1, -1, "inputBAMfile", &inputBAMfile));
72 
73     //BAM processing
74     parArray.push_back(new ParameterInfoScalar <string> (-1, -1, "bamRemoveDuplicatesType", &removeDuplicates.mode));
75     parArray.push_back(new ParameterInfoScalar <uint>   (-1, -1, "bamRemoveDuplicatesMate2basesN", &removeDuplicates.mate2basesN));
76 
77     //limits
78     parArray.push_back(new ParameterInfoScalar <uint>   (-1, -1, "limitGenomeGenerateRAM", &limitGenomeGenerateRAM));
79     parArray.push_back(new ParameterInfoVector <uint64>   (-1, -1, "limitIObufferSize", &limitIObufferSize));
80     parArray.push_back(new ParameterInfoScalar <uint>   (-1, -1, "limitOutSAMoneReadBytes", &limitOutSAMoneReadBytes));
81     parArray.push_back(new ParameterInfoScalar <uint>   (-1, -1, "limitOutSJcollapsed", &limitOutSJcollapsed));
82     parArray.push_back(new ParameterInfoScalar <uint>   (-1, -1, "limitOutSJoneRead", &limitOutSJoneRead));
83     parArray.push_back(new ParameterInfoScalar <uint>   (-1, -1, "limitBAMsortRAM", &limitBAMsortRAM));
84     parArray.push_back(new ParameterInfoScalar <uint>   (-1, -1, "limitSjdbInsertNsj", &limitSjdbInsertNsj));
85     parArray.push_back(new ParameterInfoScalar <uint>   (-1, -1, "limitNreadsSoft", &limitNreadsSoft));
86 
87     //output
88     parArray.push_back(new ParameterInfoScalar <string>     (-1, 2, "outFileNamePrefix", &outFileNamePrefix));
89     parArray.push_back(new ParameterInfoScalar <string>     (-1, 2, "outTmpDir", &outTmpDir));
90     parArray.push_back(new ParameterInfoScalar <string>     (-1, 2, "outTmpKeep", &outTmpKeep));
91     parArray.push_back(new ParameterInfoScalar <string>     (-1, 2, "outStd", &outStd));
92     parArray.push_back(new ParameterInfoScalar <string>     (-1, -1, "outReadsUnmapped", &outReadsUnmapped));
93     parArray.push_back(new ParameterInfoScalar <int>        (-1, -1, "outQSconversionAdd", &outQSconversionAdd));
94     parArray.push_back(new ParameterInfoScalar <string>     (-1, -1, "outMultimapperOrder", &outMultimapperOrder.mode));
95 
96     //outSAM
97     parArray.push_back(new ParameterInfoVector <string>     (-1, -1, "outSAMtype", &outSAMtype));
98     parArray.push_back(new ParameterInfoScalar <string>     (-1, -1, "outSAMmode", &outSAMmode));
99     parArray.push_back(new ParameterInfoScalar <string>     (-1, -1, "outSAMstrandField", &outSAMstrandField.in));
100     parArray.push_back(new ParameterInfoVector <string>     (-1, -1, "outSAMattributes", &outSAMattributes));
101     parArray.push_back(new ParameterInfoVector <string>     (-1, -1, "outSAMunmapped", &outSAMunmapped.mode));
102     parArray.push_back(new ParameterInfoScalar <string>     (-1, -1, "outSAMorder", &outSAMorder));
103     parArray.push_back(new ParameterInfoScalar <string>     (-1, -1, "outSAMprimaryFlag", &outSAMprimaryFlag));
104     parArray.push_back(new ParameterInfoScalar <string>     (-1, -1, "outSAMreadID", &outSAMreadID));
105     parArray.push_back(new ParameterInfoScalar <int>        (-1, -1, "outSAMmapqUnique", &outSAMmapqUnique));
106     parArray.push_back(new ParameterInfoScalar <uint16>        (-1, -1, "outSAMflagOR", &outSAMflagOR));
107     parArray.push_back(new ParameterInfoScalar <uint16>        (-1, -1, "outSAMflagAND", &outSAMflagAND));
108     parArray.push_back(new ParameterInfoVector <string>     (-1, -1, "outSAMattrRGline", &outSAMattrRGline));
109     parArray.push_back(new ParameterInfoVector <string>     (-1, -1, "outSAMheaderHD", &outSAMheaderHD));
110     parArray.push_back(new ParameterInfoVector <string>     (-1, -1, "outSAMheaderPG", &outSAMheaderPG));
111     parArray.push_back(new ParameterInfoScalar <string>     (-1, -1, "outSAMheaderCommentFile", &outSAMheaderCommentFile));
112     parArray.push_back(new ParameterInfoScalar <int>        (-1, -1, "outBAMcompression", &outBAMcompression));
113     parArray.push_back(new ParameterInfoScalar <int>        (-1, -1, "outBAMsortingThreadN", &outBAMsortingThreadN));
114     parArray.push_back(new ParameterInfoScalar <uint32>        (-1, -1, "outBAMsortingBinsN", &outBAMsortingBinsN));
115     parArray.push_back(new ParameterInfoVector <string>     (-1, -1, "outSAMfilter", &outSAMfilter.mode));
116     parArray.push_back(new ParameterInfoScalar <uint>     (-1, -1, "outSAMmultNmax", &outSAMmultNmax));
117     parArray.push_back(new ParameterInfoScalar <uint>     (-1, -1, "outSAMattrIHstart", &outSAMattrIHstart));
118     parArray.push_back(new ParameterInfoScalar <int>        (-1, -1, "outSAMtlen", &outSAMtlen));
119 
120     //outSJ
121     parArray.push_back(new ParameterInfoVector <string>     (-1, -1, "outSJtype", &outSJ.type));
122 
123     //output SJ filtering
124     parArray.push_back(new ParameterInfoScalar <string>  (-1, -1, "outSJfilterReads", &outSJfilterReads));
125     parArray.push_back(new ParameterInfoVector <int32>   (-1, -1, "outSJfilterCountUniqueMin", &outSJfilterCountUniqueMin));
126     parArray.push_back(new ParameterInfoVector <int32>   (-1, -1, "outSJfilterCountTotalMin", &outSJfilterCountTotalMin));
127     parArray.push_back(new ParameterInfoVector <int32>   (-1, -1, "outSJfilterOverhangMin", &outSJfilterOverhangMin));
128     parArray.push_back(new ParameterInfoVector <int32>   (-1, -1, "outSJfilterDistToOtherSJmin", &outSJfilterDistToOtherSJmin));
129     parArray.push_back(new ParameterInfoVector <int32>   (-1, -1, "outSJfilterIntronMaxVsReadN", &outSJfilterIntronMaxVsReadN));
130 
131     //output wiggle
132     parArray.push_back(new ParameterInfoVector <string>   (-1, -1, "outWigType", &outWigType));
133     parArray.push_back(new ParameterInfoVector <string>   (-1, -1, "outWigStrand", &outWigStrand));
134     parArray.push_back(new ParameterInfoScalar <string>   (-1, -1, "outWigReferencesPrefix", &outWigReferencesPrefix));
135     parArray.push_back(new ParameterInfoVector <string>   (-1, -1, "outWigNorm", &outWigNorm));
136 
137     //output filtering
138     parArray.push_back(new ParameterInfoScalar <string>   (-1, -1, "outFilterType", &outFilterType) );
139 
140     parArray.push_back(new ParameterInfoScalar <uint>     (-1, -1, "outFilterMultimapNmax", &outFilterMultimapNmax));
141     parArray.push_back(new ParameterInfoScalar <intScore> (-1, -1, "outFilterMultimapScoreRange", &outFilterMultimapScoreRange));
142 
143     parArray.push_back(new ParameterInfoScalar <intScore> (-1, -1, "outFilterScoreMin", &outFilterScoreMin));
144     parArray.push_back(new ParameterInfoScalar <double>   (-1, -1, "outFilterScoreMinOverLread", &outFilterScoreMinOverLread));
145 
146     parArray.push_back(new ParameterInfoScalar <uint>     (-1, -1, "outFilterMatchNmin", &outFilterMatchNmin));
147     parArray.push_back(new ParameterInfoScalar <double>   (-1, -1, "outFilterMatchNminOverLread", &outFilterMatchNminOverLread));
148 
149     parArray.push_back(new ParameterInfoScalar <uint>     (-1, -1, "outFilterMismatchNmax", &outFilterMismatchNmax));
150     parArray.push_back(new ParameterInfoScalar <double>   (-1, -1, "outFilterMismatchNoverLmax", &outFilterMismatchNoverLmax));
151     parArray.push_back(new ParameterInfoScalar <double>   (-1, -1, "outFilterMismatchNoverReadLmax", &outFilterMismatchNoverReadLmax));
152     parArray.push_back(new ParameterInfoScalar <string>   (-1, -1, "outFilterIntronMotifs", &outFilterIntronMotifs));
153     parArray.push_back(new ParameterInfoScalar <string>   (-1, -1, "outFilterIntronStrands", &outFilterIntronStrands));
154 
155     //clipping
156     parArray.push_back(new ParameterInfoVector <string> (-1, -1, "clipAdapterType", &pClip.adapterType));
157     parArray.push_back(new ParameterInfoVector <uint32>   (-1, -1, "clip5pNbases", &pClip.in[0].N));
158     parArray.push_back(new ParameterInfoVector <uint32>   (-1, -1, "clip3pNbases", &pClip.in[1].N));
159     parArray.push_back(new ParameterInfoVector <uint32>   (-1, -1, "clip5pAfterAdapterNbases", &pClip.in[0].NafterAd));
160     parArray.push_back(new ParameterInfoVector <uint32>   (-1, -1, "clip3pAfterAdapterNbases", &pClip.in[1].NafterAd));
161     parArray.push_back(new ParameterInfoVector <string> (-1, -1, "clip5pAdapterSeq", &pClip.in[0].adSeq));
162     parArray.push_back(new ParameterInfoVector <string> (-1, -1, "clip3pAdapterSeq", &pClip.in[1].adSeq));
163     parArray.push_back(new ParameterInfoVector <double> (-1, -1, "clip5pAdapterMMp", &pClip.in[0].adMMp));
164     parArray.push_back(new ParameterInfoVector <double> (-1, -1, "clip3pAdapterMMp", &pClip.in[1].adMMp));
165 
166     //binning, anchors, windows
167     parArray.push_back(new ParameterInfoScalar <uint>   (-1, -1, "winBinNbits", &winBinNbits));
168     parArray.push_back(new ParameterInfoScalar <uint>   (-1, -1, "winAnchorDistNbins", &winAnchorDistNbins));
169     parArray.push_back(new ParameterInfoScalar <uint>   (-1, -1, "winFlankNbins", &winFlankNbins));
170     parArray.push_back(new ParameterInfoScalar <uint>   (-1, -1, "winAnchorMultimapNmax", &winAnchorMultimapNmax));
171     parArray.push_back(new ParameterInfoScalar <double>   (-1, -1, "winReadCoverageRelativeMin", &winReadCoverageRelativeMin));
172     parArray.push_back(new ParameterInfoScalar <uint>   (-1, -1, "winReadCoverageBasesMin", &winReadCoverageBasesMin));
173 
174     //scoring
175     parArray.push_back(new ParameterInfoScalar <intScore>   (-1, -1, "scoreGap", &scoreGap));
176     parArray.push_back(new ParameterInfoScalar <intScore>   (-1, -1, "scoreGapNoncan", &scoreGapNoncan));
177     parArray.push_back(new ParameterInfoScalar <intScore>   (-1, -1, "scoreGapGCAG", &scoreGapGCAG));
178     parArray.push_back(new ParameterInfoScalar <intScore>   (-1, -1, "scoreGapATAC", &scoreGapATAC));
179     parArray.push_back(new ParameterInfoScalar <intScore>   (-1, -1, "scoreStitchSJshift", &scoreStitchSJshift));
180     parArray.push_back(new ParameterInfoScalar <double>     (-1, -1, "scoreGenomicLengthLog2scale", &scoreGenomicLengthLog2scale));
181 
182     parArray.push_back(new ParameterInfoScalar <intScore>   (-1, -1, "scoreDelBase", &scoreDelBase));
183     parArray.push_back(new ParameterInfoScalar <intScore>   (-1, -1, "scoreDelOpen", &scoreDelOpen));
184     parArray.push_back(new ParameterInfoScalar <intScore>   (-1, -1, "scoreInsOpen", &scoreInsOpen));
185     parArray.push_back(new ParameterInfoScalar <intScore>   (-1, -1, "scoreInsBase", &scoreInsBase));
186 
187     //alignment
188     parArray.push_back(new ParameterInfoScalar <uint>       (-1, -1, "seedSearchLmax", &seedSearchLmax));
189     parArray.push_back(new ParameterInfoScalar <uint>       (-1, -1, "seedSearchStartLmax", &seedSearchStartLmax));
190     parArray.push_back(new ParameterInfoScalar <double>     (-1, -1, "seedSearchStartLmaxOverLread", &seedSearchStartLmaxOverLread));
191 
192     parArray.push_back(new ParameterInfoScalar <uint>       (-1, -1, "seedPerReadNmax", &seedPerReadNmax));
193     parArray.push_back(new ParameterInfoScalar <uint>       (-1, -1, "seedPerWindowNmax", &seedPerWindowNmax));
194     parArray.push_back(new ParameterInfoScalar <uint>       (-1, -1, "seedNoneLociPerWindow", &seedNoneLociPerWindow));
195     parArray.push_back(new ParameterInfoScalar <uint>       (-1, -1, "seedMultimapNmax", &seedMultimapNmax));
196     parArray.push_back(new ParameterInfoScalar <uint>       (-1, -1, "seedSplitMin", &seedSplitMin));
197     parArray.push_back(new ParameterInfoScalar <uint64>       (-1, -1, "seedMapMin", &seedMapMin));
198 
199     parArray.push_back(new ParameterInfoScalar <uint>       (-1, -1, "alignIntronMin", &alignIntronMin));
200     parArray.push_back(new ParameterInfoScalar <uint>       (-1, -1, "alignIntronMax", &alignIntronMax));
201     parArray.push_back(new ParameterInfoScalar <uint>       (-1, -1, "alignMatesGapMax", &alignMatesGapMax));
202 
203     parArray.push_back(new ParameterInfoScalar <uint>       (-1, -1, "alignTranscriptsPerReadNmax", &alignTranscriptsPerReadNmax));
204     parArray.push_back(new ParameterInfoScalar <uint>       (-1, -1, "alignSJoverhangMin", &alignSJoverhangMin));
205     parArray.push_back(new ParameterInfoScalar <uint>       (-1, -1, "alignSJDBoverhangMin", &alignSJDBoverhangMin));
206     parArray.push_back(new ParameterInfoVector <int32>      (-1, -1, "alignSJstitchMismatchNmax", &alignSJstitchMismatchNmax));
207 
208     parArray.push_back(new ParameterInfoScalar <uint>       (-1, -1, "alignSplicedMateMapLmin", &alignSplicedMateMapLmin));
209     parArray.push_back(new ParameterInfoScalar <double>     (-1, -1, "alignSplicedMateMapLminOverLmate", &alignSplicedMateMapLminOverLmate));
210     parArray.push_back(new ParameterInfoScalar <uint>       (-1, -1, "alignWindowsPerReadNmax", &alignWindowsPerReadNmax));
211     parArray.push_back(new ParameterInfoScalar <uint>       (-1, -1, "alignTranscriptsPerWindowNmax", &alignTranscriptsPerWindowNmax));
212     parArray.push_back(new ParameterInfoScalar <string>     (-1, -1, "alignEndsType", &alignEndsType.in));
213     parArray.push_back(new ParameterInfoScalar <string>     (-1, -1, "alignSoftClipAtReferenceEnds", &alignSoftClipAtReferenceEnds.in));
214 
215     parArray.push_back(new ParameterInfoVector <string>     (-1, -1, "alignEndsProtrude", &alignEndsProtrude.in));
216     parArray.push_back(new ParameterInfoScalar <string>     (-1, -1, "alignInsertionFlush", &alignInsertionFlush.in));
217 
218     //peOverlap
219     parArray.push_back(new ParameterInfoScalar <uint>       (-1, -1, "peOverlapNbasesMin", &peOverlap.NbasesMin));
220     parArray.push_back(new ParameterInfoScalar <double>     (-1, -1, "peOverlapMMp", &peOverlap.MMp));
221 
222     //chimeric
223     parArray.push_back(new ParameterInfoScalar <uint>       (-1, -1, "chimSegmentMin", &pCh.segmentMin));
224     parArray.push_back(new ParameterInfoScalar <int>        (-1, -1, "chimScoreMin", &pCh.scoreMin));
225     parArray.push_back(new ParameterInfoScalar <int>        (-1, -1, "chimScoreDropMax", &pCh.scoreDropMax));
226     parArray.push_back(new ParameterInfoScalar <int>        (-1, -1, "chimScoreSeparation", &pCh.scoreSeparation));
227     parArray.push_back(new ParameterInfoScalar <int>        (-1, -1, "chimScoreJunctionNonGTAG", &pCh.scoreJunctionNonGTAG));
228     parArray.push_back(new ParameterInfoScalar <uint>       (-1, -1, "chimMainSegmentMultNmax", &pCh.mainSegmentMultNmax));
229     parArray.push_back(new ParameterInfoScalar <uint>       (-1, -1, "chimJunctionOverhangMin", &pCh.junctionOverhangMin));
230     parArray.push_back(new ParameterInfoVector <string>     (-1, -1, "chimOutType", &pCh.out.type));
231     parArray.push_back(new ParameterInfoVector <string>     (-1, -1, "chimFilter", &pCh.filter.stringIn));
232     parArray.push_back(new ParameterInfoScalar <uint>       (-1, -1, "chimSegmentReadGapMax", &pCh.segmentReadGapMax));
233     parArray.push_back(new ParameterInfoScalar <uint>       (-1, -1, "chimMultimapNmax", &pCh.multimapNmax));
234     parArray.push_back(new ParameterInfoScalar <uint>       (-1, -1, "chimMultimapScoreRange", &pCh.multimapScoreRange));
235     parArray.push_back(new ParameterInfoScalar <uint>       (-1, -1, "chimNonchimScoreDropMin", &pCh.nonchimScoreDropMin));
236     parArray.push_back(new ParameterInfoVector <int>        (-1, -1, "chimOutJunctionFormat", &pCh.outJunctionFormat));
237 
238     //sjdb
239     parArray.push_back(new ParameterInfoVector <string> (-1, -1, "sjdbFileChrStartEnd", &pGe.sjdbFileChrStartEnd));
240     parArray.push_back(new ParameterInfoScalar <string> (-1, -1, "sjdbGTFfile", &pGe.sjdbGTFfile));
241     parArray.push_back(new ParameterInfoScalar <string> (-1, -1, "sjdbGTFchrPrefix", &pGe.sjdbGTFchrPrefix));
242 
243     parArray.push_back(new ParameterInfoScalar <string> (-1, -1, "sjdbGTFfeatureExon", &pGe.sjdbGTFfeatureExon));
244     parArray.push_back(new ParameterInfoScalar <string> (-1, -1, "sjdbGTFtagExonParentTranscript", &pGe.sjdbGTFtagExonParentTranscript));
245     parArray.push_back(new ParameterInfoScalar <string> (-1, -1, "sjdbGTFtagExonParentGene", &pGe.sjdbGTFtagExonParentGene));
246     parArray.push_back(new ParameterInfoVector <string> (-1, -1, "sjdbGTFtagExonParentGeneName", &pGe.sjdbGTFtagExonParentGeneName));
247     parArray.push_back(new ParameterInfoVector <string> (-1, -1, "sjdbGTFtagExonParentGeneType", &pGe.sjdbGTFtagExonParentGeneType));
248 
249     parArray.push_back(new ParameterInfoScalar <uint>   (-1, -1, "sjdbOverhang", &pGe.sjdbOverhang));
250     pGe.sjdbOverhang_par=parArray.size()-1;
251     parArray.push_back(new ParameterInfoScalar <int>    (-1, -1, "sjdbScore", &pGe.sjdbScore));
252     parArray.push_back(new ParameterInfoScalar <string> (-1, -1, "sjdbInsertSave", &pGe.sjdbInsertSave));
253 
254     //variation
255     parArray.push_back(new ParameterInfoScalar <string> (-1, -1, "varVCFfile", &var.vcfFile));
256 
257     //WASP
258     parArray.push_back(new ParameterInfoScalar <string> (-1, -1, "waspOutputMode", &wasp.outputMode));
259 
260     //quant
261     parArray.push_back(new ParameterInfoVector <string> (-1, -1, "quantMode", &quant.mode));
262     parArray.push_back(new ParameterInfoScalar <int>     (-1, -1, "quantTranscriptomeBAMcompression", &quant.trSAM.bamCompression));
263     parArray.push_back(new ParameterInfoScalar <string>     (-1, -1, "quantTranscriptomeBan", &quant.trSAM.ban));
264 
265     //2-pass
266     parArray.push_back(new ParameterInfoScalar <uint>   (-1, -1, "twopass1readsN", &twoPass.pass1readsN));
267     twoPass.pass1readsN_par=parArray.size()-1;
268     parArray.push_back(new ParameterInfoScalar <string>   (-1, -1, "twopassMode", &twoPass.mode));
269 
270     //solo
271     parArray.push_back(new ParameterInfoScalar <string>   (-1, -1, "soloType", &pSolo.typeStr));
272     parArray.push_back(new ParameterInfoScalar <uint32>   (-1, -1, "soloCBstart", &pSolo.cbS));
273     parArray.push_back(new ParameterInfoScalar <uint32>   (-1, -1, "soloUMIstart", &pSolo.umiS));
274     parArray.push_back(new ParameterInfoScalar <uint32>   (-1, -1, "soloCBlen", &pSolo.cbL));
275     parArray.push_back(new ParameterInfoScalar <uint32>   (-1, -1, "soloUMIlen", &pSolo.umiL));
276     parArray.push_back(new ParameterInfoScalar <uint32>   (-1, -1, "soloBarcodeReadLength", &pSolo.bL));
277     parArray.push_back(new ParameterInfoScalar <uint32>   (-1, -1, "soloBarcodeMate", &pSolo.barcodeReadIn));
278     parArray.push_back(new ParameterInfoVector <string>   (-1, -1, "soloCBwhitelist", &pSolo.soloCBwhitelist));
279     parArray.push_back(new ParameterInfoScalar <string>   (-1, -1, "soloStrand", &pSolo.strandStr));
280     parArray.push_back(new ParameterInfoVector <string>   (-1, -1, "soloOutFileNames", &pSolo.outFileNames));
281     parArray.push_back(new ParameterInfoVector <string>   (-1, -1, "soloFeatures", &pSolo.featureIn));
282     parArray.push_back(new ParameterInfoVector <string>   (-1, -1, "soloUMIdedup", &pSolo.umiDedup.typesIn));
283     parArray.push_back(new ParameterInfoScalar <string>   (-1, -1, "soloAdapterSequence",&pSolo.adapterSeq));
284     parArray.push_back(new ParameterInfoScalar <uint32>   (-1, -1, "soloAdapterMismatchesNmax", &pSolo.adapterMismatchesNmax));
285     parArray.push_back(new ParameterInfoScalar <string>    (-1, -1, "soloCBmatchWLtype", &pSolo.CBmatchWL.type));
286     parArray.push_back(new ParameterInfoVector <string>   (-1, -1, "soloCBposition",&pSolo.cbPositionStr));
287     parArray.push_back(new ParameterInfoScalar <string>   (-1, -1, "soloUMIposition",&pSolo.umiPositionStr));
288     parArray.push_back(new ParameterInfoVector <string>   (-1, -1, "soloCellFilter",&pSolo.cellFilter.type));
289     parArray.push_back(new ParameterInfoVector <string>   (-1, -1, "soloUMIfiltering",&pSolo.umiFiltering.type));
290 
291     parArray.push_back(new ParameterInfoVector <string>   (-1, -1, "soloMultiMappers", &pSolo.multiMap.typesIn));
292 
293     parArray.push_back(new ParameterInfoScalar <string>   (-1, -1, "soloClusterCBfile",&pSolo.clusterCBfile));
294     parArray.push_back(new ParameterInfoScalar <string>   (-1, -1, "soloOutFormatFeaturesGeneField3",&pSolo.outFormat.featuresGeneField3));
295 
296     parArray.push_back(new ParameterInfoVector <string>   (-1, -1, "soloInputSAMattrBarcodeSeq",&pSolo.samAtrrBarcodeSeq));
297     parArray.push_back(new ParameterInfoVector <string>   (-1, -1, "soloInputSAMattrBarcodeQual",&pSolo.samAtrrBarcodeQual));
298 
299     parameterInputName.push_back("Default");
300     parameterInputName.push_back("Command-Line-Initial");
301     parameterInputName.push_back("Command-Line");
302     parameterInputName.push_back("genomeParameters.txt");
303 
304 };
305 
306 
inputParameters(int argInN,char * argIn[])307 void Parameters::inputParameters (int argInN, char* argIn[]) {//input parameters: default, from files, from command line
308 
309     //hard-coded parameters
310     runRestart.type=0;
311 
312 ///////// Default parameters
313 
314     #include "parametersDefault.xxd"
315     string parString( (const char*) parametersDefault,parametersDefault_len);
316     stringstream parStream (parString);
317 
318     scanAllLines(parStream, 0, -1);
319     for (uint ii=0; ii<parArray.size(); ii++) {
320         if (parArray[ii]->inputLevel<0) {
321             ostringstream errOut;
322             errOut <<"BUG: DEFAULT parameter value not defined: "<<parArray[ii]->nameString;
323             exitWithError(errOut.str(), std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
324         };
325     };
326 
327 ///////// Initial parameters from Command Line
328 
329     commandLine="";
330     string commandLineFile="";
331 
332     if (argInN>1) {//scan parameters from command line
333         commandLine += string(argIn[0]);
334         for (int iarg=1; iarg<argInN; iarg++) {
335             string oneArg=string(argIn[iarg]);
336 
337             if (oneArg=="--version") {//print version and exit
338                 std::cout << STAR_VERSION <<std::endl;
339                 exit(0);
340             };
341 
342             size_t found = oneArg.find("=");
343             if (found!=string::npos && oneArg.substr(0,2)=="--") {// --parameter=value
344                 string key = oneArg.substr(2, found - 2);
345                 string val = oneArg.substr(found + 1);
346                 if (val.find_first_of(" \t")!=std::string::npos) {//there is white space in the argument, put "" around
347                     val ='\"' + val + '\"';
348                 };
349                 commandLineFile += '\n' + key + ' ' + val;
350             } else if (oneArg.substr(0,2)=="--") {//parameter name, cut --
351                 commandLineFile +='\n' + oneArg.substr(2);
352             } else {//parameter value
353                 if (oneArg.find_first_of(" \t")!=std::string::npos) {//there is white space in the argument, put "" around
354                     oneArg ='\"'  + oneArg +'\"';
355                 };
356                 commandLineFile +=' ' + oneArg;
357             };
358             commandLine += ' ' + oneArg;
359         };
360         istringstream parStreamCommandLine(commandLineFile);
361         scanAllLines(parStreamCommandLine, 1, 2); //read only initial Command Line parameters
362     };
363 
364 	createDirectory(outFileNamePrefix, S_IRWXU, "--outFileNamePrefix", *this); //TODO: runDirPerm is hard-coded now. Need to load it from command-line
365 
366     outLogFileName=outFileNamePrefix + "Log.out";
367     inOut->logMain.open(outLogFileName.c_str());
368     if (inOut->logMain.fail()) {
369         ostringstream errOut;
370         errOut <<"EXITING because of FATAL ERROR: could not create output file: "<<outFileNamePrefix + "Log.out"<<"\n";
371         errOut <<"SOLUTION: check if the path " << outFileNamePrefix << " exists and you have permissions to write there\n";
372         exitWithError(errOut.str(),std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
373     };
374 
375     inOut->logMain << "STAR version=" << STAR_VERSION << "\n";
376     inOut->logMain << "STAR compilation time,server,dir=" << COMPILATION_TIME_PLACE << "\n";
377     #ifdef COMPILE_FOR_LONG_READS
378            inOut->logMain << "Compiled for LONG reads" << "\n";
379     #endif
380 
381     //define what goes to cout
382     if (outStd=="Log") {
383         inOut->logStdOut=& std::cout;
384     } else if (outStd=="SAM" || outStd=="BAM_Unsorted" || outStd=="BAM_SortedByCoordinate" || outStd=="BAM_Quant") {
385         inOut->logStdOutFile.open((outFileNamePrefix + "Log.std.out").c_str());
386         inOut->logStdOut= & inOut->logStdOutFile;
387     } else {
388         ostringstream errOut;
389         errOut <<"EXITING because of FATAL PARAMETER error: outStd="<<outStd <<" is not a valid value of the parameter\n";
390         errOut <<"SOLUTION: provide a valid value fot outStd: Log / SAM / BAM_Unsorted / BAM_SortedByCoordinate";
391         exitWithError(errOut.str(),std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
392     };
393 
394     /*
395     inOut->logMain << "##### DEFAULT parameters:\n" <<flush;
396     for (uint ii=0; ii<parArray.size(); ii++) {
397         if (parArray[ii]->inputLevel==0) {
398             inOut->logMain << setw(PAR_NAME_PRINT_WIDTH) << parArray[ii]->nameString <<"    "<< *(parArray[ii]) << endl;
399         };
400     };
401     */
402 
403     inOut->logMain <<"##### Command Line:\n"<<commandLine <<endl ;
404 
405     inOut->logMain << "##### Initial USER parameters from Command Line:\n";
406     for (uint ii=0; ii<parArray.size(); ii++) {
407         if (parArray[ii]->inputLevel==1) {
408             inOut->logMain << setw(PAR_NAME_PRINT_WIDTH) << parArray[ii]->nameString <<"    "<< *(parArray[ii]) << endl;
409         };
410     };
411 
412 ///////// Parameters files
413 
414     if (parametersFiles.at(0) != "-") {//read parameters from a user-defined file
415         for (uint ii=0; ii<parametersFiles.size(); ii++) {
416             parameterInputName.push_back(parametersFiles.at(ii));
417             ifstream parFile(parametersFiles.at(ii).c_str());
418             if (parFile.good()) {
419                 inOut->logMain << "##### USER parameters from user-defined parameters file " <<parametersFiles.at(ii)<< ":\n" <<flush;
420                 scanAllLines(parFile, parameterInputName.size()-1, -1);
421                 parFile.close();
422             } else {
423                 ostringstream errOut;
424                 errOut <<"EXITING because of fatal input ERROR: could not open user-defined parameters file " <<parametersFiles.at(ii)<< "\n" <<flush;
425                 exitWithError(errOut.str(), std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
426             };
427         };
428     };
429 
430 ///////// Command Line Final
431 
432     if (argInN>1) {//scan all parameters from command line and override previous values
433         inOut->logMain << "###### All USER parameters from Command Line:\n" <<flush;
434         istringstream parStreamCommandLine(commandLineFile);
435         scanAllLines(parStreamCommandLine, 2, -1);
436     };
437 
438     inOut->logMain << "##### Finished reading parameters from all sources\n\n" << flush;
439 
440     inOut->logMain << "##### Final user re-defined parameters-----------------:\n" << flush;
441 
442     ostringstream clFull;
443     clFull << argIn[0];
444     for (uint ii=0; ii<parArray.size(); ii++) {
445         if (parArray[ii]->inputLevel>0) {
446             inOut->logMain << setw(PAR_NAME_PRINT_WIDTH) << parArray[ii]->nameString <<"    "<< *(parArray[ii]) << endl;
447             if (parArray[ii]->nameString != "parametersFiles" ) {
448                 clFull << "   --" << parArray[ii]->nameString << " " << *(parArray[ii]);
449             };
450         };
451     };
452     commandLineFull=clFull.str();
453     inOut->logMain << "\n-------------------------------\n##### Final effective command line:\n" <<  clFull.str() << "\n";
454 
455     /*
456     //     parOut.close();
457     inOut->logMain << "\n##### Final parameters after user input--------------------------------:\n" << flush;
458     //     parOut.open("Parameters.all.out");
459     for (uint ii=0; ii<parArray.size(); ii++) {
460         inOut->logMain << setw(PAR_NAME_PRINT_WIDTH) << parArray[ii]->nameString <<"    "<< *(parArray[ii]) << endl;
461     };
462     //     parOut.close();
463     */
464     inOut->logMain << "----------------------------------------\n\n" << flush;
465 
466 
467     ///////////////////////////////////////// Old variables
468     //splitting
469     maxNsplit=10;
470 
471 
472 ////////////////////////////////////////////////////// Calculate and check parameters
473     iReadAll=0;
474 
475     pGe.initialize(this);
476 
477     //directory permissions TODO: this needs to be done before outPrefixFileName is created
478     if (runDirPermIn=="User_RWX") {
479         runDirPerm=S_IRWXU;
480     } else if (runDirPermIn=="All_RWX") {
481         runDirPerm= S_IRWXU | S_IRWXG | S_IRWXO;
482     } else {
483         ostringstream errOut;
484         errOut << "EXITING because of FATAL INPUT ERROR: unrecognized option in --runDirPerm=" << runDirPerm << "\n";
485         errOut << "SOLUTION: use one of the allowed values of --runDirPerm : 'User_RWX' or 'All_RWX' \n";
486         exitWithError(errOut.str(),std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
487     };
488 
489     if (outTmpDir=="-") {
490         outFileTmp=outFileNamePrefix +"_STARtmp/";
491         if (runRestart.type!=1)
492             sysRemoveDir (outFileTmp);
493     } else {
494         outFileTmp=outTmpDir + "/";
495     };
496 
497     if (mkdir (outFileTmp.c_str(),runDirPerm)!=0 && runRestart.type!=1) {
498         ostringstream errOut;
499         errOut <<"EXITING because of fatal ERROR: could not make temporary directory: "<< outFileTmp<<"\n";
500         errOut <<"SOLUTION: (i) please check the path and writing permissions \n (ii) if you specified --outTmpDir, and this directory exists - please remove it before running STAR\n"<<flush;
501         exitWithError(errOut.str(), std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
502     };
503 
504     //threaded or not
505     g_threadChunks.threadBool=(runThreadN>1);
506 
507     //wigOut parameters
508     if (outWigType.at(0)=="None") {
509         outWigFlags.yes=false;
510     } else if (outWigType.at(0)=="bedGraph") {
511         outWigFlags.yes=true;
512         outWigFlags.format=0;
513     } else if (outWigType.at(0)=="wiggle") {
514         outWigFlags.yes=true;
515         outWigFlags.format=1;
516     } else {
517         ostringstream errOut;
518         errOut << "EXITING because of FATAL INPUT ERROR: unrecognized option in --outWigType=" << outWigType.at(0) << "\n";
519         errOut << "SOLUTION: use one of the allowed values of --outWigType : 'None' or 'bedGraph' \n";
520         exitWithError(errOut.str(),std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
521     };
522     if (outWigStrand.at(0)=="Stranded") {
523         outWigFlags.strand=true;
524     } else if (outWigStrand.at(0)=="Unstranded") {
525         outWigFlags.strand=false;
526     } else {
527         ostringstream errOut;
528         errOut << "EXITING because of FATAL INPUT ERROR: unrecognized option in --outWigStrand=" << outWigStrand.at(0) << "\n";
529         errOut << "SOLUTION: use one of the allowed values of --outWigStrand : 'Stranded' or 'Unstranded' \n";
530         exitWithError(errOut.str(),std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
531     };
532 
533     if (outWigType.size()==1) {//simple bedGraph
534         outWigFlags.type=0;
535     } else {
536         if (outWigType.at(1)=="read1_5p") {
537             outWigFlags.type=1;
538         } else if (outWigType.at(1)=="read2") {
539             outWigFlags.type=2;
540         } else {
541             ostringstream errOut;
542             errOut << "EXITING because of FATAL INPUT ERROR: unrecognized second option in --outWigType=" << outWigType.at(1) << "\n";
543             errOut << "SOLUTION: use one of the allowed values of --outWigType : 'read1_5p' \n";
544             exitWithError(errOut.str(),std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
545         };
546     };
547 
548     //wigOut parameters
549     if (outWigNorm.at(0)=="None") {
550         outWigFlags.norm=0;
551     } else if (outWigNorm.at(0)=="RPM") {
552         outWigFlags.norm=1;
553     } else {
554         ostringstream errOut;
555         errOut << "EXITING because of fatal parameter ERROR: unrecognized option in --outWigNorm=" << outWigNorm.at(0) << "\n";
556         errOut << "SOLUTION: use one of the allowed values of --outWigNorm : 'None' or 'RPM' \n";
557         exitWithError(errOut.str(),std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
558     };
559 
560 
561     //remove duplicates parameters
562     if (removeDuplicates.mode=="UniqueIdentical")
563     {
564         removeDuplicates.yes=true;
565         removeDuplicates.markMulti=true;
566     } else if (removeDuplicates.mode=="UniqueIdenticalNotMulti")
567     {
568         removeDuplicates.yes=true;
569         removeDuplicates.markMulti=false;
570     } else if (removeDuplicates.mode!="-")
571     {
572             ostringstream errOut;
573             errOut << "EXITING because of fatal PARAMETERS error: unrecognized option in of --bamRemoveDuplicatesType="<<removeDuplicates.mode<<"\n";
574             errOut << "SOLUTION: use allowed option: - or UniqueIdentical or UniqueIdenticalNotMulti";
575             exitWithError(errOut.str(),std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
576     };
577 
578     runMode=runModeIn[0];
579     if (runMode=="alignReads") {
580         inOut->logProgress.open((outFileNamePrefix + "Log.progress.out").c_str());
581     } else if (runMode=="inputAlignmentsFromBAM") {
582         //at the moment, only wiggle output is implemented
583         if (outWigFlags.yes) {
584             *inOut->logStdOut << timeMonthDayTime() << " ..... reading from BAM, output wiggle\n" <<flush;
585             inOut->logMain << timeMonthDayTime()    << " ..... reading from BAM, output wiggle\n" <<flush;
586             string wigOutFileNamePrefix=outFileNamePrefix + "Signal";
587             signalFromBAM(inputBAMfile, wigOutFileNamePrefix, *this);
588             *inOut->logStdOut << timeMonthDayTime() << " ..... done\n" <<flush;
589             inOut->logMain << timeMonthDayTime()    << " ..... done\n" <<flush;
590         } else if (removeDuplicates.mode!="-") {
591             *inOut->logStdOut << timeMonthDayTime() << " ..... reading from BAM, remove duplicates, output BAM\n" <<flush;
592             inOut->logMain << timeMonthDayTime()    << " ..... reading from BAM, remove duplicates, output BAM\n" <<flush;
593             bamRemoveDuplicates(inputBAMfile, (outFileNamePrefix+"Processed.out.bam").c_str(), *this);
594             *inOut->logStdOut << timeMonthDayTime() << " ..... done\n" <<flush;
595             inOut->logMain << timeMonthDayTime()    << " ..... done\n" <<flush;
596         } else {
597             ostringstream errOut;
598             errOut <<"EXITING because of fatal INPUT ERROR: at the moment --runMode inputFromBAM only works with --outWigType bedGraph OR --bamRemoveDuplicatesType Identical"<<"\n";
599             exitWithError(errOut.str(), std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
600         };
601         sysRemoveDir (outFileTmp);
602         exit(0);
603     };
604 
605     outSAMbool=false;
606     outBAMunsorted=false;
607     outBAMcoord=false;
608     if (runMode=="alignReads" && outSAMmode != "None") {//open SAM file and write header
609         if (outSAMtype.at(0)=="BAM") {
610             if (outSAMtype.size()<2) {
611                 ostringstream errOut;
612                 errOut <<"EXITING because of fatal PARAMETER error: missing BAM option\n";
613                 errOut <<"SOLUTION: re-run STAR with one of the allowed values of --outSAMtype BAM Unsorted OR SortedByCoordinate OR both\n";
614                 exitWithError(errOut.str(), std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
615             };
616             for (uint32 ii=1; ii<outSAMtype.size(); ii++) {
617                 if (outSAMtype.at(ii)=="Unsorted") {
618                     outBAMunsorted=true;
619                 } else if (outSAMtype.at(ii)=="SortedByCoordinate") {
620                     outBAMcoord=true;
621                 } else {
622                     ostringstream errOut;
623                     errOut <<"EXITING because of fatal input ERROR: unknown value for the word " <<ii+1<<" of outSAMtype: "<< outSAMtype.at(ii) <<"\n";
624                     errOut <<"SOLUTION: re-run STAR with one of the allowed values of --outSAMtype BAM Unsorted or SortedByCoordinate or both\n";
625                     exitWithError(errOut.str(), std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
626                 };
627             };
628             //TODO check for conflicts
629             if (outBAMunsorted) {
630                 if (outStd=="BAM_Unsorted") {
631                     outBAMfileUnsortedName="-";
632                 } else {
633                     outBAMfileUnsortedName=outFileNamePrefix + "Aligned.out.bam";
634                 };
635                 inOut->outBAMfileUnsorted = bgzf_open(outBAMfileUnsortedName.c_str(),("w"+to_string((long long) outBAMcompression)).c_str());
636             };
637             if (outBAMcoord) {
638                 if (outStd=="BAM_SortedByCoordinate") {
639                     outBAMfileCoordName="-";
640                 } else {
641                     outBAMfileCoordName=outFileNamePrefix + "Aligned.sortedByCoord.out.bam";
642                 };
643                 inOut->outBAMfileCoord = bgzf_open(outBAMfileCoordName.c_str(),("w"+to_string((long long) outBAMcompression)).c_str());
644                 if (outBAMsortingThreadN==0) {
645                     outBAMsortingThreadNactual=min(6, runThreadN);
646                 } else {
647                     outBAMsortingThreadNactual=outBAMsortingThreadN;
648                 };
649                 outBAMcoordNbins=max((uint32)outBAMsortingThreadNactual*3,outBAMsortingBinsN);
650                 outBAMsortingBinStart= new uint64 [outBAMcoordNbins];
651                 outBAMsortingBinStart[0]=1;//this initial value means that the bin sizes have not been determined yet
652 
653                 outBAMsortTmpDir=outFileTmp+"/BAMsort/";
654                 mkdir(outBAMsortTmpDir.c_str(),runDirPerm);
655             };
656         } else if (outSAMtype.at(0)=="SAM") {
657             if (outSAMtype.size()>1)
658             {
659                 ostringstream errOut;
660                 errOut <<"EXITING because of fatal PARAMETER error: --outSAMtype SAM can cannot be combined with "<<outSAMtype.at(1)<<" or any other options\n";
661                 errOut <<"SOLUTION: re-run STAR with with '--outSAMtype SAM' only, or with --outSAMtype BAM Unsorted|SortedByCoordinate\n";
662                 exitWithError(errOut.str(), std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
663             };
664             outSAMbool=true;
665             if (outStd=="SAM") {
666                 inOut->outSAM = & std::cout;
667             } else {
668                 inOut->outSAMfile.open((outFileNamePrefix + "Aligned.out.sam").c_str());
669                 inOut->outSAM = & inOut->outSAMfile;
670             };
671         } else if (outSAMtype.at(0)=="None") {
672             //nothing to do, all flags are already false
673         } else {
674             ostringstream errOut;
675             errOut <<"EXITING because of fatal input ERROR: unknown value for the first word of outSAMtype: "<< outSAMtype.at(0) <<"\n";
676             errOut <<"SOLUTION: re-run STAR with one of the allowed values of outSAMtype: BAM or SAM \n"<<flush;
677             exitWithError(errOut.str(), std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
678         };
679     };
680 
681     if (!outBAMcoord && outWigFlags.yes && runMode=="alignReads") {
682         ostringstream errOut;
683         errOut <<"EXITING because of fatal PARAMETER error: generating signal with --outWigType requires sorted BAM\n";
684         errOut <<"SOLUTION: re-run STAR with with --outSAMtype BAM SortedByCoordinate, or, id you also need unsroted BAM, with --outSAMtype BAM SortedByCoordinate Unsorted\n";
685         exitWithError(errOut.str(), std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
686     };
687 
688     //versions
689     for (uint ii=0;ii<1;ii++) {
690         if (parArray[ii]->inputLevel>0) {
691             ostringstream errOut;
692             errOut <<"EXITING because of fatal input ERROR: the version parameter "<< parArray[ii]->nameString << " cannot be re-defined by the user\n";
693             errOut <<"SOLUTION: please remove this parameter from the command line or input files and re-start STAR\n"<<flush;
694             exitWithError(errOut.str(), std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
695         };
696     };
697 
698     //run
699     if (runThreadN<=0) {
700         ostringstream errOut;
701         errOut <<"EXITING: fatal input ERROR: runThreadN must be >0, user-defined runThreadN="<<runThreadN<<"\n";
702         exitWithError(errOut.str(), std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
703     };
704 
705     //
706     if (outFilterType=="BySJout" && outSAMorder=="PairedKeepInputOrder") {
707         ostringstream errOut;
708         errOut <<"EXITING: fatal input ERROR: --outFilterType=BySJout is not presently compatible with --outSAMorder=PairedKeepInputOrder\n";
709         errOut <<"SOLUTION: re-run STAR without setting one of those parameters.\n";
710         exitWithError(errOut.str(), std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
711     };
712     if (!outSAMbool && outSAMorder=="PairedKeepInputOrder") {
713         ostringstream errOut;
714         errOut <<"EXITING: fatal input ERROR: --outSAMorder=PairedKeepInputOrder is presently only compatible with SAM output, i.e. default --outSMAtype SAM\n";
715         errOut <<"SOLUTION: re-run STAR without --outSAMorder=PairedKeepInputOrder, or with --outSAMorder=PairedKeepInputOrder --outSMAtype SAM .\n";
716         exitWithError(errOut.str(), std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
717     };
718     //SJ filtering
719     for (int ii=0;ii<4;ii++) {
720         if (outSJfilterOverhangMin.at(ii)<0) outSJfilterOverhangMin.at(ii)=numeric_limits<int32>::max();
721         if (outSJfilterCountUniqueMin.at(ii)<0) outSJfilterCountUniqueMin.at(ii)=numeric_limits<int32>::max();
722         if (outSJfilterCountTotalMin.at(ii)<0) outSJfilterCountTotalMin.at(ii)=numeric_limits<int32>::max();
723         if (outSJfilterDistToOtherSJmin.at(ii)<0) outSJfilterDistToOtherSJmin.at(ii)=numeric_limits<int32>::max();
724 
725         if (alignSJstitchMismatchNmax.at(ii)<0) alignSJstitchMismatchNmax.at(ii)=numeric_limits<int32>::max();
726     };
727 
728     if (limitGenomeGenerateRAM==0) {//must be >0
729         inOut->logMain <<"EXITING because of FATAL PARAMETER ERROR: limitGenomeGenerateRAM=0\n";
730         inOut->logMain <<"SOLUTION: please specify a >0 value for limitGenomeGenerateRAM\n"<<flush;
731         exit(1);
732     } else if (limitGenomeGenerateRAM>1000000000000) {//
733         inOut->logMain <<"WARNING: specified limitGenomeGenerateRAM="<<limitGenomeGenerateRAM<<" bytes appears to be too large, if you do not have enough memory the code will crash!\n"<<flush;
734     };
735 
736     outSAMfilter.KeepOnlyAddedReferences=false;
737     outSAMfilter.KeepAllAddedReferences=false;
738     outSAMfilter.yes=true;
739     if (outSAMfilter.mode.at(0)=="KeepOnlyAddedReferences") {
740         outSAMfilter.KeepOnlyAddedReferences=true;
741     } else if (outSAMfilter.mode.at(0)=="KeepAllAddedReferences") {
742         outSAMfilter.KeepAllAddedReferences=true;
743     } else if (outSAMfilter.mode.at(0)=="None") {
744       outSAMfilter.yes=false;
745     } else {
746         ostringstream errOut;
747         errOut <<"EXITING because of FATAL INPUT ERROR: unknown/unimplemented value for --outSAMfilter: "<<outSAMfilter.mode.at(0) <<"\n";
748         errOut <<"SOLUTION: specify one of the allowed values: KeepOnlyAddedReferences or None\n";
749         exitWithError(errOut.str(), std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
750     };
751 
752     if ( (outSAMfilter.KeepOnlyAddedReferences || outSAMfilter.KeepAllAddedReferences) && pGe.gFastaFiles.at(0)=="-" ) {
753         ostringstream errOut;
754         errOut <<"EXITING because of FATAL INPUT ERROR: --outSAMfilter KeepOnlyAddedReferences OR KeepAllAddedReferences options can only be used if references are added on-the-fly with --genomeFastaFiles" <<"\n";
755         errOut <<"SOLUTION: use default --outSAMfilter None, OR add references with --genomeFataFiles\n";
756         exitWithError(errOut.str(), std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
757     };
758 
759 
760     if (outMultimapperOrder.mode=="Old_2.4") {
761         outMultimapperOrder.random=false;
762     } else if (outMultimapperOrder.mode=="Random") {
763         outMultimapperOrder.random=true;
764     } else {
765         ostringstream errOut;
766         errOut <<"EXITING because of FATAL INPUT ERROR: unknown/unimplemented value for --outMultimapperOrder: "<<outMultimapperOrder.mode <<"\n";
767         errOut <<"SOLUTION: specify one of the allowed values: Old_2.4 or SortedByCoordinate or Random\n";
768         exitWithError(errOut.str(), std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
769     };
770 
771     //read parameters
772     readFilesInit();
773 
774     //two-pass
775     if (parArray.at(twoPass.pass1readsN_par)->inputLevel>0  && twoPass.mode=="None") {
776         ostringstream errOut;
777         errOut << "EXITING because of fatal PARAMETERS error: --twopass1readsN is defined, but --twoPassMode is not defined\n";
778         errOut << "SOLUTION: to activate the 2-pass mode, use --twopassMode Basic";
779         exitWithError(errOut.str(),std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
780     };
781 
782     twoPass.yes=false;
783     twoPass.pass2=false;
784     if (twoPass.mode!="None") {//2-pass parameters
785         if (runMode!="alignReads") {
786             ostringstream errOut;
787             errOut << "EXITING because of fatal PARAMETERS error: 2-pass mapping option  can only be used with --runMode alignReads\n";
788             errOut << "SOLUTION: remove --twopassMode option";
789             exitWithError(errOut.str(),std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
790         };
791 
792         if (twoPass.mode!="Basic") {
793             ostringstream errOut;
794             errOut << "EXITING because of fatal PARAMETERS error: unrecognized value of --twopassMode="<<twoPass.mode<<"\n";
795             errOut << "SOLUTION: for the 2-pass mode, use allowed values --twopassMode: Basic";
796             exitWithError(errOut.str(),std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
797         };
798 
799         if (twoPass.pass1readsN==0) {
800             ostringstream errOut;
801             errOut << "EXITING because of fatal PARAMETERS error: --twopass1readsN = 0 in the 2-pass mode\n";
802             errOut << "SOLUTION: for the 2-pass mode, specify --twopass1readsN > 0. Use a very large number or -1 to map all reads in the 1st pass.\n";
803             exitWithError(errOut.str(),std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
804         };
805 
806         if (pGe.gLoad!="NoSharedMemory") {
807             ostringstream errOut;
808             errOut << "EXITING because of fatal PARAMETERS error: 2-pass method is not compatible with --genomeLoad "<<pGe.gLoad<<"\n";
809             errOut << "SOLUTION: re-run STAR with --genomeLoad NoSharedMemory ; this is the only option compatible with --twopassMode Basic .\n";
810             exitWithError(errOut.str(),std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
811         };
812         twoPass.yes=true;
813         twoPass.dir=outFileNamePrefix+"_STARpass1/";
814         sysRemoveDir (twoPass.dir);
815         if (mkdir (twoPass.dir.c_str(),runDirPerm)!=0) {
816             ostringstream errOut;
817             errOut <<"EXITING because of fatal ERROR: could not make pass1 directory: "<< twoPass.dir<<"\n";
818             errOut <<"SOLUTION: please check the path and writing permissions \n";
819             exitWithError(errOut.str(), std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
820         };
821     };
822 
823     // openReadFiles depends on twoPass for reading SAM header
824     if (runMode=="alignReads" && pGe.gLoad!="Remove" && pGe.gLoad!="LoadAndExit") {//open reads files to check if they are present
825         openReadsFiles();
826 
827         if (readNends > 2 && pSolo.typeStr=="None") {//could have >2 mates only for Solo
828             ostringstream errOut;
829             errOut <<"EXITING: because of fatal input ERROR: number of read mates files > 2: " <<readNends << "\n";
830             errOut <<"SOLUTION:specify only one or two files in the --readFilesIn option. If file names contain spaces, use quotes: \"file name\"\n";
831             exitWithError(errOut.str(), std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
832         };
833 
834         if ( runMode=="alignReads" && outReadsUnmapped=="Fastx" ) {//open unmapped reads file
835             for (uint imate=0;imate<readNends;imate++) {
836                 ostringstream ff;
837                 ff << outFileNamePrefix << "Unmapped.out.mate" << imate+1;
838                 inOut->outUnmappedReadsStream[imate].open(ff.str().c_str());
839             };
840         };
841     };
842 
843     if (outSAMmapqUnique<0 || outSAMmapqUnique>255) {
844             ostringstream errOut;
845             errOut <<"EXITING because of FATAL input ERROR: out of range value for outSAMmapqUnique=" << outSAMmapqUnique <<"\n";
846             errOut <<"SOLUTION: specify outSAMmapqUnique within the range of 0 to 255\n";
847             exitWithError(errOut.str(), std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
848     };
849 
850     //variation
851     var.yes=false;
852     if (var.vcfFile!="-") {
853         var.yes=true;
854     };
855 
856     //WASP
857     wasp.yes=false;
858     wasp.SAMtag=false;
859     if (wasp.outputMode=="SAMtag") {
860         wasp.yes=true;
861         wasp.SAMtag=true;
862     } else if (wasp.outputMode=="None") {
863         //nothing to do
864     } else {
865         ostringstream errOut;
866         errOut <<"EXITING because of FATAL INPUT ERROR: unknown/unimplemented --waspOutputMode option: "<<wasp.outputMode <<"\n";
867         errOut <<"SOLUTION: re-run STAR with allowed --waspOutputMode options: None or SAMtag\n";
868         exitWithError(errOut.str(), std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
869     };
870 
871     if (wasp.yes && !var.yes) {
872         ostringstream errOut;
873         errOut <<"EXITING because of FATAL INPUT ERROR: --waspOutputMode option requires VCF file: "<<wasp.outputMode <<"\n";
874         errOut <<"SOLUTION: re-run STAR with --waspOutputMode ... and --varVCFfile /path/to/file.vcf\n";
875         exitWithError(errOut.str(), std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
876     };
877 
878      if (wasp.yes && outSAMtype.at(0)!="BAM") {
879         ostringstream errOut;
880         errOut <<"EXITING because of FATAL INPUT ERROR: --waspOutputMode requires output to BAM file\n";
881         errOut <<"SOLUTION: re-run STAR with --waspOutputMode ... and --outSAMtype BAM ... \n";
882         exitWithError(errOut.str(), std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
883     };
884 
885     //quantification parameters
886     quant.yes=false;
887     quant.geCount.yes=false;
888     quant.trSAM.yes=false;
889     quant.trSAM.bamYes=false;
890     quant.trSAM.indel=false;
891     quant.trSAM.softClip=false;
892     quant.trSAM.singleEnd=false;
893     if (quant.mode.at(0) != "-") {
894         quant.yes=true;
895         for (uint32 ii=0; ii<quant.mode.size(); ii++) {
896             if (quant.mode.at(ii)=="TranscriptomeSAM") {
897                 quant.trSAM.yes=true;
898 
899                 if (quant.trSAM.bamCompression>-2)
900                     quant.trSAM.bamYes=true;
901 
902                 if (quant.trSAM.bamYes) {
903                     if (outStd=="BAM_Quant") {
904                         outFileNamePrefix="-";
905                     } else {
906                         outQuantBAMfileName=outFileNamePrefix + "Aligned.toTranscriptome.out.bam";
907                     };
908                     inOut->outQuantBAMfile=bgzf_open(outQuantBAMfileName.c_str(),("w"+to_string((long long) quant.trSAM.bamCompression)).c_str());
909                 };
910                 if (quant.trSAM.ban=="IndelSoftclipSingleend") {
911                     quant.trSAM.indel=false;
912                     quant.trSAM.softClip=false;
913                     quant.trSAM.singleEnd=false;
914                 } else if (quant.trSAM.ban=="Singleend") {
915                     quant.trSAM.indel=true;
916                     quant.trSAM.softClip=true;
917                     quant.trSAM.singleEnd=false;
918                 };
919             } else if  (quant.mode.at(ii)=="GeneCounts") {
920                 quant.geCount.yes=true;
921                 quant.geCount.outFile=outFileNamePrefix + "ReadsPerGene.out.tab";
922             } else {
923                 ostringstream errOut;
924                 errOut << "EXITING because of fatal INPUT error: unrecognized option in --quantMode=" << quant.mode.at(ii) << "\n";
925                 errOut << "SOLUTION: use one of the allowed values of --quantMode : TranscriptomeSAM or GeneCounts or - .\n";
926                 exitWithError(errOut.str(),std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
927             };
928         };
929     };
930     //these may be set in STARsolo or in SAM attributes
931     quant.geneFull.yes=false;
932     quant.gene.yes=false;
933 
934 
935     outSAMstrandField.type=0; //none
936     if (outSAMstrandField.in=="None") {
937         outSAMstrandField.type=0;
938     } else if (outSAMstrandField.in=="intronMotif") {
939         outSAMstrandField.type=1;
940     } else {
941         ostringstream errOut;
942         errOut << "EXITING because of fatal INPUT error: unrecognized option in outSAMstrandField=" << outSAMstrandField.in << "\n";
943         errOut << "SOLUTION: use one of the allowed values of --outSAMstrandField : None or intronMotif \n";
944         exitWithError(errOut.str(),std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
945     };
946 
947     //SAM attributes
948     samAttributes();
949 
950     //solo
951     pSolo.initialize(this);
952 
953     //clipping
954     pClip.initialize(this);
955 
956     //alignEnds
957     alignEndsType.ext[0][0]=false;
958     alignEndsType.ext[0][1]=false;
959     alignEndsType.ext[1][0]=false;
960     alignEndsType.ext[1][1]=false;
961 
962     if (alignEndsType.in=="EndToEnd") {
963         alignEndsType.ext[0][0]=true;
964         alignEndsType.ext[0][1]=true;
965         alignEndsType.ext[1][0]=true;
966         alignEndsType.ext[1][1]=true;
967     } else if (alignEndsType.in=="Extend5pOfRead1" ) {
968         alignEndsType.ext[0][0]=true;
969     } else if (alignEndsType.in=="Extend5pOfReads12" ) {
970         alignEndsType.ext[0][0]=true;
971         alignEndsType.ext[1][0]=true;
972     } else if (alignEndsType.in=="Extend3pOfRead1" ) {
973         alignEndsType.ext[0][1]=true;
974     } else if (alignEndsType.in=="Local") {
975         //nothing to do for now
976     } else {
977         ostringstream errOut;
978         errOut <<"EXITING because of FATAL INPUT ERROR: unknown/unimplemented value for --alignEndsType: "<<alignEndsType.in <<"\n";
979         errOut <<"SOLUTION: re-run STAR with --alignEndsType Local OR EndToEnd OR Extend5pOfRead1 OR Extend3pOfRead1\n";
980         exitWithError(errOut.str(), std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
981     };
982 
983     //open compilation-dependent streams
984     #ifdef OUTPUT_localChains
985             inOut->outLocalChains.open((outFileNamePrefix + "LocalChains.out.tab").c_str());
986     #endif
987 
988     strcpy(genomeNumToNT,"ACGTN");
989 
990    //sjdb insert on the fly
991     sjdbInsert.pass1=false;
992     sjdbInsert.pass2=false;
993     sjdbInsert.yes=false;
994     if (pGe.sjdbFileChrStartEnd.at(0)!="-" || pGe.sjdbGTFfile!="-") {//will insert annotated sjdb on the fly
995        sjdbInsert.pass1=true;
996        sjdbInsert.yes=true;
997     };
998     if (twoPass.yes) {
999        sjdbInsert.pass2=true;
1000        sjdbInsert.yes=true;
1001     };
1002 
1003     if (pGe.gLoad!="NoSharedMemory" && sjdbInsert.yes ) {
1004         ostringstream errOut;
1005         errOut << "EXITING because of fatal PARAMETERS error: on the fly junction insertion and 2-pass mappng cannot be used with shared memory genome \n" ;
1006         errOut << "SOLUTION: run STAR with --genomeLoad NoSharedMemory to avoid using shared memory\n" <<flush;
1007         exitWithError(errOut.str(),std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
1008     };
1009 
1010     if (runMode=="alignReads" && sjdbInsert.yes )
1011     {//run-time genome directory, this is needed for genome files generated on the fly
1012         if (pGe.sjdbOverhang<=0) {
1013             ostringstream errOut;
1014             errOut << "EXITING because of fatal PARAMETERS error: pGe.sjdbOverhang <=0 while junctions are inserted on the fly with --sjdbFileChrStartEnd or/and --sjdbGTFfile\n";
1015             errOut << "SOLUTION: specify pGe.sjdbOverhang>0, ideally readmateLength-1";
1016             exitWithError(errOut.str(),std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
1017         };
1018         sjdbInsert.outDir=outFileNamePrefix+"_STARgenome/";
1019         sysRemoveDir (sjdbInsert.outDir);
1020         if (mkdir (sjdbInsert.outDir.c_str(),runDirPerm)!=0) {
1021             ostringstream errOut;
1022             errOut <<"EXITING because of fatal ERROR: could not make run-time genome directory directory: "<< sjdbInsert.outDir<<"\n";
1023             errOut <<"SOLUTION: please check the path and writing permissions \n";
1024             exitWithError(errOut.str(), std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
1025         };
1026     };
1027 
1028     if (outBAMcoord && limitBAMsortRAM==0) {//check limitBAMsortRAM
1029         if (pGe.gLoad!="NoSharedMemory") {
1030             ostringstream errOut;
1031             errOut <<"EXITING because of fatal PARAMETERS error: limitBAMsortRAM=0 (default) cannot be used with --genomeLoad="<<pGe.gLoad <<", or any other shared memory options\n";
1032             errOut <<"SOLUTION: please use default --genomeLoad NoSharedMemory, \n        OR specify --limitBAMsortRAM the amount of RAM (bytes) that can be allocated for BAM sorting in addition to shared memory allocated for the genome.\n        --limitBAMsortRAM typically has to be > 10000000000 (i.e 10GB).\n";
1033             exitWithError(errOut.str(), std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
1034         };
1035         inOut->logMain<<"WARNING: --limitBAMsortRAM=0, will use genome size as RAM limit for BAM sorting\n";
1036     };
1037 
1038     for (uint ii=0; ii<readNameSeparator.size(); ii++) {
1039         if (readNameSeparator.at(ii)=="space") {
1040             readNameSeparatorChar.push_back(' ');
1041         } else if (readNameSeparator.at(ii)=="none") {
1042             //nothing to do
1043         } else if (readNameSeparator.at(ii).size()==1) {
1044             readNameSeparatorChar.push_back(readNameSeparator.at(ii).at(0));
1045         } else{
1046             ostringstream errOut;
1047             errOut << "EXITING because of fatal PARAMETERS error: unrecognized value of --readNameSeparator="<<readNameSeparator.at(ii)<<"\n";
1048             errOut << "SOLUTION: use allowed values: space OR single characters";
1049             exitWithError(errOut.str(),std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
1050         };
1051     };
1052 
1053     //outSAMunmapped
1054     outSAMunmapped.yes=false;
1055     outSAMunmapped.within=false;
1056     outSAMunmapped.keepPairs=false;
1057     if (outSAMunmapped.mode.at(0)=="None" && outSAMunmapped.mode.size()==1) {
1058         //nothing to do, all false
1059     } else if (outSAMunmapped.mode.at(0)=="Within" && outSAMunmapped.mode.size()==1) {
1060         outSAMunmapped.yes=true;
1061         outSAMunmapped.within=true;
1062     } else if (outSAMunmapped.mode.at(0)=="Within" && outSAMunmapped.mode.at(1)=="KeepPairs") {
1063         outSAMunmapped.yes=true;
1064         outSAMunmapped.within=true;
1065         if (readNmates==2) //not readNends, since this control output of alignments
1066             outSAMunmapped.keepPairs=true;
1067     } else {
1068         ostringstream errOut;
1069         errOut << "EXITING because of fatal PARAMETERS error: unrecognized option for --outSAMunmapped=";
1070         for (uint ii=0; ii<outSAMunmapped.mode.size(); ii++) errOut <<" "<< outSAMunmapped.mode.at(ii);
1071         errOut << "\nSOLUTION: use allowed options: None OR Within OR Within KeepPairs";
1072         exitWithError(errOut.str(),std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
1073     };
1074 
1075     alignEndsProtrude.nBasesMax=stoi(alignEndsProtrude.in.at(0),nullptr);
1076     alignEndsProtrude.concordantPair=false;
1077     if (alignEndsProtrude.nBasesMax>0) {//allow ends protrusion
1078         if (alignEndsProtrude.in.at(1)=="ConcordantPair") {
1079             alignEndsProtrude.concordantPair=true;
1080         } else if (alignEndsProtrude.in.at(1)=="DiscordantPair") {
1081             alignEndsProtrude.concordantPair=false;
1082         } else  {
1083             ostringstream errOut;
1084             errOut << "EXITING because of fatal PARAMETERS error: unrecognized option in of --alignEndsProtrude="<<alignEndsProtrude.in.at(1)<<"\n";
1085             errOut << "SOLUTION: use allowed option: ConcordantPair or DiscordantPair";
1086             exitWithError(errOut.str(),std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
1087         };
1088     };
1089 
1090     if (alignInsertionFlush.in=="None") {
1091         alignInsertionFlush.flushRight=false;
1092     } else if (alignInsertionFlush.in=="Right") {
1093         alignInsertionFlush.flushRight=true;
1094     } else  {
1095         ostringstream errOut;
1096         errOut << "EXITING because of fatal PARAMETERS error: unrecognized option in of --alignInsertionFlush="<<alignInsertionFlush.in<<"\n";
1097         errOut << "SOLUTION: use allowed option: None or Right";
1098         exitWithError(errOut.str(),std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
1099     };
1100 
1101     //peOverlap
1102     if (peOverlap.NbasesMin>0) {
1103         peOverlap.yes=true;
1104     } else {
1105         peOverlap.yes=false;
1106     };
1107 
1108     //alignSoftClipAtReferenceEnds.in
1109     if (alignSoftClipAtReferenceEnds.in=="Yes") {
1110         alignSoftClipAtReferenceEnds.yes=true;
1111     } else if (alignSoftClipAtReferenceEnds.in=="No") {
1112         alignSoftClipAtReferenceEnds.yes=false;
1113     } else {
1114         ostringstream errOut;
1115         errOut << "EXITING because of fatal PARAMETERS error: unrecognized option in --alignSoftClipAtReferenceEnds   "<<alignSoftClipAtReferenceEnds.in<<"\n";
1116         errOut << "SOLUTION: use allowed option: Yes or No";
1117         exitWithError(errOut.str(),std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
1118     };
1119 
1120     outSAMreadIDnumber=false;
1121     if (outSAMreadID=="Number") {
1122         outSAMreadIDnumber=true;
1123     };
1124 
1125 
1126     //////////////////////////////////////////////////////////////////////////////////
1127     ////////////////////////////////////////////////////////////////////////////////// these parameters do not depend on other parameters
1128     /////////////////////////////////////////////////////////////////////////////////
1129 
1130     ////////////////////////////////////////////////////////// limitIObufferSize
1131     /* old before 2.7.9
1132     // in/out buffers
1133     #define BUFFER_InSizeFraction 0.5
1134     if (limitIObufferSize<limitOutSJcollapsed*Junction::dataSize+1000000) {
1135         ostringstream errOut;
1136         errOut <<"EXITING because of FATAL INPUT ERROR: --limitIObufferSize="<<limitIObufferSize <<" is too small for ";
1137         errOut << "--limitOutSJcollapsed*"<<Junction::dataSize<<"="<< limitOutSJcollapsed<<"*"<<Junction::dataSize<<"="<<limitOutSJcollapsed*Junction::dataSize<<"\n";
1138         errOut <<"SOLUTION: re-run STAR with larger --limitIObufferSize or smaller --limitOutSJcollapsed\n";
1139         exitWithError(errOut.str(), std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
1140     };
1141     chunkInSizeBytesArray=(uint) int((limitIObufferSize-limitOutSJcollapsed*Junction::dataSize)*BUFFER_InSizeFraction)/2;
1142     chunkOutBAMsizeBytes= (uint) int((1.0/BUFFER_InSizeFraction-1.0)*chunkInSizeBytesArray*2.0);
1143     chunkInSizeBytes=chunkInSizeBytesArray-2*(DEF_readSeqLengthMax+1)-2*DEF_readNameLengthMax;//to prevent overflow
1144     */
1145 
1146     if (limitIObufferSize.size() != 2)
1147         exitWithError("EXITING because of FATAL input ERROR: --limitIObufferSize requires 2 numbers since 2.7.9a.\n"
1148                       "SOLUTION: specify 2 numbers in --limitIObufferSize : size of input and output buffers in bytes.\n"
1149                         , std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
1150 
1151     chunkInSizeBytesArray = limitIObufferSize[0]/readNends; //array size
1152     chunkInSizeBytes = chunkInSizeBytesArray-2*(DEF_readSeqLengthMax+1)-2*DEF_readNameLengthMax; //to prevent overflow - array is bigger to allow loading one read
1153     chunkOutBAMsizeBytes = limitIObufferSize[1];
1154 
1155 
1156     ///////////////////////////////////////////////////////// outSJ
1157     if (outSJ.type[0] == "None") {
1158         outSJ.yes = false;
1159     } else if (outSJ.type[0] == "Standard") {
1160         outSJ.yes = true;
1161     } else {
1162         exitWithError("EXITING because of FATAL input ERROR: unrecognized option in --outSJtype   " + outSJ.type[0] + '\n' +
1163                       "SOLUTION: use one of the allowed options: --outSJtype   Standard    OR    None\n"
1164                         , std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
1165     };
1166 
1167     if (outFilterType=="Normal") {
1168         outFilterBySJoutStage=0;
1169     } else if (outFilterType=="BySJout") {
1170         if (!outSJ.yes)
1171             exitWithError("EXITING because of FATAL input ERROR: --outFilterType BySJout requires --outSJtype Standard\n"
1172                       "SOLUTION: --outFilterType Normal    OR   --outFilterType BySJout --outSJtype Standard\n"
1173                         , std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
1174 
1175         outFilterBySJoutStage=1;
1176     } else {
1177         ostringstream errOut;
1178         errOut <<"EXITING because of FATAL input ERROR: unknown value of parameter outFilterType: " << outFilterType <<"\n";
1179         errOut <<"SOLUTION: specify one of the allowed values: Normal | BySJout\n";
1180         exitWithError(errOut.str(), std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
1181     };
1182 
1183     ////////////////////////////////////////////////
1184     inOut->logMain << "Finished loading and checking parameters\n" <<flush;
1185 };
1186 
1187 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
scanAllLines(istream & streamIn,int inputLevel,int inputLevelRequested)1188 void Parameters::scanAllLines (istream &streamIn, int inputLevel,  int inputLevelRequested) {//scan
1189 //     istringstream stringInStream (stringIn);
1190     string lineIn;
1191     while (getline(streamIn,lineIn)) {
1192         scanOneLine(lineIn, inputLevel, inputLevelRequested);
1193     };
1194 };
1195 
scanOneLine(string & lineIn,int inputLevel,int inputLevelRequested)1196 int Parameters::scanOneLine (string &lineIn, int inputLevel, int inputLevelRequested) {//scan one line and load the parameters,
1197                                                              //0 if comment, 1 if OK
1198     if (lineIn=="") return 0; //empty line
1199 
1200     istringstream lineInStream (lineIn);
1201 
1202     if (inputLevel==0 && ( lineIn.substr(0,1)==" " || lineIn.substr(0,1)=="\t" ) ) return 0;//for Default input spaces also mark comments, for nice formatting
1203 
1204     string parIn("");
1205     lineInStream >> parIn;
1206     if (parIn=="" || parIn.substr(0,2)=="//" || parIn.substr(0,1)=="#") return 0; //this is a comment
1207 
1208     uint iPar;
1209     for (iPar=0; iPar<parArray.size(); iPar++) {
1210         if (parIn==parArray[iPar]->nameString) {//
1211             if (inputLevelRequested < 0 || inputLevelRequested == parArray[iPar]->inputLevelAllowed) {
1212                 break;//will read this parameter values
1213             } else {
1214                 return 1; //do not read inputs not requested at this level
1215             };
1216         };
1217     };
1218 
1219     string parV("");
1220     lineInStream >> parV;
1221     if (parV=="") {//parameter value cannot be empty
1222         ostringstream errOut;
1223         errOut << "EXITING: FATAL INPUT ERROR: empty value for parameter \""<< parIn << "\" in input \"" << parameterInputName.at(inputLevel) <<"\"\n";
1224         errOut << "SOLUTION: use non-empty value for this parameter\n"<<flush;
1225         exitWithError(errOut.str(), std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
1226     };
1227 
1228     lineInStream.str(lineIn); lineInStream.clear(); lineInStream >> parIn; //get the correct state of stream, past reading parIn
1229 
1230     if (iPar==parArray.size()) {//string is not identified
1231         ostringstream errOut;
1232         errOut << "EXITING: FATAL INPUT ERROR: unrecognized parameter name \""<< parIn << "\" in input \"" << parameterInputName.at(inputLevel) <<"\"\n";
1233         errOut << "SOLUTION: use correct parameter name (check the manual)\n"<<flush;
1234         exitWithError(errOut.str(), std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
1235     } else {//found the corresponding parameter
1236         if (inputLevel==0 && parArray[iPar]->inputLevel>0) {//this is one of the initial parameters, it was read from Command Line and should not be re-defined
1237             getline(lineInStream,parV);
1238             inOut->logMain << setiosflags(ios::left) << setw(PAR_NAME_PRINT_WIDTH) << parArray[iPar]->nameString <<parV<<" ... is RE-DEFINED on Command Line as: " << *(parArray[iPar]) <<"\n";
1239         } else if (parArray[iPar]->inputLevelAllowed>0 && parArray[iPar]->inputLevelAllowed < inputLevel) {//this is initial parameter and cannot be redefined
1240             ostringstream errOut;
1241             errOut << "EXITING: FATAL INPUT ERROR: parameter \""<< parIn << "\" cannot be defined at the input level \"" << parameterInputName.at(inputLevel) << "\"\n";
1242             errOut << "SOLUTION: define parameter \""<< parIn << "\" in \"" << parameterInputName.at(parArray[iPar]->inputLevelAllowed) <<"\"\n" <<flush;
1243             exitWithError(errOut.str(), std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
1244         } else if (parArray[iPar]->inputLevel==inputLevel) {//this parameter was already defined at this input level
1245             ostringstream errOut;
1246             errOut << "EXITING: FATAL INPUT ERROR: duplicate parameter \""<< parIn << "\" in input \"" << parameterInputName.at(inputLevel) << "\"\n";
1247             errOut << "SOLUTION: keep only one definition of input parameters in each input source\n"<<flush;
1248             exitWithError(errOut.str(), std::cerr, inOut->logMain, EXIT_CODE_PARAMETER, *this);
1249         } else {//read values
1250             parArray[iPar]->inputValues(lineInStream);
1251             parArray[iPar]->inputLevel=inputLevel;
1252             if ( inOut->logMain.good() ) {
1253                 inOut->logMain << setiosflags(ios::left) << setw(PAR_NAME_PRINT_WIDTH) << parArray[iPar]->nameString << *(parArray[iPar]);
1254                 if ( parArray[iPar]->inputLevel > 0 ) inOut->logMain <<"     ~RE-DEFINED";
1255                 inOut->logMain << endl;
1256             };
1257         };
1258     };
1259     return 0;
1260 };
1261