diff --git a/Rich/RichRecUtils/RichRecUtils/RichCKResolutionFitter.h b/Rich/RichRecUtils/RichRecUtils/RichCKResolutionFitter.h
index 522cc1d83c30912eb132cb16152c107b10a4144b..544f2bf29ab8f47e72dddf897b73fe34ad505e02 100644
--- a/Rich/RichRecUtils/RichRecUtils/RichCKResolutionFitter.h
+++ b/Rich/RichRecUtils/RichRecUtils/RichCKResolutionFitter.h
@@ -5,6 +5,7 @@
 #include <string>
 #include <vector>
 #include <array>
+#include <cstdint>
 
 // ROOT includes 
 #include <TH1.h> 
@@ -33,26 +34,35 @@ namespace Rich
       class FitParams final
       {
 
+      private:
+        
+        /// Number of Radiators
+        static const std::uint8_t NRads = 2;
+        
       public:  // General fitting parameters
 
-        using RichFitTypes_t = std::array< std::vector<std::string> , 2 >;
+        /// Type for list for fit types for each radiator
+        using RichFitTypes_t = std::array< std::vector<std::string> , NRads >;
 
-        //                                         RICH1          RICH2
+        //                                               RICH1                RICH2
         /// Starting resolution guesses
-        std::array<double,2> RichStartRes      { {  0.0017,      0.0007   } };
+        std::array<double,NRads> RichStartRes      { {   0.0017,             0.0007   } };
         /// Starting prefit deltas
-        std::array<double,2> RichStartDelta    { {  0.0025,      0.00105  } };
+        std::array<double,NRads> RichStartDelta    { {   0.0025,             0.00105  } };
         /// Fit Range Minimums  
-        std::array<double,2> RichFitMin        { { -0.0079,     -0.00395  } };
+        std::array<double,NRads> RichFitMin        { { - 0.0079,            -0.00395  } };
         /// Fit range Maxmimums
-        std::array<double,2> RichFitMax        { {  0.0077,      0.00365  } };
+        std::array<double,NRads> RichFitMax        { {   0.0077,             0.00365  } };
+        /// Default Gauss Asymmetry
+        std::array<double,NRads> RichStartAsym     { {   0.0000,             0.0000   } };
         /// Fit Type(s)
-        RichFitTypes_t RichFitTypes            { { {"FreeNPol"}, {"FreeNPol"} } };
+        RichFitTypes_t RichFitTypes { { {"AsymNormal:Hyperbolic","AsymNormal:FreeNPol"}, 
+                                        {"AsymNormal:Hyperbolic","AsymNormal:FreeNPol"} } };
 
       public:  // Free polynominal background fit options
 
         /// Polynominal degree
-        std::array<unsigned int,2> RichNPol   { {    3      ,     3      } };
+        std::array<unsigned int,NRads> RichNPol   { {     3          ,          3     } };
 
       public:  // Fixed polynominal background function
 
@@ -68,73 +78,203 @@ namespace Rich
 
       private:
 
+        // polynominal function
+        inline std::string Pol( const int degree,
+                                unsigned int iFirstParam ) const noexcept
+        {
+          return ( 
+            "auto pol = [](double *x, double *p) -> double "
+            "{ "
+            " const unsigned int iFP = "+std::to_string(iFirstParam)+"; "
+            " const unsigned int deg = "+std::to_string(degree)+"; "
+            " auto ret = p[iFP+deg]; "
+            " for ( int i = deg-1; i >= 0; --i ) { ret = (ret*x[0]) + p[iFP+i]; }; "
+            " return ret;"
+            "}; "
+            );
+        }
+
         // hyperbolic fnction
-        inline std::string Hyperbolic( const unsigned int iFirstParam ) const
+        inline std::string Hyperbolic( const unsigned int iFirstParam ) const noexcept
         {
           return ( 
+            "auto hyperbol = [](double *x, double *p) -> double "
+            "{ "
             // The fit parameters
-            "const double A  = p["+std::to_string(iFirstParam  )+"]; "
-            "const double B  = p["+std::to_string(iFirstParam+1)+"]; "
-            "const double Cm = p["+std::to_string(iFirstParam+2)+"]; "
-            "const double Cp = p["+std::to_string(iFirstParam+3)+"]; "
-            "const double D  = p["+std::to_string(iFirstParam+4)+"]; "
+            " const double A  = p["+std::to_string(iFirstParam  )+"]; "
+            " const double B  = p["+std::to_string(iFirstParam+1)+"]; "
+            " const double Cm = p["+std::to_string(iFirstParam+2)+"]; "
+            " const double Cp = p["+std::to_string(iFirstParam+3)+"]; "
+            " const double D  = p["+std::to_string(iFirstParam+4)+"]; "
             // Which C
-            "const double C = ( x[0] < D ? Cm : Cp ); "
+            " const double C = ( x[0] < D ? Cm : Cp ); "
             // the function
-            "const double hyperbol = ( A - ( std::sqrt( B + C*std::pow(x[0]-D,2) ) ) ); "
+            " return ( A - ( std::sqrt( B + C*std::pow(x[0]-D,2) ) ) ); "
+            "}; "
             );
         }
 
-        // Gaussian function
-        inline std::string Gauss( const unsigned int iFirstParam ) const
+        // Asymmetric Normal function
+        inline std::string AsymNormal( const unsigned int iFirstParam ) const noexcept
         {
           return ( 
+            "auto normal = [](double *x, double *p) -> double "
+            "{ "
             // The fit parameters
-            "const double N     =      p["+std::to_string(iFirstParam  )+"]; "
-            "const double mean  =      p["+std::to_string(iFirstParam+1)+"]; "
-            "const double sigma = fabs(p["+std::to_string(iFirstParam+2)+"]); "
+            " const double N      =      p["+std::to_string(iFirstParam  )+"]; "
+            " const double mean   =      p["+std::to_string(iFirstParam+1)+"]; "
+            " const double sigma  = fabs(p["+std::to_string(iFirstParam+2)+"]); "
+            " const double alpha  =      p["+std::to_string(iFirstParam+3)+"]; "
+            " const double sigmaa = sigma * ( 1.0 + ( 0.5 * alpha ) ); "
+            " const double sigmab = sigma * ( 1.0 - ( 0.5 * alpha ) ); "
+            " const double s      = ( x[0] > mean ? sigmaa : sigmab ); "
             // the function
-            "const double gaus = ( sigma > 0 ? N * std::exp( -0.5 * std::pow((x[0]-mean)/sigma,2) ) : 0 ); "
+            " return ( s > 0 ? N * std::exp( -0.5 * std::pow((x[0]-mean)/s,2) ) : 0 ); "
+            "}; "
+            );
+        }
+
+        // Normal function
+        inline std::string Normal( const unsigned int iFirstParam ) const noexcept
+        {
+          return ( 
+            "auto normal = [](double *x, double *p) -> double "
+            "{ "
+            // The fit parameters
+            " const double N     =      p["+std::to_string(iFirstParam  )+"]; "
+            " const double mean  =      p["+std::to_string(iFirstParam+1)+"]; "
+            " const double sigma = fabs(p["+std::to_string(iFirstParam+2)+"]); "
+            // the function
+            " return ( sigma > 0 ? N * std::exp( -0.5 * std::pow((x[0]-mean)/sigma,2) ) : 0 ); "
+            "}; "
+            );
+        }
+
+        // Skewed Normal function
+        inline std::string SkewedNormal( const unsigned int iFirstParam ) const noexcept
+        {
+          return ( 
+            "auto normal = [](double *x, double *p) -> double "
+            "{ "
+            // The fit parameters
+            " const double N     =      p["+std::to_string(iFirstParam  )+"]; "
+            " const double mean  =      p["+std::to_string(iFirstParam+1)+"]; "
+            " const double sigma = fabs(p["+std::to_string(iFirstParam+2)+"]); "
+            " const double alpha =      p["+std::to_string(iFirstParam+3)+"]; "
+            // convert fit parameters to function parameters
+            " const double pi    = 3.14159265358979; "
+            " const double delta = alpha / std::sqrt( 1.0 + std::pow(alpha,2) ); "
+            " const double w     = sigma / std::sqrt( 1.0 - (2.0*std::pow(delta,2)/pi) ); "
+            " const double eta   = mean - (w*delta*std::sqrt(2.0/pi)); "
+            " const double xx    = ( x[0] - eta ) / w; "
+            // the function
+            " return N * std::exp(-0.5*xx*xx) * ( 1.0 + std::erf(alpha*xx/std::sqrt(2.0)) ); "
+            "}; "
             );
         }
 
       public:  // Hyperbolic functions
 
-        //                                          RICH1      RICH2
+        //                                             RICH1       RICH2
         /// Side band sizes
-        std::array<double,2> SideBandSize     { {  0.002,      0.001   } };
+        std::array<double,NRads> SideBandSize     { {  0.002,      0.001   } };
         /// Init values for parameter B
-        std::array<double,2> HyperInitB       { {  1e8,        1e8     } };
+        std::array<double,NRads> HyperInitB       { {  1e8,        1e8     } };
         /// Init values for parameter D
-        std::array<double,2> HyperInitD       { {  7e-4,       5e-4    } };
+        std::array<double,NRads> HyperInitD       { {  7e-4,       5e-4    } };
   
         /// lambda function for signal + background
-        inline std::string GaussHyperbolFitFunc( const unsigned int iFirstParam ) const
+        inline std::string NormalHyperbolFitFunc( const unsigned int iFirstParam = 0 ) const noexcept
         {
           return ( "[&](double *x, double *p) { "
-                   + Gauss(iFirstParam)
+                   + Normal(iFirstParam)
                    + Hyperbolic(iFirstParam+3)
-                   + "return hyperbol + gaus; }" );
+                   + "return hyperbol(x,p) + normal(x,p); }" );
         }
 
-        /// lambda function for background only
-        inline std::string HyperbolFitFunc( const unsigned int iFirstParam ) const
+        /// lambda function for signal + background
+        inline std::string AsymNormalHyperbolFitFunc( const unsigned int iFirstParam = 0 ) const noexcept
+        {
+          return ( "[&](double *x, double *p) { "
+                   + AsymNormal(iFirstParam)
+                   + Hyperbolic(iFirstParam+4)
+                   + "return hyperbol(x,p) + normal(x,p); }" );
+        }
+
+        /// lambda function for signal + background
+        inline std::string NormalPolFitFunc( const int degree,
+                                             const unsigned int iFirstParam = 0 ) const noexcept
+        {
+          return ( "[&](double *x, double *p) { "
+                   + Normal(iFirstParam)
+                   + Pol(degree,iFirstParam+3)
+                   + "return pol(x,p) + normal(x,p); }" );
+        }
+
+        /// lambda function for signal + background
+        inline std::string AsymNormalPolFitFunc( const int degree,
+                                                 const unsigned int iFirstParam = 0 ) const noexcept
+        {
+          return ( "[&](double *x, double *p) { "
+                   + AsymNormal(iFirstParam)
+                   + Pol(degree,iFirstParam+4)
+                   + "return pol(x,p) + normal(x,p); }" );
+        }
+
+        /// lambda function for hyperbol background only
+        inline std::string HyperbolFitFunc( const unsigned int iFirstParam = 0 ) const noexcept
         {
           return ( "[&](double *x, double *p) { "
                    + Hyperbolic(iFirstParam)
-                   + "return hyperbol; }" );
+                   + "return hyperbol(x,p); }" );
+        }
+
+        /// lambda function for pol background only
+        inline std::string PolFitFunc( const int degree,
+                                       const unsigned int iFirstParam = 0 ) const noexcept
+        {
+          return ( "[&](double *x, double *p) { "
+                   + Pol(degree,iFirstParam)
+                   + "return pol(x,p); }" );
+        }
+
+        /// lambda function for skewed normal signal
+        inline std::string SkewedNormalFitFunc( const unsigned int iFirstParam = 0 ) const noexcept
+        {
+          return ( "[&](double *x, double *p) { "
+                   + SkewedNormal(iFirstParam)
+                   + "return normal(x,p); }" );
+        }
+
+        /// lambda function for skewed normal signal + polynominal background
+        inline std::string SkewedNormalPolFitFunc( const unsigned int degree,
+                                                   const unsigned int iFirstParam = 0 ) const noexcept
+        {
+          return ( "[&](double *x, double *p) { "
+                   + SkewedNormal(iFirstParam)
+                   + Pol(degree,iFirstParam+4)
+                   + "return pol(x,p) + normal(x,p); }" );
+        }
+
+        /// lambda function for skewed normal signal + hyperbolic background
+        inline std::string SkewedNormalHyperbolFitFunc( const unsigned int iFirstParam = 0 ) const noexcept
+        {
+          return ( "[&](double *x, double *p) { "
+                   + SkewedNormal(iFirstParam)
+                   + Hyperbolic(iFirstParam+4)
+                   + "return hyperbol(x,p) + normal(x,p); }" );
         }
         
       public:  // Fit Quality options
 
         /// Maximum abs fitted mean for OK fit
-        std::array<double,2> RichMaxMean      { {  0.006,    0.003   } };
+        std::array<double,NRads> RichMaxMean      { {  0.006,    0.003   } };
         /// Maximum abs fitted sigma for OK fit
-        std::array<double,2> RichMaxSigma     { {  0.010,    0.005   } };
+        std::array<double,NRads> RichMaxSigma     { {  0.010,    0.005   } };
         /// Maximum shift error for OK fit
-        std::array<double,2> MaxShiftError    { {  0.001,    0.001   } };
+        std::array<double,NRads> MaxShiftError    { {  0.001,    0.001   } };
         /// Maximum resolution error for OK fit
-        std::array<double,2> MaxSigmaError    { {  0.0002,   0.0001  } };
+        std::array<double,NRads> MaxSigmaError    { {  0.0002,   0.0001  } };
 
       };
       
@@ -200,7 +340,7 @@ namespace Rich
       }
 
       /// Get the RICH array index from enum
-      inline int rIndex( const Rich::RadiatorType rad ) const noexcept
+      inline std::uint8_t rIndex( const Rich::RadiatorType rad ) const noexcept
       {
         return ( Rich::Rich1Gas == rad ? 0 : 1 );
       }
diff --git a/Rich/RichRecUtils/src/RichCKResolutionFitter.cpp b/Rich/RichRecUtils/src/RichCKResolutionFitter.cpp
index 346744edfb29d2a35851b24286c29d6570bc20a4..df294860b2910371b9f6047e512de93d4f107622 100644
--- a/Rich/RichRecUtils/src/RichCKResolutionFitter.cpp
+++ b/Rich/RichRecUtils/src/RichCKResolutionFitter.cpp
@@ -5,6 +5,9 @@
 #include <TMath.h>
 #include <TFitResult.h>
 
+// boost
+#include "boost/algorithm/string.hpp"
+
 using namespace Rich::Rec;
 
 //=============================================================================
@@ -47,6 +50,18 @@ CKResolutionFitter::fitImp( TH1& hist,
   // which RICH ?
   const auto rIn = rIndex(rad);
 
+  // Extract the signal and background forms from the fit type
+  std::vector<std::string> fitOps;
+  boost::split( fitOps, fitType, boost::is_any_of(":") );
+  // Must have exactly two splits signal:background
+  if ( fitOps.size() != 2 )
+  {
+    std::cerr << "Unknown fit type " << fitType << std::endl;
+    return fitRes;
+  }
+  const auto sigType = fitOps[0];
+  const auto bkgType = fitOps[1];
+
   // Firstly do a prefit
 
   // delta for the pre-fit
@@ -65,7 +80,8 @@ CKResolutionFitter::fitImp( TH1& hist,
   fitMax = xPeak + delta;
 
   // Do the pre-fit
-  const std::string preFitFName = "Rad" + std::to_string(rad) + "PreFitF";
+  //std::cout << rad << " Prefit" << std::endl;
+  const auto preFitFName = "Rad" + std::to_string(rad) + "PreFitF";
   TF1 preFitF( preFitFName.c_str(), "gaus", fitMin, fitMax );
   // Estimate overall scale from max bin
   preFitF.SetParameter( 0, yPeak );
@@ -75,6 +91,7 @@ CKResolutionFitter::fitImp( TH1& hist,
   preFitF.SetParameter( 2, params().RichStartRes[rIn] );
   // run the pre-fit
   const auto preFitR = hist.Fit( &preFitF, "MQRS0" );
+  //const auto preFitR = hist.Fit( &preFitF, "MRS0" );
   
   // Fit result status
   auto & fitOK = fitRes.fitOK;
@@ -93,8 +110,13 @@ CKResolutionFitter::fitImp( TH1& hist,
     fitMin = params().RichFitMin[rIn];
     fitMax = params().RichFitMax[rIn];
 
+    // Number of signal parameters
+    const bool isSkewed = "SkewedNormal" == sigType;
+    const bool isAsym   = "AsymNormal"   == sigType;
+    const unsigned int nSigParams = 4; // all forms have 4 parms (1 sometimes fixed).
+
     // Fit Type
-    if ( "FreeNPol" == fitType )
+    if ( "FreeNPol" == bkgType )
     {
       // Full free polynominal form for background
 
@@ -114,33 +136,65 @@ CKResolutionFitter::fitImp( TH1& hist,
       // Loop over poly orders
       for ( unsigned int nPol = 1; nPol < nPolFull+1; ++nPol )
       {
+
+        //std::cout << rad << " Pol " << nPol << " Fit" << std::endl;
         const auto fFitFName = "Rad" + std::to_string(rad) + "fFitF" + std::to_string(nPol);
-        const auto fFitFType = "gaus(0)+pol" + std::to_string(nPol) + "(3)" ;
-        TF1 fFitF( fFitFName.c_str(), fFitFType.c_str(), fitMin, fitMax );
-        
-        const unsigned int nParamsToSet = ( nPol > 1 ? 3 + nPol : 3 );
-        for ( unsigned int p = 0; p < nParamsToSet; ++p )
-        {
-          fFitF.SetParameter(p,lastFitF.GetParameter(p));
+        const auto fFitFType = ( isSkewed ? 
+                                 params().SkewedNormalPolFitFunc(nPol,0) :
+                                 params().AsymNormalPolFitFunc(nPol,0) );
+        TF1 fFitF( fFitFName.c_str(), fFitFType.c_str(), fitMin, fitMax, nSigParams+nPol+1 );
+
+        // set parameters from last fit
+        // If first iteration, just 3 Gaussian params otherwise number from last full fit
+        const auto nPToSet = ( 1 == nPol ? 3 : nSigParams + nPol );
+        for ( unsigned int i = 0; i < nPToSet; ++i )
+        { 
+          const auto p = lastFitF.GetParameter(i);
+          //std::cout << "  -> Setting param " << i << " to " << p << std::endl;
+          fFitF.SetParameter(i,p);
         }
 
         // set the gaussian parameter names
         fFitF.SetParName(0,"Gaus Const");
         fFitF.SetParName(1,"Gaus Mean");
         fFitF.SetParName(2,"Gaus Sigma");
+        fFitF.SetParName(3,"Gaus Asym");
         // Set the background parameter names
-        for ( int i = 3; i < fFitF.GetNpar(); ++i )
-        { fFitF.SetParName( i, ("Bkg Par "+std::to_string(i-3)).c_str() ); }
-        
-        // run the fit
-        const auto fitR = hist.Fit( &fFitF, minuitOpts.c_str() );
-        const auto validFit = fitIsValid( fitR );
-        
+        for ( int i = nSigParams; i < fFitF.GetNpar(); ++i )
+        { fFitF.SetParName( i, ("Bkg Par "+std::to_string(i-nSigParams)).c_str() ); }
+
+        // First time, fix par 3
+        fFitF.FixParameter( 3, params().RichStartAsym[rIn] ); 
+
+        // run the fit with no asymmetry
+        auto fitR     = hist.Fit( &fFitF, minuitOpts.c_str() );
+        auto validFit = fitIsValid( fitR );
+        fitOK         = validFit && fitIsOK(fFitF,rad);
+
         // save the last fit
         lastFitF = fFitF;
-        
-        // Fit OK?
-        fitOK = validFit && fitIsOK(fFitF,rad);
+
+        // If doing Asym Gauss fit, run again with that param released
+        if ( fitOK && ( isAsym || isSkewed ) )
+        {
+          fFitF.ReleaseParameter(3);
+          fFitF.SetParameter( 3, params().RichStartAsym[rIn] );
+          // limit asymmetry to at most +-20%
+          if ( isAsym ) { fFitF.SetParLimits(3,-0.2,0.2); }
+          // run the fit
+          fitR            = hist.Fit( &fFitF, minuitOpts.c_str() );
+          const auto vFit = fitIsValid( fitR );
+          const auto ok   = vFit && fitIsOK(fFitF,rad);
+          if ( ok )
+          {
+            validFit = vFit;
+            fitOK    = ok;
+            // save the last fit
+            lastFitF = fFitF;
+          }
+        }
+
+        // Save end fit result ?
         if ( fitOK )
         {
           bestFitF = fFitF;
@@ -165,7 +219,7 @@ CKResolutionFitter::fitImp( TH1& hist,
                                fitMin, fitMax );
 
     }
-    else if ( "FixedNPol" == fitType )
+    else if ( "FixedNPol" == bkgType )
     {
       // Fixed free polynominal form for background
 
@@ -175,7 +229,7 @@ CKResolutionFitter::fitImp( TH1& hist,
       //const std::string minuitOpts = "MRS0";
 
       const auto fFitFName = "Rad" + std::to_string(rad) + "fFitF";
-      const std::string fFitFType = "gaus(0)+[3]*"+params().RichFixedNPolFunc(rad,4);
+      const auto fFitFType = "gaus(0)+[3]*"+params().RichFixedNPolFunc(rad,4);
       TF1 fFitF( fFitFName.c_str(), fFitFType.c_str(), fitMin, fitMax );
 
       // Set starting gauss parameters
@@ -207,7 +261,7 @@ CKResolutionFitter::fitImp( TH1& hist,
                                fitMin, fitMax );
 
     }
-    else if ( "Hyperbolic" == fitType )
+    else if ( "Hyperbolic" == bkgType )
     {
 
       // Background : y = ( A - sqrt( B + C*(x-D)^2 ) )
@@ -219,28 +273,34 @@ CKResolutionFitter::fitImp( TH1& hist,
 
       // Full signal + Hyperbolic background function
       const auto fFitFName = "Rad" + std::to_string(rad) + "fFitF";
-      const auto fFitFType = params().GaussHyperbolFitFunc(0);
-      TF1 fFitF( fFitFName.c_str(), fFitFType.c_str(), fitMin, fitMax, 8 );
+      const auto fFitFType = ( isSkewed ? 
+                               params().SkewedNormalHyperbolFitFunc(0) :
+                               params().AsymNormalHyperbolFitFunc(0) );
+      TF1 fFitF( fFitFName.c_str(), fFitFType.c_str(), fitMin, fitMax, 9 );
 
       // Set starting gauss parameters
       for ( const int i : {0,1,2} )
       { fFitF.SetParameter( i, preFitF.GetParameter(i) ); }
 
+      // Fix the asym for now
+      fFitF.FixParameter( 3, params().RichStartAsym[rIn] ); 
+
       // Start background level at 0
-      for ( const int i : {3,4,5,6,7} )
+      for ( const int i : {4,5,6,7,8} )
       { fFitF.SetParameter( i, 0 ); }
 
       // set the signal parameter names
       fFitF.SetParName(0,"Gaus Const");
       fFitF.SetParName(1,"Gaus Mean");
       fFitF.SetParName(2,"Gaus Sigma");
+      fFitF.SetParName(3,"Gaus Asym");
 
       // background scale factor
-      fFitF.SetParName(3,"Hyper A");
-      fFitF.SetParName(4,"Hyper B");
-      fFitF.SetParName(5,"Hyper C -ve");
-      fFitF.SetParName(6,"Hyper C +ve");
-      fFitF.SetParName(7,"Hyper D");
+      fFitF.SetParName(4,"Hyper A");
+      fFitF.SetParName(5,"Hyper B");
+      fFitF.SetParName(6,"Hyper C -ve");
+      fFitF.SetParName(7,"Hyper C +ve");
+      fFitF.SetParName(8,"Hyper D");
 
       // Side band fits to get C slope parameters
       TF1 sideBmF( (fFitFName+"SideBm").c_str(), "pol1", 
@@ -255,10 +315,10 @@ CKResolutionFitter::fitImp( TH1& hist,
       const auto CpInit = std::pow( sideBpF.GetParameter(1), 2 );
 
       // Fix some of the background terms
-      fFitF.FixParameter(4,params().HyperInitB[rIn]);  // B
-      fFitF.FixParameter(5,CmInit);                    // C -ve
-      fFitF.FixParameter(6,CpInit);                    // C +ve
-      fFitF.FixParameter(7,params().HyperInitD[rIn]);  // D
+      fFitF.FixParameter(5,params().HyperInitB[rIn]);  // B
+      fFitF.FixParameter(6,CmInit);                    // C -ve
+      fFitF.FixParameter(7,CpInit);                    // C +ve
+      fFitF.FixParameter(8,params().HyperInitD[rIn]);  // D
       
       // run the fit with all but the overall background scale set
       auto fitR = hist.Fit( &fFitF, minuitOpts.c_str() );
@@ -266,8 +326,8 @@ CKResolutionFitter::fitImp( TH1& hist,
       if ( validFitA ) { bestFitF = fFitF; }
 
       // Release C and refit
-      fFitF.ReleaseParameter(5);
       fFitF.ReleaseParameter(6);
+      fFitF.ReleaseParameter(7);
       fitR = hist.Fit( &fFitF, minuitOpts.c_str() );
       const bool validFitB = fitIsValid(fitR);
       if ( validFitB ) { bestFitF = fFitF; }
@@ -276,7 +336,7 @@ CKResolutionFitter::fitImp( TH1& hist,
       bool validFitC = false;
       //if ( validFitB )
       {
-        fFitF.ReleaseParameter(7);
+        fFitF.ReleaseParameter(8);
         fitR = hist.Fit( &fFitF, minuitOpts.c_str() );
         validFitC = fitIsValid(fitR) && fitIsOK(fFitF,rad);
         if ( validFitC ) { bestFitF = fFitF; }
@@ -286,14 +346,33 @@ CKResolutionFitter::fitImp( TH1& hist,
       bool validFitD = false;
       //if ( validFitC )
       {
-        fFitF.ReleaseParameter(4);
+        fFitF.ReleaseParameter(5);
         fitR = hist.Fit( &fFitF, minuitOpts.c_str() );
         validFitD = fitIsValid(fitR) && fitIsOK(fFitF,rad);
         if ( validFitD ) { bestFitF = fFitF; }
       }
 
+      // Release asym/skew param
+      if ( validFitD && ( isAsym || isSkewed ) )
+      {
+        fFitF.ReleaseParameter(3);
+        fitR = hist.Fit( &fFitF, minuitOpts.c_str() );
+        validFitD = fitIsValid(fitR) && fitIsOK(fFitF,rad);
+        if ( validFitD ) { bestFitF = fFitF; }
+      }
+      
       // final OK status based on best fit
-      fitOK = ( validFitD || validFitC );
+      fitOK = ( "AsymNormal" == sigType ? validFitD : // for asym fit all must be ok
+                validFitD || validFitC );             // otherwise use either of last 2
+
+      // Check B is not too small compared to C
+      if ( fitOK )
+      {
+        const auto cm = fabs( fFitF.GetParameter(6) );
+        const auto cp = fabs( fFitF.GetParameter(7) );
+        const auto b  = fabs( fFitF.GetParameter(5) );
+        fitOK = ( cm < b*1e7 && cp < b*1e7 ); 
+      }
       
       // Setup the background function 
       fitRes.bkgFitFunc = TF1( "Background", 
@@ -303,17 +382,17 @@ CKResolutionFitter::fitImp( TH1& hist,
     }
     else
     {
-      std::cerr << "Unknown fit type " << fitType << std::endl;
+      std::cerr << "Unknown background type " << bkgType << std::endl;
     }
 
     // Set the background function parameters
-    for ( int i = 3; i < bestFitF.GetNpar(); ++i )
+    for ( int i = nSigParams; i < bestFitF.GetNpar(); ++i )
     {
-      fitRes.bkgFitFunc.SetParameter( i-3, bestFitF.GetParameter(i) );
-      fitRes.bkgFitFunc.SetParError ( i-3, bestFitF.GetParError(i)  );
-      fitRes.bkgFitFunc.SetParName  ( i-3, bestFitF.GetParName(i)   );
+      fitRes.bkgFitFunc.SetParameter( i-nSigParams, bestFitF.GetParameter(i) );
+      fitRes.bkgFitFunc.SetParError ( i-nSigParams, bestFitF.GetParError(i)  );
+      fitRes.bkgFitFunc.SetParName  ( i-nSigParams, bestFitF.GetParName(i)   );
     }
-  
+
     // Final sanity check on the fit results
     // limits on fit sigma and mean, to detect complete failures such as when there
     // is no Cherenkov signal at all