def importScene(filePath):
    '''
    **Return the graph of a SOFA scene**

    Thanks to the SOFA Launcher, it will launch a templated scene that 
    will extract from an original scene its content as 2 dictionnaries containing: 
        - The different Sofa.node of the scene keeping there hierarchy
        - All the SOFA component contained in each node with the node.name as key

    +----------+------+---------------------------------+
    | argument | type | definition                      |
    +==========+======+=================================+
    | filePath | str  | Absolute path to the SOFA scene |
    +----------+------+---------------------------------+
    '''
    numiterations = 1
    filename = "importScene.py"
    path = os.path.dirname(os.path.abspath(__file__)) + '/template/'
    filesandtemplates = [(open(path + filename).read(), filename)]

    listSofaScene = [{
        "ORIGINALSCENE": filePath,
        "nbIterations": numiterations
    }]

    results = startSofa(listSofaScene,
                        filesandtemplates,
                        launcher=SerialLauncher())

    with open(results[0]["directory"] + '/graphScene.yml', 'r') as ymlfile:
        cfg = yaml.load(ymlfile)

    return cfg
Example #2
0
    def phase1(self, phasesToExecute=None):
        """
        **The step will launch in parallel multiple Sofa scene (nbrCPU by nbrCPU number of scene) until
        it has run all the scene in the sequence.** 

        +-----------------+-----------+----------------------------------------------------------+
        | argument        | type      | definition                                               |
        +=================+===========+==========================================================+
        | phasesToExecute | list(int) || Allow to choose which phase to execute for the reduction|
        |                 |           || *more details see* :py:func:`setListSofaScene`          |
        +-----------------+-----------+----------------------------------------------------------+
        
        To run the SOFA scene in parallele we use the ``sofa launcher`` utility

        What does it do to each scene:

            - Add animation to each :py:class:`.ObjToAnimate` we want for our model in the predifined sequence
            - Add a componant to save the shaking resulting states (WriteState)
            - Take all the resulting states files and combines them in one file put in the ``debug`` dir with a debug scene

        """
        start_time = time.time()

        if not phasesToExecute:
            phasesToExecute = list(
                range(self.reductionAnimations.nbPossibility))

        self.setListSofaScene(phasesToExecute)

        filenames = ["phase1_snapshots.py", "debug_scene.py"]
        filesandtemplates = []
        for filename in filenames:
            filesandtemplates.append(
                (open(pathToTemplate + filename).read(), filename))

        results = startSofa(self.listSofaScene,
                            filesandtemplates,
                            launcher=ParallelLauncher(self.nbrCPU))

        if self.verbose:
            for res in results:
                print("Results: ")
                print("    directory: " + res["directory"])
                print("        scene: " + res["scene"])
                print("     duration: " + str(res["duration"]) + " sec")

        self.packageBuilder.copyAndCleanState(
            results, self.reductionParam.periodSaveGIE,
            self.reductionParam.stateFileName,
            self.reductionParam.velocityFileName)
        u.copy(
            results[self.phaseToSaveIndex]["directory"] + slash +
            "debug_scene.py", self.packageBuilder.debugDir)

        print("PHASE 1 --- %s seconds ---" % (time.time() - start_time))
Example #3
0
    def phase4(self, nbrOfModes=None):
        """
        **The final step will gather all the results in 1 folder and build a reusable scene from it**

        +-----------------+-----------+----------------------------------------------------------+
        | argument        | type      | definition                                               |
        +=================+===========+==========================================================+
        | nbrOfModes      | int       || Number of modes you want to keep                        |
        |                 |           || ``by default will keep them all``                       |
        +-----------------+-----------+----------------------------------------------------------+

        Final step :

            - compute the RID and Weigts with :py:mod:`.ReadGieFileAndComputeRIDandWeights`
            - compute the Active Nodes with :py:mod:`.ConvertRIDinActiveNodes`
            - finalize the package
            - add it to the plugin library if option activated

        """
        # MOR IMPORT
        from .script import readGieFileAndComputeRIDandWeights, convertRIDinActiveNodes

        start_time = time.time()

        if not os.path.isfile(self.packageBuilder.dataDir +
                              self.reductionParam.modesFileName):
            raise IOError("There is no mode file at "+self.packageBuilder.dataDir+self.reductionParam.modesFileName\
                +"\nPlease give one at this location or indicate the correct location or re-generate one with phase 1 & 2")

        nbrOfModesPossible = self.packageBuilder.checkNodeNbr(
            self.reductionParam.modesFileName)

        if not nbrOfModes:
            nbrOfModes = self.reductionParam.nbrOfModes
        if nbrOfModes == -1:
            nbrOfModes = self.reductionParam.nbrOfModes = nbrOfModesPossible

        if (nbrOfModes <= 0) or (nbrOfModes > nbrOfModesPossible):
            raise ValueError("nbrOfModes incorrect\n"\
                +"  nbrOfModes given :"+str(nbrOfModes)+" | nbrOfModes max possible : "+str(nbrOfModesPossible))

        # print(files)
        files = glob.glob(self.packageBuilder.debugDir + "*_elmts.txt")
        if files:
            for i, file in enumerate(files):
                file = os.path.normpath(file)
                files[i] = file.split(slash)[-1]
            # print("FILES ----------->",files)
            self.reductionParam.savedElementsFilesNames = files

        files = glob.glob(self.packageBuilder.debugDir + "*_Gie.txt")
        if files:
            for i, file in enumerate(files):
                file = os.path.normpath(file)
                files[i] = file.split(slash)[-1]
            # print("FILES ----------->",files)
            self.reductionParam.gieFilesNames = files

        for i, gie in enumerate(self.reductionParam.gieFilesNames):
            tmp = gie.replace('_Gie.txt', '')
            for j, elmts in enumerate(
                    self.reductionParam.savedElementsFilesNames):
                if tmp in elmts:
                    tmp = self.reductionParam.savedElementsFilesNames[j]
                    self.reductionParam.savedElementsFilesNames[
                        j] = self.reductionParam.savedElementsFilesNames[i]
                    self.reductionParam.savedElementsFilesNames[i] = tmp

        # print(self.reductionParam.savedElementsFilesNames)
        # print(self.reductionParam.gieFilesNames)
        tmp = glob.glob(self.packageBuilder.dataDir + "*_reduced.txt")[0]
        tmp = os.path.normpath(tmp)
        self.reductionParam.massName = tmp.split(slash)[-1]
        # print("massName -----------------------> ",self.reductionParam.massName)

        self.reductionParam.RIDFilesNames = []
        self.reductionParam.weightsFilesNames = []
        self.reductionParam.listActiveNodesFilesNames = []
        for fileName in self.reductionParam.gieFilesNames:
            if not os.path.isfile(self.packageBuilder.debugDir + fileName):
                raise IOError("There is no GIE file at "+self.packageBuilder.debugDir+fileName\
                    +"\nPlease give one at this location or indicate the correct location or re-generate one with phase 3")

            self.reductionParam.RIDFilesNames.append(
                fileName.replace('_Gie', '_RID'))
            self.reductionParam.weightsFilesNames.append(
                fileName.replace('_Gie', '_weight'))
            self.reductionParam.listActiveNodesFilesNames.append(
                fileName.replace('_Gie', '_listActiveNodes'))

        self.listActiveNodesFilesNames = []
        for i, fileName in enumerate(self.reductionParam.gieFilesNames):

            # index = self.reductionParam.gieFilesNames.index(fileName)
            readGieFileAndComputeRIDandWeights(
                self.packageBuilder.debugDir + fileName,
                self.packageBuilder.dataDir +
                self.reductionParam.RIDFilesNames[i],
                self.packageBuilder.dataDir +
                self.reductionParam.weightsFilesNames[i],
                self.reductionParam.tolGIE,
                verbose=self.verbose)
            # print(index)
            # print(len(self.reductionParam.savedElementsFilesNames))
            # if index-1 < len(self.reductionParam.savedElementsFilesNames):
            self.activesNodesLists.append(
                convertRIDinActiveNodes(
                    self.packageBuilder.dataDir +
                    self.reductionParam.RIDFilesNames[i],
                    self.packageBuilder.debugDir +
                    self.reductionParam.savedElementsFilesNames[i],
                    self.packageBuilder.dataDir +
                    self.reductionParam.listActiveNodesFilesNames[i],
                    verbose=self.verbose))

        finalListActiveNodes = []
        for activeNodes in self.activesNodesLists:
            finalListActiveNodes = list(set().union(finalListActiveNodes,
                                                    activeNodes))
        finalListActiveNodes = sorted(finalListActiveNodes)
        with open(self.packageBuilder.dataDir + 'listActiveNodes.txt',
                  "w") as file:
            for item in finalListActiveNodes:
                file.write("%i\n" % item)
        file.close()

        filename = "phase3_performECSW.py"
        filesandtemplates = [(open(pathToTemplate + filename).read(), filename)
                             ]

        self.reductionParam.addParamWrapper(self.nodeToReduce,
                                            prepareECSW=False)

        finalScene = {}
        finalScene["ORIGINALSCENE"] = self.originalScene
        finalScene["PARAMWRAPPER"] = self.reductionParam.paramWrapper
        finalScene['NBROFMODES'] = nbrOfModes
        finalScene["nbIterations"] = 1
        finalScene["ANIMATIONPATHS"] = self.reductionAnimations.listOfLocation
        finalScene["PACKAGENAME"] = self.packageBuilder.packageName

        results = startSofa([finalScene],
                            filesandtemplates,
                            launcher=ParallelLauncher(1))
        self.packageBuilder.finalizePackage(results[0])
Example #4
0
    def phase3(self, phasesToExecute=None, nbrOfModes=None):
        """
        **This step will launch in parallel multiple Sofa scene (nbrCPU by nbrCPU number of scene) until
        it has run all the scene in the sequence.**

        +-----------------+-----------+----------------------------------------------------------+
        | argument        | type      | definition                                               |
        +=================+===========+==========================================================+
        | phasesToExecute | list(int) || Allow to choose which phase to execute for the reduction|
        |                 |           || *more details see* :py:func:`setListSofaScene`          |
        +-----------------+-----------+----------------------------------------------------------+
        | nbrOfModes      | int       || Number of modes you want to keep                        |
        |                 |           || ``by default will keep them all``                       |
        +-----------------+-----------+----------------------------------------------------------+

        To run the SOFA scene in parallele we use the ``sofa launcher`` utility

        What does it do to each scene:

            - Take the previous one and add the model order reduction component:
               - HyperReducedFEMForceField
               - MappedMatrixForceFieldAndMas
               - ModelOrderReductionMapping
            - Produce an Hyper Reduced description of the model
            - Produce files listing the different element to keep
            - Take all the resulting states files and combines them in one file put in the ``debug`` dir with a debug scene


        """
        start_time = time.time()

        if not phasesToExecute:
            phasesToExecute = list(
                range(self.reductionAnimations.nbPossibility))
        if not nbrOfModes:
            nbrOfModes = self.reductionParam.nbrOfModes

        if not os.path.isfile(self.packageBuilder.dataDir +
                              self.reductionParam.modesFileName):
            raise IOError("There is no mode file at "+self.packageBuilder.dataDir+self.reductionParam.modesFileName\
                +"\nPlease give one at this location or indicate the correct location or re-generate one with phase 1 & 2")

        nbrOfModesPossible = self.packageBuilder.checkNodeNbr(
            self.reductionParam.modesFileName)

        if not nbrOfModes:
            nbrOfModes = self.reductionParam.nbrOfModes
        if nbrOfModes == -1:
            nbrOfModes = self.reductionParam.nbrOfModes = nbrOfModesPossible

        if (nbrOfModes <= 0) or (nbrOfModes > nbrOfModesPossible):
            raise ValueError("nbrOfModes incorrect\n"\
                +"  nbrOfModes given :"+str(nbrOfModes)+" | nbrOfModes max possible : "+str(nbrOfModesPossible))

        self.setListSofaScene(phasesToExecute)

        for i in range(len(phasesToExecute)):
            self.listSofaScene[i]['NBROFMODES'] = nbrOfModes

        filenames = [
            "phase2_prepareECSW.py", "phase1_snapshots.py", "debug_scene.py"
        ]
        filesandtemplates = []
        for filename in filenames:
            filesandtemplates.append(
                (open(pathToTemplate + filename).read(), filename))
        results = startSofa(self.listSofaScene,
                            filesandtemplates,
                            launcher=ParallelLauncher(self.nbrCPU))

        if self.verbose:
            for res in results:
                print("Results: ")
                print("    directory: " + res["directory"])
                print("        scene: " + res["scene"])
                print("     duration: " + str(res["duration"]) + " sec")

        files = glob.glob(results[self.phaseToSaveIndex]["directory"] + slash +
                          "*_elmts.txt")
        if files:
            for i, file in enumerate(files):
                file = os.path.normpath(file)
                files[i] = file.split(slash)[-1]
            # print("FILES ----------->",files)
            self.reductionParam.savedElementsFilesNames = files

        for fileName in self.reductionParam.savedElementsFilesNames:
            u.copyFileIntoAnother(
                results[self.phaseToSaveIndex]["directory"] + slash + fileName,
                self.packageBuilder.debugDir + fileName)
        self.reductionParam.massName = glob.glob(
            results[self.phaseToSaveIndex]["directory"] + slash +
            "*_reduced.txt")[0]
        # print("massName -----------------------> ",self.reductionParam.massName)
        u.copy(self.reductionParam.massName, self.reductionParam.dataDir)

        files = glob.glob(results[self.phaseToSaveIndex]["directory"] + slash +
                          "*_Gie.txt")
        if files:
            for i, file in enumerate(files):
                file = os.path.normpath(file)
                files[i] = file.split(slash)[-1]
            # print("FILES ----------->",files)
            self.reductionParam.gieFilesNames = files
        else:
            raise IOError("Missing GIE Files")

        self.packageBuilder.copyAndCleanState(
            results,
            self.reductionParam.periodSaveGIE,
            'step2_' + self.reductionParam.stateFileName,
            gie=self.reductionParam.gieFilesNames)

        print("PHASE 3 --- %s seconds ---" % (time.time() - start_time))