001/* 002 * Copyright 2010-2015 Institut Pasteur. 003 * 004 * This file is part of Icy. 005 * 006 * Icy is free software: you can redistribute it and/or modify 007 * it under the terms of the GNU General Public License as published by 008 * the Free Software Foundation, either version 3 of the License, or 009 * (at your option) any later version. 010 * 011 * Icy is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 014 * GNU General Public License for more details. 015 * 016 * You should have received a copy of the GNU General Public License 017 * along with Icy. If not, see <http://www.gnu.org/licenses/>. 018 */ 019package icy.util; 020 021import icy.image.IcyBufferedImage; 022import icy.sequence.MetaDataUtil; 023import icy.sequence.Sequence; 024import icy.system.IcyExceptionHandler; 025import icy.type.DataType; 026import icy.type.TypeUtil; 027 028import java.awt.Color; 029 030import org.w3c.dom.Document; 031 032import loci.common.services.DependencyException; 033import loci.common.services.ServiceException; 034import loci.common.services.ServiceFactory; 035import loci.formats.MetadataTools; 036import loci.formats.ome.OMEXMLMetadataImpl; 037import loci.formats.services.OMEXMLService; 038import loci.formats.services.OMEXMLServiceImpl; 039import ome.units.UNITS; 040import ome.units.quantity.Length; 041import ome.units.quantity.Time; 042import ome.xml.meta.MetadataRetrieve; 043import ome.xml.meta.OMEXMLMetadata; 044import ome.xml.model.OME; 045import ome.xml.model.StructuredAnnotations; 046import ome.xml.model.XMLAnnotation; 047import ome.xml.model.primitives.NonNegativeInteger; 048import ome.xml.model.primitives.PositiveFloat; 049import ome.xml.model.primitives.PositiveInteger; 050 051/** 052 * @author Stephane 053 */ 054public class OMEUtil 055{ 056 private static ServiceFactory factory; 057 private static OMEXMLService OMEService; 058 059 static 060 { 061 try 062 { 063 factory = new ServiceFactory(); 064 OMEService = factory.getInstance(OMEXMLService.class); 065 } 066 catch (DependencyException e) 067 { 068 System.err.println("Error create OME Service:" + e.getMessage()); 069 System.err.println("Using default service implementation..."); 070 071 factory = null; 072 OMEService = new OMEXMLServiceImpl(); 073 } 074 } 075 076 /** 077 * Safe integer evaluation from PositiveInteger object.<br> 078 * Return defaultValue if specified object is null. 079 */ 080 public static int getValue(PositiveInteger obj, int defaultValue) 081 { 082 if (obj == null) 083 return defaultValue; 084 085 return TypeUtil.getInt(obj.getValue(), defaultValue); 086 } 087 088 /** 089 * Safe integer evaluation from NonNegativeInteger object.<br> 090 * Return defaultValue if specified object is null. 091 */ 092 public static int getValue(NonNegativeInteger obj, int defaultValue) 093 { 094 if (obj == null) 095 return defaultValue; 096 097 return TypeUtil.getInt(obj.getValue(), defaultValue); 098 } 099 100 /** 101 * Safe float evaluation from PositiveFloat object.<br> 102 * Return <code>defaultValue</code> if <code>obj</code> is null or equal to infinite with <code>allowInfinite</code> 103 * set to false. 104 */ 105 public static double getValue(PositiveFloat obj, double defaultValue, boolean allowInfinite) 106 { 107 if (obj == null) 108 return defaultValue; 109 110 return TypeUtil.getDouble(obj.getValue(), defaultValue, allowInfinite); 111 } 112 113 /** 114 * Safe float evaluation from PositiveFloat object.<br> 115 * Return defaultValue if specified object is null. 116 */ 117 public static double getValue(PositiveFloat obj, double defaultValue) 118 { 119 return getValue(obj, defaultValue, true); 120 } 121 122 /** 123 * Convert specified Length to double value in µm (for backward compatibility).<br> 124 * Return defaultValue if specified object is <code>null</code>. 125 */ 126 public static double getValue(Length obj, double defaultValue) 127 { 128 if (obj == null) 129 return defaultValue; 130 131 final Number value = obj.value(UNITS.MICROMETER); 132 if (value == null) 133 return defaultValue; 134 135 return value.doubleValue(); 136 } 137 138 /** 139 * Convert specified Time to double value in second (for backward compatibility).<br> 140 * Return defaultValue if specified object is <code>null</code>. 141 */ 142 public static double getValue(Time obj, double defaultValue) 143 { 144 if (obj == null) 145 return defaultValue; 146 147 final Number value = obj.value(UNITS.SECOND); 148 if (value == null) 149 return defaultValue; 150 151 return value.doubleValue(); 152 } 153 154 /** 155 * Return a PositiveFloat object representing the specified value 156 */ 157 public static PositiveFloat getPositiveFloat(double value) 158 { 159 return new PositiveFloat(Double.valueOf(value)); 160 } 161 162 /** 163 * Return a PositiveInteger object representing the specified value 164 */ 165 public static PositiveInteger getPositiveInteger(int value) 166 { 167 return new PositiveInteger(Integer.valueOf(value)); 168 } 169 170 /** 171 * Return a NonNegativeInteger object representing the specified value 172 */ 173 public static NonNegativeInteger getNonNegativeInteger(int value) 174 { 175 return new NonNegativeInteger(Integer.valueOf(value)); 176 } 177 178 /** 179 * Return a Length object representing the specified value (in µm) 180 */ 181 public static Length getLength(double value) 182 { 183 return new Length(Double.valueOf(value), UNITS.MICROMETER); 184 } 185 186 /** 187 * Return a Time object representing the specified value (in second) 188 */ 189 public static Time getTime(double value) 190 { 191 return new Time(Double.valueOf(value), UNITS.SECOND); 192 } 193 194 /** 195 * Return a java Color object from a OME Color object 196 */ 197 public static Color getJavaColor(ome.xml.model.primitives.Color value) 198 { 199 if (value == null) 200 return null; 201 202 return new Color(value.getRed(), value.getGreen(), value.getBlue(), value.getAlpha()); 203 } 204 205 /** 206 * Return a OME Color object from a java Color object 207 */ 208 public static ome.xml.model.primitives.Color getOMEColor(Color value) 209 { 210 return new ome.xml.model.primitives.Color(value.getRed(), value.getGreen(), value.getBlue(), value.getAlpha()); 211 } 212 213 /** 214 * Create a new empty OME Metadata object. 215 */ 216 public synchronized static OMEXMLMetadata createOMEXMLMetadata() 217 { 218 try 219 { 220 return OMEService.createOMEXMLMetadata(); 221 } 222 catch (Exception e) 223 { 224 IcyExceptionHandler.showErrorMessage(e, true); 225 return null; 226 } 227 } 228 229 /** 230 * @deprecated Use {@link #createOMEXMLMetadata()} instead 231 */ 232 @Deprecated 233 public static OMEXMLMetadataImpl createOMEMetadata() 234 { 235 return (OMEXMLMetadataImpl) createOMEXMLMetadata(); 236 } 237 238 /** 239 * Create a new OME Metadata object from the specified Metadata object.<br> 240 */ 241 public static OMEXMLMetadata createOMEXMLMetadata(MetadataRetrieve metadata) 242 { 243 final OMEXMLMetadata result = createOMEXMLMetadata(); 244 245 // TODO: remove that when annotations loading will be fixed in Bio-Formats 246 if (metadata instanceof OMEXMLMetadata) 247 { 248 final OME root = (OME) ((OMEXMLMetadata) metadata).getRoot(); 249 final StructuredAnnotations annotations = root.getStructuredAnnotations(); 250 251 // clean up annotation 252 if (annotations != null) 253 { 254 for (int i = annotations.sizeOfXMLAnnotationList() - 1; i >= 0; i--) 255 { 256 final XMLAnnotation annotation = annotations.getXMLAnnotation(i); 257 258 if (StringUtil.isEmpty(annotation.getValue())) 259 annotations.removeXMLAnnotation(annotation); 260 } 261 } 262 } 263 264 synchronized (OMEService) 265 { 266 // need to cast to get rid of this old loci package stuff 267 OMEService.convertMetadata((loci.formats.meta.MetadataRetrieve) metadata, 268 (loci.formats.meta.MetadataStore) result); 269 } 270 271 return result; 272 } 273 274 /** 275 * @deprecated Use {@link #createOMEXMLMetadata(MetadataRetrieve)} instead 276 */ 277 @Deprecated 278 public synchronized static OMEXMLMetadataImpl createOMEMetadata(loci.formats.meta.MetadataRetrieve metadata) 279 { 280 return (OMEXMLMetadataImpl) createOMEXMLMetadata(metadata); 281 } 282 283 /** 284 * Create a new single serie OME Metadata object from the specified Metadata object. 285 * 286 * @param serie 287 * Index of the serie we want to keep. 288 */ 289 public static OMEXMLMetadata createOMEXMLMetadata(MetadataRetrieve metadata, int serie) 290 { 291 final OMEXMLMetadata result = OMEUtil.createOMEXMLMetadata(metadata); 292 293 MetaDataUtil.keepSingleSerie(result, serie); 294 295 // set the default id with correct serie number (for XML metadata) 296 result.setImageID(MetadataTools.createLSID("Image", serie), 0); 297 298 return result; 299 } 300 301 /** 302 * @deprecated Use {@link #createOMEXMLMetadata(MetadataRetrieve,int)} instead 303 */ 304 @Deprecated 305 public static OMEXMLMetadataImpl createOMEMetadata(loci.formats.meta.MetadataRetrieve metadata, int serie) 306 { 307 return (OMEXMLMetadataImpl) createOMEXMLMetadata(metadata, serie); 308 } 309 310 /** 311 * Convert the specified Metadata object to OME Metadata.<br> 312 * If the specified Metadata is already OME no conversion is done. 313 */ 314 public static OMEXMLMetadata getOMEXMLMetadata(MetadataRetrieve metadata) 315 { 316 if (metadata instanceof OMEXMLMetadata) 317 return (OMEXMLMetadata) metadata; 318 319 return createOMEXMLMetadata(metadata); 320 } 321 322 /** 323 * @deprecated Use {@link #getOMEXMLMetadata(MetadataRetrieve)} instead 324 */ 325 @Deprecated 326 public static OMEXMLMetadataImpl getOMEMetadata(loci.formats.meta.MetadataRetrieve metadata) 327 { 328 return (OMEXMLMetadataImpl) getOMEXMLMetadata(metadata); 329 } 330 331 /** 332 * Return a XML document from the specified Metadata object 333 */ 334 public static Document getXMLDocument(OMEXMLMetadata metadata) 335 { 336 try 337 { 338 return XMLUtil.createDocument(metadata.dumpXML()); 339 } 340 catch (Exception e) 341 { 342 IcyExceptionHandler.showErrorMessage(e, true); 343 } 344 345 // return empty document 346 return XMLUtil.createDocument(false); 347 } 348 349 /** 350 * @deprecated Use {@link #getXMLDocument(OMEXMLMetadata)} instead 351 */ 352 @Deprecated 353 public static Document getXMLDocument(loci.formats.meta.MetadataRetrieve metadata) 354 { 355 return getXMLDocument(getOMEXMLMetadata(metadata)); 356 } 357 358 /** 359 * @deprecated Uses {@link MetaDataUtil#setMetaData(OMEXMLMetadata, int, int, int, int, int, DataType, boolean)} 360 * instead. 361 */ 362 @Deprecated 363 public static OMEXMLMetadataImpl generateMetaData(OMEXMLMetadataImpl metadata, int sizeX, int sizeY, int sizeC, 364 int sizeZ, int sizeT, DataType dataType, boolean separateChannel) 365 { 366 final OMEXMLMetadata result; 367 368 if (metadata == null) 369 result = MetaDataUtil.createMetadata("Sample"); 370 else 371 result = metadata; 372 373 MetaDataUtil.setMetaData(result, sizeX, sizeY, sizeC, sizeZ, sizeT, dataType, separateChannel); 374 375 return (OMEXMLMetadataImpl) result; 376 } 377 378 /** 379 * @deprecated Uses {@link MetaDataUtil#generateMetaData(int, int, int, int, int, DataType, boolean)} instead. 380 */ 381 @Deprecated 382 public static OMEXMLMetadata generateMetaData(int sizeX, int sizeY, int sizeC, int sizeZ, int sizeT, 383 DataType dataType, boolean separateChannel) throws ServiceException 384 { 385 return MetaDataUtil.generateMetaData(sizeX, sizeY, sizeC, sizeZ, sizeT, dataType, separateChannel); 386 } 387 388 /** 389 * @deprecated Use {@link MetaDataUtil#generateMetaData(int, int, int, DataType, boolean)} instead. 390 */ 391 @Deprecated 392 public static OMEXMLMetadata generateMetaData(int sizeX, int sizeY, int sizeC, DataType dataType, 393 boolean separateChannel) throws ServiceException 394 { 395 return MetaDataUtil.generateMetaData(sizeX, sizeY, sizeC, dataType, separateChannel); 396 } 397 398 /** 399 * @deprecated Use {@link MetaDataUtil#generateMetaData(IcyBufferedImage, boolean)} instead. 400 */ 401 @Deprecated 402 public static OMEXMLMetadata generateMetaData(IcyBufferedImage image, boolean separateChannel) 403 throws ServiceException 404 { 405 return MetaDataUtil.generateMetaData(image, separateChannel); 406 } 407 408 /** 409 * @deprecated Use {@link MetaDataUtil#generateMetaData(Sequence, boolean)} instead. 410 */ 411 @Deprecated 412 public static OMEXMLMetadata generateMetaData(Sequence sequence, boolean useZ, boolean useT, 413 boolean separateChannel) 414 { 415 return MetaDataUtil.generateMetaData(sequence, separateChannel); 416 } 417 418 /** 419 * @deprecated Use {@link MetaDataUtil#generateMetaData(Sequence, boolean)} instead. 420 */ 421 @Deprecated 422 public static OMEXMLMetadata generateMetaData(Sequence sequence, int sizeZ, int sizeT, boolean separateChannel) 423 { 424 return MetaDataUtil.generateMetaData(sequence, separateChannel); 425 } 426 427 /** 428 * @deprecated Use {@link MetaDataUtil#generateMetaData(Sequence, boolean)} instead. 429 */ 430 @Deprecated 431 public static OMEXMLMetadata generateMetaData(Sequence sequence, boolean separateChannel) 432 { 433 return MetaDataUtil.generateMetaData(sequence, separateChannel); 434 } 435 436 /** 437 * Report and upload the specified filename to LOCI team. 438 */ 439 public static boolean reportLociError(String fileName, String errorMessage) 440 { 441 // TODO: implement this when done in LOCI 442 // final IssueReporter reporter = new IssueReporter(); 443 // return reporter.reportBug(fileName, errorMessage); 444 445 return false; 446 } 447 448}