import org.apache.commons.cli.*; /* * Class for parsing options passed to program from command line * * Top-level flags: * cells : to make a cell sample file * plate : to make a sample plate file * graph : to make a graph and data file * match : to do a cdr3 matching (WITH OR WITHOUT MAKING A RESULTS FILE. May just want to print summary for piping.) * * Cell flags: * count : number of cells to generate * diversity factor : factor by which CDR3s are more diverse than CDR1s * output : name of the output file * * Plate flags: * cellfile : name of the cell sample file to use as input * wells : the number of wells on the plate * dist : the statistical distribution to use * (if exponential) lambda : the lambda value of the exponential distribution * (if gaussian) stddev : the standard deviation of the gaussian distribution * rand : randomize well populations, take a minimum argument and a maximum argument * populations : number of t cells per well per section (number of arguments determines number of sections) * dropout : plate dropout rate, double from 0.0 to 1.0 * output : name of the output file * * Graph flags: * cellfile : name of the cell sample file to use as input * platefile : name of the sample plate file to use as input * output : name of the output file * * Match flags: * graphFile : name of graph and data file to use as input * min : minimum number of overlap wells to attempt a matching * max : the maximum number of overlap wells to attempt a matching * maxdiff : (optional) the maximum difference in occupancy to attempt a matching * minpercent : (optional) the minimum percent overlap to attempt a matching. * writefile : (optional) the filename to write results to * output : the values to print to System.out for piping * */ public class CommandLineInterface { public static void startCLI(String[] args) { //These command line options are a big mess //Really, I don't think command line tools are expected to work in this many different modes //making cells, making plates, and matching are the sort of thing that UNIX philosophy would say //should be three separate programs. //There might be a way to do it with option parameters? //main options set Options mainOptions = new Options(); Option makeCells = Option.builder("cells") .longOpt("make-cells") .desc("Makes a file of distinct cells") .build(); Option makePlate = Option.builder("plates") .longOpt("make-plates") .desc("Makes a sample plate file") .build(); Option makeGraph = Option.builder("graph") .longOpt("make-graph") .desc("Makes a graph and data file") .build(); Option matchCDR3 = Option.builder("match") .longOpt("match-cdr3") .desc("Match CDR3s. Requires a cell sample file and any number of plate files.") .build(); OptionGroup mainGroup = new OptionGroup(); mainGroup.addOption(makeCells); mainGroup.addOption(makePlate); mainGroup.addOption(makeGraph); mainGroup.addOption(matchCDR3); mainGroup.setRequired(true); mainOptions.addOptionGroup(mainGroup); //Reuse clones of this for other options groups, rather than making it lots of times Option outputFile = Option.builder("o") .longOpt("output-file") .hasArg() .argName("filename") .desc("Name of output file") .build(); mainOptions.addOption(outputFile); //Options cellOptions = new Options(); Option numCells = Option.builder("nc") .longOpt("num-cells") .desc("The number of distinct cells to generate") .hasArg() .argName("number") .build(); mainOptions.addOption(numCells); Option cdr1Freq = Option.builder("d") .longOpt("peptide-diversity-factor") .hasArg() .argName("number") .desc("Number of distinct CDR3s for every CDR1") .build(); mainOptions.addOption(cdr1Freq); //Option cellOutput = (Option) outputFile.clone(); //cellOutput.setRequired(true); //mainOptions.addOption(cellOutput); //Options plateOptions = new Options(); Option inputCells = Option.builder("c") .longOpt("cell-file") .hasArg() .argName("file") .desc("The cell sample file used for filling wells") .build(); mainOptions.addOption(inputCells); Option numWells = Option.builder("w") .longOpt("num-wells") .hasArg() .argName("number") .desc("The number of wells on each plate") .build(); mainOptions.addOption(numWells); Option numPlates = Option.builder("np") .longOpt("num-plates") .hasArg() .argName("number") .desc("The number of plate files to output") .build(); mainOptions.addOption(numPlates); //Option plateOutput = (Option) outputFile.clone(); //plateOutput.setRequired(true); //plateOutput.setDescription("Prefix for plate output filenames"); //mainOptions.addOption(plateOutput); Option plateErr = Option.builder("err") .longOpt("drop-out-rate") .hasArg() .argName("number") .desc("Well drop-out rate. (Probability between 0 and 1)") .build(); mainOptions.addOption(plateErr); Option plateConcentrations = Option.builder("t") .longOpt("t-cells-per-well") .hasArgs() .argName("number 1, number 2, ...") .desc("Number of T cells per well for each plate section") .build(); mainOptions.addOption(plateConcentrations); //different distributions, mutually exclusive OptionGroup plateDistributions = new OptionGroup(); Option plateExp = Option.builder("exponential") .desc("Sample from distinct cells with exponential frequency distribution") .build(); plateDistributions.addOption(plateExp); Option plateGaussian = Option.builder("gaussian") .desc("Sample from distinct cells with gaussain frequency distribution") .build(); plateDistributions.addOption(plateGaussian); Option platePoisson = Option.builder("poisson") .desc("Sample from distinct cells with poisson frequency distribution") .build(); plateDistributions.addOption(platePoisson); mainOptions.addOptionGroup(plateDistributions); Option plateStdDev = Option.builder("stddev") .desc("Standard deviation for gaussian distribution") .hasArg() .argName("number") .build(); mainOptions.addOption(plateStdDev); Option plateLambda = Option.builder("lambda") .desc("Lambda for exponential distribution") .hasArg() .argName("number") .build(); mainOptions.addOption(plateLambda); // // String cellFile, String filename, Double stdDev, // Integer numWells, Integer numSections, // Integer[] concentrations, Double dropOutRate // //Options matchOptions = new Options(); inputCells.setDescription("The cell sample file to be used for matching."); mainOptions.addOption(inputCells); Option lowThresh = Option.builder("low") .longOpt("low-threshold") .hasArg() .argName("number") .desc("Sets the minimum occupancy overlap to attempt matching") .build(); mainOptions.addOption(lowThresh); Option highThresh = Option.builder("high") .longOpt("high-threshold") .hasArg() .argName("number") .desc("Sets the maximum occupancy overlap to attempt matching") .build(); mainOptions.addOption(highThresh); Option occDiff = Option.builder("occdiff") .longOpt("occupancy-difference") .hasArg() .argName("Number") .desc("Maximum difference in alpha/beta occupancy to attempt matching") .build(); mainOptions.addOption(occDiff); Option overlapPer = Option.builder("ovper") .longOpt("overlap-percent") .hasArg() .argName("Percent") .desc("Minimum overlap percent to attempt matching (0 -100)") .build(); mainOptions.addOption(overlapPer); Option inputPlates = Option.builder("p") .longOpt("plate-files") .hasArgs() .desc("Plate files to match") .build(); mainOptions.addOption(inputPlates); CommandLineParser parser = new DefaultParser(); try { CommandLine line = parser.parse(mainOptions, args); if(line.hasOption("match")){ //line = parser.parse(mainOptions, args); //String cellFile = line.getOptionValue("c"); String graphFile = line.getOptionValue("g"); Integer lowThreshold = Integer.valueOf(line.getOptionValue(lowThresh)); Integer highThreshold = Integer.valueOf(line.getOptionValue(highThresh)); Integer occupancyDifference = Integer.valueOf(line.getOptionValue(occDiff)); Integer overlapPercent = Integer.valueOf(line.getOptionValue(overlapPer)); for(String plate: line.getOptionValues("p")) { matchCDR3s(graphFile, lowThreshold, highThreshold, occupancyDifference, overlapPercent); } } else if(line.hasOption("cells")){ //line = parser.parse(mainOptions, args); String filename = line.getOptionValue("o"); Integer numDistCells = Integer.valueOf(line.getOptionValue("nc")); Integer freq = Integer.valueOf(line.getOptionValue("d")); makeCells(filename, numDistCells, freq); } else if(line.hasOption("plates")){ //line = parser.parse(mainOptions, args); String cellFile = line.getOptionValue("c"); String filenamePrefix = line.getOptionValue("o"); Integer numWellsOnPlate = Integer.valueOf(line.getOptionValue("w")); Integer numPlatesToMake = Integer.valueOf(line.getOptionValue("np")); String[] concentrationsToUseString = line.getOptionValues("t"); Integer numSections = concentrationsToUseString.length; Integer[] concentrationsToUse = new Integer[numSections]; for(int i = 0; i