CellMLToSharedLibraryConverter.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "CellMLToSharedLibraryConverter.hpp"
00030
00031 #include <sstream>
00032 #include <unistd.h>
00033 #include <sys/stat.h>
00034 #include <ctime>
00035
00036 #include "Exception.hpp"
00037 #include "ChasteBuildRoot.hpp"
00038 #include "PetscTools.hpp"
00039 #include "DynamicModelLoaderRegistry.hpp"
00040
00041 DynamicCellModelLoader* CellMLToSharedLibraryConverter::Convert(const FileFinder& rFilePath,
00042 bool isCollective)
00043 {
00044 DynamicCellModelLoader* p_loader;
00045 std::string absolute_path = rFilePath.GetAbsolutePath();
00046
00047 if (!rFilePath.Exists())
00048 {
00049 EXCEPTION("Dynamically loadable cell model '" + absolute_path + "' does not exist.");
00050 }
00051
00052 size_t dot_position = absolute_path.find_last_of(".");
00053 if (dot_position == std::string::npos)
00054 {
00055 EXCEPTION("File does not have an extension: " + absolute_path);
00056 }
00057 std::string extension = absolute_path.substr(dot_position+1);
00058 if (extension == "cellml")
00059 {
00060
00061 size_t slash_position = absolute_path.find_last_of("/\\");
00062 assert(slash_position != std::string::npos);
00063 std::string folder = absolute_path.substr(0, slash_position+1);
00064 std::string leaf = absolute_path.substr(slash_position+1, dot_position-slash_position);
00065 std::string so_path = folder + "lib" + leaf + "so";
00066
00067 FileFinder so_file(so_path, cp::relative_to_type::absolute);
00068 if (!so_file.Exists() || rFilePath.IsNewerThan(so_file))
00069 {
00070 if (!isCollective)
00071 {
00072 EXCEPTION("Unable to convert .cellml to .so unless called collectively, due to possible race conditions.");
00073 }
00074 ConvertCellmlToSo(absolute_path, folder, leaf);
00075 }
00076
00077 p_loader = DynamicModelLoaderRegistry::Instance()->GetLoader(so_file);
00078 }
00079 else if (extension == "so")
00080 {
00081
00082 p_loader = DynamicModelLoaderRegistry::Instance()->GetLoader(rFilePath);
00083 }
00084 else
00085 {
00086 EXCEPTION("Unsupported extension '." + extension + "' of file '" + absolute_path + "'; must be .so or .cellml");
00087 }
00088
00089 return p_loader;
00090 }
00091
00092 void CellMLToSharedLibraryConverter::ConvertCellmlToSo(const std::string& rCellmlFullPath,
00093 const std::string& rCellmlFolder,
00094 const std::string& rModelLeafName)
00095 {
00096 std::string tmp_folder, build_folder;
00097 try
00098 {
00099
00100 if (PetscTools::AmMaster())
00101 {
00102
00103 std::stringstream folder_name;
00104 folder_name << "dynamic/tmp_" << getpid() << "_" << time(NULL);
00105 tmp_folder = std::string(ChasteBuildRootDir()) + "heart/" + folder_name.str();
00106 build_folder = std::string(ChasteBuildRootDir()) + "heart/build/" + ChasteBuildDirName() + "/" + folder_name.str();
00107 int ret = mkdir(tmp_folder.c_str(), 0700);
00108 if (ret != 0)
00109 {
00110 NEVER_REACHED;
00111 }
00112
00113 EXPECT0(system, "cp " + rCellmlFullPath + " " + tmp_folder);
00114
00115 EXPECT0(system, "./python/ConvertCellModel.py -y --normal " + tmp_folder + "/" + rModelLeafName + "cellml");
00116
00117 EXPECT0(system, "scons dyn_libs_only=1 build=" + ChasteBuildType() + " " + tmp_folder);
00118
00119 EXPECT0(system, "cp " + tmp_folder + "/lib" + rModelLeafName + "so " + rCellmlFolder);
00120
00121 EXPECT0(system, "rm -r " + build_folder);
00122 EXPECT0(system, "rm -r " + tmp_folder);
00123 }
00124 }
00125 catch (Exception& e)
00126 {
00127 PetscTools::ReplicateException(true);
00128
00129 EXPECT0(system, "rm -rf " + build_folder);
00130 EXPECT0(system, "rm -r " + tmp_folder);
00131 EXCEPTION("Conversion of CellML to Chaste shared object failed. Error was: " + e.GetMessage());
00132 }
00133
00134
00135 PetscTools::ReplicateException(false);
00136 }