# -*- coding: utf-8 -*- """ Created on Tue Oct 31 16:12:55 2023 @author: ZMK """ import flopy.utils.binaryfile as bf import csv import Base as base import os import json import subprocess import re import ModelPeriod import numpy as np import AchiveReport #添加modle def addModelJson(model_name,start_time,end_time,remark): context="" prediction_path = base.prefix + "\\model_list.json" with open(prediction_path,encoding='utf-8') as f: context = json.load(f) array=[] for item in context: array.append(item) dicts={"model_name":model_name, "start_time":start_time,"end_time":end_time,"remark":remark} array.append(dicts) with open(prediction_path, "w",encoding='utf-8') as outfile: json.dump(array, outfile,ensure_ascii=False) return "保存完毕!"; #删除model def removeModelJson(model_name): context="" prediction_path = base.prefix + "\\model_list.json" with open(prediction_path,encoding='utf-8') as f: context = json.load(f) array=[] for item in context: if item["model_name"] != model_name: array.append(item) with open(prediction_path, "w",encoding='utf-8') as outfile: json.dump(array, outfile,ensure_ascii=False) return "删除模型完毕!"; def get_model_json(model_name): period_json="" prediction_path = base.model_dir + model_name +"\\prediction.json" with open(prediction_path,encoding='utf-8') as f: period_json = json.load(f) return period_json; def get_model_period(model_name): period_json= get_model_json(model_name) start_time = period_json["start_time"] end_time = period_json["end_time"] months = ModelPeriod.get_months_in_range_ym(start_time, end_time) return months; def is_cloned_model(model_name): paths = base.model_dir + model_name + "\\water_bal.txt" if os.path.exists(paths): return False return True #观测井chart def obsChartdata(wellId,model_name, row, column): row = int(row)-1 column = int(column)-1 dir="" period_json= get_model_json(model_name) start_time = period_json["start_time"] end_time = period_json["end_time"] xmonths = ModelPeriod.get_months_in_range_ym(start_time, end_time) if model_name == base.not_allowed_model: dir = base.baseModel2 + "\\modflow.head" else: dir = base.model_dir + model_name + "\\modflow.head" cloned = is_cloned_model(model_name) if cloned ==True: return {"y_data": [],"y_data2":[],"x_data":xmonths } head = bf.HeadFile(dir) alldata = head.get_alldata() #周期数 months = int(len(alldata)/3) ydata= [] result = {} for month in range(months): z1= alldata[int(month+1)*3-1,0,:,:] cell_data = float(z1[row][column]) ydata.append(round(cell_data,2)) y_data2=[] if model_name == base.not_allowed_model: array_data = np.loadtxt(base.obswell_data_path, dtype=str,encoding='utf-8') y_data2= getObsData(wellId,array_data) result = {"y_data": ydata,"y_data2":y_data2,"x_data": xmonths} return result def getObsData(wellId,array_data): result =[] new_list =[] for item in array_data: if item[0]==wellId: result.append(item[3]) for i in range(0,len(result),3): data =( float(result[i]) +float(result[i+1])+float(result[i+2]))/3 data = round(data,2) new_list.append(data) return new_list; def getRowCloumnById(index_id): row,column,count = 104,114,0 for i in range(row): for j in range(column): if index_id == count: return (i,j) count = count +1 return "" #地下水信息 def earthWaterChart(model_name, index_id): row_column = getRowCloumnById(index_id) row = row_column[0] column = row_column[1] period_json= get_model_json(model_name) start_time = period_json["start_time"] end_time = period_json["end_time"] xmonths = ModelPeriod.get_months_in_range_ym(start_time, end_time) dir = "" if model_name == base.not_allowed_model: dir = base.baseModel2 + "\\modflow.head" else: dir = base.model_dir + model_name + "\\modflow.head" cloned = is_cloned_model(model_name) if cloned ==True: return {"y_data": [],"x_data":xmonths } head = bf.HeadFile(dir) alldata = head.get_alldata() #周期数 months = int(len(alldata)/3) ydata= [] result = {} for month in range(months): z1= alldata[int(month+1)*3-1,0,:,:] cell_data = float(z1[row][column]) ydata.append(round(cell_data,2)) result = {"y_data": ydata, "x_data": xmonths} return result #导出csv文件 def exportCsV(model_name): dir = base.model_dir + model_name + "\\modflow.head" out_path = base.model_dir + model_name + "\\output\\" if not os.path.exists(out_path): os.mkdir(out_path) # z1= alldata[int(per1)*3,0,:,:] head = bf.HeadFile(dir) alldata = head.get_alldata() months = int(len(alldata)/3) layers = 3 #例如 0-36月 for month in range(months): for layer in range (layers): z_last= alldata[(month+1)*3-1,layer,:,:] filename = out_path + str(month+1) + '-' + str(layer+1) + '.csv' f = open(filename, 'w', newline='') writer = csv.writer(f) for p in z_last: writer.writerow(p) f.close() return out_path #水均衡计算 def waterEqu(model_name): if model_name == base.not_allowed_model: water_equ_path = base.prefix + "\\water_equ.json" with open(water_equ_path,encoding='utf-8') as f: data = json.load(f) return data else: year = model_name title =[year] dict ={"title":title} jx = get_model_json(model_name) dict["start_time"]=jx["start_time"] dict["end_time"]=jx["end_time"] paths=base.model_dir + model_name +"\\water_bal.txt" wat = water_balance(model_name, paths) in_data= round(wat[0]+ wat[1]+ wat[2]+ wat[3] , 4) out_data= round(wat[4] + wat[5] + wat[6], 4) inout = round(in_data-out_data, 4) float_data=[wat[0],wat[1],wat[2],wat[3],in_data, wat[4],wat[5], wat[6],out_data,inout] inarray=[] inarray.append({"name":"降水入渗量","value":wat[0]}) inarray.append({"name":"河流入渗量","value":wat[1]}) inarray.append({"name":"一层侧向补给量","value":wat[2]}) inarray.append({"name":"三层侧向补给量","value":wat[3]}) outarray=[] outarray.append({"name":"人工开采量","value":wat[4]}) outarray.append({"name":"一层侧向流出量","value":wat[5]}) outarray.append({"name":"三层侧向流出量","value":wat[6]}) pie1={str(year):inarray} pie2={str(year):outarray} dict["pie1"]=pie1 dict["pie2"]=pie2 array2d=[] array2d.append(["数据(亿立方米)"]) for i in range(len(float_data)): tmp=[] tmp.append(str(float_data[i])) array2d.append(tmp) dict["data"]=array2d return dict def run_zonebudget_bal(model_name): # 定义exe文件的路径和参数 exe_path = base.ZoneBudget64Exe txt_path = base.model_dir + model_name + "\\water_bal.txt\n" cell_path = base.model_dir + model_name + "\\modflow.flow\n" process = subprocess.Popen([exe_path], stdin=subprocess.PIPE,shell = True) process.stdin.write(txt_path.encode()) # 输入参数1 process.stdin.write(cell_path.encode()) process.stdin.write(b"title\n") process.stdin.write(base.water_bal_zones.encode()) process.stdin.write(b"A\n") output, _ = process.communicate() print(output) def run_zonebudget_res(model_name): # 定义exe文件的路径和参数 exe_path = base.ZoneBudget64Exe txt_path = base.model_dir + model_name + "\\water_res.txt\n" cell_path = base.model_dir + model_name + "\\modflow.flow\n" process = subprocess.Popen([exe_path], stdin=subprocess.PIPE,shell = True) process.stdin.write(txt_path.encode()) # 输入参数1 process.stdin.write(cell_path.encode()) process.stdin.write(b"title\n") process.stdin.write(base.water_res_zones.encode()) process.stdin.write(b"A\n") output, _ = process.communicate() print(output) def reg_find_int(text): numbers = re.findall(r'\d+', text) return numbers def read_txt(path): data =[] with open(path, 'r') as file: lines = file.readlines() for line in lines: data.append(line) return data #解析水均衡数据 def water_balance(model_name,paths): data= read_txt(paths) lens = len(data) index = 0 segment=[] dicts={} flag = 0 title="" while index < lens: strs = data[index].strip() if strs.startswith("Flow Budget for Zone"): segment=[] flag = 1 title=strs if strs.startswith("Percent Discrepancy"): segment.append(strs) numbers = reg_find_int(title) key = ','.join(numbers) dicts[key]=segment flag = 0 if flag ==1 : segment.append(strs) index=index+1 recharge = 0 for key in dicts: array = dicts[key] temp=[] for item in array: if item.startswith("RECHARGE") : strs = item.replace(" ", "").replace("RECHARGE=", "") temp.append(float(strs)) recharge += (temp[0]-temp[1]) #河流入渗量(正) 所有应力期,for Zone 3的WELLS项相加 zone3 = 0 for key in dicts: if key.startswith("3,"): array = dicts[key] temp=[] for item in array: if item.startswith("WELLS") : strs = item.replace(" ", "").replace("WELLS=", "") temp.append(float(strs)) zone3 += (temp[0]-temp[1]) #L1侧向补给量(正) 所有应力期,for Zone 4的IN-WELLS项相加 Zone4_in_well=0 for key in dicts: if key.startswith("4,"): array = dicts[key] for item in array: if item.startswith("WELLS") : strs = item.replace(" ", "").replace("WELLS=", "") data = float(strs) Zone4_in_well +=data break #L3侧向补给量(正) 所有应力期,for Zone 8的IN-WELLS项相加 Zone8_in_well =0 for key in dicts: if key.startswith("8,"): array = dicts[key] for item in array: if item.startswith("WELLS") : strs = item.replace(" ", "").replace("WELLS=", "") data = float(strs) Zone8_in_well +=data break #人工开采量(负) 所有应力期,for Zone 5的OUT-WELLS项相加 zone5out =0 for key in dicts: if key.startswith("5,"): array = dicts[key] for item in array: if item.startswith("WELLS") : strs = item.replace(" ", "").replace("WELLS=", "") data = float(strs) zone5out +=data #L1侧向流出量(负) 所有应力期,for Zone 4的OUT-WELLS项相加 Zone4_out_well=0 for key in dicts: if key.startswith("4,"): array = dicts[key] for item in array: if item.startswith("WELLS") : strs = item.replace(" ", "").replace("WELLS=", "") data = float(strs) Zone4_out_well +=data # L3=L3侧向流出量(负) L3=0.0 result =[recharge,zone3,Zone4_in_well,Zone8_in_well,zone5out,Zone4_out_well,L3] for i in range(len(result)): # 每行数据实际上计算 的是 一个step , 1个step =10天 result[i]= round(result[i]/100000000*10, 4) return result #解析水资源量数据 def water_res(model_name,paths): data= read_txt(paths) lens = len(data) index = 0 segment=[] dicts={} flag = 0 title="" while index < lens: strs = data[index].strip() if strs.startswith("Flow Budget for Zone"): segment=[] flag = 1 title=strs if strs.startswith("Percent Discrepancy"): segment.append(strs) numbers = reg_find_int(title) key = ','.join(numbers) dicts[key]=segment flag = 0 if flag ==1 : segment.append(strs) index=index+1 # 大气降水 for zone1里所有的recharge项相加(包括in和out) zone1_rechage = 0 for key in dicts: if key.startswith("1,"): array = dicts[key] temp=[] for item in array: if item.startswith("RECHARGE") : strs = item.replace(" ", "").replace("RECHARGE=", "") temp.append(float(strs)) zone1_rechage += (temp[0]-temp[1]) #永定河渗漏 for zone1里所有的zone2项相加(包括in和out) zone1_well = 0 for key in dicts: if key.startswith("1,"): array = dicts[key] indata,outdata= 0,0 for item in array: if item.startswith("Zone 2 to 1") : strs = item.replace(" ", "").replace("Zone2to1=", "") indata = float(strs) if item.startswith("Zone 1 to 2") : strs = item.replace(" ", "").replace("Zone1to2=", "") outdata = float(strs) zone1_well += (indata-outdata) #侧向流入 For zone7 里所有的zone8项相加(包括in和out) zone7=0 for key in dicts: if key.startswith("7,"): array = dicts[key] indata,outdata= 0,0 for item in array: if item.startswith("Zone 8 to 7") : strs = item.replace(" ", "").replace("Zone8to7=", "") indata = float(strs) if item.startswith("Zone 7 to 8") : strs = item.replace(" ", "").replace("Zone7to8=", "") outdata = float(strs) zone7 += (indata-outdata) #越流排泄 For zone6 里所有的zone7项相加(包括in和out) zone6 =0 for key in dicts: if key.startswith("6,"): array = dicts[key] indata,outdata= 0,0 for item in array: if item.startswith("Zone 7 to 6") : strs = item.replace(" ", "").replace("Zone7to6=", "") indata = float(strs) if item.startswith("Zone 6 to 7") : strs = item.replace(" ", "").replace("Zone6to7=", "") outdata = float(strs) zone6 += (indata-outdata) result =[zone1_rechage,zone1_well,zone7,zone6] for i in range(len(result)): result[i]= round(result[i]/100000000*10,4) return result #解析水资源量数据 def water_res_month(model_name,paths,per): data= read_txt(paths) lens = len(data) index = 0 segment=[] dicts={} flag = 0 title="" while index < lens: strs = data[index].strip() if strs.startswith("Flow Budget for Zone"): segment=[] flag = 1 title=strs if strs.startswith("Percent Discrepancy"): segment.append(strs) numbers = reg_find_int(title) key = ','.join(numbers) dicts[key]=segment flag = 0 if flag ==1 : segment.append(strs) index=index+1 # 大气降水 for zone1里所有的recharge项相加(包括in和out) zone1_rechage = 0 zone1_keys=[ "1,1,"+str(per+1),"1,2,"+str(per+1),"1,3,"+str(per+1)] for key in zone1_keys: array = dicts[key] temp=[] for item in array: if item.startswith("RECHARGE") : strs = item.replace(" ", "").replace("RECHARGE=", "") temp.append(float(strs)) zone1_rechage += (temp[0]-temp[1]) #永定河渗漏 for zone1里所有的zone2项相加(包括in和out) zone1_well = 0 zone1_well_keys=["1,1,"+str(per+1),"1,2,"+str(per+1),"1,3,"+str(per+1)] for key in zone1_well_keys: array = dicts[key] indata,outdata= 0,0 for item in array: if item.startswith("Zone 2 to 1") : strs = item.replace(" ", "").replace("Zone2to1=", "") indata = float(strs) if item.startswith("Zone 1 to 2") : strs = item.replace(" ", "").replace("Zone1to2=", "") outdata = float(strs) zone1_well += (indata-outdata) #侧向流入 For zone7 里所有的zone8项相加(包括in和out) zone7=0 zone7_keys=["7,1,"+str(per+1),"7,2,"+str(per+1),"7,3,"+str(per+1)] for key in zone7_keys: array = dicts[key] indata,outdata= 0,0 for item in array: if item.startswith("Zone 8 to 7") : strs = item.replace(" ", "").replace("Zone8to7=", "") indata = float(strs) if item.startswith("Zone 7 to 8") : strs = item.replace(" ", "").replace("Zone7to8=", "") outdata = float(strs) zone7 += (indata-outdata) #越流排泄 For zone6 里所有的zone7项相加(包括in和out) zone6 =0 zone6_keys=["6,1,"+str(per+1),"6,2,"+str(per+1),"6,3,"+str(per+1)] for key in zone6_keys: array = dicts[key] indata,outdata= 0,0 for item in array: if item.startswith("Zone 7 to 6") : strs = item.replace(" ", "").replace("Zone7to6=", "") indata = float(strs) if item.startswith("Zone 6 to 7") : strs = item.replace(" ", "").replace("Zone6to7=", "") outdata = float(strs) zone6 += (indata-outdata) result =[zone1_rechage,zone1_well,zone7,zone6] for i in range(len(result)): result[i]= round(result[i]/100000000*10, 4) return result #多模型的水位 def water_depth(model_name): name_array = model_name.split(",") yhyMatrix = np.loadtxt(base.water_yhy_path, dtype=str,encoding='utf-8') lshMatrix = np.loadtxt(base.water_lsh_path, dtype=str,encoding='utf-8') dbwMatrix = np.loadtxt(base.water_dbw_path, dtype=str,encoding='utf-8') res ={} #颐和园,莲石湖,东北旺的水平线和多模型的多折线值 yhydata=[] base1={"name":"地表高程","data":[52]*12} yhydata.append(base1) lshdata=[] base2={"name":"地表高程","data":[80]*12} lshdata.append(base2) dbwdata=[] base3={"name":"地表高程","data":[49]*12} dbwdata.append(base3) months = ModelPeriod.get_months_in_range_ym("2023-01","2023-12") for i in range(len(name_array)): if name_array[i] != '': index = muiltyModelIndex(name_array[i]) array1 = get_column(yhyMatrix,index) array2 = get_column(lshMatrix,index) array3 = get_column(dbwMatrix,index) yhydata.append({"name":name_array[i],"data":convertColumnData(array1)}) lshdata.append({"name":name_array[i],"data":convertColumnData(array2)}) dbwdata.append({"name":name_array[i],"data":convertColumnData(array3)}) rchMatrix = np.loadtxt(base.prefix + "base_water.ini", dtype=str,encoding='utf-8') riverMatrix = np.loadtxt(base.prefix + "base_river.ini", dtype=str,encoding='utf-8') pumpMatrix = np.loadtxt(base.prefix + "base_mining.ini", dtype=str,encoding='utf-8') rchdata=[] rch_base1 = rchMatrix[1] rch_base1_float =[] for i in range (0,len(rch_base1)): float_data = round(float(rch_base1[i])/9,2) rch_base1_float.append(float_data) rchdata.append({"name":"基准值","data":rch_base1_float}) riverdata=[] riverdata.append({"name":"基准值","data":riverMatrix.astype(float).tolist()}) pumpdata=[] pumpX=pumpMatrix[1] pump_float=[] for i in range (0,len(pumpX)): float_data = round(float(pumpX[i]),2) pump_float.append(float_data) pumpdata.append({"name":"基准值","data":pump_float}) res["xAxis"] = months res["yhy_line"] = yhydata res["lsh_line"] = lshdata res["dbw_line"] = dbwdata for i in range(len(name_array)): if name_array[i] != '': rchdata.append(rchBaseResult(rchMatrix,name_array[i])) riverdata.append(riverBaseResult(riverMatrix, name_array[i])) pumpdata.append(pumpBaseResult(pumpMatrix, name_array[i])) res["rch_line"] = rchdata res["river_line"] = riverdata res["pump_line"] = pumpdata yqsdata=[] pyqdata=[] sqdata=[] for i in range(len(name_array)): if name_array[i] != '': paths = base.muiltyModel + name_array[i] + "\\modflow.head" resdata = AchiveReport.getXs3LineChart(paths) pyqdata.append({"name":name_array[i],"data":resdata["pyq"]}) sqdata.append({"name":name_array[i],"data":resdata["sq"]}) yqsdata.append({"name":name_array[i],"data":resdata["yqs"]}) res["yqs_line"] = yqsdata res["sq_line"] = sqdata res["pyq_line"] = pyqdata return res #小场景水位 和变幅 def xs_depth(model_name): res={} line1,line2=[],[] paths = base.model_dir + model_name + "\\modflow.head" if model_name == base.not_allowed_model: paths = base.baseModel2 + "\\modflow.head" resdata = AchiveReport.getXs3LineChart(paths) line1.append({"name":"平原区","data":roundArray(resdata["pyq"])}) line1.append({"name":"山区","data":roundArray(resdata["sq"])}) line1.append({"name":"玉泉山地区","data":roundArray(resdata["yqs"])}) res["depth"] = line1 line2.append({"name":"平原区","data":xs_bf(resdata["pyq"])}) line2.append({"name":"山区","data":xs_bf(resdata["sq"])}) line2.append({"name":"玉泉山地区","data":xs_bf(resdata["yqs"])}) res["bf"] = line2 return res def xs_bf(array): newlist=[] newlist.append(0) lens = len(array)-1 for i in range(0,lens): x = array[i+1]-array[i] newlist.append(round(x,2)) return newlist def roundArray(array): newlist=[] for item in array: item = round(item,2) newlist.append(item) return newlist #rch 基准数据 def rchBaseResult(rchMatrix,sp): rchDict ={} rch_base1 = rchMatrix[1] rch_base2 = rchMatrix[2] rch_base3 = rchMatrix[3] trump = getmuiltyModelparam(sp) types = trump[0] rch_x = trump[1] if types ==1: temp = muiltyArray(rch_base1,rch_x) for i in range(0,len(temp)): temp[i] =round(temp[i]/9,2) rchDict={"name":sp,"data":temp} if types ==2: temp = muiltyArray(rch_base2,rch_x) for i in range(0,len(temp)): temp[i] =round(temp[i]/9,2) rchDict={"name":sp,"data":temp} if types ==3: temp = muiltyArray(rch_base3,rch_x) for i in range(0,len(temp)): temp[i] =round(temp[i]/9,2) rchDict={"name":sp,"data":temp} return rchDict #河流基准 数据 def riverBaseResult(riverMatrix,sp): trump = getmuiltyModelparam(sp) river_x = trump[2] riverDict={"name":sp,"data":muiltyArray(riverMatrix,river_x)} return riverDict #抽水井基准数据 def pumpBaseResult(pumpMatrix,sp): trump = getmuiltyModelparam(sp) pump_x =trump[3] pumpDict={"name":sp,"data":muiltyArray(pumpMatrix[1],pump_x)} return pumpDict def muiltyArray(array,scale): result =[] for item in array: x= round(float(item) * scale,2) result.append(x) return result def convertColumnData(array): result =[] new_list=[] for i in range(len(array)): if i!= 0: data = transToNum(array[i]) result.append(data) for index in range(len(result)): if index % 3 == 0: new_list.append(result[index]) return new_list def transToNum(str): data = 0 try: data= round(float(str),2) return data except ValueError(): return 0 #获取预测场景的下标值, 需要从ini 文件中按照列进行读取 def muiltyModelIndex(name): models= muiltyModelList() indexs = models.index(name) return indexs #预测模型列表 def muiltyModelList(): models=["SP0-0","SP1-1","SP1-2","SP1-3","SP2-1","SP2-2","SP2-3","SP3-1", "SP3-2","SP3-4","SP3-5","SP3-6","SP3-7","SP4-1","SP4-7"] return models #Np获取某一列的值 def get_column(matrix, column_number): column = matrix[:, column_number] return column #元组中 1=降雨类型 2=倍数 3,河流倍数 4,抽水井倍数 def getmuiltyModelparam(sp): dicts={ "SP0-0":(1,1,1,1), "SP1-1":(2,1,1,1), "SP1-2":(3,1,1,1), "SP1-3":(3,1.2,1,1), "SP2-1":(1,1,2,1), "SP2-2":(1,1,5,1), "SP2-3":(1,1,10,1), "SP3-1":(1,1,1,0.25), "SP3-2":(1,1,1,0.5), "SP3-4":(1,1,1,0), "SP3-5":(1,1,1,0.4), "SP3-6":(1,1,1,0.3), "SP3-7":(1,1,1,0.6), "SP4-1":(1,1,2,0.5), "SP4-7":(3,1.2,10,0)} return dicts[sp]