Scripting Compound Attribute Types
The Ansys Orbit Determination Tool Kit (ODTK®) application uses several compound types that have special methods for handling units, dimensions, date representations, and coordinate system transformations. Types also include standard containers such as lists and sets.
This topic provides short descriptions and application-related code examples (COM and Cross-platform API) for the following compound types:
Type QUANTITY
Quantities are values that have an associated unit, such as 1 second, 5 kilometers, and 3 radians/second. Several methods and properties are available to work with the quantity attributes.
The properties "Unit" and "Dimension" return the default unit and dimension.
COM
MsgBox "Unit: " & scen.Filter(0).ProcessControl.TimeSpan.Unit
MsgBox "Dimension: " & scen.Filter(0).ProcessControl.TimeSpan.Dimension
var Shell = new ActiveXObject("WScript.Shell");
Shell.Popup("Unit: " + scen.Filter(0).ProcessControl.TimeSpan.Unit);
Shell.Popup("Dimension: " + scen.Filter(0).ProcessControl.TimeSpan.Dimension);
my $unit = $scen->Filter(0)->ProcessControl->TimeSpan->Unit->{Value};
my $dim = $scen->Filter(0)->ProcessControl->TimeSpan->Dimension->{Value};
Win32::MsgBox "Unit: $unit";
Win32::MsgBox "Dimension: $dim";
print("Unit: " + str(scen.Filter(0).ProcessControl.TimeSpan.Unit))
print("Dimension: " + str(scen.Filter(0).ProcessControl.TimeSpan.Dimension))
proc = scen.invoke('Filter').invoke('Item', 0).invoke('ProcessControl');
unit = proc.invoke('TimeSpan').invoke('Unit').invoke('Value');
dim = proc.invoke('TimeSpan').invoke('Dimension').invoke('Value');
fprintf('Unit: %s\nDimension: %s\n', unit, dim);
Cross-Platform API
print(f'Unit: {filter1.ProcessControl.TimeSpan.Unit.eval()}')
print(f'Dimension: {filter1.ProcessControl.TimeSpan.Dimension.eval()}')
fprintf("Unit: %s\n", filter1.ProcessControl.TimeSpan.Unit);
fprintf("Dimension: %s\n", filter1.ProcessControl.TimeSpan.Dimension);
std::cout << "Unit: " << filter1("ProcessControl")("TimeSpan")("Unit").AsString() << "\n";
std::cout << "Dimension: " << filter1("ProcessControl")("TimeSpan")("Dimension").AsString() << "\n";
System.out.println("Unit: " + filter1.get("ProcessControl.TimeSpan.Unit").asString() );
System.out.println( "Dimension: " + filter1.get("ProcessControl.TimeSpan.Dimension").asString() );
The methods GetIn() and Set() perform unit conversion based on the input unit.
COM
scen.Filter(0).ProcessControl.TimeSpan.Set 4, "min"
MsgBox scen.Filter(0).ProcessControl.TimeSpan.GetIn("min") & " min"
MsgBox scen.Filter(0).ProcessControl.TimeSpan.GetIn("sec") & " sec"
var Shell = new ActiveXObject("WScript.Shell");
scen.Filter(0).ProcessControl.TimeSpan.Set(4, "min");
Shell.Popup(scen.Filter(0).ProcessControl.TimeSpan.GetIn("min") + " min");
Shell.Popup(scen.Filter(0).ProcessControl.TimeSpan.GetIn("sec") + " sec");
$scen->Filter(0)->ProcessControl->TimeSpan->Set(4, "min");
my $mins = $scen->Filter(0)->ProcessControl->TimeSpan->GetIn("min")->{Value};
Win32::MsgBox "$mins min";
my $secs = $scen->Filter(0)->ProcessControl->TimeSpan->GetIn("sec")->{Value};
Win32::MsgBox "$secs sec";
scen.Filter(0).ProcessControl.TimeSpan.Set(4, "min")
print(str(scen.Filter(0).ProcessControl.TimeSpan.GetIn("min")) + " min")
print(str(scen.Filter(0).ProcessControl.TimeSpan.GetIn("sec")) + " sec")
proc = scen.invoke('Filter').invoke('Item', 0).invoke('ProcessControl');
proc.invoke('TimeSpan').invoke('Set', 4, 'min');
mins = proc.invoke('TimeSpan').invoke('GetIn', 'min').invoke('Value');
secs = proc.invoke('TimeSpan').invoke('GetIn', 'sec').invoke('Value');
fprintf('%f mins\n%f secs\n', mins, secs);
Cross-Platform API
filter1.ProcessControl.TimeSpan.Set(4, 'min')
print(f'{filter1.ProcessControl.TimeSpan.GetIn("min")} min')
print(f'{filter1.ProcessControl.TimeSpan.GetIn("sec")} sec')
filter1.ProcessControl.TimeSpan.Set(4, 'min');
fprintf("%f min\n", filter1.ProcessControl.TimeSpan.GetIn("min"));
fprintf("%f sec\n", filter1.ProcessControl.TimeSpan.GetIn("sec"));
filter1("ProcessControl")("TimeSpan")("Set").Invoke(4, "min");
std::cout << filter1("ProcessControl")("TimeSpan")("GetIn").InvokeDouble("min") << " min\n";
std::cout << filter1("ProcessControl")("TimeSpan")("GetIn").InvokeDouble("sec") << " sec\n";
filter1.get("ProcessControl.TimeSpan.Set").invoke(4, "min");
System.out.println(filter1.get("ProcessControl.TimeSpan.GetIn").invokeDouble("min") + " min");
System.out.println(filter1.get("ProcessControl.TimeSpan.GetIn").invokeDouble("sec") + " sec");
Even though the following will work, it is unsafe to assume the default unit.
COM
scen.Filter(0).ProcessControl.TimeSpan = 24 ' Do not assume unit!!!
MsgBox scen.Filter(0).ProcessControl.TimeSpan ' Defaults may change!!!
var Shell = new ActiveXObject("WScript.Shell");
scen.Filter(0).ProcessControl.TimeSpan = 24; // Do not assume unit!!!
Shell.Popup(scen.Filter(0).ProcessControl.TimeSpan); // Defaults may change!!!
scen.Filter(0).ProcessControl.TimeSpan = 24 # Do not assume unit!!!
print(scen.Filter(0).ProcessControl.TimeSpan) # Defaults may change!!!
You can also get the internal value with the function GetInternal, which is likely to be in different units than the default input/output units. Internal units may change from version to version, so you should avoid using this function.
In addition to working with one of the scenario object quantities, you can create a new quantity object with the ODTK.NewQuantity() function. You can either assign the returned quantity object to one of the existing attributes or use it to perform a unit conversion.
COM
set temp = ODTK.NewQuantity(2,"arcSec")
set trkSys = scen.TrackingSystem("TrkSys1")
trkSys.Facility("Facility1").MeasurementStatistics(2).Type.Bias = temp
trkSys.IonosphereModel.TransmitFreq = ODTK.NewQuantity(2100,"MHz")
MsgBox ODTK.NewQuantity(100,"mi/hr").GetIn("km/sec")
var Shell = new ActiveXObject("WScript.Shell");
var temp = ODTK.NewQuantity(2,"arcSec");
var trkSys = scen.TrackingSystem("TrkSys1");
trkSys.Facility("Facility1").MeasurementStatistics(2).Type.Bias = temp;
trkSys.IonosphereModel.TransmitFreq = ODTK.NewQuantity(2100,"MHz");
Shell.Popup(ODTK.NewQuantity(100,"mi/hr").GetIn("km/sec"));
my $temp = $ODTK->NewQuantity(2,"arcSec");
my $trkSys = $scen->TrackingSystem("TrkSys1");
$trkSys->Facility("Facility1")->MeasurementStatistics(2)->Type->Bias->Assign($temp);
$trkSys->IonosphereModel->TransmitFreq->Assign($ODTK->NewQuantity(2100,"MHz"));
my $kmsec = $ODTK->NewQuantity(100,"mi/hr")->GetIn("km/sec")->{Value};
Win32::MsgBox $kmsec;
temp = ODTK.NewQuantity(2,"arcSec")
trkSys = scen.TrackingSystem("TrkSys1")
trkSys.Facility("Facility1").MeasurementStatistics(2).Type.Bias = temp
trkSys.IonosphereModel.TransmitFreq = ODTK.NewQuantity(2100,"MHz")
print(ODTK.NewQuantity(100,"mi/hr").GetIn("km/sec"))
temp = odtk.invoke('NewQuantity', 2, 'arcSec');
trkSys = scen.invoke('TrackingSystem').invoke('TrkSys1');
trkSys.invoke('Facility').invoke('Facility1').invoke('MeasurementStatistics').invoke('Item', 2).invoke('Type').invoke('Bias').invoke('Assign', temp);
trkSys.invoke('IonosphereModel').invoke('TransmitFreq').invoke('Assign' , odtk.invoke('NewQuantity', 2100, 'MHz'));
mph = odtk.invoke('NewQuantity', 100, 'mi/hr');
mpsec = mph.invoke('GetIn', 'm/sec').invoke('Value');
fprintf('%f\n', mpsec);
When using VBScript, it is very important to use the "set" keyword when saving return values from the NewQuantity function. Using "set" ensures that you save a handle to the Quantity object. Without the "set" keyword, VBScript will retrieve the CDbl value of the Quantity value.
X = ODTK.NewQuantity(100,"mi/hr")
MsgBox x.GetIn("km/sec") ' This generates a run-time error: x is CDbl
Cross-Platform API
temp = odtk.NewQuantity(2, 'arcSec')
facility.MeasurementStatistics[2].Type.Bias = temp
tracking_system.IonosphereModel.TransmitFreq = odtk.NewQuantity(2100, 'MHz')
qty = odtk.NewQuantity(100, 'mi/hr')
kmSecQty = qty.GetIn('km/sec')
print(f'qty: {kmSecQty} km/sec')
temp = odtk.NewQuantity(2, "arcSec");
facility.MeasurementStatistics{2}.Type.Bias = temp;
trackingSystem.IonosphereModel.TransmitFreq = odtk.NewQuantity(2100, "MHz");
qty = odtk.NewQuantity(100, "mi/hr");
fprintf("Quantity: %f km/sec\n", qty.GetIn("km/sec"));
const agi::odtk::AttrProxy temp = odtk("NewQuantity").InvokeAttrProxy(2, "arcSec");
facility("MeasurementStatistics")[2]("Type")("Bias").Assign(temp);
trackingSystem("IonosphereModel")("TransmitFreq").Assign(odtk("NewQuantity").InvokeAttrProxy(2100, "MHz"));
const agi::odtk::AttrProxy qty = odtk("NewQuantity").InvokeAttrProxy(100, "mi/hr");
std::cout << "Quantity: " << qty("GetIn").InvokeDouble("km/sec") << " km/sec\n";
AttrProxy temp = odtk.get("NewQuantity").invokeAttr(2, "arcSec");
Facility.get("MeasurementStatistics[2].Type.Bias").assign(temp);
trackingSystem.get("IonosphereModel.TransmitFreq").assign(odtk.get("NewQuantity").invokeAttr(2100, "MHz"));
AttrProxy qty = odtk.get("NewQuantity").invokeAttr(100, "mi/hr");
System.out.println("Quantity: " + qty.get("GetIn").invokeDouble("km/sec") + " km/sec");
Type DATE
Dates are treated similarly to Quantities. They have a Set() method to assign a value and a Format() method to retrieve the DateTime string in a specified format. To see available date formats, click the icon while editing any Date field. You can create a new Date object using the ODTK.NewDate() function. The first parameter is the value or string containing the date, and the second parameter is one of the standard ODTK date formats.
COM
var Shell = new ActiveXObject("WScript.Shell");
var jd1 = ODTK.NewDate(1, "JDate");
Shell.Popup("1 JD:" + jd1.Format("UTCG"));
my $jd1 = $ODTK->NewDate(1, "JDate");
my $utc = $jd1->Format("UTCG")->{Value};
Win32::MsgBox "1 JD = $utc";
jd1 = odtk.invoke('NewDate', 1, 'JDate');
utc = jd1.invoke('Format', 'UTCG').invoke('Value');
fprintf('1 JD: %s\n', utc);
Cross-Platform API
const agi::odtk::AttrProxy jd1 = odtk("NewDate").InvokeAttrProxy(1, "JDate");
std::cout << "JDate: " << jd1("Format").InvokeString("UTCG") << "\n";
AttrProxy jd1 = odtk.get("NewDate").invokeAttr(1, "JDate");
System.out.println("JDate: " + jd1("Format").invokeString("UTCG") );
As with the Quantity object, make sure to use the "set" with VBScript or you will get an undefined behavior.
The Set() function returns a handle to the Date object that is being modified. The input parameters are the same as the NewDate function.
COM
set s = scen.Filter("Filter1").ProcessControl.StartTime.Set(1,"JDate")
MsgBox scen.Filter("Filter1").ProcessControl.StartTime.Format("GPSG")
var Shell = new ActiveXObject("WScript.Shell");
var s = scen.Filter("Filter1").ProcessControl.StartTime.Set(1,"JDate");
Shell.Popup(scen.Filter("Filter1").ProcessControl.StartTime.Format("GPSG"));
$scen->Filter("Filter1")->ProcessControl->StartTime->Set(1,"JDate");
my $gpsg = $scen->Filter("Filter1")->ProcessControl->StartTime->Format("GPSG")->{Value};
Win32::MsgBox $gpsg;
s = scen.Filter("Filter1").ProcessControl.StartTime.Set(1,"JDate")
print(scen.Filter("Filter1").ProcessControl.StartTime.Format("GPSG"))
proc = scen.invoke('Filter').invoke('Filter1').invoke('ProcessControl');
proc.invoke('StartTime').invoke('Set', 1, 'JDate');
gpsg = proc.invoke('StartTime').invoke('Format', 'GPSG').invoke('Value');
fprintf('%s\n', gpsg);
Cross-Platform API
filter1.ProcessControl.StartTime.Set(1, 'JDate')
start_time = filter1.ProcessControl.StartTime.Format('GPSG')
print(f'Start time: {start_time}')
filter1.ProcessControl.StartTime.Set(1, "JDate");
fprintf("JDate: %s\n", filter1.ProcessControl.StartTime.Format("GPSG"));
filter1("ProcessControl")("StartTime")("Set").Invoke(1, "JDate");
std::cout << "JDate: " << filter1("ProcessControl")("StartTime")("Format").InvokeString("GPSG") << "\n";
filter1.get("ProcessControl.StartTime.Set").invoke(1, "JDate");
System.out.println("JDate: " + filter1.get("ProcessControl.StartTime.Format").invokeString("GPSG) );
The ODTK Date object also implements three Date Time arithmetic methods: AddTime, SubtractTime, and SubtractDate.
COM
set d1 = scen.Filter("Filter1").ProcessControl.StartTime
set d2 = scen.Filter("Filter1").ProcessControl.StopTime
set d3 = d1.AddTime( ODTK.NewQuantity(1,"hr" ) )
set d4 = d2.SubtractTime( ODTK.NewQuantity(5,"min") )
set timeSpan = d4.SubtractDate(d3)
MsgBox timeSpan.GetIn("min")
var Shell = new ActiveXObject("WScript.Shell");
var d1 = scen.Filter("Filter1").ProcessControl.StartTime;
var d2 = scen.Filter("Filter1").ProcessControl.StopTime;
var d3 = d1.AddTime( ODTK.NewQuantity(1,"hr" ) );var d4 = d2.SubtractTime( ODTK.NewQuantity(5,"min") );
var timeSpan = d4.SubtractDate(d3);
Shell.Popup(timeSpan.GetIn("min"));
my $d1 = $scen->Filter("Filter1")->ProcessControl->StartTime;
my $d2 = $scen->Filter("Filter1")->ProcessControl->StopTime;
my $d3 = $d1->AddTime( $ODTK->NewQuantity(1,"hr" ) );
my $d4 = $d2->SubtractTime( $ODTK->NewQuantity(5,"min") );
my $timeSpan = $d4->SubtractDate($d3);
my $ts = $timeSpan->GetIn("min")->{Value};
Win32::MsgBox $ts;
d1 = scen.Filter("Filter1").ProcessControl.StartTime
d2 = scen.Filter("Filter1").ProcessControl.StopTime
d3 = d1.AddTime(ODTK.NewQuantity(1,"hr" ))
d4 = d2.SubtractTime(ODTK.NewQuantity(5,"min"))
timeSpan = d4.SubtractDate(d3)
print(timeSpan.GetIn("min"))
d1 = scen.invoke('Filter').invoke('Filter1').invoke('ProcessControl').invoke('StartTime');
d2 = scen.invoke('Filter').invoke('Filter1').invoke('ProcessControl').invoke('StopTime');
d3 = d1.invoke('AddTime', odtk.invoke('NewQuantity', 1, 'hr' ));
d4 = d2.invoke('SubtractTime', odtk.invoke('NewQuantity', 5, 'min'));
timeSpan = d4.invoke('SubtractDate', d3);
ts = timeSpan.invoke('GetIn', 'min').invoke('Value');
fprintf('%f\n', ts);
Cross-Platform API
d1 = filter1.ProcessControl.StartTime
d2 = filter1.ProcessControl.StopTime
d3 = d1.AddTime(odtk.NewQuantity(1, 'hr'))
d4 = d2.SubtractTime(odtk.NewQuantity(5, 'min'))
timeSpan = d4.SubtractDate(d3)
timeSpanMin = timeSpan.GetIn('min')
print(f'Time span: {timeSpanMin} min')
d1 = filter1.ProcessControl.StartTime;
d2 = filter1.ProcessControl.StopTime;
d3 = d1.AddTime(odtk.NewQuantity(1, "hr"));
d4 = d2.SubtractTime(odtk.NewQuantity(5, "min"));
timeSpan = d4.SubtractDate(d3);
fprintf("Timespan: %f min\n", timeSpan.GetIn('min'));
const agi::odtk::AttrProxy d1 = filter1("ProcessControl")("StartTime");
const agi::odtk::AttrProxy d2 = filter1("ProcessControl")("StopTime");
const agi::odtk::AttrProxy d3 = d1("AddTime").InvokeAttrProxy(odtk("NewQuantity").InvokeAttrProxy(1, "hr"));
const agi::odtk::AttrProxy d4 = d2("SubtractTime").InvokeAttrProxy(odtk("NewQuantity").InvokeAttrProxy(5, "min"));
const agi::odtk::AttrProxy timeSpan = d4("SubtractDate").InvokeAttrProxy(d3);
std::cout << "Timespan: " << timeSpan("GetIn").InvokeDouble("min") << " min\n";
AttrProxy d1 = filter1("ProcessControl")("StartTime");
AttrProxy d2 = filter1("ProcessControl")("StopTime");
AttrProxy d3 = d1("AddTime").InvokeAttrProxy(odtk("NewQuantity").InvokeAttrProxy(1, "hr"));
AttrProxy d4 = d2("SubtractTime").InvokeAttrProxy(odtk("NewQuantity").InvokeAttrProxy(5, "min"));
AttrProxy timeSpan = d4("SubtractDate").InvokeAttrProxy(d3);
std::cout << "Timespan: " << timeSpan("GetIn").InvokeDouble("min") << " min\n";
In addition to arithmetic functions, these functions allow date comparison:
-
Equals()
-
GreaterThan()
-
GreaterThanOrEqual()
-
Inequality()
-
LessThan()
-
LessThanOrEqual()
They return a Boolean, and you can use them to test dates as follows:
COM
set t1 = scen.Simulator(0).ProcessControl.StartTime
set t2 = scen.Filter(0).ProcessControl.StartTime
if t1.GreaterThan(t2) then
MsgBox "Greater than"
end if
if t1.Equals(t2) then
MsgBox "Equal"
end if
if t1.LessThanOrEqual(t2) then
MsgBox "Less than or equal"
end if
var Shell = new ActiveXObject("WScript.Shell");
var t1 = scen.Simulator(0).ProcessControl.StartTime;
var t2 = scen.Filter(0).ProcessControl.StartTime;
if(t1.GreaterThan(t2).value)
Shell.Popup("Greater than");
if(t1.Equals(t2).value)
Shell.Popup("Equal");
if(t1.LessThanOrEqual(t2).value)
Shell.Popup("Less than or equal");
my $t1 = $scen->Simulator(0)->ProcessControl->StartTime;
my $t2 = $scen->Filter(0)->ProcessControl->StartTime;
if ($t1->GreaterThan($t2)->{Value})
{
Win32::MsgBox("Greater than");
}
if ($t1->Equals($t2)->{Value})
{
Win32::MsgBox("Equal");
}
if ($t1->LessThanOrEqual($t2)->{Value})
{
Win32::MsgBox("Less than or equal");
}
t1 = scen.Simulator(0).ProcessControl.StartTime
t2 = scen.Filter(0).ProcessControl.StartTime
if t1.GreaterThan(t2).value:
print("Greater than")
if t1.Equals(t2).value:
print("Equal")
if t1.LessThanOrEqual(t2).value:
print("Less than or equal")
t1 = scen.invoke('Simulator').invoke('Item', 0).invoke('ProcessControl').invoke('StartTime');
t2 = scen.invoke('Filter').invoke('Item', 0).invoke('ProcessControl').invoke('StartTime');
if (t1.invoke('GreaterThan', t2).invoke('Value'))
fprintf('Greater than\n');
end
if (t1.invoke('Equals', t2).invoke('Value'))
fprintf('Equal\n');
end
if (t1.invoke('LessThanOrEqual', t2).invoke('Value'))
fprintf('Less than or equal\n');
end
Cross-Platform API
t1 = simulator.ProcessControl.StartTime
t2 = filter1.ProcessControl.StartTime
t1_utcg = t1.Format('UTCG')
print(f't1: {t1_utcg}')
t2_utcg = t2.Format('UTCG')
print(f't2: {t2_utcg}')
if t1.GreaterThan(t2):
print('t1 > t2')
if t1.GreaterThanOrEqual(t2):
print('t1 >= t2')
if t1.GreaterThanOrEqual(t1):
print('t1 >= t1')
if t1.LessThanOrEqual(t1):
print('t1 <= t1')
if t1.Equals(t1):
print('t1 == t1')
if t1.Inequality(t2):
print('t1 != t2')
if t2.LessThan(t1):
print('t2 < t1')
if t2.LessThanOrEqual(t1):
print('t2 <= t1')
t1 = simulator.ProcessControl.StartTime;
t2 = filter1.ProcessControl.StartTime;
fprintf("t1: %s\n", t1.Format('UTCG'));
fprintf("t2: %s\n", t2.Format('UTCG'));
if t1.GreaterThan(t2)
fprintf("t1 > t2\n");
end
if t1.GreaterThanOrEqual(t2)
fprintf("t1 >= t2\n");
end
if t1.GreaterThanOrEqual(t1)
fprintf("t1 >= t1\n")
end
if t1.LessThanOrEqual(t1)
fprintf("t1 <= t1\n")
end
if t1.Equals(t1)
fprintf("t1 == t1\n")
end
if t1.Inequality(t2)
fprintf("t1 != t2\n")
end
if t2.LessThan(t1)
fprintf("t2 < t1\n")
end
if t2.LessThanOrEqual(t1)
fprintf("t2 <= t1\n")
end
const agi::odtk::AttrProxy t1 = simulator("ProcessControl")("StartTime");
const agi::odtk::AttrProxy t2 = filter1("ProcessControl")("StartTime");
std::cout << "t1: " << t1("Format").InvokeString("UTCG") << "\n";
std::cout << "t2: " << t2("Format").InvokeString("UTCG") << "\n";
if (t1("GreaterThan").InvokeBool(t2))
{
std::cout << "t1 > t2\n";
}
if (t1("GreaterThanOrEqual").InvokeBool(t2))
{
std::cout << "t1 <= t2\n";
}
if (t1("GreaterThanOrEqual").InvokeBool(t1))
{
std::cout << "t1 <<= t1\n";
}
if (t1("LessThanOrEqual").InvokeBool(t1))
{
std::cout << "t1 <= t1\n";
}
if (t1("Equals").InvokeBool(t1))
{
std::cout << "t1 == t1\n";
}
if (t1("Inequality").InvokeBool(t2))
{
std::cout << "t1 != t2\n";
}
if (t2("LessThan").InvokeBool(t1))
{
std::cout << "t2 < t1\n";
}
if (t2("LessThanOrEqual").InvokeBool(t1))
{
std::cout << "t2 <= t1\n";
}
AttrProxy t1 = simulator.get("ProcessControl.StartTime");
AttrProxy t2 = filter1.get("ProcessControl.StartTime");
String t1Utcg = t1.get("Format").invokeString("UTCG");
System.out.println("t1: " + t1Utcg);
String t2Utcg = t2.get("Format").invokeString("UTCG");
System.out.println("t2: " + t2Utcg);
if (t1.get("GreaterThan").invokeBool(t2)) {
System.out.println("t1 > t2");
}
if (t1.get("GreaterThanOrEqual").invokeBool(t2)) {
System.out.println("t1 >= t2");
}
if (t1.get("GreaterThanOrEqual").invokeBool(t1)) {
System.out.println("t1 >= t1");
}
if (t1.get("LessThanOrEqual").invokeBool(t1)) {
System.out.println("t1 <= t1");
}
if (t1.get("Equals").invokeBool(t1)) {
System.out.println("t1 == t1");
}
if (t1.get("Inequality").invokeBool(t2)) {
System.out.println("t1 != t2");
}
if (t2.get("LessThan").invokeBool(t1)) {
System.out.println("t2 < t1");
}
if (t2.get("LessThanOrEqual").invokeBool(t1)) {
System.out.println("t2 <= t1");
}
Date objects are often useful when converting date and time formats from other software or systems. You can use the ODTK application as a date conversion utility, even when the input format is not one that the ODTK application natively supports. You can often reorganize the input date and time into something that the ODTK application can handle. For example, you may have a date and time format that consists of the year and the elapsed seconds since the beginning of the year, assumed to be 1 Jan 00:00:00 UTC. Consider the date and time given as 2009/2560004. You could rely on your own date conversion routines and worry about leap years and leap seconds. Or you could simply pass it into the ODTK application using something like the following and then request it back out in a different format.
COM
set testdate = ODTK.NewDate("1 Jan 2009 00:00:256", "UTCG")
set testdate = ODTK.NewDate("001/2560004 2009", "GMT" )
var testdate = ODTK.NewDate("1 Jan 2009 00:00:256", "UTCG");
var testdate = ODTK.NewDate("001/2560004 2009", "GMT" );
testdate = ODTK.NewDate("1 Jan 2009 00:00:256", "UTCG")
testdate = ODTK.NewDate("001/2560004 2009", "GMT" )
Cross-Platform API
test_date = odtk.NewDate("1 Jan 2009 00:00:256", "UTCG")
print(f"test_date: {test_date.Format('UTCG')}")
test_date = odtk.NewDate("001/2560004 2009", "GMT")
testDate = odtk.NewDate("1 Jan 2009 00:00:256", "UTCG");
fprintf("testDate: %s\n", testDate.Format("UTCG"));
testDate = odtk.NewDate("001/2560004 2009", "GMT");
fprintf("testDate: %s\n", testDate.Format("UTCG"));
const agi::odtk::AttrProxy testDate1 = odtk("NewDate").InvokeAttrProxy("1 Jan 2009 00:00:256", "UTCG");
std::cout << "testDate1: " << testDate1("Format").InvokeString("UTCG") << "\n";
const agi::odtk::AttrProxy testDate2 = odtk("NewDate").InvokeAttrProxy("001/2560004 2009", "GMT");
std::cout << "testDate2: " << testDate2("Format").InvokeString("UTCG") << "\n";
AttrProxy testDate = odtk.get("NewDate").invokeAttr("1 Jan 2009 00:00:256", "UTCG");
System.out.println("testDate: " + testDate.get("Format").invokeString("UTCG"));
testDate = odtk.get("NewDate").invokeAttr("001/2560004 2009", "GMT");
System.out.println("testDate: " + testDate.get("Format").invokeString("UTCG"));
This trick of using the hour, minute, or second field and putting any value you want in it is perfectly acceptable.
Type LINKTO
File and directory names are strings, but they are validated during the assignment. The application makes sure that an input file exists, or an output file can be written. Otherwise, it will generate an error and the new value will not be set.
Examples of setting values are as follows:
COM
Cross-Platform API
try
# set non-existent file
scenario.EarthDefinition.EOPFilename = 'C:\\Non-Existent-Folder\\none-existent-file.txt'
raise Exception('The expected exception was not thrown.')
except ClientException as e:
if e.error_code == ClientExceptionCodes.EXECUTION_ERROR and 'Cannot find file' in str(e):
print('Non-existent file path threw an exception as expected.')
else:
raise Exception('Unexpected exception was raised.')
try
% set non-existent file
scenario.EarthDefinition.EOPFilename = "C:\\Non-Existent-Folder\\none-existent-file.txt";
throw(MException('ScriptingGuide:unexpectedError', 'The expected exception was not thrown.'));
catch ex
if ex.identifier == ClientExceptionIDs.ExecutionError && contains(ex.message, "Cannot find file")
fprintf("Non-existent file path threw an exception as expected.\n");
else
throw(MException('ScriptingGuide:unexpectedError', 'An unexpected exception was thrown.'));
end
end
try
{
// set non - existent file
scenario("EarthDefinition")("EOPFilename").Assign("C:\\Non-Existent-Folder\\none-existent-file.txt");
throw std::runtime_error("The expected exception was not thrown.");
}
catch (const agi::odtk::ClientException& clientException)
{
if (clientException.ErrorCode == agi::odtk::clientExceptionCodes::ExecutionError && strstr(clientException.what(), "Cannot find file"))
{
std::cout << "Non-existent file path threw an exception as expected.\n";
}
else
{
throw std::runtime_error("An unexpected exception was thrown.");
}
}
try {
// set non - existent file
Scenario.get("EarthDefinition.EOPFilename").assign("C:\\Non-Existent-Folder\\none-existent-file.txt");
throw new Exception("The expected exception was not thrown.");
}
catch (ClientException clientException) {
if(!clientException.errorCode.equals(ClientExceptionCodes.EXECUTION_ERROR) || !clientException.message.contains("Cannot find file")) {
throw new Exception("Unexpected exception was raised.");
} else {
System.out.println("Non-existent file path threw an exception as expected.");
}
}
The following are examples of getting values for a filename:
COM
Cross-Platform API
try
# set non-existent file
print (scenario.EarthDefinition.EOPFilename.value.eval())
raise Exception('The expected exception was not thrown.')
except ClientException as e:
if e.error_code == ClientExceptionCodes.EXECUTION_ERROR and 'Cannot find file' in str(e):
print('Non-existent file path threw an exception as expected.')
else:
raise Exception('Unexpected exception was raised.')
try
% set non-existent file
scenario.EarthDefinition.EOPFilename = "C:\\Non-Existent-Folder\\none-existent-file.txt";
throw(MException('ScriptingGuide:unexpectedError', 'The expected exception was not thrown.'));
catch ex
if ex.identifier == ClientExceptionIDs.ExecutionError && contains(ex.message, "Cannot find file")
fprintf("Non-existent file path threw an exception as expected.\n");
else
throw(MException('ScriptingGuide:unexpectedError', 'An unexpected exception was thrown.'));
end
end
try
{
// set non - existent file
scenario("EarthDefinition")("EOPFilename").Assign("C:\\Non-Existent-Folder\\none-existent-file.txt");
throw std::runtime_error("The expected exception was not thrown.");
}
catch (const agi::odtk::ClientException& clientException)
{
if (clientException.ErrorCode == agi::odtk::clientExceptionCodes::ExecutionError && strstr(clientException.what(), "Cannot find file"))
{
std::cout << "Non-existent file path threw an exception as expected.\n";
}
else
{
throw std::runtime_error("An unexpected exception was thrown.");
}
}
try {
// set non - existent file
Scenario.get("EarthDefinition.EOPFilename").assign("C:\\Non-Existent-Folder\\none-existent-file.txt");
throw new Exception("The expected exception was not thrown.");
}
catch (ClientException clientException) {
if(!clientException.errorCode.equals(ClientExceptionCodes.EXECUTION_ERROR) || !clientException.message.contains("Cannot find file")) {
throw new Exception("Unexpected exception was raised.");
} else {
System.out.println("Non-existent file path threw an exception as expected.");
}
}
Type LINKTO ENUMERATION
Some objects have links to enumerated types, such as the solar radiation pressure model or measurement bias model, and are identified as having type "LINKTO ENUMERATION". These parameters have an extra attribute "Type" that you can use to set and get their values.
There are some unique Multiple Representation attributes that combine enumeration behavior for reading attributes, but use object-like scope for assigning attributes. See these special cases (e.g., Satellite.OrbitState and Facility.Position) in the Scripting Multiple Representations section.
COM
set sat = scen.Satellite("Satellite1")
sat.ForceModel.SolarPressure.Model.Type = "Spherical"
Msgbox sat.ForceModel.SolarPressure.Model.Type
var Shell = new ActiveXObject("WScript.Shell");
var sat = scen.Satellite("Satellite1");
sat.ForceModel.SolarPressure.Model.Type = "Spherical";
Shell.Popup(sat.ForceModel.SolarPressure.Model.Type);
my $sat =$scen->Satellite("Satellite1");
$sat->ForceModel->SolarPressure->Model->{Type} = "Spherical";
print $sat->ForceModel->SolarPressure->Model->{Type};
sat = scen.Satellite("Satellite1")
sat.ForceModel.SolarPressure.Model.Type = "Spherical"
print(sat.ForceModel.SolarPressure.Model.Type)
sat = scen.invoke('Satellte').invoke('Satellite1');
sat.invoke('ForceModel').invoke('SolarPressure').invoke('Model').invoke('Type') = 'Spherical';
fprintf('%s\n', sat.invoke('ForceModel').invoke('SolarPressure').invoke('Model').invoke('Type').invoke('Value'));
Cross-Platform API
satellite.ForceModel.SolarPressure.Model.Type = 'Spherical'
print(f'Solar pressure model: {satellite.ForceModel.SolarPressure.Model.Type.eval()}')
# currently doesn't work with ODTKRuntime (scenario.Measurements.Files is empty)
demonstrate_list = True
satellite.ForceModel.SolarPressure.Model.Type = "Spherical";
fprintf("Solar pressure model: %s\n", satellite.ForceModel.SolarPressure.Model.Type);
% currently doesn't work with ODTKRuntime (scenario.Measurements.Files is empty)
demonstrateList = true;
const agi::odtk::AttrProxy satellite = scenario[zerothSatelliteName];
satellite("ForceModel")("SolarPressure")("Model")("Type").Assign("Spherical");
std::cout << "Solar pressure model: " << satellite("ForceModel")("SolarPressure")("Model")("Type").AsString() << "\n";
// currently doesn't work with ODTKRuntime (scenario.Measurements.Files is empty)
const bool demonstrateList = true;
AttrProxy satellite = scenario[zerothSatelliteName];
satellite.get("ForceModel.SolarPressure.Model.Type").assign("Spherical");
System.out.println("Solar pressure model: " + satellite.get("ForceModel.SolarPressure.Model.Type").asString());
// currently doesn't work with ODTKRuntime(scenario.get(“Measurements.Files”) is empty)
boolean demonstrateList = true;
Type LIST
The List container holds an unordered list of simple types like STRINGs or INTs or compound objects. The easiest way to identify which types of objects are in a list is to add an element through the user interface. The columns in the list identify the names of each of the properties of the elements.
Use the NewElem() method to create a new object to add to the list. Add it to the list by using push_back(ne) or push_front(ne). You can clear the entire list using clear(), and you can remove the ith element using RemoveAt(i). Obtain the number of elements in the list by using size for COM and size.eval() or count for Cross-platform API. Access the elements in the list by index number or by iterating through the list.
COM
set mfiles = ODTK.Scenario(0).Measurements.Files
' Clear the list
set unused = mfiles.clear
' Add a new item to it
dim ne
set ne = mfiles.NewElem()
ne.Enabled = true
ne.FileName = "C:\Temp\test.geosc"
set unused = mfiles.push_back(ne)
' Walk through the list using indices
for i = 0 to (mfiles.size - 1)
MsgBox mfiles(i).FileName
next
' Walk through the list using iterators
for each file in mfiles
MsgBox file.FileName
Next
var Shell = new ActiveXObject("WScript.Shell");
var mfiles = ODTK.Scenario(0).Measurements.Files;
// Clear the list
var unused = mfiles.clear;
// Add a new item to itvar ne;
ne = mfiles.NewElem();
ne.Enabled = true;
ne.FileName = "C:\\Temp\\test.geosc";
unused = mfiles.push_back(ne);
// Walk through the list using indices
for (i = 0; i < mfiles.size - 1; i++)
{
Shell.Popup(mfiles(i).FileName);
}
my $mfiles = $ODTK->Scenario(0)->Measurements->Files;
# Clear the list
$mfiles->clear();
# Add a new item to it
my $ne = $mfiles->NewElem();
$ne->{Enabled} = 1;
$ne->{Filename} = "C:\\Temp\\test.geosc";
$mfiles->push_back($ne);
# Walk through the list using indices
my $size = $mfiles->size->{Value};
for ($i=0; $i < $size; $i++)
{
Win32::MsgBox $mfiles->Item($i)->Filename->{Value};
}
# Walk through the list using iterators
foreach $file (in $mfiles)
{
Win32::MsgBox $file->FileName->{Value};
}
mfiles = ODTK.Scenario(0).Measurements.Files
# Clear the list
unused = mfiles.clear
# Add a new item to it
ne = mfiles.NewElem()
ne.Enabled = True
ne.FileName = "C:\\Temp\\test.geosc" # Be sure the file exists in the specified location
unused = mfiles.push_back(ne)
# Walk through the list using indices
for i in range(int(mfiles.size)): # Must cast mfiles.size to an integer
print(mfiles(i).FileName)
# Walk through the list using iterators
for file in mfiles:
print(file.FileName)
mfiles = odtk.invoke('Scenario').invoke('Item', 0).invoke('Measurements').invoke('Files');
% Clear the list
mfiles.invoke('clear');
% Add a new item to it
ne = mfiles.invoke('NewElem');
ne.set('Enabled', true);
ne.set('Filename', 'C:\Temp\test.geosc');
mfiles.invoke('push_back', ne);
% Walk through the list using indices
size = mfiles.invoke('size').invoke('Value');
for i = 0:size-1
fprintf('%s\n', mfiles.invoke('Item', i).invoke('Filename').invoke('Value'));
end
% MATLAB does not support a foreach concept
Cross-Platform API
If demonstrate_list:
measurement_files = scenario.Measurements.Files
print(f'Measurement files count: {measurement_files.count}')
measurement_file = measurement_files[0]
measurement_file_name = measurement_file.FileName.value.eval()
print(f'First measurement file: {measurement_file_name}')
# Clear the list
measurement_files.clear()
print(f'Measurement files count: {measurement_files.count}')
# Add a new item to it
ne = measurement_files.NewElem()
ne.Enabled = True
ne.FileName = measurement_file_name
measurement_files.push_back(ne)
print(f'Measurement files count: {measurement_files.count}')
# Walk through the list using indices
for i in range(measurement_files.size.eval()): # 'count' can also be used instead of 'size'
print(f'Measurement file ({i}): {measurement_files[i].FileName.value.eval()}')
# Walk through the list using iterators
for file in measurement_files:
print(f'Measurement file: {file.FileName.value.eval()}')
if demonstrateList
measurementFiles = scenario.Measurements.Files;
fprintf("Measurement files count: %i\n", measurementFiles.count);
measurementFile = measurementFiles{0};
measurementFileName = measurementFile.FileName.value;
fprintf("First measurement file: %s\n", measurementFileName);
% Clear the list
measurementFiles.clear();
fprintf("Measurement files count: %i\n", measurementFiles.count);
% Add a new item to it
ne = measurementFiles.NewElem();
ne.Enabled = true;
ne.FileName = measurementFileName;
measurementFiles.push_back(ne);
fprintf("Measurement files count: %i\n", measurementFiles.count);
% Walk through the list using indices
for i = 0: measurementFiles.size-1
fprintf("Measurement file (%i): %s\n", i, measurementFiles{i}.FileName.value);
end
end
if (demonstrateList)
{
const agi::odtk::AttrProxy measurementFiles = scenario("Measurements")("Files");
std::cout << "Measurement files count: " << measurementFiles("count").AsInt() << "\n";
const agi::odtk::AttrProxy measurementFile = measurementFiles[0];
const auto measurementFileName = measurementFile("FileName")("value").AsString();
std::cout << "First measurement file: " << measurementFileName << "\n";
// Clear the list
measurementFiles("clear").Invoke();
std::cout << "Measurement files count: " << measurementFiles("count").AsInt() << "\n";
// Add a new item to it
const auto ne = measurementFiles("NewElem").InvokeAttrProxy();
ne("Enabled").Assign(true);
ne("FileName").Assign(measurementFileName);
measurementFiles("push_back").Invoke(ne);
std::cout << "Measurement files count: " << measurementFiles("count").AsInt() << "\n";
// Walk through the list using indices
for (int i = 0; i < measurementFiles("size").AsInt() - 1; ++i)
{
std::cout << "Measurement file " << i << ": " << measurementFiles[i]("FileName")("value").AsString() << "\n";
}
}
if (demonstrateList) {
AttrProxy measurementFilesProxy = scenario.get("Measurements.Files");
System.out.println("Measurement files count: " + measurementFilesProxy.get("count").asInt());
AttrProxy measurementFile = measurementFilesProxy.getItem(0);
String measurementFileName = measurementFile.get("FileName.value").asString();
System.out.println("First measurement file: " + measurementFileName);
// Clear the list
measurementFilesProxy.get("clear").invoke();
System.out.println("Measurement files count: " + measurementFilesProxy.get("count").asInt());
// Add a new item to it
AttrProxy ne = measurementFilesProxy.get("NewElem").invokeAttr();
ne.get("Enabled").assign(true);
ne.get("FileName").assign(measurementFileName);
measurementFilesProxy.get("push_back").invoke(ne);
System.out.println("Measurement files count: " + measurementFilesProxy.get("count").asInt());
// Walk through the list using indices
for (int i = 0; i < measurementFilesProxy.get("count").asInt(); i++) {
// 'count' can also be used instead of 'size'
System.out.println("Measurement file " + i + ": " + measurementFilesProxy.getItem(i).get("FileName.value").asString());
}
IterProxy measurementFilesIter = measurementFilesProxy.asIterProxy();
// Walk through the list using iterators
while (measurementFilesIter.hasNext()) {
System.out.println("Measurement file: " + measurementFilesIter.next().get("FileName.value").asString());
}
}
Type SETLINKTOOBJ
Some ODTK objects have a special container SetLinkToObj that acts like a Set. It can only contain unique items, and the unique items are links to other ODTK objects. A common example of this is a Filter object's SatelliteList. You can choose to add specific satellite objects into the SatelliteList, but you can only add the satellite once. Use the InsertbyName() method to add a new object into the list. Alternatively, you can retrieve the list in your script via the Choices property. You can clear the entire SetLinkToObj using clear() and remove an individual element using erase(). Obtain the number of elements in the SetLinkToObj by using size for COM and size.eval() or count for Cross-platform API. Access the elements in the SetLinkToObj by index number or by iterating through the SetLinkToObj. The methods begin() and end() return iterators that have the following methods: IsSafeToDereference(), Dereference(), Increment(), and Decrement().
There are some unique Multiple Representation attributes that combine enumeration behavior for reading attributes, but use object-like scope for assigning attributes. See these special cases (e.g., Satellite.OrbitState and Facility.Position) in the Scripting Multiple Representations section
COM
set scen = ODTK.Scenario(0)
set fil = scen.Filter(0)
' Clear out the existing SatelliteList
fil.SatelliteList.clear()
' Add a particular satellite called Fred
success = fil.SatelliteList.InsertByName("Fred")
MsgBox success
' Iterate through the list of possible choices we could have used
for each sChoice in fil.SatelliteList.Choices
MsgBox sChoice
next
' Add the 2nd satellite to the list (0 indexed)
fil.SatelliteList.insert(fil.SatelliteList.Choices(1))
' Remove Fred from the list
fil.SatelliteList.erase("Fred")
var Shell = new ActiveXObject("WScript.Shell");
var scen = ODTK.Scenario(0);
var fil = scen.Filter(0);
// Clear out the existing SatelliteList
fil.SatelliteList.clear()
// Add a particular satellite called Fred
var success = fil.SatelliteList.InsertByName("Fred")
Shell.Popup(success)
// Iterate through the list of possible choices we could have used
var i;
for(i = 0; i < fil.SatelliteList.Choices.Count; i++)
{
Shell.Popup(fil.SatelliteList.Choices(i));
}
// Add the 2nd satellite to the list (0 indexed)
fil.SatelliteList.insert(fil.SatelliteList.Choices(1))
// Remove Fred from the list
fil.SatelliteList.erase("Fred")
my $scen = $ODTK->Scenario(0);
my $fil = $scen->Filter(0);
# Clear out the existing SatelliteList
$fil->SatelliteList->clear();
# Add a particular satellite called Fred
my $success = $fil->SatelliteList->InsertByName("Fred");
Win32::MsgBox success;
# Iterate through the list of possible choices we could have used
$coll = $fil->SatelliteList->Choices;
foreach $sChoice (in $coll)
{
Win32::MsgBox "$sChoice";
}
# Add the 2nd satellite to the list (0 indexed)
$fil->SatelliteList->insert($fil->SatelliteList->Choices(1));
# Remove Fred from the list
$fil->SatelliteList->erase("Fred");
scen = ODTK.Scenario(0)
fil = scen.Filter("Filter1")
# Clear out the existing SatelliteList
fil.SatelliteList.clear()
# Add a particular satellite called Fred
success = fil.SatelliteList.InsertByName("Fred")
print(success)
# Iterate through the list of possible choices we could have used
for sChoice in fil.SatelliteList.Choices:
print(sChoice)
# Add the 2nd satellite to the list (0 indexed)
fil.SatelliteList.insert(fil.SatelliteList.Choices(1))
# Remove Fred from the list
fil.SatelliteList.erase("Fred")
fil = scen.invoke('Filter').invoke('Item', 0);
% Clear out the existing SatelliteList
fil.invoke('SatelliteList').invoke('clear');
% Add a particular satellite called Fred
success = fil.invoke('SatelliteList').invoke('InsertByName','Fred');
disp(success.invoke('Value'))
% Iterate through the list of possible choices we could have used
coll = fil.invoke('SatelliteList').invoke('Choices');
size = coll.invoke('Size').invoke('Value');
for i = 0:size - 1
choice = coll.invoke('Item', i);
disp(choice.invoke('Value'));
end
% Add the 2nd satellite to the list (0 indexed)
fil.invoke('SatelliteList').invoke('insert', fil.invoke('SatelliteList').invoke('Choices').invoke('Item', 1));
% Remove Fred from the list
fil.invoke('SatelliteList').invoke('erase', 'Fred');
Cross-Platform API
# Clear out the existing SatelliteList
filter1.SatelliteList.clear()
# Add a particular satellite called mySat
success = filter1.SatelliteList.InsertByName("mySat")
print(success)
# Iterate through the list of possible choices we could have used
for choice in filter1.SatelliteList.Choices:
print(choice.eval())
# Add the 2nd satellite to the list (0 indexed)
filter1.SatelliteList.insert(filter1.SatelliteList.Choices[1])
# Remove mySat from the list
filter1.SatelliteList.erase("mySat")
% Clear out the existing SatelliteList
filter1.SatelliteList.clear();
% Add a particular satellite called Fred
success = filter1.SatelliteList.InsertByName("mySat");
fprintf("%s\n", string(success));
% Iterate through the list of possible choices we could have used
satelliteChoices = filter1.SatelliteList.Choices;
for i = 0: satelliteChoices.Count-1
fprintf(" %i. %s\n", i, satelliteChoices{i});
end
% Add the 2nd satellite to the list (0 indexed)
filter1.SatelliteList.insert(filter1.SatelliteList.Choices{1});
% Remove Fred from the list
filter1.SatelliteList.erase("mySat");
// Clear out the existing SatelliteList
filter1("SatelliteList")("Clear").Invoke();
// Add a particular satellite called mySat
bool success = filter1("SatelliteList")("InsertByName").InvokeBool("mySat");
std::cout << success << "\n";
// Iterate through the list of possible choices we could have used
const agi::odtk::AttrProxy satelliteChoices = filter1("SatelliteList")("Choices");
for (int i = 0; i < satelliteChoices("Count").AsInt(); ++i)
{
std::cout << " " << i << ". " << satelliteChoices[i].AsString() << "\n";
}
// Add the 2nd satellite to the list(0 indexed)
filter1("SatelliteList")("Insert").Invoke(filter1("SatelliteList")("Choices")[1].AsString());
// Remove mySat from the list
filter1("SatelliteList")("Erase").Invoke("mySat");
Type SET
The Set container is similar to a list but is ordered by an internal constraint and will reject duplicates. The following functions are supported:
| Function | Description |
|---|---|
| NewElem() | Creates a new element to add to the set. |
| insert(element) | Adds a newly created element to the set. |
| clear() |
Clears the entire set. |
| erase(element) | Removes an individual element from the set. |
| size | Obtains the number of elements in the set for COM. |
| size.eval() or count |
Obtains the number of elements in the set for Cross-Platform API. |
| begin() |
Returns an iterator pointing to the first item of the set. The iterator has the following methods: IsSafeToDereference(), Dereference(), Increment(), and Decrement(). |
| end() |
Returns an iterator pointing to the end of the set (past the last item). The iterator has the following methods: IsSafeToDereference(), Dereference(), Increment(), and Decrement(). |
Access the elements in the set by index number or by iterating through the set. Some sets have additional methods that are useful:
| Function | Description |
|---|---|
| InsertByName(string) |
Returns a boolean indicating whether the element was successfully added. |
| FindByName(string) |
Returns an iterator pointing to the specified item in the set. The iterator has the following methods: IsSafeToDereference(), Dereference(), Increment(), and Decrement(). |
| RemoveByName(string) |
Returns a boolean indicating whether the element was successfully removed. |
COM
set scen = ODTK.Scenario(0)
set f = scen.TrackingSystem("TrkSys1").Facility("BOSS-A")
' Clear out the set
set mstats = f.MeasurementStatistics
mstats.clear()
' Add a range measurement model
success = mstats.InsertByName("Range")
set msIter = mstats.FindByName("Range")
if msIter.IsSafeToDereference() then
set m = msIter.Dereference()
set unused = m.Type.BiasSigma.Set(10, "m")
set unused = m.Type.BiasHalfLife.Set(6, "hr")
set unused = m.Type.WhiteNoiseSigma.Set(4, "m")
end if
' Add an azimuth measurement model
success = mstats.InsertByName("Azimuth")
set msIter = mstats.FindByName("Azimuth")
if msIter.IsSafeToDereference() then
set m = msIter.Dereference()
set unused = m.Type.BiasSigma.Set(0.1, "deg")
set unused = m.Type.BiasHalfLife.Set(6, "hr")
set unused = m.Type.WhiteNoiseSigma.Set(0.05, "deg")
end if
' Now remove the range model
success = mstats.RemoveByName("Range")
MsgBox "Range removed: " & success
var Shell = new ActiveXObject("WScript.Shell");
var scen = ODTK.Scenario(0);
var f = scen.TrackingSystem("TrkSys1").Facility("BOSS-A");
// Clear out the set
var mstats = f.MeasurementStatistics;
mstats.clear();
// Add a range measurement model
var success = mstats.InsertByName("Range");
var msIter = mstats.FindByName("Range");
if (msIter.IsSafeToDereference())
{
var m = msIter.Dereference();
var unused = m.Type.BiasSigma.Set(10, "m");
unused = m.Type.BiasHalfLife.Set(6, "hr");
unused = m.Type.WhiteNoiseSigma.Set(4, "m");
}
// Add an azimuth measurement model
success = mstats.InsertByName("Azimuth");
msIter = mstats.FindByName("Azimuth");
if (msIter.IsSafeToDereference())
{
m = msIter.Dereference();
unused = m.Type.BiasSigma.Set(0.1, "deg");
unused = m.Type.BiasHalfLife.Set(6, "hr");
unused = m.Type.WhiteNoiseSigma.Set(0.05, "deg");
}
// Now remove the range model
success = mstats.RemoveByName("Range");
Shell.Popup("Range removed: " + success);
my $scen = $ODTK->Scenario(0);
my $f = $scen->TrackingSystem("TrkSys1")->Facility("BOSS-A");
# Clear out the set
my $mstats = $f->MeasurementStatistics;
$mstats->clear();
# Add a range measurement model
my $success = $mstats->InsertByName("Range")->{Value};
my $msIter = $mstats->FindByName("Range");
if ($msIter->IsSafeToDereference()->{Value})
{
my $m = $msIter->Dereference();
$m->Type->BiasSigma->Set(10, "m");
$m->Type->BiasHalfLife->Set(6, "hr");
$m->Type->WhiteNoiseSigma->Set(4, "m");
}
# Add an azimuth measurement model
$success = $mstats->InsertByName("Azimuth");
$msIter = $mstats->FindByName("Azimuth");
if ($msIter->IsSafeToDereference()->{Value})
{
my $m = $msIter->Dereference();
$m->Type->BiasSigma->Set(0.1, "deg");
$m->Type->BiasHalfLife->Set(6, "hr");
$m->Type->WhiteNoiseSigma->Set(0.05, "deg");
}
# Now remove the range model
$success = $mstats->RemoveByName("Range");
Win32::MsgBox "Range removed: " . $success->{Value};
scen = ODTK.Scenario(0)
f = scen.TrackingSystem("TrkSys1").Facility("BOSS-A")
# Clear out the set
mstats = f.MeasurementStatistics
mstats.clear()
# Add a range measurement model
success = mstats.InsertByName("Range").value
msIter = mstats.FindByName("Range")
if msIter.IsSafeToDereference().value:
ms = msIter.Dereference()
ms.Type.BiasSigma.Set(10, "m")
ms.Type.BiasHalfLife.Set(6, "hr")
ms.Type.WhiteNoiseSigma.Set(4, "m")
# Add an azimuth measurement model
success = mstats.InsertByName("Azimuth").value
msIter = mstats.FindByName("Azimuth")
if msIter.IsSafeToDereference().value:
ms = msIter.Dereference()
ms.Type.BiasSigma.Set(0.1, "deg")
ms.Type.BiasHalfLife.Set(6, "hr")
ms.Type.WhiteNoiseSigma.Set(0.05, "deg")
# Now remove the range model
success = mstats.RemoveByName("Range").value
print(f"Range removed: {success}")
scen = odtk.invoke('Scenario').invoke('Item', 0);
f = scen.invoke('TrackingSystem').invoke('TrkSys1').invoke('Facility').invoke('BOSS-A');
% Clear out the set
mstats = f.invoke('MeasurementStatistics');
mstats.invoke('clear');
% Add a range measurement model
success = mstats.invoke('InsertByName', 'Range').invoke('Value');
msIter = mstats.invoke('FindByName', 'Range');
if (msIter.invoke('IsSafeToDereference').invoke('Value'))
m = msIter.invoke('Dereference');
m.invoke('Type').invoke('BiasSigma').invoke('Set', 10, 'm');
m.invoke('Type').invoke('BiasHalfLife').invoke('Set', 6, 'hr');
m.invoke('Type').invoke('WhiteNoiseSigma').invoke('Set', 4, 'm');
end
% Add an azimuth measurement model
success = mstats.invoke('InsertByName', 'Azimuth');
msIter = mstats.invoke('FindByName', 'Azimuth');
if (msIter.invoke('IsSafeToDereference').invoke('Value'))
m = msIter.invoke('Dereference');
m.invoke('Type').invoke('BiasSigma').invoke('Set', 0.1, 'deg');
m.invoke('Type').invoke('BiasHalfLife').invoke('Set', 6, 'hr');
m.invoke('Type').invoke('WhiteNoiseSigma').invoke('Set', 0.05, 'deg');
end
% Now remove the range model
success = mstats.invoke('RemoveByName', 'Range');
fprintf('Range removed: %d\n', success.invoke('Value'));
Cross-Platform API
# Clear out the set
measurement_statistics = facility.MeasurementStatistics
measurement_statistics.clear()
# Add a range measurement model
success = measurement_statistics.InsertByName('Range')
print(f'Range measurement model added: {success}')
ms = measurement_statistics[measurement_statistics.count - 1]
ms.Type.BiasSigma.Set(10, 'm')
ms.Type.BiasHalfLife.Set(6, 'hr')
ms.Type.WhiteNoiseSigma.Set(4, 'm')
# Add an azimuth measurement model
success = measurement_statistics.InsertByName('Azimuth')
print(f'Azimuth measurement model added: {success}')
ms = measurement_statistics[measurement_statistics.count - 1]
ms.Type.BiasSigma.Set(0.1, 'deg')
ms.Type.BiasHalfLife.Set(6, 'hr')
ms.Type.WhiteNoiseSigma.Set(0.05, 'deg')
# Now remove the range model
success = measurement_statistics.RemoveByName('Range')
print(f'Range model removed: {success}')
% Clear out the set
measurementStatistics = facility.MeasurementStatistics;
measurementStatistics.clear();
% Add a range measurement model
success = measurementStatistics.InsertByName("Range");
fprintf("Range measurement model added: %s\n", string(success));
ms = measurementStatistics{measurementStatistics.count - 1};
ms.Type.BiasSigma.Set(10, "m");
ms.Type.BiasHalfLife.Set(6, "hr");
ms.Type.WhiteNoiseSigma.Set(4, "m");
% Add an azimuth measurement model
success = measurementStatistics.InsertByName("Azimuth");
fprintf("Azimuth measurement model added: %s\n", string(success));
ms = measurementStatistics{measurementStatistics.count - 1};
ms.Type.BiasSigma.Set(0.1, "deg");
ms.Type.BiasHalfLife.Set(6, "hr");
ms.Type.WhiteNoiseSigma.Set(0.05, "deg");
% Now remove the range model
success = measurementStatistics.RemoveByName("Range");
fprintf("Range model removed: %s\n", string(success));
// Clear out the set
const agi::odtk::AttrProxy measurementStatistics = facility("MeasurementStatistics");
measurementStatistics("clear").Invoke();
// Add a range measurement model
bool success = measurementStatistics("InsertByName").InvokeBool("Range");
std::cout << "Range measurement model added: " << BoolToString(success) << "\n";
const agi::odtk::AttrProxy ms = measurementStatistics[measurementStatistics("count").AsInt() - 1];
ms("Type")("BiasSigma")("Set").Invoke(10, "m");
ms("Type")("BiasHalfLife")("Set").Invoke(6, "hr");
ms("Type")("WhiteNoiseSigma")("Set").Invoke(4, "m");
// Add an azimuth measurement model
success = measurementStatistics("InsertByName").InvokeBool("Azimuth");
std::cout << "Azimuth measurement model added: " << BoolToString(success) << "\n";
const auto ms2 = measurementStatistics[measurementStatistics("count").AsInt() - 1];
ms2("Type")("BiasSigma")("Set").Invoke(0.1, "deg");
ms2("Type")("BiasHalfLife")("Set").Invoke(6, "hr");
ms2("Type")("WhiteNoiseSigma")("Set").Invoke(0.05, "deg");
// Now remove the range model
success = measurementStatistics("RemoveByName").InvokeBool("Range");
std::cout << "Range model removed: " << BoolToString(success) << "\n";
// Clear out the set
AttrProxy measurementStatistics = facility.get("MeasurementStatistics");
measurementStatistics.get("clear").invoke();
// Add a range measurement model
success = measurementStatistics.get("InsertByName").invokeBool("Range");
System.out.println("Range measurement model added: " + success);
AttrProxy ms = measurementStatistics.getItem(measurementStatistics.get("count").asInt() - 1);
ms.get("Type.Biassigma.Set").invoke(10, "m");
ms.get("Type.BiasHalfLife.Set").invoke(6, "hr");
ms.get("Type.WhiteNoiseSigma.Set").invoke(4, "m");
// Add an azimuth measurement model
success = measurementStatistics.get("InsertByName").invokeBool("Azimuth");
System.out.println("Azimuth measurement model added: " + success);
ms = measurementStatistics.getItem(measurementStatistics.get("count").asInt() - 1);
ms.get("Type.Biassigma.Set").invoke(0.1, "deg");
ms.get("Type.BiasHalfLife.Set").invoke(6, "hr");
ms.get("Type.WhiteNoiseSigma.Set").invoke(0.05, "deg");
// Now remove the range model
success = measurementStatistics.get("RemoveByName").invokeBool("Range");
System.out.println("Range model removed: " + success);
In addition to the unlimited sets, there are predefined sets (SET ENUMERATION) and sets of the objects (SET LINKTOOBJ). For some sets, insert() and erase() accept either an object name or the handle. However, you have to check that each works for a particular set.