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)
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)
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)
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)
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