/* * Copyright 2016 Diamond Light Source Ltd. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ package uk.ac.diamond.scisoft.xpdf.views; import java.util.ArrayList; import java.util.List; /** * A class providing the seven crystal systems * <p> * This class provides information on the 7 crystal systems, plus an eighth * pseudo-system to cover the rhombohedral basis of trigonal space groups. * @author Timothy Spain, timothy.spain@diamond.ac.uk * */ class CrystalSystem { private int number; private static CrystalSystem[] systems; static final int nSystems = 8; // 7 crystal systems, plus rhombohedral space groups with a rhombohedral basis /** * Gets the crystal system with a given number. * <p> * A static function that retuns one of the 8 singleton objects * representing the crystal systems. Follows the usual IUCr ordering * (tricilinic, monoclinic, tetragonal, trigonal (hexagonal basis), * hexagonal, cubic), followed by the pseudo-system for trigonal space * groups on a rhombohedral basis. * @param systemOrdinal * ordinal of the system to get (zero-based) * @return the object representing that crystal system. */ public static CrystalSystem get(int systemOrdinal) { if (systems == null || systems.length < nSystems) { generateSystems(); } return systems[systemOrdinal]; } /** * Gets the name of the crystal system. * <p> * The names of the systems are "Triclinic", "Monoclinic", "Orthorhombic", * "Tetragonal", "Trigonal ⬡", "Hexagonal", "Cubic", "Trigonal ⋄". The * symbols after the trigonal names are intended to show the basis on * which the unit cell is defined. * @return the usual name of the crystal system, with a suffix to denote * the basis of trigonal space groups. */ public String getName() { return (number >= 0 && number < nSystems) ? names[number] : "Unknown"; } /** * Gets the ordinal number associated with the crystal system. * @return ordinal assigned to the crystal system. */ public int getOrdinal() { return number; } /** * Gets the names of all the crystal systems. * @return */ public static String[] getNames() { return names; } /** * Returns a List of all the space groups with this crystal system. * @return a List of all the objects representing the space groups with * this crystal system. */ public List<XPDFSpaceGroup> getGroups() { List<XPDFSpaceGroup> groupList = new ArrayList<XPDFSpaceGroup>(); for (int group = lowestGroups[number]; group <= highestGroups[number]; group++) groupList.add(XPDFSpaceGroup.get(group)); return groupList; } /** * Returns the indices of the axis that defines the length of this side of the unit cell. * <p> * For unit cells of the tetragonal, trigonal, hexagonal and cubic systems, * some edges of the unit cell are defined to be equal to others. The * return value of this method allows this to be determined. The triclinic * system returns {0,1,2}, as each axis defines itself. The cubic system * returns {0,0,0} as all three axes are defined by the first. The trigonal * system and pseudo-system return the correct values for their bases. * @return indices of the lements used to define each unit cell axis. */ public int[] getAxisIndices() { switch (nFreeAxes[number]) { case 3: return new int[]{0,1,2}; case 2: return new int[]{0,0,2}; case 1: return new int[]{0,0,0}; default: return new int[]{-1,-1,-1}; } } /** * Gets the angles between the planes of the unit cell. * <p> * For crystal systems with fixed angles (all but triclinic and trigonal * with a rhombohedral basis), the entry in the array gives the angle in * degrees. For free angles, the value is negative, and the absolute value * gives 1 more than the dimension which defines this angle. * @return The angle of the vertex of the unit cell, or a negative number * defining the index which defines the angle. */ public int[] getFixedAngles() { return fixedAngles[number]; } private static void generateSystems() { systems = new CrystalSystem[nSystems]; // 7 crystal systems plus rhombohedral bases for (int iSystem = 0; iSystem < nSystems ; iSystem++) { CrystalSystem system = new CrystalSystem(); system.number = iSystem; systems[iSystem] = system; } } public final static int[] lowestGroups = {1, 3, 16, 75, 143, 168, 195, 231}; public final static int[] highestGroups = {2, 15, 74, 142, 167, 194, 230, 237}; private final static String[] names = {"Triclinic", "Monoclinic", "Orthorhombic", "Tetragonal", "Trigonal ⬡", "Hexagonal", "Cubic", "Trigonal ⋄"}; private final static int[] nFreeAxes = {3, 3, 3, 2, 2, 2, 1, 1}; private final static int[][] fixedAngles = { new int[] {-1, -2, -3}, new int[] {90, -2, 90}, new int[] {90, 90, 90}, new int[] {90, 90, 90}, new int[] {90, 90, 120}, new int[] {90, 90, 120}, new int[] {90, 90, 90}, new int[] {-1, -1, -1}}; }