示例#1
0
def MomentCurvature(s1, axialLoad, maxK, numIncr=100):
    theDomain = Domain()
    # define two nodes at (0,0)
    node1 = Node(1, 3, 0.0, 0.0)
    node2 = Node(2, 3, 0.0, 0.0)

    # Fix all degrees of freedom except axial and bending
    sp1 = SP_Constraint(1, 1, 0.0, True)
    sp2 = SP_Constraint(1, 2, 0.0, True)
    sp3 = SP_Constraint(1, 3, 0.0, True)
    sp4 = SP_Constraint(2, 2, 0.0, True)

    # define element
    zerolengthsection1 = ZeroLengthSection(1, 2, 1, 2, s1)
    theDomain.add_element(zerolengthsection1)

    # Define constant axial load
    theSeries1 = ConstantSeries(1)
    theLoadPattern1 = LoadPattern(1)
    theLoadPattern1.set_time_series(theSeries1)
    theDomain.add_load_pattern(theLoadPattern1)
    theLoadValues = np.array([axialLoad, 0.0, 0.0])
    theLoad1 = NodalLoad(1, 2, theLoadValues)
    theDomain.add_nodal_load(theLoad1, 1)

    # define analysis parameters
    theModel = AnalysisModel()
    theSolnAlgo = NewtonRaphson()
    theIntegrator = LoadControl(0.0, 1, 0.0, 0.0)
    theHandler = PlainHandler()
    theNumberer = PlainNumberer()
    theSolver = FullGenLinSolver()
    theSOE = FullGenLinSOE(theSolver)

    theAnalysis = StaticAnalysis(theDomain, theHandler, theNumberer, theModel,
                                 theSolnAlgo, theSOE, theIntegrator)
    # Do one analysis for constant axial load
    numSteps = 1
    theAnalysis.analyze(numSteps)

    # Define reference moment
    theSeries2 = LinearSeries(2)
    theLoadPattern2 = LoadPattern(2)
    theLoadPattern2.set_time_series(theSeries2)
    theDomain.add_load_pattern(theLoadPattern2)
    theLoadValues = np.array([0.0, 0.0, 1.0])
    theLoad2 = NodalLoad(2, 2, theLoadValues)
    theDomain.add_nodal_load(theLoad2, 2)

    # Compute curvature increment
    dK = maxK / numIncr
    theIntegrator2 = DisplacementControl(2, 3, dK, theDomain, 1, dK, dK)
    theAnalysis2 = StaticAnalysis(theDomain, theHandler, theNumberer, theModel,
                                  theSolnAlgo, theSOE, theIntegrator2)
    theAnalysis2.analyze(numIncr)
示例#2
0
    def dataRoot(self):
        """DICOM data root Getter
        All detected DICOM studies will be served as children of root node
        """
        if self._rootNode is not None:
            return self._rootNode
        else:
            self._rootNode = Node("DICOM data root node")
            for study in self._studies:
                self._rootNode.addChild(study)

        return self._rootNode
    def __readGraphByListOfCoord(self):
        nodes = []
        f = open(self.__filename, "r")
        lines = f.readlines()
        for line in lines:
            args = line.split(" ")
            if len(args) != 3:
                continue
            try:
                args[1], args[2] = float(args[1]), float(args[2])
            except Exception:
                continue

            nodes.append(Node(args[0], float(args[1]), float(args[2])))
        n = len(nodes)
        matrix = []
        for i in range(n):
            row = []
            for j in range(n):
                row.append(euclidianDistance(nodes[i], nodes[j]))
            matrix.append(row)
        print(matrix)
        self.__graph = Graph(matrix)
示例#4
0
from domain.Node import Node
from domain.SP_Constraint import SP_Constraint
from domain.timeSeries.LinearSeries import LinearSeries
from element.FourNodeQuad import FourNodeQuad

# 使用3维的材料降维
from material.nD.PlaneStressMaterial import PlaneStressMaterial
from material.nD.elasticIsotropic.ElasticIsotropicThreeDimensional import ElasticIsotropicThreeDimensional

from analysis.system_of_eqn.FullGenLinSolver import FullGenLinSolver
from analysis.system_of_eqn.FullGenLinSOE import FullGenLinSOE
import numpy as np

theDomain = Domain()

node1 = Node(1, 2, -2.5, 0.0)
node2 = Node(2, 2, 2.5, 0.0)
node3 = Node(3, 2, 2.5, 1.0)
node4 = Node(4, 2, -2.5, 1.0)

theDomain.add_node(node1)
theDomain.add_node(node2)
theDomain.add_node(node3)
theDomain.add_node(node4)

theMaterial1 = ElasticIsotropicThreeDimensional(1, 200000.0, 0.3)
material = PlaneStressMaterial(2, theMaterial1)

quad1 = FourNodeQuad(1, 1, 2, 3, 4, material, 'PlaneStress', 1.0)

theDomain.add_element(quad1)
示例#5
0
from analysis.model.AnalysisModel import AnalysisModel
from domain.Domain import Domain
from domain.LoadPattern import LoadPattern
from domain.NodalLoad import NodalLoad
from domain.Node import Node
from domain.SP_Constraint import SP_Constraint
from domain.timeSeries.LinearSeries import LinearSeries
from element.Truss import Truss
from material.uniaxial.ElasticMaterial import ElasticMaterial
from analysis.system_of_eqn.FullGenLinSolver import FullGenLinSolver
from analysis.system_of_eqn.FullGenLinSOE import FullGenLinSOE
import numpy as np

theDomain = Domain()

node1 = Node(1, 2, 0.0, 0.0)
node2 = Node(2, 2, 144.0, 0.0)
node3 = Node(3, 2, 168.0, 0.0)
node4 = Node(4, 2, 72.0, 96.0)

theDomain.add_node(node1)
theDomain.add_node(node2)
theDomain.add_node(node3)
theDomain.add_node(node4)

theMaterial = ElasticMaterial(1, 3000.0)

truss1 = Truss(1, 2, 1, 4, theMaterial, 10.0)
truss2 = Truss(2, 2, 2, 4, theMaterial, 5.0)
truss3 = Truss(3, 2, 3, 4, theMaterial, 5.0)
示例#6
0
class DicomDirectoryService:
    """DICOM directory lookup service
    This service is responsible for working with DICOM files. 
    It provides hierarchical access to DICOM elements within the files.

    directory: source DICOM data directory
    """
    def __init__(self, directory):
        """Default constructor
        """
        # Setup logger - use logging config file
        self._logger = logging.getLogger(__name__)
        logging.config.fileConfig("logging.ini",
                                  disable_existing_loggers=False)

        # Path to source DICOM directory
        self._directory = directory
        # List of DICOM files in a source directory
        self._files = []

        # The list of descriptors describing DICOM files (used for search)
        self.dicomDescriptors = []

        # Data root holds hierarchy structure of underlying DICOM data
        self._rootNode = None
        # DICOM studies detected in the source data
        self._studies = []
        # DICOM series detected in the source data
        self._series = []

        # Initialised file list
        self._loadFileNames()

        # Selected patient, study, rois which will be uploaded
        self._selectedStudy = None
        self._rois = {}  # Dictionary (key = ROINumber, value = ROIName)

        self._patient = None

        self._burnedInAnnotations = False

        # Configuration of deidentification
        self._deidentConfig = DeidentConfig()

        # Searching results over DICOM tree (have to be members because searching function is recursive)
        # TODO: refactor this and make it work more transparently
        self.dataValue = ""
        self.dataList = []

        # Parsing errors
        self._errors = []

########  ########   #######  ########  ######## ########  ######## #### ########  ######
##     ## ##     ## ##     ## ##     ## ##       ##     ##    ##     ##  ##       ##    ##
##     ## ##     ## ##     ## ##     ## ##       ##     ##    ##     ##  ##       ##
########  ########  ##     ## ########  ######   ########     ##     ##  ######    ######
##        ##   ##   ##     ## ##        ##       ##   ##      ##     ##  ##             ##
##        ##    ##  ##     ## ##        ##       ##    ##     ##     ##  ##       ##    ##
##        ##     ##  #######  ##        ######## ##     ##    ##    #### ########  ######

    @property
    def isReadable(self):
        """Verify whether the source directory path is readable
        """
        return os.access(self._directory, os.R_OK)

    @property
    def size(self):
        """Get the number of files in source directory
        """
        if self._files is not None:
            return len(self._files)
        else:
            return 0

    @property
    def dataRoot(self):
        """DICOM data root Getter
        All detected DICOM studies will be served as children of root node
        """
        if self._rootNode is not None:
            return self._rootNode
        else:
            self._rootNode = Node("DICOM data root node")
            for study in self._studies:
                self._rootNode.addChild(study)

        return self._rootNode

    @property
    def patient(self):
        """DICOM Patient Getter
        """
        if self._patient is None:
            patientIdList = self.unique("PatientID")
            if len(patientIdList) == 1:
                self._patient = DicomPatient()
                self._patient.id = patientIdList[0]
                if len(self.unique("PatientName")) == 1:
                    self._patient.name = self.unique("PatientName")[0]
                if len(self.unique("PatientSex")) == 1:
                    self._patient.gender = self.unique("PatientSex")[0]
                if len(self.unique("PatientBirthDate")) == 1:
                    self._patient.dob = self.unique("PatientBirthDate")[0]

                self._patient.newName = self._deidentConfig.ReplacePatientNameWith
                if ConfigDetails().retainPatientCharacteristicsOption:
                    self._patient.newGender = self._patient.gender
                else:
                    self._patient.newGender = self._deidentConfig.ReplaceDefaultWith
                self._patient.newDob = self._deidentConfig.ReplaceDateWith
            elif len(patientIdList) > 1:
                # More patients use the first which is detected
                self._patient = DicomPatient()
                self._patient.id = patientIdList[0]
                self._patient.name = self.unique("PatientName")[0]
                self._patient.gender = self.unique("PatientSex")[0]
                self._patient.dob = self.unique("PatientBirthDate")[0]

                self._patient.newName = self._deidentConfig.ReplacePatientNameWith
                if ConfigDetails().retainPatientCharacteristicsOption:
                    self._patient.newGender = self._patient.gender
                else:
                    self._patient.newGender = self._deidentConfig.ReplaceDefaultWith
                self._patient.newDob = self._deidentConfig.ReplaceDateWith

        return self._patient

    @property
    def study(self):
        """DICOM Study Getter
        Only one DICOM study (main - selected) is considered for further work
        """
        if self._selectedStudy is None:
            if self._rootNode is not None:
                for study in self._rootNode.children:
                    if study.isChecked:
                        self._selectedStudy = study
                        break

        return self._selectedStudy

    @property
    def ROIs(self):
        """DICOM RTSTRUCT Region Of Interest Dictionary Getter
        """
        return self._rois

##     ## ######## ######## ##     ##  #######  ########   ######
###   ### ##          ##    ##     ## ##     ## ##     ## ##    ##
#### #### ##          ##    ##     ## ##     ## ##     ## ##
## ### ## ######      ##    ######### ##     ## ##     ##  ######
##     ## ##          ##    ##     ## ##     ## ##     ##       ##
##     ## ##          ##    ##     ## ##     ## ##     ## ##    ##
##     ## ########    ##    ##     ##  #######  ########   ######

    def setup(self, thread=None):
        """Setup the dicomDirectory to make it possible to lookup what DICOM data have been provided
        DICOM study descriptor dictionary for easier search
        """
        self._errors = []

        # File reading progress checking
        processed = 0

        # Gather file DICOM study data and put into DicomStudies
        tempStudies = {}
        # Gather file DICOM series data and put into DicomSeries
        tempSeries = {}

        # Only process DICOM files
        for f in self._files:
            if self._invalidFile(f):
                continue

            try:
                descriptor = None
                dcmFile = dicom.read_file(f, force=True)
                self._logger.debug("Reading DICOM file: " + f)

                # Construct DICOM file descriptor
                descriptor = {"Filename": f}

                # PatientID
                if "PatientID" in dcmFile:
                    descriptor["PatientID"] = dcmFile.PatientID
                else:
                    self._logger.error("PatientID tag is missing in " + f +
                                       "!")
                    self._errors.append("PatientID tag is missing in " + f +
                                        "!")

                # StudyInstanceUID
                if "StudyInstanceUID" in dcmFile:
                    studyInstanceUid = dcmFile.StudyInstanceUID
                    descriptor["StudyInstanceUID"] = dcmFile.StudyInstanceUID

                    # Get SUID and prepare study objects
                    if studyInstanceUid not in tempStudies:
                        tempStudies[str(studyInstanceUid)] = DicomStudy(
                            studyInstanceUid)
                else:
                    self._logger.error("StudyInstanceUID tag is missing in " +
                                       f + "!")
                    self._errors.append("StudyInstanceUID tag is missing in " +
                                        f + "!")

                # Is it a DICOM serie (SeriesInstanceUID)
                if "SeriesInstanceUID" in dcmFile:
                    seriesInstanceUID = dcmFile.SeriesInstanceUID
                    descriptor["SeriesInstanceUID"] = dcmFile.SeriesInstanceUID

                    # Get SUID and register the file with an existing or new series object
                    if seriesInstanceUID not in tempSeries:
                        tempSeries[str(seriesInstanceUID)] = DicomSeries(
                            seriesInstanceUID)

                    # Lower memory consumption by saving only paths
                    tempSeries[str(seriesInstanceUID)].appendFile(f)
                else:
                    self._logger.error("SeriesInstanceUID tag is missing in " +
                                       f + "!")
                    self._errors.append(
                        "SeriesInstanceUID tag is missing in " + f + "!")

                # SOPInstanceUID
                if "SOPInstanceUID" in dcmFile:
                    descriptor["SOPInstanceUID"] = dcmFile.SOPInstanceUID
                else:
                    self._logger.error("SOPInstanceUID tag is missing in " +
                                       f + "!")
                    self._errors.append("SOPInstanceUID tag is missing in " +
                                        f + "!")

                # PatientName in descriptor
                if "PatientName" in dcmFile:
                    descriptor["PatientName"] = dcmFile.PatientName
                else:
                    self._logger.info(
                        "PatientName tag is missing in " + f +
                        ". Replacing with default: " +
                        self._deidentConfig.ReplacePatientNameWith + ".")
                    descriptor[
                        "PatientName"] = self._deidentConfig.ReplacePatientNameWith

                # PatientBirthDate in descriptor
                if "PatientBirthDate" in dcmFile:
                    descriptor["PatientBirthDate"] = dcmFile.PatientBirthDate
                else:
                    self._logger.info("PatientBirthDate tag is missing in " +
                                      f + ". Replacing with default: " +
                                      self._deidentConfig.ReplaceDateWith +
                                      ".")
                    descriptor[
                        "PatientBirthDate"] = self._deidentConfig.ReplaceDateWith

                # PatientSex in descriptor
                if "PatientSex" in dcmFile:
                    descriptor["PatientSex"] = dcmFile.PatientSex
                else:
                    self._logger.info("PatientSex tag is missing in " + f +
                                      ". Replacing with default: O.")
                    descriptor["PatientSex"] = "O"  # Other, if not present

                # Save StudyDescription in descriptor
                if "StudyDescription" in dcmFile:
                    descriptor["StudyDescription"] = dcmFile.StudyDescription
                    tempStudies[str(
                        studyInstanceUid)].name = dcmFile.StudyDescription
                    tempStudies[str(studyInstanceUid
                                    )].description = dcmFile.StudyDescription
                    if "StudyDate" in dcmFile:
                        tempStudies[str(
                            studyInstanceUid)].date = dcmFile.StudyDate

                # Save IntanceNumber in descriptor
                if "InstanceNumber" in dcmFile:
                    descriptor["InstanceNumber"] = dcmFile.InstanceNumber
                else:
                    descriptor["InstanceNumber"] = 0

                # Save PatientsAge in descriptor
                if "PatientsAge" in dcmFile:
                    descriptor["PatientsAge"] = dcmFile.PatientsAge
                else:
                    descriptor["PatientsAge"] = "OOOY"

                # Save FrameOfReferenceUID in descriptor
                self.getValue(dcmFile, "Frame of Reference UID")
                if self.dataValue != "":
                    descriptor["FrameOfReferenceUID"] = self.dataValue

                self.dataValue = ""
                self.dataList = []

                # Save ReferencedSOPInstanceUID_RTPLAN in descriptor
                self.getValue(dcmFile,
                              "Referenced SOP Instance UID",
                              reference="Referenced Structure Set Sequence")
                if self.dataValue != "":
                    descriptor[
                        "ReferencedSOPInstanceUID_RTSTRUCT"] = self.dataValue

                self.dataValue = ""
                self.dataList = []

                # Save ReferencedSOPInstanceUID_RTPLAN in descriptor
                self.getValue(dcmFile,
                              "Referenced SOP Instance UID",
                              reference="Referenced RT Plan Sequence")
                if self.dataValue != "":
                    descriptor[
                        "ReferencedSOPInstanceUID_RTPLAN"] = self.dataValue

                self.dataValue = ""
                self.dataList = []

                # Save Countour Image Sequence
                self.getValue(dcmFile, "Contour Image Sequence")
                if self.dataList != []:
                    descriptor["ContourImageSequence"] = list(
                        set(self.dataList))

                self.dataValue = ""
                self.dataList = []

                # According to modality save
                if "Modality" in dcmFile:
                    descriptor["Modality"] = dcmFile.Modality,

                    # For RTPLAN
                    if dcmFile.Modality == "RTPLAN":

                        # Save RTPlanLabel in descriptor
                        if "RTPlanLabel" in dcmFile:
                            descriptor["RTPlanLabel"] = dcmFile.RTPlanLabel

                        # Save BeamNumbers
                        if "Beams" in dcmFile:
                            descriptor["BeamNumbers"] = len(dcmFile.Beams)

                        # Save RadiationType
                        self.getValue(dcmFile, "Radiation Type")
                        if self.dataValue != "":
                            descriptor["RadiationType"] = self.dataValue

                        self.dataValue = ""
                        self.dataList = []

                    # Save DoseSummationType for RTDOSE
                    elif dcmFile.Modality == "RTDOSE" and \
                        "DoseSummationType" in dcmFile:
                        descriptor[
                            "DoseSummationType"] = dcmFile.DoseSummationType

                    # For RTSTRUCT prepare ROIs dictionary
                    elif dcmFile.Modality == "RTSTRUCT":
                        # Oncentra MasterPlan case exports RTSTRUCT with this point we should store this info
                        if "ReferencedFrameOfReferenceSequence" in dcmFile:
                            for element in dcmFile.ReferencedFrameOfReferenceSequence:
                                if "FrameOfReferenceRelationshipSequence" in element:
                                    for secElem in element.FrameOfReferenceRelationshipSequence:
                                        if "FrameOfReferenceTransformationType" in secElem:
                                            descriptor[
                                                "TreatmentPlanningReferencePoint"] = "Yes"
                                            break

                        for element in dcmFile:
                            if element.VR == "SQ":
                                if element.name == "Structure Set ROI Sequence":
                                    for subElem in element:
                                        self._rois[subElem.ROINumber] = [
                                            subElem.ROIName
                                        ]

                        self._logger.info("Number of RTSTRUCT ROIs: " +
                                          str(len(self._rois)))

            except Exception, err:
                msg = "Unexpected error during DICOM data parsing:" + f + "!"
                self._logger.exception(msg)
                self._errors.append(msg)

            # Add descriptor for DICOM file
            if descriptor is not None:
                self.dicomDescriptors.append(descriptor)

            # Progress
            if thread:
                processed += 1
                thread.emit(QtCore.SIGNAL("taskUpdated"),
                            [processed, self.size])

        # Make a series list and sort, so that the order is deterministic
        tempSeries = tempSeries.values()
        tempSeries.sort(key=lambda x: x.suid)

        # Prepare real series objects and put it into property
        for i in range(len(tempSeries)):
            try:
                tempSeries[i]._finish()
                self._series.append(tempSeries[i])
            except Exception:
                # Finish was not successful but I do not want to
                # skip the serie (probably report-like file without pixels)
                self._series.append(tempSeries[i])

        # Assign series to temp studies
        for series in self._series:
            tempStudies[series.studyInstanceUid].addChild(series)

        # Prepare real studies objects
        tempStudies = tempStudies.values()
        tempStudies.sort(key=lambda x: x.suid)
        for i in range(len(tempStudies)):
            self._studies.append(tempStudies[i])

        # Report reading errors
        resultError = ""
        for errMsg in self._errors:
            resultError = resultError + errMsg + "\n"
        if resultError != "" and thread:
            if len(self._errors) > 40:
                resultError = "Cannot process DICOM data, because there are too many parsing errors. Please check the log file for detailed information."
            thread.emit(QtCore.SIGNAL("message(QString)"), resultError)

        # Successful reading of data or not
        if resultError != "":
            return False
        else:
            return True