def getone(self): """ Method to get the next result from the query Parameters ---------- None Returns ------- LineData object containing the transition data """ res = self.cursor.fetchone() if self.ishfs: return LineData(frequency=res[0], transition=res[1], linestrength=res[2], energies=[res[3], res[4]]) formula = str(res[0]) return LineData(formula=formula, name=str(res[1]), frequency=res[2], uid=utils.getplain(formula) + "_%.5f" % res[2], energies=[res[5], res[6]], linestrength=res[4], mass=utils.getmass(formula), transition=str(res[3]), plain=utils.getplain(formula), isocount=utils.isotopecount(formula), hfnum=res[7])
def getall(self): """ Method to get all rows from the table as a list of LineData objects Parameters ---------- None Returns ------- List of LineData objects, one for each row in the table. """ planes = self.getSpectraNames() tempspec = None if len(planes) > 0: tempspec = self.getSpectrum(planes[0]) rows = [] for i in range(len(self)): row = self.table.getRow(i) ld = LineData( name=row[self.table.columns.index("name")], uid=row[self.table.columns.index("uid")], transition=row[self.table.columns.index("transition")], energies=[ row[self.table.columns.index("El")], row[self.table.columns.index("Eu")] ], linestrength=float( row[self.table.columns.index("linestrength")]), frequency=float(row[self.table.columns.index("frequency")]), blend=int(row[self.table.columns.index("blend")]), chans=[ row[self.table.columns.index("startchan")], row[self.table.columns.index("endchan")] ], formula=row[self.table.columns.index("formula")], velocity=row[self.table.columns.index("velocity")], peakintensity=row[self.table.columns.index("peakintensity")], peakoffset=row[self.table.columns.index("peakoffset")], fwhm=row[self.table.columns.index("fwhm")], peakrms=row[self.table.columns.index("peakrms")], force=row[self.table.columns.index("force")]) if tempspec is not None: frqs = [ tempspec.getfreq( row[self.table.columns.index("startchan")]), tempspec.getfreq(row[self.table.columns.index("endchan")]) ] frqs.sort() ld.setkey("freqs", frqs) rows.append(ld) return rows
def linedatafromsegments(freq, chan, segments, specs, statspec=None): """ Common method used by LineSegment_AT and LineID_AT to construct LineData from an input list of segments. Parameters ---------- freq : array like The global frequency axis of the input segments chan : array like The global channel axis of the input segments segments: array like The input segments, as returned from e.g. mergesegments specs : Spectrum Array of spectra or single spectrum statspec : Spectrum Optional Cubestats spectrum Returns -------- List of LineData objects constructed from input segments """ lines = [] for ch in segments: for i in range(len(chan)): if chan[i] >= ch[0]: break mn = i for i in range(len(chan) - 1, -1, -1): if chan[i] <= ch[1]: break mx = i frq = [min(freq[mn], freq[mx]), max(freq[mn], freq[mx])] mid = (frq[0] + frq[1]) / 2.0 if statspec != None and len(statspec) != 0: peak, ratio, fwhm = getinfo(ch, statspec) else: peak, ratio, fwhm = getinfo(ch, specs) lname = "U_%.3f" % mid linedata = LineData.LineData(frequency=float(mid), uid=lname, formula="NotIdentified", name="Not Identified", plain="N/A", peakintensity=float(peak), fwhm=float(fwhm), chans=[ch[0], ch[1]], peakrms=float(ratio)) lines.append(linedata) return lines
def getall(self): """ Method to get all rows from the table as a list of LineData objects Parameters ---------- None Returns ------- List of LineData objects, one for each row in the table. """ planes = self.getSpectraNames() tempspec = None if len(planes) > 0: tempspec = self.getSpectrum(planes[0]) rows = [] for i in range(len(self)): row = self.table.getRow(i) ld = LineData(name=row[self.table.columns.index("name")], uid=row[self.table.columns.index("uid")], transition=row[self.table.columns.index("transition")], energies=[row[self.table.columns.index("El")], row[self.table.columns.index("Eu")]], linestrength=float(row[self.table.columns.index("linestrength")]), frequency=float(row[self.table.columns.index("frequency")]), blend=int(row[self.table.columns.index("blend")]), chans=[row[self.table.columns.index("startchan")], row[self.table.columns.index("endchan")]], formula=row[self.table.columns.index("formula")], velocity=row[self.table.columns.index("velocity")], peakintensity=row[self.table.columns.index("peakintensity")], peakoffset=row[self.table.columns.index("peakoffset")], fwhm=row[self.table.columns.index("fwhm")], peakrms=row[self.table.columns.index("peakrms")], force=row[self.table.columns.index("force")]) if tempspec is not None: frqs = [tempspec.getfreq(row[self.table.columns.index("startchan")]), tempspec.getfreq(row[self.table.columns.index("endchan")])] frqs.sort() ld.setkey("freqs", frqs) rows.append(ld) return rows
def getall(self): """ Method to get all results from the query Parameters ---------- None Returns ------- List of LineData objects, one for each transition """ results = self.cursor.fetchall() output = [] if self.ishfs: for res in results: output.append( LineData(frequency=res[0], transition=str(res[1]), linestrength=res[2], energies=[res[3], res[4]])) else: for res in results: formula = str(res[0]) output.append( LineData(formula=formula, name=str(res[1]), frequency=res[2], uid=utils.getplain(formula) + "_%.5f" % res[2], energies=[res[5], res[6]], linestrength=res[4], mass=utils.getmass(formula), transition=str(res[3]), plain=utils.getplain(formula), isocount=utils.isotopecount(formula), hfnum=res[7])) return output
def splatalogue(self, minfreq, maxfreq, rrlevelstr, allowExotics): """ Method to search through the slsearch database. Search options must already have been set. Returns a formatted list of transitions, each item in the list is another list containing the following: #. Chemical formula #. Name #. Rest frequency #. Unique identifier #. Lower state energy in K #. Upper state energy in K #. Linestrength in D^2 #. Mass of molecule (rough) #. Transition quantum numbers #. Cleanly formatted chemical formula for display purposes #. Number of non-standard isotopes in the molecule Parameters ---------- rrlevelstr : str String representation of how deep to search for recombination lines. Possibilities are: + `off` no recombination lines are allowed in the results. + `shallow` only H and He, alpha and beta lines are allowed in the results. + `deep` any recombination line is allowed in the results. allowExotics : bool Whether or not to allow exotic atoms in the molecules (e.g Ti) Returns ------- A list of LineData objects, with each containing the data for a single transition. """ possible = [] # initialize the interface class sp = Splatalogue.Splatalogue(**self.sp_kw) # do the search results = sp.query_lines(minfreq, maxfreq) # get the results lines = results.readlines() # the top row is the column headings as one long string # split the string into its individual components header = lines[0].split(":") # the indexes of the data are not guaranteed, so search for each needed one # by its known name, if splatalogue changes the column headings this will # break sidx = header.index("Species") cidx = header.index("Chemical Name") fidx = header.index("Freq-GHz") bfidx = header.index("Meas Freq-GHz") qidx = header.index("Resolved QNs") stidx = header.index( "S<sub>ij</sub>μ<sup>2</sup> (D<sup>2</sup>)") elidx = header.index("E_L (K)") euidx = header.index("E_U (K)") # remove the header row so the rest can be iterated over del lines[0] # make sure all of the indexes are found if min(sidx, cidx, fidx, qidx, stidx, elidx, euidx, bfidx) < 0: raise Exception("Missing data") # need a better message # iterate over all the results for line in lines: # sploit into columns row = line.split(":") # see which frequency we have, prefering the 'Freq-GHz' column if not row[fidx]: freq = float(row[bfidx]) else: freq = float(row[fidx]) # process the result, dropping if needed if not utils.isexotic(row[sidx] or allowExotics): if (not "RECOMBINATION" in row[cidx].upper() \ or ("RECOMBINATION" in row[cidx].upper() and (rrlevelstr == "DEEP" or ("H" in row[sidx] \ and ("alpha" in row[sidx] or "beta" in row[sidx]))))) \ and not self.checktier1overlap(row[fidx]): possible.append( LineData( formula=row[sidx], name=row[cidx], frequency=freq, uid=utils.getplain(row[sidx]) + "_%.5f" % freq, energies=[float(row[elidx]), float(row[euidx])], linestrength=float(row[stidx]), mass=utils.getmass(row[sidx]), transition=row[qidx], plain=utils.getplain(row[sidx]), isocount=utils.isotopecount(row[sidx]))) return possible
def slsearch(self, rrlevelstr, allowExotics): """ Method to search through the slsearch database. Search options must already have been set. Returns a formatted list of transitions, each item in the list is another list containing the following: #. Chemical formula #. Name #. Rest frequency #. Unique identifier #. Lower state energy in K #. Upper state energy in K #. Linestrength in D^2 #. Mass of molecule (rough) #. Transition quantum numbers #. Cleanly formatted chemical formula for display purposes #. Number of non-standard isotopes in the molecule Parameters ---------- rrlevelstr : str String representation of how deep to search for recombination lines. Possibilities are: + `off` no recombination lines are allowed in the results. + `shallow` only H and He, alpha and beta lines are allowed in the results. + `deep` any recombination line is allowed in the results. allowExotics : bool Whether or not to allow exotic atoms in the molecules (e.g Ti) Returns ------- A list of LineData objects, with each containing the data for a single transition. """ try: from slsearch import slsearch import taskinit except: logging.info( "WARNING: No CASA, slsearch is not available, no line identificaiton possible." ) raise if "outfile" not in self.sls_kw: # @todo should really use tempfile, or $$; this is an accident in waiting # also, in the same namespace if a seed is the same, the accident is guarenteed; see genspec.py) flname = "/tmp/slsearch.%i" % (int(random.random() * 1000)) utils.remove(flname) self.sls_kw["outfile"] = flname # do the search #print self.sls_kw #print flname slsearch(**self.sls_kw) # open the table and get the contents tb = taskinit.tbtool() tb.open(self.sls_kw["outfile"]) numrows = tb.nrows() possible = [] # convert the results to a list for row in range(numrows): species = tb.getcell("SPECIES", row) name = tb.getcell("CHEMICAL_NAME", row) freq = float(tb.getcell("FREQUENCY", row)) qn = tb.getcell("QUANTUM_NUMBERS", row) linestr = float(tb.getcell("SMU2", row)) el = float(tb.getcell("EL", row)) eu = float(tb.getcell("EU", row)) # only add it to the output list if it does not contain an exotic atom, # or if exotics are allowed if not utils.isexotic(species or allowExotics): if (not "RECOMBINATION" in name.upper() \ or ("RECOMBINATION" in name.upper() and (rrlevelstr == "DEEP" or ("H" in species \ and ("alpha" in species or "beta" in species))))) \ and not self.checktier1overlap(freq): possible.append( LineData(formula=species, name=name, frequency=freq, uid=utils.getplain(species) + "_%.5f" % freq, energies=[el, eu], linestrength=linestr, mass=utils.getmass(species), transition=qn, plain=utils.getplain(species), isocount=utils.isotopecount(species))) tb.close() # remove the temporary table utils.remove(self.sls_kw["outfile"]) return possible