You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

299 lines
9.0 KiB
Python

import subprocess, os, time, shutil, configparser, sys
# 获取当前文件的父目录的绝对路径
current_dir = os.path.dirname(os.path.abspath(__file__))
# 获取父目录的绝对路径
parent_dir = os.path.abspath(os.path.join(current_dir, os.pardir))
# 将父目录添加到 Python 模块搜索路径中
sys.path.append(parent_dir)
from Utils import utils as globalUtils
# python.exe main.py E:\01-Projects\01-CAE-FullLink\output\workingDir\test06\SurfaceCharacteristicSimulation
inputDir = "input/"
inputDistDir = "Dir_REF/"
outputSourceDir = "Dir_REF/"
outputDistDir = "output/"
def readParamValueList(paramFilePath: str):
paramValueList = []
with open(paramFilePath, "r", encoding="utf-8") as file:
for line in file:
paramValueList = paramValueList + [float(x) for x in line.split(",")]
return paramValueList
# 读取输入文件,生成所有组合的值
def readInput() -> list:
# 读取input_surface.txt获取每个参数文件公共内容部分
inputfilePath = inputDir + "input_surface.txt"
paramNameList = ""
publicParamValueList = []
with open(inputfilePath, "r", encoding="utf-8") as file:
lines = file.readlines()
paramNameList = lines[0]
publicParamValueList = [int(x) for x in lines[1].split(",")]
print(paramNameList)
print(publicParamValueList)
# 依次读取 Lat、Lon、SA、SZ、VA、VZ
latFilePath = inputDir + "Lat.txt"
latValueList = readParamValueList(latFilePath)
lonFilePath = inputDir + "Lon.txt"
lonValueList = readParamValueList(lonFilePath)
saFilePath = inputDir + "SA.txt"
saValueList = readParamValueList(saFilePath)
szFilePath = inputDir + "SZ.txt"
szValueList = readParamValueList(szFilePath)
vaFilePath = inputDir + "VA.txt"
vaValueList = readParamValueList(vaFilePath)
vzFilePath = inputDir + "VZ.txt"
vzValueList = readParamValueList(vzFilePath)
print("经度参数个数 " + str(len(latValueList)))
print("纬度参数个数 " + str(len(lonValueList)))
print("太阳天顶角参数个数 " + str(len(saValueList)))
print("观察天顶角参数个数 " + str(len(szValueList)))
print("太阳方位角参数个数 " + str(len(vaValueList)))
print("观测方位角参数个数 " + str(len(vzValueList)))
if not globalUtils.are_equal(
len(latValueList),
len(lonValueList),
len(saValueList),
len(szValueList),
len(vaValueList),
len(vzValueList),
):
print(
"经度、纬度、太阳天顶角、观察天顶角、太阳方位角、观测方位角的参数个数不一致,请查看参数文件。"
)
return []
# 参数内容列表
paramContentList = []
for index, lat in enumerate(latValueList):
lon = lonValueList[index]
sa = saValueList[index]
sz = szValueList[index]
va = vaValueList[index]
vz = vzValueList[index]
paramContentList.append(
[
publicParamValueList[0],
lon,
lat,
sz,
vz,
sa,
va,
publicParamValueList[1],
publicParamValueList[2],
]
)
# print(latValueList)
# return [paramNameList, paramValueList.split(",")]
return [paramNameList, paramContentList]
# 从项目目录下拷贝参数文件过来
def copyInputFiles(projectDir: str) -> bool:
# 先删除,再创建
globalUtils.rmPath(inputDir)
os.mkdir(inputDir)
inputFileList = [
"input_surface.txt",
"Lat.txt",
"Lon.txt",
"SA.txt",
"SZ.txt",
"VA.txt",
"VZ.txt",
]
for inputFile in inputFileList:
inputFileProjectPath = os.path.join(projectDir, inputFile)
if not os.path.isfile(inputFileProjectPath):
print(f"{inputFileProjectPath} is not file or exist")
return False
inputFileSolverPath = os.path.join(inputDir, inputFile)
shutil.copy(inputFileProjectPath, inputFileSolverPath)
return True
# 执行一次求解
def executeCompute(
inputFile: str, paramNameList, paramContent, outputSourceFile, outputDistFile
):
# 先删除旧的input.txt
globalUtils.rmPath(inputFile)
# 生成新的input.txt
with open(inputFile, "w") as file:
file.write(paramNameList)
file.write(paramContent)
# 先删除旧的output.txt
globalUtils.rmPath(outputSourceFile)
# 启动求解任务
result = subprocess.run(["Cal_REF/Cal_REF.exe", "Dir_REF/input.txt"], cwd="Cal_REF")
# 循环等待结果文件的生成,然后进行移动
while 1:
time.sleep(3)
# 如果文件生成,且没有被其他程序打开(被其他程序访问,例如:正在往里写文件)
if os.path.isfile(outputSourceFile) and not globalUtils.isFileOpen(
outputSourceFile
):
os.rename(outputSourceFile, outputDistFile)
break
return result
# 其它模块调用本模块的求解(大气模块调用)
def toaRunModel(surFileDir: str):
# 提供的目录下有 input.txt没有output.txt
inputSourceFile = os.path.join(surFileDir, "input.txt")
outputDistFile = os.path.join(surFileDir, "output.txt")
# 求解时的 input.txt和output.txt
inputFilePath = os.path.join(inputDistDir, "input.txt")
outputSourceFile = os.path.join(inputDistDir, "output.txt")
# 第1步拷贝inputFile到
with open(inputSourceFile, "r", encoding="utf-8") as file:
lines = file.readlines()
if len(lines) < 2:
return None
return executeCompute(
inputFilePath, lines[0], lines[1], outputSourceFile, outputDistFile
)
def test(testDir: str):
currentExeDir = os.getcwd()
print("execute dir: ", currentExeDir)
# 获取当前文件的绝对路径
currentFile = os.path.realpath(__file__)
# 获取当前文件的目录
currentDir = os.path.dirname(currentFile)
# 切换到'/home' 目录
os.chdir(currentDir)
print("surface dir: ", currentDir)
inputFilePath = os.path.join(inputDistDir, "input.txt")
print("surface input.txt: ", inputFilePath)
print(os.getcwd())
# 执行一次求解
result = toaRunModel(testDir)
print("surface run ok:", result)
# 切换回之前的目录
os.chdir(currentExeDir)
pass
def generateImgPng():
imgFileDir = "postProcessing"
pngFileDir = "output"
caseList = ["Case1", "Case2"]
for case in caseList:
imgList = ["07.REF.img", "08.REF.img", "09.REF.img", "10.REF.img"]
for imgFile in imgList:
imgFilePath = os.path.join(imgFileDir, case + "/reflectance/" + imgFile)
pngFilePath = os.path.join(
pngFileDir, case + "-" + imgFile.replace(".img", ".png")
)
pngFilePath = globalUtils.saveENVIImgToPng(imgFilePath, pngFilePath)
pass
def main():
# 项目目录的output求解结束后传回到项目目录下
projectDir = sys.argv[1]
print(projectDir)
# 从项目目录下拷贝参数文件过来
if not copyInputFiles(projectDir):
print("参数文件不完整")
return
# 读取参数文件
paramContentValue = readInput()
if len(paramContentValue) == 0:
return
paramNameList = paramContentValue[0]
paramContentList = paramContentValue[1]
# 读取配置文件
# 创建 ConfigParser 对象
config = configparser.ConfigParser()
config.read("config.ini")
taskNum = int(config.get("settings", "taskNum"))
# 生成的结果文件
outputSourceFile = outputSourceDir + "output.txt"
inputFile = inputDistDir + "input.txt"
# 删除之前的输出文件目录,创建新的目录
globalUtils.rmPath(outputDistDir)
os.mkdir(outputDistDir)
# 获取当前时间戳
timestamp = time.time()
# 根据任务数进行求解
for index, paramContent in enumerate(paramContentList):
# 只计算200个
if index == taskNum:
break
result = executeCompute(
inputFile,
paramNameList,
",".join(map(str, paramContent)),
outputSourceFile,
outputDistDir + "output" + str(index) + ".txt",
)
runTimestamp = time.time()
print(result, index, runTimestamp - timestamp)
timestamp = runTimestamp
# 生成后处理图片
generateImgPng()
# 项目目录下的output目录
projectOutputDir = os.path.join(projectDir, "output")
# 删除项目目录下旧的结果文件
globalUtils.rmPath(projectOutputDir)
# 将结果拷贝到目的目录
shutil.copytree(outputDistDir, projectOutputDir)
pass
# 主函数
if __name__ == "__main__":
try:
# 尝试执行的代码块
main()
except Exception as e:
# 捕获除了ZeroDivisionError外的所有异常
print("发生异常:", str(e))
finally:
# 无论是否发生异常,最终都会执行该代码块
print("求解执行完毕!")