1
2
3 """
4 components/tools/OmeroPy/src/omero/util/OmeroPopo.py
5
6 -----------------------------------------------------------------------------
7 Copyright (C) 2006-2010 University of Dundee. All rights reserved.
8
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License along
20 with this program; if not, write to the Free Software Foundation, Inc.,
21 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22
23 ------------------------------------------------------------------------------
24
25 @author Donald MacDonald
26 <a href="mailto:donald@lifesci.dundee.ac.uk">donald@lifesci.dundee.ac.uk</a>
27 @version 3.0
28 <small>
29 (<b>Internal version:</b> $Revision: $Date: $)
30 </small>
31 @since 3.0-Beta4.2
32
33 """
34 import math;
35 import numpy;
36 import omero.clients
37 from omero.model import ImageI
38 from omero.model import RoiI
39 from omero.model import EllipseI
40 from omero.model import LineI
41 from omero.model import RectI
42 from omero.model import PointI
43 from omero.model import LabelI
44 from omero.model import PolylineI
45 from omero.model import PolygonI
46 from omero.model import PathI
47 from omero.model import MaskI
48 from omero.model import NamespaceI
49 from omero.rtypes import rdouble
50 from omero.rtypes import rstring
51 from omero.rtypes import rint
52 from omero.rtypes import rfloat
53 from omero.rtypes import rlist
54 from omero.rtypes import rlong
55
56
57
59 """
60 Convert a list to a Comma Separated Value string.
61 @param list The list to convert.
62 @return See above.
63 """
64 lenList = len(list);
65 cnt = 0;
66 str = "";
67 for item in list:
68 str = str + item;
69 if(cnt < lenList-1):
70 str = str + ",";
71 cnt = cnt +1;
72 return str;
73
75 """
76 Convert a csv string to a list of strings
77 @param csvString The CSV string to convert.
78 @return See above.
79 """
80 list = csvString.split(',');
81 for index in range(len(list)):
82 list[index] = list[index].strip();
83 return list;
84
85
86
87
89
90
91
92
94 self.value = None;
95 self.dirty = False;
96
97
98
99
100
101
103 if(value==None):
104 raise Exception("IObject delegate for DataObject cannot be null.");
105 self.value = value;
106
107
108
109
110
112 if(self.value.getId()==None):
113 return -1;
114 return self.value.getId().getValue();
115
116
117
118
122
123
124
125
126
129
130
131
132
133
135 self.dirty = boolean;
136
137
138
139
140
143
144
145
146
149
150
151
152
155
157
158
159
160
167
168
169
170
171
172
173
180
181
182
183
184
185
194
195
196
197
198
199
200
207
208
209
210
211
212
221
222
223
224
226
227
228
229
230
232 self.theZ = z;
233 self.theT = t;
234 self.ZBITSPLIT = 18;
235
236
237
238
240 if(self.theZ == obj.theZ and self.theT == obj.theT):
241 return True;
242 return False;
243
244
245
246
248 if(self.theZ != obj.theZ or self.theT != obj.theT):
249 return True;
250 return False;
251
252
253
254
256 if(self.theT >= obj.theT):
257 return False;
258 if(self.theZ >= obj.theZ):
259 return False;
260 return True;
261
262
263
264
266 if(self.theT < obj.theT):
267 return False;
268 if(self.theZ < obj.theZ):
269 return False;
270 return True;
271
272
273
274
276 if(self.theT <= obj.theT):
277 return False;
278 if(self.theZ <= obj.theZ):
279 return False;
280 return True;
281
282
283
284
286 if(self.theT < obj.theT):
287 return False;
288 if(self.theZ < obj.theZ):
289 return False;
290 return True;
291
292
293
294
296 return self.theZ<<self.ZBITSPLIT+self.theT;
297
298
299
300
301
302
305
306
307
308
309
310
313
314
315
316
317
320
321
322
323
324
327
328
329
330
331
333 """
334 Wrap the serverSide shape as the appropriate OmeroPopos
335 @param serverSideShape The shape object to wrap.
336 @return See above.
337 """
338 print "ServerSideShape"
339 print serverSideShape.__class__.__name__
340 if serverSideShape.__class__.__name__=='EllipseI':
341 return EllipseData(serverSideShape);
342 if serverSideShape.__class__.__name__=='RectI':
343 return RectData(serverSideShape);
344 if serverSideShape.__class__.__name__=='MaskI':
345 return MaskData(serverSideShape);
346 if serverSideShape.__class__.__name__=='PolygonI':
347 return PolygonData(serverSideShape);
348 return None;
349
350
351
352
354
355
356
357
367
368
369
383
384
385
386
387
394
395
396
397
398
400 roi = self.asIObject();
401 if(roi==None):
402 raise Exception("No Roi specified.");
403 return roi.getImage();
404
405
406
407
408
410 roi = self.asIObject();
411 if(roi==None):
412 raise Exception("No Roi specified.");
413 coord = shape.getROICoordinate();
414 shapeList = None;
415 if(self.roiShapes.has_key(coord) == False):
416 shapeList = list();
417 self.roiShapes[coord] = shapeList;
418 else:
419 shapeList = self.roiShapes[coord];
420 shapeList.append(shape);
421 roi.addShape(shape.asIObject());
422 self.setDirty(True);
423
424
425
426
427
429 roi = self.asIObject();
430 if(roi==None):
431 raise Exception("No Roi specified.");
432 coord = shape.getROICoordinate();
433 shapeList = self.roiShapes[coord];
434 shapeList.remove(shape);
435 roi.removeShape(shape.asIObject());
436 self.setDirty(True);
437
438
439
440
441
443 return len(self.roiShapes)
444
445
446
447
448
455
456
457
458
459
460
461
462
465
466
467
468
469
470
472 return self.roiShapes.iteritems();
473
474
475
476
477
478
479
480
482 coordList = self.roiShapes.keys();
483 coordList.sort();
484 keyList = [];
485 for coord in coordList:
486 if(coord>=start and coord <= end):
487 keyList.append(coord);
488 return self.roiShapes.from_keys(keyList);
489
490
491
492
493
494
506
507
508
509
510
520
521
522
523
524
525
527 roi = self.asIObject();
528 if(roi==None):
529 raise Exception("No Roi specified.");
530 roi.setNamespaces(map.keys);
531 keywords = [];
532 for namespace in map.keys:
533 keywords.append(map[namespace]);
534 roi.setKeywords(keywords);
535 self.setDirty(True);
536
537
538
539
540
549
550
551
552
553
555 roi = self.asIObject();
556 if (roi == None):
557 raise Exception("No Roi specified.");
558 namespaces = self.getNamespaces();
559 namespaceKeywords = roi.getKeywords();
560 if(len(namespaces) != len(namespaceKeywords)):
561 raise Exception("Namespaces length does not match keywords namespace length.");
562 map = {};
563 for i in range(len(namespaces)):
564 map[namespaces[i]] = namespaceKeywords[i];
565 return map;
566
568
573
574
575
576
577
578
580 shape = self.asIObject();
581 if(shape==None):
582 raise Exception("No Shape specified.");
583 z = shape.getTheZ();
584 if(z==None):
585 return 0;
586 else:
587 return z.getValue();
588
589
590
591
592
593 - def setZ(self, theZ):
594 shape = self.asIObject();
595 if(shape==None):
596 raise Exception("No Shape specified.");
597 shape.setTheZ(rint(theZ));
598 self.coord.setZSection(theZ);
599 self.setDirty(True);
600
601
602
603
604
605
607 shape = self.asIObject();
608 if(shape==None):
609 raise Exception("No Shape specified.");
610 t = shape.getTheT();
611 if(t==None):
612 return 0;
613 else:
614 return t.getValue();
615
616
617
618
619
620 - def setT(self, theT):
621 shape = self.asIObject();
622 if(shape==None):
623 raise Exception("No Shape specified.");
624 shape.setTheT(rint(theT));
625 self.coord.setTimePoint(theT);
626 self.setDirty(True);
627
628
629
630
631
633 shape = self.asIObject();
634 if(shape==None):
635 raise Exception("No Shape specified.");
636 self.setZ(coord.getZSection());
637 self.setT(coord.getTimePoint());
638 self.coord.setZSection(coord.getZSection());
639 self.coord.setTimePoint(coord.getTimePoint());
640 self.setDirty(True);
641
642
643
644
645
647 shape = self.asIObject();
648 if(shape==None):
649 raise Exception("No Shape specified.");
650 return self.coord;
651
652
653
654
656 shape = self.asIObject();
657 if(shape==None):
658 raise Exception("No Shape specified.");
659 text = shape.getTextValue();
660 if(text==None):
661 return "";
662 else:
663 return text.getValue();
664
665
666
667
668 - def setText(self, text):
669 shape = self.asIObject();
670 if(shape==None):
671 raise Exception("No Shape specified.");
672 shape.setTextValue(rstring(text));
673 self.setDirty(True)
674
675
676
677
678
679
692
699
700
701
702
703
719
720
721
722
723
726
727
728
729
732
733
734
735
737
738
739
740
751
752
753
754
756 shape = self.asIObject();
757 if(shape==None):
758 raise Exception("No Shape specified.");
759 shape.setCx(rdouble(cx));
760
761
762
763
765 shape = self.asIObject();
766 if(shape==None):
767 raise Exception("No Shape specified.");
768 cx = shape.getCx();
769 if(cx==None):
770 return 0;
771 return cx.getValue();
772
773
774
775
777 shape = self.asIObject();
778 if(shape==None):
779 raise Exception("No Shape specified.");
780 shape.setCy(rdouble(cy));
781
782
783
784
786 shape = self.asIObject();
787 if(shape==None):
788 raise Exception("No Shape specified.");
789 cy = shape.getCy();
790 if(cy==None):
791 return 0;
792 return cy.getValue();
793
794
795
796
798 shape = self.asIObject();
799 if(shape==None):
800 raise Exception("No Shape specified.");
801 shape.setRx(rdouble(rx));
802
803
804
805
807 shape = self.asIObject();
808 if(shape==None):
809 raise Exception("No Shape specified.");
810 rx = shape.getRx();
811 if(rx==None):
812 return 0;
813 return rx.getValue();
814
815
816
817
819 shape = self.asIObject();
820 if(shape==None):
821 raise Exception("No Shape specified.");
822 shape.setRy(rdouble(ry));
823
824
825
826
828 shape = self.asIObject();
829 if(shape==None):
830 raise Exception("No Shape specified.");
831 ry = shape.getRy();
832 if(ry==None):
833 return 0;
834 return ry.getValue();
835
836
837
838
839
840
841
845
846
847
848
849
851 cx = self.getCx();
852 cy = self.getCy();
853 rx = self.getRx();
854 ry = self.getRy();
855 transform = self.transformToMatrix(self.getTransform());
856 point = numpy.matrix((cx, cy, 1)).transpose();
857 centre = transform*point;
858 BL = numpy.matrix((cx-rx, cy+ry, 1)).transpose();
859 BR = numpy.matrix((cx+rx, cy+ry, 1)).transpose();
860 TL = numpy.matrix((cx-rx, cy-ry, 1)).transpose();
861 TR = numpy.matrix((cx+rx, cy-ry, 1)).transpose();
862 MajorAxisLeft = numpy.matrix((cx-rx, cy, 1)).transpose();
863 MajorAxisRight = numpy.matrix((cx+rx, cy, 1)).transpose();
864 MinorAxisTop = numpy.matrix((cx, cy-ry, 1)).transpose();
865 MinorAxisBottom = numpy.matrix((cx, cy+ry, 1)).transpose();
866 lb = transform*BL;
867 rb = transform*BR;
868 lt = transform*TL;
869 rt = transform*TR;
870 majl = transform*MajorAxisLeft;
871 majr = transform*MajorAxisRight;
872 mint = transform*MinorAxisTop;
873 minb = transform*MinorAxisBottom;
874 o = (majr[1]-majl[1]);
875 a = (majr[0]-majl[0]);
876 h = math.sqrt(o*o+a*a);
877 majorAxisAngle = math.asin(o/h);
878 boundingBoxMinX = min(lt[0], rt[0],lb[0], rb[0]);
879 boundingBoxMaxX = max(lt[0], rt[0], lb[0], rb[0]);
880 boundingBoxMinY = min(lt[1], rt[1], lb[1], rb[1]);
881 boundingBoxMaxY = max(lt[1], rt[1], lb[1], rb[1]);
882 boundingBox = ((boundingBoxMinX, boundingBoxMinY), (boundingBoxMaxX, boundingBoxMaxY));
883 centredBoundingBox = ((boundingBox[0][0]-centre[0],boundingBox[0][1]-centre[1]),(boundingBox[1][0]-centre[0],boundingBox[1][1]-centre[1]))
884 points = {};
885 cx = float(centre[0]);
886 cy = float(centre[1]);
887 xrange = range(centredBoundingBox[0][0], centredBoundingBox[1][0])
888 yrange = range(centredBoundingBox[0][1], centredBoundingBox[1][1])
889 for x in xrange:
890 for y in yrange:
891 newX = x*math.cos(majorAxisAngle)+y*math.sin(majorAxisAngle);
892 newY = -x*math.sin(majorAxisAngle)+y*math.cos(majorAxisAngle);
893 val = (newX*newX)/(rx*rx)+ (newY*newY)/(ry*ry);
894 if(val <= 1):
895 points[(int(x+cx), int(y+cy))]=1;
896 return points;
897
898
899
900
902
903
904
905
918
919
920
921
922
926
927
928
929
930
934
935
936
937
938
942
943
944
945
946
950
951
952
953
954
962
963
964
965
966
967
968
970 pts = self.toString(points);
971 pts1 = self.toString(points);
972 pts2 = self.toString(points);
973 mask = self.toString(points);
974 str = "points["+pts+"] ";
975 str = str + "points1["+pts1+"] ";
976 str = str + "points2["+pts2+"] ";
977 str = str + "mask["+mask+"]";
978 self.setPointsString(str);
979
980
981
982
984 shape = self.asIObject();
985 if(shape==None):
986 raise Exception("No Shape specified.");
987 pts = shape.getPoints();
988 if(pts==None):
989 return "";
990 else:
991 return pts.getValue();
992
993
994
995
996
997
1000
1001
1002
1003
1004
1005
1006
1007
1008 - def getContents(self, string, start, end):
1009 lIndex = string.find(start);
1010 if(lIndex == -1):
1011 return "";
1012 strFragment = string[lIndex:];
1013 rIndex = strFragment.find(']');
1014 if(rIndex == -1):
1015 return "";
1016 return string[lIndex+len(start):rIndex];
1017
1018
1019
1020
1021
1023 numberList = pts.split(',');
1024 return numberList;
1025
1026
1027
1028
1029
1031 str = "";
1032 for index, pt in enumerate(pointsList):
1033 str = str + pt;
1034 if(index<len(pointsList)-1):
1035 str = str + ",";
1036 return str;
1037
1038
1039
1040
1046
1047
1048
1049
1050
1052 pts = self.toCoords(self.getPoints());
1053 minx = pts[0][0];
1054 maxx = minx;
1055 miny = pts[0][1];
1056 maxy = miny;
1057
1058 for pt in pts:
1059 minx = min(pt[0],minx);
1060 miny = min(pt[1],miny);
1061 maxx = max(pt[0],maxx);
1062 maxy = max(pt[1],maxy);
1063 return [(minx,miny), (maxx, maxy)];
1064
1065
1066
1067
1068
1070 coords = [];
1071 for index in range(len(ptsList)/2):
1072 coords.append((int(ptsList[index*2]), int(ptsList[index*2+1])));
1073 return coords;
1074
1075
1076
1077
1078
1079
1081 points = {};
1082 boundingRectangle = self.getBoundingRectangle();
1083 xrange = range(boundingRectangle[0][0], boundingRectangle[1][0])
1084 yrange = range(boundingRectangle[0][1], boundingRectangle[1][1])
1085 for xx in xrange:
1086 for yy in yrange:
1087 if(self.inPolygon((xx,yy))):
1088 points[(xx,yy)]=1;
1089 return points;
1090
1091
1092
1093
1094
1095
1097 angle = 0.0
1098 polypoints = self.getPoints();
1099 cnt = 0;
1100 polygon = [];
1101 for index in range(0,len(polypoints)/2):
1102 polygon.append((int(polypoints[index*2]), int(polypoints[index*2+1])));
1103
1104 n = len(polygon)
1105
1106 for i, (h, v) in enumerate(polygon):
1107 p1 = (h - p[0], v - p[1])
1108 h, v = polygon[(i + 1) % n]
1109 p2 = (h - p[0], v - p[1])
1110 angle += self.Angle2D(p1[0], p1[1], p2[0], p2[1]);
1111
1112 if abs(angle) < math.pi:
1113 return False
1114 return True
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124 - def Angle2D(self, x1, y1, x2, y2):
1125 theta1 = math.atan2(y1, x1)
1126 theta2 = math.atan2(y2, x2)
1127 dtheta = theta2 - theta1
1128 while dtheta > math.pi:
1129 dtheta -= 2.0 * math.pi
1130 while dtheta < -math.pi:
1131 dtheta += 2.0 * math.pi
1132 return dtheta
1133
1134
1135
1136
1138
1139
1140
1141
1153
1154
1155
1156
1157 - def setX(self, x):
1158 shape = self.asIObject();
1159 if(shape==None):
1160 raise Exception("No Shape specified.");
1161 shape.setX(rdouble(x));
1162
1163
1164
1165
1167 shape = self.asIObject();
1168 if(shape==None):
1169 raise Exception("No Shape specified.");
1170 x = shape.getX();
1171 if(x==None):
1172 return 0;
1173 return x.getValue();
1174
1175
1176
1177
1178 - def setY(self, y):
1179 shape = self.asIObject();
1180 if(shape==None):
1181 raise Exception("No Shape specified.");
1182 shape.setY(rdouble(y));
1183
1184
1185
1186
1188 shape = self.asIObject();
1189 if(shape==None):
1190 raise Exception("No Shape specified.");
1191 y = shape.getY();
1192 if(y==None):
1193 return 0;
1194 return y.getValue();
1195
1196
1197
1199 shape = self.asIObject();
1200 if(shape==None):
1201 raise Exception("No Shape specified.");
1202 shape.setWidth(rdouble(width));
1203
1204
1205
1206
1208 shape = self.asIObject();
1209 if(shape==None):
1210 raise Exception("No Shape specified.");
1211 width = shape.getWidth();
1212 if(width==None):
1213 return 0;
1214 return width.getValue();
1215
1216
1217
1219 shape = self.asIObject();
1220 if(shape==None):
1221 raise Exception("No Shape specified.");
1222 shape.setHeight(rdouble(height));
1223
1224
1225
1226
1228 shape = self.asIObject();
1229 if(shape==None):
1230 raise Exception("No Shape specified.");
1231 height = shape.getHeight();
1232 if(height==None):
1233 return 0;
1234 return height.getValue();
1235
1236
1237
1239 shape = self.asIObject();
1240 if(shape==None):
1241 raise Exception("No Shape specified.");
1242 shape.setBytes(mask);
1243
1244
1245
1246
1248 shape = self.asIObject();
1249 if(shape==None):
1250 raise Exception("No Shape specified.");
1251 mask = shape.getBytes();
1252 if(mask==None):
1253 return 0;
1254 return mask.getValue();
1255
1256
1257
1258
1259
1261
1262
1263
1264
1275
1276
1277
1278
1279 - def setX(self, x):
1280 shape = self.asIObject();
1281 if (shape == None):
1282 raise Exception("No Shape specified.");
1283 shape.setX(rdouble(x));
1284
1285
1286
1287
1289 shape = self.asIObject();
1290 if (shape == None):
1291 raise Exception("No Shape specified.");
1292 x = shape.getX();
1293 if (x == None):
1294 return 0;
1295 return x.getValue();
1296
1297
1298
1299
1300 - def setY(self, y):
1301 shape = self.asIObject();
1302 if(shape==None):
1303 raise Exception("No Shape specified.");
1304 shape.setY(rdouble(y));
1305
1306
1307
1308
1310 shape = self.asIObject();
1311 if(shape==None):
1312 raise Exception("No Shape specified.");
1313 y = shape.getY();
1314 if(y==None):
1315 return 0;
1316 return y.getValue();
1317
1318
1319
1321 shape = self.asIObject();
1322 if(shape==None):
1323 raise Exception("No Shape specified.");
1324 shape.setWidth(rdouble(width));
1325
1326
1327
1328
1330 shape = self.asIObject();
1331 if(shape==None):
1332 raise Exception("No Shape specified.");
1333 width = shape.getWidth();
1334 if(width==None):
1335 return 0;
1336 return width.getValue();
1337
1338
1339
1341 shape = self.asIObject();
1342 if(shape==None):
1343 raise Exception("No Shape specified.");
1344 shape.setHeight(rdouble(height));
1345
1346
1347
1348
1350 shape = self.asIObject();
1351 if(shape==None):
1352 raise Exception("No Shape specified.");
1353 height = shape.getHeight();
1354 if(height==None):
1355 return 0;
1356 return height.getValue();
1357
1358
1359
1360
1361
1362
1363
1367
1368
1369
1370
1371
1373 transform = self.transformToMatrix(self.getTransform());
1374 x = self.getX();
1375 y = self.getY();
1376 width = self.getWidth();
1377 height = self.getHeight();
1378 point = numpy.matrix((x, y, 1)).transpose();
1379 centre = transform*point;
1380 BL = numpy.matrix((x, y+height, 1)).transpose();
1381 BR = numpy.matrix((x+width, y+height, 1)).transpose();
1382 TL = numpy.matrix((x, y, 1)).transpose();
1383 TR = numpy.matrix((x+width, y, 1)).transpose();
1384 lb = transform*BL;
1385 rb = transform*BR;
1386 lt = transform*TL;
1387 rt = transform*TR;
1388 majl = lb
1389 majr = rb
1390 o = (majr[1]-majl[1]);
1391 a = (majr[0]-majl[0]);
1392 h = math.sqrt(o*o+a*a);
1393 angle = math.asin(o/h);
1394 boundingBoxMinX = min(lt[0], rt[0], lb[0], rb[0]);
1395 boundingBoxMaxX = max(lt[0], rt[0], lb[0], rb[0]);
1396 boundingBoxMinY = min(lt[1], rt[1], lb[1], rb[1]);
1397 boundingBoxMaxY = max(lt[1], rt[1], lb[1], rb[1]);
1398 boundingBox = ((boundingBoxMinX, boundingBoxMinY), (boundingBoxMaxX, boundingBoxMaxY));
1399 points = {};
1400 xrange = range(boundingBox[0][0], boundingBox[1][0])
1401 yrange = range(boundingBox[0][1], boundingBox[1][1])
1402 transformedX = float(centre[0]);
1403 transformedY = float(centre[1]);
1404 cx = float(centre[0]);
1405 cy = float(centre[1]);
1406 for xx in xrange:
1407 for yy in yrange:
1408 newX = xx*math.cos(angle)+yy*math.sin(angle);
1409 newY = -xx*math.sin(angle)+yy*math.cos(angle);
1410
1411 if (newX-transformedX < width and newY-transformedY < height and newX-transformedX > 0 and newY-transformedY > 0):
1412 points[(int(x+cx), int(y+cy))]=1;
1413 return points;
1414
1415
1416
1417
1428
1429
1430
1431
1433 workflow = self.asIObject();
1434 if(workflow==None):
1435 raise Exception("No workflow specified.");
1436 workflow.setName(rstring(namespace));
1437 self.setDirty(True);
1438
1439
1440
1441
1443 workflow = self.asIObject();
1444 if(workflow==None):
1445 raise Exception("No Workflow specified.");
1446 namespace = workflow.getName();
1447 if(namespace==None):
1448 return "";
1449 return namespace.getValue();
1450
1451
1452
1453
1455 workflow = self.asIObject();
1456 if(workflow==None):
1457 raise Exception("No workflow specified.");
1458 workflow.setKeywords(keywords);
1459 self.setDirty(True);
1460
1461
1462
1463
1465 workflow = self.asIObject();
1466 if(workflow==None):
1467 raise Exception("No workflow specified.");
1468 workflow.setKeywords(toList(keywords));
1469 self.setDirty(True);
1470
1471
1472
1473
1475 workflow = self.asIObject();
1476 if(workflow==None):
1477 raise Exception("No Workflow specified.");
1478 keywords = workflow.getKeywords();
1479 if(keywords==None):
1480 return [];
1481 return keywords;
1482
1483
1484
1485
1492
1493
1494
1495
1497 keywords = self.getKeywords();
1498 return (keyword in keywords);
1499
1500
1501
1502
1509