def windsp3dayGen(intensity, dt, stationn): #generate sea temperature (NDBC) type fact ##calculating fuzzyI fI = fuzzyI(intensity, stationn, 'windsp3day') ## calculating fuzzyTod fTod = fuzzyTod(dt.time()) return fact.seandbc(fuzzyI=fI, fuzzyTod=fTod, date=dt.strftime('%m_%d_%Y'), locus=stationn, I=intensity, fact_type='windsp3day')
class MCB( pk.KnowledgeEngine): def __init__(self, station): pk.KnowledgeEngine.__init__(self) self.station= station self.SRI= 0 self.MaxSRI= 0 self.alerts = {} def retract(self, idx_or_declared_fact): """ Retracts a specific fact, using its index .. note:: This updates the agenda """ self.facts.retract(idx_or_declared_fact) #if not self.running: added, removed = self.get_activations() self.strategy.update_agenda(self.agenda, added, removed) def alert_add( self, ruleName, rule_des, sri, factList): date= factList[0]['date'] i= 0 alertName= date+self.station+ruleName+"#"+str(i) while True: if alertName in self.alerts.keys(): i+=1 alertName= alertName[:-1]+str(i) else: break self.alerts[alertName]= {} self.alerts[alertName]['rule_name']= ruleName self.alerts[alertName]['rule_description']= rule_des self.alerts[alertName]['SRI']= sri self.alerts[alertName]['fact_list']= factList ###OLD KE tools #initial instruction output def display(self): print('\n', '----------------------------------------------------------------------\n', 'To declare Knowledge Engine:\n', '>> e = mcb.MCB()\n', '>> e.reset()\n', '\n\n', 'To add facts to fact list call:\n', '>> e.declare_facts()\n', '>> e.declare_facts(\'factname\', \'fuzzyI\', \'fuzzyTod\', \'date\', \'locus\')\n', '\n\n', 'To import a fact csv call:\n', '>> e.import_facts(\'./test_suite/fact_CSVs/testX.csv\')\n', '\n\n', 'To view current rule base call:\n', '>> e.get_rules()\n', '\n\n', 'To view rule nomenclature reference call:\n', '\n\n', 'To view current fact base call:\n', '>> e.facts\n', '\n\n', 'To run Knowledge Engine call:\n', '>> e.run()\n', '----------------------------------------------------------------------\n', '\n \n \n\n') #test functions to initialize specific combinations of facts def import_facts(self, filename='1'): factlines= [x.rstrip('\n') for x in open(filename)] while factlines: factString = factlines.pop(0) factName, factFuzzyI, factFuzzyTod, factDate, factLocus = factString.split(",") exec("self.declare(%s(fuzzyI=factFuzzyI, fuzzyTod=factFuzzyTod, date=factDate, locus=factLocus))" % (factName)) #function to automate declaring facts: has a function call mode w/ attributes ##or an interactive mode for terminal def declare_facts(self, x='na', y='na', z='na'): if x!='na': print(""" 'windsp3day', 'seandbcM', 'sea1mM', 'curveB','sea1m','seandbc', 'tide1m', 'windsp', 'sst', or 'parsurf' 'uLow', 'dLow', 'vLow', 'Low', 'sLow','average', 'sHigh','High', 'vHigh','dHigh', or 'uHigh' 'even'(00-03), 'midn'(03-06), 'pdaw'(06-09), 'dawn'(09-12),'morn'(12-15), 'midd'(15-18), 'psun'(18-21), 'suns'(21-24), 'nite'(00-09), 'dayb'(09-15), 'aftn'(18-24), 'dayl'(09-24), 'all'(03-03) """) exec("self.declare(%s(fuzzyI=y, fuzzyTod=z))" % (x)) else: done='n' while(done=='n'): print("""Which fact would you like to declare?('windsp3day', 'seandbcM', 'sea1mM', 'curveB', 'sea1m', 'seandbc', 'tide1m', 'windsp', 'sst', or 'parsurf').""") x = input(' ') print("""What is the fuzzyI?('uLow', 'dLow', 'vLow', 'Low', 'sLow','average', 'sHigh', 'High', 'vHigh', 'dHigh', or 'uHigh').""") y = input(' ') print("""What is the fuzzyTod?( 'even'(00-03), 'midn'(03-06), 'pdaw'(06-09), 'dawn'(09-12), 'morn'(12-15), 'midd'(15-18), 'psun'(21-24), 'suns'(21-24), 'nite'(00-09), 'dayb'(09-15), 'aftn'(18-24), 'dayl'(09-24), 'all'(03-03).""") z = input(' ') exec("self.declare(%s(fuzzyI=y, fuzzyTod=z))" % (x)) print("""Are you finished declaring facts? (y/n)""") done = input(' ') ###RULE DECLARATIONS### #Unbelievable value Rules @pk.Rule(pk.OR(fact.sst(fuzzyI='uLow'), fact.sst(fuzzyI='uHigh'))) def u_fI_sst(self): print("sst values in unbelievable range") @pk.Rule(pk.OR(fact.windsp(fuzzyI='uLow'), fact.windsp(fuzzyI='uHigh'))) def u_fI_windsp(self): print("wind scalar values in unbelievable range") @pk.Rule(pk.OR(fact.seandbc(fuzzyI='uLow'), fact.seandbc(fuzzyI='uHigh'))) def u_fI_seandbc(self): print("seandbc values in unbelievable range") @pk.Rule(pk.OR(fact.parsurf(fuzzyI='uLow'), fact.parsurf(fuzzyI='uHigh'))) def u_fI_parsurf(self): print("parsurf values in unbelievable range") @pk.Rule(pk.OR(fact.tide1m(fuzzyI='uLow'), fact.tide1m(fuzzyI='uHigh'))) def u_fI_tide1m(self): print("tide1m values in unbelievable range") @pk.Rule(pk.OR(fact.sea1m(fuzzyI='uLow'), fact.sea1m(fuzzyI='uHigh'))) def u_fI_sea1m(self): print("sea1m values in unbelievable range") @pk.Rule(pk.OR(fact.seandbcM(fuzzyI='uLow'), fact.seandbcM(fuzzyI='uHigh'))) def u_fI_seandbcM(self): print("seandbcM values in unbelievable range") @pk.Rule(pk.OR(fact.windsp3day(fuzzyI='uLow'), fact.windsp3day(fuzzyI='uHigh'))) def u_fI_windsp3day(self): print("windsp3day values in unbelievable range") @pk.Rule(pk.OR(fact.sea1mM(fuzzyI='uLow'), fact.sea1mM(fuzzyI='uHigh'))) def u_fI_sea1mM(self): print("sea1mM values in unbelievable range") @pk.Rule(pk.OR(fact.curveB(fuzzyI='uLow'), fact.curveB(fuzzyI='uHigh'))) def u_fI_curveB(self): print("curveB values in unbelievable range") #Missing info rules @pk.Rule( fact.sst(fuzzyI=~anyof('uLow', 'dLow', 'vLow', 'Low', 'sLow', 'average', 'sHigh', 'High', 'vHigh', 'dHigh', 'uHigh'))) def m_fI_sst(self): print("missing or unreadable value for sst fuzzyI") @pk.Rule( fact.seandbc(fuzzyI=~anyof('uLow', 'dLow', 'vLow', 'Low', 'sLow', 'average', 'sHigh', 'High', 'vHigh', 'dHigh', 'uHigh'))) def m_fI_seandbc(self): print("missing or unreadable value for seandbc fuzzyI") @pk.Rule( fact.parsurf(fuzzyI=~anyof('uLow', 'dLow', 'vLow', 'Low', 'sLow', 'average', 'sHigh', 'High', 'vHigh', 'dHigh', 'uHigh'))) def m_fI_parsurf(self): print("missing or unreadable value for parsurf fuzzyI") @pk.Rule(fact.windsp( fuzzyI=~anyof('uLow', 'dLow', 'vLow', 'Low', 'sLow', 'average', 'sHigh', 'High', 'vHigh', 'dHigh', 'uHigh'))) def m_fI_windsp(self): print("missing or unreadable value for windsp fuzzyI") @pk.Rule(fact.tide1m(fuzzyI=~anyof('uLow', 'dLow', 'vLow', 'Low', 'sLow', 'average', 'sHigh', 'High', 'vHigh', 'dHigh', 'uHigh'))) def m_fI_tide1m(self): print("missing or unreadable value for tide1m fuzzyI") @pk.Rule(fact.sea1m(fuzzyI=~anyof('uLow', 'dLow', 'vLow', 'Low', 'sLow', 'average', 'sHigh', 'High', 'vHigh', 'dHigh', 'uHigh'))) def m_fI_sea1m(self): print("missing or unreadable value for sea1m fuzzyI") @pk.Rule(fact.seandbcM(fuzzyI=~anyof('uLow', 'dLow', 'vLow', 'Low', 'sLow', 'average', 'sHigh', 'High', 'vHigh', 'dHigh', 'uHigh'))) def m_fI_seandbcM(self): print("missing or unreadable value for seandbcM fuzzyI") @pk.Rule(fact.curveB(fuzzyI=~anyof('uLow', 'dLow','vLow', 'Low', 'sLow', 'average', 'sHigh', 'High', 'vHigh' ,'dHigh', 'uHigh'))) def m_fI_curveB(self): print("missing or unreadable value for curveB fuzzyI") @pk.Rule( fact.sea1mM(fuzzyI=~anyof('uLow', 'dLow', 'vLow', 'Low', 'sLow', 'average', 'sHigh', 'High', 'vHigh', 'dHigh', 'uHigh'))) def m_fI_sea1mM(self): print("missing or unreadable value for sea1mM fuzzyI") #MCB MASS-CORAL-BLEACHING implementation (forecast model has 24 rules) #Description: Mass bleaching of hard corals ##Ecoforecast Rule #1: Coral-Bleaching-PtwA ##Description: Mass coral bleaching (high in-situ sea temperature + high light + low wind + low tide) @pk.Rule(pk.AS.parsurf << fact.parsurf( fuzzyI=anyof('High', 'vHigh', 'dHigh'), fuzzyTod=anyof('midd', 'psun', 'dayl', 'aftn', 'all')), pk.AS.tide1m << fact.tide1m( fuzzyI=anyof('dLow', 'vLow', 'Low'), fuzzyTod=anyof('morn', 'midd', 'psun', 'dayl', 'dayb', 'aftn', 'all')), pk.AS.windsp << fact.windsp( fuzzyI=anyof('dLow', 'vLow', 'Low'), fuzzyTod=anyof('morn', 'midd', 'psun', 'dayl', 'dayb', 'aftn', 'all')), pk.AS.seandbc << fact.seandbc( fuzzyI=anyof('High', 'vHigh', 'dHigh'), fuzzyTod=pk.W())) def mcb_PtwA(self, parsurf, tide1m, windsp, seandbc): print("\t "+parsurf['date']+" Coral-Bleaching-PtwA fired.") fact_display(parsurf) fact_display(tide1m) fact_display(windsp) fact_display(seandbc) sri = sri_calc(parsurf) +sri_calc(tide1m) +sri_calc(windsp) +sri_calc(seandbc) self.SRI += sri self.MaxSRI += config.sri_max_4f self.alert_add( 'mcb_PtwA', 'Mass coral bleaching (high in-situ sea temperature + high light + low wind + low tide)', sri, [ parsurf, tide1m, windsp, seandbc]) self.retract( parsurf) self.retract( tide1m) self.retract( windsp) self.retract( seandbc) ##Ecoforecast Rule #2: Coral-Bleaching-PtwE ##Description: Mass coral bleaching (high 'shallow' sea temperature + high light + low wind + low tide) @pk.Rule(pk.AS.parsurf << fact.parsurf( fuzzyI=anyof('High', 'vHigh', 'dHigh'), fuzzyTod=anyof('midd', 'dayl', 'all')), pk.AS.tide1m << fact.tide1m( fuzzyI=anyof('dLow', 'vLow', 'Low'), fuzzyTod=anyof('morn', 'midd', 'psun', 'dayl', 'dayb', 'aftn', 'all')), pk.AS.windsp << fact.windsp( fuzzyI=anyof('dLow', 'vLow', 'Low'), fuzzyTod=anyof('morn', 'midd', 'psun', 'dayl', 'dayb', 'aftn', 'all')), pk.AS.sea1m << fact.sea1m( fuzzyI=anyof('High', 'vHigh', 'dHigh'), fuzzyTod=pk.W())) def mcb_PtwE(self, parsurf, tide1m, windsp, sea1m): print("\t "+parsurf["date"]+ " Coral-Bleaching-PtwE fired.") fact_display( parsurf) fact_displary( tide1m) fact_display( windsp) fact_display( sea1m) sri= sri_calc(parsurf) +sri_calc(tide1m) +sri_calc(windsp) +sri_calc(sea1m) self.SRI += sri self.MaxSRI += config.sri_max_4f self.alert_add( 'mcb_PtwE', 'Mass coral bleaching (high \'shallow\' sea temperature + high light + low wind + low tide)', sri, [ parsurf, tide1m, windsp, sea1m]) self.retract( parsurf) self.retract( tide1m) self.retract( windsp) self.retract( sea1m) ##Ecoforecast Rule #3: Coral-Bleaching-PtwS ##Description: Mass coral bleaching (high SST + high light + low wind + low tide) @pk.Rule(pk.AS.parsurf << fact.parsurf(fuzzyI=anyof('High', 'vHigh', 'dHigh'), fuzzyTod=anyof('midd', 'dayl', 'all')), pk.AS.tide1m << fact.tide1m( fuzzyI=anyof('dLow', 'vLow', 'Low'), fuzzyTod=anyof('morn', 'midd', 'psun', 'dayl', 'dayb', 'aftn', 'all')), pk.AS.windsp << fact.windsp( fuzzyI=anyof('dLow', 'vLow', 'Low'), fuzzyTod=anyof('morn', 'midd', 'psun', 'dayl', 'dayb', 'aftn', 'aftn', 'all')), pk.AS.sst << fact.sst( fuzzyI=anyof('High', 'vHigh', 'dHigh'), fuzzyTod=pk.W())) def mcb_PtwS(self, parsurf, tide1m, windsp, sst): print("\t "+parsurf["date"]+" Coral-Bleaching-Tlwt fired.") fact_display( parsurf) fact_display( tide1m) fact_display( windsp) fact_display( sst) sri= sri_calc(parsurf) +sri_calc(tide1m) +sri_calc(windsp) +sri_calc(sst) self.SRI += sri self.MaxSRI += config.sri_max_4f self.alert_add( 'mcb_PtwS', 'Mass coral bleaching (high SST + high light + low wind + low tide)', sri, [ parsurf, tide1m, windsp, sst]) self.retract( parsurf) self.retract( tide1m) self.retract( windsp) self.retract( sst) ##Ecoforecast Rule #4: Coral-Bleaching-PwA ## Description: Mass coral bleaching (high in-situ sea temperature + high light + low wind) @pk.Rule(pk.AS.parsurf << fact.parsurf( fuzzyI=anyof('High', 'vHigh', 'dHigh'), fuzzyTod=anyof('midd', 'psun', 'dayl', 'aftn', 'all')), pk.AS.windsp << fact.windsp( fuzzyI=anyof('dLow', 'vLow', 'Low'), fuzzyTod=anyof('morn', 'midd', 'psun', 'dayl', 'dayb', 'aftn', 'all')), pk.AS.seandbc << fact.seandbc( fuzzyI=anyof('High', 'vHigh', 'dHigh'), fuzzyTod=pk.W())) def mcb_PwA(self, parsurf, windsp, seandbc): print("\t "+parsurf["date"]+" Coral-Bleaching-PwA fired.") fact_display( parsurf) fact_display( windsp) fact_display( seandbc) sri= sri_calc(parsurf) +sri_calc(windsp) +sri_calc(seandbc) self.SRI += sri self.MaxSRI += config.sri_max_3f self.alert_add( 'mcb_PwA', 'Mass coral bleaching (high in-situ sea temperature + high light + low wind)', sri, [ parsurf, windsp, seandbc]) self.retract( parsurf) self.retract( windsp) self.retract( seandbc) ##Ecoforecast Rule #5: Coral-Bleaching-twA ##Description: Mass coral bleaching (high in-situ sea temperature + low wind + low tide) @pk.Rule(pk.AS.tide1m << fact.tide1m( fuzzyI=anyof('dLow', 'vLow', 'low'), fuzzyTod=anyof('morn', 'midd', 'psun', 'dayl', 'dayb', 'aftn', 'all')), pk.AS.windsp << fact.windsp( fuzzyI=anyof('dLow', 'vLow', 'Low'), fuzzyTod=anyof('morn', 'midd', 'psun', 'day', 'dayb', 'aftn', 'all')), pk.AS.seandbc << fact.seandbc( fuzzyI=anyof('High', 'vHigh', 'dHigh'), fuzzyTod=pk.W())) def mcb_twA(self, tide1m, windsp, seandbc): print("\t "+tide1m["date"]+" Coral-Bleaching-twA fired.") fact_display( tide1m) fact_display( windsp) fact_display( seandbc) sri= sri_calc(tide1m) +sri_calc(windsp) +sri_calc(seandbc) self.SRI += sri self.MaxSRI += config.sri_max_3f self.alert_add( 'mcb_twA', 'Mass coral bleaching (high in-situ sea temperature + low wind + low tide)', sri, [ tide1m, windsp, seandbc]) self.retract( tide1m) self.retract( windsp) self.retract( seandbc) #Ecoforecast Rule #6: Coral-Bleaching-PwE ##Description: Mass coral bleaching (high 'shallow' sea temperature + high light + low wind) @pk.Rule(pk.AS.parsurf << fact.parsurf( fuzzyI=anyof('High', 'vHigh', 'dHigh'), fuzzyTod=anyof('midd', 'dayl', 'all')), pk.AS.windsp << fact.windsp( fuzzyI=anyof('dLow', 'vLow', 'Low'), fuzzyTod=anyof('morn', 'midd', 'psun', 'dayl', 'dayb', 'aftn', 'all')), pk.AS.sea1m << fact.sea1m( fuzzyI=anyof('High', 'vHigh', 'dHigh'), fuzzyTod=pk.W())) def mcb_PwE(self, parsurf, windsp, sea1m): print("\t "+parsurf["date"]+" Coral-Bleaching-PwE fired.") fact_display( parsurf) fact_display( windsp) fact_display( sea1m) sri= sri_calc(parsurf) +sri_calc(windsp) +sri_calc(sea1m) self.SRI += sri self.MaxSRI += config.sri_max_3f self.alert_add( 'mcb_PwE', 'Mass coral bleaching (high \'shallow\' sea temperature + high light + low wind)', sri, [ parsurf, windsp, sea1m]) self.retract( parsurf) self.retract( windsp) self.retract( sea1m) ##Ecoforecast Rule #7: Coral-Bleaching-twE ##Description: Mass coral bleaching (high 'shallow' sea temperature + low wind + low tide) @pk.Rule(pk.AS.tide1m << fact.tide1m( fuzzyI=anyof('dLow', 'vLow', 'Low'), fuzzyTod=anyof('morn', 'midd', 'psun', 'dayl', 'dayb', 'aftn', 'all')), pk.AS.windsp << fact.windsp( fuzzyI=anyof('dLow', 'vLow', 'Low'), fuzzyTod=anyof('morn', 'midd', 'psun', 'dayl', 'dayb', 'aftn', 'all')), pk.AS.sea1m << fact.sea1m( fuzzyI=anyof('High', 'vHigh', 'dHigh'), fuzzyTod=pk.W())) def mcb_twE(self, tide1m, windsp, sea1m): print("\t "+tide1m["date"]+" Coral-Bleaching-twE fired.") fact_display( tide1m) fact_display( windsp) fact_display( sea1m) sri= sri_calc(tide1m) +sri_calc(windsp) +sri_calc(sea1m) self.SRI += sri self.MaxSRI += config.sri_max_3f self.alert_add( 'mcb_twE', 'Mass coral bleaching (high \'shallow\' sea temperature + low wind + low tide)', sri, [ tide1m, windsp, sea1m]) self.retract( tide1m) self.retract( windsp) self.retract( sea1m) ##Ecoforecast Rule #8: Coral-Bleaching-PwS ##Description: Mass coral bleaching (high SST + high light + low wind) @pk.Rule(pk.AS.parsurf << fact.parsurf( fuzzyI=anyof('High', 'vHigh', 'dHigh'), fuzzyTod=anyof('midd', 'dayl', 'all')), pk.AS.windsp << fact.windsp( fuzzyI=anyof('dLow', 'vLow', 'Low'), fuzzyTod=anyof('morn', 'midd', 'psun', 'dayl', 'dayb', 'aftn', 'all')), pk.AS.sst << fact.sst( fuzzyI=anyof('High', 'vHigh', 'dHigh'), fuzzyTod=pk.W())) def mcb_PwS(self, parsurf, windsp, sst): print("\t "+parsurf["date"]+" Coral-Bleaching-PwS fired.") fact_display( parsurf) fact_display( windsp) fact_display( sst) sri= sri_calc(parsurf) +sri_calc(windsp) +sri_calc(sst) self.SRI += sri self.alert_add( 'mcb_PwS', 'Mass coral bleaching (high SST + high light + low wind)', sri, [ parsurf, windsp, sst]) self.retract( parsurf) self.retract( windsp) self.retract( sst) ##Ecoforecast Rule #9: Coral-Bleaching-twS ##Description: Mass coral bleaching (high SST + low wind + low tide) @pk.Rule(pk.AS.tide1m << fact.tide1m( fuzzyI=anyof('dLow', 'vLow', 'Low'), fuzzyTod=anyof('morn', 'midd', 'psun', 'dayl', 'dayb', 'aftn', 'all')), pk.AS.windsp << fact.windsp( fuzzyI=anyof('dLow', 'vLow', 'Low'), fuzzyTod=anyof('morn', 'midd', 'psun', 'dayl', 'dayb', 'aftn', 'all')), pk.AS.sst << fact.sst( fuzzyI=anyof('High', 'vHigh', 'dHigh'), fuzzyTod=pk.W())) def mcb_twS(self, tide1m, windsp, sst): print("\t "+tide1m["date"]+" Coral-Bleaching-twS fired.") fact_display( tide1m) fact_display( windsp) fact_display( sst) sri= sri_calc(tide1m) +sri_calc(windsp) +sri_calc(sst) self.SRI += sri self.MaxSRI += config.sri_max_3f self.alert_add( 'mcb_twS', 'Mass coral bleaching (high SST + low wind + low tide)', sri, [ tide1m, windsp, sst]) self.retract( tide1m) self.retract( windsp) self.retract( sst) ##Ecoforecast Rule #10: Coral-Bleaching-w3A ##Description: Mass coral bleaching (high in-situ sea temperature + doldrums) @pk.Rule(pk.AS.windsp3day << fact.windsp3day( fuzzyI=anyof('dLow', 'vLow', 'Low'), fuzzyTod=pk.W()), pk.AS.seandbc << fact.seandbc( fuzzyI=anyof( 'vHigh', 'dHigh'), fuzzyTod=pk.W())) #removed "High" to match MatLab restrictions better def mcb_w3A(self, windsp3day, seandbc): print("\t "+windsp3day["date"]+" Coral-Bleaching-w3A fired.") fact_display( windsp3day) fact_display( seandbc) sri= sri_calc(windsp3day) +sri_calc(seandbc) self.SRI += sri self.MaxSRI += config.sri_max_2f self.alert_add( 'mcb_w3A', 'Mass coral bleaching (high in-situ sea temperature + doldrums)', sri, [ windsp3day, seandbc]) self.retract( windsp3day) self.retract( seandbc) ##Ecoforecast Rule #11: Coral-Bleaching-PA ##Description: Mass coral bleaching (very high in-situ sea temperature + very high light) @pk.Rule(pk.AS.parsurf << fact.parsurf(fuzzyI=anyof('vHigh', 'dHigh'), fuzzyTod=anyof('midd', 'psun', 'dayl', 'aftn', 'all')), pk.AS.seandbc << fact.seandbc(fuzzyI=anyof('vHigh', 'dHigh'), fuzzyTod=pk.W())) def mcb_PA(self, parsurf, seandbc): print("\t "+parsurf["date"]+" Coral-Bleaching-PA fired.") fact_display( parsurf) fact_display( seandbc) sri = sri_calc(parsurf) +sri_calc( seandbc) self.SRI += sri self.MaxSRI += config.sri_max_2f self.alert_add( 'mcb_PA', 'Mass coral bleaching (very high in-situ sea temperature + very high light)', sri, [ parsurf, seandbc]) self.retract( parsurf) self.retract( seandbc) ##Ecoforecast Rule #12: Coral-Bleaching-wA ##Description: Mass coral bleaching (very high in-situ sea temperature + very low wind) @pk.Rule(pk.AS.windsp << fact.windsp( fuzzyI=anyof('dLow'), fuzzyTod= anyof('morn', 'midd', 'psun', 'dayl', 'dayb', 'aftn', 'all')), #removed "vLow" to match MatLab restrictions better pk.AS.seandbc << fact.seandbc( fuzzyI=anyof('vHigh', 'dHigh'), fuzzyTod= pk.W())) def mcb_wA(self, windsp, seandbc): print("\t "+windsp["date"]+" Coral-Bleaching-wA fired.") fact_display( windsp) fact_display( seandbc) sri= sri_calc( windsp) +sri_calc(seandbc) self.SRI += sri self.MaxSRI += config.sri_max_2f self.alert_add( 'mcb_wA', 'Mass coral bleaching (very high in-situ sea temperature + very low wind)', sri, [ windsp, seandbc]) self.retract( windsp) self.retract( seandbc) ##Ecoforecast Rule #13: Coral-Bleaching-w3E ##Description: Mass coral bleaching (high 'shallow' sea temperature + doldrums) @pk.Rule(pk.AS.windsp3day << fact.windsp3day(fuzzyI=anyof('dLow', 'vLow', 'Low'), fuzzyTod=pk.W()), pk.AS.sea1m << fact.sea1m( fuzzyI=anyof('High', 'dHigh', 'vHigh'), fuzzyTod=pk.W())) def mcb_w3E(self, windsp3day, sea1m): print("\t "+windsp3day["date"]+" Coral-Bleaching-w3E fired.") fact_display( windsp3day) fact_display( sea1m) sri= sri_calc( windsp3day) +sri_calc( sea1m) self.SRI += sri self.MaxSRI += config.sri_max_2f self.alert_add( 'mcb_w3E', 'Mass coral bleaching (high \'shallow\' sea temperature + doldrums)', sri, [ windsp3day, sea1m]) self.retract( windsp3day) self.retract( sea1m) ##Ecoforecast Rule #14: Coral-Bleaching-PE ##Description: Mass coral bleaching (very high 'shallow' sea temperature + very high light) @pk.Rule(pk.AS.parsurf << fact.parsurf(fuzzyI=anyof('vHigh', 'dHigh'), fuzzyTod=anyof('midd', 'dayl', 'all')), pk.AS.sea1m << fact.sea1m( fuzzyI=anyof('vHigh', 'dHigh'), fuzzyTod=pk.W())) def mcb_PE(self, parsurf, sea1m): print("\t "+parsurf["date"]+" Coral-Bleaching-PE fired.") fact_display( parsurf) fact_display( sea1m) sri= sri_calc( parsurf) +sri_calc( sea1m) self.SRI += sri self.MaxSRI += config.sri_max_2f self.alert_add( 'mcb_PE', 'Mass coral bleaching (very high \'shallow\' sea temperature + very high light)', sri, [ parsurf, sea1m]) self.retract( parsurf) self.retract( sea1m) ##Ecoforecast Rule #15: Coral-Bleaching-wE ##Description: Mass coral bleaching (very high 'shallow' sea temperature + very low wind) @pk.Rule(pk.AS.windsp << fact.windsp(fuzzyI=anyof('dLow', 'vLow'), fuzzyTod=anyof('morn', 'midd', 'psun', 'dayl', 'dayb', 'aftn', 'all')), pk.AS.sea1m << fact.sea1m(fuzzyI=anyof('vHigh', 'dHigh'), fuzzyTod=pk.W())) def mcb_wE(self, windsp, sea1m): print("\t "+windsp["date"]+" Coral-Bleaching-wE fired.") fact_display( windsp) fact_display( sea1m) sri= sri_calc( windsp) +sri_calc( sea1m) self.SRI += sri self.MaxSRI += config.sri_max_2f self.alert_add( 'mcb_wE', 'Mass coral bleaching (very high \'shallow\' sea temperature + very low wind)', sri, [ windsp, sea1m]) self.retract( windsp) self.retract( sea1m) ##Ecoforecast Rule #16: Coral-Bleaching-PS ##Description: Mass coral bleaching (very high SST + very high light) @pk.Rule(pk.AS.parsurf << fact.parsurf(fuzzyI=anyof('vHigh', 'dHigh'), fuzzyTod=anyof('midd', 'dayl', 'all')), pk.AS.sst << fact.sst(fuzzyI=anyof('vHigh', 'dHigh'), fuzzyTod=pk.W())) def mcb_PS(self, parsurf, sst): print("\t "+parsurf["date"]+" Coral-Bleaching-PS fired.") fact_display( parsurf) fact_display( sst) sri= sri_calc( parsurf) +sri_calc( sst) self.SRI += sri self.MaxSRI += config.sri_max_2f self.alert_add( 'mcb_PS', 'Mass coral bleaching (very high SST + very high light)', sri, [ parsurf, sst]) self.retract( parsurf) self.retract( sst) ##Ecoforecast Rule #17: Coral-Bleaching-wS ##Description: Mass coral bleaching (very high SST + very low wind) @pk.Rule(pk.AS.windsp << fact.windsp(fuzzyI=anyof('dLow', 'vLow'), fuzzyTod=anyof('morn', 'midd', 'psun', 'dayl', 'dayb', 'aftn', 'all')), pk.AS.sst << fact.sst(fuzzyI=anyof('vHigh', 'dHigh'), fuzzyTod=pk.W())) def mcb_wS(self, windsp, sst): print("\t "+windsp["date"]+" Coral-Bleaching-wS fired.") fact_display( windsp) fact_display( sst) sri= sri_calc( windsp) +sri_calc( sst) self.SRI += sri self.MaxSRI += config.sri_max_2f self.alert_add( 'mcb_wS', 'Mass coral bleaching (very high SST + very low wind)', sri, [ windsp, sst]) self.retract( windsp) self.retract( sst) ##Ecoforecast Rule #18: Coral-Bleaching-B ##Description: Mass coral bleaching (Berkelmans bleaching curve) @pk.Rule(pk.AS.curveB << fact.curveB(fuzzyI=anyof('Conductive', 'vConductive'), fuzzyTod=pk.W())) def mcb_B(self, curveB): print("\t "+curveB["date"]+" Coral-Bleaching-B fired.") fact_display( curveB) sri= sri_calc( curveB) self.SRI += sri self.MaxSRI += config.sri_max_1f self.alert_add( 'mcb_B', 'Mass coral bleaching (Berkelmans bleaching curve)', sri, [ curveB]) self.retract( curveB) ##Ecoforecast Rule #19: Coral-Bleaching-A ##Description: Mass coral bleaching (drastic high in-situ sea temperature) @pk.Rule(pk.AS.seandbc << fact.seandbc( fuzzyI=anyof('dHigh'), fuzzyTod=pk.W())) def mcb_A(self, seandbc): print("\t "+seandbc["date"]+" Coral-Bleaching-A fired.") fact_display( seandbc) sri= sri_calc( seandbc) self.SRI += sri self.MaxSRI += config.sri_max_1f self.alert_add( 'mcb_A', 'Mass coral bleaching (drastic high in-situ sea temperature)', sri, [ seandbc]) self.retract( seandbc) ##Ecoforecast Rule #20: Coral-Bleaching-BB ##Description: Mass coral mortality (>50%) for local sensitive species (Berkelmans) @pk.Rule(pk.AS.curveB << fact.curveB(fuzzyI=anyof('Mortality', 'hMortality'), fuzzyTod=pk.W())) def mcb_BB(self, curveB): print("\t "+curveB["date"]+" Coral-Bleaching-BB fired.") fact_display( curveB) sri= sri_calc( curveB) self.SRI += sri self.MaxSRI += config.sri_max_1f self.alert_add( 'mcb_BB', 'Mass coral mortality (>50%) for local sensitive species (Berkelmans)', sri, [curveB]) self.retract( curveB) ##Ecoforecast Rule #21: Coral-Bleaching-EM ##Description: Mass coral bleaching (high monthly mean 'shallow' sea temperature) @pk.Rule(pk.AS.sea1mM << fact.sea1mM(fuzzyI=anyof('High', 'vHigh', 'dHigh'), fuzzyTod=pk.W())) def mcb_EM(self, sea1mM): print("\t "+sea1mM+" Coral-Bleaching-EM fired.") fact_display( sea1mM) sri = sri_calc( sea1mM) self.SRI += sri self.MaxSRI += config.sri_max_1f self.alert_add( 'mcb_EM', 'Mass coral bleaching (high monthly mean \'shallow\' sea temperature)', sri, [sea1mM]) self.retract( sea1mM) ##Ecoforecast Rule #22: Coral-Bleaching-AM ##Description: Mass coral bleaching (high monthly mean in situ sea temperature) @pk.Rule(pk.AS.seandbcM << fact.seandbcM(fuzzyI=anyof( 'vHigh', 'dHigh'), fuzzyTod=pk.W())) #removed "High" to match MatLab restrictions better def mcb_AM(self, seandbcM): print("\t "+seandbcM["date"]+" Coral-Bleaching-AM fired.") fact_display( seandbcM) sri= sri_calc( seandbcM) self.SRI += sri self.MaxSRI += config.sri_max_1f self.alert_add( 'mcb_AM', 'Mass coral bleaching (high monthly mean in situ sea temperature)', sri, [seandbcM]) self.retract( seandbcM) ##Ecoforecast Rule #23: Coral-Bleaching-E ##Description: Mass coral bleaching (drastic high 'shallow' sea temperature) @pk.Rule(pk.AS.sea1m << fact.sea1m(fuzzyI=pk.L('dHigh'), fuzzyTod=pk.W())) def mcb_E(self, sea1m): print("\t "+sea1m["date"]+" Coral-Bleaching-E fired.") fact_display( sea1m) sri= sri_calc( sea1m) self.SRI += sri self.MaxSRI += config.sri_max_1f self.alert_add( 'mcb_E', "Mass coral bleaching (drastic high \'shallow\' sea temperature)", sri, [sea1m]) self.retract( sea1m) ##Ecoforecast Rule #24: Coral-Bleaching-S ##Description: Mass coral bleaching (drastic high SST) @pk.Rule(pk.AS.sst << fact.sst(fuzzyI=pk.L('dHigh'), fuzzyTod=pk.W())) def mcb_S(self, sst): print("\t "+sst["date"]+" Coral-Bleaching-S fired.") fact_display( sst) sri= sri_calc( sst) self.SRI += sri self.MaxSRI += config.sri_max_1f self.alert_add( "mcb_S", "Mass coral bleaching (drastic high SST)", sri, [sst]) self.retract( sst)