def handle_create(outname=None, filelist=[], plot_filt=False): """Create standard star correction. Units are erg/s/cm2/Ang Read in the std-correction vector for each standard star, massage the correction (see below) and output an ensemble correction. Args: outname (str): name for resulting correction array (def: atm-corr.npy) filelist (list): list of standard star extractions (e.g. sp_STD-\*.npy) plot_filt (bool): set to plot intermediate filtered steps (def: False) Returns: dict: A dictionary containing the ensemble correction and some details:: { "nm": wavelengths (nm), "maxnm": maximum wavelength, "correction": the correction spectrum, "doc": "Correct ph/10 m/nm to erg/s/cm2/ang", "Nspec": number of spectra used, "correction_std": STDev of ensemble corrections, "outname": outname (see Parameters), "files": filelist (see Parameters), "when": timestamp string, "user": user who ran the process } Note: Writes a \*.npy file with the resulting correction """ if outname is None: outname = 'atm-corr.npy' ll = Wavelength.fiducial_spectrum() corrs = [] corr_vals = [] legend = [ "corr", ] filt_legend = ["orig"] maxnm = 915. for ifile in filelist: """ Filename is sp_STD-nnnnn_obs*.npy """ # Try to read input file try: data = np.load(ifile)[0] except: raise Exception("Not able to load %s. " % ifile) # Check quality of extraction if data["quality"] > 0: print "Bad std extraction in %s" % ifile continue # Check for calculated correction if "std-correction" not in data.keys(): print "No std-correction vector in %s" % ifile continue correction = data['std-correction'] # What was the maximum wavelength? if "std-maxnm" in data.keys(): if data['std-maxnm'] > maxnm: maxnm = data['std-maxnm'] # Convert file named sp_STD-nnnn_obs* to a name compaitable # with Standards.py. First strip of "sp_STD-" pred = ifile[7:] pred = pred.split("_")[0] legend.append(pred) pred = pred.lower().replace("+", "").replace("-", "_") print ifile, pred, pred in Stds.Standards # Are we in our list of standard stars? if pred not in Stds.Standards: print( "File named '%s' is reduced to '%s' and no such standard " "seems to exist." % (ifile, pred)) continue # Record median correction in ROI roi = (ll > 600) & (ll < 850) corr_vals.append(np.median(correction[roi])) # Normalize each correction by the median value correction /= corr_vals[-1] corrs.append(correction) # END: for ifile in filelist: # Rescale each correction and scale to erg/s/cm2/Ang corrs = np.array(corrs) erg_s_cm2_ang = corrs * np.median(corr_vals) * 1e-16 # Take the median of the correction vectors the_corr = scipy.stats.nanmedian(erg_s_cm2_ang, 0) # Fit red end unless we are calibrated out there if not np.isfinite(the_corr).all() and maxnm < 1000.0: print "Fitting red end" # Fit polynomial to extrapolate correction redend = (ll > 880) & (ll < maxnm) ss = np.poly1d(np.polyfit(ll[redend], the_corr[redend], 2)) # Insert extrapolation back into correction vector redend = (ll > maxnm) the_corr[redend] = ss(ll[redend]) # Plot data, if requested if plot_filt: pl.figure(2) pl.clf() pl.grid(True) pl.ylim(1e-20, 1e-15) pl.semilogy(ll, the_corr, linewidth=1) pl.xlabel("Wavelength [nm]") pl.ylabel("Correction [erg/s/cm cm/Ang]") pl.title("Correct ph/10 m/nm to erg/s/cm2/Ang") """ # Now clean over the Balmer series (skip this for now) balmers = [656.3, 486.1, 434.0, 410.2, 397.0] #balmers = [656.3, 486.1, 434.0] for balmer in balmers: #pl.figure(3) line_ROI = sets.Set(np.where(np.abs((ll-balmer)/balmer) < 0.01)[0]) broad_ROI = sets.Set(np.where(np.abs((ll-balmer)/balmer) < 0.04)[0]) broad_ll = list(broad_ROI) broad_ll.sort() #pl.plot(ll[broad_ll], the_corr[broad_ll]) around_line_ROI = list(broad_ROI - line_ROI) #pl.plot(ll[around_line_ROI], the_corr[around_line_ROI],'^') fit = np.poly1d(np.polyfit(ll[around_line_ROI], the_corr[around_line_ROI], 5)) to_fix = list(line_ROI) #the_corr[to_fix] = fit(ll[to_fix]) #pl.plot(ll[to_fix], the_corr[to_fix]) #pl.show() """ # Plot intermediate correction if plot_filt: pl.semilogy(ll, the_corr * 4., linewidth=2) filt_legend.append("Balmer*4") # Filter correction to remove spectral features and leave response alone the_corr = scipy.signal.savgol_filter(the_corr, 9, 5) # Plot intermediate correction if plot_filt: pl.semilogy(ll, the_corr * 2., linewidth=2) filt_legend.append("Filtered*2") pl.semilogy(ll, the_corr, linewidth=2) filt_legend.append("Filtered") pl.legend(filt_legend) pl.show() # Plot data pl.figure(1) pl.clf() pl.grid(True) pl.ylim(1e-20, 1e-15) pl.semilogy(ll, the_corr, linewidth=4) for ix, e in enumerate(erg_s_cm2_ang): pl.semilogy(ll, e * corr_vals[ix] / np.mean(corr_vals)) pl.xlabel("Wavelength [nm]") pl.ylabel("Correction [erg/s/cm cm/Ang]") pl.title("Correct ph/10 m/nm to erg/s/cm2/Ang") pl.legend(legend) with warnings.catch_warnings(): warnings.simplefilter("ignore", category=RuntimeWarning) pl.savefig("Standard_Correction.pdf") print("Mean cor: %10.3g, Sigma cor: %10.3g" % (np.mean(corr_vals) * 1e-16, np.std(corr_vals) * 1e-16)) maxnm = np.min([maxnm, np.max(ll)]) print "Max nm: %7.2f" % maxnm # Construct result with warnings.catch_warnings(): warnings.simplefilter("ignore", category=RuntimeWarning) res = { "nm": ll, "maxnm": maxnm, "correction": the_corr, "doc": "Correct ph/10 m/nm to erg/s/cm2/ang", "Nspec": len(corrs), "correction_std": np.nanstd(erg_s_cm2_ang, 0), "outname": outname, "files": filelist, "when": '%s' % datetime.datetime.now(), "user": os.getlogin() } np.save(outname, [res]) return res
def handle_create(outname=None, filelist=[]): ''' Create standard star correction. Units are erg/s/cm2/Ang ''' if outname is None: outname = 'atm-corr.npy' ll = Wavelength.fiducial_spectrum() spectra = [] corrs = [] corr_vals = [] for file in filelist: ''' Filename is STD-nnnnn_obs* ''' try: data = np.load(file)[0] except: raise Exception( "Not passed a spectrum file, the file should start with spectrum_" ) # Convert file named sp_STD-nnnn_obs* to a name compaitable # with Standards.py pred = file.lstrip("spectrum_STD-") pred = pred.lstrip("sp_STD-") pred = pred.split("_")[0] pred = pred.lower().replace("+", "").replace("-", "_") print file, pred, pred in SS.Standards if pred not in SS.Standards: print "File named '%s' is reduced to '%s' and no such standard seems to exist." % ( file, pred) continue ff = interp1d(data['nm'], data['ph_10m_nm'], bounds_error=False) spectra.append(ff(ll)) # Now process the standard standard = SS.Standards[pred] wav = standard[:, 0] / 10.0 flux = standard[:, 1] std_ff = interp1d(wav, flux, bounds_error=False, fill_value=np.nan) correction = std_ff(ll) / ff(ll) ROI = (ll > 600) & (ll < 850) corr_vals.append(np.median(correction[ROI])) correction /= corr_vals[-1] corrs.append(correction) corrs = np.array(corrs) erg_s_cm2_ang = corrs * np.median(corr_vals) * 1e-16 roi = (ll > 900) & (ll < 1000) the_corr = scipy.stats.nanmedian(erg_s_cm2_ang, 0) if not np.isfinite(the_corr).all(): # Fit polynomial to extrapolate correction redend = (ll > 800) & (ll < 915) ss = np.poly1d(np.polyfit(ll[redend], the_corr[redend], 2)) redend = (ll > 910) the_corr[redend] = ss(ll[redend]) # Now clean over the Balmer series balmers = [656.3, 486.1, 434.0, 410.2, 397.0] for balmer in balmers: eps = balmer * 0.02 line_ROI = sets.Set(np.where(np.abs((ll - balmer) / balmer) < 0.03)[0]) broad_ROI = sets.Set( np.where(np.abs((ll - balmer) / balmer) < 0.06)[0]) around_line_ROI = list(broad_ROI - line_ROI) fit = np.poly1d( np.polyfit(ll[around_line_ROI], the_corr[around_line_ROI], 1)) to_fix = list(line_ROI) the_corr[to_fix] = fit(ll[to_fix]) the_corr = scipy.signal.savgol_filter(the_corr, 3, 1) # Plot data pl.figure(1) pl.clf() pl.grid(True) pl.ylim(1e-20, 1e-15) pl.semilogy(ll, the_corr, linewidth=4) for ix, e in enumerate(erg_s_cm2_ang): pl.semilogy(ll, e * corr_vals[ix] / np.mean(corr_vals)) pl.xlabel("Wavelength [nm]") pl.ylabel("Correction [erg/s/cm cm/Ang]") pl.title("Correct ph/10 m/nm to erg/s/cm2/Ang") pl.savefig("Standard_Correction.pdf") print np.mean(corr_vals) * 1e-16, np.std(corr_vals) * 1e-16 # Construct result res = { "nm": ll, "correction": the_corr, "doc": "Correct ph/10 m/nm to erg/2/cm2/ang", "Nspec": len(corrs), "correction_std": np.nanstd(erg_s_cm2_ang, 0), "outname": outname, "files": filelist, "when": '%s' % datetime.datetime.now(), "user": os.getlogin() } np.save(outname, [res]) return res
def handle_create(outname=None, filelist=[], plot_filt=False): """Create standard star correction. Units are erg/s/cm2/Ang Read in the std-correction vector for each standard star, massage the correction (see below) and output an ensemble correction. Args: outname (str): name for resulting correction array (def: atm-corr.npy) filelist (list): list of standard star extractions (e.g. sp_STD-\*.npy) plot_filt (bool): set to plot intermediate filtered steps (def: False) Returns: dict: A dictionary containing the ensemble correction and some details:: { "nm": wavelengths (nm), "maxnm": maximum wavelength, "correction": the correction spectrum, "doc": "Correct ph/10 m/nm to erg/s/cm2/ang", "Nspec": number of spectra used, "correction_std": STDev of ensemble corrections, "outname": outname (see Parameters), "files": filelist (see Parameters), "when": timestamp string, "user": user who ran the process } Note: Writes a \*.npy file with the resulting correction """ if outname is None: outname = 'atm-corr.npy' ll = Wavelength.fiducial_spectrum() corrs = [] corr_vals = [] legend = ["corr", ] filt_legend = ["orig"] maxnm = 915. for ifile in filelist: """ Filename is sp_STD-nnnnn_obs*.npy """ # Try to read input file try: data = np.load(ifile)[0] except: raise Exception("Not able to load %s. " % ifile) # Check quality of extraction if data["quality"] > 0: print "Bad std extraction in %s" % ifile continue # Check for calculated correction if "std-correction" not in data.keys(): print "No std-correction vector in %s" % ifile continue correction = data['std-correction'] # What was the maximum wavelength? if "std-maxnm" in data.keys(): if data['std-maxnm'] > maxnm: maxnm = data['std-maxnm'] # Convert file named sp_STD-nnnn_obs* to a name compaitable # with Standards.py. First strip of "sp_STD-" pred = ifile[7:] pred = pred.split("_")[0] legend.append(pred) pred = pred.lower().replace("+", "").replace("-", "_") print ifile, pred, pred in Stds.Standards # Are we in our list of standard stars? if pred not in Stds.Standards: print("File named '%s' is reduced to '%s' and no such standard " "seems to exist." % (ifile, pred)) continue # Record median correction in ROI roi = (ll > 600) & (ll < 850) corr_vals.append(np.median(correction[roi])) # Normalize each correction by the median value correction /= corr_vals[-1] corrs.append(correction) # END: for ifile in filelist: # Rescale each correction and scale to erg/s/cm2/Ang corrs = np.array(corrs) erg_s_cm2_ang = corrs * np.median(corr_vals) * 1e-16 # Take the median of the correction vectors the_corr = scipy.stats.nanmedian(erg_s_cm2_ang, 0) # Fit red end unless we are calibrated out there if not np.isfinite(the_corr).all() and maxnm < 1000.0: print "Fitting red end" # Fit polynomial to extrapolate correction redend = (ll > 880) & (ll < maxnm) ss = np.poly1d(np.polyfit(ll[redend], the_corr[redend], 2)) # Insert extrapolation back into correction vector redend = (ll > maxnm) the_corr[redend] = ss(ll[redend]) # Plot data, if requested if plot_filt: pl.figure(2) pl.clf() pl.grid(True) pl.ylim(1e-20, 1e-15) pl.semilogy(ll, the_corr, linewidth=1) pl.xlabel("Wavelength [nm]") pl.ylabel("Correction [erg/s/cm cm/Ang]") pl.title("Correct ph/10 m/nm to erg/s/cm2/Ang") """ # Now clean over the Balmer series (skip this for now) balmers = [656.3, 486.1, 434.0, 410.2, 397.0] #balmers = [656.3, 486.1, 434.0] for balmer in balmers: #pl.figure(3) line_ROI = sets.Set(np.where(np.abs((ll-balmer)/balmer) < 0.01)[0]) broad_ROI = sets.Set(np.where(np.abs((ll-balmer)/balmer) < 0.04)[0]) broad_ll = list(broad_ROI) broad_ll.sort() #pl.plot(ll[broad_ll], the_corr[broad_ll]) around_line_ROI = list(broad_ROI - line_ROI) #pl.plot(ll[around_line_ROI], the_corr[around_line_ROI],'^') fit = np.poly1d(np.polyfit(ll[around_line_ROI], the_corr[around_line_ROI], 5)) to_fix = list(line_ROI) #the_corr[to_fix] = fit(ll[to_fix]) #pl.plot(ll[to_fix], the_corr[to_fix]) #pl.show() """ # Plot intermediate correction if plot_filt: pl.semilogy(ll, the_corr * 4., linewidth=2) filt_legend.append("Balmer*4") # Filter correction to remove spectral features and leave response alone the_corr = scipy.signal.savgol_filter(the_corr, 9, 5) # Plot intermediate correction if plot_filt: pl.semilogy(ll, the_corr * 2., linewidth=2) filt_legend.append("Filtered*2") pl.semilogy(ll, the_corr, linewidth=2) filt_legend.append("Filtered") pl.legend(filt_legend) pl.show() # Plot data pl.figure(1) pl.clf() pl.grid(True) pl.ylim(1e-20, 1e-15) pl.semilogy(ll, the_corr, linewidth=4) for ix, e in enumerate(erg_s_cm2_ang): pl.semilogy(ll, e * corr_vals[ix] / np.mean(corr_vals)) pl.xlabel("Wavelength [nm]") pl.ylabel("Correction [erg/s/cm cm/Ang]") pl.title("Correct ph/10 m/nm to erg/s/cm2/Ang") pl.legend(legend) with warnings.catch_warnings(): warnings.simplefilter("ignore", category=RuntimeWarning) pl.savefig("Standard_Correction.pdf") print("Mean cor: %10.3g, Sigma cor: %10.3g" % (np.mean(corr_vals) * 1e-16, np.std(corr_vals) * 1e-16)) maxnm = np.min([maxnm, np.max(ll)]) print "Max nm: %7.2f" % maxnm # Construct result with warnings.catch_warnings(): warnings.simplefilter("ignore", category=RuntimeWarning) res = { "nm": ll, "maxnm": maxnm, "correction": the_corr, "doc": "Correct ph/10 m/nm to erg/s/cm2/ang", "Nspec": len(corrs), "correction_std": np.nanstd(erg_s_cm2_ang, 0), "outname": outname, "files": filelist, "when": '%s' % datetime.datetime.now(), "user": os.getlogin() } np.save(outname, [res]) return res
def handle_create(outname=None, filelist=[]): ''' Create standard star correction. Units are erg/s/cm2/Ang ''' if outname is None: outname='atm-corr.npy' ll = Wavelength.fiducial_spectrum() spectra = [] corrs = [] corr_vals =[] for file in filelist: ''' Filename is STD-nnnnn_obs* ''' try: data = np.load(file)[0] except: raise Exception("Not passed a spectrum file, the file should start with spectrum_") # Convert file named sp_STD-nnnn_obs* to a name compaitable # with Standards.py pred = file.lstrip("spectrum_STD-") pred = pred.lstrip("sp_STD-") pred = pred.split("_")[0] pred = pred.lower().replace("+","").replace("-","_") print file, pred, pred in SS.Standards if pred not in SS.Standards: print "File named '%s' is reduced to '%s' and no such standard seems to exist." % (file, pred) continue ff = interp1d(data['nm'], data['ph_10m_nm'], bounds_error=False) spectra.append(ff(ll)) # Now process the standard standard = SS.Standards[pred] wav = standard[:,0]/10.0 flux = standard[:,1] std_ff = interp1d(wav, flux, bounds_error=False, fill_value=np.nan) correction = std_ff(ll)/ff(ll) ROI = (ll > 600) & (ll < 850) corr_vals.append(np.median(correction[ROI])) correction /= corr_vals[-1] corrs.append(correction) corrs = np.array(corrs) erg_s_cm2_ang = corrs * np.median(corr_vals) * 1e-16 roi = (ll > 900) & (ll < 1000) the_corr = scipy.stats.nanmedian(erg_s_cm2_ang,0) if not np.isfinite(the_corr).all(): # Fit polynomial to extrapolate correction redend = (ll > 800) & (ll < 915) ss = np.poly1d(np.polyfit(ll[redend], the_corr[redend], 2)) redend = (ll>910) the_corr[redend] = ss(ll[redend]) # Now clean over the Balmer series balmers = [656.3, 486.1, 434.0, 410.2, 397.0] for balmer in balmers: eps = balmer * 0.02 line_ROI = sets.Set(np.where(np.abs((ll-balmer)/balmer) < 0.03)[0]) broad_ROI = sets.Set(np.where(np.abs((ll-balmer)/balmer) < 0.06)[0]) around_line_ROI = list(broad_ROI - line_ROI) fit = np.poly1d(np.polyfit(ll[around_line_ROI], the_corr[around_line_ROI], 1)) to_fix = list(line_ROI) the_corr[to_fix] = fit(ll[to_fix]) the_corr = scipy.signal.savgol_filter(the_corr, 3, 1) # Plot data pl.figure(1) pl.clf() pl.grid(True) pl.ylim(1e-20,1e-15) pl.semilogy(ll, the_corr, linewidth=4) for ix,e in enumerate(erg_s_cm2_ang): pl.semilogy(ll, e*corr_vals[ix]/np.mean(corr_vals)) pl.xlabel("Wavelength [nm]") pl.ylabel("Correction [erg/s/cm cm/Ang]") pl.title("Correct ph/10 m/nm to erg/s/cm2/Ang") pl.savefig("Standard_Correction.pdf") print np.mean(corr_vals) * 1e-16, np.std(corr_vals)*1e-16 # Construct result res = {"nm": ll, "correction": the_corr, "doc": "Correct ph/10 m/nm to erg/2/cm2/ang", "Nspec": len(corrs), "correction_std": np.nanstd(erg_s_cm2_ang,0), "outname": outname, "files": filelist, "when": '%s' % datetime.datetime.now(), "user": os.getlogin() } np.save(outname, [res]) return res
def handle_create(outname=None, filelist=[], plot_filt=False): ''' Create standard star correction. Units are erg/s/cm2/Ang ''' if outname is None: outname='atm-corr.npy' ll = Wavelength.fiducial_spectrum() corrs = [] corr_vals =[] legend=["corr",] filt_legend=["orig"] maxnm = 915. for file in filelist: ''' Filename is sp_STD-nnnnn_obs*.npy ''' # Try to read input file try: data = np.load(file)[0] except: raise Exception("Not passed a spectrum file, the file should start with sp_") # Check for calculated correction if "std-correction" not in data.keys(): print "No std-correction vector in %s" % file continue correction = data['std-correction'] # What was the maximum wavelength? if "std-maxnm" in data.keys(): if data['std-maxnm'] > maxnm: maxnm = data['std-maxnm'] # Convert file named sp_STD-nnnn_obs* to a name compaitable # with Standards.py pred = file.lstrip("sp_STD-") pred = pred.split("_")[0] legend.append(pred) pred = pred.lower().replace("+","").replace("-","_") print file, pred, pred in SS.Standards if pred not in SS.Standards: print "File named '%s' is reduced to '%s' and no such standard seems to exist." % (file, pred) continue # Record median correction in ROI ROI = (ll > 600) & (ll < 850) corr_vals.append(np.median(correction[ROI])) # Normalize each correction by the median value correction /= corr_vals[-1] corrs.append(correction) # END: for file in filelist: # Rescale each correction and scale to erg/s/cm2/Ang corrs = np.array(corrs) erg_s_cm2_ang = corrs * np.median(corr_vals) * 1e-16 # Take the median of the correction vectors the_corr = scipy.stats.nanmedian(erg_s_cm2_ang,0) # Fit red end unless we are calibrated out there if not np.isfinite(the_corr).all() and maxnm < 1000.0: print "Fitting red end" # Fit polynomial to extrapolate correction redend = (ll > 880) & (ll < maxnm) ss = np.poly1d(np.polyfit(ll[redend], the_corr[redend], 2)) redend = (ll>maxnm) the_corr[redend] = ss(ll[redend]) # Plot data, if requested if plot_filt: pl.figure(2) pl.clf() pl.grid(True) pl.ylim(1e-20,1e-15) pl.semilogy(ll, the_corr, linewidth=1) pl.xlabel("Wavelength [nm]") pl.ylabel("Correction [erg/s/cm cm/Ang]") pl.title("Correct ph/10 m/nm to erg/s/cm2/Ang") ''' # Now clean over the Balmer series (skip this for now) balmers = [656.3, 486.1, 434.0, 410.2, 397.0] #balmers = [656.3, 486.1, 434.0] for balmer in balmers: #pl.figure(3) line_ROI = sets.Set(np.where(np.abs((ll-balmer)/balmer) < 0.01)[0]) broad_ROI = sets.Set(np.where(np.abs((ll-balmer)/balmer) < 0.04)[0]) broad_ll = list(broad_ROI) broad_ll.sort() #pl.plot(ll[broad_ll], the_corr[broad_ll]) around_line_ROI = list(broad_ROI - line_ROI) #pl.plot(ll[around_line_ROI], the_corr[around_line_ROI],'^') fit = np.poly1d(np.polyfit(ll[around_line_ROI], the_corr[around_line_ROI], 5)) to_fix = list(line_ROI) #the_corr[to_fix] = fit(ll[to_fix]) #pl.plot(ll[to_fix], the_corr[to_fix]) #pl.show() ''' if plot_filt: pl.semilogy(ll, the_corr*4., linewidth=2) filt_legend.append("Balmer*4") # Filter correction to remove spectral features and leave response alone the_corr = scipy.signal.savgol_filter(the_corr, 9, 5) if plot_filt: pl.semilogy(ll, the_corr*2., linewidth=2) filt_legend.append("Filtered*2") pl.semilogy(ll, the_corr, linewidth=2) filt_legend.append("Filtered") pl.legend(filt_legend) pl.show() # Plot data pl.figure(1) pl.clf() pl.grid(True) pl.ylim(1e-20,1e-15) pl.semilogy(ll, the_corr, linewidth=4) for ix,e in enumerate(erg_s_cm2_ang): pl.semilogy(ll, e*corr_vals[ix]/np.mean(corr_vals)) pl.xlabel("Wavelength [nm]") pl.ylabel("Correction [erg/s/cm cm/Ang]") pl.title("Correct ph/10 m/nm to erg/s/cm2/Ang") pl.legend(legend) with warnings.catch_warnings(): warnings.simplefilter("ignore", category=RuntimeWarning) pl.savefig("Standard_Correction.pdf") print "Mean cor: %10.3g, Sigma cor: %10.3g" % (np.mean(corr_vals) * 1e-16, np.std(corr_vals)*1e-16) maxnm = np.min([maxnm,np.max(ll)]) print "Max nm: %7.2f" % maxnm # Construct result with warnings.catch_warnings(): warnings.simplefilter("ignore", category=RuntimeWarning) res = {"nm": ll, "maxnm": maxnm, "correction": the_corr, "doc": "Correct ph/10 m/nm to erg/2/cm2/ang", "Nspec": len(corrs), "correction_std": np.nanstd(erg_s_cm2_ang,0), "outname": outname, "files": filelist, "when": '%s' % datetime.datetime.now(), "user": os.getlogin() } np.save(outname, [res]) return res