diff --git a/pub/src/curve.cpp b/pub/src/curve.cpp
index 6f681886afdac8bff184eade62449253615ccc24..c434d2dd5003688dc20e2cd61ba24f02902be0f3 100644
--- a/pub/src/curve.cpp
+++ b/pub/src/curve.cpp
@@ -183,10 +183,13 @@ void NCurveFile::ChangeExpr()
 
 void NCurveFile::ChangeRange()
 {
+    NOlm::IterateC fiter;
+    if( !(fiter.size()) )
+        throw "no curve to operate on";
+
     string expr = sask(
         "Fit range restriction (expr to be evaluated as boolean) ?" );
         
-    NOlm::IterateC fiter;
     POlc fc;
     while( (fc=fiter()) ) {
         fc->range_expr = expr;
@@ -207,6 +210,9 @@ void NCurveFile::ChangeRange()
 void NCurveFile::SetAllPars(void)
 {
     NOlm::IterateC fiter;
+    if( !(fiter.size()) )
+        throw "no curve to operate on";
+
     POlc fin;
     while( (fin=fiter()) ) {
         for( int ip=0; ip<fin->nPar(); ++ip )
@@ -300,55 +306,25 @@ string COlc::pInfoCat() const
 
 //! Fix or unfix curve parameters.
 
-void NCurveFile::SetFixed()
+void NCurveFile::SetFixed( bool fix )
 {
-    // Everything is driven by one input string
-    string lin;
-    while ( true ) {
-        lin = sask( "Change fix status", "help" );
-        if        ( lin=="h" || lin=="help" ) {
-            cout <<
-                "cx input:\n"
-                "  blank separated list of instructions\n"
-                "instruction:\n"
-                "  <ip>+         # to make parameter number ip fixed\n"
-                "  <ip>-         # to release the fixation\n"
-                "  <ip>=<j-list> # to fix the parameter for spectra in j-list\n";
-            continue;
-        } else if ( lin=="q" )
-            return;
-        break;
-    }
+    NOlm::IterateC fiter;
+    if( !(fiter.size()) )
+        throw "no curve to operate on";
+
+    static string sel;
+    sel = wask( string(fix?"Fix":"Unfix") + " which parameters", sel );
+    if( sel=="" )
+        return;
 
-    boost::regex re1( "\\s+" );
-    boost::regex re2( "(\\d+)(\\+|\\-|\\=)(.*)" );
-
-    // Split input string in words
-    boost::sregex_token_iterator _wrd( lin.begin(), lin.end(), re1, -1 );
-    while ( _wrd!=boost::sregex_token_iterator() ) {
-        // Parse one instruction
-        string wrd = *_wrd++;
-        boost::smatch tokens;
-        if( !boost::regex_match( wrd, tokens, re2 ) )
-            throw "invalid instruction "+wrd;
-        if ( tokens[2]!="=" && tokens[3]!="" )
-            throw "invalid instruction "+wrd;
-        int ip;
-        if( !mystd::any2int( tokens[1], &ip ) )
-            throw string( "BUG: unreadable ip in spite of match" );
-        // Loop over selected curve files
-        NOlm::IterateC fiter;
-        POlc f;
-        while( (f=fiter()) ) {
-            if( ip>=f->nPar() )
-                throw string( "invalid parameter number" );
+    POlc f;
+    while( (f=fiter()) ) {
+        CList lis( sel, 0, f->nPar()-1 );
+        for( uint iv=0; iv<lis.size(); ++iv ) {
             for( uint j=0; j<f->nJ(); ++j ){
                 if ( f->ProtectedSpecs.contains(j) )
                     continue;
-                if      ( tokens[2] == "+" )
-                    f->VC(j)->fixed[ip] = true;
-                else if ( tokens[2] == "-" )
-                    f->VC(j)->fixed[ip] = false;
+                f->VC(j)->fixed[lis.V[iv]] = fix;
             }
         }
     }
diff --git a/pub/src/curve.h b/pub/src/curve.h
index fafc0c701d2a1b901d3b072fc0822069c773efc2..22fa8612a8a15dd04ca068e371df71a8dd207894 100644
--- a/pub/src/curve.h
+++ b/pub/src/curve.h
@@ -23,7 +23,7 @@ namespace NCurveFile {
     void SetAllPars();
     void ShowPar();
     void EditPar();
-    void SetFixed();
+    void SetFixed( bool fix );
 
     void SetFitTuningPars( string which );
     void Fit( bool _allow_slow_conv );
diff --git a/pub/src/frida2.cpp b/pub/src/frida2.cpp
index 2d838b65af6732c3d8ebb3015812a5314e9ab0b1..dd6a4b730349775bb1fa76cef046c512e0d1616a 100644
--- a/pub/src/frida2.cpp
+++ b/pub/src/frida2.cpp
@@ -152,7 +152,8 @@ int main()
                     "Fit to data:\n"
                     "  cf   fit\n"
                     "  cfs  fit, allow slow convolution\n"
-                    "  cx   toggle fixed (also: cx+ cx-)\n"
+                    "  cx   fix parameters\n"
+                    "  cu   unfix parameters\n"
                     "  cwc  weighing: constant\n"
                     "  cwl  weighing: logarithmic\n"
                     "  cwv  weighing: reciprocal variance (default)\n"
@@ -200,7 +201,9 @@ int main()
             } else if (cmd == "cfs") {
                 NCurveFile::Fit( true );
             } else if (cmd == "cx") {
-                NCurveFile::SetFixed();
+                NCurveFile::SetFixed( true );
+            } else if (cmd == "cu") {
+                NCurveFile::SetFixed( false );
             } else if (cmd.substr(0,2) == "cw") {
                 NCurveFile::SetProperties( cmd.substr(1) );
 
diff --git a/pub/src/mem.h b/pub/src/mem.h
index 4eafc8c57a70bb3b9cbab9464a3e6c9bb64c5930..4ed87a86e5990582e751abf382195b739eda39da 100644
--- a/pub/src/mem.h
+++ b/pub/src/mem.h
@@ -39,7 +39,7 @@ namespace NOlm {
         void choose_all() { Sel = CList(0,MOM.size()-1); };
         uint k() const { return Sel.V[iV-1]; }
         uint iteration() const { return iV-1; }
-        uint size() const { return Sel.V.size(); }
+        virtual uint size() const =0;
     };
     class IterateO : public IterateBase { // all types
     public:
@@ -47,6 +47,7 @@ namespace NOlm {
             if (iV>=Sel.size()) return POlo();
             return MOM[Sel.V[iV++]];
         };
+        uint size() const { return Sel.V.size(); }
     };
     class IterateD : public IterateBase { // must be data file
     public:
@@ -55,6 +56,13 @@ namespace NOlm {
             while ( iV<Sel.size() && !(e = P2D( MOM[Sel.V[iV++]] )) ) {};
             return e;
         };
+        uint size() const {
+            uint ret = 0;
+            for ( uint ii=0; ii<Sel.size(); ++ii )
+                if ( P2D( MOM[Sel.V[ii]] ) )
+                    ++ret;
+            return ret;
+        }
     };
     class IterateC : public IterateBase { // must be curve file
     public:
@@ -63,5 +71,12 @@ namespace NOlm {
             while ( iV<Sel.size() && !(e = P2C( MOM[Sel.V[iV++]] )) ) {};
             return e;
         };
+        uint size() const {
+            uint ret = 0;
+            for ( uint ii=0; ii<Sel.size(); ++ii )
+                if ( P2C( MOM[Sel.V[ii]] ) )
+                    ++ret;
+            return ret;
+        }
     };
 };