Commit fa1a56ca authored by Greenwood, Scott's avatar Greenwood, Scott
Browse files

modified to auto create the setup.mos file (or language equivalent) in the...

modified to auto create the setup.mos file (or language equivalent) in the temp folder along with the simulator.mo file geing loaded
parent d246a8af
Loading
Loading
Loading
Loading
+16 −1
Original line number Diff line number Diff line
@@ -177,6 +177,21 @@ class AutoCSM:
            print(f"Failed to create the model: {str(e)}")
            raise

    def create_setup(self, *args: tuple, **kwargs: dict) -> None:
        """
        Creates the setup file for the simulation model.

        Args:
            *args: Additional positional arguments passed to the model creation method.
            **kwargs: Additional keyword arguments passed to the model creation method.
        """        
        try:
            return self._execute_with_animation("Creating the setup file...",
                                                self._language_method.create_setup, *args, **kwargs)
        except Exception as e:
            print(f"Failed to create the setup file: {str(e)}")
            raise
            
    def create_fmu(self, *args: tuple, **kwargs: dict) -> None:
        """
        Creates the Functional Mock-up Unit (FMU).
+47 −1
Original line number Diff line number Diff line
@@ -174,3 +174,49 @@ def convert_numbers_to_bracket_form(name):
    # Use regex to find numbers surrounded by underscores and replace with "[number]."
    new_name = re.sub(r'_(\d+)_', r'[\1].', name)
    return new_name
    
#%%
def overwrite_line_with_list(input_file, output_file, keyword, replacement, replaceLine=False):
    """
    Reads a text file, searches for a keyword, and either replaces the entire line or 
    just the keyword with the provided replacement. The modified content is saved to a new file.

    Parameters:
    -----------
    input_file : str
        The path to the input text file to be read.
    output_file : str
        The path to the output text file where the modified content will be written.
    keyword : str
        The keyword to search for in the lines of the text file.
    replacement : str or list of str
        The replacement content. If replacing a line, the replacement can be a string 
        or a list of strings (which will be joined with newline characters).
        If replacing the keyword within a line, this should be a string.
    replaceLine : bool, optional
        If True, replaces the entire line containing the keyword with the replacement content. 
        If False, only the keyword within the line is replaced. Defaults to False.

    Returns:
    --------
    None
    """
    # Open the input file for reading
    with open(input_file, 'r') as file:
        lines = file.readlines()

    # Replace the line containing the keyword with the replacement_list
    with open(output_file, 'w') as file:
        for line in lines:
            if keyword in line:
                if replaceLine:
                    # Write replacement in this line
                    file.write(replacement)
                else:
                   # Replace only the keyword in the line, keeping the rest of the line intact
                   new_line = line.replace(keyword, replacement)
                   file.write(new_line)
            else:
                # Write the line as-is if keyword not found
                file.write(line)
    
 No newline at end of file
+30 −0
Original line number Diff line number Diff line
@@ -83,6 +83,33 @@ class JuliaMethods(LanguageMethod):
        except Exception as e:
            raise RuntimeError(f"Failed to create model: {str(e)}")
            
    def create_setup(self, dependencies: list = None, **kwargs):
        """
        Generates an setup file for the simulation model.
        
        Args:
            dependencies (list[str], optional): List of dependencies required for FMU generation.
            **kwargs: Additional keyword arguments for FMU creation.
        
        Raises:
            RuntimeError: If FMU creation fails.
        """       
        # Verify dependencies
        dependencies = super().create_setup(dependencies, **kwargs)
        
        # Add required project and template dependencies
        dependencies = super()._add_required_dependencies(dependencies)

        # Add simulation file
        dependencies.append(pathlib.Path(self.parent.model_path).absolute().as_posix())
        
        template_path = (self.METHOD_PATH / '../UPDATEME.mos').as_posix()
        output_path = (pathlib.Path(self.parent.model_path).parent / 'UPDATEME.mos').as_posix()
        replacement = '{' + ',\n\t\t'.join(f'"{dep}"' for dep in dependencies) + '}'
        # Modify for language:
        # overwrite_line_with_list(template_path, output_path, 'TODO_ADD_DEPENDENCIES_HERE', replacement)
        print('No create_setup currently implemented. Skipping create_setup.')
            
    def create_fmu(self, dependencies: list = None, fmu_compiler: str = 'dymola', experimentSettings: dict = None, **kwargs):
        """
        Generates an FMU using the specified compiler.
@@ -99,6 +126,9 @@ class JuliaMethods(LanguageMethod):

        dependencies, experimentSettings = super().create_fmu(dependencies, fmu_compiler, experimentSettings, **kwargs)
    
        # Add required project and template dependencies
        dependencies = super()._add_required_dependencies(dependencies)
        
        # Use this to populate default dependencies
        # TODO: dependencies.append()
            
+37 −1
Original line number Diff line number Diff line
@@ -88,6 +88,18 @@ class LanguageMethod:
        
        return absolute_paths
    
    def _add_required_dependencies(self, dependencies: list = None):
        # Adds project package if not already in dependency list
        project_package = (pathlib.Path(self.parent.project_path) / 'package.mo').resolve()
        if project_package.as_posix() not in dependencies:
            dependencies.append(project_package.as_posix())
                
        # This avoids redefining the ExaDigiT method template if it already was included in the dependency in a different location (e.g., a customized version)
        exadigit_package  = self.METHOD_PATH if self.METHOD_PATH.parts[-1] == 'package.mo' else self.METHOD_PATH / 'package.mo'
        if '/'.join(list(exadigit_package.parts[-2:])) not in dependencies:
            dependencies.append(exadigit_package.as_posix())
        return dependencies
    
    @abstractmethod
    def create_architecture(self, template_folder: str = None, **kwargs):
        """
@@ -134,6 +146,29 @@ class LanguageMethod:
        
        return structure_path
    
    @abstractmethod
    def create_setup(self, dependencies: list = None, **kwargs):
        """
        Generates an setup file (e.g., setup.mos) to simplify use of the generated model (e.g., Simulator.mo) in non-fmu form.
        
        Args:
            dependencies Optional[List[str]] List of dependencies required for FMU generation. If not provided, uses defaults.
            **kwargs: Additional keyword arguments passed to the method.
            
        Note:
            This method must be implemented by child classes to handle architecture
            creation specific to the language (e.g., Modelica, etc.).
        """            

        # Verify dependencies are valid
        if dependencies is not None:
            dependencies = self.validate_and_convert_paths(dependencies)
        
        # Update input parameters
        dependencies = dependencies or []
        
        return dependencies
    
    @abstractmethod
    def create_fmu(self, dependencies: list = None, fmu_compiler: str = '', experimentSettings: dict = None, **kwargs):
        """
@@ -153,6 +188,7 @@ class LanguageMethod:
        self.validate_fmu_compiler(fmu_compiler)
            
        # Verify dependencies are valid
        if dependencies is not None:
            dependencies = self.validate_and_convert_paths(dependencies)
        
        # Update input parameters
+30 −11
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@ from ..language_method import LanguageMethod
from . import create_model_nested
from . import create_fmu_dymola
from . import create_architecture
from helper_functions import overwrite_line_with_list

class ModelicaMethods(LanguageMethod):
    """
@@ -95,6 +96,31 @@ class ModelicaMethods(LanguageMethod):
        except Exception as e:
            raise RuntimeError(f"Failed to create model: {str(e)}")
            
    def create_setup(self, dependencies: list = None, **kwargs):
        """
        Generates an setup file (i.e., setup.mos).
        
        Args:
            dependencies (list[str], optional): List of dependencies required for FMU generation.
            **kwargs: Additional keyword arguments for FMU creation.
        
        Raises:
            RuntimeError: If FMU creation fails.
        """      
        # Verify dependencies
        dependencies = super().create_setup(dependencies, **kwargs)
        
        # Add required project and template dependencies
        dependencies = super()._add_required_dependencies(dependencies)

        # Add simulation file
        dependencies.append(pathlib.Path(self.parent.model_path).absolute().as_posix())
        
        template_path = (self.METHOD_PATH / '../template_setup.mos').as_posix()
        output_path = (pathlib.Path(self.parent.model_path).parent / 'setup.mos').as_posix()
        replacement = '{' + ',\n\t\t'.join(f'"{dep}"' for dep in dependencies) + '}'
        overwrite_line_with_list(template_path, output_path, 'TODO_ADD_DEPENDENCIES_HERE', replacement)
        
    def create_fmu(self, dependencies: list = None, fmu_compiler: str = 'dymola', experimentSettings: dict = None, **kwargs):
        """
        Generates an FMU using the specified compiler.
@@ -108,18 +134,11 @@ class ModelicaMethods(LanguageMethod):
        Raises:
            RuntimeError: If FMU creation fails.
        """

        # Verify dependencies
        dependencies, experimentSettings = super().create_fmu(dependencies, fmu_compiler, experimentSettings, **kwargs)
    
        # Adds project package if not already in dependency list
        project_package = (pathlib.Path(self.parent.project_path) / 'package.mo').resolve()
        if project_package.as_posix() not in dependencies:
            dependencies.append(project_package.as_posix())
                
        # This avoids redefining the ExaDigiT method template if it already was included in the dependency in a different location (e.g., a customized version)
        exadigit_package  = self.METHOD_PATH if self.METHOD_PATH.parts[-1] == 'package.mo' else self.METHOD_PATH / 'package.mo'
        if '/'.join(list(exadigit_package.parts[-2:])) not in dependencies:
            dependencies.append(exadigit_package.as_posix())
        # Add required project and template dependencies
        dependencies = super()._add_required_dependencies(dependencies)
            
        try:
            if fmu_compiler == 'dymola':
Loading