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(",")] globalUtils.printWithFlush(paramNameList) globalUtils.printWithFlush(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) globalUtils.printWithFlush("经度参数个数 " + str(len(latValueList))) globalUtils.printWithFlush("纬度参数个数 " + str(len(lonValueList))) globalUtils.printWithFlush("太阳天顶角参数个数 " + str(len(saValueList))) globalUtils.printWithFlush("观察天顶角参数个数 " + str(len(szValueList))) globalUtils.printWithFlush("太阳方位角参数个数 " + str(len(vaValueList))) globalUtils.printWithFlush("观测方位角参数个数 " + str(len(vzValueList))) if not globalUtils.are_equal( len(latValueList), len(lonValueList), len(saValueList), len(szValueList), len(vaValueList), len(vzValueList), ): globalUtils.printWithFlush( "经度、纬度、太阳天顶角、观察天顶角、太阳方位角、观测方位角的参数个数不一致,请查看参数文件。" ) 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], ] ) # globalUtils.printWithFlush(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): globalUtils.printWithFlush(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() globalUtils.printWithFlush("execute dir: ", currentExeDir) # 获取当前文件的绝对路径 currentFile = os.path.realpath(__file__) # 获取当前文件的目录 currentDir = os.path.dirname(currentFile) # 切换到'/home' 目录 os.chdir(currentDir) globalUtils.printWithFlush("surface dir: ", currentDir) inputFilePath = os.path.join(inputDistDir, "input.txt") globalUtils.printWithFlush("surface input.txt: ", inputFilePath) globalUtils.printWithFlush(os.getcwd()) # 执行一次求解 result = toaRunModel(testDir) globalUtils.printWithFlush("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] globalUtils.printWithFlush(projectDir) # 从项目目录下拷贝参数文件过来 if not copyInputFiles(projectDir): globalUtils.printWithFlush("参数文件不完整") 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() globalUtils.printWithFlush(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外的所有异常 globalUtils.printWithFlush("发生异常:", str(e)) finally: # 无论是否发生异常,最终都会执行该代码块 globalUtils.printWithFlush("求解执行完毕!")