def read_all_spectra(path, quick=True): """Reads in all the spectra""" if quick: ## Read in pickles labels, spectra = [], [] files = glob( os.path.join(os.path.dirname(__file__), 'all_spectra_pickles', '*.pkl')) ################################################################### ## ## using a smaller set for development, eventually remove the indexing ## ################################################################### for file in files: with open(file, 'rb') as pklfile: l, s = pickle.load(pklfile) if l[0] == 'M' and int(l[1]) <= 8: labels.append(l) spectra.append(s) else: ## Grab files, ignore giants files = glob(os.path.join(path, '*', 'spec-*.fits')) files = np.array([file for file in files if 'Giant' not in file]) ## Create a Spectrum object from PyHammer cwd = os.getcwd() ## Save cwd ## Need to be in PyHammer directory for Spectrum class to function properly os.chdir(os.path.split(os.path.dirname(__file__))[0]) from spectrum import Spectrum spec = Spectrum() labels = [] spectra = [] for file in files: ## Directory is label label = os.path.split(os.path.dirname(file))[1] ## Process spectrum just like in PyHammer message, ftype = spec.readFile(file, filetype='sdssdr12') spec.normalizeFlux() spec.guessSpecType() shift = spec.findRadialVelocity() spec.shiftToRest(shift) spec.interpOntoGrid() labels.append(label) spectra.append(spec.flux) ## Go back to previous directory os.chdir(cwd) return labels, spectra
def main(options): """ The main method of PyHammer which executes the overarching procedure. Description: This is the main part of the code that executes the actual pyhammer algorithms. This is arrived at either by pyhammerStartCmd or PyHammerStartGui, both of which get all the necessary options from the user and pass them to this function. The general process of this function should be to: - Define a Spectrum object to be used in reading files. - Load each spectrum sequentially. - Guess the spectral type. - Use the best guess for the spectral type and find the radial velocity shift. Shift the spectrum to rest. - Guess the spectral type again. - Repeat for all spectra - Bring up eyecheck GUI. Input: options: A dict containing the options the user has specified. Output: This program outputs two files, an outfile and a rejectfile. The outfile contains all results of the spectral type guess as well as the user's eyecheck guess and the rejectfile contains the list of spectra which could not be classified for some reason. """ # Create a Spectrum object spec = Spectrum() # If the user has decided to not skip to the eyecheck, let's # do some processing if not options['eyecheck']: # Open the input file try: infile = open(options['infile'], 'r') except IOError as e: notifyUser(options['useGUI'], str(e)) return # Open and setup the output files outfile = open(options['outfile'], 'w') rejectfile = open(options['rejectfile'], 'w') outfile.write( '#Filename,File Type,Radial Velocity (km/s),Guessed Spectral Type,Guessed [Fe/H],User Spectral Type,User [Fe/H]\n' ) rejectfile.write('#Filename,File Type,Spectra S/N\n') # Define the string to contain all failure messages. These will be compiled # and printed once at the end, if anything is put into it. rejectMessage = '' for i, line in enumerate(infile): # Remove extra whitespace and other unwanted characters and split line = line.strip() if ',' in line: line = line.replace(',', ' ') if ' ' in line: fname, ftype = ' '.join(line.split()).rsplit(' ', 1) else: fname = line ftype = None # Print statement of progress for user print(i + 1, ') Processing ', os.path.basename(fname), sep='') # Now read in the current file (this process reads in the file, converts air to # vac when necessary and interpolates onto the template grid) message, ftype = spec.readFile(options['spectraPath'] + fname, ftype) # If the attempt at reading the file did not succeed, then we # should just continue if message is not None: rejectfile.write(fname + ',' + ('N/A' if ftype is None else ftype) + ',N/A\n') rejectMessage += 'FILE: ' + fname + '\nREASON: ' + message.replace( '\n', '') + '\n\n' continue # Now that we have the necessary data in the spec object, let's # begin processing. # --- 1 --- # Calculate the signal to noise of the spectrum to potentially reject if options['sncut'] is not None: snVal = spec.calcSN() if snVal < options['sncut']: rejectfile.write(fname + ',' + ftype + ',' + str(snVal) + '\n') rejectMessage += 'FILE: ' + fname + '\nREASON: S/N = ' + str( snVal) + ' < ' + str(options['sncut']) + '\n\n' continue # --- 2 --- # Normalize the input spectrum to the same place where the templates are normalized (8000A) spec.normalizeFlux() # --- 3 --- # Call guessSpecType function for the initial guess # this function measures the lines then makes a guess of all parameters spec.guessSpecType() # --- 4 --- # Call findRadialVelocity function using the initial guess shift = spec.findRadialVelocity() # --- 5 --- # Call shiftToRest that shifts the spectrum to rest wavelengths, # then interp back onto the grid spec.shiftToRest(shift) spec.interpOntoGrid() # --- 6 --- # Repeat guessSpecType function to get a better guess of the spectral # type and metallicity spec.guessSpecType() # End of the automatic guessing. We should have: # 1. Spectrum object with observed wavelength, flux, var, # 2. rest wavelength, # 3. spectral type (guessed), # 4. radial velocity and uncertainty, # 5. metallicity estimate, # 6. and line indice measurements # --- 7 --- # Translate the numbered spectral types into letters letterSpt = ['O', 'B', 'A', 'F', 'G', 'K', 'M', 'L'][spec.guess['specType']] # Write the file outfile.write( options['spectraPath'] + fname + ',' + # The spectra path and filename ftype + ',' + # The filetype str(shift) + ',' + # The RV shift letterSpt + str(spec.guess['subType']) + ',' + # The auto-guessed spectral type '{:+2.1f}'.format( spec.guess['metal']) + # The auto-guessed metallicity ',nan,nan\n') # The to-be-determined user classifications # We're done so let's close all the files. infile.close() outfile.close() rejectfile.close() # Check that we processed every spectrum in the infile. If not, print out # the reject method. if rejectMessage != '': # Prepend to the reject message message = 'At least one spectra was rejected. See the details for more information.' notifyUser(options['useGUI'], message, details=rejectMessage) # Check if all spectra were skipped by seeing if the number of # lines in the reject message is equal to the number of processed # times 3 (since each reject message has three newlines). If they # were all skipped, theres nothing to eyecheck so return. if rejectMessage.count('\n') == 3 * (i + 1): notifyUser(options['useGUI'], 'All spectra were bad. Exiting PyHammer.') # Clean up any temporary input files created if os.path.basename(options['infile'])[:11] == 'temp_input_': os.remove(options['infile']) return # At this point, we should call up the GUI to do the eyechecking. Eyecheck(spec, options) # Finally, clean up any temporary input files created if os.path.basename(options['infile'])[:11] == 'temp_input_': os.remove(options['infile'])
def main(options): """ The main method of PyHammer which executes the overarching procedure. Description: This is the main part of the code that executes the actual pyhammer algorithms. This is arrived at either by startCmd or StartGUI, both of which get all the necessary options from the user and pass them to this function. The general process of this function should be to: - Define a Spectrum object to be used in reading files. - Load each spectrum sequentially. - Guess the spectral type. - Use the best guess for the spectral type and find the radial velocity shift. Shift the spectrum to rest. - Guess the spectral type again. - Repeat for all spectra - Bring up eyecheck GUI. Input: options: A dict containing the options the user has specified. Output: This program outputs two files, an outfile and a rejectfile. The outfile contains all results of the spectral type guess as well as the user's eyecheck guess and the rejectfile contains the list of spectra which could not be classified for some reason. """ # Create a Spectrum object spec = Spectrum() # If the user has decided to not skip to the eyecheck, let's # do some processing if not options["eyecheck"]: # Open the input file try: infile = open(options["infile"], "r") except IOError as e: notifyUser(options["useGUI"], str(e)) return # Open and setup the output files outfile = open(options["outfile"], "w") rejectfile = open(options["rejectfile"], "w") outfile.write( "#Filename,Radial Velocity (km/s),Guessed Spectral Type,Guessed [Fe/H],User Spectral Type,User [Fe/H]\n" ) rejectfile.write("#Filename,File Type,Spectra S/N\n") # Define the string to contain all failure messages. These will be compiled # and printed once at the end, if anything is put into it. rejectMessage = "" for i, line in enumerate(infile): # Remove extra whitespace and other unwanted characters and split line = line.strip() if line.find(",") > 0: line = line.replace(",", " ") fname, ftype = " ".join(line.split()).rsplit(" ", 1) # Print statement of progress for user print(i + 1, ") Processing ", os.path.basename(fname), sep="") # Now read in the current file (this process reads in the file, converts air to # vac when necessary and interpolates onto the template grid) success, message = spec.readFile(options["spectraPath"] + fname, ftype) # If the attempt at reading the file did not succeed, then we # should just continue if not success: rejectfile.write(fname + "," + ftype + ",N/A\n") rejectMessage += "FILE: " + fname + " REASON: " + message.replace("\n", "") + "\n" continue # Now that we have the necessary data in the spec object, let's # begin processing. # --- 1 --- # Calculate the signal to noise of the spectrum to potentially reject if options["sncut"] is not None: snVal = spec.calcSN() if snVal < options["sncut"]: rejectfile.write(fname + "," + ftype + "," + str(snVal) + "\n") rejectMessage += ( "FILE: " + fname + " REASON: S/N = " + str(snVal) + " < " + str(options["sncut"]) + "\n" ) continue # --- 2 --- # Normalize the input spectrum to the same place where the templates are normalized (8000A) spec.normalizeFlux() # --- 3 --- # Call guessSpecType function for the initial guess # this function measures the lines then makes a guess of all parameters spec.guessSpecType() # --- 4 --- # Call findRadialVelocity function using the initial guess shift = spec.findRadialVelocity() # --- 5 --- # Call shiftToRest that shifts the spectrum to rest wavelengths, # then interp back onto the grid spec.shiftToRest(shift) spec.interpOntoGrid() # --- 6 --- # Repeat guessSpecType function to get a better guess of the spectral # type and metallicity spec.guessSpecType() # End of the automatic guessing. We should have: # 1. Spectrum object with observed wavelength, flux, var, # 2. rest wavelength, # 3. spectral type (guessed), # 4. radial velocity and uncertainty, # 5. metallicity estimate, # 6. and line indice measurements # --- 7 --- # Translate the numbered spectral types into letters letterSpt = ["O", "B", "A", "F", "G", "K", "M", "L"][spec.guess["specType"]] # Write the file outfile.write( fname + "," + str(shift) + "," + letterSpt + str(spec.guess["subType"]) + "," + "{:+2.1f}".format(spec.guess["metal"]) + ",nan,nan" + "\n" ) # We're done so let's close all the files. infile.close() outfile.close() rejectfile.close() # Check that we processed every spectrum in the infile. If not, print out # the reject method. if rejectMessage != "": # Prepend to the reject message rejectMessage = ( "The following is a list of rejected spectra\n" "along with the reason for its rejection.\n\n" + rejectMessage ) notifyUser(options["useGUI"], rejectMessage) # Check if all spectra were skipped by seeing if the number of # lines in the reject message is equal to the number of spectra # processed (plus three lines for the prepended message). If # they were all skipped, theres nothing to eyecheck so return. if rejectMessage.count("\n") == i + 4: notifyUser(options["useGUI"], "All spectra were bad. Exiting PyHammer.") # Clean up any temporary input files created if os.path.basename(options["infile"])[:11] == "temp_input_": os.remove(options["infile"]) return # At this point, we should call up the GUI to do the eyechecking. Eyecheck(spec, options) # Clean up any temporary input files created if os.path.basename(options["infile"])[:11] == "temp_input_": os.remove(options["infile"])
def main(options): """ main(options) Description: This is the main part of the code that executes the actual pyhammer algorithms. This is arrived at either by startCmd or startGui, both of which get all the necessary options from the user and pass them to this function. The general process of this function should be to: 1) Define a Spectrum object to be used in reading files 2) Call the measureLines() method to find the good lines 3) Run guessSpecType() to get the initial guessed spectral type. 4) Use the best-guess from guessSpecType() and run findRadialVelocity() to find the radial velocity measurements, cross correlate the lines to get the inital spectral type and metallicity guess. Repeat for all spectra 5) Bring up eyecheck GUI. Input: options - A dict containing the options the user can specify. These may already have default values if they were provided on the command line. Output: autoSpTResults.tbl - list of the spectra with the results of the auto spectral typing, radial velocity and metallicity results. """ # If the user has decided to not skip to the eyecheck, let's # do some processing if (not options['eyecheck']): # Open the input file and define a Spectrum object infile = open(options['infile'], 'r') spec = Spectrum() # Open and setup the output files outfile = open(options['outfile'], 'w') rejectfile = open(options['rejectfile'], 'w') outfile.write('Filename\t\tFile Type\t\tSpectra S/N\t\tSpectral Type\n') rejectfile.write('Filename\t\tFile Type\t\tSpectra S/N\n') for line in infile: # Remove extra whitespace and other unwanted characters and split fname, ftype = ' '.join(line.strip().split()).split(' ') # Now read in the current file success = spec.readFile(options['spectraPath']+fname, ftype) # If the attempt at reading the file did not succeed, then we # should just continue if (not success): rejectfile.write(fname + '\t' + ftype + '\tN/A\n') continue # Now that we have the necessary data in the spec object, let's # begin processing. ########################## ### OUTLINE OF PROCESS ### ########################## # Interpolate the observed spectrum to be logarithmically spaced. # Use interpSpec in spectrum class # Call the Spectrum.measureLines() function on the Spectrum object to get # the initial line measurements # Call the guessSpecType function to get an inital guess of the spectral type # Call findRadialVelocity function # Call a Spectrum.shiftToRest() that shifts the spectrum to rest # wavelengths. # Repeat the Spectrum.measurelines() on using the new rest-calibrated # spectrum. # Repeat guessSpecType function to get a better guess of the spectral type # and metallicity # End of the automatic guessing. We should have: # 1) Spectrum object with observed wavelength, flux, noise # 2) rest wavelength # 3) Spectral type (guessed) # 4) radial velocity and uncertainty, # 5) metallicity estimate, # 6) and line indice measurements. # 7) (eventually reddening?) # Write results in autoSpTResults.tbl # (includes spectral type, metallicity and RV measurements) ###################### ### END OF OUTLINE ### ###################### # We're done so let's close all the files for now. infile.close() outfile.close() rejectfile.close() # At this point, we should call up the GUI to do the eyechecking. eyecheck.main()