mtex 1.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (506) hide show
  1. mtex/__init__.py +94 -0
  2. mtex/analysis/__init__.py +34 -0
  3. mtex/analysis/cluster.py +308 -0
  4. mtex/analysis/data/__init__.py +1 -0
  5. mtex/analysis/data/cie1931.py +478 -0
  6. mtex/analysis/denoising.py +511 -0
  7. mtex/analysis/dislocations.py +105 -0
  8. mtex/analysis/elasticity.py +372 -0
  9. mtex/analysis/embedding.py +424 -0
  10. mtex/analysis/gbnd.py +223 -0
  11. mtex/analysis/gbnd3d.py +116 -0
  12. mtex/analysis/kernels.py +181 -0
  13. mtex/analysis/mechanics.py +286 -0
  14. mtex/analysis/optics.py +137 -0
  15. mtex/analysis/optimalsample.py +445 -0
  16. mtex/analysis/pf2odf.py +464 -0
  17. mtex/analysis/taylor.py +397 -0
  18. mtex/analysis/texture.py +345 -0
  19. mtex/analysis/variational.py +300 -0
  20. mtex/docpages/CrystalGeometry/CrystalDirections.py +231 -0
  21. mtex/docpages/CrystalGeometry/CrystalOperations.py +351 -0
  22. mtex/docpages/CrystalGeometry/CrystalReferenceSystem.py +243 -0
  23. mtex/docpages/CrystalGeometry/CrystalShapeSmorf.py +151 -0
  24. mtex/docpages/CrystalGeometry/CrystalShapes.py +349 -0
  25. mtex/docpages/CrystalGeometry/CrystalSymmetries.py +267 -0
  26. mtex/docpages/CrystalGeometry/FundamentalSector.py +157 -0
  27. mtex/docpages/CrystalGeometry/LatticeMetric.py +226 -0
  28. mtex/docpages/CrystalGeometry/QuasiCrystals.py +166 -0
  29. mtex/docpages/CrystalGeometry/SymmetryAlignment.py +150 -0
  30. mtex/docpages/CrystalOrientations/DefinitionAsCoordinateTransform.py +213 -0
  31. mtex/docpages/CrystalOrientations/MTEXvsBungeConvention.py +201 -0
  32. mtex/docpages/CrystalOrientations/OrientationDefinition.py +186 -0
  33. mtex/docpages/CrystalOrientations/OrientationEmbeddings.py +279 -0
  34. mtex/docpages/CrystalOrientations/OrientationExport.py +180 -0
  35. mtex/docpages/CrystalOrientations/OrientationFibre.py +311 -0
  36. mtex/docpages/CrystalOrientations/OrientationFundamentalRegion.py +271 -0
  37. mtex/docpages/CrystalOrientations/OrientationGrid.py +179 -0
  38. mtex/docpages/CrystalOrientations/OrientationImport.py +133 -0
  39. mtex/docpages/CrystalOrientations/OrientationInversePoleFigure.py +172 -0
  40. mtex/docpages/CrystalOrientations/OrientationPoleFigure.py +144 -0
  41. mtex/docpages/CrystalOrientations/OrientationStandard.py +266 -0
  42. mtex/docpages/CrystalOrientations/OrientationSymmetry.py +176 -0
  43. mtex/docpages/CrystalOrientations/OrientationVisualization3d.py +118 -0
  44. mtex/docpages/CrystalOrientations/OrientationVisualizationSections.py +127 -0
  45. mtex/docpages/CrystalOrientations/SpecimenSymmetry.py +145 -0
  46. mtex/docpages/EBSD3Analysis/EBSD3Analysis.py +249 -0
  47. mtex/docpages/EBSD3Analysis/EBSD3Plotting.py +240 -0
  48. mtex/docpages/EBSD3Analysis/Grains3D.py +174 -0
  49. mtex/docpages/EBSD3Analysis/Grains3DBoundaries.py +199 -0
  50. mtex/docpages/EBSD3Analysis/Grains3DOperations.py +222 -0
  51. mtex/docpages/EBSD3Analysis/Grains3DProperties.py +300 -0
  52. mtex/docpages/EBSD3Analysis/Grains3DReconstruction.py +159 -0
  53. mtex/docpages/EBSD3Analysis/Grains3DSmoothing.py +224 -0
  54. mtex/docpages/EBSD3Analysis/NeperInterface.py +211 -0
  55. mtex/docpages/EBSDAnalysis/EBSD2ODF.py +371 -0
  56. mtex/docpages/EBSDAnalysis/EBSDAdvancedMaps.py +254 -0
  57. mtex/docpages/EBSDAnalysis/EBSDDenoising.py +325 -0
  58. mtex/docpages/EBSDAnalysis/EBSDExport.py +158 -0
  59. mtex/docpages/EBSDAnalysis/EBSDFilling.py +333 -0
  60. mtex/docpages/EBSDAnalysis/EBSDGROD.py +276 -0
  61. mtex/docpages/EBSDAnalysis/EBSDGrid.py +453 -0
  62. mtex/docpages/EBSDAnalysis/EBSDIPFMap.py +255 -0
  63. mtex/docpages/EBSDAnalysis/EBSDImport.py +250 -0
  64. mtex/docpages/EBSDAnalysis/EBSDIndex.py +178 -0
  65. mtex/docpages/EBSDAnalysis/EBSDInter.py +174 -0
  66. mtex/docpages/EBSDAnalysis/EBSDInterfaceHDF5.py +268 -0
  67. mtex/docpages/EBSDAnalysis/EBSDKAM.py +241 -0
  68. mtex/docpages/EBSDAnalysis/EBSDMapsAndImages.py +283 -0
  69. mtex/docpages/EBSDAnalysis/EBSDOrientationAnalysis.py +211 -0
  70. mtex/docpages/EBSDAnalysis/EBSDOrientationPlots.py +215 -0
  71. mtex/docpages/EBSDAnalysis/EBSDPerceptualKey.py +141 -0
  72. mtex/docpages/EBSDAnalysis/EBSDPlotting.py +157 -0
  73. mtex/docpages/EBSDAnalysis/EBSDProfile.py +155 -0
  74. mtex/docpages/EBSDAnalysis/EBSDPseudoSymmetry.py +278 -0
  75. mtex/docpages/EBSDAnalysis/EBSDReferenceFrame.py +307 -0
  76. mtex/docpages/EBSDAnalysis/EBSDSelect.py +204 -0
  77. mtex/docpages/EBSDAnalysis/EBSDSharpPlot.py +295 -0
  78. mtex/docpages/EBSDAnalysis/EBSDSimulation.py +180 -0
  79. mtex/docpages/EBSDAnalysis/EBSDSpatialTransform.py +295 -0
  80. mtex/docpages/EBSDAnalysis/EBSDTrueEbsd.py +284 -0
  81. mtex/docpages/Elasticity/AnisotropicTheory.py +281 -0
  82. mtex/docpages/Elasticity/CPOSeismicProperties.py +248 -0
  83. mtex/docpages/Elasticity/IsotropicTheory.py +321 -0
  84. mtex/docpages/Elasticity/WaveVelocities.py +467 -0
  85. mtex/docpages/GeneralConcepts/ClusterDemo.py +149 -0
  86. mtex/docpages/GeneralConcepts/Contribute2Doc.py +81 -0
  87. mtex/docpages/GeneralConcepts/DensityEstimation.py +369 -0
  88. mtex/docpages/GeneralConcepts/GeneralConceptsConfiguration.py +99 -0
  89. mtex/docpages/GeneralConcepts/GeneralConceptsOptions.py +96 -0
  90. mtex/docpages/GeneralConcepts/Glossary.py +261 -0
  91. mtex/docpages/GeneralConcepts/Installation.py +311 -0
  92. mtex/docpages/GeneralConcepts/ListsAndIndexing.py +114 -0
  93. mtex/docpages/GeneralConcepts/MATLABtoPython.py +257 -0
  94. mtex/docpages/GeneralConcepts/MTEXScripts.py +100 -0
  95. mtex/docpages/GeneralConcepts/NotationAndConventions.py +185 -0
  96. mtex/docpages/GeneralConcepts/OptimalKernel.py +253 -0
  97. mtex/docpages/GeneralConcepts/Properties.py +162 -0
  98. mtex/docpages/GeneralConcepts/PythonDevelopers.py +172 -0
  99. mtex/docpages/GeneralConcepts/changelog.py +22 -0
  100. mtex/docpages/GrainBoundaries/BoundaryCurvature.py +278 -0
  101. mtex/docpages/GrainBoundaries/BoundaryIntersections.py +144 -0
  102. mtex/docpages/GrainBoundaries/BoundaryMisorientations.py +201 -0
  103. mtex/docpages/GrainBoundaries/BoundaryNormalDistribution.py +377 -0
  104. mtex/docpages/GrainBoundaries/BoundaryPlots.py +274 -0
  105. mtex/docpages/GrainBoundaries/BoundaryProperties.py +365 -0
  106. mtex/docpages/GrainBoundaries/BoundarySelect.py +208 -0
  107. mtex/docpages/GrainBoundaries/CSLBoundaries.py +402 -0
  108. mtex/docpages/GrainBoundaries/GrainSmoothing.py +258 -0
  109. mtex/docpages/GrainBoundaries/GrainSmoothingAdvanced.py +357 -0
  110. mtex/docpages/GrainBoundaries/QuadruplePoints.py +182 -0
  111. mtex/docpages/GrainBoundaries/SubGrainBoundaries.py +231 -0
  112. mtex/docpages/GrainBoundaries/TiltAndTwistBoundaries.py +251 -0
  113. mtex/docpages/GrainBoundaries/TriplePoints.py +246 -0
  114. mtex/docpages/GrainBoundaries/TwinningBoundaries.py +216 -0
  115. mtex/docpages/Grains/Dream3dGrains.py +100 -0
  116. mtex/docpages/Grains/EllipseBasedParameters.py +359 -0
  117. mtex/docpages/Grains/GrainExport.py +298 -0
  118. mtex/docpages/Grains/GrainMerge.py +291 -0
  119. mtex/docpages/Grains/GrainNeighbours.py +235 -0
  120. mtex/docpages/Grains/GrainOrientationParameters.py +428 -0
  121. mtex/docpages/Grains/GrainReconstruction.py +382 -0
  122. mtex/docpages/Grains/GrainReconstructionAdvanced.py +316 -0
  123. mtex/docpages/Grains/GrainReconstructionMCL.py +162 -0
  124. mtex/docpages/Grains/GrainSpatialPlots.py +340 -0
  125. mtex/docpages/Grains/Grain_dispersion_axes.py +317 -0
  126. mtex/docpages/Grains/HullBasedParameters.py +164 -0
  127. mtex/docpages/Grains/ProjectionBasedParameters.py +402 -0
  128. mtex/docpages/Grains/SelectingGrains.py +341 -0
  129. mtex/docpages/Grains/ShapeParameters.py +341 -0
  130. mtex/docpages/Misorientations/AngleDistributionFunction.py +177 -0
  131. mtex/docpages/Misorientations/AxisDistributionFunction.py +231 -0
  132. mtex/docpages/Misorientations/MisorientationDistributionFunction.py +228 -0
  133. mtex/docpages/Misorientations/MisorientationGrainExchangeSym.py +163 -0
  134. mtex/docpages/Misorientations/MisorientationTheory.py +359 -0
  135. mtex/docpages/Misorientations/Twinning.py +195 -0
  136. mtex/docpages/ODFAnalysis/BinghamODFs.py +244 -0
  137. mtex/docpages/ODFAnalysis/DetectionOfSampleSymmetry.py +209 -0
  138. mtex/docpages/ODFAnalysis/EulerAngleSections.py +212 -0
  139. mtex/docpages/ODFAnalysis/FibreODFs.py +225 -0
  140. mtex/docpages/ODFAnalysis/ODFCharacteristics.py +157 -0
  141. mtex/docpages/ODFAnalysis/ODFComponents.py +175 -0
  142. mtex/docpages/ODFAnalysis/ODFExport.py +198 -0
  143. mtex/docpages/ODFAnalysis/ODFImport.py +215 -0
  144. mtex/docpages/ODFAnalysis/ODFInversePoleFigure.py +158 -0
  145. mtex/docpages/ODFAnalysis/ODFModeling.py +155 -0
  146. mtex/docpages/ODFAnalysis/ODFPlot.py +218 -0
  147. mtex/docpages/ODFAnalysis/ODFPoleFigure.py +165 -0
  148. mtex/docpages/ODFAnalysis/ODFShapes.py +159 -0
  149. mtex/docpages/ODFAnalysis/ODFTheory.py +189 -0
  150. mtex/docpages/ODFAnalysis/RadialODFs.py +165 -0
  151. mtex/docpages/ODFAnalysis/RandomSampling.py +354 -0
  152. mtex/docpages/ODFAnalysis/SO3FunHarmonicRepresentation.py +225 -0
  153. mtex/docpages/ODFAnalysis/SigmaSections.py +260 -0
  154. mtex/docpages/PhaseTransitions/GrainGraphBasedReconstruction.py +338 -0
  155. mtex/docpages/PhaseTransitions/LowLevelParentGrainReconstruction.py +388 -0
  156. mtex/docpages/PhaseTransitions/MaParentGrainReconstruction.py +407 -0
  157. mtex/docpages/PhaseTransitions/MaParentGrainReconstructionAdvanced.py +461 -0
  158. mtex/docpages/PhaseTransitions/MartensiteVariants.py +309 -0
  159. mtex/docpages/PhaseTransitions/OrientationRelationshipFit.py +274 -0
  160. mtex/docpages/PhaseTransitions/ParentChildVariants.py +197 -0
  161. mtex/docpages/PhaseTransitions/PhaseTransitions.py +129 -0
  162. mtex/docpages/PhaseTransitions/TiBetaReconstruction.py +273 -0
  163. mtex/docpages/PhaseTransitions/TransformationTexture.py +184 -0
  164. mtex/docpages/PhaseTransitions/TriplePointBasedReconstruction.py +298 -0
  165. mtex/docpages/Plasticity/DislocationSystems.py +185 -0
  166. mtex/docpages/Plasticity/GND.py +316 -0
  167. mtex/docpages/Plasticity/Lankford.py +227 -0
  168. mtex/docpages/Plasticity/SachsModel.py +139 -0
  169. mtex/docpages/Plasticity/SchmidFactor.py +304 -0
  170. mtex/docpages/Plasticity/SingleSlipModel.py +228 -0
  171. mtex/docpages/Plasticity/SlipSystems.py +148 -0
  172. mtex/docpages/Plasticity/SlipTransmission.py +231 -0
  173. mtex/docpages/Plasticity/TaylorHex.py +227 -0
  174. mtex/docpages/Plasticity/TaylorModel.py +220 -0
  175. mtex/docpages/Plasticity/TextureEvolution.py +196 -0
  176. mtex/docpages/Plasticity/TwinningTutorial.py +174 -0
  177. mtex/docpages/Plasticity/VPSCImport.py +135 -0
  178. mtex/docpages/Plasticity/WBV.py +299 -0
  179. mtex/docpages/Plotting/Annotations.py +202 -0
  180. mtex/docpages/Plotting/AxesAlignment.py +225 -0
  181. mtex/docpages/Plotting/ColorMaps.py +186 -0
  182. mtex/docpages/Plotting/CombinedPlots.py +204 -0
  183. mtex/docpages/Plotting/ContourPlots.py +144 -0
  184. mtex/docpages/Plotting/Legends.py +73 -0
  185. mtex/docpages/Plotting/Multiplot.py +115 -0
  186. mtex/docpages/Plotting/PlotTypes.py +154 -0
  187. mtex/docpages/Plotting/PlottingExport.py +146 -0
  188. mtex/docpages/Plotting/SphericalProjections.py +185 -0
  189. mtex/docpages/Plotting/TransparencyDemo.py +213 -0
  190. mtex/docpages/PoleFigureAnalysis/PoleFigure2ODF.py +246 -0
  191. mtex/docpages/PoleFigureAnalysis/PoleFigure2ODFAmbiguity.py +475 -0
  192. mtex/docpages/PoleFigureAnalysis/PoleFigure2ODFGhostCorrection.py +242 -0
  193. mtex/docpages/PoleFigureAnalysis/PoleFigureCorrection.py +282 -0
  194. mtex/docpages/PoleFigureAnalysis/PoleFigureDubna.py +239 -0
  195. mtex/docpages/PoleFigureAnalysis/PoleFigureExport.py +186 -0
  196. mtex/docpages/PoleFigureAnalysis/PoleFigureImport.py +198 -0
  197. mtex/docpages/PoleFigureAnalysis/PoleFigurePlot.py +146 -0
  198. mtex/docpages/PoleFigureAnalysis/PoleFigureRefinement.py +265 -0
  199. mtex/docpages/PoleFigureAnalysis/PoleFigureSantaFe.py +203 -0
  200. mtex/docpages/PoleFigureAnalysis/PoleFigureSimulation.py +215 -0
  201. mtex/docpages/Rotations/RotationDefinition.py +278 -0
  202. mtex/docpages/Rotations/RotationFibre.py +192 -0
  203. mtex/docpages/Rotations/RotationImproper.py +159 -0
  204. mtex/docpages/Rotations/RotationOperations.py +204 -0
  205. mtex/docpages/Rotations/RotationPlotting.py +126 -0
  206. mtex/docpages/Rotations/RotationRepresentations.py +212 -0
  207. mtex/docpages/Rotations/RotationSpinTensor.py +243 -0
  208. mtex/docpages/Rotations/RotationTangentSpace.py +178 -0
  209. mtex/docpages/SO3Functions/HarmonicApproximationTheory.py +308 -0
  210. mtex/docpages/SO3Functions/RBFApproximationTheory.py +351 -0
  211. mtex/docpages/SO3Functions/SO3FunApproximationTheory.py +307 -0
  212. mtex/docpages/SO3Functions/SO3FunConcept.py +146 -0
  213. mtex/docpages/SO3Functions/SO3FunConvolution.py +359 -0
  214. mtex/docpages/SO3Functions/SO3FunDefinition.py +202 -0
  215. mtex/docpages/SO3Functions/SO3FunOperations.py +248 -0
  216. mtex/docpages/SO3Functions/SO3FunQuadrature.py +266 -0
  217. mtex/docpages/SO3Functions/SO3FunSymmetricFunctions.py +219 -0
  218. mtex/docpages/SO3Functions/SO3FunVectorField.py +341 -0
  219. mtex/docpages/SO3Functions/SO3FunVectorValued.py +248 -0
  220. mtex/docpages/SO3Functions/SO3Kernels.py +492 -0
  221. mtex/docpages/SO3Functions/WignerFunctions.py +186 -0
  222. mtex/docpages/SphericalFunctions/S1FunHarmonics.py +301 -0
  223. mtex/docpages/SphericalFunctions/S2Bingham.py +183 -0
  224. mtex/docpages/SphericalFunctions/S2FunApproximationInterpolation.py +141 -0
  225. mtex/docpages/SphericalFunctions/S2FunAxisField.py +107 -0
  226. mtex/docpages/SphericalFunctions/S2FunConcept.py +133 -0
  227. mtex/docpages/SphericalFunctions/S2FunHarmonicRepresentation.py +182 -0
  228. mtex/docpages/SphericalFunctions/S2FunOperations.py +251 -0
  229. mtex/docpages/SphericalFunctions/S2FunPlotting.py +153 -0
  230. mtex/docpages/SphericalFunctions/S2FunQuadrature.py +121 -0
  231. mtex/docpages/SphericalFunctions/S2FunRadon.py +173 -0
  232. mtex/docpages/SphericalFunctions/S2FunSampling.py +231 -0
  233. mtex/docpages/SphericalFunctions/S2FunSym.py +117 -0
  234. mtex/docpages/SphericalFunctions/S2FunVectorField.py +171 -0
  235. mtex/docpages/SphericalFunctions/S2FunVectorValued.py +185 -0
  236. mtex/docpages/SphericalFunctions/S2Kernels.py +261 -0
  237. mtex/docpages/SphericalFunctions/SphericalHarmonics.py +145 -0
  238. mtex/docpages/Tensors/BirefringenceDemo.py +414 -0
  239. mtex/docpages/Tensors/MagneticAnisotropy.py +217 -0
  240. mtex/docpages/Tensors/PiezoElectricity.py +187 -0
  241. mtex/docpages/Tensors/TensorArithmetics.py +228 -0
  242. mtex/docpages/Tensors/TensorAverage.py +247 -0
  243. mtex/docpages/Tensors/TensorDefinition.py +274 -0
  244. mtex/docpages/Tensors/TensorImport.py +144 -0
  245. mtex/docpages/Tensors/TensorVisualisation.py +174 -0
  246. mtex/docpages/Tutorials/BoundaryTutorial.py +202 -0
  247. mtex/docpages/Tutorials/EBSDTutorial.py +235 -0
  248. mtex/docpages/Tutorials/GrainTutorial.py +290 -0
  249. mtex/docpages/Tutorials/ODFTutorial.py +268 -0
  250. mtex/docpages/Tutorials/PoleFigureTutorial.py +192 -0
  251. mtex/docpages/Vectors/VectorDefinition.py +182 -0
  252. mtex/docpages/Vectors/VectorGrids.py +166 -0
  253. mtex/docpages/Vectors/VectorsAxes.py +227 -0
  254. mtex/docpages/Vectors/VectorsDensityEstimation.py +415 -0
  255. mtex/docpages/Vectors/VectorsExport.py +127 -0
  256. mtex/docpages/Vectors/VectorsImport.py +129 -0
  257. mtex/docpages/Vectors/VectorsOperations.py +183 -0
  258. mtex/functions/__init__.py +72 -0
  259. mtex/functions/bingham.py +476 -0
  260. mtex/functions/characteristics.py +940 -0
  261. mtex/functions/density.py +315 -0
  262. mtex/functions/discrepancy.py +622 -0
  263. mtex/functions/funcs.py +29 -0
  264. mtex/functions/funops.py +401 -0
  265. mtex/functions/halfwidth.py +583 -0
  266. mtex/functions/handles.py +585 -0
  267. mtex/functions/harmonicarithmetic.py +34 -0
  268. mtex/functions/harmonics.py +519 -0
  269. mtex/functions/kde.py +211 -0
  270. mtex/functions/kernelfunctions.py +1125 -0
  271. mtex/functions/kernels.py +1263 -0
  272. mtex/functions/lsqr.py +68 -0
  273. mtex/functions/nfft.py +150 -0
  274. mtex/functions/polefigure.py +846 -0
  275. mtex/functions/quadrature.py +322 -0
  276. mtex/functions/rbf.py +802 -0
  277. mtex/functions/rbfinterpolation.py +156 -0
  278. mtex/functions/s1fun.py +339 -0
  279. mtex/functions/s2axisfield.py +215 -0
  280. mtex/functions/s2fun.py +530 -0
  281. mtex/functions/s2funclass.py +78 -0
  282. mtex/functions/s2funtri.py +152 -0
  283. mtex/functions/s2vectorfield.py +513 -0
  284. mtex/functions/so3fun.py +567 -0
  285. mtex/functions/so3funclass.py +35 -0
  286. mtex/functions/so3vectorfield.py +915 -0
  287. mtex/functions/transforms.py +971 -0
  288. mtex/geometry/__init__.py +94 -0
  289. mtex/geometry/_array.py +170 -0
  290. mtex/geometry/arguments.py +24 -0
  291. mtex/geometry/crystalaxes.py +178 -0
  292. mtex/geometry/crystalshape.py +584 -0
  293. mtex/geometry/csl.py +193 -0
  294. mtex/geometry/data/__init__.py +0 -0
  295. mtex/geometry/data/cif/4060300.cif +397 -0
  296. mtex/geometry/data/cif/4060301.cif +316 -0
  297. mtex/geometry/data/cif/5000035.cif +72 -0
  298. mtex/geometry/data/cif/Ag-Silver.cif +248 -0
  299. mtex/geometry/data/cif/Al-Aluminum.cif +240 -0
  300. mtex/geometry/data/cif/Al2O3-Corundum.cif +83 -0
  301. mtex/geometry/data/cif/C-Diamond.cif +226 -0
  302. mtex/geometry/data/cif/Cr-Chromium.cif +152 -0
  303. mtex/geometry/data/cif/Cu-Copper.cif +248 -0
  304. mtex/geometry/data/cif/Fe-Iron-Austenite.cif +250 -0
  305. mtex/geometry/data/cif/Fe-Iron-alpha.cif +154 -0
  306. mtex/geometry/data/cif/Fe-Iron-beta.cif +154 -0
  307. mtex/geometry/data/cif/Fe-Iron-delta.cif +154 -0
  308. mtex/geometry/data/cif/Fe-Iron-gamma.cif +248 -0
  309. mtex/geometry/data/cif/GaAs.cif +149 -0
  310. mtex/geometry/data/cif/Hematite.cif +84 -0
  311. mtex/geometry/data/cif/LaB6.cif +91 -0
  312. mtex/geometry/data/cif/Magnetite.cif +232 -0
  313. mtex/geometry/data/cif/Mg-Magnesium.cif +75 -0
  314. mtex/geometry/data/cif/Mn-Manganese-gamma.cif +227 -0
  315. mtex/geometry/data/cif/Mo-Molybdenum-bcc.cif +131 -0
  316. mtex/geometry/data/cif/Mo-Molybdenum-fcc.cif +227 -0
  317. mtex/geometry/data/cif/NaCl-Halite.cif +232 -0
  318. mtex/geometry/data/cif/Ni-Nickel-cubic.cif +264 -0
  319. mtex/geometry/data/cif/Ni-Nickel-hexagonal.cif +69 -0
  320. mtex/geometry/data/cif/Rhabdite.cif +142 -0
  321. mtex/geometry/data/cif/Si-Silicon.cif +249 -0
  322. mtex/geometry/data/cif/Ti-Titanium-alpha.cif +79 -0
  323. mtex/geometry/data/cif/Ti-Titanium-beta.cif +154 -0
  324. mtex/geometry/data/cif/ZrO2-Baddeleyite.cif +42 -0
  325. mtex/geometry/data/cif/crystal.phl +181 -0
  326. mtex/geometry/data/cif/olivin.cif +77 -0
  327. mtex/geometry/data/cif/quartz.cif +63 -0
  328. mtex/geometry/data/crystalshapes.py +172 -0
  329. mtex/geometry/data/pointgroupnames.py +98 -0
  330. mtex/geometry/display.py +148 -0
  331. mtex/geometry/fibre.py +408 -0
  332. mtex/geometry/framepair.py +20 -0
  333. mtex/geometry/frames.py +1076 -0
  334. mtex/geometry/frametransform.py +75 -0
  335. mtex/geometry/funcs.py +124 -0
  336. mtex/geometry/gridlayout.py +109 -0
  337. mtex/geometry/grids/__init__.py +0 -0
  338. mtex/geometry/grids/fibonacci.py +77 -0
  339. mtex/geometry/grids/gridsearch.py +343 -0
  340. mtex/geometry/grids/healpix.py +38 -0
  341. mtex/geometry/grids/localgrids.py +111 -0
  342. mtex/geometry/grids/orientationtree.py +185 -0
  343. mtex/geometry/grids/s1grid.py +124 -0
  344. mtex/geometry/grids/s2grid.py +306 -0
  345. mtex/geometry/grids/search.py +162 -0
  346. mtex/geometry/grids/so3grid.py +307 -0
  347. mtex/geometry/grids/superfibonacci.py +130 -0
  348. mtex/geometry/homochoric.py +115 -0
  349. mtex/geometry/hull.py +155 -0
  350. mtex/geometry/install.py +28 -0
  351. mtex/geometry/kernels.py +1108 -0
  352. mtex/geometry/latticetype.py +60 -0
  353. mtex/geometry/miller.py +210 -0
  354. mtex/geometry/orientation.py +552 -0
  355. mtex/geometry/orientationregion.py +335 -0
  356. mtex/geometry/parent2child.py +580 -0
  357. mtex/geometry/plane.py +180 -0
  358. mtex/geometry/plottingconvention.py +308 -0
  359. mtex/geometry/products.py +110 -0
  360. mtex/geometry/quaternion.py +717 -0
  361. mtex/geometry/representations.py +292 -0
  362. mtex/geometry/s2triangulation.py +93 -0
  363. mtex/geometry/session.py +136 -0
  364. mtex/geometry/settings.py +114 -0
  365. mtex/geometry/slipsystem.py +485 -0
  366. mtex/geometry/spatialtransform.py +786 -0
  367. mtex/geometry/sphericalregion.py +524 -0
  368. mtex/geometry/standardorientations.py +299 -0
  369. mtex/geometry/symmetry.py +497 -0
  370. mtex/geometry/symmetryops.py +383 -0
  371. mtex/geometry/symreduce.py +111 -0
  372. mtex/geometry/tangent.py +518 -0
  373. mtex/geometry/units.py +7 -0
  374. mtex/geometry/vector3d.py +890 -0
  375. mtex/geometry/vocabulary.py +51 -0
  376. mtex/io/__init__.py +31 -0
  377. mtex/io/ang.py +196 -0
  378. mtex/io/cif.py +112 -0
  379. mtex/io/completer.py +291 -0
  380. mtex/io/crc.py +162 -0
  381. mtex/io/ctf.py +147 -0
  382. mtex/io/exportebsd.py +526 -0
  383. mtex/io/exportodf.py +127 -0
  384. mtex/io/exportorientation.py +72 -0
  385. mtex/io/exportpolefigure.py +36 -0
  386. mtex/io/generic.py +97 -0
  387. mtex/io/h5.py +840 -0
  388. mtex/io/h5array.py +125 -0
  389. mtex/io/hdf5_config/Bruker.json +59 -0
  390. mtex/io/hdf5_config/EDAX.json +230 -0
  391. mtex/io/hdf5_config/EDAXh5.json +78 -0
  392. mtex/io/hdf5_config/EMSphInx.json +69 -0
  393. mtex/io/hdf5_config/Oxford.json +82 -0
  394. mtex/io/hdf5_config/ThermoFisher.json +47 -0
  395. mtex/io/importscript.py +150 -0
  396. mtex/io/inspect.py +439 -0
  397. mtex/io/kernels.py +493 -0
  398. mtex/io/load.py +528 -0
  399. mtex/io/load3d.py +265 -0
  400. mtex/io/loadgrains3d.py +172 -0
  401. mtex/io/loadodf.py +155 -0
  402. mtex/io/loadpolefigure.py +419 -0
  403. mtex/io/loadtensor.py +94 -0
  404. mtex/io/opendoc.py +164 -0
  405. mtex/io/orientations.py +76 -0
  406. mtex/io/osc.py +205 -0
  407. mtex/io/polefigureformats.py +827 -0
  408. mtex/io/sampledata.json +1521 -0
  409. mtex/io/sampledata.py +531 -0
  410. mtex/io/table.py +170 -0
  411. mtex/io/vectors.py +119 -0
  412. mtex/io/vocabulary.py +104 -0
  413. mtex/maps/__init__.py +48 -0
  414. mtex/maps/boundary.py +870 -0
  415. mtex/maps/boundaryresampling.py +394 -0
  416. mtex/maps/calcgrains.py +241 -0
  417. mtex/maps/criteria.py +266 -0
  418. mtex/maps/decomposition.py +385 -0
  419. mtex/maps/dynprop.py +33 -0
  420. mtex/maps/ebsd.py +678 -0
  421. mtex/maps/fmc.py +514 -0
  422. mtex/maps/funcs.py +56 -0
  423. mtex/maps/grains.py +686 -0
  424. mtex/maps/gridify.py +321 -0
  425. mtex/maps/hexgrid.py +63 -0
  426. mtex/maps/intragranular.py +500 -0
  427. mtex/maps/kernels.py +1698 -0
  428. mtex/maps/lattice.py +460 -0
  429. mtex/maps/mapimage.py +534 -0
  430. mtex/maps/phaselist.py +231 -0
  431. mtex/maps/polygon.py +269 -0
  432. mtex/maps/pseudosym.py +93 -0
  433. mtex/maps/quadruple.py +121 -0
  434. mtex/maps/reconstruction.py +1014 -0
  435. mtex/maps/registration.py +253 -0
  436. mtex/maps/segment.py +128 -0
  437. mtex/maps/shape.py +431 -0
  438. mtex/maps/simulate.py +171 -0
  439. mtex/maps/smoothing.py +304 -0
  440. mtex/maps/traces.py +201 -0
  441. mtex/maps/trueebsd.py +632 -0
  442. mtex/maps/variantgraph.py +395 -0
  443. mtex/maps3d/__init__.py +12 -0
  444. mtex/maps3d/calcgrains3d.py +191 -0
  445. mtex/maps3d/ebsd3.py +278 -0
  446. mtex/maps3d/grain3boundary.py +296 -0
  447. mtex/maps3d/grain3d.py +419 -0
  448. mtex/maps3d/intragranular3d.py +183 -0
  449. mtex/maps3d/neper.py +194 -0
  450. mtex/maps3d/orientfaces.py +99 -0
  451. mtex/maps3d/section3d.py +179 -0
  452. mtex/maps3d/smoothing3d.py +163 -0
  453. mtex/maps3d/voxellattice.py +162 -0
  454. mtex/plotting/__init__.py +167 -0
  455. mtex/plotting/colormaps.py +213 -0
  456. mtex/plotting/directionkeys.py +471 -0
  457. mtex/plotting/distributionplot.py +116 -0
  458. mtex/plotting/fibreplot.py +38 -0
  459. mtex/plotting/grainplots.py +128 -0
  460. mtex/plotting/kernelplot.py +122 -0
  461. mtex/plotting/kernels.py +235 -0
  462. mtex/plotting/keywords.py +102 -0
  463. mtex/plotting/mapplot.py +1118 -0
  464. mtex/plotting/maps.py +395 -0
  465. mtex/plotting/mtexfigure.py +641 -0
  466. mtex/plotting/orientationkeys.py +474 -0
  467. mtex/plotting/patalakey.py +204 -0
  468. mtex/plotting/planarkey.py +158 -0
  469. mtex/plotting/polarplot.py +311 -0
  470. mtex/plotting/polefigureplot.py +292 -0
  471. mtex/plotting/poles.py +82 -0
  472. mtex/plotting/render3d.py +295 -0
  473. mtex/plotting/richdisplay.py +84 -0
  474. mtex/plotting/scene3d.py +339 -0
  475. mtex/plotting/sectionplot.py +474 -0
  476. mtex/plotting/sections.py +590 -0
  477. mtex/plotting/sectorfold.py +263 -0
  478. mtex/plotting/shapeplot.py +327 -0
  479. mtex/plotting/space.py +256 -0
  480. mtex/plotting/spaceplot.py +891 -0
  481. mtex/plotting/spherical.py +601 -0
  482. mtex/plotting/sphericalplot.py +1436 -0
  483. mtex/plotting/tensorplot.py +125 -0
  484. mtex/plotting/vocabulary.py +29 -0
  485. mtex/plotting/volumeplot.py +400 -0
  486. mtex/tensors/__init__.py +12 -0
  487. mtex/tensors/kernels.py +326 -0
  488. mtex/tensors/tensor.py +1203 -0
  489. mtex/wizard/__init__.py +21 -0
  490. mtex/wizard/__main__.py +18 -0
  491. mtex/wizard/binning.py +61 -0
  492. mtex/wizard/browser.py +552 -0
  493. mtex/wizard/callbacks.py +745 -0
  494. mtex/wizard/desktop.py +70 -0
  495. mtex/wizard/icon.svg +23 -0
  496. mtex/wizard/phases.py +287 -0
  497. mtex/wizard/pictogram.py +289 -0
  498. mtex/wizard/scriptview.py +175 -0
  499. mtex/wizard/state.py +125 -0
  500. mtex/wizard/views.py +687 -0
  501. mtex/wizard/window.py +261 -0
  502. mtex-1.0.0.dist-info/METADATA +190 -0
  503. mtex-1.0.0.dist-info/RECORD +506 -0
  504. mtex-1.0.0.dist-info/WHEEL +4 -0
  505. mtex-1.0.0.dist-info/entry_points.txt +2 -0
  506. mtex-1.0.0.dist-info/licenses/LICENSE +340 -0
mtex/__init__.py ADDED
@@ -0,0 +1,94 @@
1
+ """MTEX: the crystallographic texture analysis toolbox
2
+
3
+ The Python port of MTEX: crystal symmetry and orientations, EBSD maps, grains and their
4
+ boundaries, pole figures, orientation distribution functions and tensors, in one flat
5
+ namespace, with MATLAB's names
6
+
7
+ from mtex import *
8
+ cs = crystalFrame('m-3m')
9
+ ori = orientation.byEuler(30*degree, 50*degree, 10*degree, cs)
10
+ ebsd = mtexdata('forsterite')
11
+ grains = calcGrains(ebsd('indexed'))
12
+
13
+ The namespace is assembled from the layers, each importing only those above it
14
+
15
+ mtex.geometry vectors, rotations, orientations, point groups, frames, Miller indices, grids
16
+ mtex.functions harmonics, kernels, functions on S2 and SO(3), ODFs, pole figures
17
+ mtex.tensors the tensor container, its algebra and the physical tensors
18
+ mtex.maps EBSD maps, grains, grain boundaries, parent grain reconstruction
19
+ mtex.maps3d maps of volumes: EBSD3, 3D grains and boundaries
20
+ mtex.analysis what iterates or optimises: pole figure inversion, elasticity, Taylor, ...
21
+ mtex.io loadEBSD, loadPoleFigure, export, mtexdata, openDoc
22
+ mtex.plotting plot, plotPF, plotIPF, plotSection, the colour keys (matplotlib, the plot extra)
23
+
24
+ Help
25
+
26
+ help(orientation) what a class or function is and takes
27
+ openDoc('GrainReconstruction') a documentation page as a script to run
28
+ mtexdata() the sample data sets
29
+
30
+ The documentation is at https://mtex-toolbox.github.io
31
+ """
32
+ from importlib.metadata import PackageNotFoundError as _PackageNotFoundError, version as _version
33
+
34
+ # the version of the installed distribution
35
+ try:
36
+ __version__ = _version("mtex")
37
+ except _PackageNotFoundError:
38
+ __version__ = "unknown"
39
+
40
+ from typing import TYPE_CHECKING
41
+
42
+ from . import geometry as _geometry
43
+ from . import maps as _maps
44
+ from . import maps3d as _maps3d
45
+ from . import functions as _functions
46
+ from . import tensors as _tensors
47
+ from . import analysis as _analysis
48
+ from . import io as _io
49
+ from . import plotting as _plotting
50
+ from .geometry import * # noqa: F401,F403
51
+ from .maps import * # noqa: F401,F403
52
+ from .maps3d import * # noqa: F401,F403
53
+ from .functions import * # noqa: F401,F403
54
+ from .tensors import * # noqa: F401,F403
55
+ from .analysis import * # noqa: F401,F403
56
+ from .io import * # noqa: F401,F403
57
+ from .plotting import * # noqa: F401,F403
58
+ from .wizard import importWizard # noqa: F401
59
+
60
+ # the one flat namespace, the layers in the order they import each other
61
+ __all__ = []
62
+ __all__ += _geometry.__all__
63
+ __all__ += _maps.__all__
64
+ __all__ += _maps3d.__all__
65
+ __all__ += _functions.__all__
66
+ __all__ += _tensors.__all__
67
+ __all__ += _analysis.__all__
68
+ __all__ += _io.__all__
69
+ __all__ += _plotting.__all__
70
+ __all__ += ["importWizard", "xvector", "yvector", "zvector"]
71
+
72
+
73
+ # the displays of a notebook and of the IPython terminal, when mtex is imported in one
74
+ from .plotting.richdisplay import registerDisplays as _registerDisplays
75
+ _registerDisplays()
76
+
77
+ # in IPython, the strings a call takes completed inside its quotes
78
+ from .io.completer import registerCompleter as _registerCompleter
79
+ _registerCompleter()
80
+
81
+ # the user's saved settings, what MATLAB keeps in mtex_settings.m
82
+ from .geometry.settings import loadSettings as _loadSettings
83
+ _loadSettings()
84
+
85
+
86
+ # xvector, yvector, zvector are fresh on every access
87
+ def __getattr__(name):
88
+ if name in ("xvector", "yvector", "zvector"):
89
+ return getattr(_geometry, name)
90
+ raise AttributeError(name)
91
+
92
+
93
+ if TYPE_CHECKING:
94
+ from .geometry.vector3d import xvector, yvector, zvector
@@ -0,0 +1,34 @@
1
+ """the analysis layer: the algorithms that iterate or optimise over the cores, from the
2
+ pole figure inversion to the denoising of a map"""
3
+ from .elasticity import (velocity, energyVector, YoungsModulus, linearCompressibility, volumeCompressibility,
4
+ shearModulus, PoissonRatio, bulkModulus, isotropicShearModulus, HashinShtrikmanModulus,
5
+ hashinShtrikmanBounds)
6
+ from .mechanics import (meanStress, deviatoric, deviatoricStress, deviatoricStrain, equivalentStress, equivalentStrain,
7
+ octahedralStrain, axisRatios, maxStrain, calcShearStress, SchmidFactor, CauchyStrain,
8
+ GreenStrain, strainRate, spin, angularVelocityVector, rotationRate, vorticity, spinTensorOf,
9
+ dislocationDensity)
10
+ from .optics import refractiveIndex, birefringence, opticalAxis, spectralTransmission
11
+ from .taylor import calcTaylor, linearProgram, linprogCentre, TaylorModel
12
+ from .texture import calcTensor, calcLankford, calcKearnsFactor, SO3FunSBF, doEulerStep
13
+ from .pf2odf import MLSSolver, zeroRangeMethod, calcODF, calcODFIterative
14
+ from .embedding import embedding, embeddingSpec, double, setDouble
15
+ from .optimalsample import optimalSample, OptimalSampleResult
16
+ from .cluster import calcCluster, classix, knnRadius
17
+ from .variational import EBSDFilter, splineFilter, halfQuadraticFilter, l1TVFilter, infimalConvolutionFilter
18
+ from .dislocations import fitDislocationSystems
19
+ from .denoising import meanFilter, medianFilter, KuwaharaFilter
20
+ from .gbnd import calcGBNDKernel
21
+ from .gbnd3d import calcGBND
22
+
23
+ __all__ = ["velocity", "energyVector", "YoungsModulus", "linearCompressibility", "volumeCompressibility",
24
+ "shearModulus", "PoissonRatio", "bulkModulus", "isotropicShearModulus", "HashinShtrikmanModulus",
25
+ "hashinShtrikmanBounds", "meanStress", "deviatoric", "deviatoricStress", "deviatoricStrain",
26
+ "equivalentStress", "equivalentStrain", "octahedralStrain", "axisRatios", "maxStrain", "calcShearStress",
27
+ "SchmidFactor", "CauchyStrain", "GreenStrain", "strainRate", "spin", "angularVelocityVector", "rotationRate",
28
+ "vorticity", "spinTensorOf", "dislocationDensity", "refractiveIndex", "birefringence", "opticalAxis",
29
+ "spectralTransmission", "calcTaylor", "linearProgram", "linprogCentre", "TaylorModel", "calcTensor",
30
+ "calcLankford", "calcKearnsFactor", "SO3FunSBF", "doEulerStep", "MLSSolver", "zeroRangeMethod", "calcODF",
31
+ "calcODFIterative", "embedding", "embeddingSpec", "double", "setDouble", "optimalSample",
32
+ "OptimalSampleResult", "calcCluster", "classix", "knnRadius", "EBSDFilter", "splineFilter",
33
+ "halfQuadraticFilter", "l1TVFilter", "infimalConvolutionFilter", "fitDislocationSystems", "meanFilter",
34
+ "medianFilter", "KuwaharaFilter", "calcGBND", "calcGBNDKernel"]
@@ -0,0 +1,308 @@
1
+ # clustering directions and orientations (MATLAB vector3d/calcCluster, orientation/calcCluster,
2
+ # extern/classix; docs/plans/functions.md F6, ported 2026-09-22)
3
+ #
4
+ # cId, center = calcCluster(v) CLASSIX on the coordinates
5
+ # cId, center = calcCluster(ori, method='classix', radius=, minPoints=)
6
+ # cId, center = calcCluster(ori) the modes of the density, MATLAB's default
7
+ # cId, center = calcCluster(ori, method='hierarchical', maxAngle=15*degree, numCluster=)
8
+ # labels = classix(X, radius, minPts=, mergeScale=1.5)
9
+ #
10
+ # CLASSIX (Chen and Guettel, Fast and explainable clustering based on sorting,
11
+ # arXiv:2202.01456): the data is centred, scaled by its median norm and sorted along its
12
+ # first principal axis; every point joins the first group whose centre lies within radius;
13
+ # groups whose centres lie within mergeScale times the radius are merged; a cluster below
14
+ # minPts points is dissolved into the nearest larger one. Directions cluster on their
15
+ # coordinates, axes on the rank one tensor that identifies v with -v, orientations on the
16
+ # isometric embedding that carries the symmetry. The hierarchical method merges the closest
17
+ # pair of centres until the count or the angle is reached; the density method takes the
18
+ # modes the orientations ascend to.
19
+ from __future__ import annotations
20
+
21
+ import numpy as np
22
+
23
+ from ..geometry.orientation import orientation
24
+ from ..geometry.quaternion import rotation
25
+ from ..geometry.units import degree
26
+ from ..geometry.vector3d import vector3d
27
+ from ..geometry.install import install
28
+
29
+
30
+ # ------------------------------------------------------------------ CLASSIX
31
+
32
+ # the entries of one block of distances when the small clusters are dissolved
33
+ DISSOLVE_BLOCK = 1 << 22
34
+
35
+
36
+ def classix(X, radius, minPts=1, mergeScale=1.5, mergeTiny=True):
37
+ """one cluster label per row of X, counted from zero"""
38
+ X = np.asarray(X, dtype=float)
39
+ if X.ndim == 1:
40
+ X = X[:, None]
41
+ n, d = X.shape
42
+ if n == 0:
43
+ return np.zeros(0, dtype=int)
44
+ if radius <= 0:
45
+ raise ValueError("the radius must be positive")
46
+ # centre by the mean, scale by the median norm
47
+ x = X - X.mean(axis=0)
48
+ scale = np.median(np.linalg.norm(x, axis=1))
49
+ x = x / (scale if scale > 0 else 1.0)
50
+ # the scores along the first principal axis, oriented deterministically
51
+ if d == 1:
52
+ u = x[:, 0].copy()
53
+ else:
54
+ vals, vecs = np.linalg.eigh(x.T @ x)
55
+ u = x @ vecs[:, np.argmax(np.abs(vals))]
56
+ u = u * (1.0 if u[0] == 0 else -np.sign(u[0]))
57
+ perm = np.argsort(u, kind="stable")
58
+ x, u = x[perm], u[perm]
59
+ halfN = np.sum(x * x, axis=1) / 2
60
+ halfR2 = radius ** 2 / 2
61
+ # aggregation: the first group within the radius takes the point
62
+ label = np.full(n, -1)
63
+ centres, sizes = [], []
64
+ for i in range(n):
65
+ if label[i] >= 0:
66
+ continue
67
+ lab = len(centres)
68
+ centres.append(i)
69
+ sizes.append(1)
70
+ label[i] = lab
71
+ hi = np.searchsorted(u, u[i] + radius, side="right")
72
+ if hi <= i + 1:
73
+ continue
74
+ window = slice(i + 1, hi)
75
+ close = (label[window] < 0) & (halfN[window] - x[window] @ x[i] <= halfR2 - halfN[i])
76
+ idx = np.flatnonzero(close) + i + 1
77
+ label[idx] = lab
78
+ sizes[lab] += idx.size
79
+ centres, sizes = np.array(centres), np.array(sizes)
80
+ ng = len(centres)
81
+ # merge the group centres within mergeScale times the radius by union find
82
+ gx, gu, gh = x[centres], u[centres], halfN[centres]
83
+ parent = np.arange(ng)
84
+
85
+ def find(a):
86
+ while parent[a] != a:
87
+ parent[a] = parent[parent[a]]
88
+ a = parent[a]
89
+ return a
90
+
91
+ mr = mergeScale * radius
92
+ for i in range(ng):
93
+ if not mergeTiny and sizes[i] < minPts:
94
+ continue
95
+ hi = np.searchsorted(gu, gu[i] + mr, side="right")
96
+ if hi <= i + 1:
97
+ continue
98
+ window = slice(i + 1, hi)
99
+ close = gh[window] - gx[window] @ gx[i] <= mr ** 2 / 2 - gh[i]
100
+ if not mergeTiny:
101
+ close &= sizes[window] >= minPts
102
+ ri = find(i)
103
+ for j in np.flatnonzero(close) + i + 1:
104
+ rj = find(j)
105
+ if ri != rj:
106
+ if ri < rj:
107
+ parent[rj] = ri
108
+ else:
109
+ parent[ri] = rj
110
+ ri = rj
111
+ gLabel, counts = _renumber(np.array([find(k) for k in range(ng)]), sizes)
112
+ # dissolve the clusters below minPts into the nearest group of a large enough cluster
113
+ if np.any(counts < minPts):
114
+ fixed = gLabel.copy()
115
+ large = counts[fixed] >= minPts
116
+ if np.any(large):
117
+ # every group of a small cluster to the nearest group of a large one, in blocks of rows
118
+ small = np.flatnonzero(~large)
119
+ step = max(1, DISSOLVE_BLOCK // len(gh))
120
+ for a in range(0, len(small), step):
121
+ g = small[a:a + step]
122
+ dist = gh - gx[g] @ gx.T
123
+ dist[:, ~large] = np.inf
124
+ gLabel[g] = fixed[np.argmin(dist, axis=1)]
125
+ gLabel, counts = _renumber(gLabel, sizes)
126
+ out = np.empty(n, dtype=int)
127
+ out[perm] = gLabel[label]
128
+ return out
129
+
130
+
131
+ # the labels renamed to 0..K-1, in order of appearance, with the points per cluster
132
+ def _renumber(gLabel, sizes):
133
+ uniq, inv = np.unique(gLabel, return_inverse=True)
134
+ counts = np.bincount(inv, weights=sizes, minlength=len(uniq)).astype(int)
135
+ return inv, counts
136
+
137
+
138
+ def knnRadius(X, k=10, sub=1500):
139
+ """the median distance to the tenth nearest neighbour of a subsample, the estimate CLASSIX suggests"""
140
+ from scipy.spatial import cKDTree
141
+ X = np.asarray(X, dtype=float)
142
+ n = len(X)
143
+ if n <= k + 1:
144
+ return 1.0
145
+ idx = np.arange(n) if n <= sub else np.unique(np.round(np.linspace(0, n - 1, sub)).astype(int))
146
+ d, _ = cKDTree(X).query(X[idx], k=k + 1)
147
+ return float(np.median(d[:, -1]))
148
+
149
+
150
+ # ------------------------------------------------------------------ the clusters of directions and orientations
151
+
152
+ def calcCluster(x, *args, method=None, radius=None, minPoints=None, mergeScale=1.5, numCluster=None, maxAngle=None,
153
+ halfwidth=5 * degree, weights=None, resolution=2.5 * degree, verbose=False):
154
+ """the clusters of directions or orientations: one cluster id per element, counted from
155
+ zero, and the centre of every cluster
156
+
157
+ cId, center = calcCluster(v) directions by CLASSIX
158
+ cId, center = calcCluster(ori, method='classix', radius=0.1, minPoints=15)
159
+ cId, center = calcCluster(ori) the modes of the density
160
+ cId, center = calcCluster(ori, method='hierarchical', maxAngle=15*degree)
161
+ cId, center = calcCluster(v, method='hierarchical', numCluster=5)
162
+ """
163
+ for a in args:
164
+ if isinstance(a, str):
165
+ method = a
166
+ isOri = isinstance(x, orientation)
167
+ if method is None:
168
+ method = "odf" if isOri else "classix"
169
+ if method == "classix":
170
+ return _classixCluster(x, radius, minPoints, mergeScale)
171
+ if method == "hierarchical":
172
+ return _hierarchical(x, numCluster, maxAngle, weights, resolution)
173
+ if method == "odf":
174
+ if not isOri:
175
+ raise ValueError("the density method clusters orientations; use 'classix' or 'hierarchical' for directions")
176
+ return _densityCluster(x, halfwidth, weights, numCluster)
177
+ raise ValueError("the method is 'classix', 'hierarchical' or 'odf'")
178
+
179
+
180
+ def _classixCluster(x, radius, minPoints, mergeScale):
181
+ n = x.size
182
+ if isinstance(x, orientation):
183
+ from .embedding import embedding
184
+ X = embedding(x.flatten()).double()
185
+ r = 0.5 * knnRadius(X) / np.max(np.std(X, axis=0)) if radius is None else float(radius)
186
+ else:
187
+ v = x.flatten()
188
+ xyz = v.normalize().data
189
+ if v.antipodal:
190
+ X = np.stack([xyz[:, 0] ** 2, xyz[:, 1] ** 2, xyz[:, 2] ** 2, xyz[:, 0] * xyz[:, 1], xyz[:, 0] * xyz[:, 2], xyz[:, 1] * xyz[:, 2]], axis=1)
191
+ else:
192
+ X = xyz
193
+ r = 2 * knnRadius(X) if radius is None else float(radius)
194
+ mp = max(1, round(n / 100)) if minPoints is None else int(minPoints)
195
+ cId = classix(X, r, minPts=mp, mergeScale=mergeScale)
196
+ return cId.reshape(x.shape), _centers(x, cId)
197
+
198
+
199
+ # the mean of every cluster, as the elements are: an axis mean for axes, a symmetry reduced
200
+ # mean for orientations
201
+ def _centers(x, cId):
202
+ K = int(cId.max()) + 1 if cId.size else 0
203
+ flat = x.flatten()
204
+ if isinstance(x, orientation):
205
+ q = np.stack([rotation(flat[cId == c].mean().data).data.reshape(4) for c in range(K)]) if K else np.zeros((0, 4))
206
+ return orientation(rotation(q), x.CS, x.SS, antipodal=x.antipodal)
207
+ data = np.stack([flat[cId == c].mean().data.reshape(3) for c in range(K)]) if K else np.zeros((0, 3))
208
+ return vector3d(data, antipodal=x.antipodal, frame=x.frame)
209
+
210
+
211
+ # the modes of the density the orientations ascend to, the largest numCluster of them
212
+ def _densityCluster(o, halfwidth, weights, numCluster):
213
+ from ..functions.characteristics import calcComponents
214
+ from ..functions.density import calcDensity
215
+ flat = o.flatten()
216
+ odf = calcDensity(flat, weights=weights, halfwidth=halfwidth)
217
+ modes, vol, cId = calcComponents(odf, seed=flat, weights=weights)
218
+ K = min(20 if numCluster is None else int(numCluster), modes.size)
219
+ cId = np.asarray(cId).astype(float)
220
+ cId[cId >= K] = np.nan
221
+ center = modes[:K]
222
+ # the points too far from their centre, beyond twice the mean angle, are dropped
223
+ for i in range(K):
224
+ mask = cId == i
225
+ if not np.any(mask):
226
+ continue
227
+ omega = flat[mask].angle(center[i])
228
+ far = np.flatnonzero(mask)[omega > 2 * np.mean(omega)]
229
+ cId[far] = np.nan
230
+ return cId.reshape(o.shape), center
231
+
232
+
233
+ # the closest pair of centres merged, the mean weighted by the points behind them, until
234
+ # the number of clusters or the angle between the centres is reached; a large list is
235
+ # binned on a grid first
236
+ def _hierarchical(x, numCluster, maxAngle, weights, resolution):
237
+ flat = x.flatten()
238
+ n = flat.size
239
+ w = np.ones(n) if weights is None else np.asarray(weights, dtype=float).ravel()
240
+ isOri = isinstance(x, orientation)
241
+ if n > 1000 and isOri:
242
+ from ..geometry.grids.so3grid import equispacedSO3Grid
243
+ g = equispacedSO3Grid(x.CS, x.SS, resolution=resolution)
244
+ ind, _ = g.find(flat)
245
+ gw = np.bincount(np.asarray(ind).ravel(), weights=w, minlength=g.size)
246
+ keep = gw > 0
247
+ _, center = _hierarchical(g.subGrid(keep), numCluster, maxAngle, gw[keep], resolution)
248
+ cId = _nearest(flat, center)
249
+ center = _centers(x, cId)
250
+ cId = _nearest(flat, center)
251
+ counts = np.bincount(cId, minlength=center.size)
252
+ order = np.argsort(-counts, kind="stable")
253
+ rank = np.empty_like(order)
254
+ rank[order] = np.arange(order.size)
255
+ cId = rank[cId]
256
+ center = center[order][counts[order] > 0]
257
+ return cId.reshape(x.shape), center
258
+ nTarget = 2 if numCluster is None else int(numCluster)
259
+ cosMax = -np.inf if maxAngle is None else np.cos(maxAngle)
260
+ members = [[i] for i in range(n)]
261
+ # the coordinates of the centres, one row each, the merged ones kept but never read again
262
+ C = np.array(flat.data.reshape(n, -1), dtype=float)
263
+ d = _similarity(flat, flat)
264
+ np.fill_diagonal(d, -np.inf)
265
+ alive = np.ones(n, dtype=bool)
266
+ while np.count_nonzero(alive) > nTarget:
267
+ k = int(np.argmax(d))
268
+ i, j = divmod(k, n)
269
+ if d[i, j] < cosMax:
270
+ break
271
+ members[i] += members[j]
272
+ members[j] = []
273
+ alive[j] = False
274
+ sel = np.array(members[i])
275
+ centre = flat[sel].mean(weights=w[sel])
276
+ C[i] = centre.data.reshape(-1)
277
+ dd = _similarity(centre, flat._new(C)).ravel()
278
+ dd[~alive] = -np.inf
279
+ dd[i] = -np.inf
280
+ d[i, :] = dd
281
+ d[:, i] = dd
282
+ d[j, :] = -np.inf
283
+ d[:, j] = -np.inf
284
+ cId = np.empty(n, dtype=int)
285
+ keep = np.flatnonzero(alive)
286
+ for c, i in enumerate(keep):
287
+ cId[members[i]] = c
288
+ center = flat._new(C[keep])
289
+ return cId.reshape(x.shape), center
290
+
291
+
292
+ # the cosine of the angle between every pair, reduced by the symmetry
293
+ def _similarity(a, b):
294
+ A, B = a.reshape(-1, 1), b.reshape(1, -1)
295
+ return np.cos(A.angle(B))
296
+
297
+
298
+ def _nearest(x, center):
299
+ return np.argmin(x.reshape(-1, 1).angle(center.reshape(1, -1)), axis=1)
300
+
301
+
302
+ def _install():
303
+ install((vector3d, orientation), calcCluster)
304
+
305
+
306
+ _install()
307
+
308
+ __all__ = ["calcCluster", "classix", "knnRadius"]
@@ -0,0 +1 @@
1
+ """the data tables of the function layer"""