1function model = JSIM2LINE(filename,modelName)
2% MODEL = JSIM2LINE(FILENAME,MODELNAME)
4% Copyright (c) 2012-2026, Imperial College London
8Pref.Str2Num = 'always';
9xDoc = xml_read(filename,Pref);
16 [~,modelName] = fileparts(xDoc.ATTRIBUTE.name);
18model = Network(modelName);
21node_name = cellfun(@(x) x.name, {xDoc.node.ATTRIBUTE},
'UniformOutput',
false)
';
22orig_node_name = node_name;
23for i=1:length(node_name)
24 node_name{i}=strrep(node_name{i},'/
','_
');
25 node_name{i}=strrep(node_name{i},'\
','_
');
28xsection = {xDoc.node.section};
29strategy = cell(1,length(node_name));
32xsection_javaClass = {};
36% This is to create the cs elements last, unclear if it affects correctness
37% isStation = ones(1,length(node_name));
38% for i=1:length(node_name)
39% xsection_i{i} = {xsection{i}};
40% xsection_i{i} = xsection_i{i}{1}; % input, service, and output sections of node i
41% xsection_class{i} = {xsection_i{i}.ATTRIBUTE};
42% switch xsection_class{i}{1}.className % input section
44% xsection_i_type{i} = {xsection{i}.ATTRIBUTE};
45% switch xsection_i_type{i}{2}.className
46% case {'StatelessClassSwitcher
'}
52%for i=[find(isStation==1), find(isStation==0)]
53for i=1:length(node_name)
54 xsection_i{i} = {xsection{i}};
55 xsection_i{i} = xsection_i{i}{1}; % input, service, and output sections of node i
56 xsection_javaClass{i} = {xsection_i{i}.ATTRIBUTE};
57 switch xsection_javaClass{i}{1}.className % input section
59 node{i} = Sink(model, node_name{i});
62 node{i} = Source(model, node_name{i});
64 xrouting{i} = {xsection_i{i}(3).parameter.subParameter.ATTRIBUTE};
67 forkMap=find(cellfun(@any,strfind(cellfun(@class,model.nodes,'UniformOutput
',false),'Fork
')));
69 line_error(mfilename,'JSIM2LINE supports at most a single fork-join pair.
');
71 node{i} = Join(model, node_name{i}, node{forkMap});
72 xrouting{i} = {xsection_i{i}(3).parameter.subParameter.ATTRIBUTE};
74 switch xsection_javaClass{i}{3}.className
76 node{i} = Fork(model, node_name{i});
77 node{i}.setTasksPerLink(xsection_i{i}(3).parameter(1).value); %jobsPerLink
78 xrouting{i} = {xsection_i{i}(3).parameter(4).subParameter.ATTRIBUTE};
80 switch xsection_javaClass{i}{2}.className
82 node{i} = Router(model, node_name{i});
83 xrouting{i} = {xsection_i{i}(3).parameter.subParameter.ATTRIBUTE};
85 xsection_par{i} = {xsection{i}.parameter};
86 xsection_i_par{i} = xsection_i{i}.parameter;
88 xsection_i_value{i} = {xsection_i_par{i}.value};
89 xsection_i_par_attr{i} = {xsection_i_par{i}.ATTRIBUTE};
91 xsection_i_subpar{i} = {xsection_i_par{i}.subParameter};
92 %if xsection_i_value{i}{1}==-1
93 % node{i} = Router(model, node_name{i});
96 xsvc{i} = {xsection_i{i}(2).parameter.subParameter};
97 xrouting{i} = {xsection_i{i}(3).parameter.subParameter.ATTRIBUTE};
99 % xget_strategy{i} = {xsection_i_par{i}.ATTRIBUTE};
100 % switch xget_strategy{i}{3}.name
101 % case 'LCFSstrategy
'
102 % strategy{i} = SchedStrategy.LCFS;
103 % case 'FCFSstrategy
'
104 % strategy{i} = SchedStrategy.FCFS;
107 xput_strategy{i} = xsection_i_par{i};
108 switch xput_strategy{i}(3).ATTRIBUTE.name
109 case 'retrialDistributions
'
110 % new XML format from 1.2.0
111 %xretrial_strategy{i}= {xput_strategy{i}(4)};
112 xput_strategy{i}= {xput_strategy{i}(5).subParameter.ATTRIBUTE};
114 xput_strategy{i}= {xput_strategy{i}(4).subParameter.ATTRIBUTE};
116 switch xput_strategy{i}{1}.name
118 strategy{i} = SchedStrategy.FCFS;
119 case 'TailStrategyPriority
'
120 strategy{i} = SchedStrategy.HOL;
122 strategy{i} = SchedStrategy.LCFS;
124 strategy{i} = SchedStrategy.SIRO;
126 strategy{i} = SchedStrategy.SJF;
128 strategy{i} = SchedStrategy.SEPT;
130 strategy{i} = SchedStrategy.LJF;
132 strategy{i} = SchedStrategy.LEPT;
135 xsection_i_type{i} = {xsection{i}.ATTRIBUTE};
136 switch xsection_i_type{i}{2}.className
138 node{i} = Delay(model, node_name{i});
139 xcapacity = {xsection_i_par{i}.value};
140 node{i}.setCapacity(xcapacity{1}); % buffer size
142 node{i} = Queue(model, node_name{i}, strategy{i});
143 xcapacity = {xsection_i_par{i}.value};
144 node{i}.setCapacity(xcapacity{1}); % buffer size
145 xsection_par_val{i} = {xsection_par{end}{2}.value};
146 node{i}.setNumServers(xsection_par_val{i}{1});
147 switch SchedStrategy.toId(strategy{i})
148 case SchedStrategy.SEPT
149 schedparams{i} = NaN;
151 case 'PSServer
' % requires JMT >= 1.0.2
152 strategy_i_sub={xsection_par{i}{2}.subParameter};
153 strategy_i_sub4=strategy_i_sub{4}; strategy_i_sub4={strategy_i_sub4.ATTRIBUTE};
154 strategy_i_sub5=strategy_i_sub{5};
155 schedparams{i} = cell2mat({strategy_i_sub5.value});
156 r=1; % we assume the strategies are identical across classes
157 switch strategy_i_sub4{r}.name
159 strategy{i} = SchedStrategy.PS;
161 strategy{i} = SchedStrategy.DPS;
163 strategy{i} = SchedStrategy.GPS;
164 case 'EPSStrategyPriority
'
165 strategy{i} = SchedStrategy.PSPRIO;
166 case 'DPSStrategyPriority
'
167 strategy{i} = SchedStrategy.DPSPRIO;
168 case 'GPSStrategyPriority
'
169 strategy{i} = SchedStrategy.GPSPRIO;
171 node{i} = Queue(model, node_name{i}, strategy{i});
172 xcapacity = {xsection_i_par{i}.value};
173 node{i}.setCapacity(xcapacity{1}); % buffer size
174 xsection_par_val{i} = {xsection_par{end}{2}.value};
175 node{i}.setNumServers(xsection_par_val{i}{1});
177 strategy_i_sub={xsection_par{i}{2}.subParameter};
178 strategy_i_sub1=strategy_i_sub{1}; strategy_i_sub1={strategy_i_sub1.subParameter};
179 csMatrix = zeros(length(strategy_i_sub1));
180 for r=1:length(strategy_i_sub1)
181 csMatrix(r,:) = cell2mat({strategy_i_sub1{r}.value});
183 node{i} = ClassSwitch(model, node_name{i}, csMatrix);
188 node{i} = Place(model, node_name{i});
190 node{i} = Transition(model, node_name{i});
195classes = {xDoc.userClass.ATTRIBUTE};
196% JMT uses higher priority value = higher priority, LINE uses lower value = higher priority
197% We need to invert priorities when importing from JMT
199for r=1:length(classes)
200 if classes{r}.priority > maxPrio
201 maxPrio = classes{r}.priority;
204for r=1:length(classes)
205 ref = findstring(node_name,classes{r}.referenceSource);
206 % Invert priority: JMT uses higher=higher, LINE uses lower=higher
207 linePrio = maxPrio - classes{r}.priority;
208 switch classes{r}.type
209 case JobClassType.toText(JobClassType.CLOSED)
210 jobclass{r} = ClosedClass(model, classes{r}.name, classes{r}.customers, node{ref}, linePrio);
211 case JobClassType.toText(JobClassType.OPEN)
212 % sink and source have been created before
213 jobclass{r} = OpenClass(model, classes{r}.name, linePrio);
214 if strcmpi(classes{r}.referenceSource,'StatelessClassSwitcher
')
215 sourceIdx = cellisa(node,'Source
');
216 node{sourceIdx}.setArrival(jobclass{r},Disabled.getInstance());
222for i=1:length(node_name)
223 xsection_i{i} = {xsection{i}};
224 xsection_i{i} = xsection_i{i}{1}; % input, service, and output sections of node i
225 xsection_javaClass{i} = {xsection_i{i}.ATTRIBUTE};
226 switch xsection_javaClass{i}{1}.className % input section
230 if xsection_i{1,i}(1).parameter(1).value == -1
231 node{i}.setCapacity(Inf);
233 node{i}.setCapacity(xsection_i{1,i}(1).parameter(1).value);
235 if isa(xsection_i{1, i}(1).parameter(2).refClass,'cell
')
236 nclasses = length(xsection_i{1, i}(1).parameter(2).refClass);
241 if xsection_i{1, i}(1).parameter(2).subParameter(c).value == -1
242 node{i}.setClassCapacity(c, Inf);
244 node{i}.setClassCapacity(c, xsection_i{1, i}(1).parameter(2).subParameter(c).value);
246 switch xsection_i{1, i}(1).parameter(3).subParameter(c).value
248 node{i}.setDropRule(c, DropStrategy.BAS);
250 node{i}.setDropRule(c, DropStrategy.DROP);
252 node{i}.setDropRule(c, DropStrategy.WAITQ);
259 nmodes = length(xsection_i{1, i}(1).parameter(1).subParameter);
261 node{i}.setModeNames(m, xsection_i{1, i}(2).parameter(1).subParameter(m).value);
265 ninputs = length(xsection_i{1, i}(1).parameter(1).subParameter(m).subParameter.subParameter);
267 refClasses = xsection_i{1, i}(1).parameter(1).subParameter(m).subParameter.subParameter(j).subParameter(2).refClass;
268 if isa(refClasses,'cell
')
269 nclasses = length(refClasses);
273 nodeName = xsection_i{1, i}(1).parameter(1).subParameter(m).subParameter.subParameter(j).subParameter(1).value;
274 targetNode = model.getNodeByName(nodeName);
276 enable = xsection_i{1, i}(1).parameter(1).subParameter(m).subParameter.subParameter(j).subParameter(2).subParameter(k).value;
278 node{i}.setEnablingConditions(m,k,targetNode,Inf);
280 node{i}.setEnablingConditions(m,k,targetNode,enable);
282 inhibit = xsection_i{1, i}(1).parameter(2).subParameter(m).subParameter.subParameter(j).subParameter(2).subParameter(k).value;
284 node{i}.setInhibitingConditions(m,k,targetNode,Inf);
286 node{i}.setInhibitingConditions(m,k,targetNode,inhibit);
293 numOfServers = xsection_i{1, i}(2).parameter(2).subParameter(m).value;
294 if numOfServers == -1
295 node{i}.setNumberOfServers(m, Inf);
297 node{i}.setNumberOfServers(m, numOfServers);
299 timingSt = xsection_i{1, i}(2).parameter(3).subParameter(m).ATTRIBUTE.classPath;
300 if strcmp(timingSt,'jmt.engine.NetStrategies.ServiceStrategies.ZeroServiceTimeStrategy
')
301 node{i}.setTimingStrategy(m,TimingStrategy.IMMEDIATE);
303 node{i}.setTimingStrategy(m,TimingStrategy.TIMED);
304 distribution = xsection_i{1, i}(2).parameter(3).subParameter(m).subParameter(1).ATTRIBUTE.name;
305 lambda = xsection_i{1, i}(2).parameter(3).subParameter(m).subParameter(2).subParameter(1).value;
308 node{i}.setDistribution(m,Exp(lambda));
310 lambda1 = xsection_i{1, i}(2).parameter(3).subParameter(m).subParameter(2).subParameter(2).value;
311 node{i}.setDistribution(m,Erlang(lambda, lambda1));
312 case 'Hyperexponential
'
313 lambda1 = xsection_i{1, i}(2).parameter(3).subParameter(m).subParameter(2).subParameter(2).value;
314 lambda2 = xsection_i{1, i}(2).parameter(3).subParameter(m).subParameter(2).subParameter(3).value;
315 node{i}.setDistribution(m,HyperExp(lambda, lambda1, lambda2));
317 lambda1 = xsection_i{1, i}(2).parameter(3).subParameter(m).subParameter(2).subParameter(2).value;
318 lambda2 = xsection_i{1, i}(2).parameter(3).subParameter(m).subParameter(2).subParameter(3).value;
319 node{i}.setDistribution(m,Coxian([lambda, lambda1], [lambda2,1]));
321 node{i}.setDistribution(m,Det(lambda));
323 lambda1 = xsection_i{1, i}(2).parameter(3).subParameter(m).subParameter(2).subParameter(2).value;
324 node{i}.setDistribution(m,Pareto(lambda, lambda1));
326 lambda1 = xsection_i{1, i}(2).parameter(3).subParameter(m).subParameter(2).subParameter(2).value;
327 node{i}.setDistribution(m,Gamma(lambda, lambda1));
329 lambda1 = xsection_i{1, i}(2).parameter(3).subParameter(m).subParameter(2).subParameter(2).value;
330 node{i}.setDistribution(m,Uniform(lambda, lambda1));
332 node{i}.setDistribution(m,Replayer(lambda));
334 node{i}.setDistribution(m,Trace(lambda));
336 lambda1 = xsection_i{1, i}(2).parameter(3).subParameter(m).subParameter(2).subParameter(2).value;
337 node{i}.setDistribution(m,Weibull(lambda1, lambda)); % scale and shape are inverted in the constructor
339 lambda1 = xsection_i{1, i}(2).parameter(3).subParameter(m).subParameter(2).subParameter(2).value;
340 node{i}.setDistribution(m,Lognormal(lambda, lambda1));
342 error('The model includes an arrival distribution not supported by the model-to-model transformation from JMT.
')
345 firingPriorities = xsection_i{1, i}(2).parameter(4).subParameter(m).value;
346 node{i}.setFiringPriorities(m, firingPriorities);
347 firingWeights = xsection_i{1, i}(2).parameter(5).subParameter(m).value;
348 node{i}.setFiringWeights(m, firingWeights);
352 if isfield(xsection_i{1, i}(3).parameter(1).subParameter(m).subParameter,'CONTENT
')
355 noutputs = length(xsection_i{1, i}(3).parameter(1).subParameter(m).subParameter.subParameter);
358 refClasses = xsection_i{1, i}(3).parameter(1).subParameter(m).subParameter.subParameter(j).subParameter(2).refClass;
359 if isa(refClasses, 'cell
')
360 nclasses = length(refClasses);
364 nodeName = xsection_i{1, i}(3).parameter(1).subParameter(m).subParameter.subParameter(j).subParameter(1).value;
366 outcome = xsection_i{1, i}(3).parameter(1).subParameter(m).subParameter.subParameter(j).subParameter(2).subParameter(k).value;
368 node{i}.setFiringOutcome(m,k,nodeName,Inf);
370 node{i}.setFiringOutcome(m,k,nodeName,outcome);
378schedparams = cell(1,length(node_name));
379% set service distributions
380for i=1:length(node_name)
381 if isa(node{i},'Source
')
382 for r=1:length(classes)
383 xsection_par{i} = {xsection{i}.parameter};
384 xsection_i_par{i} = xsection_i{i}.parameter;
385 xsection_i_subpar{i} = {xsection_i_par{i}.subParameter};
386 xarv_statdistrib{i}{r}={xsection_i_subpar{i}{1}.subParameter};
387 if isempty(xarv_statdistrib{i}{r}{r})
388 node{i}.setArrival(jobclass{r}, Disabled.getInstance());
390 xarv_statdistrib{i}{r}={xarv_statdistrib{i}{r}{r}.ATTRIBUTE};
391 xarv{i} = {xsection_i{i}(1).parameter.subParameter};
392 xarv_sec{i} = {xarv{i}{1}.subParameter};
393 switch xarv_statdistrib{i}{r}{1}.name
395 par={xarv_sec{i}{r}.subParameter}; par=par{2};
396 node{i}.setArrival(jobclass{r}, Exp(par.value));
398 par={xarv_sec{i}{r}.subParameter}; par=par{2};
399 node{i}.setArrival(jobclass{r}, Erlang(par(1).value,par(2).value));
400 case 'Hyperexponential
'
401 par={xarv_sec{i}{r}.subParameter}; par=par{2};
402 node{i}.setArrival(jobclass{r}, HyperExp(par(1).value,par(2).value,par(3).value));
404 par={xarv_sec{i}{r}.subParameter}; par=par{2};
405 node{i}.setArrival(jobclass{r}, Coxian([par(1).value,par(2).value],[par(3).value,1]));
407 par={xarv_sec{i}{r}.subParameter}; par=par{2};
408 node{i}.setArrival(jobclass{r}, Det(par.value));
410 par={xarv_sec{i}{r}.subParameter}; par=par{2};
411 node{i}.setArrival(jobclass{r}, Pareto(par(1).value, par(2).value));
413 par={xarv_sec{i}{r}.subParameter}; par=par{2};
414 node{i}.setArrival(jobclass{r}, Weibull(par(1).value, par(2).value));
416 par={xarv_sec{i}{r}.subParameter}; par=par{2};
417 node{i}.setArrival(jobclass{r}, Lognormal(par(1).value, par(2).value));
419 par={xarv_sec{i}{r}.subParameter}; par=par{2};
420 node{i}.setArrival(jobclass{r}, Gamma(par(1).value, par(2).value));
422 par={xarv_sec{i}{r}.subParameter}; par=par{2};
423 node{i}.setArrival(jobclass{r}, Uniform(par(1).value, par(2).value));
425 par={xarv_sec{i}{r}.subParameter}; par=par{2};
426 node{i}.setArrival(jobclass{r}, Replayer(par.value));
428 par={xarv_sec{i}{r}.subParameter}; par=par{2};
429 node{i}.setArrival(jobclass{r}, Trace(par.value));
431 par={xarv_sec{i}{r}.subParameter}; par=par{2};
432 node{i}.setArrival(jobclass{r}, MMPP2(par(1).value,par(2).value,par(3).value,par(4).value));
434 par={xarv_sec{i}{r}.subParameter}; par=par{2};
435 pars = {par(1).subParameter.subParameter};
438 D0 = [D0; pars{c}.value];
440 pars = {par(2).subParameter.subParameter};
443 D1 = [D1; pars{c}.value];
446 node{i}.setArrival(jobclass{r}, ax);
448 par={xarv_sec{i}{r}.subParameter}; par=par{2};
449 alpha = [par(1).subParameter.subParameter.value];
450 pars = {par(2).subParameter.subParameter};
453 T = [T; pars{c}.value];
455 if any(any(tril(T,-1))>0) % not APH
456 line_warning(mfilename,'The input model uses a general PH distribution, which
is not yet supported in LINE. Fitting the first three moments into an APH distribution.
');
457 PH = {T,-T*ones(size(T,1),1)*alpha};
458 ax = APH.fitCentral(map_mean(PH), map_var(PH), map_skew(PH));
462 node{i}.setArrival(jobclass{r}, ax);
464 line_error(mfilename,'The model includes an arrival distribution not supported by the model-to-model transformation from JMT.
')
465 xarv_statdistrib{i}{r}{1}.name
466 node{i}.setArrival(jobclass{r}, Exp(1)); %TODO
470 elseif isa(node{i},'Queue
') || isa(node{i},'Delay
') || isa(node{i},'DelayStation
')
471 if isempty(schedparams{i})
472 switch SchedStrategy.toId(strategy{i})
473 case {SchedStrategy.SEPT,SchedStrategy.LEPT}
474 schedparams{i} = NaN*ones(1,length(classes));
476 schedparams{i} = ones(1,length(classes));
479 for r=1:length(classes)
480 switch xsection_i_type{i}{2}.className
481 case 'StatelessClassSwitcher
'
485 xsvc_sec{i} = {xsvc{i}{1}.subParameter};
487 xsvc_sec{i} = {xsvc{i}{3}.subParameter};
489 if isempty(xsvc_sec{i}{r})
490 xsvc_statdistrib{i}{r}={struct('name
','Disabled
')};
492 xsvc_statdistrib{i}{r}={xsvc_sec{i}{r}.ATTRIBUTE};
494 para_ir = schedparams{i}(r);
495 switch xsvc_statdistrib{i}{r}{1}.name
497 node{i}.setService(jobclass{r}, Disabled.getInstance());
499 par={xsvc_sec{i}{r}.subParameter}; par=par{2};
500 node{i}.setService(jobclass{r}, Replayer(par.value), para_ir);
502 par={xsvc_sec{i}{r}.subParameter}; par=par{2};
503 node{i}.setService(jobclass{r}, Trace(par.value), para_ir);
505 par={xsvc_sec{i}{r}.subParameter}; par=par{2};
506 node{i}.setService(jobclass{r}, Exp(par.value), para_ir);
508 par={xsvc_sec{i}{r}.subParameter}; par=par{2};
509 node{i}.setService(jobclass{r}, Erlang(par(1).value,par(2).value), para_ir);
510 case 'Hyperexponential
'
511 par={xsvc_sec{i}{r}.subParameter}; par=par{2};
512 node{i}.setService(jobclass{r}, HyperExp(par(1).value,par(2).value,par(3).value), para_ir);
514 par={xsvc_sec{i}{r}.subParameter}; par=par{2};
515 node{i}.setService(jobclass{r}, Coxian([par(1).value,par(2).value],[par(3).value,1]), para_ir);
517 par={xsvc_sec{i}{r}.subParameter}; par=par{2};
518 node{i}.setService(jobclass{r}, Det(par.value));
520 par={xsvc_sec{i}{r}.subParameter}; par=par{2};
521 node{i}.setService(jobclass{r}, Pareto(par(1).value, par(2).value));
523 par={xsvc_sec{i}{r}.subParameter}; par=par{2};
524 node{i}.setService(jobclass{r}, Weibull(par(1).value, par(2).value));
526 par={xsvc_sec{i}{r}.subParameter}; par=par{2};
527 node{i}.setService(jobclass{r}, Lognormal(par(1).value, par(2).value));
529 par={xsvc_sec{i}{r}.subParameter}; par=par{2};
530 node{i}.setService(jobclass{r}, Gamma(par(1).value, par(2).value));
532 par={xsvc_sec{i}{r}.subParameter}; par=par{2};
533 node{i}.setService(jobclass{r}, MMPP2(par(1).value,par(2).value,par(3).value,par(4).value));
535 par={xsvc_sec{i}{r}.subParameter}; par=par{2};
536 pars = {par(1).subParameter.subParameter};
539 D0 = [D0; pars{c}.value];
541 pars = {par(2).subParameter.subParameter};
544 D1 = [D1; pars{c}.value];
547 node{i}.setService(jobclass{r}, ax);
549 par={xsvc_sec{i}{r}.subParameter}; par=par{2};
550 alpha = [par(1).subParameter.subParameter.value];
551 pars = {par(2).subParameter.subParameter};
554 T = [T; pars{c}.value];
556 if any(any(tril(T,-1))>0) % not APH
557 line_warning(mfilename,'The input model uses a general PH distribution, which
is not yet supported in LINE. Fitting the first three moments into an APH distribution.
');
558 PH = {T,-T*ones(size(T,1),1)*alpha};
559 ax = APH.fitCentral(map_mean(PH), map_var(PH), map_skew(PH));
563 node{i}.setService(jobclass{r}, ax);
565 par={xsvc_sec{i}{r}.subParameter}; par=par{2};
566 node{i}.setService(jobclass{r}, Uniform(par(1).value, par(2).value));
568 xsvc_statdistrib{i}{r}{1}.name
569 line_error(mfilename,'The model includes a service distribution not supported by the model-to-model transformation from JMT.
')
570 xsvc_statdistrib{i}{r}{1}.name
571 node{i}.setService(jobclass{r}, Exp(1), para_ir); %TODO
574 for c=1:length(xsection_i_par_attr{i})
575 switch xsection_i_par_attr{i}{c}.name
577 node{i}.input.setSize(xsection_i_value{i}{c}); % buffer size
584C = zeros(length(node_name)); % connection matrix
585links = {xDoc.connection.ATTRIBUTE};
587 source = findstring(orig_node_name,links{l}.source);
588 target = findstring(orig_node_name,links{l}.target);
589 % model.addLink(station{source},station{target});
590 C(source,target) = 1;
593% assign routing probabilities
594P = zeros(length(node_name)*length(classes));
595for from=1:length(node_name)
596 for target=1:length(node_name)
598 model.addLink(node{from},node{target});
603for from=1:length(node_name)
604 switch class(node{from})
609 for r=1:length(classes)
610 switch xrouting{from}{r}.name
612 node{from}.setRouting(jobclass{r},RoutingStrategy.RAND);
613 % targets = find(C(from,:));
614 % if isa(jobclass{r},'Class
')
615 % targets = setdiff(targets, [sink_idx, source_idx]);
617 % for target = targets(:)'
618 % % node{from}.setProbRouting(
jobclass{r}, node{target}, 1 / length(targets));
619 %
P((from-1)*length(
classes)+r, (target-1)*length(
classes)+r) = 1 / length(targets);
622 node{from}.setRouting(
jobclass{r},RoutingStrategy.PROB);
623 xroutprobarray = {xsection_i{from}(3).parameter.subParameter.subParameter};
624 xroutprob = {xroutprobarray{r}.subParameter}; xroutprob = xroutprob{1};
625 xroutprobdest = {xroutprob.subParameter};
626 for j=1:length(xroutprobdest)
627 xprob={xroutprobdest{j}.value};
628 target = findstring(node_name,xprob{1});
630 node{from}.setProbRouting(
jobclass{r}, node{target}, prob);
634 line_error(mfilename,
'Power of k import not supported yet.')
636 node{from}.setRouting(
jobclass{r},RoutingStrategy.RROBIN);
637 case 'Weighted Round Robin'
638 node{from}.setRouting(
jobclass{r},RoutingStrategy.WRROBIN);
639 xroutprobarray = {xsection_i{from}(3).parameter.subParameter.subParameter};
640 xroutprob = {xroutprobarray{r}.subParameter}; xroutprob = xroutprob{1};
641 xroutprobdest = {xroutprob.subParameter};
642 for j=1:length(xroutprobdest)
643 xprob={xroutprobdest{j}.value};
644 target = findstring(node_name,xprob{1});
646 node{from}.setRouting(RoutingStrategy.WRROBIN, node{target},
jobclass{r}, weight);
648 case 'Join the Shortest Queue (JSQ)'
649 node{from}.setRouting(
jobclass{r},RoutingStrategy.JSQ);
651 node{from}.setRouting(
jobclass{r},RoutingStrategy.DISABLED);
657%line_printf([
'JMT2LINE parsing time: ',num2str(Ttot),
' s\n']);
659if length(model.getIndexSourceStation)>1
660 txt = sprintf(
'LINE supports JMT models with at most a single source node. You can refactor your JMT model in several ways:\n - If you are mapping in JMT each class to a different source, this is not required. You can instead assign the same reference station to each class and configure class routing in the routing panel of the source node.\n - In more general cases, you may follow these three steps:\n (1) give a different name to each class of arrival, assigning these classes to a single source as reference station.\n (2) put a class-switch node after the source to switch the new classes into the original classes they were in the model with multiple sources.\n (3) configure the routing section of this class-switch node to set the same routing for the classes as they were in the original model.\n');
666state = zeros(length(node),length(
classes));
667if isfield(xDoc,
'preload') && ~isempty(xDoc.preload.stationPopulations)
668 npreloadStates = length(xDoc.preload.stationPopulations);
669 for st=1:npreloadStates
670 nodeName = xDoc.preload.stationPopulations(st).ATTRIBUTE.stationName;
671 ind = model.getNodeIndex(nodeName);
672 for r=1:length(xDoc.preload.stationPopulations(st).classPopulation)
673 c = model.getClassIndex(xDoc.preload.stationPopulations(st).classPopulation(r).ATTRIBUTE.refClass);
674 state(ind,c) = xDoc.preload.stationPopulations(st).classPopulation(r).ATTRIBUTE.population;
676 if isa(node{ind},
'Place')
677 %node{ind}.setState(state(ind,:));
679 line_error(mfilename,
'Import failed: Colored Petri net models are not yet supported in LINE.\n');
685 model.initFromMarginal(state);
687 line_warning(mfilename,
'Import failed to automatically initialize the model.\n');