/* * Copyright (C) 2010 Brockmann Consult GmbH (info@brockmann-consult.de) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 3 of the License, or (at your option) * any later version. * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, see http://www.gnu.org/licenses/ */ package org.esa.beam.dataio.smos; import com.bc.ceres.binio.DataContext; import com.bc.ceres.binio.DataFormat; import com.bc.ceres.core.ProgressMonitor; import com.bc.ceres.core.VirtualDir; import org.esa.beam.dataio.smos.dddb.BandDescriptor; import org.esa.beam.dataio.smos.dddb.Dddb; import org.esa.beam.framework.dataio.AbstractProductReader; import org.esa.beam.framework.dataio.ProductReaderPlugIn; import org.esa.beam.framework.datamodel.Band; import org.esa.beam.framework.datamodel.Product; import org.esa.beam.framework.datamodel.ProductData; import org.esa.beam.smos.EEFilePair; import org.esa.beam.smos.SmosUtils; import org.esa.beam.smos.lsmask.SmosLsMask; import org.esa.beam.util.io.FileUtils; import java.awt.Rectangle; import java.awt.image.Raster; import java.awt.image.RenderedImage; import java.io.File; import java.io.IOException; import java.text.MessageFormat; public class SmosProductReader extends AbstractProductReader { private static final String LSMASK_SCHEMA_NAME = "DBL_SM_XXXX_AUX_LSMASK_0200"; private ProductFile productFile; private VirtualDir virtualDir; public ProductFile getProductFile() { return productFile; } public static ProductFile createProductFile(File file) throws IOException { if (file.isDirectory()) { final File[] files = file.listFiles(new ExplorerFilenameFilter()); if (files != null && files.length == 2) { file = files[0]; } } final ProductFile productFile = createProductFileImplementation(file); if (productFile == null) { throw new IOException(MessageFormat.format("File ''{0}'': unknown/unsupported SMOS data format.", file)); } return productFile; } private static ProductFile createProductFile(VirtualDir virtualDir) throws IOException { String listPath = ""; String[] list = virtualDir.list(listPath); if (list.length == 1) { listPath = list[0] + "/"; } list = virtualDir.list(listPath); String fileName = null; for (String listEntry : list) { if (listEntry.contains(".hdr") || listEntry.contains(".HDR")) { fileName = listEntry; break; } } if (fileName == null) { return null; } final File hdrFile = virtualDir.getFile(listPath + fileName); File dblFile = FileUtils.exchangeExtension(hdrFile, ".DBL"); dblFile = virtualDir.getFile(listPath + dblFile.getName()); return createProductFileImplementation(dblFile); } SmosProductReader(ProductReaderPlugIn readerPlugIn) { super(readerPlugIn); } @Override protected final Product readProductNodesImpl() throws IOException { synchronized (this) { final File inputFile = getInputFile(); final String inputFileName = inputFile.getName(); if (SmosUtils.isDblFileName( inputFileName) || (SmosUtils.isLightBufrTypeSupported() && SmosUtils.isLightBufrType( inputFileName))) { productFile = createProductFile(inputFile); } else { productFile = createProductFile(getInputVirtualDir()); } if (productFile == null) { throw new IOException( MessageFormat.format("File ''{0}'': unknown/unsupported SMOS data format.", inputFile)); } final Product product = productFile.createProduct(); if (virtualDir != null && virtualDir.isCompressed()) { final String path = virtualDir.getBasePath(); product.setFileLocation(new File(path)); } else { product.setFileLocation(productFile.getDataFile()); } if (productFile instanceof SmosFile) { addLandSeaMask(product); } return product; } } @Override protected final void readBandRasterDataImpl(int sourceOffsetX, int sourceOffsetY, int sourceWidth, int sourceHeight, int sourceStepX, int sourceStepY, Band targetBand, int targetOffsetX, int targetOffsetY, int targetWidth, int targetHeight, ProductData targetBuffer, ProgressMonitor pm) { synchronized (this) { final RenderedImage image = targetBand.getSourceImage(); final Raster data = image.getData(new Rectangle(targetOffsetX, targetOffsetY, targetWidth, targetHeight)); data.getDataElements(targetOffsetX, targetOffsetY, targetWidth, targetHeight, targetBuffer.getElems()); } } @Override public void close() throws IOException { synchronized (this) { productFile.close(); if (virtualDir != null) { virtualDir.close(); } super.close(); } } private File getInputFile() { final Object input = getInput(); if (input instanceof String) { return new File((String) input); } if (input instanceof File) { return (File) input; } throw new IllegalArgumentException(MessageFormat.format("Illegal input: {0}", input)); } private VirtualDir getInputVirtualDir() { File inputFile = getInputFile(); if (!SmosUtils.isCompressedFile(inputFile)) { inputFile = inputFile.getParentFile(); } virtualDir = VirtualDir.create(inputFile); if (virtualDir == null) { throw new IllegalArgumentException(MessageFormat.format("Illegal input: {0}", inputFile)); } return virtualDir; } private void addLandSeaMask(Product product) { final BandDescriptor descriptor = Dddb.getInstance().getBandDescriptors( LSMASK_SCHEMA_NAME).getMember(SmosConstants.LAND_SEA_MASK_NAME); final Band band = product.addBand(descriptor.getBandName(), ProductData.TYPE_UINT8); band.setScalingOffset(descriptor.getScalingOffset()); band.setScalingFactor(descriptor.getScalingFactor()); if (descriptor.hasFillValue()) { band.setNoDataValueUsed(true); band.setNoDataValue(descriptor.getFillValue()); } if (!descriptor.getValidPixelExpression().isEmpty()) { band.setValidPixelExpression(descriptor.getValidPixelExpression()); } if (!descriptor.getUnit().isEmpty()) { band.setUnit(descriptor.getUnit()); } if (!descriptor.getDescription().isEmpty()) { band.setDescription(descriptor.getDescription()); } if (descriptor.getFlagDescriptors() != null) { ProductHelper.addFlagsAndMasks(product, band, descriptor.getFlagCodingName(), descriptor.getFlagDescriptors()); } band.setSourceImage(SmosLsMask.getInstance().getMultiLevelImage()); band.setImageInfo(ProductHelper.createImageInfo(band, descriptor)); } private static ProductFile createProductFileImplementation(File file) throws IOException { if (SmosUtils.isLightBufrTypeSupported() && SmosUtils.isLightBufrType(file.getName())) { return new LightBufrFile(file); } final File hdrFile = FileUtils.exchangeExtension(file, ".HDR"); final File dblFile = FileUtils.exchangeExtension(file, ".DBL"); final DataFormat format = Dddb.getInstance().getDataFormat(hdrFile); if (format == null) { return null; } final EEFilePair eeFilePair = new EEFilePair(hdrFile, dblFile); final String formatName = format.getName(); final DataContext context = format.createContext(dblFile, "r"); if (SmosUtils.isBrowseFormat(formatName)) { return new L1cBrowseSmosFile(eeFilePair, context); } else if (SmosUtils.isDualPolScienceFormat(formatName) || SmosUtils.isFullPolScienceFormat(formatName)) { return new L1cScienceSmosFile(eeFilePair, context); } else if (SmosUtils.isSmUserFormat(formatName)) { return new SmUserSmosFile(eeFilePair, context); } else if (SmosUtils.isOsUserFormat(formatName) || SmosUtils.isOsAnalysisFormat(formatName) || SmosUtils.isSmAnalysisFormat(formatName) || SmosUtils.isAuxECMWFType(formatName)) { return new SmosFile(eeFilePair, context); } else if (SmosUtils.isDffLaiFormat(formatName)) { return new LaiFile(eeFilePair, context); } else if (SmosUtils.isVTecFormat(formatName)) { return new VTecFile(eeFilePair, context); } else if (SmosUtils.isLsMaskFormat(formatName)) { return new GlobalSmosFile(eeFilePair, context); } else if (SmosUtils.isDggFloFormat(formatName) || SmosUtils.isDggRfiFormat(formatName) || SmosUtils.isDggRouFormat(formatName) || SmosUtils.isDggTfoFormat(formatName) || SmosUtils.isDggTlvFormat(formatName)) { return new AuxiliaryFile(eeFilePair, context); } return null; } }