001    package util;
002    
003    import java.io.*;
004    import java.text.DecimalFormat;
005    import java.util.*;
006    
007    /**
008     * A data container to hold the quasar instances from the Hewitt and Burbidge catalog
009     * 1993ApJS...87..451H
010     */
011    public class Quasar implements Star {
012        public static DecimalFormat zFormatter = new DecimalFormat("0.00");
013        public static int count = 0;
014        public static List<Line> allLines = new LinkedList<Line>();  // global line list for all quasars
015    
016        public String name;
017        public String altid;
018        public String ra;
019        public String dec;
020        public String mag;
021        public String zem;
022        public boolean hasEmissionLines = false;
023        protected double zemValue = 0.0;
024        public String refs;
025    
026        List<Line> emissionLines = new LinkedList<Line>();
027    
028        public Quasar() {
029            count++;
030        }
031    
032        public void addFirstRow(String aFirstRow) {
033            if (aFirstRow.length() < 73) {
034                hasEmissionLines = false;
035                return;
036            }
037            name = aFirstRow.substring(0, 8);     // row 1 columns 1-9
038            altid = aFirstRow.substring(10, 20);  // row 1 columns 11-21
039            ra = aFirstRow.substring(35, 46);     // row 1 columns 36-47
040            mag = aFirstRow.substring(48, 66);    // row 1 columns 49-67
041            refs = aFirstRow.substring(92);       // row 1 columns 93-end of line
042            zem = aFirstRow.substring(66, 73);    // row 1 columns 67-74
043            hasEmissionLines = (zem.trim().length() > 0);
044            // Convert zem to numeric value, ends with first non-numeric char or whitespace
045            if (hasEmissionLines) {
046              String zemTemp = zem.substring(1, 6);  // row 1 (value is in col 68-73)
047              if (zemTemp.trim().length() == 0) {
048                hasEmissionLines = false;
049                return;
050              }
051              int parentheses = zemTemp.indexOf(")");
052              if (parentheses > -1) zemTemp = zemTemp.substring(0, parentheses);
053              zemValue = Double.parseDouble(zemTemp);
054              addEmissionLine(aFirstRow);
055              hasEmissionLines = (emissionLines.size() != 0);
056            }
057        }
058    
059        public void addSecondRow(String aSecondRow) {
060            dec = aSecondRow.substring(34, 45);   // row 2 columns 35-46
061            if (hasEmissionLines) addEmissionLine(aSecondRow);
062        }
063    
064        public void addMoreRows(String anotherRow) {
065            if (hasEmissionLines) addEmissionLine(anotherRow);
066        }
067    
068        public double getZem() {
069            return zemValue;
070        }
071        /** Precondition: must have read zem first
072         */
073        protected void addEmissionLine(String aRow) {
074            // Attempt to read emission line if they are tabulated]
075            if (aRow.length() < 80) return;
076            String wavelengthString = aRow.substring(80, 84).trim();  // columns 81-85
077            if (wavelengthString.length() > 0) {
078                double wavelength = Double.parseDouble(wavelengthString);
079                double observedWavelength = shift(wavelength);
080                Line line = new Line(this, observedWavelength);
081                getEmissionLines().add(line);
082                allLines.add(line);
083            }
084        }
085        /** Apply the cosmological redshift of this quasar to convert
086         * rest frame wavelength to the original observed frame wavedlength
087         */
088        protected double shift(double wavelength) {
089            return wavelength * ( 1.0 + getZem());
090        }
091    
092        /** Format similar to Veron's one line per quasar table
093         */
094        public String toString() {
095            String lines = "";
096            String blank = "                                                                                                       ";
097            // 13 entries:  3057.13 3057.13 3057.13 3057.13 3057.13 3057.13 3057.13 3057.13 3057.13 3057.13 3057.13 3057.13 3057.13
098            if (hasEmissionLines) {  // create a concatenated list of emission lines
099                for (Iterator x = getEmissionLines().iterator(); x.hasNext(); ) {
100                    Line line = (Line) x.next();
101                    String wavelengthString = zFormatter.format(line.getWavelength());
102                    if (wavelengthString.length() == 7) wavelengthString = " " + wavelengthString;
103                    lines += wavelengthString;
104                }
105                if (lines.length() > blank.length()) {
106                    lines = lines.substring(0, blank.length());
107                } else {
108                    lines = lines + blank.substring(0, blank.length()-lines.length());
109                }
110            } else {
111                lines = blank;
112            }
113            return name + zem + lines + " " + altid + " " + ra + " " + dec + " " + mag + " " + refs;
114        }
115    
116        public List<Line> getEmissionLines() {
117            return emissionLines;
118        }
119    
120        public List<Line> getAbsorptionLines() {
121            return null;
122        }
123    }
124    
125