[us-commits] r2788 - in trunk: gui programs/us_2dsa programs/us_convert programs/us_experiment programs/us_fematch utils

svn at svn.aucsolutions.com svn at svn.aucsolutions.com
Fri Jul 5 08:13:30 MDT 2019


Author: gegorbet
Date: 2019-07-05 14:13:28 +0000 (Fri, 05 Jul 2019)
New Revision: 2788

Modified:
   trunk/gui/us_solution_gui.cpp
   trunk/programs/us_2dsa/us_2dsa.cpp
   trunk/programs/us_convert/us_convert.cpp
   trunk/programs/us_convert/us_convert.h
   trunk/programs/us_convert/us_convert_gui.cpp
   trunk/programs/us_convert/us_convert_gui.h
   trunk/programs/us_experiment/us_exp_utils.cpp
   trunk/programs/us_fematch/us_fematch.cpp
   trunk/utils/us_astfem_math.cpp
   trunk/utils/us_astfem_math.h
   trunk/utils/us_simparms.cpp
Log:
import (convert) option w low accel rate to adjust speed step, plus general accel-adjust options, including for 3krpm leak test cases

Modified: trunk/gui/us_solution_gui.cpp
===================================================================
--- trunk/gui/us_solution_gui.cpp	2019-06-29 01:00:53 UTC (rev 2787)
+++ trunk/gui/us_solution_gui.cpp	2019-07-05 14:13:28 UTC (rev 2788)
@@ -816,7 +816,7 @@
    // Let's calculate if we're eligible to save this solution
    //pb_save         -> setEnabled( false );
 
-DbgLv(1) << "We are at RESET_1: ";
+DbgLv(1) << "We are at RESET_1:  aInf count" << solution->analyteInfo.count();
 
    if ( ! bufferDesc.isEmpty() ) //we can have a solution with buffer only
    {
@@ -840,6 +840,7 @@
 
       lw_analytes->addItem( item );
    }
+DbgLv(1) << "We are at RESET_2:  aInf count" << solution->analyteInfo.count() << ai.size();
 
    // Turn the red label back
    //QPalette p = lb_amount->palette();
@@ -872,14 +873,21 @@
    //    : "";
 
    // le_investigator->setText( number +  US_Settings::us_inv_name() );
+DbgLv(1) << "We are at RESET_9:  aInf count" << solution->analyteInfo.count() << ai.size();
 }
 
 // Function to handle when solution listwidget item is selected
 void US_SolutionMgrSelect::selectAnalyte( QListWidgetItem* item )
 {
+qDebug() << "Sol:SselAna: IN";
    // Get the right index in the sorted list, and load the amount
+qDebug() << "Sol:SselAna:  aMap count" << analyteMap.size();
    int ndx = analyteMap[ item ];
+qDebug() << "Sol:SselAna:  ndx" << ndx;
+qDebug() << "Sol:SselAna:  aInf count" << solution->analyteInfo.size();
+qDebug() << "Sol:SselAna:  amt" << solution->analyteInfo[ ndx ].amount;
    le_amount ->setText( QString::number( solution->analyteInfo[ ndx ].amount ) );
+qDebug() << "Sol:SselAna:  amt" << le_amount->text();
 
    QPalette p = lb_amount->palette();
    p.setColor( QPalette::WindowText, Qt::red );
@@ -1290,8 +1298,11 @@
 // Function to handle when solution listwidget item is selected
 void US_SolutionMgrNew::selectAnalyte( QListWidgetItem* item )
 {
+qDebug() << "Sol:NselAna: IN";
    // Get the right index in the sorted list, and load the amount
+qDebug() << "Sol:NselAna:  aMap count" << analyteMap.size();
    int ndx = analyteMap[ item ];
+qDebug() << "Sol:NselAna:  ndx" << ndx;
    ct_amount ->setValue( solution->analyteInfo[ ndx ].amount );
 
    // Now turn the label red to catch attention

Modified: trunk/programs/us_2dsa/us_2dsa.cpp
===================================================================
--- trunk/programs/us_2dsa/us_2dsa.cpp	2019-06-29 01:00:53 UTC (rev 2787)
+++ trunk/programs/us_2dsa/us_2dsa.cpp	2019-07-05 14:13:28 UTC (rev 2788)
@@ -1125,7 +1125,7 @@
  << rspeed << accel1 << tf_aend << tf_scan
  << "accel2" << accel2 << "lo_ss_acc" << lo_ss_acc;
 //x0  1  2  3  4  5
-   if ( accel1 < lo_ss_acc  ||  tf_aend > ( tf_scan - 6 ) )
+   if ( accel1 < lo_ss_acc  ||  tf_aend > ( tf_scan - 3 ) )
    {
       QString wmsg = tr( "The TimeState used is likely bad:<br/>"
                          "The acceleration implied is %1 rpm/sec.<br/>"

Modified: trunk/programs/us_convert/us_convert.cpp
===================================================================
--- trunk/programs/us_convert/us_convert.cpp	2019-06-29 01:00:53 UTC (rev 2787)
+++ trunk/programs/us_convert/us_convert.cpp	2019-07-05 14:13:28 UTC (rev 2788)
@@ -1062,3 +1062,103 @@
 
    if ( excluded ) qDebug() << "excluded";
 }
+
+// Adjusts times and omegas in AUCs and speedsteps so that
+//  the first speed step acceleration is 400 rpm/second.
+int US_Convert::adjustSpeedstep( QVector< US_DataIO::RawData >& allData,
+     QVector< US_SimulationParameters::SpeedProfile >& speedsteps )
+{
+   int stat          = 0;
+
+   // Re-check that there is a problem with low acceleration.
+   //  [ See comments for US_AstfemMath::low_acceleration() ]
+   const double tfac = ( 4.0 / 3.0 );
+   double t2         = speedsteps[ 0 ].time_first;
+   double w2t        = speedsteps[ 0 ].w2t_first;
+   double om1t       = speedsteps[ 0 ].rotorspeed * M_PI / 30.0;
+   double w2         = sq( om1t );
+   double t1w        = w2t / w2;
+   double t1         = tfac * ( t2 - t1w );
+
+   if ( t1 >= t2 )
+   {  // Something wrong!  set t1 to a few seconds before t2
+      t1             = t2 - 5.0;
+   }
+
+   int t_acc      = (int)qRound( t1 );
+   t1             = (double)t_acc;
+   double rate    = (double)( speedsteps[ 0 ].rotorspeed ) / t1;
+qDebug() << "CVT:Adj: t_acc rate" << t_acc << rate;
+
+   if ( rate >= 250.0 )
+   {  // No adjustment will be done, since acceleration is large enough.
+      return 1;
+   }
+
+   // Determine time and omega offsets. A "t0" value is initially time-zero,
+   //  the beginning of the first acceleration zone. Using an acceleration
+   //  of 400.0 rpm/second, a new zone start is determined and that becomes
+   //  the time offset to subtract from all AUC and speedstep times. The
+   //  omega^2t offset is based on the value at the new zone start.
+   double azdur      = (double)qRound( speedsteps[ 0 ].rotorspeed / 400.0 );
+   double t_offs     = t1 - azdur;
+   double azwrate    = sq( rate * M_PI / 30.0 );
+   double w_offs     = w2t - ( w2 * ( t2 - t1 ) ) - ( azwrate * azdur );
+qDebug() << "CVT:Adj: azdur azwrate" << azdur << azwrate << "t_offs w_offs"
+ << t_offs << w_offs;
+
+   for ( int ii = 0; ii < allData.count(); ii++ )
+   {  // Adjust scan times,omegas so t0 is zero
+      US_DataIO::RawData* rdata = &allData[ ii ];
+      for ( int jj = 0; jj < rdata->scanCount(); jj++ )
+      {
+qDebug() << "CVT:Adj:  t w" << rdata->scanData[ jj ].seconds
+ << rdata->scanData[ jj ].omega2t << "ii jj" << ii << jj;
+         rdata->scanData[ jj ].seconds  -= t_offs;
+         rdata->scanData[ jj ].omega2t  -= w_offs;
+qDebug() << "CVT:Adj:    new t w" << rdata->scanData[ jj ].seconds
+ << rdata->scanData[ jj ].omega2t;
+      }
+   }
+
+   for ( int ii = 0; ii < speedsteps.count(); ii++ )
+   {  // Adjust speed step times,omegas
+qDebug() << "CVT:Adj:  tf tl" << speedsteps[ii].time_first
+ << speedsteps[ii].time_last << "wf wl" << speedsteps[ii].w2t_first
+ << speedsteps[ii].w2t_last;
+      speedsteps[ ii ].time_first  -= t_offs;
+      speedsteps[ ii ].w2t_first   -= w_offs;
+      speedsteps[ ii ].time_last   -= t_offs;
+      speedsteps[ ii ].w2t_last    -= w_offs;
+      speedsteps[ ii ].acceleration = 400;
+qDebug() << "CVT:Adj:   new tf tl" << speedsteps[ii].time_first
+ << speedsteps[ii].time_last << "wf wl" << speedsteps[ii].w2t_first
+ << speedsteps[ii].w2t_last;
+
+      if ( ii == 0 )
+      {  // For 1st step, adjust duration and delay-to-1st-scan
+         double dur_sec    =  speedsteps[ ii ].duration_hours * 3600
+                            + speedsteps[ ii ].duration_minutes * 60.0
+                            - t_offs;
+         double dur_min    = dur_sec / 60.0;
+         int    dur_hrs    = (int)( dur_min / 60.0 );
+         dur_min           = dur_min - ( dur_hrs * 60 );
+         speedsteps[ ii ].duration_hours   = dur_hrs;
+         speedsteps[ ii ].duration_minutes = dur_min;
+         double dly_sec    =  speedsteps[ ii ].delay_hours * 3600
+                            + speedsteps[ ii ].delay_minutes * 60.0
+                            - t_offs;
+         double dly_min    = dly_sec / 60.0;
+         int    dly_hrs    = (int)( dly_min / 60.0 );
+         dly_min           = dly_min - ( dly_hrs * 60 );
+         speedsteps[ ii ].delay_hours   = dly_hrs;
+         speedsteps[ ii ].delay_minutes = dly_min;
+qDebug() << "CVT:Adj:   new dur" << speedsteps[ii].duration_hours
+ << speedsteps[ii].duration_minutes << "new dly" << speedsteps[ii].delay_hours
+ << speedsteps[ii].delay_minutes;
+      }
+   }
+
+   return stat;
+}
+

Modified: trunk/programs/us_convert/us_convert.h
===================================================================
--- trunk/programs/us_convert/us_convert.h	2019-06-29 01:00:53 UTC (rev 2787)
+++ trunk/programs/us_convert/us_convert.h	2019-07-05 14:13:28 UTC (rev 2788)
@@ -5,6 +5,7 @@
 #include "us_extern.h"
 #include "us_dataIO.h"
 #include "us_solution.h"
+#include "us_simparms.h"
 
 //! \class US_Convert
 //!        This class provides the ability to convert raw data in the
@@ -173,6 +174,14 @@
                                 int ,
                                 QList< double >& );
 
+      //! \brief Adjusts times and omegas in AUC and speedstep so that
+      //!        the first speed step acceleration is 400 rpm/second.
+      //! \param allData     Input/Output raw AUC data
+      //! \param speedsteps  Input/Output speed step profile
+      //! \returns           A status code (0=OK)
+      static int  adjustSpeedstep( QVector< US_DataIO::RawData >& ,
+                                   QVector< US_SimulationParameters::SpeedProfile >& );
+                                   
    private:
       static void convert( QList< US_DataIO::BeckmanRawScan >& rawLegacyData,
                            US_DataIO::RawData&          newRawData,

Modified: trunk/programs/us_convert/us_convert_gui.cpp
===================================================================
--- trunk/programs/us_convert/us_convert_gui.cpp	2019-06-29 01:00:53 UTC (rev 2787)
+++ trunk/programs/us_convert/us_convert_gui.cpp	2019-07-05 14:13:28 UTC (rev 2788)
@@ -1309,7 +1309,7 @@
     gmpRun_bool = true;
  
   
-  int impType = getImports_auto( details_at_live_update[ "dataPath" ] );
+  impType     = getImports_auto( details_at_live_update[ "dataPath" ] );
 
 
   /* -------------------------------------------------------------------------------------------------------------------*/
@@ -1486,7 +1486,7 @@
 // User pressed the import data button
 void US_ConvertGui::import()
 {
-   int impType = getImports();
+   impType     = getImports();
 
    if ( impType == 1 )
    {
@@ -2325,7 +2325,6 @@
 
    }
 
-   
    // This can go on the todo list, but should not prevent user from saving
    if ( ( runType == "RI" ) && ( ! referenceDefined ) )
    {
@@ -2334,13 +2333,12 @@
                             tr( ": Define reference scans" ) );
 
       if ( count == 1 )
-	{
-	  pb_reference->setEnabled( true ); 
-	  //ALEXEY <--- Save btn is disabled when Reference scan is NOT defined (for Absorbance)
-
-	  if ( ! ExpData.expType.contains( "calibrat", Qt::CaseInsensitive ) )
-	    completed = false;
-	}
+      {
+         pb_reference->setEnabled( true ); 
+         //ALEXEY <--- Save btn is disabled when Reference scan is NOT defined (for Absorbance)
+         if ( ! ExpData.expType.contains( "calibrat", Qt::CaseInsensitive ) )
+            completed = false;
+      }
    }
 
    // If we made it here, user can save
@@ -5772,7 +5770,7 @@
 int US_ConvertGui::getImports_auto( QString & CurrDir) // ALEXEY TO BE EDITED...
 {
    QString dir;
-   int impType  = 0;
+   int jmpType      = 0;
 
    // dir = QFileDialog::getExistingDirectory( this,
    //       tr( "Raw Data Directory" ),
@@ -5864,16 +5862,16 @@
  << nmwrs << nauc << ntxml << ntmst << nother;
 
    if ( nmwrs > 0 )
-      impType     = 1;             // Flag import of MWL data
+      jmpType     = 1;             // Flag import of MWL data
 
    else if ( nauc > 0 )
-      impType     = 2;             // Flag import of AUC data
+      jmpType     = 2;             // Flag import of AUC data
 
    else
-      impType     = 0;             // Flag import of Beckman Raw
+      jmpType     = 0;             // Flag import of Beckman Raw
 
-DbgLv(1) << "CGui:gI:  RTN impType" << impType;
-   return impType;
+DbgLv(1) << "CGui:gI:  RTN jmpType" << jmpType;
+   return jmpType;
 }
 
 
@@ -5881,7 +5879,7 @@
 int US_ConvertGui::getImports()
 {
    QString dir;
-   int impType  = 0;
+   int jmpType  = 0;
 
    dir = QFileDialog::getExistingDirectory( this,
          tr( "Raw Data Directory" ),
@@ -5971,16 +5969,16 @@
  << nmwrs << nauc << ntxml << ntmst << nother;
 
    if ( nmwrs > 0 )
-      impType     = 1;             // Flag import of MWL data
+      jmpType     = 1;             // Flag import of MWL data
 
    else if ( nauc > 0 )
-      impType     = 2;             // Flag import of AUC data
+      jmpType     = 2;             // Flag import of AUC data
 
    else
-      impType     = 0;             // Flag import of Beckman Raw
+      jmpType     = 0;             // Flag import of Beckman Raw
 
-DbgLv(1) << "CGui:gI:  RTN impType" << impType;
-   return impType;
+DbgLv(1) << "CGui:gI:  RTN jmpType" << jmpType;
+   return jmpType;
 }
 
 bool US_ConvertGui::read( void )
@@ -6826,6 +6824,8 @@
    int     nspeed   = US_SimulationParameters::readSpeedSteps( runID, dataType,
                                                                speedsteps );
    int     nspeedc  = 0;
+   bool low_accel   = false;
+   double rate      = 400.0;
 DbgLv(1) << "CGui:IOD:   rSS nspeed" << nspeed;
 
    if ( nspeed == 0 )
@@ -6833,9 +6833,58 @@
       US_SimulationParameters::computeSpeedSteps( allData, speedsteps );
       nspeedc          = speedsteps.size();
       nspeed           = nspeedc;
-   }
 DbgLv(1) << "CGui:IOD:   cSS nspeed" << speedsteps.size();
 
+      // Check to see if implied 1st acceleration is too low
+#define DSS_LO_ACC 250.0 // default SetSpeedLowAccel
+      if ( impType != 2 )  // Check if not imported AUC
+      {
+         QString dbgval   = US_Settings::debug_value( "SetSpeedLowAcc" );
+         double ss_lo_acc = dbgval.isEmpty() ? DSS_LO_ACC : dbgval.toDouble();
+         low_accel        = US_AstfemMath::low_acceleration( speedsteps, ss_lo_acc, rate );
+      }
+   }
+
+   // Report problematic 1st speed step
+   if ( low_accel )
+   {
+      int tf_scan      = speedsteps[ 0 ].time_first;
+      int accel1       = (int)qRound( rate );
+      int rspeed       = speedsteps[ 0 ].rotorspeed;
+      int tf_aend      = ( rspeed + accel1 - 1 ) / accel1;
+
+      QString wmsg = tr( "The SpeedStep computed/used is likely bad:<br/>"
+                         "The acceleration implied is %1 rpm/sec.<br/>"
+                         "The acceleration zone ends at %2 seconds,<br/>"
+                         "with a first scan time of %3 seconds.<br/><br/>"
+                         "<b>You should rerun the experiment without<br/>"
+                         "any interim constant speed, and then<br/>"
+                         "you should reimport the data.</b>" )
+                     .arg( accel1 ).arg( tf_aend ).arg( tf_scan );
+
+      QMessageBox msgBox( this );
+      msgBox.setWindowTitle( tr( "Bad TimeState Implied!" ) );
+      msgBox.setTextFormat( Qt::RichText );
+      msgBox.setText( wmsg );
+      msgBox.addButton( tr( "Continue" ), QMessageBox::RejectRole );
+      QPushButton* bAbort = msgBox.addButton( tr( "Abort" ),
+            QMessageBox::YesRole    );
+      msgBox.setDefaultButton( bAbort );
+      msgBox.exec();
+      if ( msgBox.clickedButton() == bAbort )
+      {  // Abort the import of this data
+         QApplication::restoreOverrideCursor();
+         qApp->processEvents();
+         reset();
+         return false;
+      }
+      else
+      {  // Modify times and omegas of this data, then proceed to import
+         int status = US_Convert::adjustSpeedstep( allData, speedsteps );
+DbgLv(1) << "CGui:IOD: adjSS stat" << status;
+      }
+   }
+
    // MultiWaveLength if channels and triples counts differ
    isMwl            = ( all_chaninfo.count() != all_tripinfo.count() );
    if ( isMwl  &&  ( all_tripinfo.count() / all_chaninfo.count() ) < 4 )
@@ -7219,3 +7268,4 @@
    reset_lambdas();      // Make sure internal MWL lambdas are right
 
 }
+

Modified: trunk/programs/us_convert/us_convert_gui.h
===================================================================
--- trunk/programs/us_convert/us_convert_gui.h	2019-06-29 01:00:53 UTC (rev 2787)
+++ trunk/programs/us_convert/us_convert_gui.h	2019-07-05 14:13:28 UTC (rev 2788)
@@ -243,6 +243,7 @@
       int           elambda;                   // End Lambda on output
       int           nlamb_i;                   // Lambda count for raw input
       int           dbg_level;                 // Debug level
+      int           impType;                   // Import type flag: 0,1,2 == Beck,MWL,AUC
 
       QString       currentDir;                // Current data file directory
       QString       saveDescription;           // Saved channel description

Modified: trunk/programs/us_experiment/us_exp_utils.cpp
===================================================================
--- trunk/programs/us_experiment/us_exp_utils.cpp	2019-06-29 01:00:53 UTC (rev 2787)
+++ trunk/programs/us_experiment/us_exp_utils.cpp	2019-07-05 14:13:28 UTC (rev 2788)
@@ -905,14 +905,14 @@
    {
       US_Rotor::AbstractRotor* arotor = abstractRotor( rpRotor->rotor );
       value          = ( arotor != NULL ) ? arotor->numHoles : 0;
-DbgLv(1) << "EGRo:gIV:  arotor" << arotor->name << "value" << value;
+DbgLv(1) << "EGRo:gIV:  arotor" << getSValue("arotor") << "value" << value;
    }
    else if ( type == "maxrpm" )
    {
       US_Rotor::AbstractRotor* arotor = abstractRotor( rpRotor->rotor );
 DbgLv(1) << "EGRo:gIV:  arotor" << arotor << "rotor" << rpRotor->rotor;
       value          = ( arotor != NULL ) ? arotor->maxRPM : 50000;
-DbgLv(1) << "EGRo:gIV:  arotor" << arotor->name << "value" << value;
+DbgLv(1) << "EGRo:gIV:  arotor" << getSValue("arotor") << "value" << value;
    }
    else if ( type == "labID" )   { value = rpRotor->labID; }
    else if ( type == "rotID" )   { value = rpRotor->rotID; }

Modified: trunk/programs/us_fematch/us_fematch.cpp
===================================================================
--- trunk/programs/us_fematch/us_fematch.cpp	2019-06-29 01:00:53 UTC (rev 2787)
+++ trunk/programs/us_fematch/us_fematch.cpp	2019-07-05 14:13:28 UTC (rev 2788)
@@ -1856,6 +1856,7 @@
    solution.manual    = manual;
    solution.vbar20    = vbar20;
    solution.vbar      = US_Math2::calcCommonVbar( solution_rec, avgTemp );
+//   solution.vbar      = US_Math2::adjust_vbar20( solution.vbar20, avgTemp );
 
    US_Math2::data_correction( avgTemp, solution );
 
@@ -1872,6 +1873,7 @@
    sd.vbar20       = solution.vbar20;
    sd.vbar         = solution.vbar;
    sd.manual       = solution.manual;
+DbgLv(1) << "Fem:Adj:  avgT" << avgTemp << "scorr dcorr" << scorrec << dcorrec;
 
    if ( cnstvb  &&  mc_vbar != sd.vbar20  &&  mc_vbar != 0.0 )
    {  // Use vbar from the model component, instead of from the solution
@@ -1880,6 +1882,7 @@
       US_Math2::data_correction( avgTemp, sd );
       scorrec      = sd.s20w_correction;
       dcorrec      = sd.D20w_correction;
+DbgLv(1) << "Fem:Adj:   cnstvb" << cnstvb << "  scorr dcorr" << scorrec << dcorrec;
    }
 DbgLv(1) << "Fem:Adj:  avgT" << avgTemp << "vb20 vb" << sd.vbar20 << sd.vbar;
 
@@ -1905,7 +1908,7 @@
       sc->s      /= scorrec;
       sc->D      /= dcorrec;
 DbgLv(1) << "Fem:Adj:  s20w D20w" << s20w << d20w
- << "s D" << sc->s << sc->D << "  jj" << jj;
+ << "s D" << sc->s << sc->D << "  jj" << jj << "vb20 vb" << sc->vbar20 << sd.vbar;
 
       if ( sc->extinction > 0.0 )
          sc->molar_concentration = sc->signal_concentration / sc->extinction;
@@ -2209,7 +2212,7 @@
  << rspeed << accel1 << lo_ss_acc << "tf_aend tf_scan"
  << tf_aend << tf_scan;
 //x0  1  2  3  4  5
-   if ( accel1 < lo_ss_acc  ||  tf_aend > ( tf_scan - 6 ) )
+   if ( accel1 < lo_ss_acc  ||  tf_aend > ( tf_scan - 3 ) )
    {
       QString wmsg = tr( "The TimeState computed/used is likely bad:<br/>"
                          "The acceleration implied is %1 rpm/sec.<br/>"

Modified: trunk/utils/us_astfem_math.cpp
===================================================================
--- trunk/utils/us_astfem_math.cpp	2019-06-29 01:00:53 UTC (rev 2787)
+++ trunk/utils/us_astfem_math.cpp	2019-07-05 14:13:28 UTC (rev 2788)
@@ -6,8 +6,8 @@
 #ifndef DbgLv
 #define DbgLv(a) if(dbg_level>=a)qDebug() //!< debug-level-conditioned qDebug()
 #endif
+#define DSS_LO_ACC 250.0  // default SetSpeedLowAccel
 
-
 #if 0
 #ifdef NO_DB
 #include <mpi.h>
@@ -52,8 +52,9 @@
    int    step_nbr      = 0;
    double temperature   = sim_data.scanData[ 0 ].temperature;
    int nscans           = sim_data.scanData.size(); // Used for number of scans
-   int t_acc;    // Used for time when accelerated up to the specified rotor speed
-   double rate, speed;
+   int t_acc            = 1; // Used for time when accelerated up to the specified rotor speed
+   double rate          = 1.0;
+   double speed         = 1000.0;
    int ss_reso          = 100;
    // If debug_text so directs, change set_speed_resolution
    QStringList dbgtxt = US_Settings::debug_text();
@@ -79,53 +80,15 @@
 
    if ( simparams.sim == false )
    {  // Handle 1st acceleration zone for real data (compute acceleration rate)
-      const double tfac = ( 4.0 / 3.0 );
-      double t2   = simparams.speed_step[ 0 ].time_first;
-      double w2t  = simparams.speed_step[ 0 ].w2t_first;
-      double om1t = simparams.speed_step[ 0 ].rotorspeed * M_PI / 30.0;
-      double w2   = sq( om1t ); 
-      // For the first speed step, we compute "t1", the end of the initial
-      // acceleration zone, using
-      //   "t2"   , the time in seconds for the first scan;
-      //   "w2t"  , the omega^2_t integral for the first scan time;
-      //   "w2"   , the omega^2 value for the constant zone speed;
-      //   "tfac" , a factor (==(4/3)==1.333333) derived from the following.
-      // The acceleration zone begins at t0=0.0.
-      // It ends at time "t1".
-      // The time between t1 and t2 is at constant speed.
-      // The time between 0 and t1 is at changing speeds averaging (rpm/2).
-      // For I1 and I2, the omega^2t integrals at t1 and t2,
-      //        ( I2 - I1 ) = ( t2 - t1 ) * w2       (equ.1)
-      //        I1 = ( (rpm/2) * PI / 30 )^2 * t1    (equ.2)
-      //        I1 = ( ( rpm * PI / 30 )^2 / 4 ) * t1
-      //        w2 = ( rpm * PI / 30 )^2
-      //        I1 = ( w2 / 4 ) * t1
-      //        I2 = w2t
-      // Substituting into equ.1, we get:
-      //        ( w2t - ( ( w2 / 4 ) * t1 ) ) = ( t2 - t1 ) * w2
-      //        t1 * ( w2 - ( w2 / 4 ) )      = t2 * w2 - w2t
-      //        t1 * ( 3 / 4 ) * w2           = t2 * w2 - w2t
-      //        t1  = ( 4 / 3 ) * ( t2 - ( w2t / w2 ) )
-      double t1   = tfac * ( t2 - ( w2t / w2 ) );
-double t1w=(w2t/w2);
-DbgLv(1) << "AMATH:wrts: om1t w2 w2t" << om1t << w2 << w2t
- << "t1w" << t1w << "tfac" << tfac;
-      if ( t1 >= t2 )
-      {  // Something wrong!  set t1 to a few seconds before t2
-         t1          = t2 - 5.0;
-      }
-//      t_acc       = qCeil( t1 );
-      t_acc       = (int)qRound( t1 );
-      rate        = (double)( simparams.speed_step[ 0 ].rotorspeed )
-                    / (double)t_acc;
-DbgLv(1) << "AMATH:wrts:t1 t2" << t1 << t2 << "t_acc rate" << t_acc << rate;
-//DbgLv(1)<<  "from speed profile"
-// << "t_acc=" << t_acc << "rate=" << rate << "first_time:" << simparams.speed_step[0].time_first
-// << "first_w2t" << simparams.speed_step[0].w2t_first
-// << "rpm=" << simparams.speed_step[0].rotorspeed;
-//DbgLv(1) << " from sim_data"
-// << "t_acc=" << t_acc1 << "rate= " << rate1 << "first_time: " << sim_data.scanData[0].seconds
-// << "first_w2t" << sim_data.scanData[0].omega2t << "rpm=" << sim_data.scanData[0].rpm;
+      // If debug_text so directs, change set_speed_low_accel
+      QString dbgval   = US_Settings::debug_value( "SetSpeedLowAcc" );
+      double low_accel = dbgval.isEmpty() ? DSS_LO_ACC : dbgval.toDouble();
+
+      // Get the 1st acceleration zone's rate and end-time
+      low_acceleration( simparams.speed_step, low_accel, rate );
+      t_acc       = (int)qRound( (double)( simparams.speed_step[ 0 ].rotorspeed )
+                                           / rate );
+DbgLv(1)<< "AMATH:wrts: computed rate:" << rate;
    }
    else
    {  // Handle 1st acceleration zone for simulation (astfem_sim) data
@@ -258,9 +221,63 @@
    return timestate.time_count();
 }
 
+// Determine if first time step's acceleration is too low
+bool US_AstfemMath::low_acceleration(
+      const QVector< US_SimulationParameters::SpeedProfile >& speedsteps,
+      const double min_accel, double& rate )
+{
+   int dbg_level     = US_Settings::us_debug();
+   const double tfac = ( 4.0 / 3.0 );
+   double t2         = speedsteps[ 0 ].time_first;
+   double w2t        = speedsteps[ 0 ].w2t_first;
+   double om1t       = speedsteps[ 0 ].rotorspeed * M_PI / 30.0;
+   double w2         = sq( om1t ); 
+   double t1w        = w2t / w2;
+
+   // =====================================================================
+   // For the first speed step, we compute "t1", the end of the initial
+   // acceleration zone, using
+   //   "t2"   , the time in seconds for the first scan;
+   //   "w2t"  , the omega^2_t integral for the first scan time;
+   //   "w2"   , the omega^2 value for the constant zone speed;
+   //   "tfac" , a factor (==(4/3)==1.333333) derived from the following.
+   // The acceleration zone begins at t0=0.0.
+   // It ends at time "t1".
+   // The time between t1 and t2 is at constant speed.
+   // The time between 0 and t1 is at changing speeds averaging (rpm/2).
+   // For I1 and I2, the omega^2t integrals at t1 and t2,
+   //        ( I2 - I1 ) = ( t2 - t1 ) * w2       (equ.1)
+   //        I1 = ( (rpm/2) * PI / 30 )^2 * t1    (equ.2)
+   //        I1 = ( ( rpm * PI / 30 )^2 / 4 ) * t1
+   //        w2 = ( rpm * PI / 30 )^2
+   //        I1 = ( w2 / 4 ) * t1
+   //        I2 = w2t
+   // Substituting into equ.1, we get:
+   //        ( w2t - ( ( w2 / 4 ) * t1 ) ) = ( t2 - t1 ) * w2
+   //        t1 * ( w2 - ( w2 / 4 ) )      = t2 * w2 - w2t
+   //        t1 * ( 3 / 4 ) * w2           = t2 * w2 - w2t
+   //        t1  = ( 4 / 3 ) * ( t2 - ( w2t / w2 ) )
+   // =====================================================================
+
+   double t1      = tfac * ( t2 - t1w );
+DbgLv(1) << "AMATH:loac: om1t w2 w2t" << om1t << w2 << w2t
+ << "t1w" << t1w << "tfac" << tfac;
+
+   if ( t1 >= t2 )
+   {  // Something wrong!  set t1 to a few seconds before t2
+      t1             = t2 - 5.0;
+   }
+
+   int t_acc      = (int)qRound( t1 );
+   rate           = (double)( speedsteps[ 0 ].rotorspeed ) / (double)t_acc;
+DbgLv(1) << "AMATH:loac:t1 t2" << t1 << t2 << "t_acc rate" << t_acc << rate;
+
+   return ( rate < min_accel );
+}
+
 // Determine if a timestate file holds one-second-interval records
 bool US_AstfemMath::timestate_onesec( const QString& tmst_fpath,
-                                      US_DataIO::RawData& sim_data )
+                                      US_DataIO::RawData&      sim_data )
 {
    bool onesec_intv = false;
    bool constti     = false;

Modified: trunk/utils/us_astfem_math.h
===================================================================
--- trunk/utils/us_astfem_math.h	2019-06-29 01:00:53 UTC (rev 2787)
+++ trunk/utils/us_astfem_math.h	2019-07-05 14:13:28 UTC (rev 2788)
@@ -37,6 +37,14 @@
       static int  writetimestate( const QString&, US_SimulationParameters&,
                                   US_DataIO::RawData& );
 
+      //! \brief Determine if first time step's acceleration is too low
+      //! \param speedsteps  Vector of speed steps
+      //! \param min_accel   Minimum reasonable acceleration value
+      //! \param rate        Returned computed first-step acceleration rate
+      //! \returns Flag:     True iff acceleration rate is too low
+      static bool low_acceleration( const QVector< US_SimulationParameters::SpeedProfile >&,
+                                    const double, double& );
+
       //! \brief Determine if a timestate file holds one-second-interval records
       //! \param tmst_fpath  Full path to timestate file to examine
       //! \param sim_data    Raw data with scans to examine

Modified: trunk/utils/us_simparms.cpp
===================================================================
--- trunk/utils/us_simparms.cpp	2019-06-29 01:00:53 UTC (rev 2787)
+++ trunk/utils/us_simparms.cpp	2019-07-05 14:13:28 UTC (rev 2788)
@@ -9,6 +9,9 @@
 
 //!< level-conditioned debug print
 #define DbgLv(a) if(dbg_level>=a)qDebug()
+#define DSS_RESO   100   // default SetSpeedResolution
+#define DSS_LO_RPM 1500  // default SetSpeedLowRpm
+#define DSS_LO_SEC 20    // default SpeedStepLowSec
 
 US_SimulationParameters::US_SimulationParameters()
 {
@@ -1182,11 +1185,13 @@
       return -1;                           // Do not have needed keys
 
    // If debug_text so directs, change set_speed_resolution
-   //  and/or set_speed_low_rpm
+   //  and/or set_speed_low_rpm and/or speed_step_low_secs
    QString dbgval   = US_Settings::debug_value( "SetSpeedReso" );
-   int ss_reso      = dbgval.isEmpty() ? 100  : dbgval.toInt();
+   int ss_reso      = dbgval.isEmpty() ? DSS_RESO  : dbgval.toInt();
    dbgval           = US_Settings::debug_value( "SetSpeedLowR" );
-   int ss_lo_rpm    = dbgval.isEmpty() ? 1500 : dbgval.toInt();
+   int ss_lo_rpm    = dbgval.isEmpty() ? DSS_LO_RPM : dbgval.toInt();
+   dbgval           = US_Settings::debug_value( "SpeedStepLowSec" );
+   int ss_lo_sec    = dbgval.isEmpty() ? DSS_LO_SEC : dbgval.toInt();
 
    int nrec         = tsobj->time_count(); // Total time record count
    QList< int >  cspeeds;                  // Constant speeds list
@@ -1354,10 +1359,10 @@
  << "rs_p rs_c" << rs_p << rs_c << "ss_c_ts" << ss_c_ts;
 
             // But, wait a minute! If the "constant zone" just ending is less than
-            // 5 minutes long or contains no scans, then add it to the current
+            // 20 seconds long or contains no scans, then add it to the current
             // speed step's acceleration zone and resume looking for an end
             // to the acceleration zone
-            if ( ndtimes < 300  ||  ssp.time_f_scan < 1 )
+            if ( ndtimes < ss_lo_sec  ||  ssp.time_f_scan < 1 )
             {
                in_accel         = true;
                naintvs         += ndtimes;



More information about the us-commits mailing list