diff --git a/Cpp/lib/uniformization.cpp b/Cpp/lib/uniformization.cpp
index fdfe017778d3d7371ca8abdc7693e0aa7c01fbbf..438815263305977ad90d3cf292465bbeb34ba1a6 100644
--- a/Cpp/lib/uniformization.cpp
+++ b/Cpp/lib/uniformization.cpp
@@ -86,6 +86,8 @@ void Uniformization::run(
         std::filesystem::create_directory(figSavePath);
     }
     std::filesystem::path dataSavePath = savePath;
+    auto wfmSavePath = dataSavePath / "initWfmParam.csv";
+    waveform.saveParam(wfmSavePath);
 
     auto detProbe = npy::read_npy<double>(probePath).data;
     std::reverse(detProbe.begin(), detProbe.end());
@@ -116,7 +118,7 @@ void Uniformization::run(
     std::vector<double> finalPower = initPower;
     for (int i = 0; i < config.maxLoop; i++) {
         std::cout << "\r" << "running uniformization "
-            << "loop " << i+1 << "/" << config.maxLoop << std::flush;
+            << "loop " << i+1 << "/" << config.maxLoop << ", ";
         auto twzrImage = grabMulti(basler, config.numImgingAvg);
         auto twzrCrops = ImageProcessing::getSubImgs(
             twzrImage,
@@ -128,18 +130,25 @@ void Uniformization::run(
             weightedMask * powersEigen 
             - (weightedMask * powersEigen).mean()
         ) / (weightedMask * powersEigen).mean();
+        std::cout << "mean abs error: " << std::setprecision(4) << std::fixed
+            << powerErrs.abs().mean() << std::flush;
+        if (powerErrs.abs().mean() <= config.errorThreshold) { break; }
+
         auto amps = waveform.getAmplitude();
         Eigen::Map<Eigen::ArrayXd> ampsEigen(amps.data(), amps.size());
         ampsEigen -= config.stepSize * powerErrs;
         waveform.setAmplitude(amps);
         reloadAWG(awg, waveform);
 
-        powerErrTotal.push_back(powerErrs.abs().sum());
+        powerErrTotal.push_back(powerErrs.abs().mean());
         if (i == config.maxLoop - 1) {
             finalPower = powers;
             std::cout << std::endl;
         }
     }
+    auto finalWfmSavePath = dataSavePath / "finalWfmParam.csv";
+    waveform.saveParam(finalWfmSavePath);
+    
     auto initPowerFile = dataSavePath / "initial_power.csv";
     auto finalPowerFile = dataSavePath / "final_power.csv";
     auto errorFile = dataSavePath / "errors.csv";
diff --git a/Cpp/lib/uniformization.h b/Cpp/lib/uniformization.h
index 3fd4b6093754a6fb00ae30ba5b14f553f78dd5ae..63766949a6ef4b3db925b1d121c6656cf57bee2f 100644
--- a/Cpp/lib/uniformization.h
+++ b/Cpp/lib/uniformization.h
@@ -11,6 +11,7 @@ namespace Uniformization {
         double polarizability;
         double meanDepth;
         double stepSize;
+        double errorThreshold;
         int maxLoop;
         int numImgingAvg;
         int numTweezer;