Analyze the symmetries of the input Atom array using the DEFAULT
parameters.

@param atoms
representative Atom array of the Structure
@return CeSymmResult
@throws StructureException
969763
public static CeSymmResult analyze(Atom[] atoms) throws StructureException {
		CESymmParameters params = new CESymmParameters();
		return analyze(atoms, params);
	}
482253
public double getAtomicSoftnessCore(IAtomContainer ac, int atomPosition) throws CDKException {
        if (factory == null) {
            factory = AtomTypeFactory
                    .getInstance("org/openscience/cdk/config/data/jmol_atomtypes.txt", ac.getBuilder());
        }
        IAtom target = null;
        double core = 0;
        double radiusTarget = 0;
        target = ac.getAtom(atomPosition);
        double partial = 0;
        double radius = 0;
        String symbol = null;
        IAtomType type = null;
        try {
            symbol = ac.getAtom(atomPosition).getSymbol();
            type = factory.getAtomType(symbol);
            if (getCovalentRadius(symbol, ac.getMaximumBondOrder(target)) > 0) {
                radiusTarget = getCovalentRadius(symbol, ac.getMaximumBondOrder(target));
            } else {
                radiusTarget = type.getCovalentRadius();
            }

        } catch (Exception ex1) {
            logger.debug(ex1);
            throw new CDKException("Problems with AtomTypeFactory due to " + ex1.getMessage(), ex1);
        }

        Iterator<IAtom> atoms = ac.atoms().iterator();
        while (atoms.hasNext()) {
            IAtom atom = atoms.next();
            if (!target.equals(atom)) {
                symbol = atom.getSymbol();
                partial = 0;
                try {
                    type = factory.getAtomType(symbol);
                } catch (Exception ex1) {
                    logger.debug(ex1);
                    throw new CDKException("Problems with AtomTypeFactory due to " + ex1.getMessage(), ex1);
                }
                if (getCovalentRadius(symbol, ac.getMaximumBondOrder(atom)) > 0) {
                    radius = getCovalentRadius(symbol, ac.getMaximumBondOrder(atom));
                } else {
                    radius = type.getCovalentRadius();
                }
                partial += radius * radius;
                partial += (radiusTarget * radiusTarget);
                partial = partial / (calculateSquaredDistanceBetweenTwoAtoms(target, atom));
                core += partial;
            }
        }
        core = 2 * core;
        core = 0.172 * core;
        return core;
    }
1142090
@Override
    public DescriptorValue calculate(IAtomContainer atomContainer) {
        IAtomContainer container;
        try {
            container = (IAtomContainer) atomContainer.clone();
            container = AtomContainerManipulator.removeHydrogens(container);
        } catch (CloneNotSupportedException e) {
            DoubleArrayResult result = new DoubleArrayResult(5);
            for (int i = 0; i < 5; i++)
                result.add(Double.NaN);
            return new DescriptorValue(getSpecification(), getParameterNames(), getParameters(), result,
                    getDescriptorNames(), new CDKException("Error during cloner: " + e.getMessage(), e));
        }

        try {
            double[] w = listConvertion(container);
            int natom = container.getAtomCount();
            int[][] distancematrix = TopologicalMatrix.getMatrix(container);
            double[] masSum = new double[5];

            for (int k = 0; k < 5; k++) {
                for (int i = 0; i < natom; i++) {
                    for (int j = 0; j < natom; j++) {

                        if (distancematrix[i][j] == k) {
                            masSum[k] += w[i] * w[j];
                        } else
                            masSum[k] += 0.0;
                    }
                }
                if (k > 0) masSum[k] = masSum[k] / 2;

            }
            DoubleArrayResult result = new DoubleArrayResult(5);
            for (double aMasSum : masSum) {
                result.add(aMasSum);
            }

            return new DescriptorValue(getSpecification(), getParameterNames(), getParameters(), result,
                    getDescriptorNames());

        } catch (IOException | ClassNotFoundException ex) {
            DoubleArrayResult result = new DoubleArrayResult(5);
            for (int i = 0; i < 5; i++)
                result.add(Double.NaN);
            return new DescriptorValue(getSpecification(), getParameterNames(), getParameters(), result,
                    getDescriptorNames(), new CDKException("Error while calculating the ATS_mass descriptor: "
                            + ex.getMessage(), ex));
        }
    }
55997
public List<StructureIdentifier> getRepeatsID() throws StructureException {

		if (!isRefined())
			return null;

		List<StructureIdentifier> repeats = new ArrayList<StructureIdentifier>(
				numRepeats);

		String pdbId = structureId.toCanonical().getPdbId();
		Block align = multipleAlignment.getBlocks().get(0);

		for (int su = 0; su < numRepeats; su++) {
			// Get the start and end residues of the repeat
			ResidueNumber res1 = atoms[align.getStartResidue(su)].getGroup()
					.getResidueNumber();
			ResidueNumber res2 = atoms[align.getFinalResidue(su)].getGroup()
					.getResidueNumber();
			ResidueRange range = new ResidueRange(res1.getChainName(), res1, res2);

			StructureIdentifier id = new SubstructureIdentifier(pdbId,
					Arrays.asList(range));

			repeats.add(id);
		}
		return repeats;
	}
200831
public static final void shift(Structure structure, Atom a ){

		AtomIterator iter = new AtomIterator(structure) ;
		while (iter.hasNext() ) {
			Atom atom = null ;

			atom = iter.next()  ;

			Atom natom = add(atom,a);
			double x = natom.getX();
			double y = natom.getY() ;
			double z = natom.getZ();
			atom.setX(x);
			atom.setY(y);
			atom.setZ(z);

		}
	}
571068
public static final void transform (Atom atom, Matrix4d m) {

		Point3d p = new Point3d(atom.getX(),atom.getY(),atom.getZ());
		m.transform(p);

		atom.setX(p.x);
		atom.setY(p.y);
		atom.setZ(p.z);
	}
572969
public static void calculateScores(MultipleAlignment alignment)
			throws StructureException {

		// Put RMSD
		List<Atom[]> trans = MultipleAlignmentTools.transformAtoms(alignment);
		alignment.putScore(RMSD, getRMSD(trans));

		// Put AvgTM-Score
		List<Integer> lengths = new ArrayList<Integer>(alignment.size());
		for (Atom[] atoms : alignment.getAtomArrays()) {
			lengths.add(atoms.length);
		}
		alignment.putScore(AVGTM_SCORE, getAvgTMScore(trans, lengths));
	}
162160
public static List<AtomSite> convertStructureToAtomSites(Structure s) {
		List<AtomSite> list = new ArrayList<AtomSite>();

		for (int m=0;m<s.nrModels();m++) {
			for (Chain c:s.getChains(m)) {
				list.addAll(convertChainToAtomSites(c, m+1, c.getName(), c.getId()));
			}
		}
		return list;
	}
221598
public static final void plus(Structure s, Matrix matrix){
		AtomIterator iter = new AtomIterator(s) ;
		Atom oldAtom = null;
		Atom rotOldAtom = null;
		while (iter.hasNext()) {
			Atom atom = null ;

			atom = iter.next() ;
			try {
				if ( oldAtom != null){
					logger.debug("before {}", getDistance(oldAtom,atom));
				}
			} catch (Exception e){
				logger.error("Exception: ", e);
			}
			oldAtom = (Atom)atom.clone();

			double x = atom.getX();
			double y = atom.getY() ;
			double z = atom.getZ();
			double[][] ad = new double[][]{{x,y,z}};

			Matrix am = new Matrix(ad);
			Matrix na = am.plus(matrix);

			double[] coords = new double[3] ;
			coords[0] = na.get(0,0);
			coords[1] = na.get(0,1);
			coords[2] = na.get(0,2);
			atom.setCoords(coords);
			try {
				if ( rotOldAtom != null){
					logger.debug("after {}", getDistance(rotOldAtom,atom));
				}
			} catch (Exception e){
				logger.error("Exception: ", e);
			}
			rotOldAtom  = (Atom) atom.clone();
		}

	}
1000314
public static final double getPsi(AminoAcid a, AminoAcid b)
			throws StructureException {
		if ( ! isConnected(a,b)) {
			throw new StructureException(
					"can not calc Psi - AminoAcids are not connected!");
		}

		Atom a_N   = a.getN();
		Atom a_CA  = a.getCA();
		Atom a_C   = a.getC();
		Atom b_N   = b.getN();

		// C and N were checked in isConnected already
		if (a_CA == null)
			throw new StructureException(
					"Can not calculate Psi, CA atom is missing");

		return torsionAngle(a_N,a_CA,a_C,b_N);

	}
246501
public static void convertImplicitToExplicitHydrogens(IAtomContainer atomContainer) {
        List<IAtom> hydrogens = new ArrayList<IAtom>();
        List<IBond> newBonds = new ArrayList<IBond>();

        // store a single explicit hydrogen of each original neighbor
        Map<IAtom, IAtom> hNeighbor = Maps.newHashMapWithExpectedSize(atomContainer.getAtomCount());

        for (IAtom atom : atomContainer.atoms()) {
            if (!atom.getSymbol().equals("H")) {
                Integer hCount = atom.getImplicitHydrogenCount();
                if (hCount != null) {
                    for (int i = 0; i < hCount; i++) {

                        IAtom hydrogen = atom.getBuilder().newInstance(IAtom.class, "H");
                        hydrogen.setAtomTypeName("H");
                        hydrogen.setImplicitHydrogenCount(0);
                        hydrogens.add(hydrogen);
                        newBonds.add(atom.getBuilder().newInstance(IBond.class, atom, hydrogen,
                                Order.SINGLE));

                        if (hNeighbor.get(atom) == null) hNeighbor.put(atom, hydrogen);

                    }
                    atom.setImplicitHydrogenCount(0);
                }
            }
        }
        for (IAtom atom : hydrogens)
            atomContainer.addAtom(atom);
        for (IBond bond : newBonds)
            atomContainer.addBond(bond);

        // update stereo elements with an implicit part
        List<IStereoElement> stereos = new ArrayList<>();
        for (IStereoElement stereo : atomContainer.stereoElements()) {
            if (stereo instanceof ITetrahedralChirality) {
                ITetrahedralChirality tc = (ITetrahedralChirality) stereo;

                IAtom   focus    = tc.getFocus();
                IAtom[] carriers = tc.getCarriers().toArray(new IAtom[4]);
                IAtom   hydrogen = hNeighbor.get(focus);

                // in sulfoxide - the implicit part of the tetrahedral centre
                // is a lone pair

                if (hydrogen != null) {
                    replaceAtom(carriers, focus, hydrogen);
                    stereos.add(new TetrahedralChirality(focus, carriers, tc.getStereo()));
                } else {
                    stereos.add(stereo);
                }
            } else if (stereo instanceof ExtendedTetrahedral) {
                ExtendedTetrahedral tc = (ExtendedTetrahedral) stereo;

                IAtom   focus    = tc.getFocus();
                IAtom[] carriers = tc.getCarriers().toArray(new IAtom[4]);
                IAtom[] ends     = ExtendedTetrahedral.findTerminalAtoms(atomContainer, focus);
                IAtom   h1       = hNeighbor.get(ends[0]);
                IAtom   h2       = hNeighbor.get(ends[1]);
                if (h1 != null || h2 != null) {
                    if (h1 != null)
                        replaceAtom(carriers, ends[0], h1);
                    if (h2 != null)
                        replaceAtom(carriers, ends[1], h2);
                    stereos.add(new ExtendedTetrahedral(focus, carriers, tc.getConfigOrder()));
                } else {
                    stereos.add(stereo);
                }
            } else {
                stereos.add(stereo);
            }
        }
        atomContainer.setStereoElements(stereos);

    }
527297
@Override
    public List<IAtom> getConnectedAtomsList(IAtom atom) {
        List<IAtom> atomsList = new ArrayList<IAtom>();
        for (int i = 0; i < bondCount; i++) {
            if (bonds[i].contains(atom)) atomsList.add(bonds[i].getOther(atom));
        }
        return atomsList;
    }
225679
@Override
    public DescriptorValue calculate(IAtom atom, IAtomContainer container) {
        try {
            matched = CDKAtomTypeMatcher.getInstance(atom.getBuilder()).findMatchingAtomType(container, atom);
        } catch (CDKException e) {
            return getDummyDescriptorValue(e);
        }
        if (matched == null) {
            int atnum = container.indexOf(atom);
            return getDummyDescriptorValue(new CDKException("The matched atom type was null (atom number " + atnum
                    + ") " + atom.getSymbol()));
        }
        Hybridization atomHybridization = matched.getHybridization();
        IntegerResult result = new IntegerResult(atomHybridization == null ? 0 : atomHybridization.ordinal());
        return new DescriptorValue(getSpecification(), getParameterNames(), getParameters(), result,
                getDescriptorNames());
    }
532305
public List<Orbit> calculateOrbits() {
        List<Orbit> orbits = new ArrayList<Orbit>();
        List<SymmetryClass> symmetryClasses = super.getSymmetryClasses();
        for (SymmetryClass symmetryClass : symmetryClasses) {
            Orbit orbit = new Orbit(symmetryClass.getSignatureString(), -1);
            for (int atomIndex : symmetryClass) {
                orbit.addAtom(atomIndex);
            }
            orbits.add(orbit);
        }
        return orbits;
    }
1187416
public static List<Structure> divideStructure(CeSymmResult symmetry)
			throws StructureException {

		if (!symmetry.isRefined())
			throw new IllegalArgumentException("The symmetry result "
					+ "is not refined, repeats cannot be defined");

		int order = symmetry.getMultipleAlignment().size();
		Atom[] atoms = symmetry.getAtoms();
		Set<Group> allGroups = StructureTools.getAllGroupsFromSubset(atoms, GroupType.HETATM);
		List<StructureIdentifier> repeatsId = symmetry.getRepeatsID();
		List<Structure> repeats = new ArrayList<Structure>(order);

		// Create new structure containing the repeat atoms
		for (int i = 0; i < order; i++) {

			Structure s = new StructureImpl();
			s.addModel(new ArrayList<Chain>(1));
			s.setStructureIdentifier(repeatsId.get(i));

			Block align = symmetry.getMultipleAlignment().getBlock(0);

			// Get the start and end of the repeat
			// Repeats are always sequential blocks
			int res1 = align.getStartResidue(i);
			int res2 = align.getFinalResidue(i);

			// All atoms from the repeat, used for ligand search
			// AA have an average of 8.45 atoms, so guess capacity with that
			List<Atom> repeat = new ArrayList<>(Math.max(9*(res2-res1+1),9));
			// speedy chain lookup
			Chain prevChain = null;
			for(int k=res1;k<=res2; k++) {
				Group g = atoms[k].getGroup();
				prevChain = StructureTools.addGroupToStructure(s, g, 0, prevChain,true);
				repeat.addAll(g.getAtoms());
			}


			List<Group> ligands = StructureTools.getLigandsByProximity(
					allGroups,
					repeat.toArray(new Atom[repeat.size()]),
					StructureTools.DEFAULT_LIGAND_PROXIMITY_CUTOFF);

			logger.warn("Adding {} ligands to {}",ligands.size(), symmetry.getMultipleAlignment().getStructureIdentifier(i));
			for( Group ligand : ligands) {
				prevChain = StructureTools.addGroupToStructure(s, ligand, 0, prevChain,true);
			}

			repeats.add(s);
		}
		return repeats;
	}
38837
public static StructureAlignmentJmol display(AFPChain afpChain, Atom[] ca1, Atom[] ca2) throws StructureException {

		if ( ca1.length < 1 || ca2.length < 1){
			throw new StructureException("length of atoms arrays is too short! " + ca1.length + "," + ca2.length);
		}

		Group[] twistedGroups = AlignmentTools.prepareGroupsForDisplay(afpChain, ca1, ca2);

		List<Group> hetatms  = StructureTools.getUnalignedGroups(ca1);
		List<Group> hetatms2 = StructureTools.getUnalignedGroups(ca2);

		return DisplayAFP.display(afpChain, twistedGroups, ca1, ca2, hetatms, hetatms2);

	}
1171918
public static Atom[] getRepresentativeAtoms(Structure structure) {

		if (structure.isNmr())
			return StructureTools.getRepresentativeAtomArray(structure);

		else {

			// Get Atoms of all models
			List<Atom> atomList = new ArrayList<Atom>();
			for (int m = 0; m < structure.nrModels(); m++) {
				for (Chain c : structure.getModel(m))
					atomList.addAll(Arrays.asList(StructureTools
							.getRepresentativeAtomArray(c)));
			}
			return atomList.toArray(new Atom[0]);
		}

	}