001 package util; 002 003 import java.text.DecimalFormat; 004 import org.eso.fits.*; 005 import java.lang.*; 006 import java.util.*; 007 import java.io.*; 008 009 import javax.swing.*; 010 import ui.recognizer.PlotFileFilter; 011 012 /** Convert FITS from 2QZ format to one or more text files 013 * @version 1.0 Oct 17 2003 014 * @author John Talbot 015 */ 016 public class ConvertFits2qz { 017 /** Static method for converting FITS to text files. 018 * 019 * @param argv array of arguments i.e. FITS files 020 */ 021 022 /** 023 *group of pixels | has number of pixels | one or more 024 * continuous range of pixels | is a kind of | group of pixels 025 * continuous range of pixels | has definition | A kind of group of pixels which are continuous 026 * continuous range of pixels | has lower bound | given as an integer or wavelength 027 * continuous range of pixels | has upper bound | given as an integer or wavelength 028 * hole | is a kind of | continuous range of pixels 029 * hole | has definition | A kind of continuous range of pixels with intensity value equal to -200 030 * hole | has intensity value | -200 031 * hole | is dealt with using the procedure | which depends the range of the hole 032 * leading hole | is a kind of | hole 033 * leading hole | has definition | A kind of hole located at the beginning of the pixel array 034 * leading hole | has lower bound | beginning of the pixel array 035 * leading hole | has upper bound | a given pixel 036 * leading hole | is dealt with using the procedure | truncate the spectra range up to the first non-hole value 037 * trailing hole | is a kind of | hole 038 * trailing hole | has definition | A kind of hole located at the end of the pixel array 039 * trailing hole | has lower bound | a given pixel 040 * trailing hole | has upper bound | end of the pixel array 041 * trailing hole | is dealt with using the procedure | truncate the spectra range down to the last non-hole value 042 * internal hole | is a kind of | hole 043 * internal hole | has definition | A kind of hole located within the non-hole pixel array 044 * internal hole | has lower bound | a given pixel 045 * internal hole | has upper bound | a higher pixel location than the lower bound 046 * internal hole | is dealt with using the procedure | linear interpolation between the first non-hole value below lower bound and the first non-hole value above the upper bound 047 */ 048 public static final double HOLE = -199; // should be -200 but some values are like -199.9999 049 050 /** truncate spectra range to non-hole values and only export non-hole intensities */ 051 public static final boolean SKIP_HOLES = true; 052 053 /** interpolate between the lower and upper bound of internal holes */ 054 public static final boolean INTERPOLATE_INTERNAL_HOLES = true; 055 056 public static void main(String[] argv) { 057 058 if (argv.length < 1) { 059 javax.swing.filechooser.FileFilter filter = new PlotFileFilter("FITS Files", new String[] {"fits", "fit"}); 060 061 JFileChooser loadFileChooser = new JFileChooser(); 062 loadFileChooser.setDialogTitle("Convert FITS files or directory"); 063 loadFileChooser.setCurrentDirectory(new File(".")); 064 loadFileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); 065 loadFileChooser.addChoosableFileFilter(filter); 066 loadFileChooser.setFileFilter(filter); 067 068 JFrame f = new JFrame("Convert FITS files or directory"); 069 070 f.setSize(300, 150); 071 f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 072 f.pack(); 073 f.setVisible(true); 074 075 File file = null; 076 if (loadFileChooser.showOpenDialog(f) == JFileChooser.APPROVE_OPTION) { // BUG: 'up' icon in file chooser is disabled 077 file = loadFileChooser.getSelectedFile(); 078 } 079 convertFiles(file); 080 } else { 081 for (int na = 0; na < argv.length; na++) { 082 convertFiles(new File(argv[na])); 083 } 084 } 085 //TODO: handle command line arguments for (int na=0; na<argv.length; na++) { 086 System.exit(0); 087 } 088 089 // Handle recursive directories 090 public static void convertFiles(File aFile) { 091 if (aFile == null) 092 return; 093 else if (aFile.isDirectory()) { // if File is a directory then process all files in that directory 094 System.out.println("Dir : " + aFile); 095 File[] files = aFile.listFiles(); 096 for (int i = 0 ; i < files.length; i++) { 097 convertFiles(files[i]); 098 } 099 } else { 100 convertFile(aFile); 101 } 102 } 103 104 public static void convertFile(File aFile) { 105 DecimalFormat xFormatter = new DecimalFormat("0.000"); 106 DecimalFormat yFormatter = new DecimalFormat("0.000"); 107 FitsFile file = null; 108 try { 109 file = new FitsFile(aFile); 110 String name = aFile.getName(); 111 int noHDU = file.getNoHDUnits(); 112 for (int i = 0; i < 1; i++) { 113 FitsHDUnit hdu = file.getHDUnit(i); 114 FitsHeader hdr = hdu.getHeader(); 115 int noKw = hdr.getNoKeywords(); 116 int type = hdr.getType(); 117 int size = (int) hdr.getDataSize(); 118 String fileName = name.split("fits")[0] + "txt"; 119 FileWriter writer = new FileWriter(fileName); 120 System.out.println("Creating spectra " + fileName); 121 Enumeration enumeration = hdr.getKeywords(); 122 while (enumeration.hasMoreElements()) { 123 FitsKeyword kw = (FitsKeyword) enumeration.nextElement(); 124 writer.write("#" + kw.getName()); 125 switch (kw.getType()) { 126 case FitsKeyword.COMMENT: 127 writer.write("(C) " + kw.getComment()); 128 break; 129 case FitsKeyword.STRING: 130 writer.write("(S)= '" + kw.getString() + "'"); 131 break; 132 case FitsKeyword.BOOLEAN: 133 writer.write("(B)= " + kw.getBool()); 134 break; 135 case FitsKeyword.INTEGER: 136 writer.write("(I)= " + kw.getInt()); 137 break; 138 case FitsKeyword.REAL: 139 writer.write("(R)= " + kw.getReal()); 140 break; 141 case FitsKeyword.DATE: 142 writer.write("(D)= " + kw.getString()); 143 break; 144 default: 145 } 146 if (0<kw.getComment().length() && (kw.getType()!=FitsKeyword.COMMENT)) { 147 writer.write(" / " + kw.getComment()); 148 } 149 writer.write("\n"); 150 } 151 if (type == Fits.IMAGE) { 152 FitsMatrix dm = (FitsMatrix) hdu.getData(); 153 int naxis[] = dm.getNaxis(); 154 double crval[] = dm.getCrval(); 155 double crpix[] = dm.getCrpix(); 156 double cdelt[] = dm.getCdelt(); 157 int nv, off, npix; 158 int nval = dm.getNoValues(); 159 if (0 < nval) { 160 int ncol = naxis[0]; 161 int nrow = nval/ncol; 162 float data[] = new float[ncol]; 163 off = 0; 164 nrow = 1; // Only get first row 165 for (int nr = 0; nr < nrow; nr++) { 166 try { 167 dm.getFloatValues(off, ncol, data); 168 if (INTERPOLATE_INTERNAL_HOLES) { // linear interpolation internal holes 169 boolean firstHole = true; 170 boolean inHole = false; 171 int hole_start = 0; 172 int hole_end = 0; 173 for (int n = 0; n < ncol; n++) { 174 double val = data[n]; 175 if (firstHole && val < HOLE) // ignore leading hole 176 continue; 177 else 178 firstHole = false; 179 180 if (!inHole && val < HOLE) { 181 inHole = true; 182 hole_start = n - 1; 183 } else if(inHole && val > HOLE) { 184 inHole = false; 185 hole_end = n; 186 if (hole_end != ncol - 1) { // ignore trailing hole 187 // linear interpolation of this instance of internal hole 188 double x1 = (double) hole_start; 189 double x2 = (double) hole_end; 190 double y1 = data[hole_start]; 191 double y2 = data[hole_end]; 192 double slope = (y2-y1)/(x2-x1); 193 for (int j = 1; j < hole_end - hole_start; j++) { 194 data[hole_start + j] = (float) (slope*((double)j) + y1); 195 } 196 } 197 } 198 199 } 200 } 201 202 // wavelength computation verified with FV fits viewer 203 FitsKeyword kw = hdr.getKeyword("CD1_1"); 204 double deltaWavelength = kw.getReal(); //cdelt[0]; 205 double startWavelength = crval[0] - (crpix[0]-1)*deltaWavelength; 206 for (int n = 0; n < ncol; n++) { 207 double val = data[n]; 208 // avoid floating point truncation error by not using wavelength += deltaWavelength 209 double wavelength = startWavelength + n*deltaWavelength; 210 // don't export leading hole and trailing hole (truncate spectra range) 211 if (!SKIP_HOLES || val > HOLE) { 212 StringBuffer s = new StringBuffer(xFormatter.format(wavelength)); 213 s.append(" "); 214 String y = yFormatter.format(val); 215 s.append(y); 216 s.append("\n"); 217 writer.write(s.toString()); 218 } 219 } 220 } catch (FitsException e) { 221 } 222 off += ncol; 223 } 224 } 225 } 226 if (writer != null) writer.close(); 227 228 229 230 231 } 232 if (file != null) file.closeFile(); 233 } catch (FitsException e) { 234 System.out.println("Error: is not a FITS file >" + aFile + "<"); 235 return; 236 } catch (IOException e) { 237 System.out.println("Error: cannot open file >" + aFile + "<"); 238 return; 239 } 240 } 241 }