1 /*****************************************************************************
2   sortBedMain.cpp
3 
4   (c) 2009 - Aaron Quinlan
5   Hall Laboratory
6   Department of Biochemistry and Molecular Genetics
7   University of Virginia
8   aaronquinlan@gmail.com
9 
10   Licenced under the GNU General Public License 2.0 license.
11 ******************************************************************************/
12 #include "sortBed.h"
13 #include "version.h"
14 
15 using namespace std;
16 
17 // define our program name
18 #define PROGRAM_NAME "bedtools sort"
19 
20 
21 // define our parameter checking macro
22 #define PARAMETER_CHECK(param, paramLen, actualLen) (strncmp(argv[i], param, min(actualLen, paramLen))== 0) && (actualLen == paramLen)
23 
24 // function declarations
25 void sort_help(void);
26 
sort_main(int argc,char * argv[])27 int sort_main(int argc, char* argv[]) {
28 
29     // our configuration variables
30     bool showHelp = false;
31 
32     // input files
33     string bedFile;
34     string faidxFile;
35     bool haveBed    = false;
36     int sortChoices = 0;
37 
38     bool sortBySizeAsc            = false;
39     bool sortBySizeDesc           = false;
40     bool sortByChromThenSizeAsc   = false;
41     bool sortByChromThenSizeDesc  = false;
42     bool sortByChromThenScoreAsc  = false;
43     bool sortByChromThenScoreDesc = false;
44     bool sortByFaidx              = false;
45     bool printHeader        = false;
46 
47     for(int i = 1; i < argc; i++) {
48         int parameterLength = (int)strlen(argv[i]);
49 
50         if((PARAMETER_CHECK("-h", 2, parameterLength)) ||
51         (PARAMETER_CHECK("--help", 5, parameterLength))) {
52             showHelp = true;
53         }
54     }
55 
56     if(showHelp) sort_help();
57 
58     // do some parsing (all of these parameters require 2 strings)
59     for(int i = 1; i < argc; i++) {
60 
61         int parameterLength = (int)strlen(argv[i]);
62 
63         if(PARAMETER_CHECK("-i", 2, parameterLength)) {
64             if ((i+1) < argc) {
65                 bedFile = argv[i + 1];
66                 i++;
67                 haveBed = true;
68             }
69         }
70         else if(PARAMETER_CHECK("-sizeA", 6, parameterLength)) {
71             sortBySizeAsc = true;
72             sortChoices++;
73         }
74         else if(PARAMETER_CHECK("-sizeD", 6, parameterLength)) {
75             sortBySizeDesc = true;
76             sortChoices++;
77         }
78         else if(PARAMETER_CHECK("-chrThenSizeA", 13, parameterLength)) {
79             sortByChromThenSizeAsc = true;
80             sortChoices++;
81         }
82         else if(PARAMETER_CHECK("-chrThenSizeD", 13, parameterLength)) {
83             sortByChromThenSizeDesc = true;
84             sortChoices++;
85         }
86         else if(PARAMETER_CHECK("-chrThenScoreA", 14, parameterLength)) {
87             sortByChromThenScoreAsc = true;
88             sortChoices++;
89         }
90         else if(PARAMETER_CHECK("-chrThenScoreD", 14, parameterLength)) {
91             sortByChromThenScoreDesc = true;
92             sortChoices++;
93         }
94         else if(PARAMETER_CHECK("-faidx", 6, parameterLength)) {
95              if ((i+1) < argc) {
96                 faidxFile = argv[i + 1];
97                 i++;
98            		  }
99            	sortByFaidx = true;
100             sortChoices++;
101         }
102         else if(PARAMETER_CHECK("-g", 2, parameterLength)) {
103              if ((i+1) < argc) {
104                 faidxFile = argv[i + 1];
105                 i++;
106                   }
107             sortByFaidx = true;
108             sortChoices++;
109         }
110         else if(PARAMETER_CHECK("-header", 7, parameterLength)) {
111             printHeader = true;
112         }
113         else {
114             cerr << endl << "*****ERROR: Unrecognized parameter: " << argv[i] << " *****" << endl << endl;
115             showHelp = true;
116         }
117     }
118 
119     // make sure we have input
120     if (!haveBed) {
121         if (!isatty(STDIN_FILENO))
122         {
123             bedFile = "stdin";
124         }
125         else
126         {
127             cerr << endl << "*****" << endl << "*****ERROR: Need -i BED file. " << endl << "*****" << endl;
128             showHelp = true;
129         }
130     }
131     if (sortChoices > 1) {
132         cerr << endl << "*****" << endl << "*****ERROR: Sorting options are mutually exclusive.  Please choose just one. " << endl << "*****" << endl;
133         showHelp = true;
134     }
135 
136 
137     if (!showHelp) {
138         BedSort *bm = new BedSort(bedFile, printHeader,faidxFile);
139 
140         if (sortBySizeAsc) {
141             bm->SortBedBySizeAsc();
142         }
143         else if (sortBySizeDesc) {
144             bm->SortBedBySizeDesc();
145         }
146         else if (sortByChromThenSizeAsc) {
147             bm->SortBedByChromThenSizeAsc();
148         }
149         else if (sortByChromThenSizeDesc) {
150             bm->SortBedByChromThenSizeDesc();
151         }
152         else if (sortByChromThenScoreAsc) {
153             bm->SortBedByChromThenScoreAsc();
154         }
155         else if (sortByChromThenScoreDesc) {
156             bm->SortBedByChromThenScoreDesc();
157         }
158         else if (sortByFaidx) {
159             bm->SortBedOnFaidx();
160         }
161         else {
162             bm->SortBed();
163         }
164         return 0;
165     }
166     else {
167         sort_help();
168     }
169     return 0;
170 }
171 
sort_help(void)172 void sort_help(void) {
173 
174     cerr << "\nTool:    bedtools sort (aka sortBed)" << endl;
175     cerr << "Version: " << VERSION << "\n";
176     cerr << "Summary: Sorts a feature file in various and useful ways." << endl << endl;
177     cerr << "Usage:   " << PROGRAM_NAME << " [OPTIONS] -i <bed/gff/vcf>" << endl << endl;
178 
179     cerr << "Options: " << endl;
180     cerr << "\t" << "-sizeA\t\t\t"    << "Sort by feature size in ascending order." << endl;
181     cerr << "\t" << "-sizeD\t\t\t"    << "Sort by feature size in descending order." << endl;
182     cerr << "\t" << "-chrThenSizeA\t\t"   << "Sort by chrom (asc), then feature size (asc)." << endl;
183     cerr << "\t" << "-chrThenSizeD\t\t"   << "Sort by chrom (asc), then feature size (desc)." << endl;
184     cerr << "\t" << "-chrThenScoreA\t\t"  << "Sort by chrom (asc), then score (asc)." << endl;
185     cerr << "\t" << "-chrThenScoreD\t\t"  << "Sort by chrom (asc), then score (desc)." << endl;
186     cerr << "\t" << "-g (names.txt)\t"    << "Sort according to the chromosomes declared in \"genome.txt\"" << endl;
187     cerr << "\t" << "-faidx (names.txt)\t"  << "Sort according to the chromosomes declared in \"names.txt\"" << endl;
188 
189     cerr << "\t-header\t"       << "Print the header from the A file prior to results." << endl << endl;
190 
191     exit(1);
192 
193 }
194