2 |
26 Feb 07 |
jari |
1 |
/* |
2 |
26 Feb 07 |
jari |
Copyright @ 1999-2002, The Institute for Genomic Research (TIGR). |
2 |
26 Feb 07 |
jari |
All rights reserved. |
2 |
26 Feb 07 |
jari |
4 |
|
2 |
26 Feb 07 |
jari |
This software is provided "AS IS". TIGR makes no warranties, express |
2 |
26 Feb 07 |
jari |
or implied, including no representation or warranty with respect to |
2 |
26 Feb 07 |
jari |
the performance of the software and derivatives or their safety, |
2 |
26 Feb 07 |
jari |
effectiveness, or commercial viability. TIGR does not warrant the |
2 |
26 Feb 07 |
jari |
merchantability or fitness of the software and derivatives for any |
2 |
26 Feb 07 |
jari |
particular purpose, or that they may be exploited without infringing |
2 |
26 Feb 07 |
jari |
the copyrights, patent rights or property rights of others. TIGR shall |
2 |
26 Feb 07 |
jari |
not be liable for any claim, demand or action for any loss, harm, |
2 |
26 Feb 07 |
jari |
illness or other damage or injury arising from access to or use of the |
2 |
26 Feb 07 |
jari |
software or associated information, including without limitation any |
2 |
26 Feb 07 |
jari |
direct, indirect, incidental, exemplary, special or consequential |
2 |
26 Feb 07 |
jari |
damages. |
2 |
26 Feb 07 |
jari |
17 |
|
2 |
26 Feb 07 |
jari |
This software program may not be sold, leased, transferred, exported |
2 |
26 Feb 07 |
jari |
or otherwise disclaimed to anyone, in whole or in part, without the |
2 |
26 Feb 07 |
jari |
prior written consent of TIGR. |
2 |
26 Feb 07 |
jari |
21 |
*/ |
2 |
26 Feb 07 |
jari |
22 |
package org.tigr.microarray.mev.cluster.algorithm.impl; |
2 |
26 Feb 07 |
jari |
23 |
|
2 |
26 Feb 07 |
jari |
24 |
|
2 |
26 Feb 07 |
jari |
25 |
import javax.swing.JFrame; |
2 |
26 Feb 07 |
jari |
26 |
|
2 |
26 Feb 07 |
jari |
27 |
import org.tigr.microarray.mev.cluster.algorithm.AbortException; |
2 |
26 Feb 07 |
jari |
28 |
import org.tigr.microarray.mev.cluster.algorithm.AbstractAlgorithm; |
2 |
26 Feb 07 |
jari |
29 |
import org.tigr.microarray.mev.cluster.algorithm.Algorithm; |
2 |
26 Feb 07 |
jari |
30 |
import org.tigr.microarray.mev.cluster.algorithm.AlgorithmData; |
2 |
26 Feb 07 |
jari |
31 |
import org.tigr.microarray.mev.cluster.algorithm.AlgorithmEvent; |
2 |
26 Feb 07 |
jari |
32 |
import org.tigr.microarray.mev.cluster.algorithm.AlgorithmException; |
2 |
26 Feb 07 |
jari |
33 |
import org.tigr.microarray.mev.cluster.algorithm.AlgorithmParameters; |
2 |
26 Feb 07 |
jari |
34 |
import org.tigr.util.FloatMatrix; |
2 |
26 Feb 07 |
jari |
35 |
import org.tigr.util.awt.ProgressDialog; |
2 |
26 Feb 07 |
jari |
36 |
|
2 |
26 Feb 07 |
jari |
37 |
public class GDM extends AbstractAlgorithm { |
2 |
26 Feb 07 |
jari |
38 |
private boolean stop = false; |
2 |
26 Feb 07 |
jari |
39 |
private int function; |
2 |
26 Feb 07 |
jari |
40 |
private float factor; |
2 |
26 Feb 07 |
jari |
41 |
private boolean absolute; |
2 |
26 Feb 07 |
jari |
42 |
private FloatMatrix expMatrix; |
2 |
26 Feb 07 |
jari |
43 |
|
2 |
26 Feb 07 |
jari |
44 |
private FloatMatrix geneDistanceMatrix; |
2 |
26 Feb 07 |
jari |
45 |
private FloatMatrix rawMatrix; |
2 |
26 Feb 07 |
jari |
46 |
|
2 |
26 Feb 07 |
jari |
47 |
private int num_samples; // m = number_of_samples |
2 |
26 Feb 07 |
jari |
48 |
private int num_genes; //n = number_of_genes |
2 |
26 Feb 07 |
jari |
49 |
private boolean pearson=false; |
2 |
26 Feb 07 |
jari |
50 |
|
2 |
26 Feb 07 |
jari |
51 |
private long StartTime; |
2 |
26 Feb 07 |
jari |
52 |
private long CalculationTime; |
2 |
26 Feb 07 |
jari |
53 |
|
2 |
26 Feb 07 |
jari |
54 |
private boolean Stop; |
2 |
26 Feb 07 |
jari |
55 |
private int DistanceFunction; |
2 |
26 Feb 07 |
jari |
56 |
|
2 |
26 Feb 07 |
jari |
57 |
private ProgressDialog PD; |
2 |
26 Feb 07 |
jari |
58 |
|
2 |
26 Feb 07 |
jari |
59 |
private double zeroValue; |
2 |
26 Feb 07 |
jari |
60 |
|
2 |
26 Feb 07 |
jari |
61 |
private float maxDist; |
2 |
26 Feb 07 |
jari |
62 |
private float minDist; |
2 |
26 Feb 07 |
jari |
63 |
|
2 |
26 Feb 07 |
jari |
64 |
public GDM() { |
2 |
26 Feb 07 |
jari |
65 |
} |
2 |
26 Feb 07 |
jari |
66 |
|
2 |
26 Feb 07 |
jari |
67 |
public AlgorithmData execute(AlgorithmData data) throws AlgorithmException { |
2 |
26 Feb 07 |
jari |
68 |
|
2 |
26 Feb 07 |
jari |
69 |
AlgorithmParameters map = data.getParams(); |
2 |
26 Feb 07 |
jari |
70 |
|
2 |
26 Feb 07 |
jari |
71 |
function = map.getInt("distance-function", EUCLIDEAN); |
2 |
26 Feb 07 |
jari |
72 |
factor = map.getFloat("distance-factor", 1.0f); |
2 |
26 Feb 07 |
jari |
73 |
absolute = map.getBoolean("distance-absolute", false); |
2 |
26 Feb 07 |
jari |
74 |
this.expMatrix = data.getMatrix("experiment"); |
2 |
26 Feb 07 |
jari |
75 |
if (expMatrix == null) { |
2 |
26 Feb 07 |
jari |
76 |
throw new AlgorithmException("Input data is absent."); |
2 |
26 Feb 07 |
jari |
77 |
} |
2 |
26 Feb 07 |
jari |
78 |
|
2 |
26 Feb 07 |
jari |
79 |
num_genes = this.expMatrix.getRowDimension(); //n = number_of_genes |
2 |
26 Feb 07 |
jari |
80 |
num_samples = this.expMatrix.getColumnDimension();//m = number_of_samples |
2 |
26 Feb 07 |
jari |
81 |
geneDistanceMatrix = new FloatMatrix(num_genes, num_genes); |
2 |
26 Feb 07 |
jari |
82 |
rawMatrix = new FloatMatrix(num_genes, num_genes); |
2 |
26 Feb 07 |
jari |
83 |
|
2 |
26 Feb 07 |
jari |
84 |
JFrame dummyFrame = new JFrame(); |
2 |
26 Feb 07 |
jari |
85 |
PD = new ProgressDialog(dummyFrame, "Gene Distance Matrix Progression", false, 4); |
2 |
26 Feb 07 |
jari |
86 |
|
2 |
26 Feb 07 |
jari |
87 |
generateDistanceMatrix(); |
2 |
26 Feb 07 |
jari |
88 |
|
2 |
26 Feb 07 |
jari |
89 |
AlgorithmData result = new AlgorithmData(); |
2 |
26 Feb 07 |
jari |
90 |
result.addMatrix("gdMatrix", geneDistanceMatrix); |
2 |
26 Feb 07 |
jari |
91 |
result.addMatrix("rawMatrix", rawMatrix); |
2 |
26 Feb 07 |
jari |
92 |
|
2 |
26 Feb 07 |
jari |
93 |
result.addParam("maxDist", String.valueOf(maxDist)); |
2 |
26 Feb 07 |
jari |
94 |
result.addParam("minDist", String.valueOf(minDist)); |
2 |
26 Feb 07 |
jari |
95 |
result.addParam("num_genes", String.valueOf(num_genes)); |
2 |
26 Feb 07 |
jari |
96 |
return result; |
2 |
26 Feb 07 |
jari |
97 |
|
2 |
26 Feb 07 |
jari |
98 |
} |
2 |
26 Feb 07 |
jari |
99 |
|
2 |
26 Feb 07 |
jari |
100 |
|
2 |
26 Feb 07 |
jari |
101 |
public void abort() { |
2 |
26 Feb 07 |
jari |
102 |
stop = true; |
2 |
26 Feb 07 |
jari |
103 |
} |
2 |
26 Feb 07 |
jari |
104 |
|
2 |
26 Feb 07 |
jari |
// Calculate the Actual "Raw" distance between a pair of genes. |
2 |
26 Feb 07 |
jari |
106 |
synchronized float getRawDistance(int g1, int g2) { |
2 |
26 Feb 07 |
jari |
107 |
float result = Float.NaN; |
2 |
26 Feb 07 |
jari |
108 |
switch (function) { |
2 |
26 Feb 07 |
jari |
109 |
case Algorithm.PEARSON: |
2 |
26 Feb 07 |
jari |
110 |
result = ExperimentUtil.genePearson(expMatrix, null, g1, g2, factor); |
2 |
26 Feb 07 |
jari |
111 |
break; |
2 |
26 Feb 07 |
jari |
112 |
case Algorithm.COSINE: |
2 |
26 Feb 07 |
jari |
113 |
result = ExperimentUtil.geneCosine(expMatrix, null, g1, g2, factor); |
2 |
26 Feb 07 |
jari |
114 |
break; |
2 |
26 Feb 07 |
jari |
115 |
case Algorithm.COVARIANCE: |
2 |
26 Feb 07 |
jari |
116 |
result = ExperimentUtil.geneCovariance(expMatrix, null, g1, g2, factor); |
2 |
26 Feb 07 |
jari |
117 |
break; |
2 |
26 Feb 07 |
jari |
118 |
case Algorithm.EUCLIDEAN: |
2 |
26 Feb 07 |
jari |
119 |
result = ExperimentUtil.geneEuclidianDistance(expMatrix, null, g1, g2, factor); |
2 |
26 Feb 07 |
jari |
120 |
break; |
2 |
26 Feb 07 |
jari |
121 |
case Algorithm.DOTPRODUCT: |
2 |
26 Feb 07 |
jari |
122 |
result = ExperimentUtil.geneDotProduct(expMatrix, null, g1, g2, factor); |
2 |
26 Feb 07 |
jari |
123 |
break; |
2 |
26 Feb 07 |
jari |
124 |
case Algorithm.PEARSONUNCENTERED: |
2 |
26 Feb 07 |
jari |
125 |
result = ExperimentUtil.genePearsonUncentered(expMatrix, null, g1, g2, factor); |
2 |
26 Feb 07 |
jari |
126 |
break; |
2 |
26 Feb 07 |
jari |
127 |
case Algorithm.PEARSONSQARED: |
2 |
26 Feb 07 |
jari |
128 |
result = (float)Math.pow(ExperimentUtil.genePearsonUncentered(expMatrix, null, g1, g2, factor), 2)*factor; |
2 |
26 Feb 07 |
jari |
129 |
break; |
2 |
26 Feb 07 |
jari |
130 |
case Algorithm.MANHATTAN: |
2 |
26 Feb 07 |
jari |
131 |
result = ExperimentUtil.geneManhattan(expMatrix, null, g1, g2, factor); |
2 |
26 Feb 07 |
jari |
132 |
break; |
2 |
26 Feb 07 |
jari |
133 |
case Algorithm.SPEARMANRANK: |
2 |
26 Feb 07 |
jari |
134 |
result = ExperimentUtil.geneSpearmanRank(expMatrix, null, g1, g2, factor); |
2 |
26 Feb 07 |
jari |
135 |
break; |
2 |
26 Feb 07 |
jari |
136 |
case Algorithm.KENDALLSTAU: |
2 |
26 Feb 07 |
jari |
137 |
result = ExperimentUtil.geneKendallsTau(expMatrix, null, g1, g2, factor); |
2 |
26 Feb 07 |
jari |
138 |
break; |
2 |
26 Feb 07 |
jari |
139 |
case Algorithm.MUTUALINFORMATION: |
2 |
26 Feb 07 |
jari |
140 |
result = ExperimentUtil.geneMutualInformation(expMatrix, null, g1, g2, factor); |
2 |
26 Feb 07 |
jari |
141 |
break; |
2 |
26 Feb 07 |
jari |
142 |
default: {} |
2 |
26 Feb 07 |
jari |
143 |
} |
2 |
26 Feb 07 |
jari |
144 |
|
2 |
26 Feb 07 |
jari |
145 |
if (absolute) { |
2 |
26 Feb 07 |
jari |
146 |
result = Math.abs(result); |
2 |
26 Feb 07 |
jari |
147 |
} |
2 |
26 Feb 07 |
jari |
148 |
return result; |
2 |
26 Feb 07 |
jari |
149 |
} |
2 |
26 Feb 07 |
jari |
150 |
|
2 |
26 Feb 07 |
jari |
// Scale the calculated "raw" distance value to range between 0 & 1. |
2 |
26 Feb 07 |
jari |
152 |
synchronized float getScaledDistance(int g1, int g2, float max, float min) { |
2 |
26 Feb 07 |
jari |
153 |
|
2 |
26 Feb 07 |
jari |
154 |
float val = Float.NaN; |
2 |
26 Feb 07 |
jari |
155 |
float rawval = rawMatrix.get(g1, g2); |
2 |
26 Feb 07 |
jari |
156 |
|
2 |
26 Feb 07 |
jari |
157 |
if (Float.isNaN(rawval)) |
2 |
26 Feb 07 |
jari |
158 |
return rawval; |
2 |
26 Feb 07 |
jari |
159 |
|
2 |
26 Feb 07 |
jari |
160 |
switch(function) { |
2 |
26 Feb 07 |
jari |
161 |
case Algorithm.EUCLIDEAN: |
2 |
26 Feb 07 |
jari |
162 |
case Algorithm.MANHATTAN: |
2 |
26 Feb 07 |
jari |
163 |
val = rawval / max; |
2 |
26 Feb 07 |
jari |
164 |
break; |
2 |
26 Feb 07 |
jari |
165 |
|
2 |
26 Feb 07 |
jari |
166 |
case Algorithm.PEARSON: |
2 |
26 Feb 07 |
jari |
167 |
case Algorithm.PEARSONUNCENTERED: |
2 |
26 Feb 07 |
jari |
168 |
case Algorithm.SPEARMANRANK: |
2 |
26 Feb 07 |
jari |
169 |
case Algorithm.KENDALLSTAU: |
2 |
26 Feb 07 |
jari |
170 |
case Algorithm.MUTUALINFORMATION: |
2 |
26 Feb 07 |
jari |
171 |
case Algorithm.COSINE: |
2 |
26 Feb 07 |
jari |
172 |
if (!absolute) { |
2 |
26 Feb 07 |
jari |
173 |
val = (1 - rawval) / 2; |
2 |
26 Feb 07 |
jari |
174 |
}else { |
2 |
26 Feb 07 |
jari |
175 |
val = 1 - Math.abs(rawval); |
2 |
26 Feb 07 |
jari |
176 |
} |
2 |
26 Feb 07 |
jari |
177 |
break; |
2 |
26 Feb 07 |
jari |
178 |
|
2 |
26 Feb 07 |
jari |
179 |
case Algorithm.PEARSONSQARED: |
2 |
26 Feb 07 |
jari |
180 |
{ |
2 |
26 Feb 07 |
jari |
181 |
float pearson; |
2 |
26 Feb 07 |
jari |
182 |
if (!absolute) { |
2 |
26 Feb 07 |
jari |
183 |
pearson = (1 - rawval) / 2; |
2 |
26 Feb 07 |
jari |
184 |
} else { |
2 |
26 Feb 07 |
jari |
185 |
pearson = 1 - Math.abs(rawval); |
2 |
26 Feb 07 |
jari |
186 |
} |
2 |
26 Feb 07 |
jari |
187 |
val = 1 - (pearson*pearson); |
2 |
26 Feb 07 |
jari |
188 |
break; |
2 |
26 Feb 07 |
jari |
189 |
} |
2 |
26 Feb 07 |
jari |
190 |
case Algorithm.DOTPRODUCT: |
2 |
26 Feb 07 |
jari |
191 |
case Algorithm.COVARIANCE: |
2 |
26 Feb 07 |
jari |
192 |
{ |
2 |
26 Feb 07 |
jari |
193 |
float tmp; |
2 |
26 Feb 07 |
jari |
194 |
if (!absolute) { |
2 |
26 Feb 07 |
jari |
195 |
tmp = (max - rawval) / (max - min); |
2 |
26 Feb 07 |
jari |
196 |
} else { |
2 |
26 Feb 07 |
jari |
197 |
max = (Math.abs(min) > Math.abs(max)) ? Math.abs(min) : Math.abs(max); |
2 |
26 Feb 07 |
jari |
198 |
tmp = Math.abs(rawval) / max; |
2 |
26 Feb 07 |
jari |
199 |
} |
2 |
26 Feb 07 |
jari |
200 |
val = 1 - tmp; |
2 |
26 Feb 07 |
jari |
201 |
break; |
2 |
26 Feb 07 |
jari |
202 |
} |
2 |
26 Feb 07 |
jari |
203 |
default: {} |
2 |
26 Feb 07 |
jari |
204 |
} |
2 |
26 Feb 07 |
jari |
205 |
return val; |
2 |
26 Feb 07 |
jari |
206 |
} |
2 |
26 Feb 07 |
jari |
207 |
|
2 |
26 Feb 07 |
jari |
208 |
|
2 |
26 Feb 07 |
jari |
// Calculate the Gene Distance Matrix |
2 |
26 Feb 07 |
jari |
210 |
synchronized void generateDistanceMatrix() throws AbortException { |
2 |
26 Feb 07 |
jari |
211 |
|
2 |
26 Feb 07 |
jari |
212 |
AlgorithmEvent event = new AlgorithmEvent(this, AlgorithmEvent.SET_UNITS, 100, "Construct Distance Matrix"); |
2 |
26 Feb 07 |
jari |
213 |
fireValueChanged(event); |
2 |
26 Feb 07 |
jari |
214 |
|
2 |
26 Feb 07 |
jari |
215 |
event.setId(AlgorithmEvent.PROGRESS_VALUE); |
2 |
26 Feb 07 |
jari |
216 |
|
2 |
26 Feb 07 |
jari |
217 |
int progress = 0; |
2 |
26 Feb 07 |
jari |
218 |
int sum = num_genes * num_genes; |
2 |
26 Feb 07 |
jari |
219 |
int step = sum/100+1; |
2 |
26 Feb 07 |
jari |
220 |
|
2 |
26 Feb 07 |
jari |
221 |
int i,j,k,nan; |
2 |
26 Feb 07 |
jari |
222 |
float dist, rawdist, maxraw, minraw; |
2 |
26 Feb 07 |
jari |
223 |
|
2 |
26 Feb 07 |
jari |
224 |
maxraw = minraw = maxDist = minDist = nan = 0; |
2 |
26 Feb 07 |
jari |
225 |
for (i=0;i<num_genes;i++){ |
2 |
26 Feb 07 |
jari |
226 |
|
2 |
26 Feb 07 |
jari |
227 |
progress++; |
2 |
26 Feb 07 |
jari |
228 |
|
2 |
26 Feb 07 |
jari |
229 |
for (j=i+1; j<num_genes; j++) { |
2 |
26 Feb 07 |
jari |
230 |
if (stop) { |
2 |
26 Feb 07 |
jari |
231 |
throw new AbortException(); |
2 |
26 Feb 07 |
jari |
232 |
} |
2 |
26 Feb 07 |
jari |
233 |
rawdist = getRawDistance(i, j); |
2 |
26 Feb 07 |
jari |
234 |
if (!Float.isNaN(rawdist)) { |
2 |
26 Feb 07 |
jari |
235 |
maxraw = Math.max(maxraw, rawdist); |
2 |
26 Feb 07 |
jari |
236 |
minraw = Math.min(minraw, rawdist); |
2 |
26 Feb 07 |
jari |
237 |
if (rawdist == 0 && i != j) { |
2 |
26 Feb 07 |
jari |
238 |
int cols = expMatrix.getColumnDimension(); |
2 |
26 Feb 07 |
jari |
239 |
for (k=0; k<cols; k++) { |
2 |
26 Feb 07 |
jari |
240 |
if (!Float.isNaN(expMatrix.get(i,k)) && !Float.isNaN(expMatrix.get(j,k))) { |
2 |
26 Feb 07 |
jari |
241 |
break; |
2 |
26 Feb 07 |
jari |
242 |
} |
2 |
26 Feb 07 |
jari |
243 |
} |
2 |
26 Feb 07 |
jari |
244 |
if (k == cols) { |
2 |
26 Feb 07 |
jari |
245 |
rawdist = Float.NaN; |
2 |
26 Feb 07 |
jari |
246 |
nan++; |
2 |
26 Feb 07 |
jari |
247 |
} |
2 |
26 Feb 07 |
jari |
248 |
} |
2 |
26 Feb 07 |
jari |
249 |
rawMatrix.set(i, j, rawdist); |
2 |
26 Feb 07 |
jari |
250 |
rawMatrix.set(j, i, rawdist); |
2 |
26 Feb 07 |
jari |
251 |
|
2 |
26 Feb 07 |
jari |
// progress events handling |
2 |
26 Feb 07 |
jari |
253 |
progress++; |
2 |
26 Feb 07 |
jari |
254 |
if (progress%step == 0) { |
2 |
26 Feb 07 |
jari |
255 |
event.setIntValue(progress/step); |
2 |
26 Feb 07 |
jari |
256 |
event.setDescription("Construct Distance Matrix"); |
2 |
26 Feb 07 |
jari |
257 |
fireValueChanged(event); |
2 |
26 Feb 07 |
jari |
258 |
} |
2 |
26 Feb 07 |
jari |
259 |
} |
2 |
26 Feb 07 |
jari |
260 |
} |
2 |
26 Feb 07 |
jari |
261 |
} |
2 |
26 Feb 07 |
jari |
262 |
|
2 |
26 Feb 07 |
jari |
263 |
for (i=0; i<num_genes; i++) { |
2 |
26 Feb 07 |
jari |
264 |
|
2 |
26 Feb 07 |
jari |
265 |
progress++; |
2 |
26 Feb 07 |
jari |
266 |
|
2 |
26 Feb 07 |
jari |
267 |
for (j=i+1; j<num_genes; j++) { |
2 |
26 Feb 07 |
jari |
268 |
if (stop) { |
2 |
26 Feb 07 |
jari |
269 |
throw new AbortException(); |
2 |
26 Feb 07 |
jari |
270 |
} |
2 |
26 Feb 07 |
jari |
271 |
dist = getScaledDistance(i, j, maxraw, minraw); |
2 |
26 Feb 07 |
jari |
272 |
maxDist = Math.max(maxDist, dist); |
2 |
26 Feb 07 |
jari |
273 |
minDist = Math.min(minDist, dist); |
2 |
26 Feb 07 |
jari |
274 |
geneDistanceMatrix.set(i, j, dist); |
2 |
26 Feb 07 |
jari |
275 |
geneDistanceMatrix.set(j, i, dist); |
2 |
26 Feb 07 |
jari |
276 |
|
2 |
26 Feb 07 |
jari |
// progress events handling |
2 |
26 Feb 07 |
jari |
278 |
progress++; |
2 |
26 Feb 07 |
jari |
279 |
if (progress%step == 0) { |
2 |
26 Feb 07 |
jari |
280 |
event.setIntValue(progress/step); |
2 |
26 Feb 07 |
jari |
281 |
event.setDescription("Construct Distance Matrix"); |
2 |
26 Feb 07 |
jari |
282 |
fireValueChanged(event); |
2 |
26 Feb 07 |
jari |
283 |
} |
2 |
26 Feb 07 |
jari |
284 |
} |
2 |
26 Feb 07 |
jari |
285 |
} |
2 |
26 Feb 07 |
jari |
// Since we are displaying "scaled" distance values, therefore set min=0 & max=1 |
2 |
26 Feb 07 |
jari |
287 |
minDist = 0; |
2 |
26 Feb 07 |
jari |
288 |
maxDist = 1; |
2 |
26 Feb 07 |
jari |
289 |
} |
2 |
26 Feb 07 |
jari |
290 |
|
2 |
26 Feb 07 |
jari |
291 |
} |