Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def test_spectrum(self):
spec = Spectrum(3)
spec.add_value(479.1, 1000)
self.assertEqual(
spec.trim(),
[[479.1], [1000]]
)
spec2 = Spectrum(3)
spec2.add_value(443.1, 1000)
self.assertEqual(
spec2.trim(),
[[443.1], [1000]]
)
spec += spec2
self.assertEqual(
spec.trim(),
[[443.1, 479.1], [1000, 1000]]
)
spec3 = Spectrum(3, start=50, end=2500)
spec3.add_value(2150.9544, 1000)
self.assertEqual(
spec3.trim(),
[[2150.954], [1000]]
)
output:
filled dictionary, each subkey will have:
'raw': list of raw integrated values dictacted by the bounds
'function': the function that the species was associated with
if sumspec is true, will also output a dictionary of Spectrum objects
the keys of this dictionary are the function numbers
explicitly interprets full scan mass spectra and UV species
"""
if sumspec is True:
spec = {}
for function in self.functions: # create spectrum objects for all MS species
if self.functions[function]['type'] == 'MS':
spec[function] = Spectrum(3)
for species in sp: # look for and assign function affinity
sp[species]['function'] = self.associate_to_function(
dct=sp[species]) # associate each species in the spectrum with a function
if 'raw' not in sp[species]: # look for empty raw list
sp[species]['raw'] = []
if self.ftt is False: # if timepoints and tic values have not been extracted yet, extract those
self.function_timetic()
if self.verbose is True:
prog = self.Progress( # generate progress instance
string='Extracting species data from spectrum',
last=self.nscans,
writeevery=5
)
for spectrum in self.tree.getElementsByTagName('spectrum'):
function, proc, scan = fps(spectrum) # pull function, process, and scan numbers
**Returns**
specout: *list*
A list of paired lists (similar to *speclst*) where each index is a binned spectrum.
cv: *list*
A sorted list of collision voltages with each index corresponding to that index in *specout*.
"""
binned = {}
for ind, ce in enumerate(celist):
sys.stdout.write('\rBinning spectrum by CID value #%i/%i %.1f%%' % (
ind + 1, len(celist), float(ind + 1) / float(len(celist)) * 100.))
if ce not in binned: # generate key and spectrum object if not present
binned[ce] = Spectrum(dec, start=startmz, end=endmz)
else: # otherwise add spectrum
binned[ce].add_spectrum(speclist[ind][0], speclist[ind][1])
if threshold > 0 or fillzeros is True: # if manipulation is called for
for vol in binned: # for each voltage
sys.stdout.write('\rZero filling spectrum for %s eV' % str(vol))
if threshold > 0:
binned[vol].threshold(threshold) # apply threshold
if fillzeros is True:
binned[vol].fill_with_zeros() # fill with zeros
sys.stdout.write(' DONE\n')
cv = [] # list for collision voltages
specout = [] # list for spectra
for vol, spec in sorted(binned.items()):
sys.stdout.write('\rTrimming spectrum for %s eV' % str(vol))
if 'raw' not in sp[key]:
newsp[key] = sp[key] # create references in the namespace
if len(newsp) is not 0:
newpeaks = True
if verbose is True:
sys.stdout.write('Some peaks are not in the raw data, extracting these from raw file.\n')
ips = xlfile.pullmultispectrum(
'Isotope Patterns') # pull predefined isotope patterns and add them to species
for species in ips: # set spectrum list
sp[species]['spectrum'] = [ips[species]['x'], ips[species]['y']]
mzml = mzML(filename) # load mzML class
sp = prepformula(sp) # prep formula etc for summing
newsp = prepformula(newsp) # prep formula species for summing
for species in newsp:
if 'spectrum' not in newsp[species]:
newsp[species]['spectrum'] = Spectrum(3, newsp[species]['bounds'][0], newsp[species]['bounds'][1])
newsp = mzml.pull_species_data(newsp) # pull data
else:
if verbose is True:
sys.stdout.write('No new peaks were specified. Proceeding directly to summing and normalization.\n')
if rd is False: # if no raw data is present, process mzML file
mzml = mzML(filename, verbose=verbose) # load mzML class
sp = prepformula(sp)
sp, sum_spectra = mzml.pull_species_data(sp, combine_spectra) # pull relevant data from mzML
chroms = mzml.pull_chromatograms() # pull chromatograms from mzML
rtime = {}
tic = {}
for key in sp: # compare predicted isotope patterns to the real spectrum and save standard error of the regression
func = sp[key]['function']
if mzml.functions[func]['type'] == 'MS': # determine mode key
if combine_spectra is True:
verbose: bool = VERBOSE,
):
"""
Simulates the isotope pattern that would be observed in a mass
spectrometer with the resolution specified as a fwhm value.
:param barip: The isotope pattern to be simulated. This can be either the bar isotope
pattern or the raw isotope pattern (although this will be substantially
slower for large molecules).
:param fwhm: full-width-at-half-maximum
:param verbose: chatty mode
:return: The predicted gaussian isotope pattern in the form of a paired list
``[[m/z values],[intensity values]]``
:rtype: list
"""
spec = Spectrum( # generate Spectrum object to encompass the entire region
autodec(fwhm),
start=min(barip[0]) - fwhm * 2,
end=max(barip[0]) + fwhm * 2,
empty=False, # whether or not to use emptyspec
filler=0., # fill with zeros, not None
)
for ind, val in enumerate(barip[0]): # generate normal distributions for each peak
# if verbose is True:
# sys.stdout.write('\rSumming m/z %.3f %d/%d' %(val,ind+1,len(self.barip[0])))
nd = normal_distribution(val, fwhm, barip[1][ind]) # generate normal distribution for that peak
spec.add_spectrum(nd[0], nd[1]) # add the generated spectrum to the total spectrum
spec.normalize() # normalize
gausip = spec.trim() # trim None values and output
if verbose is True:
sys.stdout.write(' DONE\n')
return gausip
for key in comp: # for each element
if key in mass_dict: # if not a single isotope
if verbose is True:
prog = Progress(string=f'Processing element {key}', last=comp[key])
masses = [] # list for masses of each isotope
abunds = [] # list for abundances
for mass in mass_dict[key]:
if mass != 0:
if mass_dict[key][mass][1] > 0: # if abundance is nonzero
masses.append(mass_dict[key][mass][0])
abunds.append(mass_dict[key][mass][1])
for n in range(comp[key]): # for n number of each element
if verbose is True:
prog.write(n + 1)
if spec is None: # if spectrum object has not been defined
spec = Spectrum(
decpl, # decimal places
start=min(masses) - 10 ** -decpl, # minimum mass
end=max(masses) + 10 ** -decpl, # maximum mass
specin=[masses, abunds], # supply masses and abundances as initialization spectrum
empty=True, # whether or not to use emptyspec
filler=0., # fill with zeros, not None
)
continue
spec.add_element(masses, abunds) # add the element to the spectrum object
spec.normalize(100.) # normalize spectrum
if dropmethod == 'threshold': # drop values below threshold
spec.threshold(threshold)
elif dropmethod == 'npeaks': # keep top n number of peaks
spec.keep_top_n(npeaks)
elif dropmethod == 'consolidate': # consolidate values being dropped
# todo figure out what's wrong here
isos[isotope] = element # create isotope,element association for reference
iterators.append(
ReiterableCWR( # create iterator instance
isosets[element],
comp[element]
)
)
if verbose is True:
nk.append([ # track n and k for list length output
len(isosets[element]),
comp[element]
])
else: # if it's an isotope
speciso = True
spec = Spectrum( # initiate spectrum object
decpl, # decimal places
start=None, # no minimum mass
end=None, # no maximum mass
empty=True, # whether or not to use emptyspec
filler=0., # fill with zeros, not None
)
if verbose is True:
counter = 0 # create a counter
iterations = int(cpu_list_product([numberofcwr(n, k) for n, k in nk])) # number of iterations
prog = Progress( # create a progress instance
string='Processing isotope combination',
last=iterations
)
for comb in product(*iterators):
if verbose is True:
"""
extending the spectrum object then dropping is very fast,
but requires subtracting the original spectrum before dropping
slicing, deepcopy, list(), building the subtraction into the boxxed lists, and switching the array calls
are all slower than generating a temporary Spectrum object
"""
# self.newend(max(masses) + max(self.x)) # define new end point for Spectrum object
# for i in range(newx.shape[0]): # add calculated masses and intensities to object
# if i == 0:
# self.addspectrum(newx[i],newy[i],True) # subtract original spectrum
# continue
# self.addspectrum(newx[i],newy[i])
# self.addspectrum(oldx,oldy,True) # subtract old spectrum
# self.dropbelow(min(masses) + min(self.x)) # drop values below new start point
tempspec = Spectrum(
self.decpl,
start=min(masses) + self.start - 10 ** -self.decpl,
end=max(masses) + self.end + 10 ** -self.decpl,
empty=self.empty,
filler=self.filler,
)
for x, y in zip(newx, newy):
tempspec.add_spectrum(x, y)
# for i in range(newx.shape[0]):
# tempspec.addspectrum(newx[i], newy[i])
self.x = tempspec.x # redefine the x and y lists
self.y = tempspec.y
self._start = min(masses) + self.start - 10 ** -self.decpl
self._end = max(masses) + self.end + 10 ** -self.decpl
sortlist = sorted(sortlist) # sorted list of elements based on the length of their isotope patterns
sortlist.reverse()
if verbose is True:
prog = Progress(
last=len(sortlist) - 1,
percent=False,
fraction=False,
)
spec = None
for lenlist, element in sortlist:
if verbose is True:
prog.string = f'Adding element {element} to isotope pattern'
prog.write(1)
if spec is None:
spec = Spectrum(
autodec(fwhm), # decimal places
start=None, # minimum mass
end=None, # maximum mass
empty=True, # whether or not to use emptyspec
filler=0., # fill with zeros, not None
specin=eleips[element], # supply masses and abundances as initialization spectrum
)
if verbose is True:
prog.fin()
continue
spec.add_element(eleips[element][0], eleips[element][1])
spec.normalize(100.) # normalize spectrum object
if dropmethod == 'threshold': # drop values below threshold
spec.threshold(threshold)
elif dropmethod == 'npeaks': # keep top n number of peaks