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, use general PH
460 node{i}.setArrival(jobclass{r}, ax);
462 line_error(mfilename,'The model includes an arrival distribution not supported by the model-to-model transformation from JMT.
')
463 xarv_statdistrib{i}{r}{1}.name
464 node{i}.setArrival(jobclass{r}, Exp(1)); %TODO
468 elseif isa(node{i},'Queue
') || isa(node{i},'Delay
') || isa(node{i},'DelayStation
')
469 if isempty(schedparams{i})
470 switch SchedStrategy.toId(strategy{i})
471 case {SchedStrategy.SEPT,SchedStrategy.LEPT}
472 schedparams{i} = NaN*ones(1,length(classes));
474 schedparams{i} = ones(1,length(classes));
477 for r=1:length(classes)
478 switch xsection_i_type{i}{2}.className
479 case 'StatelessClassSwitcher
'
483 xsvc_sec{i} = {xsvc{i}{1}.subParameter};
485 xsvc_sec{i} = {xsvc{i}{3}.subParameter};
487 if isempty(xsvc_sec{i}{r})
488 xsvc_statdistrib{i}{r}={struct('name
','Disabled
')};
490 xsvc_statdistrib{i}{r}={xsvc_sec{i}{r}.ATTRIBUTE};
492 para_ir = schedparams{i}(r);
493 switch xsvc_statdistrib{i}{r}{1}.name
495 node{i}.setService(jobclass{r}, Disabled.getInstance());
497 par={xsvc_sec{i}{r}.subParameter}; par=par{2};
498 node{i}.setService(jobclass{r}, Replayer(par.value), para_ir);
500 par={xsvc_sec{i}{r}.subParameter}; par=par{2};
501 node{i}.setService(jobclass{r}, Trace(par.value), para_ir);
503 par={xsvc_sec{i}{r}.subParameter}; par=par{2};
504 node{i}.setService(jobclass{r}, Exp(par.value), para_ir);
506 par={xsvc_sec{i}{r}.subParameter}; par=par{2};
507 node{i}.setService(jobclass{r}, Erlang(par(1).value,par(2).value), para_ir);
508 case 'Hyperexponential
'
509 par={xsvc_sec{i}{r}.subParameter}; par=par{2};
510 node{i}.setService(jobclass{r}, HyperExp(par(1).value,par(2).value,par(3).value), para_ir);
512 par={xsvc_sec{i}{r}.subParameter}; par=par{2};
513 node{i}.setService(jobclass{r}, Coxian([par(1).value,par(2).value],[par(3).value,1]), para_ir);
515 par={xsvc_sec{i}{r}.subParameter}; par=par{2};
516 node{i}.setService(jobclass{r}, Det(par.value));
518 par={xsvc_sec{i}{r}.subParameter}; par=par{2};
519 node{i}.setService(jobclass{r}, Pareto(par(1).value, par(2).value));
521 par={xsvc_sec{i}{r}.subParameter}; par=par{2};
522 node{i}.setService(jobclass{r}, Weibull(par(1).value, par(2).value));
524 par={xsvc_sec{i}{r}.subParameter}; par=par{2};
525 node{i}.setService(jobclass{r}, Lognormal(par(1).value, par(2).value));
527 par={xsvc_sec{i}{r}.subParameter}; par=par{2};
528 node{i}.setService(jobclass{r}, Gamma(par(1).value, par(2).value));
530 par={xsvc_sec{i}{r}.subParameter}; par=par{2};
531 node{i}.setService(jobclass{r}, MMPP2(par(1).value,par(2).value,par(3).value,par(4).value));
533 par={xsvc_sec{i}{r}.subParameter}; par=par{2};
534 pars = {par(1).subParameter.subParameter};
537 D0 = [D0; pars{c}.value];
539 pars = {par(2).subParameter.subParameter};
542 D1 = [D1; pars{c}.value];
545 node{i}.setService(jobclass{r}, ax);
547 par={xsvc_sec{i}{r}.subParameter}; par=par{2};
548 alpha = [par(1).subParameter.subParameter.value];
549 pars = {par(2).subParameter.subParameter};
552 T = [T; pars{c}.value];
554 if any(any(tril(T,-1))>0) % not APH, use general PH
559 node{i}.setService(jobclass{r}, ax);
561 par={xsvc_sec{i}{r}.subParameter}; par=par{2};
562 node{i}.setService(jobclass{r}, Uniform(par(1).value, par(2).value));
564 xsvc_statdistrib{i}{r}{1}.name
565 line_error(mfilename,'The model includes a service distribution not supported by the model-to-model transformation from JMT.
')
566 xsvc_statdistrib{i}{r}{1}.name
567 node{i}.setService(jobclass{r}, Exp(1), para_ir); %TODO
570 for c=1:length(xsection_i_par_attr{i})
571 switch xsection_i_par_attr{i}{c}.name
573 node{i}.input.setSize(xsection_i_value{i}{c}); % buffer size
580C = zeros(length(node_name)); % connection matrix
581links = {xDoc.connection.ATTRIBUTE};
583 source = findstring(orig_node_name,links{l}.source);
584 target = findstring(orig_node_name,links{l}.target);
585 % model.addLink(station{source},station{target});
586 C(source,target) = 1;
589% assign routing probabilities
590P = zeros(length(node_name)*length(classes));
591for from=1:length(node_name)
592 for target=1:length(node_name)
594 model.addLink(node{from},node{target});
599for from=1:length(node_name)
600 switch class(node{from})
605 for r=1:length(classes)
606 switch xrouting{from}{r}.name
608 node{from}.setRouting(jobclass{r},RoutingStrategy.RAND);
609 % targets = find(C(from,:));
610 % if isa(jobclass{r},'Class
')
611 % targets = setdiff(targets, [sink_idx, source_idx]);
613 % for target = targets(:)'
614 % % node{from}.setProbRouting(
jobclass{r}, node{target}, 1 / length(targets));
615 %
P((from-1)*length(
classes)+r, (target-1)*length(
classes)+r) = 1 / length(targets);
618 node{from}.setRouting(
jobclass{r},RoutingStrategy.PROB);
619 xroutprobarray = {xsection_i{from}(3).parameter.subParameter.subParameter};
620 xroutprob = {xroutprobarray{r}.subParameter}; xroutprob = xroutprob{1};
621 xroutprobdest = {xroutprob.subParameter};
622 for j=1:length(xroutprobdest)
623 xprob={xroutprobdest{j}.value};
624 target = findstring(node_name,xprob{1});
626 node{from}.setProbRouting(
jobclass{r}, node{target}, prob);
632 xroutparams = {xsection_i{from}(3).parameter.subParameter.subParameter};
633 if ~isempty(xroutparams) && length(xroutparams) >= r && ~isempty(xroutparams{r})
634 k = xroutparams{r}.value;
637 node{from}.setRouting(
jobclass{r}, RoutingStrategy.KCHOICES, k);
639 node{from}.setRouting(
jobclass{r},RoutingStrategy.RROBIN);
640 case 'Weighted Round Robin'
641 node{from}.setRouting(
jobclass{r},RoutingStrategy.WRROBIN);
642 xroutprobarray = {xsection_i{from}(3).parameter.subParameter.subParameter};
643 xroutprob = {xroutprobarray{r}.subParameter}; xroutprob = xroutprob{1};
644 xroutprobdest = {xroutprob.subParameter};
645 for j=1:length(xroutprobdest)
646 xprob={xroutprobdest{j}.value};
647 target = findstring(node_name,xprob{1});
649 node{from}.setRouting(RoutingStrategy.WRROBIN, node{target},
jobclass{r}, weight);
651 case 'Join the Shortest Queue (JSQ)'
652 node{from}.setRouting(
jobclass{r},RoutingStrategy.JSQ);
654 node{from}.setRouting(
jobclass{r},RoutingStrategy.DISABLED);
660%line_printf([
'JMT2LINE parsing time: ',num2str(Ttot),
' s\n']);
662if length(model.getIndexSourceStation)>1
663 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');
669state = zeros(length(node),length(
classes));
670if isfield(xDoc,
'preload') && ~isempty(xDoc.preload.stationPopulations)
671 npreloadStates = length(xDoc.preload.stationPopulations);
672 for st=1:npreloadStates
673 nodeName = xDoc.preload.stationPopulations(st).ATTRIBUTE.stationName;
674 ind = model.getNodeIndex(nodeName);
675 for r=1:length(xDoc.preload.stationPopulations(st).classPopulation)
676 c = model.getClassIndex(xDoc.preload.stationPopulations(st).classPopulation(r).ATTRIBUTE.refClass);
677 state(ind,c) = xDoc.preload.stationPopulations(st).classPopulation(r).ATTRIBUTE.population;
679 if isa(node{ind},
'Place')
680 %node{ind}.setState(state(ind,:));
682 line_error(mfilename,
'Import failed: Colored Petri net models are not yet supported in LINE.\n');
688 model.initFromMarginal(state);
690 line_warning(mfilename,
'Import failed to automatically initialize the model.\n');