I am following the example in Esper documentation to create an expression following js dialect
Here's my EPL declaration
expression float js:IOU(xBottom1,yBottom1, xTop1, yTop1, xBottom2, yBottom2, xTop2, yTop2) [
IOU(xBottom1,yBottom1, xTop1, yTop1, xBottom2, yBottom2, xTop2, yTop2);
function IOU(xBottom1,yBottom1, xTop1, yTop1, xBottom2, yBottom2, xTop2, yTop2) {
//get the bottom left and top right points of the intersection triangle
var xIntersection1 = Math.max(xBottom1,xBottom2);
var yIntersection1 = Math.max(yBottom1,yBottom2);
var xIntersection2 = Math.min(xTop1,xTop2);
var yIntersection2 = Math.min(yTop1,yTop2);
var interArea = (Math.max(0, xIntersection2 - xIntersection1 +1) * Math.max(0, yIntersection2 - yIntersection1 +1));
var box1Area = (Math.max(0, xTop1 - xBottom1 +1) * Math.max(0, yTop1 - yBottom1 +1));
var box2Area = (Math.max(0, xTop2 - xBottom2 +1) * Math.max(0, yTop2 - yBottom2 +1));
var iou = interArea / parseFloat(box1Area+box2Area-interArea);
return iou;
}
]
However, I get a compilation error as Incorrect syntax near 'IOU' at line 2 column 4 [expression float js:IOU(xBottom1,yBottom1, xTop1, yTop1, xBottom2, yBottom2, xTop2, yTop2)...
I am not sure what is missing and if there are examples in Esper Github for using expressions? Do I need to configure the compiler somehow? This is not mentioned in the respective chapter, Chapter 19 of the documentation.
Just to clarify, I tried even with a single-line JS script and I verified the above JS function. So, I believe that it is related to how to define the script in EPL not the syntax itself within the respective dialect.
The standalone expression syntax is "create expression". Since I don't see anything else I presume you want to do a standalone expression and so its missing "create".
And when its not a standalone expression the syntax is "expression ... select ...".
Here is a link to one of the regression tests.
Related
I am working with Dymola, and try to use the functions provided by Modelica standard library in the command window, but it seems that I can't use them, and I couldn't claim a variable of a specific type either. I am wondering if there is some kind of limit of the command I could use in the command window of Dymola. Where should I find all the allowable commands?
I try to use some functions from Modelica.Media, it seems the input variables are out of range, but I tried a lot of times and different units system. I find that I can't declare a variable of pressure type in the command window, but Modelica.Media.Water.IF97_Utilities.h_pT() requires that I need to provide the variable as pressure and enthalpy type, is this the reason I can't use this function in the command window?
Modelica.Media.Water.IF97_Utilities.h_pT(1e6,800,1)
Failed to expand Modelica.Media.Water.IF97_Utilities.h_props_pT(
1000000.0,
800,
Modelica.Media.Common.IF97BaseTwoPhase(
phase = 1,
region = 1,
p = 1000000.0,
T = 800.0,
h = 9.577648835649013E+20,
R = 461.526,
cp = 1.8074392528071426E+20,
cv = -3.7247229288028774E+18,
rho = 5.195917767496603E-13,
s = 1.2052984524009106E+18,
pt = 645518.9415389205,
pd = 6.693617079374418E+18,
vt = 357209983199.2206,
vp = -553368.7088215105,
x = 0.0,
dpT = 645518.9415389205
)).
Failed to expand Modelica.Media.Water.IF97_Utilities.h_pT(1000000.0, 800, 1).
Assuming the inputs are valid there seems to be an issue specifically related to evaluating some media-functions interactively in Dymola (since they shouldn't be evaluated in models). It will be corrected in Dymola 2022x.
A temporary work-around is to first set the flag Advanced.SemiLinear = false; and then:
Modelica.Media.Water.IF97_Utilities.h_pT(1e6,800,1)
= 9.577648835649013E+20
(I'm not sure how valid the formulation is in that region.)
But please remember to set Advanced.SemiLinear = true; before translating and simulating any models - in particular models using media-functions.
The problem is that you are giving the function an invalid input. It seems Dymola does not give you the error-message for this based on the screenshot and logs you provided. I tried it in OpenModelica and got:
Modelica.Media.Water.IF97_Utilities.h_pT(100e5, 500e3)
[Modelica 4.0.0/Media/Water/IF97_Utilities.mo:2245:9-2246:77] Error: assert triggered: IF97 medium function g5: input temperature (= 500000 K) is higher than limit of 2273.15K in region 5
By using a value within the limits, it returns a value:
Modelica.Media.Water.IF97_Utilities.h_pT(100e5, 1e3)
I am working on a new version of the bfast monitor algorithm in Google Earth Engine. See the code of the original algorithm on Github.
The function bfastMonitor() takes user-defined parameters and applies some parameter checks before starting actual calculations. When the user-defined parameter settings are incompatible with the algorithm, an error should be raised.
During the parameter check, two types of if statements are made: statements that only check the parameter boundaries and raise an error at incompatible values, and statements that check and rewrite the contents of a parameter and raise an error at incompatible values. For the sake of the focus of this question, I will consider only the latter one.
Obviously, in a conventional coding paradigm, if-statements can be used to do this parameter check, however, using if-statements goes against the client-server model of GEE.
Consider the period parameter, which can only be 2,4,6,8, or 10. This parameter code used to index a list later in the code (line 459 on Github), where a period-value of 4 means that the list should be indexed at position 1, for instance.
Currently the implementation looks like this, using if-statements:
period = period||10
if (period == 2) {
period = 0;
} else if (period == 4){
period = 1;
}else if (period == 6){
period = 2;
}else if (period == 8){
period = 3;
}else if (period == 10){
period = 4;
}else {
alert("Error: for period parameter, we only have 2, 4, 6, 8,10. Choose one of these values");
}
Later on, the period parameter is used a form like this (from Github):
var exampleList = ee.List([0.001, 0.002, 0.003, 0.004, 0.005]);
var exampleValue = exampleList[period];
The code could be rewritten easily to get rid of the if-statements, like this for instance:
var period = ee.Number(6);
var periodDict = ee.Dictionary({
'2':0,
'4':1,
'6':2,
'8':3,
'10':4,
});
var exampleList = ee.List([0.001, 0.002, 0.003, 0.004, 0.005]);
var exampleValue = exampleList.get(periodDict.get(period.format()));
But then I don't know how to retain the opportunity to throw an error when the value for period is out of bounds.
How can I check the parameters of a function in Google Earth Engine and throw errors while avoiding if-statements?
There is nothing at all wrong with using a JavaScript if statement when it works. The advice you linked is about using ee.Algorithms.If which is unfortunately often inefficient — that's completely unrelated. The usual problem with a JavaScript if is when you're trying to use it on a server-side value that hasn't been computed yet.
But in your case, it looks like you want to validate a user-provided parameter. if is a perfectly fine way to do this.
I'll suggest one improvement: instead of using alert("error message");, use throw new Error:
throw new Error("For period parameter, we only have 2, 4, 6, 8,10. Choose one of these values");
This has two advantages:
It doesn't pop a dialog that the user must interact with before fixing the problem, but just results in an error message in the usual place, the Code Editor's Console.
It will stop the rest of the code from executing, which alert() doesn't.
When I add this equation
colViewHeight = (colItemSize * CGFloat(Counts)) + (colLineSpace *
CGFloat(Counts)) + (colViewTopSpace+colViewBottomSpace) as CGFloat
I get the below mentioned error.
The compiler is unable to type-check this expression in reasonable
time; try breaking up the expression into distinct sub-expressions
How to solve this issue? I am using xcode 10.01 version
Split it into multiple subexpressions and check if type casting is working fine
Such as:
let first = (colItemSize * CGFloat(Counts))
let second = (colViewTopSpace + colViewBottomSpace) as CGFloat
colViewHeight = first + second
Just delete the redundant bridge cast as CGFloat and the redundant parentheses
colViewHeight = colItemSize * CGFloat(Counts) + colLineSpace * CGFloat(Counts) + colViewTopSpace + colViewBottomSpace
I'm trying to split a datetime in two variables cx (should be the day in the year) and cy (should be the hour+minute/60) according to:
<!-- date format of d.date: 24-8-2016 9:47:38-->
var parseDayinYearFormat = d3.time.format('%j').parse;
var parseHourFormat = d3.time.format('%H').parse;
var parseMinuteFormat = d3.time.format('%M').parse;
<!-- add the objects-->
var circles = svg.selectAll("circle")
.data(data)
.enter()
.append("circle");
var circleAttributes = circles
.attr("cx", function (d) { return +parseDayinYearFormat(d.date); })
.attr("cy", function (d) { return +parseHourFormat(d.date)+(parseMinuteFormat(d.date)/60); })
.attr("r", function (d) { return 20.0/(9-d.total); })
.attr("class", function (d) {if (d.w>d.total-d.w) {return "cr"} else { return "cb" }});
But d3 isn't playing nice: cx and cy become a NaN and d3 is giving the error Uncaught TypeError: n.apply is not a function
Please help.
You need to parse the entire string with a single format object. You can’t parse the string with a sequence of parsings.
Using the d3 version 3.x documentation I came up with the following, which works on your example.
var datestring = '24-8-2016 9:47:38';
var format = d3.time.format('%-d-%-m-%Y %-H:%-M:%-S');
console.log(format.parse(datestring))
// "2016-08-24T13:47:38.000Z" // (my time zone is UTC-4)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
Note that because your example 24-8-2016 9:47:38 has many fields that show no zero-padding, I use a dash between the % and the specifier, i.e., %-d, to tell d3 that there may be no zero in the beginning.
Also note that in your example, there is no way 24 is a day-of-year, which is between 1 and 366: 24 is clearly just a day of the month, right?
However, it appears from your code snippet that you just want to extract the day and hour and minute from a string. For this simple purpose, d3.time.format might be overkill, since it gives you a Date object, which then you have to parse to extract the day/hour/minute. Consider using a regular expression for this task.
These two lines of code are giving me the
Could not find an overload for 'init' that accepts the supplied arguments
error:
var w = Int(self.bounds.size.width / Float(worldSize.width))
var h = Int(self.bounds.size.height / Float(worldSize.height))
The error message is misleading. This should work:
var w = Int(self.bounds.size.width / CGFloat(worldSize.width))
var h = Int(self.bounds.size.height / CGFloat(worldSize.height))
The width and height elements of CGSize are declared as CGFloat.
On the 64-bit platform, CGFloat is the same as Double and has 64-bit,
whereas Float has only 32-bit.
So the problem is the division operator,
which requires two operands of the same type. In contrast to (Objective-)C, Swift never implicitly converts values to a
different type.
If worldSize is also a CGSize then you do not need a cast at all:
var w = Int(self.bounds.size.width / worldSize.width)
var h = Int(self.bounds.size.height / worldSize.height)