diff --git a/src/yapsut/montecarlo_fitting.py b/src/yapsut/montecarlo_fitting.py
index f975a6034fbb6668b949e1e38f74d7deb51360d6..2adc35b857d2759e9a198fa614dc44ae1e70c4fd 100644
--- a/src/yapsut/montecarlo_fitting.py
+++ b/src/yapsut/montecarlo_fitting.py
@@ -1,5 +1,7 @@
 import numpy as np
 import pandas as pd
+from .stats import CumulativeOfData
+from .struct import struct as STRUCT
 
 class EnsembleFitting_Base :
     """This class implements Ensemble fitting with curve_fit for (a,b,c,Rdark) out of the input curve.
@@ -135,6 +137,22 @@ class EnsembleFitting_Base :
         except :
             return np.ones(len(self._param_names))+np.nan
     #
+    def montecarlo_cdf(self) :
+        """returns a dictionary with the cdf for the montecarlo simulations.
+        CDF are instatiations of .stats/CumulativeOfData so they are interpolating functions
+        of the montecarlo distribution of each variable.
+        """
+        try :
+            self._mc[:,0]
+        except :
+            raise Exception("Error: no montecarlo simulation stored")
+        #
+        out=STRUCT()
+
+        for ik,k in enumerate(self.param_names) :
+            out[k]=CumulativeOfData(self._mc[:,ik])
+        return out
+    #
     def fitting(self,X,Y,sgm) :
         """
         the fitter function, must be specialized according to the this template
diff --git a/src/yapsut/stats.py b/src/yapsut/stats.py
index bee75b1f4929d523ec0bc910819501bbd0c66bf8..ff58bfba4929081e126545a7c5f7601b10db3939 100644
--- a/src/yapsut/stats.py
+++ b/src/yapsut/stats.py
@@ -5,11 +5,13 @@ Simple stats
 import numpy as np
 
 class CumulativeOfData :
-   """strucuture to handle the cumulative of 1d data"""
+   """strucuture to handle the cumulative of 1d data
+      It uses linear interpolations
+   """
    @property
-   def cdf(self) :
-      """the cdf """
-      return self._cdf
+   def CDF(self) :
+      """the cdf sampled curve """
+      return self._eff
    @property
    def x(self) :
       """the score"""
@@ -18,6 +20,10 @@ class CumulativeOfData :
    def N(self) :
       """the number of finite samples"""
       return self._N
+   @property
+   def z(self) :
+      """normalized x: z(x) = (x-x.min())/(x.max()-x.min())"""
+      return (self._x-self._x[0])/(self._x[-1]-self._x[0])
    def __init__(self,X) :
       """:X: 1d array of scores"""
       idx=np.where(np.isfinite(X))
@@ -32,12 +38,57 @@ class CumulativeOfData :
       :x: the score
       """
       return np.interp(x,self._x,self._eff,left=0.,right=1.)
+   #
+   def sampled_pdf(self,x,method='hist') :
+      """returns the sample pdf for a list of x
+         output: hh, xx
+
+         x must be monotously increasing or an integer
+
+         if method = 'hist' the pdf is calculated using an histogram like function (default)
+         if method = 'tan' the pdf is calculated using the local tangent to the cdf
+      """
+      if not method in ['hist','tan'] :
+         raise Exception("Error: method must be either 'hist' or 'tan'")
+      #
+      if method == 'hist' :
+         if np.isscalar(x) :
+            n=int(x)
+            _x=np.linspace(self._x[0],self._x[-1],n)
+         else :
+            _x=np.sort(x)
+         #
+         yy=self.cdf(_x)
+         hh=(yy[:-1]-yy[1:])/(_x[:-1]-_x[1:])
+         return hh, _x
+      elif method == 'tan' :
+         h=(self._x[-1]-self._x[0])*eps
+         ydotF=(self.cdf(_x+h)-self.cdf(_x-h))/(2*h)
+         ydotH=(self.cdf(_x+h/2)-self.cdf(_x-h/2))/(h)
+         ydot=2*ydotH-ydotF
+         #
+         # if the lower limit is below the minimum value in the cdf
+         if _x[0]-h<self._x[0] :
+            ydotF=(self.cdf(_x[0]+h)-self.cdf(_x[0]))/(h)
+            ydotH=((self.cdf(_x[0]+h)-self.cdf(_x[0])))/(h/2)
+            ydot[0]=2*ydotH-ydotF
+         #
+         # if the upper limit is above the maximum value of the cdf
+         if _x[-1]+h>self._x[-1] :
+            ydotF=(self.cdf(_x[-1])-self.cdf(_x[-1]-h))/(h)
+            ydotH=(self.cdf(_x[-1])-self.cdf(_x[-1]-h/2))/(h/2)
+            ydot[-1]=2*ydotH-ydotF
+         #
+         return ydot, _x
+      else :
+         raise Exception("Error: method must be either 'hist' or 'tan'")
+   #
    def percentile(self,eff) :
       """computes the percentile of samples for which x<=percentile(eff)
       
       :eff: the required percentile [0,1]
       if eff<0 the result is -infty
-      if eff>0 the result is +infty
+      if eff>1 the result is +infty
       """
       return np.interp(eff,self._eff,self._x,left=-np.infty,right=np.infty)