1function [result, parsed] = getResultsJMVA(self)
2% [RESULT, PARSED] = GETRESULTSJMVA()
4% Copyright (c) 2012-2026, Imperial College London
8 fileName = [getFileName(self),
'.jmva-result.jmva'];
9 filePath = [getFilePath(self),filesep,fileName];
10 if exist(filePath,
'file')
11 Pref.Str2Num = 'always';
12 parsed = xml_read(filePath,Pref);
14 line_error(mfilename,'JMT did not output a result file, the analysis has likely failed.');
17 line_error(mfilename,'Unknown error upon parsing JMT result file. ');
19self.result.('solver') = getName(self);
20self.result.('model') = parsed.ATTRIBUTE;
21self.result.('metric') = {};
22self.result.(
'Prob') =
struct();
24 % older JMVA versions
do not have the logValue field and will
throw an
26 switch class(parsed.solutions.algorithm.normconst.ATTRIBUTE.logValue)
28 self.result.Prob.logNormConstAggr = parsed.solutions.algorithm.normconst.ATTRIBUTE.logValue;
30 self.result.Prob.logNormConstAggr = NaN;
33 self.result.Prob.logNormConstAggr = NaN;
38M = sn.nstations; %number of stations
40NK = sn.njobs
'; % initial population per class
44% determine service times
49[~,STchain,Vchain,alpha,~,~] = sn_get_demands_chain(sn);
51statres = parsed.solutions.algorithm.stationresults;
55 switch sn.nodetype(self.getStruct.stationToNode(i))
59 s.('analyzedSamples
') = Inf;
60 s.('class') = sn.classnames{k};
61 s.('discardedSamples
') = 0;
62 s.('lowerLimit
') = sn.rates(i,k);
63 s.('maxSamples
') = Inf;
64 s.('meanValue
') = sn.rates(i,k);
65 s.('measureType
') = MetricType.toText(MetricType.Tput);
66 s.('nodeType
') = 'station
';
67 s.('precision
') = Inf;
68 s.('station
') = sn.nodenames{self.getStruct.stationToNode(i)};
69 s.('successful
') = 'true';
70 s.('upperLimit
') = sn.rates(i,k);
71 self.result.metric{end+1} = s;
75 s.('analyzedSamples
') = Inf;
76 s.('class') = sn.classnames{k};
77 s.('discardedSamples
') = 0;
79 s.('maxSamples
') = Inf;
81 s.('measureType
') = MetricType.toText(MetricType.QLen);
82 s.('nodeType
') = 'station
';
83 s.('precision
') = Inf;
84 s.('station
') = sn.nodenames{self.getStruct.stationToNode(i)};
85 s.('successful
') = 'true';
87 self.result.metric{end+1} = s;
91 s.('analyzedSamples
') = Inf;
92 s.('class') = sn.classnames{k};
93 s.('discardedSamples
') = 0;
95 s.('maxSamples
') = Inf;
97 s.('measureType
') = MetricType.toText(MetricType.RespT);
98 s.('nodeType
') = 'station
';
99 s.('precision
') = Inf;
100 s.('station
') = sn.nodenames{self.getStruct.stationToNode(i)};
101 s.('successful
') = 'true';
102 s.('upperLimit
') = 0;
103 self.result.metric{end+1} = s;
107 s.('analyzedSamples
') = Inf;
108 s.('class') = sn.classnames{k};
109 s.('discardedSamples
') = 0;
110 s.('lowerLimit
') = 0;
111 s.('maxSamples
') = Inf;
113 s.('measureType
') = MetricType.toText(MetricType.Util);
114 s.('nodeType
') = 'station
';
115 s.('precision
') = Inf;
116 s.('station
') = sn.nodenames{self.getStruct.stationToNode(i)};
117 s.('successful
') = 'true';
118 s.('upperLimit
') = 0;
119 self.result.metric{end+1} = s;
129% inchain = sn.inchain{c};
131% X(k) = Xchain(c) * alpha(sn.refstat(k),k);
132%
for i=1:sn.nstations
134% U(i,k) = ST(i,k) * (Xchain(c) * Vchain(i,c) / Vchain(sn.refstat(k),c)) * alpha(i,k);
136% U(i,k) = ST(i,k) * (Xchain(c) * Vchain(i,c) / Vchain(sn.refstat(k),c)) * alpha(i,k) / S(i);
139% Q(i,k) = Rchain(i,c) * ST(i,k) / STchain(i,c) * Xchain(c) * Vchain(i,c) / Vchain(sn.refstat(k),c) * alpha(i,k);
140% T(i,k) = Tchain(i,c) * alpha(i,k);
141% R(i,k) = Q(i,k) / T(i,k);
148% C(k) = sn.njobs(k) / X(k);
151% Q=abs(Q); R=abs(R); X=abs(X); U=abs(U); T=abs(T); C=abs(C);
152% T(~isfinite(T))=0; U(~isfinite(U))=0; Q(~isfinite(Q))=0; R(~isfinite(R))=0; X(~isfinite(X))=0; C(~isfinite(C))=0;
155for i=1:length(statres)
156 classres = statres(i).classresults;
157 for c=1:length(classres)
158 inchain = sn.inchain{c};
159 for m=1:length(classres(c).measure)
163 s.('analyzedSamples
') = Inf;
164 s.('class
') = sn.classnames{k};
165 s.('discardedSamples
') = 0;
166 s.('meanValue
') = classres(c).measure(m).ATTRIBUTE.meanValue;
167 if strcmp(s.meanValue,'NaN
')
170 s.('maxSamples
') = Inf;
171 s.('measureType
') = classres(c).measure(m).ATTRIBUTE.measureType;
172 switch classres(c).measure(m).ATTRIBUTE.measureType
174 if isinf(sn.nservers(i))
175 s.meanValue = ST(i,k) * (s.meanValue / STchain(i,c)) * Vchain(i,c) / Vchain(sn.refstat(k),c) * alpha(i,k);
177 s.meanValue = ST(i,k) * (s.meanValue / STchain(i,c)) / Vchain(sn.refstat(k),c) * alpha(i,k) * min(sum(NK(isfinite(NK))), sn.nservers(i)) / sn.nservers(i);
179 s.('measureType
') = classres(c).measure(m).ATTRIBUTE.measureType;
181 s.meanValue = s.meanValue * alpha(i,k);
182 case 'Number of Customers
'
183 % Q(i,k) = Rchain(i,c) * ST(i,k) / STchain(i,c) * Xchain(c) * Vchain(i,c) / Vchain(sn.refstat(k),c) * alpha(i,k);
184 s.meanValue = s.meanValue * ST(i,k) / STchain(i,c) / Vchain(sn.refstat(k),c) * alpha(i,k);
185 case 'Residence time
'
186 s.('measureType
') = 'Response Time
';
187 s.meanValue = s.meanValue / sn.visits{c}(i,k); % this is to convert from JMVA's residence into LINE
's response time per visit
188 if isinf(sn.nservers(i))
189 s.meanValue = s.meanValue * ST(i,k) / STchain(i,c) / Vchain(sn.refstat(k),c) * alpha(i,k);
191 s.meanValue = s.meanValue * ST(i,k) / STchain(i,c) / Vchain(sn.refstat(k),c) * alpha(i,k);
194 s.('measureType
') = classres(c).measure(m).ATTRIBUTE.measureType;
196 s.('lowerLimit
') = s.meanValue;
197 s.('upperLimit
') = s.meanValue;
198 s.('nodeType
') = 'station
';
199 s.('precision
') = Inf;
200 s.('station
') = statres(i).ATTRIBUTE.station;
201 s.('successful
') = classres(c).measure(m).ATTRIBUTE.successful;
202 self.result.metric{end+1} = s;