import nom.tam.fits.*;
import nom.tam.util.*;

import java.io.*;
import java.util.*;
import java.text.*;

public class MapSpeedTool {
    public static String version = "3 March 2005";
    public static String fileName = "mappingspeed.dat";

    public static void main(String[] args) {
	try {
	    versionInfo();
	    if(args.length == 0) usage();

	    ReducedData reduced = new ReducedData();

	    for(int i=0; i<args.length; i++) {
		if(isOption(args[i])) option(args[i]);
		else reduced.read(args[i]);
	    }

	    final double arcsec = Unit.ArcSECOND;

	    File file = new File(fileName);
	    boolean isNew = !file.exists();
	    RandomAccessFile outFile = new RandomAccessFile(file, "rw");

	    if(isNew) {
		String header = "Date\t\tScan\tName\t\ttau225\tM-Speed\tNEFD\tSky"; 
		
		outFile.writeBytes("! SHARC2 Map Speed File\n");
		outFile.writeBytes("! Created by Crush " + Crush.version + "\n");
		outFile.writeBytes("!\n");
		outFile.writeBytes("! tau225 is quoted in the line of sight\n");
		outFile.writeBytes("! MapSpeed has units of deg^2 / (Jy/beam)^2 / hr\n");
		outFile.writeBytes("! NEFD has units Jy s^1/2 / beam\n");
		outFile.writeBytes("! Sky is RMS variance of detectors in nV/sqrt(min)\n");
		outFile.writeBytes("!\n");
		outFile.writeBytes("! " + header + "\n");
	    }
	    
	    outFile.seek(outFile.length());

	    SharcScan scan = reduced.scan[0];

	    StringTokenizer dateTokens = new StringTokenizer(scan.date, "-:T");

	    int year = Integer.parseInt(dateTokens.nextToken());
	    int month = Integer.parseInt(dateTokens.nextToken());
	    int day = Integer.parseInt(dateTokens.nextToken());
	    int hour = Integer.parseInt(dateTokens.nextToken());
	    int min = Integer.parseInt(dateTokens.nextToken());
	    double sec = Double.parseDouble(dateTokens.nextToken());
	    
	    reduced.convolveTo(9.0 * Unit.ArcSECOND);
	    ReductionTool.beamFWHM = 9.0 * Unit.ArcSECOND;
	    reduced.init();

	    // These numbers are using 7.98 nV / Jy scaling.
	    // The mean Sept. 2004 scaling
	    // reduced.scale(1.44);
	    // An estimate of the Sep. 2004 good focus scaling
	    // reduced.scale(1.30);

	    double pixelArea = reduced.delta * reduced.delta;
	    
	    double nepd = 0.0;
	    int n=0;
	    for(int i=0; i<reduced.sizeX; i++) for(int j=0; j<reduced.sizeY; j++) if(reduced.flag[i][j] == 0) {
		double I = reduced.clean[i][j] / reduced.janskyPerBeam.value;
		double t = reduced.count[i][j];

		nepd += I * I * t;
		
		n++;
	    }	    
	    nepd *= reduced.scan[0].pixelArea / pixelArea / n;

	    double speed = n > 0 ? reduced.scan[0].activePixels * reduced.scan[0].pixelArea / nepd : 0.0;
	    double nefd = Math.sqrt(nepd);

	    // Cast into final units
	    speed /= 3600.0 * Unit.ArcMINUTE * Unit.ArcMINUTE / Unit.HOUR;
	    nefd /= Math.sqrt(Unit.SECOND);

	    DecimalFormat f3 = new DecimalFormat("0.000");
	    DecimalFormat e3 = new DecimalFormat("0.000E0");

	    System.out.println("Mapping Speed is " + f3.format(speed) + " deg^2 / hr / (Jy/beam)^2.");
	    System.out.println("NEFD is " + f3.format(nefd) + " Jy s^1.2 / beam.");

	    String info = 
		year + "-" +
		month + "-" +		
		day + " \t" +

		scan.serialNo + "\t" +

		scan.sourceName + (scan.sourceName.length() <= 7 ? "\t\t" : "\t") +

		f3.format(ReductionTool.getTau("225GHz", scan.tau)/Math.sin(scan.EL)) + "\t" +

		f3.format(speed) + "\t" +
		
		f3.format(nefd) + "\t";
		    

	    try { info += e3.format(reduced.header.getDoubleValue("COR_RMS") / 1.0e-9
				    / Math.sqrt(reduced.scan[0].frames * reduced.scan[0].samplingInterval / Unit.MINUTE)); }
	    catch(Exception e) { info += "NaN"; }
	    
	    info += "\n";

	    outFile.writeBytes(info);
	    outFile.close();
	}
	   
	      
	catch(Exception e) { e.printStackTrace(); }
    }

    public static void option(String optionString) {
	StringTokenizer tokens = new StringTokenizer(optionString, "=,");

	String key = tokens.nextToken();

	//options.add(optionString);
	
	if(key.equalsIgnoreCase("-out")) fileName = tokens.nextToken();

	else if(key.equalsIgnoreCase("-help")) usage();

	else System.out.println("WARNING! Unrecognized option: " + key);
    
    }

    public static boolean isOption(String argument) {
	return argument.charAt(0) == '-';
    }
    
    public static void versionInfo() {
	System.out.println("mapspeed -- Mapping Speed Tool for SHARC2");
	System.out.println("            Author: Attila Kovacs <attila@submm.caltech.edu>");
	System.out.println("            Version: " + version);
	System.out.println();
    }
    
    public static void usage() {
	Crush.versionInfo();
	System.out.println("usage: mapspeed [options] <image>");
	System.out.println();
	System.out.println("    Appends mapping speed data from the image to \'" + fileName + "\'.");
	System.out.println("    If the file does not exist, it will be created.");
	System.out.println();
	System.out.println("options:");
	System.out.println();
	System.out.println("    <image>    The FITS image file to process.");
	System.out.println("    -out=      The output file name (" + fileName + ")");
	System.out.println("    -help      Shows this help screen.");
	
			   
	System.out.println();
	
	System.exit(0);
    }
    
}


