Extracting quantities of elements with IfcOpenShell in python - python
I am trying to read the deepest level of quantities for objects in an ifc file, using IfcOpenShell in Python. So far I have:
import ifcopenshell
path = r'D:\ifcos_1\slab.ifc'
ifc_file = ifcopenshell.open(path)
geometries = ifc_file.by_type("IfcProduct")
for geometry in geometries:
if geometry.is_a("IfcSlab"):
print geometry
test = geometry.IfcPhysicalQuantity()
print test
I've studied the definitions
No matter which type of function I try to place for the test = geometry.X(), I get an error:
File "C:\Python27\lib\site-packages\ifcopenshell\entity_instance.py", line 48, in __getattr__
"entity instance of type '%s' has no attribute '%s'" % (self.wrapped_data.is_a(), name))
AttributeError: entity instance of type 'IfcSlab' has no attribute 'IfcPhysicalQuantity'
Not sure how to solve this and would appreciate help.
EDIT:
Further work which gets the slab and further references:
for geometry in geometries:
if geometry.is_a("IfcSlab"):
print geometry
definedBy = geometry.IsDefinedBy
print definedBy[0]
for each in definedBy:
test = each.is_a()
print test
As of this moment the obstacle is the compatibility with IFC4, which I will try to recompile with instructions from this forum post.
EDIT 2:
Further work using for now the IFC 2x3 standard, with a file that has quantity information (verified via the raw data). The following is the relevant code:
for geometry in geometries:
if geometry.is_a("IfcSlab"):
definedBy = geometry.IsDefinedBy
for line in definedBy:
test = line.is_a()
# print test
if line.is_a() == 'IfcRelDefinesByProperties' or line.is_a() == 'IfcRelDefinesByType':
step1 = line.RelatingPropertyDefinition
step2 = step1.is_a()
print step2
There is an error no matter what I place after step1 = line., none of the following give a result:
line.IfcPropertySet
line.IfcElementQuantity
line.RelatingPropertyDefiniton
The output from this code is nevertheless:
IfcPropertySet
IfcPropertySet
IfcPropertySet
IfcPropertySet
IfcPropertySet
IfcPropertySet
IfcPropertySet
IfcPropertySet
IfcPropertySet
IfcPropertySet
IfcElementQuantity
IfcElementQuantity
Which means that I can access IfcElementQuantity but none of the Attributes work. I've looked at schema reference but can't find the correct one.
When implementing this you should take care which version of IFC your import library works on - the version distributed by the IfcOpenShell-Website works with IFC2X3. For IFC4 you will probably need to compile a version yourself. (you can check your IFC version with ifcopenshell.schema_identifier)
I am putting links up to the buildingSMART IFC 4 definition even if I am talking about IFC2X3. Differences to IFC2X3 are marked in red on the buildingSMART web page. And the IFC4 definition is nicer to read (IMO).
Quantities aren't directly attached like an attribute. They are written as property sets and then related to the element or element type. So first you should ensure your IFC file contains quantities - otherwise you will not find any. Usually you start with a specific product - ifc_file.by_type('IfcSlab'). You can reach the property sets via inverse attributes - those are usually set up by the IFC library, they don't appear directly as attribute in the file.
I took you example file and shortened it to about a third (so it's still a valid IFC2X3 file):
ISO-10303-21;
HEADER;FILE_DESCRIPTION(('ViewDefinition [Custom, QuantityTakeOffAddOnView, SpaceBoundary2ndLevelAddOnView]','Option [Drawing Scale: 100.000000]','Option [Global Unique Identifiers (GUID): Keep existing]','Option [Elements to export: Visible elements (on all stories)]','Option [Partial Structure Display: Entire Model]','Option [IFC Domain: All]','Option [Structural Function: All Elements]','Option [Convert Grid elements: On]','Option [Convert IFC Annotations and ARCHICAD 2D elements: Off]','Option [Convert 2D symbols of Doors and Windows: Off]','Option [Explode Composite and Complex Profile elements into parts: On]','Option [Export geometries that Participates in Collision Detection only: Off]','Option [Elements in Solid Element Operations: Extruded/revolved]','Option [Elements with junctions: Extruded/revolved without junctions]','Option [Slabs with slanted edge(s): Extruded]','Option [Use legacy geometric methods as in Coordination View 1.0: Off]','Option [IFC Site Geometry: As boundary representation (BRep)]','Option [IFC Site Location: At Project Origin]','Option [Curtain Wall export mode: Container Element]','Option [Railing export mode: Single Element]','Option [Stair export mode: Container Element]','Option [Properties To Export: All properties]','Option [Space containment: On]','Option [IFC Domain For Space Containment: All]','Option [Bounding Box: Off]','Option [Geometry to type objects: Off]','Option [Element Properties: All]','Option [Property Type Element Parameter: On]','Option [Quantity Type Element Parameter: On]','Option [IFC Base Quantities: On]','Option [Window Door Lining and Panel Parameters: On]','Option [IFC Space boundaries: On]','Option [ARCHICAD Zone Categories as IFC Space classification data: On]','Option [Element Classifications: On]'),'2;1');
FILE_NAME('D:\\Side Projects\\Paragraph3\\The database\\IFC Files\\Local tests\\ifcos_1\\slab.ifc','2018-06-13T18:28:40',('Architect'),('Building Designer Office'),'The EXPRESS Data Manager Version 5.02.0100.09 : 26 Sep 2013','IFC file generated by GRAPHISOFT ARCHICAD-64 21.0.0 INT FULL Windows version (IFC2x3 add-on version: 3005 INT FULL).','The authorising person');
FILE_SCHEMA(('IFC2X3'));
ENDSEC;
DATA;
#1= IFCPERSON($,'Undefined',$,$,$,$,$,$);
#7= IFCPERSONANDORGANIZATION(#1,#10,$);
#10= IFCORGANIZATION('GS','GRAPHISOFT','GRAPHISOFT',$,$);
#11= IFCAPPLICATION(#10,'21.0.0','ARCHICAD-64','IFC2x3 add-on version: 3005 INT FULL');
#12= IFCOWNERHISTORY(#7,#11,$,.ADDED.,$,$,$,1528907320);
#13= IFCSIUNIT(*,.LENGTHUNIT.,.MILLI.,.METRE.);
#14= IFCSIUNIT(*,.AREAUNIT.,$,.SQUARE_METRE.);
#16= IFCSIUNIT(*,.PLANEANGLEUNIT.,$,.RADIAN.);
#17= IFCMEASUREWITHUNIT(IFCPLANEANGLEMEASURE(0.0174532925199),#16);
#18= IFCDIMENSIONALEXPONENTS(0,0,0,0,0,0,0);
#19= IFCCONVERSIONBASEDUNIT(#18,.PLANEANGLEUNIT.,'DEGREE',#17);
#29= IFCUNITASSIGNMENT((#13,#14,#19));
#31= IFCDIRECTION((1.,0.,0.));
#35= IFCDIRECTION((0.,0.,1.));
#37= IFCCARTESIANPOINT((0.,0.,0.));
#39= IFCAXIS2PLACEMENT3D(#37,#35,#31);
#40= IFCDIRECTION((0.,1.));
#42= IFCGEOMETRICREPRESENTATIONCONTEXT($,'Model',3,1.00000000000E-5,#39,#40);
#45= IFCPROJECT('344O7vICcwH8qAEnwJDjSU',#12,'Project',$,$,$,$,(#42),#29);
#59= IFCLOCALPLACEMENT($,#39);
#62= IFCSITE('20FpTZCqJy2vhVJYtjuIce',#12,'Site',$,$,#59,$,$,.ELEMENT.,(47,33,34,948800),(19,3,17,204400),0.,$,$);
#68= IFCRELAGGREGATES('0Du7$nzQXCktKlPUTLFSAT',#12,$,$,#45,(#62));
#74= IFCQUANTITYLENGTH('GrossPerimeter',$,$,0.);
#76= IFCQUANTITYAREA('GrossArea',$,$,0.);
#77= IFCELEMENTQUANTITY('2GNZepdf73fvGc$0W6rozj',#12,'BaseQuantities',$,'ARCHICAD BIM Base Quantities',(#74,#76));
#82= IFCRELDEFINESBYPROPERTIES('2Hm9JvZjohDNSD2kdxZI3b',#12,$,$,(#62),#77);
#93= IFCLOCALPLACEMENT(#59,#39);
#95= IFCBUILDING('00tMo7QcxqWdIGvc4sMN2A',#12,'Building',$,$,#93,$,$,.ELEMENT.,$,$,$);
#97= IFCRELAGGREGATES('2b_h_mYcGArd6glJG2Fmbt',#12,$,$,#62,(#95));
#101= IFCQUANTITYAREA('GrossFloorArea',$,$,0.);
#102= IFCELEMENTQUANTITY('1kQMlmT0rD35a9E43iKTas',#12,'BaseQuantities',$,'ARCHICAD BIM Base Quantities',(#101));
#104= IFCRELDEFINESBYPROPERTIES('0L87OdSD3DqSTjSRlAciZL',#12,$,$,(#95),#102);
#115= IFCLOCALPLACEMENT(#93,#39);
#117= IFCBUILDINGSTOREY('1oZ0wPs_PE8ANCPg3bIs4j',#12,'Ground Floor',$,$,#115,$,$,.ELEMENT.,0.);
#119= IFCRELAGGREGATES('118jwqMnuwK1xuf97w7fU5',#12,$,$,#95,(#117));
#180= IFCSLAB('3W29Drc$H6CxK3FGIxjJNl',#12,'SLA - 001',$,$,$,$,'E0089375-9BF4-4633-B503-3D04BBB535EF',.FLOOR.);
#195= IFCRELCONTAINEDINSPATIALSTRUCTURE('04ldtj6cp2dME6CiP80Bzh',#12,$,$,(#180),#117);
#326= IFCPROPERTYSINGLEVALUE('Fragility rating',$,IFCLABEL('0'),$);
#327= IFCPROPERTYSINGLEVALUE('Tile dimensions',$,IFCLABEL('Undefined'),$);
#328= IFCPROPERTYSINGLEVALUE('Anti-static Surface',$,IFCBOOLEAN(.F.),$);
#329= IFCPROPERTYSINGLEVALUE('Non-skid Surface',$,IFCBOOLEAN(.F.),$);
#330= IFCPROPERTYSET('0LYX8AqOOS9ft8M4aJYEYa',#12,'FLOORINGS',$,(#326,#327,#328,#329));
#332= IFCRELDEFINESBYPROPERTIES('1G6WWCSQGg0PdTnW7hwMrM',#12,$,$,(#180),#330);
#335= IFCPROPERTYSINGLEVALUE('Renovation Status',$,IFCLABEL('Existing'),$);
#336= IFCPROPERTYSET('0cR6wsk2QWcLKPchA8mF3u',#12,'AC_Pset_RenovationAndPhasing',$,(#335));
#338= IFCRELDEFINESBYPROPERTIES('3nYD8KGPhoBw5okmj1JjsA',#12,$,$,(#180),#336);
#341= IFCQUANTITYLENGTH('Width',$,$,300.);
#342= IFCQUANTITYLENGTH('Perimeter',$,$,22000.);
#343= IFCQUANTITYAREA('GrossArea',$,$,28.);
#344= IFCQUANTITYAREA('NetArea',$,$,28.);
#345= IFCQUANTITYVOLUME('GrossVolume',$,$,8.4);
#346= IFCQUANTITYVOLUME('NetVolume',$,$,8.4);
#347= IFCELEMENTQUANTITY('1RfXJewSc7OCIaD$L2ZoXT',#12,'BaseQuantities',$,'ARCHICAD BIM Base Quantities',(#341,#342,#343,#344,#345,#346));
#349= IFCRELDEFINESBYPROPERTIES('085uLttAQRllG3nL_YikZ8',#12,$,$,(#180),#347);
#375= IFCQUANTITYVOLUME('Gross Volume of the Slab',$,$,8.4);
#376= IFCQUANTITYVOLUME('Gross Volume of the Slab with Holes',$,$,8.4);
#377= IFCQUANTITYLENGTH('Holes Perimeter',$,$,0.);
#378= IFCQUANTITYAREA('Holes Surface Area',$,$,0.);
#379= IFCQUANTITYLENGTH('Perimeter',$,$,22000.);
#381= IFCQUANTITYAREA('Top Surface Area',$,$,28.);
#382= IFCELEMENTQUANTITY('0DuZ12CVtssgcIQPaQ$1sp',#12,'ArchiCADQuantities',$,'ARCHICAD BIM Quantities',(#375,#376,#377,#378,#379,#381));
#384= IFCRELDEFINESBYPROPERTIES('0KgGv0Y8Fc2jg8BCPhxnM5',#12,$,$,(#180),#382);
#393= IFCSLABTYPE('0K1otpnkQcEpOBXPxnZ3dB',#12,'Timber - Floor 300',$,$,(#396),$,'14072DF3-C6E6-A63B-360B-859EF18C39CB',$,.FLOOR.);
#395= IFCRELDEFINESBYTYPE('353egCMRpZtJd$CDCoSsCb',#12,$,$,(#180),#393);
#352= IFCQUANTITYAREA('Area',$,$,28.);
#353= IFCQUANTITYLENGTH('Height',$,$,300.);
#354= IFCQUANTITYVOLUME('Net Volume',$,$,8.4);
#396= IFCELEMENTQUANTITY('1Zyxf4r7NogSp4V7ORMpET',#12,'ArchiCADQuantities',$,'ARCHICAD BIM Quantities',(#352,#353,#354));
ENDSEC;
END-ISO-10303-21;
This is a slab with an area measurement attached. It should have an inverse attribute IsDefinedBy. In IFC2X3 this points to a list of entities IfcRelDefinesByProperties and IfcRelDefinesByType. With IFC4 IfcRelDefinesByType will be put in the inverse attribute IsTypedBy.
Each IfcRelDefinesByProperties point to a property set in their attribute RelatingPropertyDefinition. There are various property set types, you want it to be of type IfcElementQuantity when searching for physical quantities. You will have to check at run time which type you currently hold while iterating the list of property relations.
The quantity set has a list of IfcPhysicalQuantities attached in the attribute Quantities. These can be simple quantities or complex quantities, which are composed of multiple simple quantities. For simple quantities there are specific subtypes for area, count or weight. Again you will have to check at runtime for the concrete type.
The area quantity itself has a name and description to give further context (not ours, but possibly in the real world). The value attribute is named after the quantity type, so IfcQuantityArea has an attribute AreaValue. Also of interest is attribute Unit which is a reference to the unit of the value. If it is not set (as in our example) you will need to look for assigned units at the IfcProject entity.
Unfortunately this might not be all. If the object (here our IfcSlab) has an assigned object type, that type can also have property sets attached (I modified the example file to be this case). Thy type entity does not have an inverse attribute, but a direct one, HasProperties. If it is set, you can discover attached properties through it.
To summarise, you will probably need multiple loops:
For each object, get property sets
For each property set, test if it is quantity set
For each quantity set, go through quantities
And potentially repeat this search if the object has a user defined type.
The following code should do exactly this (written on my machine with python 3.5.4 and ifcopenshell with IFC2X3 schema)):
Get all slabs from the file (there is only one)
Go through all entities in the inverse attribute IsDefinedBy - these can be IfcRelDefinesByProperties or IFcRelDefinesByType.
Get property sets from the entity
Check if the given property set is IfcElementQuantity and proceed to print quantitites if it is.
import ifcopenshell
def print_quantities(property_definition):
if 'IfcElementQuantity' == property_definition.is_a():
for quantity in property_definition.Quantities:
if 'IfcQuantityArea' == quantity.is_a():
print('Area value: ' + str(quantity.AreaValue))
if 'IfcQuantityVolume' == quantity.is_a():
print('Volume value: ' + str(quantity.VolumeValue))
if 'IfcQuantityLength' == quantity.is_a():
print('Length value: ' + str(quantity.LengthValue))
ifc_file = ifcopenshell.open('slab.ifc')
products = ifc_file.by_type('IfcSlab')
for product in products:
if product.IsDefinedBy:
definitions = product.IsDefinedBy
for definition in definitions:
#In IFC2X3 this could be property or type
#in IFC4 type is in inverse attribute IsTypedBy
if 'IfcRelDefinesByProperties' == definition.is_a():
property_definition = definition.RelatingPropertyDefinition
print_quantities(property_definition)
if 'IfcRelDefinesByType' == definition.is_a():
type = definition.RelatingType
if type.HasPropertySets:
for property_definition in type.HasPropertySets:
print_quantities(property_definition)
For the example this results in:
Length value: 300.0
Length value: 22000.0
Area value: 28.0
Area value: 28.0
Volume value: 8.4
Volume value: 8.4
Volume value: 8.4
Volume value: 8.4
Length value: 0.0
Area value: 0.0
Length value: 22000.0
Area value: 28.0
Area value: 28.0
Length value: 300.0
Volume value: 8.4
Quantities in IFC are stored in quantity sets, which are very similar in structure to property sets. IfcOpenShell offers utility functions to extract this data in a schema-agnostic manner:
for slab in ifc_file.by_type("IfcSlab"):
quantities = ifcopenshell.util.element.get_psets(slab, qtos_only=True)
print(quantities) # A dictionary of qtos and quantities
# For example print(quantities["Qto_SlabBaseQuantities"]["GrossVolume"])
I wrote a few functions once, to extract all properties.
https://github.com/johannesmichael/ifc-python/blob/master/modules/ifc_pset_utils.py
Might not be complete, but can give you an idea.
I extract all to excel for further analyzis.
BaseQuantities:
def get_related_quantities(ifc_instance):
"""
Returns a list of IfcElementQuantity for given IFC ID
argument: ifc_instance
return: list of property sets
"""
quantities_list =[]
for x in ifc_instance.IsDefinedBy:
if x.is_a("IfcRelDefinesByProperties"):
if x.RelatingPropertyDefinition.is_a("IfcElementQuantity"):
quantities_list.append(x.RelatingPropertyDefinition)
return quantities_list
def get_quantity_single_value(x):
"""
Returns a dict of dicts of IfcElementQuantity single values.
Returning a dictionary of dictionaries
is used, because it is easy to transform to pandas.DataFrame
argument: IFC Element as contained in list from get_related_property_sets()
return: dict of property single values like {"IfcName":"xx", "IfcGlobalId": "klkhlkh", ......}
"""
quantities_dicts = {}
for y in x.Quantities:
if y.is_a('IfcQuantityArea'):
quantities_dicts.update({y.Name:y.AreaValue})
if y.is_a('IfcQuantityLength'):
quantities_dicts.update({y.Name:y.LengthValue})
if y.is_a('IfcQuantityVolume'):
quantities_dicts.update({y.Name:y.VolumeValue})
if y.is_a('IfcQuantityCount'):
quantities_dicts.update({y.Name:y.CountValue})
if y.is_a('IfcQuantityWeight'):
quantities_dicts.update({y.Name:y.WeightValue})
return quantities_dicts
This was done for IFC 2x3 TC1
Hope that helps
Related
In abaqus, how to output the maximum stress value at each time point without selecting an object
During the compression test, how to output the maximum stress value at each time point without selecting an object Step&question I created a field output,MISESMAX maximum mises equivalent stress-submit this job-creat XY data-click ODB field output- select MISESMAX(i chorse intergration point in this part)then I save,but abaqus hint “At least one entity should be selscted”. Goal I want to output Maximum stress value of each step in XY data,but the area of maximum stress value in each step will be different,so how to How to output XY value without selecting an area.
In order to create XY data, you must select the some or full part of the model. Hence the error from the Abaqus. I find this method is slow for your application. Alternatively you can use below method: In Abaqus/CAE: from Report menu -> select Field Output -> select appropriate Step/Frame -> select MISESMAX variable -> select position (If you want the nodal results then select Unique Nodal)-> In the setup tab check on Column Min/Max option. Please note this writes the field output data to the file for ONE frame only. and at the end of the file you will get to see the max value and it's position (If the position you selected is Unique Nodal, the node label will be written.). Similarly, you can repeat this process for each frame of the step. or you can use following code: import displayGroupOdbToolset as dgo import odbAccess odbName = 'example.odb'; outFile = 'example.dat' odb = odbAccess.openOdb(path=odbName) session.viewports['Viewport: 1'].setValues(displayedObject=odb) leaf = dgo.Leaf(leafType=DEFAULT_MODEL) session.viewports['Viewport: 1'].odbDisplay.displayGroup.replace(leaf=leaf) for stp in odb.steps.keys(): stpNum = odb.steps[stp].number tframe = len(odb.steps['Step-1'].frames) - 1 session.writeFieldReport(fileName=outFile, append=ON, sortItem='Node Label', odb=odb, step=stpNum, frame=tframe, outputPosition=NODAL, variable=(('S', INTEGRATION_POINT, ((INVARIANT, 'Mises'), )), )) Please change the argument to variable option in above code as per your field output data.
I found an effective method in the help document Finding the maximum value of von Mises stress https://help.3ds.com/2020/english/dssimulia_established/simacaecmdrefmap/simacmd-c-odbintroexamaxmisespyc.htm?contextscope=all
Is there an function for writing all Elements and Characteristics from Revit in an .csv file?
I use Revit(PyRevit) and want to wirte all used Elements with their characteristics in an .csv file. This is one example: Get Parameter Value by Name Get value of one of element's parameters. TESTED REVIT API: 2016,2017 Author: Francisco Possetto | github.com/franpossetto Shared on www.revitapidocs.com For more information visit http://github.com/gtalarico/revitapidocs License: http://github.com/gtalarico/revitapidocs/blob/master/LICENSE.md """ #Imports. from Autodesk.Revit.DB import Element doc = __revit__.ActiveUIDocument.Document uidoc = __revit__.ActiveUIDocument def get_parameter_value_by_name(element, parameterName): return element.LookupParameter(parameterName).AsValueString() #Select elements from revit. selection = [doc.GetElement(x) for x in uidoc.Selection.GetElementIds()] #Example with Walls. for wall in selection: print get_parameter_value_by_name(wall, "Base Constraint") But there I only get "Base Constraint" is it possible to get all Elements/Categories into that file? Thanks a lot. Best regards
You can use rpw Collector to get all FamilySymbol elements. If you only want all instances in your project. Just use 'FamilyInstance' to get them. from rpw import db collector = db.Collector(of_class='FamilySymbol') elements = collector.get_elements() for e in elements: print(e.name)
Abaqus python script, how to 'addData' for elements with multiple integration points (e.g. C3D20R)
I have the following piece of code: from abaqus import * from odbAccess import * from abaqusConstants import * import visualization import fileinput import os import shutil import numpy as np from odbAccess import * def tupled_list(mylist,n): '''group every n elements of the list into a tuple ''' return list(zip(*[iter(mylist)]*n)) # Open odb odb_filename = 'AbaqusResults.odb' work_directory=os.getcwd() odb_filepath = os.path.abspath(os.path.join(os.getcwd(),'..','outputs',odb_filename)) my_odb=session.openOdb(name=odb_filepath,readOnly=FALSE) # Automate the proces of reading the step no matter what its name is StepNames=(my_odb.steps.keys() ) lastStep=( StepNames[-1] ) # Automation of an instance naming (in the same way) AllInstances = (my_odb.rootAssembly.instances.keys()) MyInstance = ( AllInstances[-1] ) SubmodelInstance=my_odb.rootAssembly.instances[MyInstance] # Get dataset containing element labels and calculated quantities in here from text file dataset = np.loadtxt(os.path.join(os.getcwd(),'AbaqusDataInput.txt'),delimiter=',') # List of all element labels elLabels = dataset[0,:].astype(int).tolist() # Count the number of integration points for a single element gausspoints = elLabels.count(1) # Get damage data from dataset and format into a list of tuples, tuple length depends on number of integration points for eache element damage = tupled_list(list(dataset[1,:]),gausspoints) damage = [list(elem) for elem in damage] # Remove duplicates from elLabel list elLabels = list(set(elLabels)) for i in range(len(my_odb.steps[lastStep].frames)): new_field_damage = my_odb.steps[lastStep].frames[i].FieldOutput(name='Damage',description='Damage sustained after one repitition of the loading history', type=SCALAR) new_field_damage.addData(position=INTEGRATION_POINT, instance=SubmodelInstance, labels=elLabels, data=damage) my_odb.save() my_odb.close() but I get the following error: Data at 141968 locations expected. Data at 17746 locations provided. Element data request failed. Element type is C3D20R. Data at 8 integration points per element expected elLabels is a list with 17746 items and damage is a tuple list with 17746 items but each item has 8 values (one for each integration point) e.g. [(x,x,x,x,x,x,x,x) , (x,x,x,x,x,x,x,x), … ] Thus I provide abaqus with 17746 element labels and 17746 * 8 locations (141968 data points in total as asked) so I don’t see why I get the error. I have tried a list of lists instead of a list of tuples but the same error occurs. I suspect is merely an issue of using the correct datatypes but the Abaqus documentation seems severely lacking. The script works fine for odb files with C3D8R elements which have 1 integration point. I then provide the same elLabels list and damage list but then each tuple only has 1 value (e.g. [(x, ) (x, ), … ] ) which works fine. Do you know how I can import my data into the elements integration points?
This is an old question but I stumbled across a similar problem. The correct format seems to be just plain lists: elLabels = [1, 2, ...] damage = [1_1, 1_2, 1_3, 1_4, 1_5, 1_6, 1_7, 1_8, 2_1, 2_2, ...] where i_j is the data of element i at integration point j. By the way, it's probably better to remove duplicates like this to maintain a correct order: from collections import OrderedDict list(OrderedDict.fromkeys(elLabels))
I think you can first try to confirm if the data in Abaqus is indeed stored in element sequence first followed by integration point sequence within an element. For example for S4R type, the stresses of S22 are stored for the bottom surface of all elements, and then for the top surface of all elements. That is, they are not in sequence of element 1(bottom, top), element2(bottom, top)....element n(bottom top); rather, it is: bottom (element1), bottom (element2)...bottom (element n), top(element1), top(element2).. top (element n) try: S22_ES = (o1.steps[LoadStep].frames[loadDir+1].fieldOutputs['S'].getScalarField(componentLabel="S22") .getSubset(region=Elset,position=INTEGRATION_POINT,))
AttributeError: 'FileDataset' object has no attribute 'PixelSpacing'
I want to convert the filetype of a series of images from .dcm to .mha. Following is my code: import numpy import pydicom import os PathDicom ='./DicomResource' lstFilesDCM = [] for dirName, subdirList, fileList in os.walk(PathDicom): for filename in fileList: if '.dcm' in filename.lower(): lstFilesDCM.append(os.path.join(dirName, filename)) RefDs = pydicom.read_file(lstFilesDCM[0]) ConstPixelDims = (int(RefDs.Rows), int(RefDs.Columns), len(lstFilesDCM)) #RefDs.PixelSpacing = 0 ConstPixelSpacing = (float(RefDs.PixelSpacing[0]), float(RefDs.PixelSpacing[1]), float(RefDs.SliceThickness)) info = ConstPixelDims + ConstPixelSpacing f = open('info.txt', 'w') for n in info: f.write(str(n)+' ') f.close() location = [] for i in range(len(lstFilesDCM)): ds = pydicom.read_file(lstFilesDCM[i]) location.append(ds.SliceLocation) location.sort() ArrayDicom = numpy.zeros((len(lstFilesDCM), RefDs.Rows, RefDs.Columns), dtype=RefDs.pixel_array.dtype) for filenameDCM in lstFilesDCM: ds = pydicom.read_file(filenameDCM) ArrayDicom[location.index(ds.SliceLocation), :, :] = ds.pixel_array ds = ArrayDicom.tostring() f = open('1.mha', 'wb') f.write(ds) f.close() With this, I am getting following error: AttributeError: 'FileDataset' object has no attribute 'PixelSpacing' I also tried adding RefDs.PixelSpacing = 0. It throws next error. Is there anyone can help me to solve the problem?
Attribute "PixelSpacing" (0028,0030) is not mandatory in all SOP Classes. With some SOP Classes like "CT Image Storage" (Modality CT), this is Type "1". With many others, it is Type "1C". In SOP Classes like "Computed Radiography Image Storage" (Modality CR), equivalent attribute "Imager Pixel Spacing" (0018,1164) is included in dataset. Following quote from 2017a Part 3 - Information Object Definitions explains this a bit. 10.7.1.1 Pixel Spacing Pixel Spacing (0028,0030) specifies the physical distance in the patient between the center of each pixel. If Pixel Spacing (0028,0030) is present and the image has not been calibrated to correct for the effect of geometric magnification, the values of this attribute shall be the same as in Imager Pixel Spacing (0018,1164) or Nominal Scanned Pixel Spacing (0018,2010), if either of those attributes are present. If Pixel Spacing (0028,0030) is present and the values are different from those in Imager Pixel Spacing (0018,1164) or Nominal Scanned Pixel Spacing (0018,2010), then the image has been corrected for known or assumed geometric magnification or calibrated with respect to some object of known size at known depth within the patient. If Pixel Spacing Calibration Type (0028,0A02) and Imager Pixel Spacing (0018,1164) and Nominal Scanned Pixel Spacing (0018,2010) are absent, then it cannot be determined whether or not correction or calibration have been performed. Note 1. Imager Pixel Spacing (0018,1164) is a required attribute in DX family IODs. 2. Nominal Scanned Pixel Spacing (0018,2010) is a required attribute in Multi-frame SC family IODs Looking at your question, it seems that your code is not bound to any specific Modality/SOP Class. Considering this, it is quite possible your loop encounter some instances those are missing this attribute. About first error: AttributeError: 'FileDataset' object has no attribute 'PixelSpacing' Error is very clear. The DICOM dataset does not contain the attribute you are looking for. About second error: TypeError: 'DSfloat' object does not support indexing Value Multiplicity of attribute is 2. Pixel Spacing = Row Spacing\Column Spacing = 0.30 mm\0.25 mm So, you should be able to access the value using index. First value should be for row and second should be column. But this depends on the implementation of your toolkit/technology. I am not aware about both here so I cannot say. May be, your toolkit returns single value (no array; hence no index) which you should further split on separator ('\') and then use it. Or may be that as the attribute does not present, the value of the variable is null (or whatever similar in your technology) and that is why indexing is not working.
(Blender) (Python)How can I animate the factor value in the mix node with Python code?
What I want is a way to handle the 'factor' value in the mixRGB node like a normal object, like for example a cube, so with fcurves, fmodifiers and so on. All this via Python code made in the Text Editor
The first step is to find the mix node you want. Within a material you can access each node by name, while the first mixRGB node is named 'Mix', following mix nodes will have a numerical extension added to the name. The name may also be changed manually by the user (or python script). By showing the properties region (press N) you can see the name of the active node in the node properties. To adjust the fac value you alter the default_value of the fac input. To keyframe the mix factor you tell the fac input to insert a keyframe with a data_path of default_value import bpy cur_frame = bpy.context.scene.frame_current mat_nodes = bpy.data.materials['Material'].node_tree.nodes mix_factor = mat_nodes['Mix.002'].inputs['Fac'] mix_factor.default_value = 0.5 mix_factor.keyframe_insert('default_value', frame=cur_frame) Of course you may specify any frame number for the keyframe not just the current frame. If you have many mix nodes, you can loop over the nodes and add each mix shader to a list mix_nodes = [n for n in mat_nodes if n.type == 'MIX_RGB'] You can then loop over them and keyframe as desired. for m in mix_nodes: m.inputs['Fac'].default_value = 0.5 m.inputs['Fac'].keyframe_insert('default_value', frame=cur_frame) Finding the fcurves after adding them is awkward for nodes. While you tell the input socket to insert a keyframe, the fcurve is stored in the node_tree so after keyframe_insert() you would use bpy.data.materials['Material'].node_tree.animation_data.action.fcurves.find() Knowing the data path you want to search for can be tricky, as the data path for the Fac input of node Mix.002 will be nodes["Mix.002"].inputs[0].default_value If you want to find an fcurve after adding it to adjust values or add modifiers you will most likely find it easier to keep a list of them as you add the keyframes. After keyframe_insert() the new fcurve should be at material.node_tree.animation_data.action.fcurves[-1]