def design_IS(Aimp, dcv, targets, tech_apps, soilK, systemK, minsize, maxsize):
    #Design of Infiltration systems
    #   input: Imparea = Impervious Area to treat
    #          tarQ = Runoff reduction target
    #          tarTSS = TSS reduction target
    #          tarTP = TP reduction target
    #          tarTN = TN reduction target
    #          soilK = soil hydraulic conductivity
    #          maxsize = maximum allowable system size
    tarQ, tarTSS, tarTP, tarTN = targets[0:4]
    tarQ *= tech_apps[0]
    tarTSS *= tech_apps[1]
    tarTP *= tech_apps[1]
    tarTN *= tech_apps[1]
    
    exfil = min(soilK, systemK)
    
    if Aimp == 0:   #if there is no impervious area to design for, why bother?
        return [None, 1]
    
    #size the system
    if soilK != 0:
        psystem = ddcv.retrieveDesign(dcv, "IS", exfil, [tarQ, tarTSS, tarTP, tarTN, 100])
        #print psystem
    else:
        psystem = np.inf
        
    if psystem == np.inf or psystem == 0:       #if the system cannot be designed, it will return infinity
        return [None, 1]
    
    system_area = max(Aimp * psystem, minsize)  #the larger of the two
    
    if system_area > maxsize:          #if the final design exceeds the maximum allowable size, forget it!
        #print "Warning, Maximum System Size Exceeded"
        return [None, 1]
    
    #if the system design has passed to this point: i.e. not impossible and there is impervious to treat, then add planning constraints
    #find setback requirement based on soilK
    if soilK >= 3600:
        setback = 1.0
    elif soilK >= 1800:
        setback = 1.0
    elif soilK >= 360:
        setback = 1.0
    elif soilK >= 180:
        setback = 1.0
    elif soilK > 36:
        setback = 2
    elif soilK > 3.6:
        setback = 4.0   #metres
    else:
        #print "Soil is unsuitable for infiltration"
        return [None, 1]

    Areq = m.pow((m.sqrt(system_area)+2*setback),2)
#    print "Required Area: ", Areq
    diff = Areq/system_area
    return [Areq, diff]
def design_BF(Aimp, dcv, targets, tech_apps, soilK, systemK, minsize, maxsize):
    #Design of Biofiltration systems
    #   input: Imparea = Impervious Area to treat
    #          tarQ = Runoff reduction target
    #          tarTSS = TSS reduction target
    #          tarTP = TP reduction target
    #          tarTN = TN reduction target
    #          soilK = soil hydraulic conductivity
    #          maxsize = maximum allowable system size
    tarQ, tarTSS, tarTP, tarTN = targets[0:4]
    tarQ *= tech_apps[0]
    tarTSS *= tech_apps[1]
    tarTP *= tech_apps[1]
    tarTN *= tech_apps[1]
    
    exfil = min(soilK, systemK)
    #print Aimp, tarTSS, tarTP, tarTN, exfil
    if Aimp == 0:   #if there is no impervious area to design for, why bother?
        return [None, 1]
    #size the system for runoff reduction and pollution reduction independently
    if soilK != 0:
        psystem = ddcv.retrieveDesign(dcv, "BF", exfil, [tarQ, tarTSS, tarTP, tarTN, 100])
    else:
        psystem = np.inf
        
    if psystem == np.inf or psystem == 0:
        return [None, 1]
    
    system_area = max(Aimp * psystem, minsize)  #the larger of the two
    
    #if the system design has passed to this point: i.e. not impossible and there is impervious to treat, then add planning constraints
    
    if system_area > maxsize:          #if the final design exceeds the maximum allowable size, forget it!
        #print "Warning, Maximum System Size Exceeded"
        return [None, 1]
        
    #an infiltrating system (extra space around it required), determine the setback required
    if soilK > 180:
        setback = 1.0   #metres
    elif soilK > 36:
        setback = 2.0   #metres
    elif soilK > 3.6:
        setback = 4.0   #metres
    else:
        setback = 5.0   #metres
    
    Areq = m.pow((m.sqrt(system_area)+2*setback),2)
    #print "Arequired", Areq
    diff = Areq/system_area
    #final check, if the system has exceeded maximum size, return 'impossible' = inf
    return [Areq, diff]
def design_WSUR(Aimp, dcv, targets, tech_apps, soilK, systemK, minsize, maxsize ):
    #Design of Ponds & Lakes
    #   input: Imparea = Impervious Area to treat
    #          tarQ = Runoff reduction target
    #          tarTSS = TSS reduction target
    #          tarTP = TP reduction target
    #          tarTN = TN reduction target
    #          soilK = soil hydraulic conductivity
    #          maxsize = maximum allowable system size
    tarQ, tarTSS, tarTP, tarTN = targets[0:4]
    tarQ *= tech_apps[0]
    tarTSS *= tech_apps[1]
    tarTP *= tech_apps[1]
    tarTN *= tech_apps[1]
    
    exfil = min(soilK, systemK)
    
    if Aimp == 0:   #if there is no impervious area to design for, why bother?
        return [None, 1]
    #size the system
    if soilK != 0:
        psystem = ddcv.retrieveDesign(dcv, "WSUR", exfil, [tarQ, tarTSS, tarTP, tarTN, 100])
    else:
        psystem = np.inf    
    
    if psystem == np.inf or psystem == 0:       #if the system cannot be designed, it will return infinity
        return [None, 1]
    
    system_area = max(Aimp * psystem, minsize)  #the larger of the two
       
    if system_area > maxsize:   #if the final design exceeds the maximum allowable size, forget it!
        #print "Warning, Maximum System Size Exceeded"
        return [None, 1]
    
    #add extra area to the system (multipliers for batters)
    batter_multiplier = 1.3
    
    Areq = system_area * batter_multiplier
    diff = Areq/system_area
    
    return [Areq, diff]