Grain class in the ebsd module
Hi all. Thank yo for this amazing software.
I have ran into a problem with the ebsd module, as below:
The Grain class takes two arguments "grainID and ebsd.Map", and should inherit the objects that exist in the ebsd.Map. But I think this does NOT happen.
The problem starts with running the crystalSym function, which is defined as below:
def crystalSym(self): return self.phase.crystalStructure.name
After calling this function, it shows the below error: AttributeError: 'Grain' object has no attribute 'phase'.
I think the "crystalStructure.name" should be inherited from the Phase class in the defdap.Crystal module, which is already called in the ebsd.Map class. But it seems the code does NOT pass the information from the ebsd.Map class into the ebsd.Grain class.
Since the crystalSym does not run, all subsequent functions of the Grain class that use that function do not run accordingly.
Thank you.
In continue of the last comment:
On the other hand, I tried to check which attributes and methods of the ebsd.Map are being passed to the Grain class.
It yields the below result, which shows all required inputs for the crystalSym function are seemingly being passed to the Grain object. But sill I can't resolve why it does NOT recognize the "phase".
Attributes of ebsdMap passed into the Grain class: ['GND', 'Nye', 'class', 'delattr', 'dict', 'dir', 'doc', 'eq', 'format', 'ge', 'getattribute', 'getitem', 'getstate', 'gt', 'hash', 'init', 'init_subclass', 'le', 'len', 'lt', 'module', 'ne', 'new', 'reduce', 'reduce_ex', 'repr', 'setattr', 'sizeof', 'str', 'subclasshook', 'weakref', 'bandContrastArray', 'bandSlopeArray', 'boundaries', 'boundariesX', 'boundariesY', 'boundaryLines', 'buildNeighbourNetwork', 'buildQuatArray', 'cOverA', 'calcAverageGrainSchmidFactors', 'calcGrainAv', 'calcGrainAvOris', 'calcGrainMisOri', 'calcKam', 'calcLineProfile', 'calcNye', 'calcProxigram', 'checkDataLoaded', 'checkGrainsDetected', 'clickGrainID', 'clickGrainNeighbours', 'clickHomog', 'clickSaveHomog', 'crystalSym', 'currGrainId', 'displayNeighbours', 'drawLineProfile', 'eulerAngleArray', 'filterData', 'findBoundaries', 'findGrains', 'floodFill', 'grainDataToMapData', 'grainList', 'grainPlot', 'grains', 'highlightAlpha', 'homogPoints', 'kam', 'keyHomog', 'loadData', 'locateGrainID', 'meanAngularDeviationArray', 'misOri', 'misOriAxis', 'neighbourNetwork', 'numPhases', 'origin', 'phaseArray', 'phaseBoundaries', 'phaseBoundariesX', 'phaseBoundariesY', 'phaseBoundaryLines', 'phases', 'plotAverageGrainSchmidFactorsMap', 'plotBandContrastMap', 'plotBoundaryMap', 'plotDefault', 'plotEulerMap', 'plotGNDMap', 'plotGrainDataIPF', 'plotGrainDataMap', 'plotGrainMap', 'plotGrainNumbers', 'plotHomog', 'plotIPFMap', 'plotKamMap', 'plotMisOriMap', 'plotPhaseBoundaryMap', 'plotPhaseMap', 'primaryPhase', 'primaryPhaseID', 'profilePlot', 'proxigram', 'proxigramArr', 'quatArray', 'rotateData', 'save', 'scale', 'setHomogPoint', 'shape', 'stepSize', 'updateHomogPoint', 'xDim', 'yDim']
PS:
Could solve the issue.
I should have created the instance of the grain object, in a way that calls "individual" grains from the ebsd.Map class. Something like this: ebsdGrain = ebsdMap[5]
Then I can call the methods of the Grain class. ebsdGrain.crystalSym
Now it works.
Hi, thanks for your comments. The grain classes are not really meant to be created directly, rather created during grain finding. It's some bad design you've found, the phase attribute on the grains is assigned after initial grain segmentation https://github.com/MechMicroMan/DefDAP/blob/fe772de3c2f69efd19a148f139331d8f08f99e0f/defdap/ebsd.py#L982 but this is not passed when the grains are created or even given a default value in the constructor.