1
$\begingroup$

I have a problem fitting a function to data, where I only have the falling and rising edges of the data, with the peak having been capped and was wondering if you have some tips.

The data should have the shape of a Landau distribution but peak values were out of range. Example of data that I want to fit:

signalpart2 = {{880., 0.6299}, {880.8, 0.5354}, {881.6, 0.378}, {882.4, 0.2992}, {883.2, 0.3465}, {884., 0.4252}, {884.8, 0.4409}, {885.6, 0.3622},{886.4, 0.2992}, {887.2, 0.2362}, {888., 0.2677}, {888.8, 0.3622}, {889.6, 0.4252}, {890.4, 0.3937}, {891.2, 0.2992}, {892., 0.2362}, {892.8, 0.252}, {893.6, 0.378}, {894.4, 0.4882}, {895.2, 0.4567}, {896., 0.3622}, {896.8, 0.2677}, {897.6, 0.252}, {898.4, 0.2992}, {899.2, 0.3465}, {900., 0.3622}, {900.8, 0.2992}, {901.6, 0.2362}, {902.4, 0.2047}, {903.2, 0.2677}, {904., 0.3622}, {904.8, 0.4094}, {905.6, 0.3622}, {906.4, 0.2992}, {907.2, 0.252}, {908., 0.315}, {908.8, 0.5039}, {909.6, 0.6614}, {910.4, 0.6457}, {911.2, 0.5197}, {912., 0.4094}, {912.8, 0.5669}, {913.6, 1.3071}, {914.4, 1.9685}, {915.2, 2.}, {916., 1.6063}, {916.8, 1.0866}, {917.6, 1.1181}, {918.4, 1.8898}, {919.2, 2.}, {931.2, 2.}, {932., 1.9843}, {932.8, 1.8583}, {933.6, 1.748}, {934.4, 1.7008}, {935.2, 1.5748}, {936., 1.3858}, {936.8, 1.1654}, {937.6, 1.1496}, {938.4, 1.2598}, {939.2, 1.2756}, {940., 1.1496}, {940.8, 1.0551}, {941.6, 0.8819}, {942.4, 0.6772}, {943.2, 0.6299}, {944., 0.8346}, {944.8, 0.9449}, {945.6, 0.8189}, {946.4, 0.5827}, {947.2, 0.4252}, {948., 0.4409}, {948.8, 0.4409}, {949.6, 0.4724}, {950.4, 0.5197}, {951.2, 0.5354}, {952., 0.4724}, {952.8, 0.4252}, {953.6, 0.378}, {954.4, 0.4567}, {955.2, 0.4724}, {956., 0.4094}, {956.8, 0.378}, {957.6, 0.4409}, {958.4, 0.4882}, {959.2, 0.4882}, {960., 0.4409}, {960.8, 0.3937}, {961.6, 0.3465}, {962.4, 0.2992}, {963.2, 0.2992}, {964., 0.3465}, {964.8, 0.3465}, {965.6, 0.3622}, {966.4, 0.378}, {967.2, 0.3465}, {968., 0.315}, {968.8, 0.2677}, {969.6, 0.2677}, {970.4, 0.315}, {971.2, 0.3307}, {972., 0.3622}, {972.8, 0.378}, {973.6, 0.3465}, {974.4, 0.2677}, {975.2, 0.2047}, {976., 0.189}, {976.8,  0.2205}, {977.6, 0.252}, {978.4, 0.2677}, {979.2, 0.2677}, {980., 0.2362}, {980.8, 0.189}, {981.6, 0.1417}, {982.4, 0.1575}, {983.2, 0.2047}, {984., 0.2362}, {984.8, 0.2205}, {985.6, 0.189}, {986.4, 0.1732}, {987.2, 0.189}, {988., 0.2047}, {988.8, 0.2205}, {989.6, 0.2205}, {990.4, 0.189}, {991.2, 0.189}, {992., 0.189}, {992.8, 0.2362}, {993.6, 0.2677}, {994.4, 0.2205}, {995.2, 0.1732}, {996., 0.1575}, {996.8, 0.1575}, {997.6, 0.1732}, {998.4, 0.1732}, {999.2, 0.189}, {1000., 0.2047}, {1000.8, 0.189}, {1001.6, 0.1575}, {1002.4,0.1575}, {1003.2, 0.2047}, {1004., 0.1732}, {1004.8, 0.1575}, {1005.6, 0.1417}, {1006.4, 0.1732}, {1007.2, 0.2205}, {1008., 0.2362}, {1008.8, 0.2362}, {1009.6, 0.189}, {1010.4, 0.1102}, {1011.2, 0.0472}, {1012., 0.0472}, {1012.8, 0.0945}, {1013.6, 0.1732}, {1014.4, 0.189}, {1015.2, 0.1417}, {1016., 0.0945}, {1016.8, 0.0472}, {1017.6, 0.0472}, {1018.4, 0.0945}, {1019.2, 0.1417}, {1020., 0.2047}, {1020.8, 0.189}, {1021.6, 0.1575}, {1022.4, 0.1417}, {1023.2, 0.1417}, {1024., 0.126}, {1024.8, 0.1102}, {1025.6, 0.1102}, {1026.4, 0.1102}, {1027.2, 0.1417}, {1028., 0.1732}, {1028.8, 0.2047}, {1029.6, 0.2047}, {1030.4, 0.1575}, {1031.2, 0.1417}, {1032., 0.126}, {1032.8, 0.0787}, {1033.6, 0.0945}, {1034.4, 0.1102}, {1035.2, 0.126}, {1036., 0.126}, {1036.8,0.126}, {1037.6, 0.1102}, {1038.4, 0.0945}, {1039.2, 0.0787}, {1040., 0.1102}, {1040.8, 0.126}, {1041.6, 0.1417}, {1042.4, 0.1417}, {1043.2, 0.1417}, {1044., 0.0945}, {1044.8, 0.0472}, {1045.6, 0.}, {1046.4, 0.}, {1047.2, 0.0315}, {1048., 0.0945}, {1048.8, 0.1417}, {1049.6, 0.1417}, {1050.4, 0.1102}, {1051.2, 0.063}}

I've defined the function:

Landau[ampl_, x0_, sigma_, x_] := ampl*PDF[LandauDistribution[x0, sigma], x]  

And I fit as follows:

ClearAll[ampl, x0, sigma, x];
landfit = FindFit[signalpart2[[1138 ;; 1400]],
  Landau[ampl, x0, sigma, x], {{ampl, 80}, {x0, 915}, {sigma, 8.5}}, 
  x, MaxIterations -> 20, Method -> Automatic, AccuracyGoal -> 5, 
  PrecisionGoal -> 5]

Which gives me the following fit: {ampl -> 79.7375, x0 -> 911.464, sigma -> 10.5445} bad fit

Entering the values manually gives a fit that corresponds better to how it should be (values {ampl -> 80, x0 -> 915, sigma -> 8.3} : better fit

I've tried to limit the data that I fit to to exclude the non-zero parts before the rising edge as well as parts of the tail, which gives a slightly better fit, but still far from how it should be. Somehow it seems I need to put more weight to the higher values of the data and forcing Mathematica to not see the high values as the actual peak values.

I couldn't find any similar questions, but if I missed any I'd appreciate a link to the questions.

Thank you very much for any help and suggestions!

EDIT The data is the voltage readout from a sensor being hit by particles and ideally a single particle should produce a Landau peak, but due to various reasons (mainly signal overlap and slow charge collection) especially the low values don't really correspond to this. The high values are more close to the Landau. It's indeed a bit arbitrary, but I will know how reliable it actually turns out to be.

This is a non-capped signal and a proper looking fit: enter image description here

Which uses the following data:

{{840.,0.0394},{840.8,0.0787},{841.6,0.},{842.4,0.0394},{843.2,0.0394},{844.,0.},{844.8,0.0394},{845.6,0.0394},{846.4,0.0394},{847.2,0.0394},{848.,0.},{848.8,0.0394},{849.6,0.0394},{850.4,0.0394},{851.2,0.0394},{852.,0.0394},{852.8,0.},{853.6,0.},{854.4,0.0394},{855.2,0.0787},{856.,0.0394},{856.8,0.0394},{857.6,0.0394},{858.4,0.0394},{859.2,0.0394},{860.,0.0394},{860.8,0.0394},{861.6,0.0394},{862.4,0.},{863.2,0.},{864.,0.},{864.8,0.0394},{865.6,0.0394},{866.4,0.0394},{867.2,0.0394},{868.,0.0394},{868.8,0.},{869.6,0.0394},{870.4,0.0787},{871.2,0.0394},{872.,0.},{872.8,0.0394},{873.6,0.},{874.4,0.0394},{875.2,0.0787},{876.,0.0394},{876.8,0.0394},{877.6,0.0394},{878.4,0.},{879.2,0.0394},{880.,0.0394},{880.8,0.0394},{881.6,0.},{882.4,0.0394},{883.2,0.},{884.,0.0394},{884.8,0.0787},{885.6,0.0787},{886.4,0.0394},{887.2,0.},{888.,0.},{888.8,0.0394},{889.6,0.0394},{890.4,0.0394},{891.2,0.0394},{892.,0.0787},{892.8,0.},{893.6,0.},{894.4,0.0394},{895.2,0.0787},{896.,0.0394},{896.8,0.0394},{897.6,0.0394},{898.4,0.},{899.2,0.0394},{900.,0.0394},{900.8,0.0394},{901.6,0.0394},{902.4,0.0394},{903.2,0.},{904.,0.0394},{904.8,0.0394},{905.6,0.0394},{906.4,0.0787},{907.2,0.},{908.,-0.0394},{908.8,0.},{909.6,0.0394},{910.4,0.0787},{911.2,0.0787},{912.,0.0394},{912.8,0.},{913.6,0.2756},{914.4,0.4331},{915.2,0.2756},{916.,0.0787},{916.8,0.},{917.6,0.4724},{918.4,2.0472},{919.2,2.6378},{920.,2.6378},{920.8,2.3622},{921.6,2.2441},{922.4,1.9685},{923.2,2.0866},{924.,2.2441},{924.8,2.126},{925.6,1.6142},{926.4,1.1024},{927.2,0.9055},{928.,0.9055},{928.8,0.9843},{929.6,0.8268},{930.4,0.6299},{931.2,0.5906},{932.,0.5906},{932.8,0.5118},{933.6,0.5118},{934.4,0.5512},{935.2,0.5118},{936.,0.3543},{936.8,0.2362},{937.6,0.3937},{938.4,0.5118},{939.2,0.5512},{940.,0.4331},{940.8,0.4331},{941.6,0.2756},{942.4,0.1181},{943.2,0.1575},{944.,0.3937},{944.8,0.5118},{945.6,0.3543},{946.4,0.1575},{947.2,0.0394},{948.,0.0394},{948.8,0.1181},{949.6,0.1575},{950.4,0.2362},{951.2,0.2362},{952.,0.1969},{952.8,0.1575},{953.6,0.1575},{954.4,0.1969},{955.2,0.2362},{956.,0.1575},{956.8,0.1181},{957.6,0.1969},{958.4,0.2362},{959.2,0.2362},{960.,0.1969},{960.8,0.1969},{961.6,0.1181},{962.4,0.0394},{963.2,0.1181},{964.,0.1575},{964.8,0.1181},{965.6,0.1575},{966.4,0.1575},{967.2,0.1575},{968.,0.1181},{968.8,0.0787},{969.6,0.0787},{970.4,0.1181},{971.2,0.1575},{972.,0.1969},{972.8,0.1969},{973.6,0.1575},{974.4,0.0787},{975.2,0.},{976.,0.0394},{976.8,0.0787},{977.6,0.0787},{978.4,0.1181},{979.2,0.1181},{980.,0.0787},{980.8,0.0394},{981.6,0.},{982.4,0.0394},{983.2,0.0787},{984.,0.0787},{984.8,0.0787},{985.6,0.0394},{986.4,0.0394},{987.2,0.0787},{988.,0.1181},{988.8,0.0787},{989.6,0.1181},{990.4,0.0787},{991.2,0.0787},{992.,0.0787},{992.8,0.1181},{993.6,0.1575},{994.4,0.1181},{995.2,0.0394},{996.,0.0394},{996.8,0.0394},{997.6,0.0394},{998.4,0.1181},{999.2,0.1181},{1000.,0.1181},{1000.8,0.0787},{1001.6,0.0394},{1002.4,0.0787},{1003.2,0.0787},{1004.,0.0787},{1004.8,0.0394},{1005.6,0.0394},{1006.4,0.0787},{1007.2,0.1181},{1008.,0.1575},{1008.8,0.1181},{1009.6,0.0787},{1010.4,0.},{1011.2,-0.0787},{1012.,0.},{1012.8,0.0787},{1013.6,0.1181},{1014.4,0.0787},{1015.2,0.0787},{1016.,-0.0394},{1016.8,-0.0394},{1017.6,0.},{1018.4,0.},{1019.2,0.0787},{1020.,0.1181},{1020.8,0.0787},{1021.6,0.0394},{1022.4,0.0394},{1023.2,0.0787},{1024.,0.0394},{1024.8,0.0394},{1025.6,0.0394},{1026.4,0.0787},{1027.2,0.0394},{1028.,0.1181},{1028.8,0.1181},{1029.6,0.1181},{1030.4,0.0394},{1031.2,0.0787},{1032.,0.0394},{1032.8,0.},{1033.6,0.},{1034.4,0.0394},{1035.2,0.0787},{1036.,0.0394},{1036.8,0.0394},{1037.6,0.0394},{1038.4,0.},{1039.2,0.0394},{1040.,0.0787}}
$\endgroup$
  • $\begingroup$ try working with NonlinearModelFit, which has a provision to supply weights. $\endgroup$ – george2079 Jul 22 '15 at 18:21
  • $\begingroup$ When I extract signalpart2 I get 200 components. You are using signalpart2[[1138 ;; 1400] in your call to FindFit. This is over 200 components. Can you share the exact data you are using. What are the manual parameters that fit the data better? $\endgroup$ – Jack LaVigne Jul 22 '15 at 21:05
  • $\begingroup$ Using all 200 points the error I get between the manual values of 80, 915 and 8.5 is 10.26 while the error I get between the fit values using all 200 points and default parameters for FindFit (80.6, 910.1, 11.24) is indeed better (an error of 8.2). $\endgroup$ – Jack LaVigne Jul 22 '15 at 21:18
  • $\begingroup$ Now I tried elements 38 to 90 to fit the data. I still get a smaller error using FindFit than the manual parameters. I think we need to know the indices of the data that you are trying to fit. $\endgroup$ – Jack LaVigne Jul 22 '15 at 21:26
  • $\begingroup$ I understand the data should have a Landau distribution but clearly because the left tail does not drop to zero, it doesn't. One wouldn't fit a line to something that is clearly quadratic, so why would one fit a distribution just doesn't fit the data? But even then what you really have is a histogram - bins with counts (as opposed to x and y pairs where it would make sense to perform a regression). Finally, why would a set of histogram counts get "capped" ? Does that mean those counts are larger than 127 (which is the largest count that you have)? $\endgroup$ – JimB Jul 22 '15 at 22:14
3
$\begingroup$

In order to fit various parts of the data you can use this Manipulate to set the start and stop indices (Note: In version 10.1 when you first open up the Manipulate variables to type in an index it will jump to a bad value. Just type in the good value and it will resurrect itself).

Manipulate[
 landfit = FindFit[signalpart2[[startIndex ;; stopIndex]],
   Landau[ampl, x0, sigma, x],
   {
    {ampl, 80},
    {x0, 915},
    {sigma, 8.5}
    },
   x
   ];
 Column[{
   landfit,
   Show[
    Plot[Landau[ampl, x0, sigma, x] /. landfit,
     {x, 880, 1060},
     PlotRange -> {{870, 1070}, {0, 3}},
     PlotStyle -> Red,
     AxesOrigin -> {870, 0}
      ],
    ListPlot[signalpart2],
    ListPlot[signalpart2[[startIndex ;; stopIndex]], PlotStyle -> Red],
    ImageSize -> 400
    ]
   }],
 {{startIndex, 38}, 1, 100, Appearance -> "Labeled"},
 {{stopIndex, 90}, 50, 200, Appearance -> "Labeled"}
 ]

Here is one snapshot

Mathematica graphics

$\endgroup$
  • $\begingroup$ Nice! (+1) To work around the Manipulate issue, you can use Appearance -> {"Open", "Labeled"}. If they start out open, they won't do any funny jumping any more. I am worried, though, that such selective fitting may be a bit too ad hoc: to me, it is a bit fishy to select only a portion of the data to run the fit. $\endgroup$ – MarcoB Jul 23 '15 at 4:45
  • 1
    $\begingroup$ @MarcoB Yes, if you're going to choose the data points based on the fit that you want, why bother having the data at all? You could just write down the fit to begin with. But this could be a good tool to check which parts of the data are behaving as you expect. $\endgroup$ – Simon Rochester Jul 23 '15 at 6:31
  • $\begingroup$ Thank you very much! This will help a lot in qualitatively understanding how it works and where it goes wrong. $\endgroup$ – bjorn Jul 23 '15 at 12:53
  • $\begingroup$ @MarboB, you're correct, it's a bit ad hoc, but not without reasoning. I know that the higher values are more true to the ideal Landau peak that should theoretically be produced. Of course I will have to analyze how reliable it will actually be in the end and I can easily see if and to what degree the results correspond with reality or not. $\endgroup$ – bjorn Jul 23 '15 at 12:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.