001 /** 002 * 003 */ 004 package org.wdssii.core; 005 006 import java.io.File; 007 import java.io.FileWriter; 008 import java.io.IOException; 009 import java.io.PrintWriter; 010 import java.text.DecimalFormat; 011 import java.text.NumberFormat; 012 import java.text.SimpleDateFormat; 013 import java.util.Date; 014 015 import org.apache.commons.logging.Log; 016 import org.apache.commons.logging.LogFactory; 017 018 /** 019 * @author lakshman 020 * 021 */ 022 public abstract class DataEncoder { 023 private static Log log = LogFactory.getLog(DataEncoder.class); 024 private float sparseGridThreshold = 0.75f; 025 private boolean compressionEnabled = false; 026 027 protected DataEncoder(){ 028 } 029 030 public float getSparseGridThreshold() { 031 return sparseGridThreshold; 032 } 033 public boolean isAlwaysSparseGrid(){ 034 return (sparseGridThreshold <= 0); 035 } 036 public boolean isNeverSparseGrid(){ 037 return (sparseGridThreshold >= 1); 038 } 039 public void setSparseGridThreshold(String sparseGridThreshold) { 040 if ( sparseGridThreshold != null && sparseGridThreshold.length() > 0 ){ 041 if (sparseGridThreshold.equals("never")){ 042 this.sparseGridThreshold = 2; 043 } else if ( sparseGridThreshold.equals("always") ){ 044 this.sparseGridThreshold = -1; 045 } else { 046 this.sparseGridThreshold = Float.parseFloat(sparseGridThreshold); 047 } 048 } 049 if ( log.isInfoEnabled() ){ 050 log.info("Sparsegridthreshold=" + this.sparseGridThreshold); 051 } 052 } 053 public boolean isCompressionEnabled() { 054 return compressionEnabled; 055 } 056 public void setCompressionEnabled(boolean compression) { 057 this.compressionEnabled = compression; 058 } 059 public void setCompressionEnabled(String compression) { 060 if ( compression != null ){ 061 boolean c = compression.equals("yes") || compression.equals("true"); 062 this.compressionEnabled = c; 063 } 064 } 065 066 public static void writeDataAndNotify(DataType dt, String outputDir, String subtype){ 067 if (subtype == null || subtype.length() == 0){ 068 writeDataAndNotify(dt, outputDir); // use default subtype 069 } else { 070 writeDataAndNotify(dt, outputDir, new String[]{subtype} ); 071 } 072 } 073 074 /** Uses default subtype for product */ 075 public static void writeDataAndNotify(DataType dt, String outputDir){ 076 String subtype = (String) dt.getAttribute("SubType"); 077 if (subtype == null || subtype.length() == 0 ){ 078 if ( dt instanceof PolarGrid ){ 079 PolarGrid grid = (PolarGrid) dt; 080 NumberFormat nf = new DecimalFormat("00.00"); 081 subtype = nf.format( grid.getElevation() ); 082 } else { 083 NumberFormat nf = new DecimalFormat("00.000"); 084 subtype = nf.format(dt.getLocation().getHeightKms()); 085 } 086 } 087 writeDataAndNotify(dt, outputDir, subtype); 088 } 089 090 /** The method to use **/ 091 public static void writeDataAndNotify(DataType dt, String outputDir, String[] subtypes){ 092 DataEncoder encoder = DataEncoderFactory.getInstance().getEncoder(dt); 093 if ( dt instanceof PolarGrid ){ 094 encoder.writeAndNotify( (PolarGrid) dt, outputDir, subtypes); 095 } else if ( dt instanceof LatLonGrid ) { 096 encoder.writeAndNotify( (LatLonGrid) dt, outputDir, subtypes); 097 } else if ( dt instanceof DataTable ){ 098 encoder.writeAndNotify( (DataTable) dt, outputDir, subtypes); 099 } else { 100 log.warn("No encoder implemented to write object of type " + dt.getClass()); 101 } 102 } 103 104 /** Computes sparse grid ratio if necessary to decide whether to write sparse */ 105 protected boolean shouldWriteSparse(float[][] values, float background) { 106 if ( this.isAlwaysSparseGrid() ){ 107 return true; 108 } else if ( this.isNeverSparseGrid() ){ 109 return false; 110 } else { 111 float ratio = NetcdfSparseGrid.computeSparseGridRatio(values,background); 112 return (ratio > this.getSparseGridThreshold()); 113 } 114 } 115 116 protected void notifyRecord(DataType dt, String outputDir, 117 String[] subtypes, String formattedDate, String relativeFileName) 118 throws IOException { 119 PrintWriter writer = null; 120 try { 121 String famDir = outputDir + "/code_index.fam/"; 122 new File(famDir).mkdirs(); 123 String[] params = getParams(relativeFileName); 124 for (String subtype : subtypes) { 125 String[] selections = new String[] { formattedDate, 126 dt.getTypeName(), subtype }; 127 IndexRecord rec = new IndexRecord(dt.getTime(), selections, 128 params); 129 String notifyName = new StringBuilder(famDir).append( 130 dt.getTypeName()).append('_').append(subtype).append( 131 '_').append(formattedDate).toString(); 132 writer = new PrintWriter(new FileWriter(notifyName)); 133 writer.println(rec.toXMLString()); 134 writer.close(); 135 } 136 } finally { 137 if (writer != null) { 138 writer.close(); 139 } 140 } 141 } 142 143 protected static String getFormattedDate(DataType dt) { 144 return getFormattedDate(dt.getTime()); 145 } 146 147 public static String getFormattedDate(Date time) { 148 SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd-HHmmss"); 149 String formatted = sdf.format(time); 150 return formatted; 151 } 152 153 154 protected abstract String[] getParams(String relativeFileName); 155 protected abstract void writeAndNotify(PolarGrid dt, String outputDir, String[] subtypes); 156 protected abstract void writeAndNotify(LatLonGrid dt, String outputDir, String[] subtypes); 157 protected abstract void writeAndNotify(DataTable dt, String outputDir, String[] subtypes); 158 }