# ******************************************************
## Revision "$LastChangedDate: 2014-01-26 12:25:00 +0100 (Sun, 26 Jan 2014) $"
## Date "$LastChangedRevision: 456 $"
## Author "$LastChangedBy: arthurbeusen $"
## URL "$HeadURL: https://pbl.sliksvn.com/globalnutrients/P_model/trunk/tools/pmouth.py $"
# ******************************************************

import ascraster
import my_sys
import write_dict
import mouth

class PMouth(mouth.Mouth):
    '''Derived phosphor parameter values of river basin map'''
    def __init__(self,basinid=-9999,lat=-9999,lon=-9999,index_grid=-1,retention=-1,qs = -9999.):
        self.basinid = int(basinid)
        self.lat = float(lat)
        self.lon = float(lon)
        self.index_grid = int(index_grid)
        self.index_grid_full = 0
        self.number_of_cells = 0
        self.retention = float(retention)
        self.qs = float(qs)
        self.minreduction = 0.0
        self.maxreduction = 0.0
        self.landarea = 0.0
        self.grasarea = 0.0
        self.croparea = 0.0
        self.natarea = 0.0
        self.waterarea = 0.0
        self.wetland_area = 0.0
        self.flooding_area = 0.0
        self.discharge_mouth = 0.0
        self.pbudget = 0.0
	self.psro = 0.0
        self.psro_arable = 0.0
        self.psro_grs = 0.0
        self.p_erosion_arable = 0.0
        self.p_erosion_grass = 0.0
        self.p_erosion_nat = 0.0
        self.p_erosion = 0.0
        self.pbackground = 0.0
        self.ptotal_diffuse = 0.0
        self.ppoint = 0.0
        self.p_gnpp = 0.0
        self.p_wetland_in = 0.0
        self.p_wetland_out = 0.0
        self.p_aquaculture = 0.0
        self.pload_river = 0.0
        self.subgrid_load = 0.0
        self.retentionload_subgrid = 0.0
        self.retention_subgrid = 0.0
        self.pload_mouth = 0.0
        self.pconc_mouth = 0.0
        self.avg_traveltime = 0.0
        self.avg_Ptraveltime = 0.0 
        self.avg_Ptemperature = 0.0
        self.avg_Phydraulic_load  = 0.0
        self.number_of_lakes = 0
        self.lakes_water_area = 0.0
        self.lakes_volume = 0.0
        self.lakes_retention_load = 0.0
        self.fr_lakes_retention = 0.0
        self.lakes_load_in = 0.0
        self.lakes_load_out = 0.0
        self.lakes_retention = 0.0
        self.number_of_reserv = 0
        self.reserv_water_area = 0.0
        self.reserv_volume = 0.0
        self.reserv_retention_load = 0.0
        self.fr_reserv_retention = 0.0
        self.reserv_load_in = 0.0
        self.reserv_load_out = 0.0
        self.reserv_retention = 0.0
    
    def write_header(self,fp, sep=" "):
        '''
        Write the header that belongs to the function write (see below) to the file which has filepointer fp.
        '''
        fp.write(str("basinid") + sep +\
              str("lon") + sep +\
              str("lat") + sep +\
              str("landarea") + sep +\
              str("grasarea") + sep +\
              str("croparea") + sep +\
              str("natarea") + sep +\
              str("waterarea") + sep +\
              str("wetland_area") + sep +\
              str("flooding_area") + sep +\
              str("discharge_mouth") + sep +\
              str("qs") + sep +\
              str("pbudget") + sep +\
              str("psro") + sep +\
              str("psro_arable") + sep +\
              str("psro_grs") + sep +\
              str("p_erosion_arable") + sep +\
	      str("p_erosion_grass") + sep +\
	      str("p_erosion_nat") + sep +\
              str("p_erosion") + sep +\
              str("pbackground") + sep +\
              str("ptotal_diffuse") + sep +\
              str("ppoint") + sep +\
              str("p_gnpp") + sep +\
              str("p_wetland_in") + sep +\
              str("p_wetland_out") + sep +\
              str("p_aquaculture") + sep +\
              str("pload_river") + sep +\
              str("subgrid_load") + sep +\
              str("retentionload_subgrid") + sep +\
              str("retention_subgrid") + sep +\
              str("pretention") + sep +\
              str("pload_mouth") + sep +\
              str("pconc_mouth") + sep +\
              str("number_of_cells") + sep +\
              str("avg_traveltime") + sep +\
              str("avg_Ptraveltime") + sep +\
              str("avg_Ptemperature") + sep +\
              str("avg_Phydraulic_load") + sep +\
              str("number_of_lakes") + sep +\
              str("lakes_water_area") + sep +\
              str("lakes_volume") + sep +\
              str("lakes_retention_load") + sep +\
              str("fr_lakes_retention") + sep +\
              str("lakes_load_in") + sep +\
              str("lakes_load_out") + sep +\
              str("lakes_retention") + sep +\
              str("number_of_reserv") + sep +\
              str("reserv_water_area") + sep +\
              str("reserv_volume") + sep +\
              str("reserv_retention_load") + sep +\
              str("fr_reserv_retention") + sep +\
              str("reserv_load_in") + sep +\
              str("reserv_load_out") + sep +\
              str("reserv_retention") +\
              "\n")

    def write(self,fp, sep=" "):
        '''
        Write this class to file which has filepointer fp.
        '''

        fp.write(str(self.basinid) + sep +\
              str(self.lon) + sep +\
              str(self.lat) + sep +\
              str(self.landarea) + sep +\
              str(self.grasarea) + sep +\
              str(self.croparea) + sep +\
              str(self.natarea) + sep +\
              str(self.waterarea) + sep +\
              str(self.wetland_area) + sep +\
              str(self.flooding_area) + sep +\
              str(self.discharge_mouth) + sep +\
              str(self.qs) + sep +\
              str(self.pbudget) + sep +\
              str(self.psro) + sep +\
              str(self.psro_arable) + sep +\
              str(self.psro_grs) + sep +\
              str(self.p_erosion_arable) + sep +\
	      str(self.p_erosion_grass) + sep +\
	      str(self.p_erosion_nat) + sep +\
              str(self.p_erosion) + sep +\
              str(self.pbackground) + sep +\
              str(self.ptotal_diffuse) + sep +\
              str(self.ppoint) + sep +\
              str(self.p_gnpp) + sep +\
              str(self.p_wetland_in) + sep +\
              str(self.p_wetland_out) + sep +\
              str(self.p_aquaculture) + sep +\
              str(self.pload_river) + sep +\
              str(self.subgrid_load) + sep +\
              str(self.retentionload_subgrid) + sep +\
              str(self.retention_subgrid) + sep +\
              str(self.retention) + sep +\
              str(self.pload_mouth) + sep +\
              str(self.pconc_mouth) + sep +\
              str(self.number_of_cells) + sep +\
              str(self.avg_traveltime) + sep +\
              str(self.avg_Ptraveltime) + sep +\
              str(self.avg_Ptemperature) + sep +\
              str(self.avg_Phydraulic_load) + sep +\
              str(self.number_of_lakes) + sep +\
              str(self.lakes_water_area) + sep +\
              str(self.lakes_volume) + sep +\
              str(self.lakes_retention_load) + sep +\
              str(self.fr_lakes_retention) + sep +\
              str(self.lakes_load_in) + sep +\
              str(self.lakes_load_out) + sep +\
              str(self.lakes_retention) + sep +\
              str(self.number_of_reserv) + sep +\
              str(self.reserv_water_area) + sep +\
              str(self.reserv_volume) + sep +\
              str(self.reserv_retention_load) + sep +\
              str(self.fr_reserv_retention) + sep +\
              str(self.reserv_load_in) + sep +\
              str(self.reserv_load_out) + sep +\
              str(self.reserv_retention) +\
              "\n")

        
    def sum(self,m):
        '''
        Aggregation of several parameters of this class 
        '''
        # Set basic data on nodata
        self.basinid = "Total"
        self.lat = -9999.
        self.lon = -9999.
        self.index_grid = -9999.
        self.index_grid_full = -9999.
        self.minreduction = -9999.
        self.maxreduction = -9999.

        # Make aggregation
        self.number_of_cells += m.number_of_cells
        self.landarea  += m.landarea
        self.grasarea  += m.grasarea
        self.croparea  += m.croparea
        self.natarea   += m.natarea
        self.waterarea += m.waterarea
        self.wetland_area    += m.wetland_area
        self.flooding_area   += m.flooding_area
        self.discharge_mouth += m.discharge_mouth
        
        try:
            self.qs   = 1000.0 * self.discharge_mouth/self.waterarea
        except ZeroDivisionError:
            self.qs   = 0.0

        # This is an estimate. No account for difference in area of cells. 
        self.weigh_avg(m,"avg_traveltime","number_of_cells")
        # Calculate weighed average over the next attributes.
        self.weigh_avg(m,"avg_Ptraveltime","pload_river")
        self.weigh_avg(m,"avg_Ptemperature","pload_river")
        self.weigh_avg(m,"avg_Phydraulic_load","pload_river")

        self.pbudget                  += m.pbudget
        self.psro                     += m.psro
        self.psro_arable              += m.psro_arable
        self.psro_grs                 += m.psro_grs
        self.p_erosion_arable         += m.p_erosion_arable
        self.p_erosion_grass          += m.p_erosion_grass
        self.p_erosion_nat            += m.p_erosion_nat
        self.p_erosion                += m.p_erosion
        self.pbackground              += m.pbackground
        self.ptotal_diffuse           += m.ptotal_diffuse
        self.ppoint                   += m.ppoint      
        self.p_gnpp                   += m.p_gnpp
        self.p_wetland_in             += m.p_wetland_in
        self.p_wetland_out            += m.p_wetland_out
        self.p_aquaculture            += m.p_aquaculture
        self.pload_river              += m.pload_river
        self.subgrid_load             += m.subgrid_load
        self.retentionload_subgrid    += m.retentionload_subgrid
        self.pload_mouth              += m.pload_mouth
        self.number_of_lakes          += m.number_of_lakes
        self.lakes_water_area         += m.lakes_water_area
        self.lakes_volume             += m.lakes_volume
        self.lakes_retention_load     += m.lakes_retention_load
        self.lakes_load_in            += m.lakes_load_in
        self.lakes_load_out           += m.lakes_load_out
        self.number_of_reserv         += m.number_of_reserv
        self.reserv_water_area        += m.reserv_water_area
        self.reserv_volume            += m.reserv_volume
        self.reserv_retention_load    += m.reserv_retention_load
        self.reserv_load_in           += m.reserv_load_in
        self.reserv_load_out          += m.reserv_load_out
       
        try:
	    self.pconc_mouth = 1.0e-6 * self.pload_mouth/self.discharge_mouth
	except ZeroDivisionError:
            self.pconc_mouth = 0.0        
       
        try:
	    self.retention_subgrid = self.retentionload_subgrid/self.subgrid_load
	except ZeroDivisionError:
            self.retention_subgrid = 0.0

        try:
	    self.retention = 1.0 - (self.pload_mouth/self.pload_river)
	except ZeroDivisionError:
            self.retention = 0.0

        try:
	    self.fr_lakes_retention = self.lakes_retention_load/(self.retention * self.pload_river)
	except ZeroDivisionError:
            self.fr_lakes_retention = 0.0
        try:
	    self.lakes_retention = 1.0 - (self.lakes_load_out/self.lakes_load_in)
	except ZeroDivisionError:
            self.lakes_retention = 0.0
        try:
	    self.fr_reserv_retention = self.reserv_retention_load/(self.retention * self.pload_river)
	except ZeroDivisionError:
            self.fr_reserv_retention = 0.0

        try:
	    self.reserv_retention = 1.0 - (self.reserv_load_out/self.reserv_load_in)
	except ZeroDivisionError:
            self.reserv_retention = 0.0

    def copy(self):
        '''
        Copy a PMouth class object 
        '''
        # Create a new PMouth object
        new = PMouth()
        # Copy all the attributes.
        new.basinid            =        self.basinid
        new.lat                =        self.lat
        new.lon                =        self.lon
        new.index_grid         =        self.index_grid
        new.index_grid_full    =        self.index_grid_full
        new.number_of_cells    =        self.number_of_cells
        new.retention          =        self.retention
        new.qs                 =        self.qs
        new.minreduction       =        self.minreduction
        new.maxreduction       =        self.maxreduction
        new.landarea           =        self.landarea
        new.grasarea           =        self.grasarea
        new.croparea           =        self.croparea
        new.natarea            =        self.natarea
        new.waterarea          =        self.waterarea
        new.wetland_area       =        self.wetland_area
        new.flooding_area      =        self.flooding_area
        new.discharge_mouth    =        self.discharge_mouth
        new.pbudget            =        self.pbudget
        new.psro               =        self.psro
        new.psro_arable        =        self.psro_arable
        new.psro_grs           =        self.psro_grs
        new.p_erosion_arable   =        self.p_erosion_arable
        new.p_erosion_grass    =        self.p_erosion_grass
        new.p_erosion_nat      =        self.p_erosion_nat
        new.p_erosion          =        self.p_erosion
        new.pbackground        =        self.pbackground
        new.ptotal_diffuse     =        self.ptotal_diffuse
        new.ppoint             =        self.ppoint
        new.p_gnpp             =        self.p_gnpp
        new.p_wetland_in       =        self.p_wetland_in
        new.p_wetland_out      =        self.p_wetland_out
        new.p_aquaculture      =        self.p_aquaculture
        new.pload_river        =        self.pload_river
        new.subgrid_load       =        self.subgrid_load
        new.retentionload_subgrid =     self.retentionload_subgrid
        new.retention_subgrid  =        self.retention_subgrid
        new.pload_mouth        =        self.pload_mouth
        new.pconc_mouth        =        self.pconc_mouth
        new.avg_traveltime     =        self.avg_traveltime
        new.avg_Ptraveltime    =        self.avg_Ptraveltime
        new.avg_Ptemperature   =        self.avg_Ptemperature
        new.avg_Phydraulic_load       = self.avg_Phydraulic_load
        new.number_of_lakes    =        self.number_of_lakes
        new.lakes_water_area   =        self.lakes_water_area
        new.lakes_volume       =        self.lakes_volume
        new.lakes_retention_load      = self.lakes_retention_load
        new.fr_lakes_retention =        self.fr_lakes_retention
        new.lakes_load_in      =        self.lakes_load_in
        new.lakes_load_out     =        self.lakes_load_out
        new.lakes_retention    =        self.lakes_retention
        new.number_of_reserv   =        self.number_of_reserv
        new.reserv_water_area  =        self.reserv_water_area
        new.reserv_volume      =        self.reserv_volume
        new.reserv_retention_load     = self.reserv_retention_load
        new.fr_reserv_retention =       self.fr_reserv_retention
        new.reserv_load_in     =        self.reserv_load_in
        new.reserv_load_out    =        self.reserv_load_out
        new.reserv_retention   =        self.reserv_retention

        # Return new (copied) object
        return new   
    
    
