def opl_run(mod_file, input_tdf, input_dat, soln_tdf, infinity=INFINITY, oplrun_path=None): """ solve an optimization problem using an OPL .mod file :param mod_file: An OPL .mod file. :param input_tdf: A TicDatFactory defining the input schema :param input_dat: A TicDat object consistent with input_tdf :param soln_tdf: A TicDatFactory defining the solution schema :param infinity: A number used to represent infinity in OPL :return: a TicDat object consistent with soln_tdf, or None if no solution found """ verify(os.path.isfile(mod_file), "mod_file %s is not a valid file."%mod_file) verify(not find_case_space_duplicates(input_tdf), "There are case space duplicate field names in the input schema.") verify(not find_case_space_duplicates(soln_tdf), "There are case space duplicate field names in the solution schema.") verify(len({input_tdf.opl_prepend + t for t in input_tdf.all_tables}.union( {soln_tdf.opl_prepend + t for t in soln_tdf.all_tables})) == len(input_tdf.all_tables) + len(soln_tdf.all_tables), "There are colliding input and solution table names.\nSet opl_prepend so " + "as to insure the input and solution table names are effectively distinct.") msg = [] verify(input_tdf.good_tic_dat_object(input_dat, msg.append), "tic_dat not a good object for the input_tdf factory : %s"%"\n".join(msg)) orig_input_tdf, orig_soln_tdf = input_tdf, soln_tdf input_tdf = _fix_fields_with_opl_keywords(input_tdf) soln_tdf = _fix_fields_with_opl_keywords(soln_tdf) input_dat = input_tdf.TicDat(**make_json_dict(orig_input_tdf, input_dat)) assert input_tdf.good_tic_dat_object(input_dat) mod_file_name = os.path.basename(mod_file)[:-4] with open(mod_file, "r") as f: mod = f.read() assert 'writeOutputToFile()' in mod assert ("ticdat_" + mod_file_name + ".mod") in mod assert ("ticdat_" + mod_file_name + "_output.mod") in mod working_dir = os.path.abspath(os.path.dirname(mod_file)) if tu.development_deployed_environment: working_dir = os.path.join(working_dir, "oplticdat_%s"%uuid.uuid4()) shutil.rmtree(working_dir, ignore_errors = True) os.mkdir(working_dir) working_dir = os.path.abspath(working_dir) _ = os.path.join(working_dir, os.path.basename(mod_file)) shutil.copy(mod_file, _) mod_file = _ datfile = os.path.join(working_dir, "temp.dat") output_txt = os.path.join(working_dir, "output.txt") results_dat = os.path.join(working_dir, "results.dat") if os.path.isfile(results_dat): os.remove(results_dat) with open(datfile, "w") as f: f.write(create_opl_text(input_tdf, input_dat, infinity)) verify(os.path.isfile(datfile), "Could not create temp.dat") with open(os.path.join(working_dir, "ticdat_"+mod_file_name+".mod"), "w") as f: f.write("/* Autogenerated input file, created by opl.py on " + time.asctime() + " */\n") f.write(create_opl_mod_text(orig_input_tdf)) with open(os.path.join(working_dir,"ticdat_"+mod_file_name+"_output.mod"), "w") as f: f.write("/* Autogenerated output file, created by opl.py on " + time.asctime() + " */\n") f.write(create_opl_mod_output_text(orig_soln_tdf)) if not oplrun_path: verify_str = "need to either pass oplrun_path argument or run oplrun_setup.py" if tu.development_deployed_environment: verify_str = "could not find oplrun. Make sure the Application Type is set correctly" verify(os.path.isfile(os.path.join(_code_dir(),"oplrun_path.txt")), verify_str) with open(os.path.join(_code_dir(),"oplrun_path.txt"),"r") as f: oplrun_path = f.read().strip() verify(os.path.isfile(oplrun_path), "%s not a valid path to oplrun"%oplrun_path) if tu.development_deployed_environment: if "LD_LIBRARY_PATH" not in os.environ.keys(): os.environ["LD_LIBRARY_PATH"] = os.path.abspath(os.path.join(oplrun_path,'..')) elif not oplrun_path in os.environ["LD_LIBRARY_PATH"]: os.environ["LD_LIBRARY_PATH"] = os.path.abspath(os.path.join(oplrun_path,'..')) + \ ":" + os.environ["LD_LIBRARY_PATH"] try: output = subprocess.check_output([oplrun_path, mod_file, datfile], stderr=subprocess.STDOUT) except subprocess.CalledProcessError as err: if tu.development_deployed_environment: raise Exception("oplrun failed to complete: " + err.output) output = err.output with open(output_txt, "w") as f: f.write(str(output)) if not os.path.isfile(results_dat): print("%s is not a valid file. A solution was likely not generated. Check 'output.txt' for details."%results_dat) return None with open(results_dat, "r") as f: output = f.read() soln_tdf = _unfix_fields_with_opl_keywords(soln_tdf) return read_opl_text(soln_tdf, output, False)
def lingo_run(lng_file, input_tdf, input_dat, soln_tdf, infinity=INFINITY, runlingo_path=None): """ solve an optimization problem using an Lingo .lng file :param lng_file: An Lingo .lng file. :param input_tdf: A TicDatFactory defining the input schema :param input_dat: A TicDat object consistent with input_tdf :param soln_tdf: A TicDatFactory defining the solution variables :param infinity: A number used to represent infinity in Lingo :param runlingo_path: A path to the runlingo executable :return: a TicDat object consistent with soln_tdf, or None if no solution found """ verify(os.path.isfile(lng_file), "lng_file %s is not a valid file."%lng_file) verify(not find_case_space_duplicates(input_tdf), "There are case space duplicate field names in the input schema.") verify(not find_case_space_duplicates(soln_tdf), "There are case space duplicate field names in the solution schema.") verify(len({input_tdf.lingo_prepend + t for t in input_tdf.all_tables}.union( {soln_tdf.lingo_prepend + t for t in soln_tdf.all_tables})) == len(input_tdf.all_tables) + len(soln_tdf.all_tables), "There are colliding input and solution table names.\nSet lingo_prepend so " + "as to insure the input and solution table names are effectively distinct.") msg = [] verify(input_tdf.good_tic_dat_object(input_dat, msg.append), "tic_dat not a good object for the input_tdf factory : %s"%"\n".join(msg)) mapping = _try_create_space_case_mapping(input_tdf, input_dat) verify("failures" not in mapping, "The following case-space mapping data collisions were found.\n%s"% mapping.get("failures")) input_dat = _apply_space_case_mapping(input_tdf, input_dat, {v:k for k,v in mapping["mapping"].items()}) orig_input_tdf, orig_soln_tdf = input_tdf, soln_tdf input_dat = input_tdf.TicDat(**make_json_dict(orig_input_tdf, input_dat)) assert input_tdf.good_tic_dat_object(input_dat) lng_file_name = os.path.basename(lng_file)[:-4] with open(lng_file, "r") as f: lng = f.read() assert ("ticdat_" + lng_file_name + ".lng") in lng assert ("ticdat_" + lng_file_name + "_output.ldt") in lng assert ("ticdat_" + lng_file_name + ".ldt") in lng working_dir = os.path.abspath(os.path.dirname(lng_file)) if tu.development_deployed_environment: working_dir = os.path.join(working_dir, "lingoticdat_%s"%uuid.uuid4()) shutil.rmtree(working_dir, ignore_errors = True) os.mkdir(working_dir) working_dir = os.path.abspath(working_dir) _ = os.path.join(working_dir, os.path.basename(lng_file)) shutil.copy(lng_file, _) lng_file = _ commandsfile = os.path.join(working_dir, "ticdat_"+lng_file_name+".ltf") ldtfile = os.path.join(working_dir, "ticdat_"+lng_file_name+".ldt") output_txt = os.path.join(working_dir, "output.txt") soln_tables = {t for t, pk in soln_tdf.primary_key_fields.items() if pk} results = [] for tbn in soln_tables: fn = os.path.join(working_dir, tbn+".ldt") if os.path.isfile(fn): os.remove(fn) results.append(fn) with open(ldtfile, "w") as f: f.write(create_lingo_text(input_tdf, input_dat, infinity)) verify(os.path.isfile(ldtfile), "Could not create ticdat_" + lng_file_name+".ldt") with open(os.path.join(working_dir, "ticdat_"+lng_file_name+".lng"), "w") as f: f.write("! Autogenerated input file, created by lingo.py on " + time.asctime() + " ;\n") f.write(create_lingo_mod_text(orig_input_tdf)) with open(os.path.join(working_dir,"ticdat_"+lng_file_name+"_output.ldt"), "w") as f: f.write("! Autogenerated output file, created by lingo.py on " + time.asctime() + " ;\n") f.write(create_lingo_output_text(orig_soln_tdf)) commands = [ "! Autogenerated commands file, created by lingo.py on " + time.asctime() + " ;", "TAKE " + lng_file, "GO", "QUIT" ] with open(commandsfile, "w") as f: f.write("\n".join(commands)) if not runlingo_path: if 'TICDAT_LINGO_PATH' in os.environ: runlingo_path = os.environ['TICDAT_LINGO_PATH'] else: verify(os.path.isfile(os.path.join(_code_dir(),"runlingo_path.txt")), "need to either pass runlingo_path argument or run lingo_run_setup.py") with open(os.path.join(_code_dir(),"runlingo_path.txt"),"r") as f: runlingo_path = f.read().strip() verify(os.path.isfile(runlingo_path), "%s not a valid path to runlingo"%runlingo_path) output = '' try: output = subprocess.check_output([runlingo_path, commandsfile], stderr=subprocess.STDOUT, cwd=working_dir) except subprocess.CalledProcessError as err: if tu.development_deployed_environment: raise Exception("runlingo failed to complete: " + str(err.output)) with open(output_txt, "w") as f: f.write(str(output)) output_data = {} for i in zip(soln_tables,results): if not os.path.isfile(i[1]): print("%s is not a valid file. A solution was likely not generated. Check 'output.txt' for details."%i[1]) return None with open(i[1], "r") as f: output_data[i[0]] = f.read() rtn = read_lingo_text(soln_tdf, output_data) return _apply_space_case_mapping(soln_tdf, rtn, mapping["mapping"])