001/*
002 * $Id: HDFHydraDataSource.java,v 1.10 2011/03/24 16:06:33 davep Exp $
003 *
004 * This file is part of McIDAS-V
005 *
006 * Copyright 2007-2011
007 * Space Science and Engineering Center (SSEC)
008 * University of Wisconsin - Madison
009 * 1225 W. Dayton Street, Madison, WI 53706, USA
010 * https://www.ssec.wisc.edu/mcidas
011 * 
012 * All Rights Reserved
013 * 
014 * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and
015 * some McIDAS-V source code is based on IDV and VisAD source code.  
016 * 
017 * McIDAS-V is free software; you can redistribute it and/or modify
018 * it under the terms of the GNU Lesser Public License as published by
019 * the Free Software Foundation; either version 3 of the License, or
020 * (at your option) any later version.
021 * 
022 * McIDAS-V is distributed in the hope that it will be useful,
023 * but WITHOUT ANY WARRANTY; without even the implied warranty of
024 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
025 * GNU Lesser Public License for more details.
026 * 
027 * You should have received a copy of the GNU Lesser Public License
028 * along with this program.  If not, see http://www.gnu.org/licenses.
029 */
030
031package edu.wisc.ssec.mcidasv.data.hydra;
032
033import edu.wisc.ssec.mcidasv.data.HydraDataSource;
034
035import java.rmi.RemoteException;
036
037import java.util.ArrayList;
038import java.util.HashMap;
039import java.util.Hashtable;
040import java.util.List;
041
042import ucar.unidata.data.DataCategory;
043import ucar.unidata.data.DataChoice;
044import ucar.unidata.data.DataSelection;
045import ucar.unidata.data.DataSourceDescriptor;
046import ucar.unidata.data.DirectDataChoice;
047
048import ucar.unidata.util.Misc;
049
050import visad.Data;
051import visad.VisADException;
052
053
054/**
055 * A data source for HYDRA hdf data
056 */
057public class HDFHydraDataSource extends HydraDataSource {
058
059    /** Sources file */
060    protected String filename;
061
062    /** list of data sets */
063    protected List sdsList;
064
065    private static final String DATA_DESCRIPTION = "Hydra hdf data";
066
067    private HDF4File reader;
068
069    /**
070     * Zero-argument constructor for construction via unpersistence.
071     */
072    public HDFHydraDataSource() {}
073
074    /**
075     * Construct a new HYDRA hdf data source.
076     * @param  descriptor  descriptor for this <code>DataSource</code>
077     * @param  fileName  name of the hdf file to read
078     * @param  properties  hashtable of properties
079     *
080     * @throws VisADException problem creating data
081     */
082    public HDFHydraDataSource(DataSourceDescriptor descriptor,
083                                 String fileName, Hashtable properties)
084            throws VisADException {
085        this(descriptor, Misc.newList(fileName), properties);
086/*
087        System.out.println("HDFHydraDataSource:");
088        System.out.println("   descriptor=" + descriptor); 
089        System.out.println("   fileName=" + fileName); 
090        System.out.println("   properties=" + properties); 
091*/
092    }
093
094    /**
095     * Construct a new HYDRA hdf data source.
096     * @param  descriptor  descriptor for this <code>DataSource</code>
097     * @param  sources   List of filenames
098     * @param  properties  hashtable of properties
099     *
100     * @throws VisADException problem creating data
101     */
102    public HDFHydraDataSource(DataSourceDescriptor descriptor,
103                                 List newSources, Hashtable properties)
104            throws VisADException {
105        super(descriptor, newSources, DATA_DESCRIPTION, properties);
106/*
107        System.out.println("HDFHydraDataSource:");
108        System.out.println("   descriptor=" + descriptor); 
109        System.out.println("   newSources=" + newSources); 
110        System.out.println("   properties=" + properties);
111*/
112        this.filename = (String)sources.get(0);
113        setSDSList(makeSdsDescriptors(filename));
114    }
115
116
117    /**
118     * Set the list of SDS descriptors 
119     * source.
120     *
121     * @param l The list of image descriptors.
122     */
123    private void setSDSList(List l) {
124        this.sdsList = l;
125    }
126
127    /**
128     * Get the list of SDS descriptors 
129     *
130     * @param l The list of image descriptors.
131     */
132    public List  getSDSList() {
133        return sdsList;
134    }
135
136    /**
137     * Make a list of sds descriptors
138     *
139     * @param fileName  Name of hdf file
140     *
141     * @return List of sds descriptors
142     */
143    private List makeSdsDescriptors(String fileName) {
144        List descriptors = new ArrayList();
145        try {
146            reader = new HDF4File(fileName);
147            HDFFile hf = reader.hdf;
148            int numSD = hf.getNumberSDdatasets();
149/*
150            System.out.println("number of datasets=" + numSD);
151            System.out.println("number of globalAttrs=" + hf.num_globalAttrs);
152*/
153            HDFVariable var = null;
154            for (int idx=0; idx<numSD; idx++) {
155                var = hf.select(idx);
156                HDFVariableInfo info = var.getinfo();
157                descriptors.add(info.var_name);
158/*
159                System.out.print(info.var_name);
160                System.out.print("   dimensions=");
161                int[] lens = info.dim_lengths;
162                for (int k=0;k<info.rank;k++) System.out.print(lens[k]+" ");
163                System.out.println("");
164*/
165            }
166/*
167            System.out.println(" ");
168            HDFAttribute attr = null;
169            for (int idx=0; idx<hf.num_globalAttrs; idx++) {
170                attr = hf.readattr(idx);
171                System.out.println(attr);
172                System.out.println("   class=" + attr.type);
173            }
174*/
175        } catch (Exception e) {
176            System.out.println("makeSdsDescriptors e=" + e);
177        }
178//        System.out.println("");
179        return descriptors;
180    }
181
182
183    /**
184     * Make and insert the <code>DataChoice</code>-s for this
185     * <code>DataSource</code>.
186     */
187    public void doMakeDataChoices() {
188        DataChoice choice;
189        for (int idx=0; idx<sdsList.size(); idx++) {
190            choice = doMakeDataChoice(idx, (String)sdsList.get(idx));
191            addDataChoice(choice);
192        }
193    }
194
195    private DataChoice doMakeDataChoice(int idx, String var) {
196        List categories = DataCategory.parseCategories("2D grid;GRID-2D;");
197        String name = var;
198        DataSelection dataSel = new DataSelection(Misc.newList(new Integer(idx)));
199        DirectDataChoice ddc = new DirectDataChoice(this, idx, name, name,
200            categories, dataSel);
201        return ddc;
202    }
203
204    /**
205     * Check to see if this <code>HDFHydraDataSource</code> is equal to the object
206     * in question.
207     * @param o  object in question
208     * @return true if they are the same or equivalent objects
209     */
210    public boolean equals(Object o) {
211        if ( !(o instanceof HDFHydraDataSource)) {
212            return false;
213        }
214        return (this == (HDFHydraDataSource) o);
215    }
216
217
218
219    protected Data getDataInner(DataChoice dataChoice, DataCategory category,
220                                DataSelection dataSelection, Hashtable requestProperties)
221                                throws VisADException, RemoteException {
222/*
223        System.out.println("McIdasXDataSource getDataInner:");
224        System.out.println("   dataChoice=" + dataChoice);
225        System.out.println("   category=" + category);
226        System.out.println("   dataSelection=" + dataSelection);
227        System.out.println("   requestProperties=" + requestProperties);
228*/
229        HashMap table = SwathAdapter.getEmptyMetadataTable();
230
231        table.put("array_name", "Optical_Depth_Land_And_Ocean");
232        table.put("lon_array_name", "Longitude");
233        table.put("lat_array_name", "Latitude");
234        table.put("XTrack", "Cell_Across_Swath:mod04");
235        table.put("Track", "Cell_Along_Swath:mod04");
236        table.put("geo_Track", "Cell_Along_Swath:mod04");
237        table.put("geo_XTrack", "Cell_Across_Swath:mod04");
238        table.put("scale_name", "scale_factor");
239        table.put("offset_name", "add_offset");
240        table.put("fill_value_name", "_FillValue");
241/*
242        table.put("array_name", "Cloud_Optical_Thickness");
243        table.put("lon_array_name", "Longitude");
244        table.put("lat_array_name", "Latitude");
245        table.put("XTrack", "Cell_Across_Swath_1km:mod06");
246        table.put("Track", "Cell_Along_Swath_1km:mod06");
247        table.put("geo_Track", "Cell_Along_Swath_5km:mod06");
248        table.put("geo_XTrack", "Cell_Across_Swath_5km:mod06");
249        table.put("scale_name", "scale_factor");
250        table.put("offset_name", "add_offset");
251        table.put("fill_value_name", "_FillValue");
252*/
253
254        SwathAdapter swath = new SwathAdapter(reader, table);
255        HashMap subset = SwathAdapter.getEmptySubset();
256
257        double[] coords = (double[])subset.get("Track");
258        coords[0] = 0.0;
259        coords[1] = 202.0;
260        //coords[1] = 2029.0;
261        coords[2] = 1.0;
262        subset.put("Track", coords);
263
264        coords = (double[])subset.get("XTrack");
265        coords[0] = 0.0;
266        coords[1] = 134.0;
267        //coords[1] = 1353.0;
268        coords[2] = 1.0;
269        subset.put("XTrack", coords);
270
271        Data data = null;
272        try {
273            data = swath.getData(subset);
274           
275        } catch (Exception e) {
276            System.out.println("getData exception e=" + e);
277        }
278        return data;
279    }
280}
281