package org.skymaps;
import java.io.File;
import java.io.FilenameFilter;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Formatter;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.regex.Pattern;
/**
* SkyMapCounter
is a program designed to count the number of
* files (usually sky maps and star subtraction files) associated with
* standard SMEI dates in YYYY_DOY format. The counts are tallied and writted
* to a tabulated text file.
*
* The program has the following call syntax (from a terminal): *
*
* % java -cp /zshare/smei/java/common org.skymaps.SkyMapCounter
* [Options]
*
*
* Note that there may be a BASH alias for this program, such as
* skymapcounter
.
*
* Options
* The following command-line options are allowed:
*
** * @author Jordan T. Vaughan * @version 1.0 */ public class SkyMapCounter { // No $ permitted in Java representations of environment variables. private static final String SMEIDB_ENV_VARIABLE = "SMEIDB"; private static final String SMEISKY0_ENV_VARIABLE = "SMEISKY0"; private static final String DEFAULT_SMEISKY0_PATH = "/sky/"; private static final String DEFAULT_SMEIDB_PATH = "/cat/list/"; private static final String DEFAULT_OUTPUT_FILE = "smei_sky_cnt.txt"; /** * String array of subdirectory names. Each subdirectory in this array * is expected to be in the equ directory (star-subtracted sky map * directory) and in the unprocessed sky map directory. */ public static final String[] SUBDIRECTORIES = { "c1", "c1m0", "c2", "c2m0", "c3", "c3m0" }; private static final String DEST_OPTION = "-dest="; private static final String FILE_OPTION = "-file="; private static final String HELP_OPTION = "-help"; private static final String SRC_OPTION = "-src="; private static final String OUTPUT_HEADER_DESCRIPTION = "Contains counts of sky maps or star subtraction files based on\n" + "SMEI standard dates (YYYY_DOY).\n\n"; private static final String OUTPUT_HEADER_BASE_DIRECTORY = "Base directory for counting: "; private static final String OUTPUT_DATE_FIELD_TITLE = "date"; private static final int OUTPUT_DATE_FIELD_SIZE = 8; private static final int OUTPUT_TALLY_FIELD_SIZE = 5; private static final int OUTPUT_FIELD_SEPARATION_SIZE = 3; /** * The*
*- *
-dest=dest_dir
- This instructs
* *SkyMapCounter
to write the tabulated * tally information to the directorydest_dir
, which must be * a valid path, either absolute or relative, to an existing directory. If * this option is not specified, then the default output directory is *$SMEIDB/cat/list
.- *
-file=filename
- This instructs
* *SkyMapCounter
to name the tabulated * output filefilename
. This must be a valid file name and is * NOT meant to be a path. Iffilename
* already exists in the output directory, then it will be overwritten when *SkyMapCounter
is run (the user will be notified of this on * standard output). If this option is not specified, then the default * filename for the output file issmei_sky_cnt.txt
.- *
-help
- This option makes
* *SkyMapCounter
display a helpful usage * message to the user on standard output.- *
-src=source_dir
- This instructs
*SkyMapCounter
to begin its search in the * subdirectories of the directorysource_dir
, which must be a * valid path, either absolute or relative, to an existing directory. * The subdirectories that are searched within this directory are (in order) *c1
,c1m0
,c2
,c2m0
, *c3
, andc3m0
. If one of the subdirectories * cannot be located within the given search directory, then the user is * notified on standard output and the subdirectory is skipped. If this * option is not specified, then the default base search directory is *$SMEISKY0/sky
.
SkyMapCounter
program begins here. The command line
* options are processed before the sky map search and comparison
* algorithms are run.
*
* @param args the command line options parsed as an array of Strings.
* @since 1.0
*/
public static void main(String[] args) {
// Relevant local variables.
File baseDirectory = null;
File destinationFile = null;
String destinationFileName = null;
TreeMap-help
option was specified by the user.
*
* @since 1.0
*/
public static void printUsageMessage() {
System.out.println(
"\nUsage:\n % java SkyMapCounter [Options]\n\n" +
"Options:\n" +
" -src=source_dir Specifies which directory to start " +
"the search in.\n" +
" The subdirectories c1, c1m0, c2, c2m0, " +
"c3, and c3m0\n" +
" should be locted in source_dir.\n" +
" [default=$" + SMEISKY0_ENV_VARIABLE +
DEFAULT_SMEISKY0_PATH + "]\n" +
" -dest=dest_dir Specifies which directory to write the " +
"list file\n" +
" to when the counts are tallied.\n" +
" [default=$" +
SMEIDB_ENV_VARIABLE + DEFAULT_SMEIDB_PATH + "]\n" +
" -file=filename The name of the output file that will " +
"contain the sky map\n" +
" counts. This is not a path.\n" +
" [default=" + DEFAULT_OUTPUT_FILE + "]\n" +
" -help Displays this usage message to standard" +
" output.\n\n" +
"Examples:\n" +
" % java SkyMapCounter\n" +
" Counts sky map files in the subdirectories of $" +
SMEISKY0_ENV_VARIABLE + DEFAULT_SMEISKY0_PATH + "\n" +
" and outputs the count results to $" + SMEIDB_ENV_VARIABLE +
DEFAULT_SMEIDB_PATH + DEFAULT_OUTPUT_FILE + " (the\n" +
" default output file).\n" +
" % java SkyMapCounter -help\n" +
" Displays this helpful usage message and exits.\n" +
" % java SkyMapCounter -file=list_name.txt\n" +
" Counts sky map files in the subdirectories of the default "+
"source directory\n" +
" and writes the results to the file list_name.txt in the\n" +
" default output directory.\n" +
" % java SkyMapCounter -src=$SMEISKY0/equ -dest=$SMEIDB/fakedir"+
" -file=test.txt\n" +
" Counts sky map files in the subdirectories of $SMEISKY0/" +
"equ and outputs\n" +
" the count results to $SMEIDB/fakedir/test.txt.\n\n");
}
/* Class used to filter sky map files. This can be used flexibly to filter
* ANY file, regardless of extensions and prefixes, based on the standard
* SMEI date.
*/
private static class SkyMapFilenameFilter implements FilenameFilter {
public SkyMapFilenameFilter() { }
public boolean accept(File dir, String name) {
if(Pattern.matches("(.*)\\d\\d\\d\\d_\\d\\d\\d_\\d\\d\\d\\d\\d\\d"+
"(.*)", name)) {
return true;
}
return false;
}
public static String extractDate(String filename) {
// Does the given file name even have a SMEI date in it?
if(!new SkyMapFilenameFilter().accept(null, filename)) {
return null;
}
// Go through the file name linearly and find the date.
int index = 0;
for(int counter = 0; counter < filename.length(); counter++) {
if(Character.isDigit(filename.charAt(counter))) {
// Start the extraction index afresh.
index = counter;
counter++;
// Find the other digits.
boolean continueExtraction = true;
for(int subcounter = 0; subcounter < 3; subcounter++) {
if(!Character.isDigit(filename.charAt(counter))) {
continueExtraction = false;
break;
}
counter++;
}
if(!continueExtraction) {
counter = index;
continue;
}
if(filename.charAt(counter) != '_') {
counter = index;
continue;
}
counter++;
for(int subcounter = 0; subcounter < 3; subcounter++) {
if(!Character.isDigit(filename.charAt(counter))) {
continueExtraction = false;
break;
}
counter++;
}
if(!continueExtraction) {
counter = index;
continue;
}
// Extract the substring and return it.
return filename.substring(index, counter);
}
}
// No date found. This shouldn't happen.
System.err.println("ERROR: SkyMapFilenameFilter.extractDate " +
"encountered an internal error and returned null.");
return null;
}
}
}