02-23-2025 11:28 AM
I need to change the scale of a channel using the function ChnLinScale(ChnScaleInputChannel, ChnScaleOutputChannel, ChnScaleFactor, ChnScaleOffset).
The ChnScaleInputChannel has an arbitrary unit (i.e., A, mA, kPa).
The parameters ChnScaleFactor and ChnScaleOffset must be calculated from these equations.
ChnScaleFactor = (PhysicalRngUpper - PhysicalRngLower) / (MeasuredRngUpper - MeasuredRngLower)
ChnScaleOffset = - ChnScaleFactor * MeasuredRngLower + PhysicalRngLower
The parameters PhysicalRng and MeasuredRng can also have arbitrary unit.
MeasuredRng has the same physical quantity as ChnScaleInputChannel (current, voltage, etc.), but usually does not have the same unit.
In short, sometimes I need to convert the "mA" range to "kPa", other times "A" to "MPa". Any combination is possible.
I tried this calculation script but it doesn´t seem to work properly - see attachment "Calculation failed.png". With "Quantity-based" turned off the script works fine.
'Calculation Script Body
'------------------------------------------------------------------------------------
If Not This.QuantityBased Then
ChnScaleFactor.Value = (PhysicalRngUpper.Value - PhysicalRngLower.Value) / (MeasuredRngUpper.Value - MeasuredRngLower.Value)
ChnScaleOffset.Value = -ChnScaleFactor.Value * MeasuredRngLower.Value + PhysicalRngLower.Value
Call ChnLinScale(ChnScaleInputChannel, ChnScaleOutputChannel, ChnScaleFactor.Value, ChnScaleOffset.Value)
Else
Call Calculate(" ChnScaleFactor = (PhysicalRngUpper - PhysicalRngLower) /(MeasuredRngUpper- MeasuredRngLower)",CurrSymbols,CurrValues,"")
Call Calculate(" ChnScaleOffset = -ChnScaleFactor * MeasuredRngLower + PhysicalRngLower",CurrSymbols,CurrValues,"")
Call ChnLinScale(ChnScaleInputChannel, ChnScaleOutputChannel, ChnScaleFactor, ChnScaleOffset)
End If
I'd like to avoid adding new units to the database, I probably just need to get Diadem to correctly calculate ChnScaleFactor and ChnScaleOffset with respect to the input channel unit and input/output range unit.
Any help is appreciated.
John
02-27-2025 07:24 AM
Did you have a look at the build in conversion mechanisms?
Normally this should help on your job.
Try it in the Data portal when pressing the ... button behind the unit of your channel and use teachin to see the sript.
ChnConvertUnit("[2]/Noise_1", "[2]/Noise_1", "kPa")
03-01-2025 07:34 AM
Hello
Thanks for the hint.
I finally used similar approach and it seems to be working.
I spent some time trying to make Diadem to calculate it all by itself. But there were many problems.
Especially with unregistered units. I wanted to avoid having to constantly register new units combinations (e.g. kPa/m, kPa/mA etc.)
Also the function ChnLinScale probably takes parameters ChnScaleFactor and ChnScaleOffset as dimensionless.
So I finally turn off Quantity-based option and added few lines of code and this is the result.
'-------------------------------------------------------------------------------
'Calculation Script Body
'-------------------------------------------------------------------------------
Call MeasuredRngLower.Convert(ChnScaleInputChannel.UnitSymbol)
Call MeasuredRngUpper.Convert(ChnScaleInputChannel.UnitSymbol)
ChnScaleFactor.Value = (PhysicalRngUpper.Value - PhysicalRngLower.Value) / (MeasuredRngUpper.Value - MeasuredRngLower.Value)
ChnScaleOffset.Value = -ChnScaleFactor.Value * MeasuredRngLower.Value + PhysicalRngLower.Value
Call ChnLinScale(ChnScaleInputChannel, ChnScaleOutputChannel, ChnScaleFactor.Value, ChnScaleOffset.Value)
'-------------------------------------------------------------------------------
' post-processing
'-------------------------------------------------------------------------------
If PhysicalRngLower.UnitSymbol <> vbNullString Then
ChnScaleOutputChannel.UnitSymbol = PhysicalRngLower.UnitSymbol
ElseIf PhysicalRngUpper.UnitSymbol <> vbNullString Then
ChnScaleOutputChannel.UnitSymbol = PhysicalRngUpper.UnitSymbol
End If
By the way, when I was fiddling with quantity-based calculation I came across a few oddities.
For example the second part of this code returns wrong unit. (at least in Diadem 2023 Q2)
Dim sFormula, aSymbol(6), aMyValueUnit(6)
CalcQuantityBased = TRUE
aSymbol(1) = "I1"
aSymbol(2) = "I2"
aSymbol(3) = "O1"
aSymbol(4) = "O2"
aSymbol(5) = "Factor"
aSymbol(6) = "Offset"
Set aMyValueUnit(1) = CreateValueWithUnit(4, "s")
Set aMyValueUnit(2) = CreateValueWithUnit(20, "s")
Set aMyValueUnit(3) = CreateValueWithUnit(-1, "m")
Set aMyValueUnit(4) = CreateValueWithUnit(10, "m")
Set aMyValueUnit(5) = CreateValueWithUnit(null, "")
Set aMyValueUnit(6) = CreateValueWithUnit(null, "")
sFormula = "Factor= (O2-O1)/(I2-I1)"
Call Calculate (sFormula, aSymbol, aMyValueUnit, "")
'Result's unit is correctly 'm/s'
sFormula = "Offset = -Factor * I1 + O1"
Call Calculate (sFormula, aSymbol, aMyValueUnit, "")
'Throws error 'Invalid "s"(+)"m" unit conversion', because result's unit of
-Factor * I1 is incorrectly 's'
sFormula = "Offset = (-1) * Factor * I1 + O1"
Call Calculate (sFormula, aSymbol, aMyValueUnit, "")
'Result's unit is correctly 'm'
Or this example. It is using syntax from Diadem help.
CalcQuantityBased = TRUE
Call Calculate("R1=(VU(20,""m"")-VU(4,""m""))/(VU(10,""s"")-VU(-1,""s""))",,,"")
LogFileWrite R1 & " " & CalculateResultUnit
'Output is correct 'm/s'
T1 = CalculateResultUnit
Call Calculate("R2= -1* R1 * VU(-1,""s"") ",,,"")
LogFileWrite R2 & " " & CalculateResultUnit
'Output is incorrect 's'
Call Calculate("R2= -1* VU(R1,T1) * VU(-1,""s"") ",,,"")
LogFileWrite R2 & " " & CalculateResultUnit
'This doesn't work at all
Maybe, I can't use correct methods, syntax or whatever.
John