21347

Origin-Script to integrate over multiple curves

Jan 15th, 2014
150
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 17.26 KB | None | 0 0
  1. #include <Origin.h>
  2.  
  3. //#pragma labtalk(0) // to disable OC functions for LT calling.
  4. #include <XFBase.h>
  5. #include <GetNbox.h>
  6.  
  7. /**
  8.  * Get Parameters for Integration; is: Start- & Endpoint in X-Axis-Coordinates
  9. **/
  10. bool askForParameters_Integration(double &xStart, double &xEnd, bool &recalcWidth, double &baseline, string &newName)
  11. {
  12.     GETN_TREE(myTree);
  13.  
  14.     GETN_NUM(get_xStart, "X-Range Start", xStart);
  15.     GETN_NUM(get_xEnd, "X-Range End", xEnd);
  16.     GETN_STR(info_Text1, "(Integration range in X-Values)", "hidden"); GETN_HINT_EX(FALSE, FALSE);
  17.     GETN_CHECK(get_recalcWidth, "Integrate over xStart+RiseTime", recalcWidth)
  18.     GETN_STR(info_Text2, "(Try to read user-parameter \"RiseTime\" and adjust integration-Width accordingly)", "hidden"); GETN_HINT_EX(FALSE, FALSE)
  19.     GETN_NUM(get_Baseline, "j0 (\"Baseline\")", baseline);
  20.     GETN_STR(info_Text3, "(4th Row will be filled with that value to calculate n)", "hidden"); GETN_HINT_EX(FALSE, FALSE);
  21.     GETN_STR(get_Name, "LongName for new Worksheet", newName);
  22.    
  23.    
  24.  
  25.     if(GetNBox(myTree, "Integrate All", "Select parameters for integration"))
  26.     {
  27.         xStart = myTree.get_xStart.dVal;
  28.         xEnd = myTree.get_xEnd.dVal;
  29.         baseline = myTree.get_Baseline.dVal;
  30.         recalcWidth = (myTree.get_recalcWidth.nVal != 0);
  31.         newName = myTree.get_Name.strVal;
  32.         return true;
  33.     }
  34.     else
  35.     {
  36.         return false;
  37.     }
  38. }
  39. bool askForParameters_Averaging(double &xStart, double &xEnd, bool &recalcWidth, double &baseline, string &newName)
  40. {
  41.     GETN_TREE(myTree);
  42.  
  43.     GETN_NUM(get_xStart, "X-Range Start", xStart);
  44.     GETN_NUM(get_xEnd, "X-Range End", xEnd);
  45.     GETN_STR(info_Text1, "(Averaging range in X-Values)", "hidden"); GETN_HINT_EX(FALSE, FALSE);
  46.     GETN_CHECK(get_recalcWidth, "Integrate over xStart+RiseTime", recalcWidth)
  47.     GETN_STR(info_Text2, "(Try to read user-parameter \"RiseTime\" and adjust integration-Width accordingly)", "hidden"); GETN_HINT_EX(FALSE, FALSE)
  48.     GETN_NUM(get_Baseline, "j0 (\"Baseline\")", baseline);
  49.     GETN_STR(info_Text3, "(4th Row will be filled with that value to calculate n)", "hidden"); GETN_HINT_EX(FALSE, FALSE);
  50.     GETN_STR(get_Name, "LongName for new Worksheet", newName);
  51.    
  52.    
  53.  
  54.     if(GetNBox(myTree, "Average All", "Select parameters vor averaging"))
  55.     {
  56.         xStart = myTree.get_xStart.dVal;
  57.         xEnd = myTree.get_xEnd.dVal;
  58.         baseline = myTree.get_Baseline.dVal;
  59.         recalcWidth = (myTree.get_recalcWidth.nVal != 0);
  60.         newName = myTree.get_Name.strVal;
  61.         return true;
  62.     }
  63.     else
  64.     {
  65.         return false;
  66.     }
  67. }
  68.  
  69. /**
  70.  * Find nearest Index in a Dataset that starts with the lowest value in dX[0]
  71. **/
  72. int findNearestX(Dataset &dX, double value)
  73. {
  74.     int startIndex = dX.GetLowerBound();
  75.     double dif = abs(value - dX[startIndex]);
  76.     double newDif = dif;
  77.     for (int ii=startIndex+1; ii <= dX.GetUpperBound(); ii++)
  78.     {
  79.         newDif = abs(value - dX[ii]);
  80.         if (newDif > dif)
  81.         {
  82.             return ii-1;
  83.         }
  84.         dif = newDif;
  85.     }
  86.     return dX.GetUpperBound();
  87. }
  88.  
  89. /**
  90.  * Find an entry in the Form "<Name> = <Value>" in the UserParameters of the given Worksheet
  91. **/
  92. double getUserParameter(Worksheet &ws, string name, double defValue = 0)
  93. {
  94.     if (name.IsEmpty()) return defValue;
  95.    
  96.     string label;
  97.     int i = 0;
  98.    
  99.     while (ws.Columns(0).GetExtendedLabel(label, RCLT_UDL+(i++)))
  100.     {
  101.         int pos = label.Find("=");
  102.         if (pos >= 0)
  103.         {
  104.             string nameString = label.Left(pos);
  105.             nameString.TrimLeft(); nameString.TrimRight();
  106.             if (nameString.IsEmpty()) continue;
  107.             if (nameString.CompareNoCase(name) == 0)
  108.             {
  109.                 //Found the name, extract the value...
  110.                 string valueString = label.Right(label.GetLength()-pos-1);
  111.                 valueString.TrimLeft(); valueString.TrimRight();
  112.                 valueString.Replace(',','.');
  113.                 double val = atof(valueString, true);
  114.                 if (val == NANUM) return defValue;
  115.                 else return val;
  116.             }
  117.         }
  118.     }
  119.    
  120.     return defValue;
  121. }
  122.  
  123. /**
  124.  * Create a Worksheet-Object and bind it to the worksheet used in the given curve
  125. **/
  126. Worksheet getWorksheetForCurve(Curve &curve)
  127. {
  128.     string strTemp, strWks;
  129.     curve.GetName(strTemp);
  130.     int nn = strTemp.Find('_');
  131.     if(nn > 0)
  132.         strWks = strTemp.Left(nn);
  133.        
  134.     Worksheet wks(strWks);
  135.     return wks;
  136. }
  137.  
  138. /**
  139.  * Create a Worksheet-Object and bind it to the worksheet displayed by the given DataPlot
  140. **/
  141. bool getWorksheetForPlot(DataPlot &plot, Worksheet &worksheet)
  142. {
  143.     Curve theCurve(plot);
  144.     return getWorksheetForCurve(theCurve);
  145. }
  146.  
  147.  
  148. bool doIntegration()
  149. {
  150.     //Parameters:
  151.     //-adjustWidth: if true, each worksheet will be searched for the UserParameter "RiseTime" to adjust the integration width
  152.     //-based on (currentRisetime) - ((given width) - (originalRiseTime))
  153.     bool adjustWidth = false;
  154.     double originalRiseTime = 0;
  155.     double riseTimeDifference = 0;
  156.     double baseline = 0;
  157.     //-xStart, xEnd: Start and End-Rows for integration, oroginal selected dataset
  158.     int xStart = 0;
  159.     int xEnd = 0;
  160.     //-X-Value for Start and End of integration
  161.     double valStart, valEnd;
  162.     //-Name for the new Worksheet
  163.     string newWorksheetName;
  164.    
  165.     GraphLayer graph = Project.ActiveLayer();  
  166.     if( !graph )
  167.     {
  168.         MessageBox(GetWindow(), "No Graph appears to be active, cannot continue!", "Integrate All" , 16);
  169.         return false;
  170.     }
  171.    
  172.     using cc = Project.ActiveCurve();
  173.     if( !cc )
  174.     {
  175.         MessageBox(GetWindow(), "There is no active dataset, cannot determine integration range and the Range-Adjust function might not work!", "Integrate All" , 64);
  176.         valStart = 0.0;
  177.         valEnd = 40.0;
  178.     }
  179.     else
  180.     {
  181.         //There is an active dataset, so use this to determine the start- and end-values for integration
  182.         if (graph.GetDataMarkers(xStart, xEnd))
  183.         {
  184.             //Query the currently active curve (cc) for data and extract the "real" values
  185.             Dataset xd;
  186.             printf("Active dataset is %s",cc.GetName());
  187.             if(cc.AttachX(xd, FALSE))
  188.             {
  189.                 printf(", its corresponding X dataset is %s\n",xd.GetName());
  190.                 valStart = xd[xStart];
  191.                 valEnd = xd[xEnd];
  192.             }
  193.             else
  194.             {
  195.                 printf(", but I cannot access it's values!!\n");
  196.                 MessageBox(GetWindow(), "I failed getting the integration range from the current curve.", "Integrate All" , 64);
  197.                 //No marker set, default to 0..40
  198.                 valStart = 0.0;
  199.                 valEnd = 40.0;
  200.             }
  201.             printf("Range: %f, %f\n", valStart, valEnd);
  202.            
  203.             //Try to find the RiseTime of the currently selected curve
  204.             Worksheet selWorksheet = getWorksheetForCurve(cc);
  205.             newWorksheetName = selWorksheet.GetPage().GetLongName().Left(11)+"-nData";
  206.             newWorksheetName.Replace("_", "-");
  207.             originalRiseTime = getUserParameter(selWorksheet, "RiseTime", (valEnd-valStart)/1E6)*1E6;
  208.            
  209.         }
  210.         else
  211.         {
  212.             //No marker set, default to 0..40
  213.             valStart = 0.0;
  214.             valEnd = 40.0;
  215.         }
  216.     }
  217.        
  218.     if ( !askForParameters_Integration(valStart, valEnd, adjustWidth, baseline, newWorksheetName) ) return false;
  219.        
  220.     //Calculate and Print RiseTime correction
  221.     riseTimeDifference = originalRiseTime - (valEnd - valStart);
  222.     printf("Original RiseTime was determined to be %f.\n", originalRiseTime);
  223.     printf("Difference to integration range: %f.\n", riseTimeDifference);
  224.     printf("Adjusting of integration range was switched %s\n", (adjustWidth ? "on" : "off"));
  225.    
  226.    
  227.     //Prepare vectors to save results
  228.     vector<double> vec_delayTime();
  229.     vector<double> vec_integralData();
  230.     vector<double> vec_integralWidth();
  231.    
  232.     //Traverse all Plots in the Graph and calculate...
  233.     foreach (DataPlot dp in graph.DataPlots)
  234.     {
  235.         //Get the original Datarange of the Plot
  236.         DataRange dr;
  237.         dp.GetDataRange(dr);
  238.        
  239.         // Curve
  240.         Curve cur(dp);
  241.         string strTemp;
  242.         cur.GetName(strTemp);
  243.         if (strTemp == "_MARKER") continue;
  244.         printf("Working on %s...\n", strTemp);
  245.        
  246.         //Get the Dataset associated with the Plot
  247.         //Get Dataset and find Bounds
  248.         Dataset dX;
  249.         if (!cur.AttachX(dX, FALSE))
  250.         {
  251.             printf("  Cannot attach to curv's dataset.\n");
  252.             continue;
  253.         }
  254.        
  255.         //Get the Worksheet associated with the Curve
  256.         Worksheet myWorksheet = getWorksheetForCurve(cur);
  257.        
  258.         //Get the DelayTime
  259.         double delayTime = getUserParameter(myWorksheet, "DelayTime", -1);
  260.        
  261.         //Get the X and Y Column Index
  262.         int index1, index2;
  263.         string shortName, strX, strY;
  264.         curve_get_wks_col_names(cur, strX, strY);
  265.        
  266.         for( int ii = 0; ii < myWorksheet.Columns.Count(); ii++ )
  267.         {
  268.             myWorksheet.Columns(ii).GetName(shortName);
  269.             if (shortName == strX) index1 = ii;
  270.             else if (shortName == strY) index2 = ii;
  271.         }
  272.        
  273.         //Recalculate?
  274.         double myStart, myEnd;
  275.         myStart = valStart;
  276.         myEnd = valEnd;
  277.         if (adjustWidth)
  278.         {
  279.             double myRiseTime = getUserParameter(myWorksheet, "RiseTime", valEnd-valStart/1E6)*1E6;
  280.             printf("  New RiseTime = %f\n", myRiseTime);
  281.             myRiseTime = myRiseTime - riseTimeDifference;
  282.             myEnd = myStart + myRiseTime;
  283.         }
  284.         printf("  xStart = %f, xEnd = %f\n", myStart, myEnd);
  285.         printf("  Integration Range = %f\n", myEnd - myStart);
  286.        
  287.         xStart = findNearestX(dX, myStart);
  288.         xEnd = findNearestX(dX, myEnd);
  289.         printf("  Will Integrage from row %d to %d...\n", xStart, xEnd);
  290.         printf("  Using Columns X: %d, Y: %d\n", index1, index2);
  291.        
  292.         // Create Datarange
  293.         DataRange newRange();
  294.         newRange.Add(myWorksheet, index1, "X", index1, xStart, xEnd);
  295.         newRange.Add(myWorksheet, index2, "Y", index2, xStart, xEnd);
  296.        
  297.         //Copy Values from the Datarange
  298.         vector<double> xData, yData;
  299.         newRange.GetData(xData, 0);
  300.         newRange.GetData(yData, 1);
  301.        
  302.         //Integrate!
  303.         double area = 0;
  304.         int res = ocmath_numeric_integral(myEnd, &area, xData.GetSize(), xData, yData);
  305.         printf("  Area = %f, ",area);
  306.         vec_delayTime.Add(delayTime);
  307.         vec_integralData.Add(area);
  308.         vec_integralWidth.Add(myEnd - myStart);
  309.         switch (res)
  310.         {
  311.             case OE_NOERROR:
  312.                 printf("Success!\n");
  313.                 break;
  314.             case OE_NULL_POINTER:
  315.                 printf("Error: Null Pointer!\n");
  316.                 break;
  317.             case OE_SIZE_LT:
  318.                 printf("Warning: No data to integrage!\n");
  319.                 break;
  320.             case OE_NOT_STRICTLY_INCREASING:
  321.                 printf("Error: pxData must be monotonically increasing.!\n");
  322.                 break;
  323.             case OE_UNDERFLOW:
  324.                 printf("Error: xStart > xEnd!\n");
  325.                 break;
  326.             case OE_OVERFLOW:
  327.                 printf("Error: xStart is out of range!\n");
  328.                 break;
  329.             default:
  330.                 printf("Error: unknown, %d\n", res);
  331.         }
  332.     }
  333.    
  334.     //Display Data
  335.     Worksheet wks;
  336.     wks.Create("OtraceNBook");
  337.     wks.GetPage().SetLongName(newWorksheetName);
  338.     /*while(wks.Columns.Count()<3) wks.AddCol();
  339.     wks.SetColDesignations("XY");
  340.     wks.Columns(0).SetLongName("DelayTime");
  341.     wks.Columns(0).SetUnits("µs");
  342.     wks.Columns(1).SetLongName("Width");
  343.     wks.Columns(1).SetUnits("µs");
  344.     wks.Columns(2).SetLongName("Area");*/
  345.     vectorbase &data1 = wks.Columns(0).GetDataObject();
  346.     data1.Append(vec_delayTime);
  347.     vectorbase &data2 = wks.Columns(1).GetDataObject();
  348.     data2.Append(vec_integralWidth);
  349.     vectorbase &data3 = wks.Columns(2).GetDataObject();
  350.     data3.Append(vec_integralData);
  351.     vectorbase &data4 = wks.Columns(3).GetDataObject();
  352.     vector<double> baselineData;
  353.     for (int i = 0; i < vec_integralData.GetSize(); i++) baselineData.Add(baseline);
  354.     data4.Append(baselineData);
  355.    
  356.     return true;
  357. }
  358.  
  359. bool doAveraging()
  360. {
  361.     //Parameters:
  362.     //-adjustWidth: if true, each worksheet will be searched for the UserParameter "RiseTime" to adjust the averaging width
  363.     //-based on (currentRisetime) - ((given width) - (originalRiseTime))
  364.     bool adjustWidth = false;
  365.     double originalRiseTime = 0;
  366.     double riseTimeDifference = 0;
  367.     double baseline = 0;
  368.     //-xStart, xEnd: Start and End-Rows for averaging, oroginal selected dataset
  369.     int xStart = 0;
  370.     int xEnd = 0;
  371.     //-X-Value for Start and End of averaging
  372.     double valStart, valEnd;
  373.     //-Name for the new Worksheet
  374.     string newWorksheetName;
  375.    
  376.     GraphLayer graph = Project.ActiveLayer();  
  377.     if( !graph )
  378.     {
  379.         MessageBox(GetWindow(), "No Graph appears to be active, cannot continue!", "Average All" , 16);
  380.         return false;
  381.     }
  382.    
  383.     using cc = Project.ActiveCurve();
  384.     if( !cc )
  385.     {
  386.         MessageBox(GetWindow(), "There is no active dataset, cannot determine averaging range and the Range-Adjust function might not work!", "Average All" , 64);
  387.         valStart = 0.0;
  388.         valEnd = 40.0;
  389.     }
  390.     else
  391.     {
  392.         //There is an active dataset, so use this to determine the start- and end-values for averaging
  393.         if (graph.GetDataMarkers(xStart, xEnd))
  394.         {
  395.             //Query the currently active curve (cc) for data and extract the "real" values
  396.             Dataset xd;
  397.             printf("Active dataset is %s",cc.GetName());
  398.             if(cc.AttachX(xd, FALSE))
  399.             {
  400.                 printf(", its corresponding X dataset is %s\n",xd.GetName());
  401.                 valStart = xd[xStart];
  402.                 valEnd = xd[xEnd];
  403.             }
  404.             else
  405.             {
  406.                 printf(", but I cannot access it's values!!\n");
  407.                 MessageBox(GetWindow(), "I failed getting the integration range from the current curve.", "Average All" , 64);
  408.                 //No marker set, default to 0..40
  409.                 valStart = 0.0;
  410.                 valEnd = 40.0;
  411.             }
  412.             printf("Range: %f, %f\n", valStart, valEnd);
  413.            
  414.             //Try to find the RiseTime of the currently selected curve
  415.             Worksheet selWorksheet = getWorksheetForCurve(cc);
  416.             newWorksheetName = selWorksheet.GetPage().GetLongName().Left(11)+"-nData";
  417.             newWorksheetName.Replace("_", "-");
  418.             originalRiseTime = getUserParameter(selWorksheet, "RiseTime", (valEnd-valStart)/1E6)*1E6;
  419.            
  420.         }
  421.         else
  422.         {
  423.             //No marker set, default to 0..40
  424.             valStart = 0.0;
  425.             valEnd = 40.0;
  426.         }
  427.     }
  428.        
  429.     if ( !askForParameters_Averaging(valStart, valEnd, adjustWidth, baseline, newWorksheetName) ) return false;
  430.        
  431.     //Calculate and Print RiseTime correction
  432.     riseTimeDifference = originalRiseTime - (valEnd - valStart);
  433.     printf("Original RiseTime was determined to be %f.\n", originalRiseTime);
  434.     printf("Difference to integration range: %f.\n", riseTimeDifference);
  435.     printf("Adjusting of integration range was switched %s\n", (adjustWidth ? "on" : "off"));
  436.    
  437.    
  438.     //Prepare vectors to save results
  439.     vector<double> vec_delayTime();
  440.     vector<double> vec_averageData();
  441.     vector<double> vec_averageWidth();
  442.    
  443.     //Traverse all Plots in the Graph and calculate...
  444.     foreach (DataPlot dp in graph.DataPlots)
  445.     {
  446.         //Get the original Datarange of the Plot
  447.         DataRange dr;
  448.         dp.GetDataRange(dr);
  449.        
  450.         // Curve
  451.         Curve cur(dp);
  452.         string strTemp;
  453.         cur.GetName(strTemp);
  454.         if (strTemp == "_MARKER") continue;
  455.         printf("Working on %s...\n", strTemp);
  456.        
  457.         //Get the Dataset associated with the Plot
  458.         //Get Dataset and find Bounds
  459.         Dataset dX;
  460.         if (!cur.AttachX(dX, FALSE))
  461.         {
  462.             printf("  Cannot attach to curv's dataset.\n");
  463.             continue;
  464.         }
  465.        
  466.         //Get the Worksheet associated with the Curve
  467.         Worksheet myWorksheet = getWorksheetForCurve(cur);
  468.        
  469.         //Get the DelayTime
  470.         double delayTime = getUserParameter(myWorksheet, "DelayTime", -1);
  471.        
  472.         //Get the X and Y Column Index
  473.         int index1, index2;
  474.         string shortName, strX, strY;
  475.         curve_get_wks_col_names(cur, strX, strY);
  476.        
  477.         for( int ii = 0; ii < myWorksheet.Columns.Count(); ii++ )
  478.         {
  479.             myWorksheet.Columns(ii).GetName(shortName);
  480.             if (shortName == strX) index1 = ii;
  481.             else if (shortName == strY) index2 = ii;
  482.         }
  483.        
  484.         //Recalculate?
  485.         double myStart, myEnd;
  486.         myStart = valStart;
  487.         myEnd = valEnd;
  488.         if (adjustWidth)
  489.         {
  490.             double myRiseTime = getUserParameter(myWorksheet, "RiseTime", valEnd-valStart/1E6)*1E6;
  491.             printf("  New RiseTime = %f\n", myRiseTime);
  492.             myRiseTime = myRiseTime - riseTimeDifference;
  493.             myEnd = myStart + myRiseTime;
  494.         }
  495.         printf("  xStart = %f, xEnd = %f\n", myStart, myEnd);
  496.         printf("  Averaging Range = %f\n", myEnd - myStart);
  497.        
  498.         xStart = findNearestX(dX, myStart);
  499.         xEnd = findNearestX(dX, myEnd);
  500.         printf("  Will Average from row %d to %d...\n", xStart, xEnd);
  501.         printf("  Using Columns X: %d, Y: %d\n", index1, index2);
  502.        
  503.         // Create Datarange
  504.         DataRange newRange();
  505.         //newRange.Add(myWorksheet, index1, "X", index1, xStart, xEnd);
  506.         newRange.Add(myWorksheet, index2, "Y", index2, xStart, xEnd);
  507.        
  508.         //Copy Values from the Datarange
  509.         vector<double> xData, yData;
  510.         newRange.GetData(yData, 0);
  511.         //newRange.GetData(yData, 1);
  512.        
  513.         //Average!
  514.         double average = 0;
  515.         int len = yData.GetSize();
  516.         if (len > 0)
  517.         {
  518.             //Problem: sum first, or device first; I'd say: sum first, as values summed up
  519.             //are likely to be much smaller than the integer count of samples...
  520.             for (int i=0; i < len; i++) average += yData[i];
  521.             average = average / len;
  522.         }
  523.         else
  524.           printf("Warning: No data to average!\n");
  525.         printf("  Average = %f, ",average);
  526.         vec_delayTime.Add(delayTime);
  527.         vec_averageData.Add(average);
  528.         vec_averageWidth.Add(myEnd - myStart);
  529.     }
  530.    
  531.     //Display Data
  532.     Worksheet wks;
  533.     wks.Create("OtraceBaselineBook");
  534.     wks.GetPage().SetLongName(newWorksheetName);
  535.     vectorbase &data1 = wks.Columns(0).GetDataObject();
  536.     data1.Append(vec_delayTime);
  537.     vectorbase &data2 = wks.Columns(1).GetDataObject();
  538.     data2.Append(vec_averageWidth);
  539.     vectorbase &data3 = wks.Columns(2).GetDataObject();
  540.     data3.Append(vec_averageData);
  541.    
  542.     return true;
  543. }
Advertisement
Add Comment
Please, Sign In to add comment