Exemple #1
0
def fitpix(wave,pararr):
	# define bad pixels
	cfg.bad_pixels = update_bad_pixels() # this variable stores the indices of bad pixels

	ll=pararr[0]
	lz=pararr[3]
	lv1=pararr[5]
	lv2=pararr[6]
	relpix=[]
	for i in range(len(ll)):
		vels=jbg.veltrans(lz[i],wave,ll[i])
		#w1=ll[i]*(1.+lz[i]+lv1[i]/c)
		#w2=ll[i]*(1.+lz[i]+lv2[i]/c)
		#p1=jbg.closest(wave,w1)
		#p2=jbg.closest(wave,w2)
		p1=jbg.closest(vels,lv1[i])
		p2=jbg.closest(vels,lv2[i])

		if ((p1>=10) & (p2<=(len(wave)-1-10))):
			relpix.extend(range(p1-10,p2+10))
		elif (p1<10):
			relpix.extend(range(0, p2 + 10))
		else:
			relpix.extend(range(p1 - 10, len(wave)-1))
	rp = np.unique(np.array(relpix))
	clean_rp = np.array([i for i in rp if i not in cfg.bad_pixels])
	return clean_rp
Exemple #2
0
def fitpix(wave,pararr,find_bad_pixels=True):
	if find_bad_pixels:
		# define bad pixels
		cfg.bad_pixels = update_bad_pixels() # this variable stores the indices of bad pixels
	else:
		cfg.bad_pixels = []
		
	ll=pararr[0]
	lz=pararr[3]
	lv1=pararr[5]
	lv2=pararr[6]
	relpix=[]
	for i in range(len(ll)):
		vels=jbg.veltrans(lz[i],wave,ll[i])
		p1=jbg.closest(vels,lv1[i])
		p2=jbg.closest(vels,lv2[i])

		if ((p1>=10) & (p2<=(len(wave)-1-10))):
			relpix.extend(range(p1-10,p2+10))
		elif (p1<10):
			relpix.extend(range(0, p2 + 10))
		else:
			relpix.extend(range(p1 - 10, len(wave)-1))
	rp = np.unique(np.array(relpix))
	clean_rp = np.array([i for i in rp if i not in cfg.bad_pixels])
	return clean_rp
Exemple #3
0
def fitpix(wave, pararr, find_bad_pixels=True):

    if find_bad_pixels:
        # define bad pixels
        cfg.bad_pixels = update_bad_pixels(
        )  # this variable stores the indices of bad pixels
    else:
        cfg.bad_pixels = []

    ll = pararr[0]
    lz = pararr[3]
    lv1 = pararr[5]
    lv2 = pararr[6]
    relpix = []
    for i in range(len(ll)):
        vels = jbg.veltrans(lz[i], wave, ll[i])
        p1 = jbg.closest(vels, lv1[i])
        p2 = jbg.closest(vels, lv2[i])

        if ((p1 >= 10) & (p2 <= (len(wave) - 1 - 10))):
            relpix.extend(range(p1 - 10, p2 + 10))
        elif (p1 < 10):
            relpix.extend(range(0, p2 + 10))
        else:
            relpix.extend(range(p1 - 10, len(wave) - 1))
    rp = np.unique(np.array(relpix))
    clean_rp = np.array([i for i in rp if i not in cfg.bad_pixels])

    if len(clean_rp) > 1:
        # Matt and Kirill trimming off tiny pixel patches
        max_index_jump = 4  # this is called buf in makevoigt
        min_group_size = 5

        last_idx = clean_rp[0]
        group_idxs = [last_idx]
        really_clean_rp = []
        for idx in clean_rp[1:]:
            jump = idx - last_idx
            if jump <= max_index_jump:
                group_idxs.append(idx)
            else:
                if len(group_idxs) >= min_group_size:
                    really_clean_rp.extend(group_idxs)
                group_idxs = [idx]  # start a new group

            last_idx = idx

        if len(group_idxs) >= min_group_size:
            really_clean_rp.extend(group_idxs)

        return np.array(really_clean_rp, dtype=int)
    else:
        return clean_rp
Exemple #4
0
 def initplot(self,fig,numchunks=8):
     wlen=len(self.spectrum.wavelength)/numchunks
     self.spls=[]
     if self.wave1==None:  waveidx1=0  # Default to plotting entire spectrum for now
     else: waveidx1=jbg.closest(self.wave,self.wave1)
     if self.fitpars!=None:
             model=joebvpfit.voigtfunc(self.wave,self.datamodel.fitpars)
     sg=jbg.subplotgrid(numchunks)
     for i in range(numchunks):
         self.spls.append(fig.add_subplot(sg[i][0],sg[i][1],sg[i][2]))
         pixs=np.arange(waveidx1+i*wlen,waveidx1+(i+1)*wlen, dtype='int')
         self.spls[i].plot(self.wave[pixs],self.normflux[pixs],
                           linestyle='steps-mid',linewidth=cfg.spec_linewidth)
         if self.fitpars!=None:
             self.spls[i].plot(self.wave,model,'r')
         self.spls[i].set_xlim(self.wave[pixs[0]],self.wave[pixs[-1]])
         self.spls[i].set_ylim(cfg.ylim)
         self.spls[i].set_xlabel('wavelength', fontsize=cfg.xy_fontsize,
                                 labelpad=cfg.x_labelpad)
         self.spls[i].set_ylabel('relative flux', fontsize=cfg.xy_fontsize,
                                 labelpad=cfg.y_labelpad)
         self.spls[i].get_xaxis().get_major_formatter().set_scientific(False)
         self.spls[i].tick_params(axis='both', which='major',direction='in',
                                  pad=2,length=2)
     fig.subplots_adjust(top=0.98,bottom=0.05,left=0.08,right=0.97,
                         wspace=0.15,hspace=0.24)
     self.addmpl(fig)
Exemple #5
0
 def initplot(self,fig,numchunks=8):
     wlen=len(self.spectrum.wavelength)/numchunks
     self.spls=[]
     if self.wave1==None:  waveidx1=0  # Default to plotting entire spectrum for now
     else: waveidx1=jbg.closest(self.wave,self.wave1)
     if self.fitpars!=None:
             model=joebvpfit.voigtfunc(self.wave,self.datamodel.fitpars)
     sg=jbg.subplotgrid(numchunks)
     for i in range(numchunks):
         self.spls.append(fig.add_subplot(sg[i][0],sg[i][1],sg[i][2]))
         pixs=range(waveidx1+i*wlen,waveidx1+(i+1)*wlen)
         self.spls[i].plot(self.wave[pixs],self.normflux[pixs],linestyle='steps-mid')
         if self.fitpars!=None:
             self.spls[i].plot(self.wave,model,'r')
         self.spls[i].set_xlim(self.wave[pixs[0]],self.wave[pixs[-1]])
         self.spls[i].set_ylim(cfg.ylim)
         self.spls[i].set_xlabel('wavelength',labelpad=0)
         self.spls[i].set_ylabel('relative flux',labelpad=-5)
         self.spls[i].get_xaxis().get_major_formatter().set_scientific(False)
     fig.subplots_adjust(top=0.98,bottom=0.05,left=0.08,right=0.97,wspace=0.15,hspace=0.25)
     self.addmpl(fig)
Exemple #6
0
    def updateplot(self):
        if self.wave1==None:  waveidx1=0  # Default to plotting entire spectrum for now
        else: waveidx1=jbg.closest(self.wave,self.wave1)
        wlen=len(self.spectrum.wavelength)/self.numchunks
        for i,sp in enumerate(self.spls):
                sp.clear()
                prange=range(waveidx1+i*wlen,waveidx1+(i+1)*wlen)
    
                if ((len(self.fitpars[0])>0)):
    
                    sp.plot(self.wave,self.normflux,linestyle='steps-mid')
                    if self.pixtog==1:
                        sp.plot(self.wave[cfg.fitidx], self.normflux[cfg.fitidx], 'gs', markersize=4, mec='green')
                    model=joebvpfit.voigtfunc(self.wave,self.fitpars)
                    res=self.normflux-model
                    sp.plot(self.wave,model,'r')
                    if self.restog==1:
                        sp.plot(self.wave,-res,'.',color='black', ms=2)
                    sp.plot(self.wave,[0]*len(self.wave),color='gray')
    
                    ### label lines we are trying to fit
                    if self.labeltog==1:
                        for j in range(len(self.fitpars[0])):
                            labelloc=self.fitpars[0][j]*(1.+self.fitpars[3][j])+self.fitpars[4][j]/c*self.fitpars[0][j]*(1.+self.fitpars[3][j])
                            label = ' {:.1f}_\nz{:.4f}'.format(self.fitpars[0][j], self.fitpars[3][j])
                            sp.text(labelloc, cfg.label_ypos, label, rotation=90, withdash=True, ha='center', va='bottom', clip_on=True, fontsize=cfg.label_fontsize)
                
    
                sp.plot(self.wave,self.normsig,linestyle='steps-mid',color='red', lw=0.5)
                sp.plot(self.wave,-self.normsig,linestyle='steps-mid',color='red', lw=0.5)
                sp.set_ylim(cfg.ylim)
                sp.set_xlim(self.wave[prange[0]],self.wave[prange[-1]])
                sp.set_xlabel('wavelength (A)', fontsize=cfg.xy_fontsize, labelpad=cfg.x_labelpad)
                sp.set_ylabel('normalized flux', fontsize=cfg.xy_fontsize, labelpad=cfg.y_labelpad)
                sp.get_xaxis().get_major_formatter().set_scientific(False)
                sp.get_xaxis().get_major_formatter().set_useOffset(False)

        self.changefig(self.fig)
Exemple #7
0
    def updateplot(self):
        if self.wave1==None:  waveidx1=0  # Default to plotting entire spectrum for now
        else: waveidx1=jbg.closest(self.wave,self.wave1)
        wlen=len(self.spectrum.wavelength)/self.numchunks
        for i,sp in enumerate(self.spls):
                sp.clear()
                prange=np.arange(waveidx1+i*wlen,waveidx1+(i+1)*wlen,dtype='int')
                if ((len(self.fitpars[0])>0)):

                    sp.plot(self.wave,self.normflux,linestyle='steps-mid')
                    if self.pixtog==1:
                        sp.plot(self.wave[cfg.fitidx], self.normflux[cfg.fitidx], 'gs', markersize=4, mec='green')
                    model=joebvpfit.voigtfunc(self.wave,self.fitpars)
                    res=self.normflux-model
                    sp.plot(self.wave,model,'r')
                    if self.restog==1:
                        sp.plot(self.wave,-res,'.',color='black', ms=cfg.residual_markersize)
                    sp.plot(self.wave,[0]*len(self.wave),color='gray')

                    ### label lines we are trying to fit
                    if self.labeltog==1:
                        for j in range(len(self.fitpars[0])):
                            labelloc=self.fitpars[0][j]*(1.+self.fitpars[3][j])+self.fitpars[4][j]/c*self.fitpars[0][j]*(1.+self.fitpars[3][j])
                            label = ' {:.1f}_\nz{:.4f}'.format(self.fitpars[0][j], self.fitpars[3][j])
                            sp.text(labelloc, cfg.label_ypos, label, rotation=90, withdash=True, ha='center', va='bottom', clip_on=True, fontsize=cfg.label_fontsize)


                sp.plot(self.wave,self.normsig,linestyle='steps-mid',color='red', lw=0.5)
                sp.plot(self.wave,-self.normsig,linestyle='steps-mid',color='red', lw=0.5)
                sp.set_ylim(cfg.ylim)
                sp.set_xlim(self.wave[prange[0]],self.wave[prange[-1]])
                sp.set_xlabel('wavelength (A)', fontsize=cfg.xy_fontsize, labelpad=cfg.x_labelpad)
                sp.set_ylabel('normalized flux', fontsize=cfg.xy_fontsize, labelpad=cfg.y_labelpad)
                sp.get_xaxis().get_major_formatter().set_scientific(False)
                sp.get_xaxis().get_major_formatter().set_useOffset(False)
        self.changefig(self.fig)
Exemple #8
0
def picksyslines(z, comps):
    ''' Return all lines at a systemic redshift
	'''
    zval = comps['z'][closest(comps['z'], z)]
    zmatches = np.where(np.abs(comps['z'] - zval) < 0.0001)[0]
    return [comps['idxs'][idx] for idx in zmatches]
Exemple #9
0
def writelinepars(fitpars,
                  fiterrors,
                  parinfo,
                  specfile,
                  outfilename,
                  linecmts=None):
    '''
	Write fit parameters out to file.

	Parameters
	----------
	fitpars : list of lists
		Parameters for fit ready for fitter!
	fiterrors : array of numpy vectors
		Error array for the fitting initialized to '0' for each param
	parinfo : array of arrays
		Flags to be used in fit
	specfile : str
		Name of the input file containing the spectrum
	outfilename : str
		Parameter output filename
	linecmts : list of lists, optional
		Reliability flags and comments, e.g., from igmguesses

	'''
    import os
    ### Set outputs and open files
    bigfiletowrite = cfg.largeVPparfile
    filetowrite = outfilename
    if os.path.isfile(filetowrite):
        VPparfile = open(filetowrite, 'wb')
        bigparfile = open(bigfiletowrite, 'ab')  # Append to the running list
    else:
        VPparfile = open(filetowrite, 'wb')
        bigparfile = open(bigfiletowrite, 'wb')

    ### Prep header of line parameter file
    if linecmts is not None:
        header = b'specfile|restwave|zsys|col|sigcol|bval|sigbval|vel|sigvel|nflag|bflag|vflag|vlim1|vlim2|wobs1|wobs2|pix1|pix2|z_comp|trans|rely|comment \n'
    else:
        header = b'specfile|restwave|zsys|col|sigcol|bval|sigbval|vel|sigvel|nflag|bflag|vflag|vlim1|vlim2|wobs1|wobs2|pix1|pix2|z_comp|trans \n'
    VPparfile.write(header)
    bigparfile.write(header)

    ### Grab parameters/info for each line
    for i in range(len(fitpars[0])):
        zline = fitpars[3][i]
        vlim1 = fitpars[5][i]
        vlim2 = fitpars[6][i]
        restwave = fitpars[0][i]
        wobs1 = restwave * (1 + zline + vlim1 / 299792.458)
        wobs2 = restwave * (1 + zline + vlim2 / 299792.458)
        pix1 = jbg.closest(cfg.wave, wobs1)
        pix2 = jbg.closest(cfg.wave, wobs2)
        trans = atomicdata.lam2ion(fitpars[0][i])
        z_comp = ltu.z_from_dv(fitpars[4][i] * u.km / u.s, zline)
        if linecmts is not None:
            towrite = jbg.pipedelimrow([
                specfile, restwave,
                round(zline, 5),
                round(fitpars[1][i], 3),
                round(fiterrors[1][i], 3),
                round(fitpars[2][i], 3),
                round(fiterrors[2][i], 3),
                round(fitpars[4][i], 3),
                round(fiterrors[4][i], 3), parinfo[1][i], parinfo[2][i],
                parinfo[4][i], vlim1, vlim2, wobs1, wobs2, pix1, pix2,
                round(z_comp, 5), trans, linecmts[0][i], linecmts[1][i]
            ])
        else:
            towrite = jbg.pipedelimrow([
                specfile, restwave,
                round(zline, 5),
                round(fitpars[1][i], 3),
                round(fiterrors[1][i], 3),
                round(fitpars[2][i], 3),
                round(fiterrors[2][i], 3),
                round(fitpars[4][i], 3),
                round(fiterrors[4][i], 3), parinfo[1][i], parinfo[2][i],
                parinfo[4][i], vlim1, vlim2, wobs1, wobs2, pix1, pix2,
                round(z_comp, 5), trans
            ])
        VPparfile.write(towrite.encode())
        bigparfile.write(towrite.encode())
    VPparfile.close()
    bigparfile.close()
    print('Line parameters written to:')
    print(filetowrite)
Exemple #10
0
def initlinepars(zs, restwaves, initvals=[], initinfo=[]):
    '''

	Parameters
	----------
	zs : numpy vector of floats
		Redshifts of lines (this parameter will be fixed during fitting)
	restwaves : numpy vector of floats
		Rest frame wavelengths of lines to be fitted
	initvals : list of numpy vectors, optional
		Contains the following (in order): [restwaves,linecol,lineb,zs,linevel,linevlim1,linevlim2]
		Will default to values set in cfg.py if not set
	initinfo : list of numpy vectors, optional
		Contains the flags for fitting (in order): [colflag,bflag,velflag]
		Parameters with flags = 0 and 1 will freely value and fixed, respectively
		If 2 or more lines have the same flag value for the same parameter, the parameters will
			be tied to one another.

	Returns
	-------
	initpars : list of lists
		Parameters for fit ready for fitter!
	parinfo : array of arrays
		Flags to be used in fit
	'''

    ### Set atomic data for each line
    lam, fosc, gam = atomicdata.setatomicdata(restwaves)
    cfg.lams = lam
    cfg.fosc = fosc
    cfg.gam = gam

    initpars = [[], [], [], [], [], [], []]
    defaultcol = cfg.defaultcol
    defaultb = cfg.defaultb
    if initvals == []:
        for i in range(len(restwaves)):
            initpars[0].extend([restwaves[i]])
            initpars[1].extend([defaultcol])
            initpars[2].extend([defaultb])
            initpars[3].extend([zs[i]])
            initpars[4].extend([0.])
            initpars[5].extend([-cfg.defaultvlim])
            initpars[6].extend([cfg.defaultvlim])
    else:
        if len(initvals) == 5:
            for i in range(len(restwaves)):
                initpars[0].extend([initvals[0][i]])
                initpars[1].extend([initvals[1][i]])
                initpars[2].extend([initvals[2][i]])
                initpars[3].extend([initvals[3][i]])
                initpars[4].extend([initvals[4][i]])
                initpars[5].extend([-cfg.defaultvlim])
                initpars[6].extend([cfg.defaultvlim])
        else:
            initpars = [[], [], [], [], [], [], []]
            for i in range(len(restwaves)):
                initpars[0].extend([initvals[0][i]])
                initpars[1].extend([initvals[1][i]])
                initpars[2].extend([initvals[2][i]])
                initpars[3].extend([initvals[3][i]])
                initpars[4].extend([initvals[4][i]])
                initpars[5].extend([initvals[5][i]])
                initpars[6].extend([initvals[6][i]])

    #cfg.lowblim alteration was removed from here

    parinfo = np.zeros([5, len(restwaves)], dtype=int)
    parinfo[0] = parinfo[0] + 1
    parinfo[3] = parinfo[3] + 1
    if ((initinfo == []) & (initvals == [])):

        ### Look for multiplet membership of each line
        seriesassoc = np.zeros(len(restwaves)) - 99
        for i in range(len(restwaves)):
            for j in range(len(cfg.multiplets)):
                currmult = np.array(cfg.multiplets[j])
                if (abs(restwaves[i] -
                        currmult[jbg.closest(currmult, restwaves[i])]) < 0.01):
                    seriesassoc[i] = j

        uqions = np.unique(seriesassoc).tolist()

        if -99 in uqions: uqions.remove(-99)
        flagctr = 2
        for uqion in uqions:
            ionmatch = np.where(seriesassoc == uqion)[0]
            uqzs = np.unique(zs[ionmatch])
            for uz in uqzs:
                matchcrit = (zs == uz) & (seriesassoc == uqion)
                rellines = np.where(matchcrit)[0]
                uqlams = np.unique(restwaves[rellines])
                if len(uqlams) > 1:
                    complist = []
                    numcomps = []
                    for ul in uqlams:
                        matchcrit2 = matchcrit & (restwaves == ul)
                        matches = np.where(matchcrit2)[0]
                        complist.append(matches)
                        numcomps.append(len(matches))
                    numcomps = np.array(numcomps)
                    complist = np.array(complist)
                    compidxsort = sorted(range(len(numcomps)),
                                         key=lambda x: numcomps[x],
                                         reverse=True)
                    numcompsort = numcomps[compidxsort]
                    complistsort = complist[compidxsort]
                    maxcomps = numcompsort[0]
                    for compidx in range(maxcomps):
                        for li in range(len(complistsort)):
                            if compidx < numcompsort[li]:
                                parinfo[1][complistsort[li][compidx]] = flagctr
                                parinfo[2][complistsort[li][compidx]] = flagctr
                                parinfo[4][complistsort[li][compidx]] = flagctr
                            else:
                                continue
                        flagctr += 1

    elif initinfo != []:
        parinfo[1] = initinfo[0]
        parinfo[2] = initinfo[1]
        parinfo[4] = initinfo[2]
    elif ((initinfo == []) & (initvals != [])):

        ### Look for multiplet membership of each line
        seriesassoc = np.zeros(len(restwaves)) - 99
        for i in range(len(restwaves)):
            for j in range(len(cfg.multiplets)):
                currmult = np.array(cfg.multiplets[j])
                if (abs(restwaves[i] -
                        currmult[jbg.closest(currmult, restwaves[i])]) < 0.01):
                    seriesassoc[i] = j

        ### Fix measurements that are imported
        for i in range(len(restwaves)):
            if ((initpars[1][i] != defaultcol) & (initpars[2][i] != defaultb)):
                parinfo[1][i] = 1
                parinfo[2][i] = 1
                parinfo[4][i] = 1
        uqions = np.unique(seriesassoc).tolist()
        if -99 in uqions: uqions.remove(-99)
        flagctr = 2
        for uqion in uqions:
            ionmatch = np.where(seriesassoc == uqion)[0]
            uqzs = np.unique(zs[ionmatch])
            for uz in uqzs:
                matchcrit = (zs == uz) & (seriesassoc == uqion)
                rellines = np.where(matchcrit)[0]
                uqlams = np.unique(restwaves[rellines])
                if len(uqlams) > 1:
                    complist = []
                    numcomps = []
                    for ul in uqlams:
                        matchcrit2 = matchcrit & (restwaves == ul)
                        matches = np.where(matchcrit2)[0]
                        complist.append(matches.tolist())
                        numcomps.append(len(matches))
                    numcomps = np.array(numcomps)
                    complist = np.array(complist)
                    compidxsort = sorted(range(len(numcomps)),
                                         key=lambda x: numcomps[x])
                    complistsort = complist[compidxsort]
                    complistsort = complistsort.tolist()
                    for i in range(len(complistsort) - 1):
                        for idx in complistsort[i]:
                            parinfo[1][idx] = flagctr
                            parinfo[2][idx] = flagctr
                            parinfo[4][idx] = flagctr
                            for j in range(i + 1, len(complistsort)):
                                idxidx = jbg.closest(
                                    initvals[4][complistsort[j]],
                                    initvals[4][idx])
                                clidx = complistsort[j][idxidx]
                                parinfo[1][clidx] = flagctr
                                parinfo[2][clidx] = flagctr
                                parinfo[4][clidx] = flagctr
                                complistsort[j].remove(clidx)
                            flagctr += 1

    return initpars, parinfo
Exemple #11
0
def writelinepars(fitpars,fiterrors,parinfo, specfile, outfilename, linecmts=None):
	'''
	Write fit parameters out to file.

	Parameters
	----------
	fitpars : list of lists
		Parameters for fit ready for fitter!
	fiterrors : array of numpy vectors
		Error array for the fitting initialized to '0' for each param
	parinfo : array of arrays
		Flags to be used in fit
	specfile : str
		Name of the input file containing the spectrum
	outfilename : str
		Parameter output filename
	linecmts : list of lists, optional
		Reliability flags and comments, e.g., from igmguesses

	'''
	import os
	### Set outputs and open files
	bigfiletowrite = cfg.largeVPparfile
	filetowrite = outfilename
	if os.path.isfile(filetowrite):
		VPparfile = open(filetowrite, 'wb')
		bigparfile = open(bigfiletowrite, 'ab') # Append to the running list
	else:
		VPparfile = open(filetowrite, 'wb')
		bigparfile = open(bigfiletowrite, 'wb')

	### Prep header of line parameter file
	if linecmts is not None:
		header = 'specfile|restwave|zsys|col|sigcol|bval|sigbval|vel|sigvel|nflag|bflag|vflag|vlim1|vlim2|wobs1|wobs2|pix1|pix2|z_comp|trans|rely|comment \n'
	else:
		header = 'specfile|restwave|zsys|col|sigcol|bval|sigbval|vel|sigvel|nflag|bflag|vflag|vlim1|vlim2|wobs1|wobs2|pix1|pix2|z_comp|trans \n'
	VPparfile.write(header)
	bigparfile.write(header)

	### Grab parameters/info for each line
	for i in range(len(fitpars[0])):
		zline = fitpars[3][i]
		vlim1 = fitpars[5][i]
		vlim2 = fitpars[6][i]
		restwave = fitpars[0][i]
		wobs1 = restwave * (1 + zline + vlim1 / 299792.458)
		wobs2 = restwave * (1 + zline + vlim2 / 299792.458)
		pix1 = jbg.closest(cfg.wave, wobs1)
		pix2 = jbg.closest(cfg.wave, wobs2)
		trans = atomicdata.lam2ion(fitpars[0][i])
		z_comp = ltu.z_from_dv(fitpars[4][i]*u.km/u.s, zline)
		if linecmts is not None:
			towrite = jbg.pipedelimrow(
				[specfile, restwave, round(zline, 5), round(fitpars[1][i], 3), round(fiterrors[1][i], 3),
				 round(fitpars[2][i], 3), round(fiterrors[2][i], 3), round(fitpars[4][i], 3), round(fiterrors[4][i], 3),
				 parinfo[1][i], parinfo[2][i], parinfo[4][i], vlim1, vlim2, wobs1, wobs2, pix1, pix2,round(z_comp, 5), trans,
				 linecmts[0][i],linecmts[1][i]])
		else:
			towrite = jbg.pipedelimrow(
				[specfile, restwave, round(zline, 5), round(fitpars[1][i], 3), round(fiterrors[1][i], 3),
				 round(fitpars[2][i], 3), round(fiterrors[2][i], 3), round(fitpars[4][i], 3), round(fiterrors[4][i], 3),
				 parinfo[1][i], parinfo[2][i], parinfo[4][i], vlim1, vlim2, wobs1, wobs2, pix1, pix2, round(z_comp, 5),trans])
		VPparfile.write(towrite)
		bigparfile.write(towrite)
	VPparfile.close()
	bigparfile.close()
	print('Line parameters written to:')
	print(filetowrite)
Exemple #12
0
def initlinepars(zs,restwaves,initvals=[],initinfo=[]):
	'''

	Parameters
	----------
	zs : numpy vector of floats
		Redshifts of lines (this parameter will be fixed during fitting)
	restwaves : numpy vector of floats
		Rest frame wavelengths of lines to be fitted
	initvals : list of numpy vectors, optional
		Contains the following (in order): [restwaves,linecol,lineb,zs,linevel,linevlim1,linevlim2]
		Will default to values set in cfg.py if not set
	initinfo : list of numpy vectors, optional
		Contains the flags for fitting (in order): [colflag,bflag,velflag]
		Parameters with flags = 0 and 1 will freely value and fixed, respectively
		If 2 or more lines have the same flag value for the same parameter, the parameters will
			be tied to one another.

	Returns
	-------
	initpars : list of lists
		Parameters for fit ready for fitter!
	parinfo : array of arrays
		Flags to be used in fit
	'''

	### Set atomic data for each line
	lam,fosc,gam=atomicdata.setatomicdata(restwaves)
	cfg.lams=lam ; cfg.fosc=fosc ; cfg.gam=gam

	initpars=[[],[],[],[],[],[],[]]
	defaultcol=cfg.defaultcol
	defaultb=cfg.defaultb
	if initvals==[]:
		for i in range(len(restwaves)):
			initpars[0].extend([restwaves[i]])
			initpars[1].extend([defaultcol])
			initpars[2].extend([defaultb])
			initpars[3].extend([zs[i]])
			initpars[4].extend([0.])
			initpars[5].extend([-cfg.defaultvlim])
			initpars[6].extend([cfg.defaultvlim])
	else:
		if len(initvals)==5:
			for i in range(len(restwaves)):
				initpars[0].extend([initvals[0][i]])
				initpars[1].extend([initvals[1][i]])
				initpars[2].extend([initvals[2][i]])
				initpars[3].extend([initvals[3][i]])
				initpars[4].extend([initvals[4][i]])
				initpars[5].extend([-cfg.defaultvlim])
				initpars[6].extend([cfg.defaultvlim])
		else:
			initpars=[[],[],[],[],[],[],[]]
			for i in range(len(restwaves)):
				initpars[0].extend([initvals[0][i]])
				initpars[1].extend([initvals[1][i]])
				initpars[2].extend([initvals[2][i]])
				initpars[3].extend([initvals[3][i]])
				initpars[4].extend([initvals[4][i]])
				initpars[5].extend([initvals[5][i]])
				initpars[6].extend([initvals[6][i]])

	### If hard limits on Doppler b-value are smaller or greater than cfg.lowblim or cfg.upperblim,
	### modify those limits
	maxb=np.max(initpars[2][:])
	minb=np.min(initpars[2][:])
	if maxb>cfg.upperblim:
		cfg.upperblim= maxb + 10.
	if minb<cfg.lowblim: cfg.lowblim= minb - 2.

	parinfo=np.zeros([5,len(restwaves)],dtype=int)
	parinfo[0]=parinfo[0]+1
	parinfo[3]=parinfo[3]+1
	if ((initinfo==[])&(initvals==[])):

		### Look for multiplet membership of each line
		seriesassoc = np.zeros(len(restwaves)) - 99
		for i in range(len(restwaves)):
			for j in range(len(cfg.multiplets)):
				currmult = np.array(cfg.multiplets[j])
				if (abs(restwaves[i] - currmult[jbg.closest(currmult, restwaves[i])]) < 0.01):
					seriesassoc[i] = j

		uqions=np.unique(seriesassoc).tolist()

		if -99 in uqions: uqions.remove(-99)
		flagctr=2
		for uqion in uqions:
			ionmatch=np.where(seriesassoc == uqion)[0]
			uqzs=np.unique(zs[ionmatch])
			for uz in uqzs:
				matchcrit=(zs==uz)&(seriesassoc==uqion)
				rellines=np.where(matchcrit)[0]
				uqlams=np.unique(restwaves[rellines])
				if len(uqlams)>1:
					complist=[]
					numcomps=[]
					for ul in uqlams:
						matchcrit2=matchcrit&(restwaves==ul)
						matches=np.where(matchcrit2)[0]
						complist.append(matches)
						numcomps.append(len(matches))
					numcomps=np.array(numcomps)
					complist=np.array(complist)
					compidxsort=sorted(range(len(numcomps)),key = lambda x: numcomps[x],reverse=True)
					numcompsort=numcomps[compidxsort]
					complistsort=complist[compidxsort]
					maxcomps=numcompsort[0]
					for compidx in range(maxcomps):
						for li in range(len(complistsort)):
							if compidx<numcompsort[li]:
								parinfo[1][complistsort[li][compidx]]=flagctr
								parinfo[2][complistsort[li][compidx]]=flagctr
								parinfo[4][complistsort[li][compidx]]=flagctr
							else: continue
						flagctr+=1

	elif initinfo!=[]:
		parinfo[1]=initinfo[0]
		parinfo[2]=initinfo[1]
		parinfo[4]=initinfo[2]
	elif ((initinfo==[])&(initvals!=[])):

		### Look for multiplet membership of each line
		seriesassoc = np.zeros(len(restwaves)) - 99
		for i in range(len(restwaves)):
			for j in range(len(cfg.multiplets)):
				currmult = np.array(cfg.multiplets[j])
				if (abs(restwaves[i] - currmult[jbg.closest(currmult, restwaves[i])]) < 0.01):
					seriesassoc[i] = j

		### Fix measurements that are imported
		for i in range(len(restwaves)):
			if ((initpars[1][i]!=defaultcol)&(initpars[2][i]!=defaultb)):
				parinfo[1][i]=1 ; parinfo[2][i]=1 ; parinfo[4][i]=1
		uqions=np.unique(seriesassoc).tolist()
		if -99 in uqions: uqions.remove(-99)
		flagctr=2
		for uqion in uqions:
			ionmatch=np.where(seriesassoc == uqion)[0]
			uqzs=np.unique(zs[ionmatch])
			for uz in uqzs:
				matchcrit=(zs==uz)&(seriesassoc==uqion)
				rellines=np.where(matchcrit)[0]
				uqlams=np.unique(restwaves[rellines])
				if len(uqlams)>1:
					complist=[]
					numcomps=[]
					for ul in uqlams:
						matchcrit2=matchcrit&(restwaves==ul)
						matches=np.where(matchcrit2)[0]
						complist.append(matches.tolist())
						numcomps.append(len(matches))
					numcomps=np.array(numcomps)
					complist=np.array(complist)
					compidxsort=sorted(range(len(numcomps)),key = lambda x: numcomps[x])
					complistsort=complist[compidxsort]
					complistsort=complistsort.tolist()
					for i in range(len(complistsort)-1):
						for idx in complistsort[i]:
							parinfo[1][idx]=flagctr
							parinfo[2][idx]=flagctr
							parinfo[4][idx]=flagctr
							for j in range(i+1,len(complistsort)):
								idxidx=jbg.closest(initvals[4][complistsort[j]],initvals[4][idx])
								clidx=complistsort[j][idxidx]
								parinfo[1][clidx]=flagctr
								parinfo[2][clidx]=flagctr
								parinfo[4][clidx]=flagctr
								complistsort[j].remove(clidx)
							flagctr+=1

	return initpars,parinfo