# ******************************************************
## 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/N_model/trunk/tools/nmouth.py $"
# ******************************************************

import ascraster
import my_sys
import write_dict
import mouth

class NMouth(mouth.Mouth):
    '''Derived nitrogen 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.retention = float(retention)
        self.qs = float(qs)
        self.index_grid_full = 0
        self.number_of_cells = 0

        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.nbudget = 0.0
        self.n_inactive = 0.0
        self.n_inactive_grs = 0.0
        self.n_inactive_nat = 0.0
        self.nbudget_act = 0.0
        self.nbudget_arable = 0.0
        self.nbudget_grs = 0.0
        self.nbudget_nat = 0.0
        self.nsro = 0.0
        self.fr_nsro = 0.0
        self.nsro_arable = 0.0
        self.nsro_grs = 0.0
        self.nsro_nat = 0.0
        self.n_erosion = 0.0
        self.n_erosion_arable = 0.0
        self.n_erosion_grs = 0.0
        self.n_erosion_nat = 0.0
        self.soil_denitrification = 0.0
        self.fr_soil_denitrification = 0.0
        self.soil_denitrification_arable = 0.0
        self.soil_denitrification_grs = 0.0
        self.soil_denitrification_nat = 0.0
        self.N2O_soil_denitrification = 0.0
        self.nleaching = 0.0
        self.fr_nleaching = 0.0
        self.nleaching_arable = 0.0
        self.nleaching_grs = 0.0
        self.nleaching_nat = 0.0
        self.ngrw_retention = 0.0
        self.fr_ngrw_retention = 0.0
        self.n_denitr_grw = 0.0
        self.nsgrw = 0.0
        self.fr_nsgrw = 0.0
        self.ndgrw = 0.0
        self.fr_ndgrw = 0.0
        self.n_rip_load = 0.0
        self.n_rip_bypass_load = 0.0
        self.n_denitr_rip = 0.0
        self.n2o_denitr_rip = 0.0
        self.nsgrw_end = 0.0
        self.ntotal_diffuse = 0.0
        self.fr_ntotal_diffuse = 0.0
        self.npoint = 0.0
        self.n_gnpp = 0.0
        self.n_wetland_in = 0.0
        self.n_wetland_out = 0.0
        self.n_aquaculture = 0.0
        self.n_deposition_water = 0.0
        self.nload_river = 0.0
        self.subgrid_load = 0.0
        self.retentionload_subgrid = 0.0
        self.retention_subgrid = 0.0
        self.nload_mouth = 0.0
        self.nconc_mouth = 0.0
        self.sgd         = 0.0
        self.avg_traveltime = 0.0
        self.avg_Ntraveltime = 0.0
        self.avg_Ntemperature = 0.0
        self.avg_Nhydraulic_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("nbudget") + sep +\
              str("n_inactive") + sep +\
              str("n_inactive_grs") + sep +\
              str("n_inactive_nat") + sep +\
              str("nbudget_act") + sep +\
              str("nbudget_arable") + sep +\
              str("nbudget_grs") + sep +\
              str("nbudget_nat") + sep +\
              str("nsro") + sep +\
              str("fr_nsro") + sep +\
              str("nsro_arable") + sep +\
              str("nsro_grs") + sep +\
              str("nsro_nat") + sep +\
              str("n_erosion") + sep +\
              str("n_erosion_arable") + sep +\
              str("n_erosion_grs") + sep +\
              str("n_erosion_nat") + sep +\
              str("soil_denitrification") + sep +\
              str("fr_soil_denitrification") + sep +\
              str("soil_denitrification_arable") + sep +\
              str("soil_denitrification_grs") + sep +\
              str("soil_denitrification_nat") + sep +\
              str("N2O_soil_denitrification") + sep +\
              str("nleaching") + sep +\
              str("fr_nleaching") + sep +\
              str("nleaching_arable") + sep +\
              str("nleaching_grs") + sep +\
              str("nleaching_nat") + sep +\
              str("ngrw_retention") + sep +\
              str("fr_ngrw_retention") + sep +\
              str("n_denitr_grw") + sep +\
              str("nsgrw") + sep +\
              str("fr_nsgrw") + sep +\
              str("ndgrw") + sep +\
              str("fr_ndgrw") + sep +\
              str("n_rip_load") + sep +\
              str("n_rip_bypass_load") + sep +\
              str("n_denitr_rip") + sep +\
              str("n2o_denitr_rip") + sep +\
              str("nsgrw_end") + sep +\
              str("ntotal_diffuse") + sep +\
              str("fr_ntotal_diffuse") + sep +\
              str("npoint") + sep +\
              str("n_gnpp") + sep +\
              str("n_wetland_in") + sep +\
              str("n_wetland_out") + sep +\
              str("n_aquaculture") + sep +\
              str("n_deposition_water") + sep +\
              str("nload_river") + sep +\
              str("subgrid_load") + sep +\
              str("retentionload_subgrid") + sep +\
              str("retention_subgrid") + sep +\
              str("retention") + sep +\
              str("nload_mouth") + sep +\
              str("nconc_mouth") +  sep +\
              str("sgd") +  sep +\
              str("number_of_cells") + sep +\
              str("avg_traveltime") + sep +\
              str("avg_Ntraveltime") + sep +\
              str("avg_Ntemperature") + sep +\
              str("avg_Nhydraulic_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.nbudget) + sep +\
              str(self.n_inactive) + sep +\
              str(self.n_inactive_grs) + sep +\
              str(self.n_inactive_nat) + sep +\
              str(self.nbudget_act) + sep +\
              str(self.nbudget_arable) + sep +\
              str(self.nbudget_grs) + sep +\
              str(self.nbudget_nat) + sep +\
              str(self.nsro) + sep +\
              str(self.fr_nsro) + sep +\
              str(self.nsro_arable) + sep +\
              str(self.nsro_grs) + sep +\
              str(self.nsro_nat) + sep +\
              str(self.n_erosion) + sep +\
              str(self.n_erosion_arable) + sep +\
              str(self.n_erosion_grs) + sep +\
              str(self.n_erosion_nat) + sep +\
              str(self.soil_denitrification) + sep +\
              str(self.fr_soil_denitrification) + sep +\
              str(self.soil_denitrification_arable) + sep +\
              str(self.soil_denitrification_grs) + sep +\
              str(self.soil_denitrification_nat) + sep +\
              str(self.N2O_soil_denitrification) + sep +\
              str(self.nleaching) + sep +\
              str(self.fr_nleaching) + sep +\
              str(self.nleaching_arable) + sep +\
              str(self.nleaching_grs) + sep +\
              str(self.nleaching_nat) + sep +\
              str(self.ngrw_retention) + sep +\
              str(self.fr_ngrw_retention) + sep +\
              str(self.n_denitr_grw) + sep +\
              str(self.nsgrw) + sep +\
              str(self.fr_nsgrw) + sep +\
              str(self.ndgrw) + sep +\
              str(self.fr_ndgrw) + sep +\
              str(self.n_rip_load) + sep +\
              str(self.n_rip_bypass_load) + sep +\
              str(self.n_denitr_rip) + sep +\
              str(self.n2o_denitr_rip) + sep +\
              str(self.nsgrw_end) + sep +\
              str(self.ntotal_diffuse) + sep +\
              str(self.fr_ntotal_diffuse) + sep +\
              str(self.npoint) + sep +\
              str(self.n_gnpp) + sep +\
              str(self.n_wetland_in) + sep +\
              str(self.n_wetland_out) + sep +\
              str(self.n_aquaculture) + sep +\
              str(self.n_deposition_water) + sep +\
              str(self.nload_river) + sep +\
              str(self.subgrid_load) + sep +\
              str(self.retentionload_subgrid) + sep +\
              str(self.retention_subgrid) + sep +\
              str(self.retention) + sep +\
              str(self.nload_mouth) + sep +\
              str(self.nconc_mouth) + sep +\
              str(self.sgd) + sep +\
              str(self.number_of_cells) + sep +\
              str(self.avg_traveltime) + sep +\
              str(self.avg_Ntraveltime) + sep +
              str(self.avg_Ntemperature) + sep +\
              str(self.avg_Nhydraulic_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_Ntraveltime","nload_river")
        self.weigh_avg(m,"avg_Ntemperature","nload_river")
        self.weigh_avg(m,"avg_Nhydraulic_load","nload_river")

     
        self.nbudget                     += m.nbudget
        self.n_inactive                  += m.n_inactive
        self.n_inactive_grs              += m.n_inactive_grs
        self.n_inactive_nat              += m.n_inactive_nat
        self.nbudget_act                 += m.nbudget_act
        self.nbudget_arable              += m.nbudget_arable
        self.nbudget_grs                 += m.nbudget_grs
        self.nbudget_nat                 += m.nbudget_nat
        self.nsro                        += m.nsro
        self.nsro_arable                 += m.nsro_arable
        self.nsro_grs                    += m.nsro_grs
        self.nsro_nat                    += m.nsro_nat
        self.n_erosion                   += m.n_erosion
        self.n_erosion_arable            += m.n_erosion_arable
        self.n_erosion_grs               += m.n_erosion_grs
        self.n_erosion_nat               += m.n_erosion_nat
        self.soil_denitrification        += m.soil_denitrification
        self.soil_denitrification_arable += m.soil_denitrification_arable
        self.soil_denitrification_grs    += m.soil_denitrification_grs
        self.soil_denitrification_nat    += m.soil_denitrification_nat
        self.N2O_soil_denitrification    += m.N2O_soil_denitrification
        self.ngrw_retention              += m.ngrw_retention

        self.nleaching                   += m.nleaching
        self.nleaching_arable            += m.nleaching_arable
        self.nleaching_grs               += m.nleaching_grs
        self.nleaching_nat               += m.nleaching_nat
        self.n_denitr_grw                += m.n_denitr_grw
        self.nsgrw                       += m.nsgrw
        self.ndgrw                       += m.ndgrw
        self.n_rip_load                  += m.n_rip_load
        self.n_rip_bypass_load           += m.n_rip_bypass_load
        self.n_denitr_rip                += m.n_denitr_rip
        self.n2o_denitr_rip              += m.n2o_denitr_rip
        self.nsgrw_end                   += m.nsgrw_end

        self.npoint                      += m.npoint
        self.n_gnpp                      += m.n_gnpp
        self.n_wetland_in                += m.n_wetland_in
        self.n_wetland_out               += m.n_wetland_out
        self.n_aquaculture               += m.n_aquaculture
        self.n_deposition_water          += m.n_deposition_water
        self.ntotal_diffuse              += m.ntotal_diffuse
        self.nload_river                 += m.nload_river
        self.subgrid_load                += m.subgrid_load
        self.retentionload_subgrid       += m.retentionload_subgrid
        self.nload_mouth                 += m.nload_mouth
        self.sgd                         += m.sgd
        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.fr_nsro   = self.nsro/self.nbudget
        except ZeroDivisionError:
            self.fr_nsro   = 0.0
        
        try:
	    self.fr_soil_denitrification   = self.soil_denitrification/self.nbudget
	except ZeroDivisionError:
            self.fr_soil_denitrification   = 0.0

        try:
	    self.fr_nleaching = self.nleaching/self.nbudget
	except ZeroDivisionError:
            self.fr_nleaching   = 0.0
        
        try:
	    self.fr_ngrw_retention = self.ngrw_retention/self.nbudget
	except ZeroDivisionError:
            self.fr_ngrw_retention = 0.0
        
        try:
	    self.fr_nsgrw = self.nsgrw/self.nbudget
	except ZeroDivisionError:
            self.fr_nsgrw = 0.0        
        
        try:
	    self.fr_ndgrw = self.ndgrw/self.nbudget
	except ZeroDivisionError:
            self.fr_ndgrw = 0.0    
        
        try:
	    self.fr_ntotal_diffuse = self.ntotal_diffuse/self.nbudget
	except ZeroDivisionError:
            self.fr_ntotal_diffuse = 0.0  

        try:
	    self.nconc_mouth = 1.0e-6 * self.nload_mouth/self.discharge_mouth
	except ZeroDivisionError:
            self.nconc_mouth = 0.0        
                  
        try:
	    self.retention = 1.0 - (self.nload_mouth/self.nload_river)
	except ZeroDivisionError:
            self.retention = 0.0

        try:
	    self.retention_subgrid = self.retentionload_subgrid/self.subgrid_load
	except ZeroDivisionError:
            self.retention_subgrid = 0.0

        try:
	    self.fr_lakes_retention = self.lakes_retention_load/(self.retention * self.nload_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.nload_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 Mouth class object 
        '''
        # Create a new Mouth object
        new = NMouth()
        # 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.nbudget                   = self.nbudget
        new.n_inactive                = self.n_inactive
        new.n_inactive_grs            = self.n_inactive_grs
        new.n_inactive_nat            = self.n_inactive_nat
        new.nbudget_act               = self.nbudget_act
        new.nbudget_arable            = self.nbudget_arable
        new.nbudget_grs               = self.nbudget_grs
        new.nbudget_nat               = self.nbudget_nat
        new.nsro                      = self.nsro
        new.fr_nsro                   = self.fr_nsro
        new.nsro_arable               = self.nsro_arable
        new.nsro_grs                  = self.nsro_grs
        new.nsro_nat                  = self.nsro_nat
        new.n_erosion                 = self.n_erosion
        new.n_erosion_arable          = self.n_erosion_arable
        new.n_erosion_grs             = self.n_erosion_grs
        new.n_erosion_nat             = self.n_erosion_nat
        new.soil_denitrification      = self.soil_denitrification
        new.fr_soil_denitrification   = self.fr_soil_denitrification
        new.soil_denitrification_arable  = self.soil_denitrification_arable
        new.soil_denitrification_grs  = self.soil_denitrification_grs
        new.soil_denitrification_nat  = self.soil_denitrification_nat
        new.N2O_soil_denitrification  = self.N2O_soil_denitrification
        new.nleaching                 = self.nleaching
        new.fr_nleaching              = self.fr_nleaching
        new.nleaching_arable          = self.nleaching_arable
        new.nleaching_grs             = self.nleaching_grs
        new.nleaching_nat             = self.nleaching_nat
        new.ngrw_retention            = self.ngrw_retention
        new.fr_ngrw_retention         = self.fr_ngrw_retention
        new.n_denitr_grw              = self.n_denitr_grw
        new.nsgrw                     = self.nsgrw
        new.fr_nsgrw                  = self.fr_nsgrw
        new.ndgrw                     = self.ndgrw
        new.fr_ndgrw                  = self.fr_ndgrw
        new.n_rip_load                = self.n_rip_load
        new.n_rip_bypass_load         = self.n_rip_bypass_load
        new.n_denitr_rip              = self.n_denitr_rip
        new.n2o_denitr_rip            = self.n2o_denitr_rip
        new.nsgrw_end                 = self.nsgrw_end
        new.ntotal_diffuse            = self.ntotal_diffuse
        new.fr_ntotal_diffuse         = self.fr_ntotal_diffuse
        new.npoint                    = self.npoint
        new.n_gnpp                    = self.n_gnpp
        new.n_wetland_in              = self.n_wetland_in
        new.n_wetland_out             = self.n_wetland_out
        new.n_aquaculture             = self.n_aquaculture
        new.n_deposition_water        = self.n_deposition_water
        new.nload_river               = self.nload_river
        new.subgrid_load              = self.subgrid_load
        new.retentionload_subgrid     = self.retentionload_subgrid
        new.retention_subgrid         = self.retention_subgrid
        new.nload_mouth               = self.nload_mouth
        new.nconc_mouth               = self.nconc_mouth
        new.sgd                       = self.sgd
        new.avg_traveltime            = self.avg_traveltime
        new.avg_Ntraveltime           = self.avg_Ntraveltime
        new.avg_Ntemperature          = self.avg_Ntemperature
        new.avg_Nhydraulic_load       = self.avg_Nhydraulic_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
