2

I am working on photoluminescence temperature series. I hence have several intensity Vs energy (eV) spectra, taken at different temperatures.

My issue is that the signal processing/peak finding packages I have found so far (Peaks, hyperSpec, msProcess, Timp, and other mass spectrometry / chemometrics-oriented packages) are not really suitable to my needs :

  • Peaks can not find "shoulders" (peaks are too close in position, which gives an hybrid peak (see at 3.75 eV))
  • hyperSpec and msProcess are too automated for my use : the location of photoluminescence peaks depends on temperature so peak identification is not repeatable over the temperature series.

What I think I should implement is : something that detects peaks & shoulders (automated or using locate() for a raw estimate), asks for manual identification of the peaks found, and outputs the label, position, intensity and FWHM of each peak. This would allow me to track accurately the location, intensity and FWHM of a given peak (identified by its label) over the temperature series.

Here is an example of a temperature series plot :

Example temperature series

So my questions are :

  1. Do you know of a package which already implement similar functions ?
  2. Do you think the approach I suggest is sensible / doable ?

Thank you very much !

Thibaud Ruelle

PS : I hope I was clear enough, do not hesitate to ask me for clarifications. PS2 : I hope the question is not too general, I can provide a typical spectrum if needed.

Thibaud Ruelle
  • 303
  • 1
  • 16
  • 1
    You assume we know *everything* about your work. I suggest you boil down on the terminology a bit and break it down in layman terms. What's an overlapping peak here? What's FWHM? – Arun Mar 16 '13 at 09:39
  • Okay, I was wondering if I should do that. Thanks a lot ! – Thibaud Ruelle Mar 16 '13 at 09:42
  • one approach I've used in the past is to 1) get a `smooth.spline()` through the data; 2) locate the extrema of this smooth function (e.g. looking at the sign changes of `diff()`; 3) use these guesses as starting points for an optimisation function. – baptiste Mar 16 '13 at 10:33
  • try reading the vignette about the `fda` package too, I have a feeling your problem would fall well into the realm of functional data analysis. – baptiste Mar 16 '13 at 10:36
  • Thank you very much for your suggestion ! I am looking into it right now. At first sight (I am trying to confirm it) the main issue is that peaks are not supposed to change position with the parameters. – Thibaud Ruelle Mar 16 '13 at 12:16

1 Answers1

1

Disclaimer: I've never personally had to do any serious peak fitting.

That being said, I see two ways here, which in the end probably aren't that different:

  • functional data analysis, like @baptiste says.
  • fitting a preset number of peaks of known shape (e.g. Gaussian or Lorentzian or Voigt)
    Then use the fit parameters of these as a new feature set for further analysis.
    FWHM would be coded in the fit parameters.

Which approach is more suitable for you probably depends on the further analysis you plan.

Some more bits and pieces:

  • As you are looking for shoulders, the 1st derivative will not allow you to detect all peaks. You may get sufficiently useful start points for peak fitting from 2nd derivatives' minima. However, for peaks that just show as shoulders on some larger peak, these positions will be quite off (too far on the low intensity side of the larger peak).
    package signal implements Savitzky-Golay filters, which can help with this approach.
  • Deconvolution may be a better bet for detection of peak positions.
  • You should be aware that these methods tend to "eat up" your signal-to-noise ratio rapidly, and the solutions can be much off if you have a baseline below your peaks. I don't know whether fda is better at this, but I suspect it is inherent to the problem you are trying to solve.
    You'll want to check the stability of the solutions you get wrt. SNR and possible baselines.

(And no, hyperSpec doesn't offer anything like this. However, if you end up with generally applicable functions for that, you'd be welcome to distribute that via hyperSpec, it can still be your own package. And if this turns out to be substantial programming work, you could consider applying for a google summer of code project with this - this year's application period is just about to start).

cbeleites unhappy with SX
  • 13,717
  • 5
  • 45
  • 57
  • Thank you very much for your suggestions ! The main issue with deconvolution and functional data analysis is that they do not allow to "follow" a given peak which position varies with temperature. As a result, I think that the most promising method would be to fit a set of peaks to the data using `nls()`. However, another issue is that the number of peaks vary with temperature (transitions happen), so I might have to use a model which changes at (a) given temperature(s) (maybe it is possible to fit these transition temperatures too). – Thibaud Ruelle Mar 17 '13 at 15:50
  • Another route would be to be to pick the peaks manually using `locate()` and then use these starting values to perform a fit with `nls()`. This would allow to store semi-automatically the intensity, position and FWHM of the different peaks at different temperatures. It may be a more robust method. – Thibaud Ruelle Mar 17 '13 at 15:59
  • @ThibaudRuelle: no, they don't follow, but they can generate a set of new features on which you can then e.g. relate position to temperature. I guess a functional version of multivariate curve resolution may be what you are looking for - but I think I just now invented this really awesome method ;-). As for the `locate`, this has probably at least the same problems the derivatives have. But if you go for it, `hyperSpec::spc.identify` may help you (it defaults on looking for a local max, but you can switch that off). – cbeleites unhappy with SX Mar 17 '13 at 17:34
  • I'll spend some more time thinking about it, but I think I may have to begin by doing it all by hand. This is only a semester project so I have limited time to spend on it, sadly. I will keep you posted. Thanks ! – Thibaud Ruelle Mar 17 '13 at 19:13
  • Finally, the structure was too complex and I had to do it by hand given the approaching deadline. However there is an idea to use iterative starting values to follow the "moving" peaks from spectra to spectra and I will try to implement this (I hope in the near future). @cbeleites I will notify you if I come up with something worth introducing into the hyperspec package. – Thibaud Ruelle Mar 23 '13 at 14:48