Same results after sweeping globalSeed parameter - modelica

I rewrited an example found in the Forum (which by the way works fine) in order to suit my case - swepping globaSeed parameter.
I expected that each simulation run will give a different result, but it wasn't so.
C:\Users\USUARIO\Documents\MyOModelica\MyModels\OMScripting\parsweep1>"C:\Program Files\OpenModelica1.19.2-64bit\bin\omc" parsweep1.mos
true
""
{"C:/Users/USUARIO/Documents/MyOModelica/MyModels/OMScripting/parsweep1/brisi","brisi_init.xml"}
"Notification: Automatically loaded package Modelica 3.2.3 due to uses annotation.
Notification: Automatically loaded package Complex 3.2.3 due to uses annotation.
Notification: Automatically loaded package ModelicaServices 3.2.3 due to uses annotation.
Notification: Automatically loaded package PNlib 2.2 due to usage.
Warning: The initial conditions are not fully specified. For more information set -d=initialization. In OMEdit Tools->Options->Simulation->Show additional information from the initialization process, in OMNotebook call setCommandLineOptions(\"-d=initialization\").
"
"time,p1,
"
brisi.exe -override globalSeed=1
brisi.exe -override globalSeed=2
brisi.exe -override globalSeed=3
brisi.exe -override globalSeed=4
time,p1,
1,46,
2,46,
3,46,
4,46,
""
true
true`
When I simulate model using OMedit, I've got different results as it should be.
Below is the script I used for this experiment. Model is a simple one, made from the two components from PNLib library:
loadString("
class brisi
PNlib.Components.PD p1(nOut = 1, startTokens = 50) annotation(
Placement(visible = true, transformation(origin = {-54, 42}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
PNlib.Components.TDS t1(localSeed = 1, nIn = 1) annotation(
Placement(visible = true, transformation(origin = {6, 42}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
inner PNlib.Components.Settings settings(globalSeed = 30020) annotation(
Placement(visible = true, transformation(origin = {66, 76}, extent = {{-10, -10}, {10, 10}}, rotation = 0)));
equation
connect(p1.outTransition[1], t1.inPlaces[1]) annotation(
Line(points = {{-44, 42}, {1, 42}}, thickness = 0.5));
end brisi;
"); getErrorString();
buildModel(brisi, stopTime=6); getErrorString();
results := "time,p1,\n";
for globalSeed in {1, 2, 3, 4} loop
str_a := String(globalSeed); getErrorString();
str_cmd := "brisi.exe -override globalSeed=" + str_a;
print(str_cmd + "\n"); getErrorString();
system(str_cmd, "output.txt"); getErrorString();
res := readSimulationResult("brisi_res.mat", p1.t); getErrorString();
results := results + str_a + "," + String(res[size(res, 1), size(res, 2)]) + ",\n";
closeSimulationResultFile();
end for;
print(results); getErrorString();
//oms_getInteger("globalSeed");getErrorString();
writeFile("results.csv", results);
plot(p1, true, "results.csv");
Apreciate if someone could help me with this.

From the model it is seen thatglobalSeed is not a top-level parameter but inside settings class, so please change to settings.globalSeedin the code as below inside the for loop:
str_cmd := "brisi.exe -override settings.globalSeed=" + str_a;
The notifications logs is shown in below image:
Plot command output:
Hope this works!

Related

Transfering algorithms AsymptoticOutputTracking to Matlab-Simulink

https://mathematica.stackexchange.com/questions/241776/transfering-algorithms-asymptoticoutputtracking-to-matlab-simulink
The following system is built and modeled in simulink.
I am interested in the transient process in the variable $x$.
This system is described by the following differential equations:
\begin{cases} \frac{dx}{dt}=-H(t) \ \frac{dH}{dt}+h H(t)=\frac{df}{dt} \end{cases}
where $f=e^{-(x(t)-x_e)^2}$,$x_e$=0,$h$=1
If we numerically solve this system in Mathematica, then we get:
Clear["Derivative"]
ClearAll["Global`*"]
pars = {xs = -1, xe = 0, h = 1}
f = Exp[-(x[t] - xe)^2]
sys = NDSolve[{x'[t] == -H[t], H'[t] + h H[t] == D[f, t], x[0] == xs,
H[0] == Exp[-(xs - xe)^2]}, {x, H}, {t, 0, 10}]
Plot[{Evaluate[x[t] /. sys]}, {t, 0, 10}, PlotRange -> Full,
PlotPoints -> 100]
We can see that the results from Simulink and Mathematica are the same.
Next, I want to do the following. Using the AsymptoticOutputTracker command, control the variable $x$ according to the specified reference law, i.e. the system of equations will take the form:
\begin{cases} \frac{dx}{dt}=-H(t)+u(t) \ \frac{dH}{dt}+h H(t)=\frac{df}{dt} \end{cases}
As a reference signal I use $r_1=e^{-t}+1$ with decay rate $p_1=-5$. As a controlled output, I use the variable $x$, and with $f$ I just see what happens in the end. There is my code:
(***)
Clear["Derivative"]
ClearAll["Global`*"]
f = Exp[-(x[t] - xe)^2]
asys = AffineStateSpaceModel[{x'[t] == -H[t] + u[t],
H'[t] + h H[t] == D[f, t]}, {{x[t], xs}, {H[t],
Exp[-(xs - xe)^2]}}, {u[t]}, {x[t], f}, t] // Simplify
pars1 = {Subscript[r, 1] -> Exp[-t] + 1, Subscript[p, 1] -> -5}
fb = AsymptoticOutputTracker[
asys, {Subscript[r, 1]}, {Subscript[p, 1]}] // Simplify
pars = {xs = -1, xe = 0, h = 1}
csys = SystemsModelStateFeedbackConnect[asys, fb] /. pars1 //
Simplify // Chop
plots = {OutputResponse[{csys}, {0, 0}, {t, 0, 10}]}
Plot[{plots[[1, 1]], Exp[-t] + 1}, {t, 0, 10}, PlotRange -> All,
PlotPoints -> 200]
Plot[{plots[[1, 2]]}, {t, 0, 10}, PlotRange -> All, PlotPoints -> 200]
In general, everything works, but now QUESTION:
And how to transfer the feedback signal generated by the AsymptoticOutputTracker command to simulink and in general simulate all this in simulink?
I would be grateful for the help and advice of respected experts.

Strange problem with the fluid library in openmodelica

I wrote a simple code to experiment the use of the PrescribedPump machine in the Fluid package of the standard library. I'm using OpenModelica 1.13.2.
I would like to pump some water from a tank to another one, by using a prescribedPump driven with a constant value of 10000.
Here the code:
model PompaPilotata
package Medium = Modelica.Media.Water.ConstantPropertyLiquidWater;
inner Modelica.Fluid.System system ;
Modelica.Fluid.Vessels.OpenTank bacinella1(redeclare package Medium = Medium,
T_ambient = system.T_ambient, T_start = system.T_ambient, crossArea = 4, energyDynamics = Modelica.Fluid.Types.Dynamics.FixedInitial,
height = 10, level_start = 2, massDynamics = Modelica.Fluid.Types.Dynamics.FixedInitial, nPorts = 1, p_ambient = system.p_ambient,
use_HeatTransfer = false, use_T_start = true, use_portsData = false) ;
Modelica.Fluid.Vessels.OpenTank bacinella2(redeclare package Medium = Medium,
T_ambient = system.T_ambient, T_start = system.T_ambient, crossArea = 4, energyDynamics = Modelica.Fluid.Types.Dynamics.FixedInitial,
height = 10, level_start = 2, massDynamics = Modelica.Fluid.Types.Dynamics.FixedInitial, nPorts = 1, p_ambient = system.p_ambient,
use_HeatTransfer = false, use_T_start = true, use_portsData = false) ;
Modelica.Fluid.Machines.PrescribedPump Pompa(redeclare package Medium = Medium,
medium(h(stateSelect = StateSelect.default), p(stateSelect = StateSelect.default)),N_nominal = 100, V = 0.1, allowFlowReversal = false,
checkValve = true, energyDynamics = Modelica.Fluid.Types.Dynamics.DynamicFreeInitial, m_flow_start = 0.0000001,
massDynamics = Modelica.Fluid.Types.Dynamics.DynamicFreeInitial, nParallel = 1, use_HeatTransfer = false, use_N_in = true) ;
Modelica.Blocks.Sources.Constant Costante(k = 10000);
Modelica.Fluid.Pipes.StaticPipe tubo1(redeclare package Medium = Medium,allowFlowReversal = true,
diameter = 0.1, height_ab = 0, isCircular = true, length = 5, nParallel = 1) ;
Modelica.Fluid.Pipes.StaticPipe tubo2(redeclare package Medium = Medium,allowFlowReversal = true,
diameter = 0.1, height_ab = 0, isCircular = true, length = 5, nParallel = 1);
equation
connect(tubo2.port_b, bacinella2.ports[1]);
connect(Pompa.port_b, tubo2.port_a);
connect(tubo1.port_b, Pompa.port_a);
connect(bacinella1.ports[1], tubo1.port_a);
connect(Costante.y, Pompa.N_in);
end PompaPilotata;
I get this error message from the compiler:
In file included from C:/OpenModelica1.13.264bit/include/omc/c/util/modelica_string.h:38:0,
from C:/OpenModelica1.13.264bit/include/omc/c/openmodelica_func.h:52,
from PompaPilotata_model.h:6,
from PompaPilotata_06inz.c:2:
PompaPilotata_06inz.c: In function 'PompaPilotata_eqFunction_237':
C:/OpenModelica1.13.264bit/include/omc/c/meta/meta_modelica_data.h:231:21: error: incompatible type for argument 2 of 'omc_Modelica_Fluid_Machines_PrescribedPump$Pompa_flowCharacteristic'
#define mmc_mk_real mmc_mk_rcon
^
C:/OpenModelica1.13.264bit/include/omc/c/meta/meta_modelica_data.h:225:45: note: in definition of macro 'mmc_unbox_real'
#define mmc_unbox_real(X) mmc_prim_get_real(X)
^
PompaPilotata_06inz.c:3005:139: note: in expansion of macro 'mmc_mk_real'
data->simulationInfo->realParameter[7] = mmc_unbox_real(omc_Modelica_Fluid_Machines_PrescribedPump$Pompa_flowCharacteristic(threadData, mmc_mk_real(data->simulationInfo->realParameter[5])));
^
In file included from PompaPilotata_model.h:23:0,
from PompaPilotata_06inz.c:2:
PompaPilotata_functions.h:223:15: note: expected 'modelica_real {aka double}' but argument is of type 'void *'
modelica_real omc_Modelica_Fluid_Machines_PrescribedPump$Pompa_flowCharacteristic(threadData_t threadData, modelica_real _V_flow);
^
: recipe for target 'PompaPilotata_06inz.o' failed
\tools\msys\mingw64\bin\mingw32-make: [PompaPilotata_06inz.o] Error 1
\tools\msys\mingw64\bin\mingw32-make: * Waiting for unfinished jobs....
Compilation process failed. Exited with code 2.
Someone can explain me what does it mean and how to fix it?
Thanks
The model does not work in Dymola eiter, but it gives the following hint:
Function Pompa.flowCharacteristic_Unique7 is neither external nor has an algorithm. It should have been redeclared.
Therefore redeclaring the function for the flowCharacteristic should help. Copying this part from Modelica.Fluid.Examples.PumpingSystem and reducing the values for V_flow_nominal by a factor of 1000 (which is a wild guess) gives:
Modelica.Fluid.Machines.PrescribedPump Pompa(redeclare package Medium = Medium,
redeclare function flowCharacteristic = Modelica.Fluid.Machines.BaseClasses.PumpCharacteristics.quadraticFlow (V_flow_nominal={0.001,0.0025,0.005}, head_nominal={100,60,0}),
medium(h(stateSelect = StateSelect.default), p(stateSelect = StateSelect.default)),N_nominal = 100, V = 0.1, allowFlowReversal = false,
checkValve = true, energyDynamics = Modelica.Fluid.Types.Dynamics.DynamicFreeInitial, m_flow_start = 0.0000001,
massDynamics = Modelica.Fluid.Types.Dynamics.DynamicFreeInitial, nParallel = 1, use_HeatTransfer = false, use_N_in = true);
With the second line actually being added.

Scale and Rotation Issue with Model Import 3DS Max to Unity

I have just designed simple 3d model in 3ds Max and try to import within Unity. But notice one thing that is irrelevant for me, I was getting -90 rotation in X degree and scale of model is also not proper.
I don't know what is the reason behind this though I am beginner with 3ds max software.
As per above image, I hope you understand my point so what kind of settings, I require to do in 3ds max software so that it get imported with 0 rotation in X degree and with (1,1,1) scale.
Give me some suggestions into this.
I have used this plugin for Blender and it works great for me:
Unity Rotation Fix for Blender
If you can't find a plugin for 3DS Max you can try to write similar plugin yourself or export your model to Blender and then use the plugin.
Here is the original Python code in case the link gets deprecated:
import bpy
bl_info = {
"name": "Unity Tools",
"author": "Karol \"Mirgar\" Głażewski",
"version": (1, 0, 2),
"blender": (2, 6, 5),
"location": "3D View > Tool Shelf > Unity Tools",
"description": "Tools to ease workflow with Unity Engine",
"warning": "",
"wiki_url": "",
"tracker_url": "",
"category": "Object"}
# fixes rotation on X axis, +X is -X in Unity compared to Blender
class UnityRotationFixerX(bpy.types.Operator):
bl_description = "Fixes rotation of object so it will not \"lay on its face\" in Unity, +X axis is -X compared to Unity"
bl_label = "Simple rotation fix"
bl_idname = "object.unity_rotation_fix_x"
bl_options = {'REGISTER', 'UNDO'}
def FixRotationForUnity3D(self):
bpy.ops.object.transform_apply(rotation = True)
bpy.ops.transform.rotate(value = -1.5708, axis = (1, 0, 0), constraint_axis = (True, False, False), constraint_orientation = 'GLOBAL')
bpy.ops.object.transform_apply(rotation = True)
bpy.ops.transform.rotate(value = 1.5708, axis = (1, 0, 0), constraint_axis = (True, False, False), constraint_orientation = 'GLOBAL')
#classmethod
def poll(cls, context):
return context.mode == 'OBJECT' and context.area.type == 'VIEW_3D'
def execute(self, context):
self.FixRotationForUnity3D()
return {'FINISHED'}
# fixes rotation on X and Z axis, front is now +Y
class UnityRotationFixerXZ(bpy.types.Operator):
bl_description = "Fixes rotation of object, +Y is now front"
bl_label = "Full rotation fix"
bl_idname = "object.unity_rotation_fix_xz"
bl_options = {'REGISTER', 'UNDO'}
def FixRotationForUnity3D(self):
bpy.ops.object.transform_apply(rotation = True)
bpy.ops.transform.rotate(value = -1.5708, axis = (1, 0, 0), constraint_axis = (True, False, False), constraint_orientation = 'GLOBAL')
bpy.ops.transform.rotate(value = -3.1416, axis = (0, 1, 0), constraint_axis = (False, True, False), constraint_orientation = 'GLOBAL')
bpy.ops.object.transform_apply(rotation = True)
bpy.ops.transform.rotate(value = 1.5708, axis = (1, 0, 0), constraint_axis = (True, False, False), constraint_orientation = 'GLOBAL')
bpy.ops.transform.rotate(value = 3.1416, axis = (0, 0, 1), constraint_axis = (False, False, True), constraint_orientation = 'GLOBAL')
#classmethod
def poll(cls, context):
return context.mode == 'OBJECT' and context.area.type == 'VIEW_3D'
def execute(self, context):
self.FixRotationForUnity3D()
return {'FINISHED'}
class UnityPanel(bpy.types.Panel):
bl_idname = "OBJECT_PT_unity_tools"
bl_label = "Unity Tools"
bl_space_type = 'VIEW_3D'
bl_region_type = 'TOOLS'
bl_context = "objectmode"
bl_options = {'DEFAULT_CLOSED'}
def draw(self, context):
layout = self.layout
col = layout.column(align=True)
col.label(text="Rotation:")
col.operator("object.unity_rotation_fix_x")
col.operator("object.unity_rotation_fix_xz")
#registers
def register():
bpy.utils.register_class(UnityRotationFixerX)
bpy.utils.register_class(UnityRotationFixerXZ)
bpy.utils.register_class(UnityPanel)
def unregister():
bpy.utils.unregister_class(UnityRotationFixerX)
bpy.utils.unregister_class(UnityRotationFixerXZ)
bpy.utils.unregister_class(UnityPanel)
if __name__ == "__main__":
register()
And the installation guide:
To install this addon unpack it to your Blender addon folder, e.g.
"C:\Program Files\Blender Foundation\Blender\2.67\scripts\addons" or
use install from file button in user preferences under addons tab.
After installing, addon is in Object category and after enabling it,
can be accessed from Tool Shelf under "Unity Tools" panel.
Note that complete rotation fix on X and Z axis will swap object so it
will face +Y axis instead -Y, if you export through fbx remember to
set Forward Z and Up Y as export axis when you use full rotation fix.
Unity have different axis that 3D Max (and Blender etc.) and to fix that Unity is rotating models by default. Just Unity thing. If it's bordering you, you can always set your model as a child of an empty object.
load the ball in 3d max, rotate it -90 degrees on the x axis, reset transform and re-export. as for the scale,
https://docs.unity3d.com/Manual/FBXImporter-Model.html
select the model in the inspector and check out its properties, specifically the import props.... do a little math and adjust the import scale.

Multiple Factor Analysis (MFA) with R using FactoMineR

I have encountered a problem with the MFA in FactoMineR. I am working with a data set containing physical, chemical and microbiological continuous variables measured in tomato plants, taken from 2 different treatments and at 3 time points. I have accommodated my data like this:
structure(list(row.names = structure(c(1L, 4L, 7L, 10L, 13L,
16L), .Label = c("GBA1", "GBA2", "GBA3", "GBB1", "GBB2", "GBB3",
"GBC1", "GBC2", "GBC3", "GBD1", "GBD2", "GBD3", "GBE1", "GBE2",
"GBE3", "RWA1", "RWA2", "RWA3", "RWB1", "RWB2", "RWB3", "RWC1",
"RWC2", "RWC3", "RWD1", "RWD2", "RWD3", "RWE1", "RWE2", "RWE3",
"RWF1", "RWF2", "RWF3", "RWG1", "RWG2", "RWG3", "RWH1", "RWH2",
"RWH3", "RWI1", "RWI2", "RWI3", "RWJ1", "RWJ2", "RWJ3"), class = "factor"),
Trt = structure(c(2L, 2L, 2L, 2L, 2L, 1L), .Label = c("Mineral",
"Organic"), class = "factor"), Status = structure(c(1L, 1L,
1L, 1L, 1L, 1L), .Label = c("H", "S"), class = "factor"),
Humidity = c(87.21704394, 80.29885961, 65.68047337, 85.9775641,
83.33333333, 85.98568282), pH = c(5.44, 5.94, 6.64, 6.19,
6.13, 5.45), Conductivity = c(837L, 867L, 752L, 871L, 699L,
406L), Nit.N = c(436.18, 433.92, 418.1, 458.78, 411.32, 167.24
), Ammonia.N = c(3.8122, 2.6452, 1.945, 1.7116, 2.4896, 7.16
), P = c(30.95, 15.2, 20.15, 16.1, 18.35, 48.2), K = c(135,
35, 95, 40, 145, 275), Ca = c(1287.5, 1427.5, 1610, 1570,
1640, 130), Mg = c(367.5, 575, 537.5, 532.5, 590, 42.5),
S = c(705L, 924L, 603L, 962L, 626L, 111L), Sodium = c(92.5,
170, 135, 127.5, 137.5, 35), Chlorides = c(15.1, 11.1, 15.4,
13.2, 13.8, 10.8), Fe = c(1.5, 2.2, 1.7, 2, 2.1, 3.1), Mn = c(1.1,
0.55, 0.7, 0.4, 0.65, 1.9), Rhizobium = c(0, 0, 0, 0, 0,
0), Total.bacteria = c(7207207.207, 5454545.455, 22727272.73,
18918918.92, 30630630.63, 64864864.86)), .Names = c("row.names",
"Trt", "Status", "Humidity", "pH", "Conductivity", "Nit.N", "Ammonia.N",
"P", "K", "Ca", "Mg", "S", "Sodium", "Chlorides", "Fe", "Mn",
"Rhizobium", "Total.bacteria"), row.names = c(NA, 6L), class = "data.frame")
I divided the variables in categorical (first 2), then the other 16 are continuous. However, I want to treat the 2 categorical variables separately. So I wrote the following code:
>res <- MFA(Oliver, group=c(1,1,3,11,2), type=c("n", "n","s", "s","s"),ncp=5,name.group=c("Sub","Stat", "Phys", "Chem", "Microbial"))
However, it doesn't seem to work. Hence, I tried the following:
>res=MFA(Oliver,group=c(2,16),type=c(rep("n",1),rep("s",1)),ncp=5,name.group=c("cat","cont"))
and this other:
>res=MFA(Oliver,group=c(2, 3, 11,2),type=c(rep("n",1),rep("s",3)), ncp=5,name.group=c("type","Phys", "Chem", "Microbial"))
But I kept having the same problem ("not convenient group definition"). Is there anything that I can do to keep the first 2 categorical groups separately? I would really appreciate your advice on how to properly run the model!
Best wishes,
Emma
I think that the problem comes from your variable Status which is not a variable since all the values are equal to "H". So no analysis cn be done with this "variable".
You can suppress it, there is no information in this column. And then, it should work.
Francois

Import data from txt to Mathematica

Consider the following list in mathematica:
a = {
{
{0, 0, 0}, {1, 0, 0}, {1, 1, 0}
},
{
{0, 0, 1}, {1, 0, 1}, {1, 1, 1}
}
};
Now, invoke:
Export["test.dat", a]
and then
b = Import["test.dat"]
You will see that at the end a doesn't equal b. Should I consider this as a feature or a bug?
Furthermore, I would like to import a list having the following format: {P1,P2,P3...,Pn} where Pi={v1,v2,v3,...,vm} and each vi={x,y,z} where x,y,z are numbers representing the coordinates of the vertex vi. This should be a list of polygons.
How should I set my .dat file so I can read it with Mathematica, and how should I read it? I tried to imitate the output of Export["test.dat",a] above, but then I discovered the other issue. I found this question, but couldn't make the answer work for me...
Any ideas? Thanks in advance!
You should specify the exact format that you need to import/export in, otherwise Mathematica might not be able to guess the correct format.
So your question boils down to what textual format is suitable for storing 3D arrays?
If you work with Mathematica, probably the easiest thing to do is exporting the expression using Mathematica's expression syntax, i.e. Export["data.m", a, "Package"]. This format is relatively easy to write from other languages (but it's not as easy to parse). Your other option would be to make up some new easy to parse textual format for your 3D data, and write your own input/output functions for it in both Mathematica and the other languages you need to work with.
Since the format of the data you are working with is fixed (you always have coordinate triplets), the easiest solution may be to just flatten out your list before exporting, and partition it after importing, like this:
Export["test.txt", Join ### a, "Table"]
b = Import["text.txt", "Table"]
Partition[#, 3]& /# a
For storing MMA expression I'd suggest DumpSave (binary, system dependent),Save or Put, but if you want to use Export I'd convert a to a string , and export that as text. (I use ImportString and ExpertString below, so that I don't need a file, but it works the same for Import and Export). IMO this is solid as a rock.
a = {{{0, 0, 0}, {1, 0, 0}, {1, 1, 0}}, {{0, 0, 1}, {1, 0, 1}, {1, 1, 1}}};
b = ToExpression#ImportString[ExportString[a // ToString, "Text"], "Text"]
(* ==>
{{{0, 0, 0}, {1, 0, 0}, {1, 1, 0}}, {{0, 0, 1}, {1, 0, 1}, {1, 1, 1}}}
*)
a == b
(* ==> True *)
Reading your polygon list should work the same:
b = ToExpression#ImportString["test.dat", "Text"]
You may also do for example:
a={{{0,0,0},{1,0,0},{1,1,0}},{{0,0,1},{1,0,1},{1,1,1}}};
Export["c:\\test.dat",a,"MathML"];
b=ToExpression#Import["c:\\test.dat","MathML"]
(*
->{{{0, 0, 0}, {1, 0, 0}, {1, 1, 0}}, {{0, 0, 1}, {1, 0, 1}, {1, 1, 1}}}
*)
The additional benefit is that this method does not require parsing the Import output
I also go this Problem. My solution is the following:
IN[]: a = {{{0, 0, 0}, {1, 0, 0}, {1, 1, 0}}, {{0, 0, 1}, {1, 0, 1}, {1, 1, 1}}};
Export["test.dat", a, "List"];
b = ToExpression#Import["test.dat", "List"];
a == b
Out[]: True
Hope this helps. Best regards.