Most formulas can be defined in the formula table or using the formula dialog in the data browser. Script formula can be created for formulas which cannot defined in the table because they are too long or too complex.
Script formulas can use all UniScript elements, such as if-else conditions and for-loops.
The following script formula computes power from speed and torque.
// Power P in kW
// T*2*PI*rpm
// Speed rpm in 1/min
// Trq T in Nm
def _fi_P(bInfo)
{
ssChannels = "rpm, Trq";
if (bInfo) {
return ["P"; ..
"kW"; ..
"Power"; ..
ssChannels; ..
""; ..
"%.2lf"];
}
rpm = ch("rpm");
Trq = ch("Trq");
P = (rpm .* Trq) ./ 9549.3;
set_ch("P", P, ssChannels);
}
In script formulas, the operators .*, ./, .^ should be used. The period before the operator means that the operation of vectors is performed on an element by element basis.
rpm and Trq are vectors containing all data points. The result vector P contains as many elements as rpm and Trq. If rpm and Trq contain a different number of data points, the function would be terminated with an error message.
For MDF-, Famos- or ASAM-ODS-Data the formula can contain channels with different number of data points. In this case the formula interpreter will interpolate all used channels to the time base of the first specified data channel.
Example:
In the following example the channels a is multiplied with b. a is measured with 10 Hz and b with 100 Hz. The formula result c will have a resolution of 10 Hz.
If you want to calculate c with 100 Hz, switch a and b in the variable ssChannels (ssChannels = "b, a") and replace the second parameter in ch in all functions calls (_fich_a = ch("a", "b")).
def _fi_c(bInfo)
{
ssChannels = "a, b";
if (bInfo) {
return ["c"; ..
""; ..
""; ..
ssChannels];
}
_fich_a = ch("a", "a"); // a 10 Hz -> interpolate to 10Hz
_fich_b = ch("b", "a"); // b 100 Hz -> interpolate to 10Hz
_fich_c = _fich_a .* _fich_b;
set_ch("c", _fich_c, ssChannels);
}
In order for the formulas to be evaluated by UniPlot, the function must fulfill the following regulations:
A UniScript function specified for each formula.
Each formula produces one channel.
The name of a function begins with _fi_. The function has one parameter bInfo.
If the function is called with bInfo == TRUE, the function must return a string vector with at least 4 elements. The meaning of the elements is described in Query Function Information.
The function can access the data of a NC file with the function ch Calculated data is written to the NC file using the set_ch function.
All UniScript functions can be called within the function.
If a formula function is called with the value bInfo == TRUE, the function must return a string vector with at least 4 elements (see example Example Formula):
The following program listing shows the UniScript function for the condition “Diesel”:
def _fiis_diesel()
{
ncid = get_ncid();
if (ncid == -1) {
error();
return FALSE;
}
if (nc_attinq_datatype(ncid, NC_GLOBAL, "PEtrol___DIesel") == NC_CHAR) {
ssEngineType = nc_attget(ncid, NC_GLOBAL, "PEtrol___DIesel");
if (ssEngineType == "DI") {
return TRUE;
}
}
return FALSE;
}
The function get_ncid returns the handle of the active NC file. Use the handle to retrieve information from the file.
In the example, we checked whether the file contains the global attribute “PEtrol___DIesel ”. If the attribute value is “DI”, the function returns TRUE (1). In all other cases the return value is FALSE (0). This means that all formulas containing the value “Diesel” in the info text will only be applied on NC files where the attribute “PEtrol___DIesel” is “DI”.
Condition functions begin with the character sequence _fiis _ followed by the function name, which must correspond to the name rules for UniScript functions. Only lowercase letters should be used for the name, e.g. _fiis_diesel.
Condition functions can be stored in an ic file in the directory UniPlotFormula.
If the program which executes the conversion of table formulas into UniScript functions finds any function calls, e.g. sqrt(), it replaces the name with _fif_sqrt(). Instead of sqrt, the function _fif_sqrt() is called.
The reason for this is that the UniScript function sqrt ignores “Missing Values” (see Channels with Missing Values) and will calculate complex numbers for negative values.
The function _fif_sqrt() is defined as following:
def _fif_sqrt(rvData)
{
r = rvData;
idx = find(rvData < 0 || rvData == MISSING_VALUE);
if (idx[1] != 0) {
r[idx] = MISSING_VALUE;
}
r = sqrt(r);
if (idx[1] != 0) {
r[idx] = MISSING_VALUE;
}
return r;
}
Accordingly, you can write your own functions for the formula table.
The function OnFormulaStartEval is called if the user starts the formula evaluation, e.g. over the F9 key.
The function has one parameter: The netCDF file handle (NC handle).
This function can check whether the formulas are to be applied to the active NC file or not. If the function does not exist, the formulas are calculated with all NC-files.
The function has read access to the NC-file.
In the following program listing the function checks whether the NC file contains a global attribute “Creator” that contains the string “Pasy”.
def OnFormulaStartEval(ncid)
{
if (nc_attinq_datatype(ncid, NC_GLOBAL, "Creator") == NC_CHAR) {
ssCreator = nc_attget(ncid, NC_GLOBAL, "Creator");
if (strmatch("*Pasy*", ssCreator)) {
return TRUE;
}
}
return FALSE;
}
OnFormulaStartEval(ncid) functions can also be stored in an IC file in the directory UniPlot\Formula.
The OnFormulaStartEval can be used to set a different formula directory.
If a function with the name OnFormulaStartEval is defined, it will be invoked by UniPlot to finish the calculation. OnFormulaStartEval can be used to set the original formula directory.
def OnFormulaStartEval(ncid)
{
svOldDir = FE_SetFormulaDirectory("C:/formula");
WriteProfileString("Formula", "olddir", strcat(svOldDir, ";"));
return TRUE;
}
def OnFormulaFinishEval()
{
ssOldDir = GetProfileString("Formula", "olddir");
FE_SetFormulaDirectory(ssOldDir);
}
id-71732