Channel.java [src/java/m/weppws] Revision: default  Date:
package m.weppws;

import java.util.List;
import csip.api.server.ServiceException;
import csip.SessionLogger;
import java.util.Arrays;
import java.util.Iterator;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import org.codehaus.jettison.json.JSONArray;
import util.Grid;
import util.WeppConstants;

/**
 * Represents a WEPP and TauDEM channel.
 *
 */
public class Channel {

  int id;
  int topazid;
  int order;
  int downstream;
  int upstream1;
  int upstream2;
  Flowpath flowpath;
  int majorSoil;
  int majorLanduse;
  int cells;
  V1_0 par;
  int startRow;
  int startCol;
  double area;
  double width;
  Channel leftChannel;  // channel that drains into this channel from left, 
  Channel rightChannel;  // channel that drains into this channel from right
  Channel topChannel;   // channel that drains into this channel from top
  Impoundment leftImpoundment; // impoundment that drains into this channel from left
  Impoundment rightImpoundment; // impoundment that drains into this channel from right
  Impoundment topImpoundment; // impoundment that drains into this channel from top
  Subcatchment hillslope;   
  int weppID;
  boolean inUse;
  
  JSONObject userParameters;
  String def;

  double length;
  double discharge;
  double sedYield;
  double loss; // soil loss from bottom and sidewalls

  Channel(int id, int downs, int up1, int up2, int order, V1_0 par) {
    this.id = id;
    downstream = downs;
    upstream1 = up1;
    upstream2 = up2;
    majorSoil = 0;
    majorLanduse = 0;
    this.par = par;
    width = 1;
    this.order = order;
    startRow = -1;
    startCol = -1;
    discharge = 0;
    sedYield = 0;
    flowpath = null;
    inUse = true;
    loss = 0;
  }

  String summarizeInput() throws JSONException {
    JSONObject so = new JSONObject();
    so.put("id", id);
    so.put("weppID", weppID);
    so.put("topazid", topazid);
    so.put("upstream1", upstream1);
    so.put("upstream2", upstream2);
    so.put("downstream", downstream);
    so.put("Length (ft)", 0);
    so.put("Grid cells", cells);
    so.put("Major Soil", par.soilIndexToShortName(majorSoil));
    so.put("Major Soil id", majorSoil);
    so.put("Major Landuse", par.manIndexToShortName(majorLanduse));
    so.put("Major Landuse id", majorLanduse);
    so.put("Channel Start Row", startRow);
    so.put("Channel Start Col", startCol);
    return so.toString(2);
  }


  String summarizeOutput(SessionLogger log) throws JSONException {
    JSONObject so = new JSONObject();
    so.put("id", id);
    so.put("weppID", weppID);
    so.put("topazid", topazid);
    so.put("Order", order);
    
    if (userParameters != null) {
        so.put("Channel Parameter Set: ", userParameters.optString("def",par.getChannelName(order)));
    } else {
        so.put("Channel Parameter Set: ", par.getChannelName(order));
    }

    if (flowpath != null) {
      so.put("Length (ft)", Float.valueOf(String.format("%.0f", flowpath.totalLengthMeters * WeppConstants.CONV_M_TO_FT)));
      so.put("Width (ft)", Float.valueOf(String.format("%.0f", width * WeppConstants.CONV_M_TO_FT)));
    } else {
      so.put("Length (ft)", 0);
      so.put("Width (ft)", 0);
    }
    so.put("Grid cells", cells);
    so.put("Major Soil", par.soilIndexToShortName(majorSoil));
    so.put("Major Soil id", majorSoil);
    so.put("Major Landuse", par.manIndexToShortName(majorLanduse));
    so.put("Major Landuse id", majorLanduse);
    so.put("Runoff Volume (ft^3/yr)", Float.valueOf(String.format("%.0f", discharge)));
    so.put("Sediment Yield (ton/yr)", Float.valueOf(String.format("%.2f", sedYield)));
    so.put("Soil Loss(ton/yr)", Float.valueOf(String.format("%.2f", loss)));
    return so.toString(2);
  }


  void addStart(int r, int c) {
    startRow = r;
    startCol = c;
  }


  void addFlowpath(List<Integer> rows, List<Integer> cols, List<Float> slp,
      List<Integer> man, List<Integer> soil, List<Float> dist) {
    int r[] = new int[rows.size()];
    int c[] = new int[cols.size()];
    float sl[] = new float[slp.size()];
    int s[] = new int[soil.size()];
    int m[] = new int[man.size()];
    float d[] = new float[dist.size()];

    for (int i = 0; i < rows.size(); i++) {
      r[i] = rows.get(i);
      c[i] = cols.get(i);
      sl[i] = slp.get(i);
      s[i] = soil.get(i);
      m[i] = man.get(i);
      d[i] = dist.get(i);
    }
    flowpath = new Flowpath(1, r, c, sl, m, s, d, par, -1, -1, id);
  }


  String printProfile() {
    if (flowpath != null) {
      return flowpath.printProfile(width);
    } else {
      return virtualFlowpath(width);
    }
  }


  void setMajorSoil(int val) {
    majorSoil = val;
  }


  void setMajorLanduse(int val) {
    majorLanduse = val;
  }


  void calcArea() {
    if (flowpath != null) {
      cells = flowpath.rows.length;
      area = (cells * width * width) / 10000; // total area in ha of channel only
    } else {
      area = 0;
    }
  }


  void setHillslope(Subcatchment s) {
    hillslope = s;
    hillslope.setInuse(true);
    hillslope.setOrder(order);
  }

  String getLeftHillslope() {
    if (hillslope.leftsub == null) {
      return "0";
    } else {
      if (inUse) {
          if (leftImpoundment == null) {
            return "H" + String.valueOf(hillslope.leftsub.weppAltID);
          } else {
            return ("0");
        }
      } else {
          return "0";
      }
    }
  }


  String getRightHillslope() {
    if (hillslope.rightsub == null) {
      return "0";
    } else {
      if (inUse) {
         if (rightImpoundment == null) {
            return "H" + String.valueOf(hillslope.rightsub.weppAltID);
         } else {
            return ("0");
         }
      } else {
          return "0";
      }
    }
  }


  String getTopHillslope() {
    if (hillslope.topsub == null) {
      return "0";
    } else {
      if (inUse) {
         if (topImpoundment == null) {
            return "H" + String.valueOf(hillslope.topsub.weppAltID);
         } else {
            return ("0");
         }
      } else {
         return "0";
      }
    }
  }

  String getHillslope() {
    if (hillslope == null) {
      return "0";
    } else {
      if (hillslope.getInuse()) {
        if ((leftImpoundment == null) && (rightImpoundment == null)) {
           return "H" + String.valueOf(hillslope.weppid);
        } else {
            return "0";
        }
      } else {
        return "0";
      }
    }
  }

  String getLeftChannel() {
        if (leftChannel == null) {
            return "0";
        } else {
            if (par.aoi.getImpoundmentAfterChannel(leftChannel.id) == 0) {
                return "C" + String.valueOf(leftChannel.weppID);
            } else {
                return "0";
            }
        }
  }


  String getRightChannel() {
        if (rightChannel == null) {
            return "0" ;
        } else {
            if (par.aoi.getImpoundmentAfterChannel(rightChannel.id) == 0) {
                return "C" + String.valueOf(rightChannel.weppID);
            } else {
                return "0";
            }
        }
   }


  String getTopChannel() {
         if (topChannel == null) {
           return "0";
       } else {
           if (par.aoi.getImpoundmentAfterChannel(topChannel.id) == 0) {
               return "C" + String.valueOf(topChannel.weppID);
            } else {
               return "0";
            }
       }
    }


  String getLeftImpoundment() {
    int possibleImp;
    
    if (leftChannel == null) {
        possibleImp = 0;
    } else {
        possibleImp = par.aoi.getImpoundmentWeppIDAfterChannel(leftChannel.id);
    }
    
    if (possibleImp == 0) {  
       return (leftImpoundment == null) ? "0" : ("I" + String.valueOf(leftImpoundment.weppID));
    } else {
        return ("I" + String.valueOf(possibleImp));
    }
  }


  String getRightImpoundment() {
    int possibleImp;
    
    if (rightChannel == null) {
        possibleImp = 0;
    } else {
        possibleImp = par.aoi.getImpoundmentWeppIDAfterChannel(rightChannel.id);
    }
 
    
    if (possibleImp == 0) {  
      return (rightImpoundment == null) ? "0" : ("I" + String.valueOf(rightImpoundment.weppID));
    } else {
      return ("I" + String.valueOf(possibleImp));
    }
  }


  String getTopImpoundment() {
    int possibleImp;
     
    if (topChannel == null) {
        possibleImp = 0;
    } else {
        possibleImp = par.aoi.getImpoundmentWeppIDAfterChannel(topChannel.id);
    }
    
    if (possibleImp == 0) {  
      return (topImpoundment == null) ? "0" : ("I" + String.valueOf(topImpoundment.weppID));
    } else {
      return ("I" + String.valueOf(possibleImp));
    }
  }


  int getPrevDir(int chnEndRow, int chnEndCol) {
    int prev = 0;
    try {
      prev = flowpath.getPrevDir(chnEndRow, chnEndCol);
    } catch (ServiceException ex) {
      prev = 0;
    }
    return prev;
  }


  protected String virtualFlowpath(double slopeWidth) {
    double slopeAspect = 180;

    StringBuilder output = new StringBuilder();
    output.append(slopeAspect);
    output.append(' ');
    output.append(slopeWidth);
    output.append('\n');
    output.append("2 0.01\n");

    // only two points
    output.append(String.format("0.0 %.3f, ", 0.01));
    output.append(String.format("1.0 %.3f\n", 0.01));

    return output.toString();
  }
  
  void setWeppID(int val) {
      weppID = val;
  }
  
  boolean getInuse() {
      return inUse;
  }
  
  void setInuse(boolean val) {
      inUse = val;
  }
  
  void setTopazID(SessionLogger log,int val) throws ServiceException {
      topazid = val;
      if (hillslope != null) {
          hillslope.setTopazID(val-4);
      } else {
         throw new ServiceException("Could not set topaz id for hillslope on channel:" + id + " with topaz id: " + val);
      }
  }
  
   int fillsub3grid(Grid sub3) throws ServiceException {
     int cellsFilled = 0;
     
     cellsFilled = flowpath.fillsub3gridChannel(sub3,topazid);  
  
     return cellsFilled; 
  }
   
    void updateParameters(JSONObject chdata) throws JSONException {
        List<String> ckeysStrs = Arrays.asList("comment","management","def");
        List<String> ckeysInts = Arrays.asList("ishape","icntrl","ienslp","flgout","width");
        List<String> ckeysDbl = Arrays.asList("chnz","chnnbr","chnn","chnk","chntcr",
         "chnedm","chneds","ctlslp","ctlz","ctln","rccoeff","rcexp","rcoset");
   
        userParameters = new JSONObject();
        Iterator it = chdata.keys();    
        while (it.hasNext()) { 
            String pname = it.next().toString();
            if (ckeysStrs.contains(pname)) {        
                   userParameters.put(pname,chdata.getString(pname));
            } else if (ckeysInts.contains(pname)) {
                   userParameters.put(pname,chdata.getInt(pname));
            } else if (ckeysDbl.contains(pname)) {
                   userParameters.put(pname,chdata.getDouble(pname));
            }
        }
        
        if (userParameters.has("width")) {
           width = userParameters.getDouble("width");
        }
        if (userParameters.has("def")) {
           def = userParameters.getString("def");
        } else {
           def = par.getChannelName(order);
        }        
  }
    
  void writeUserParameters(StringBuilder output, double defaultWidth, String defaultDef) throws JSONException {
        if (userParameters != null) {
            output.append("  Width = " + userParameters.optDouble("width", defaultWidth) + "\n");
            output.append("  Definition = \"" + userParameters.optString("def", defaultDef) + "\"\n");
            if (userParameters.optString("management","").equals("")) { 
               
            } else {
                output.append("  Management = \"" + par.manNameToRot(userParameters.optString("management", "")) + "\"\n");
            }
        } else {
            output.append("  Width = " + defaultWidth + "\n");
            output.append("  Definition = \"" + defaultDef + "\"\n");
        }
        
  }
  
   boolean usesChannelParms(String id) {
     
      if (def == null) {
        def = par.getChannelName(order);
      }
     
      if (def.equals(id)) {
         return true;
      } else {
         return false;
      }
  }
   
  boolean usesImpoundmentParms(String id, SessionLogger log) {
      if (!getLeftImpoundment().equals("0")) {
          String name = getLeftImpoundment();
          log.info("channel impound name left: " + name);
          if (leftImpoundment.name.equals(id)) {
              return true;
          }
      }
      if (!getRightImpoundment().equals("0")) {
          String name = getRightImpoundment();
           log.info("channel impound name right: " + name);
          if (rightImpoundment.name.equals(id)) {
              return true;
          }
      }
      if (!getTopImpoundment().equals("0")) {
           String name = getTopImpoundment();
           log.info("channel impound name top: " + name);
          if (topImpoundment.name.equals(id)) {
              return true;
          }
      }
      return false;
  }
   
   void setLeftImpoundment(Impoundment imp) {
       leftImpoundment = imp;
   }
   
   void setRightImpoundment(Impoundment imp) {
       rightImpoundment = imp;
   }
  
   void setTopImpoundment(Impoundment imp) {
       topImpoundment = imp;
   }
}