Calculate the rotation angle for a structure
@param afpChain
@return The rotation angle, in radians
@throws StructureException If the alignment doesn't contain any blocks
@throws NullPointerException If the alignment doesn't have a rotation matrix set
778938
public static double getAngle(AFPChain afpChain) throws StructureException {
		if(afpChain.getBlockNum() < 1) {
			throw new StructureException("No aligned residues");
		}
		Matrix rotation = afpChain.getBlockRotationMatrix()[0];

		if(rotation == null) {
			throw new NullPointerException("AFPChain does not contain a rotation matrix");
		}
		return getAngle(rotation);
	}
169906
private static void transformOrigPDB(int n, int[] res1, int[] res2,
			Atom[] ca1, Atom[] ca2, AFPChain afpChain, int blockNr)
			throws StructureException {
		logger.debug(
				"transforming original coordinates {} len1: {} res1: {} len2: {} res2: {}",
				n, ca1.length, res1.length, ca2.length, res2.length);

		Atom[] cod1 = getAtoms(ca1, res1, n, false);
		Atom[] cod2 = getAtoms(ca2, res2, n, false);

		// double *cod1 = pro1->Cod4Res(n, res1);
		// double *cod2 = pro2->Cod4Res(n, res2);

		Matrix4d transform = SuperPositions.superpose(Calc.atomsToPoints(cod1),
				Calc.atomsToPoints(cod2));

		Matrix r = Matrices.getRotationJAMA(transform);
		Atom t = Calc.getTranslationVector(transform);

		logger.debug("transPdb: transforming orig coordinates with matrix: {}",
				r);

		if (afpChain != null) {
			Matrix[] ms = afpChain.getBlockRotationMatrix();
			if (ms == null)
				ms = new Matrix[afpChain.getBlockNum()];

			ms[blockNr] = r;

			Atom[] shifts = afpChain.getBlockShiftVector();
			if (shifts == null)
				shifts = new Atom[afpChain.getBlockNum()];
			shifts[blockNr] = t;

			afpChain.setBlockRotationMatrix(ms);
			afpChain.setBlockShiftVector(shifts);
		}

		for (Atom a : ca2)
			Calc.transform(a.getGroup(), transform);

	}
7187
public static Alignable align_NPE(Matrix sim,StrucAligParameters params){
		//System.out.println("align_NPE");

		float gapOpen = params.getGapOpen();
		float gapExtension = params.getGapExtension();

		int rows = sim.getRowDimension();
		int cols = sim.getColumnDimension();

		Alignable al = new StrCompAlignment(rows,cols);
		al.setGapExtCol(gapExtension);
		al.setGapExtRow(gapExtension);
		al.setGapOpenCol(gapOpen);
		al.setGapOpenRow(gapOpen);
		//System.out.println("size of aligmat: " + rows+1 + " " + cols+1);
		//AligMatEl[][] aligmat = new AligMatEl[rows+1][cols+1];
		AligMatEl[][] aligmat = al.getAligMat();

		for (int i = 0; i < rows; i++) {
			for (int j = 0; j < cols; j++) {

				int e=0;
				//if ( ( i < rows) &&
				//        ( j < cols)) {
					//TODO: the ALIGFACTOR calc should be hidden in Gotoh!!

				e = (int)Math.round(Gotoh.ALIGFACTOR * sim.get(i,j));
				//}
				//System.out.println(e);
				AligMatEl am = new AligMatEl();
				am.setValue(e);
				//am.setTrack(new IndexPair((short)-99,(short)-99));
				aligmat[i+1][j+1] = am;

			}
		}
		//al.setAligMat(aligmat);

		 new Gotoh(al);

		return al;
	}
702028
public void align(Atom[] ca1, Atom[] ca2, StrucAligParameters params)
			throws StructureException {

		reset();
		this.params = params;

		long timeStart = System.currentTimeMillis();

		// step 1 get all Diagonals of length X that are similar between both
		// structures
		logger.debug(" length atoms1:" + ca1.length);
		logger.debug(" length atoms2:" + ca2.length);

		logger.debug("step 1 - get fragments with similar intramolecular distances ");

		int k = params.getDiagonalDistance();
		int k2 = params.getDiagonalDistance2();
		int fragmentLength = params.getFragmentLength();

		if (ca1.length < (fragmentLength + 1)) {
			throw new StructureException("structure 1 too short (" + ca1.length
					+ "), can not align");
		}
		if (ca2.length < (fragmentLength + 1)) {
			throw new StructureException("structure 2 too short (" + ca2.length
					+ "), can not align");
		}
		int rows = ca1.length - fragmentLength + 1;
		int cols = ca2.length - fragmentLength + 1;
		distanceMatrix = new Matrix(rows, cols, 0.0);

		double[] dist1 = AlignUtils.getDiagonalAtK(ca1, k);

		double[] dist2 = AlignUtils.getDiagonalAtK(ca2, k);
		double[] dist3 = new double[0];
		double[] dist4 = new double[0];
		if (k2 > 0) {
			dist3 = AlignUtils.getDiagonalAtK(ca1, k2);
			dist4 = AlignUtils.getDiagonalAtK(ca2, k2);
		}

		double[][] utmp = new double[][] { { 0, 0, 1 } };
		Atom unitvector = new AtomImpl();
		unitvector.setCoords(utmp[0]);

		List<FragmentPair> fragments = new ArrayList<FragmentPair>();

		for (int i = 0; i < rows; i++) {

			Atom[] catmp1 = AlignUtils.getFragment(ca1, i, fragmentLength);
			Atom center1 = AlignUtils.getCenter(ca1, i, fragmentLength);

			for (int j = 0; j < cols; j++) {

				double rdd1 = AlignUtils.rms_dk_diag(dist1, dist2, i, j,
						fragmentLength, k);
				double rdd2 = 0;
				if (k2 > 0)
					rdd2 = AlignUtils.rms_dk_diag(dist3, dist4, i, j,
							fragmentLength, k2);
				double rdd = rdd1 + rdd2;
				distanceMatrix.set(i, j, rdd);

				if (rdd < params.getFragmentMiniDistance()) {
					FragmentPair f = new FragmentPair(fragmentLength, i, j);
					Atom[] catmp2 = AlignUtils.getFragment(ca2, j,
							fragmentLength);
					Atom center2 = AlignUtils.getCenter(ca2, j,
							fragmentLength);

					f.setCenter1(center1);
					f.setCenter2(center2);

					Matrix4d t = SuperPositions.superpose(
							Calc.atomsToPoints(catmp1),
							Calc.atomsToPoints(catmp2));

					Matrix rotmat = Matrices.getRotationJAMA(t);
					f.setRot(rotmat);

					Atom aunitv = (Atom) unitvector.clone();
					Calc.rotate(aunitv, rotmat);
					f.setUnitv(aunitv);

					boolean doNotAdd = false;
					if (params.reduceInitialFragments()) {
						doNotAdd = FragmentJoiner.reduceFragments(
								fragments, f, distanceMatrix);

					}
					if (doNotAdd)
						continue;

					fragments.add(f);
				}
			}
		}

		notifyFragmentListeners(fragments);

		FragmentPair[] fp = fragments
				.toArray(new FragmentPair[fragments.size()]);
		setFragmentPairs(fp);

		logger.debug(" got # fragment pairs: {}", fp.length);

		logger.debug("step 2 - join fragments");

		// step 2 combine them to possible models
		FragmentJoiner joiner = new FragmentJoiner();

		JointFragments[] frags;

		if (params.isJoinFast()) {
			// apply the quick alignment procedure.
			// less quality in alignments, better for DB searches...
			frags = joiner.approach_ap3(ca1, ca2, fp, params);

			joiner.extendFragments(ca1, ca2, frags, params);

		} else if (params.isJoinPlo()) {
			// this approach by StrComPy (peter lackner):
			frags = joiner.frag_pairwise_compat(fp, params.getAngleDiff(),
					params.getFragCompat(), params.getMaxrefine());

		} else {

			// my first implementation
			frags = joiner.approach_ap3(ca1, ca2, fp, params);
		}

		notifyJointFragments(frags);

		logger.debug(" number joint fragments: ", frags.length);

		logger.debug("step 3 - refine alignments");

		List<AlternativeAlignment> aas = new ArrayList<AlternativeAlignment>();
		for (int i = 0; i < frags.length; i++) {
			JointFragments f = frags[i];
			AlternativeAlignment a = new AlternativeAlignment();
			a.apairs_from_idxlst(f);
			a.setAltAligNumber(i + 1);
			a.setDistanceMatrix(distanceMatrix);

			try {
				if (params.getMaxIter() > 0) {

					a.refine(params, ca1, ca2);
				} else {

					a.finish(params, ca1, ca2);

				}
			} catch (StructureException e) {
				logger.error("Refinement of fragment {} failed", i, e);
			}
			a.calcScores(ca1, ca2);
			aas.add(a);
		}

		// sort the alternative alignments
		Comparator<AlternativeAlignment> comp = new AltAligComparator();
		Collections.sort(aas, comp);
		Collections.reverse(aas);

		alts = aas.toArray(new AlternativeAlignment[aas.size()]);
		// do final numbering of alternative solutions
		int aanbr = 0;
		for (AlternativeAlignment a : alts) {
			aanbr++;
			a.setAltAligNumber(aanbr);
		}

		logger.debug("total calculation time: {} ms.",
				(System.currentTimeMillis() - timeStart));
	}
190237
public static void blockInfo(AFPChain afpChain)
	{
		int     i, j, k, a, n;

		int blockNum = afpChain.getBlockNum();

		int[] blockSize =afpChain.getBlockSize();
		int[] afpChainList = afpChain.getAfpChainList();
		int[] block2Afp = afpChain.getBlock2Afp();
		int[][][]blockResList = afpChain.getBlockResList();

		List<AFP>afpSet = afpChain.getAfpSet();
		int[] blockResSize = afpChain.getBlockResSize();

		for(i = 0; i < blockNum; i ++)  {
			n = 0;
			for(j = 0; j < blockSize[i]; j ++)      {
				//the index in afpChainList, not in the whole afp set
				a = afpChainList[block2Afp[i] + j];
				for(k = 0; k < afpSet.get(a).getFragLen(); k ++)     {
					blockResList[i][0][n] = afpSet.get(a).getP1() + k;
					blockResList[i][1][n] = afpSet.get(a).getP2() + k;
					n ++;
				}
			}
			blockResSize[i] = n;
		}

		afpChain.setBlockResSize(blockResSize);
		afpChain.setBlockSize(blockSize);
		afpChain.setAfpChainList(afpChainList);
		afpChain.setBlock2Afp(block2Afp);
		afpChain.setBlockResList(blockResList);
	}
659627
private AffineTransform getRotationTransform ()
    {
        double theta;

        switch (_orient) {
            case NORTH:
            default:
                theta = 0.0;
                break;

            case SOUTH:
                theta = Math.PI;
                break;

            case EAST:
                theta = Math.PI*0.5;
                break;

            case WEST:
                theta = -Math.PI*0.5;
                break;

            case NORTHEAST:
                theta = Math.PI*0.25;
                break;

            case NORTHWEST:
                theta = -Math.PI*0.25;
                break;

            case SOUTHEAST:
                theta = Math.PI*0.75;
                break;

            case SOUTHWEST:
                theta = -Math.PI*0.75;
                break;

            case NORTHNORTHEAST:
                theta = -Math.PI*0.125;
                break;

            case NORTHNORTHWEST:
                theta = Math.PI*0.125;
                break;

            case SOUTHSOUTHEAST:
                theta = -Math.PI*0.875;
                break;

            case SOUTHSOUTHWEST:
                theta = Math.PI*0.875;
                break;

            case EASTNORTHEAST:
                theta = -Math.PI*0.375;
                break;

            case EASTSOUTHEAST:
                theta = -Math.PI*0.625;
                break;

            case WESTNORTHWEST:
                theta = Math.PI*0.375;
                break;

            case WESTSOUTHWEST:
                theta = Math.PI*0.625;
                break;
        }

        return AffineTransform.getRotateInstance(
            theta,
            (_ox - _oxoff) + _frames.getWidth(_frameIdx)/2,
            (_oy - _oyoff) + _frames.getHeight(_frameIdx)/2
        );
    }
652902
@Override
	public String getDefaultOrientation() {
		StringBuilder s = new StringBuilder();
		s.append(setCentroid());

		// calculate  orientation
		Quat4d q = new Quat4d();
		q.set(polyhedron.getViewMatrix(0));
		q.normalize();
		Quat4d r = new Quat4d();
		r.set(rotationAxisAligner.getRotationMatrix());
		r.normalize();
		q.mul(r);
		q.normalize();

		// set orientation
		s.append("moveto 0 quaternion{");
		s.append(jMolFloat(q.x));
		s.append(",");
		s.append(jMolFloat(q.y));
		s.append(",");
		s.append(jMolFloat(q.z));
		s.append(",");
		s.append(jMolFloat(q.w));
		s.append("};");
		return s.toString();
	}
392982
private static double[] angleToCbCr(double angle) {
        double cb = Math.cos(angle);
        double cr = Math.sin(angle);

        double acb = Math.abs(cb);
        double acr = Math.abs(cr);
        double factor;
        if (acr > acb) {
            factor = 0.5 / acr;
        } else {
            factor = 0.5 / acb;
        }

        cb *= factor;
        cr *= factor;

        return new double[] {cb, cr};
    }
589149
def get_node_angle(self, node):
        
        return atan2(self.pos[0]-node.pos[0], self.pos[1]-node.pos[1]) - pi / 2
1142648
public void transform(AffineTransform af) {
        double arr[] = new double[6];
        af.getMatrix(arr);
        content.append(arr[0]).append(' ').append(arr[1]).append(' ').append(arr[2]).append(' ');
        content.append(arr[3]).append(' ').append(arr[4]).append(' ').append(arr[5]).append(" cm").append_i(separator);
    }
599040
public AFPChain invertAlignment(AFPChain a) {
		String name1 = a.getName1();
		String name2 = a.getName2();
		a.setName1(name2);
		a.setName2(name1);

		int len1 = a.getCa1Length();
		a.setCa1Length( a.getCa2Length() );
		a.setCa2Length( len1 );

		int beg1 = a.getAlnbeg1();
		a.setAlnbeg1(a.getAlnbeg2());
		a.setAlnbeg2(beg1);

		char[] alnseq1 = a.getAlnseq1();
		a.setAlnseq1(a.getAlnseq2());
		a.setAlnseq2(alnseq1);

		Matrix distab1 = a.getDisTable1();
		a.setDisTable1(a.getDisTable2());
		a.setDisTable2(distab1);

		int[] focusRes1 = a.getFocusRes1();
		a.setFocusRes1(a.getFocusRes2());
		a.setFocusRes2(focusRes1);

		//What are aftIndex and befIndex used for? How are they indexed?
		//a.getAfpAftIndex()


		String[][][] pdbAln = a.getPdbAln();
		if( pdbAln != null) {
			for(int block = 0; block < a.getBlockNum(); block++) {
				String[] paln1 = pdbAln[block][0];
				pdbAln[block][0] = pdbAln[block][1];
				pdbAln[block][1] = paln1;
			}
		}

		int[][][] optAln = a.getOptAln();
		if( optAln != null ) {
			for(int block = 0; block < a.getBlockNum(); block++) {
				int[] aln1 = optAln[block][0];
				optAln[block][0] = optAln[block][1];
				optAln[block][1] = aln1;
			}
		}
		a.setOptAln(optAln); // triggers invalidate()

		Matrix distmat = a.getDistanceMatrix();
		if(distmat != null)
			a.setDistanceMatrix(distmat.transpose());


		// invert the rotation matrices
		Matrix[] blockRotMat = a.getBlockRotationMatrix();
		Atom[] shiftVec = a.getBlockShiftVector();
		if( blockRotMat != null) {
			for(int block = 0; block < a.getBlockNum(); block++) {
				if(blockRotMat[block] != null) {
					// if y=x*A+b, then x=y*inv(A)-b*inv(A)
					blockRotMat[block] = blockRotMat[block].inverse();

					Calc.rotate(shiftVec[block],blockRotMat[block]);
					shiftVec[block] = Calc.invert(shiftVec[block]);
				}
			}
		}

		return a;
	}
1009686
@SuppressWarnings("unused")
	private static void displayAlignment(AFPChain afpChain, Atom[] ca1, Atom[] ca2) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, StructureException {
		Atom[] ca1clone = StructureTools.cloneAtomArray(ca1);
		Atom[] ca2clone = StructureTools.cloneAtomArray(ca2);
		if (! GuiWrapper.isGuiModuleInstalled()) {
			System.err.println("The biojava-structure-gui and/or JmolApplet modules are not installed. Please install!");
			// display alignment in console
			System.out.println(afpChain.toCE(ca1clone, ca2clone));
		} else {
			Object jmol = GuiWrapper.display(afpChain,ca1clone,ca2clone);
			GuiWrapper.showAlignmentImage(afpChain, ca1clone,ca2clone,jmol);
		}
	}
501499
public static void showStructure(Structure structure)
			throws ClassNotFoundException, NoSuchMethodException,
			InvocationTargetException, IllegalAccessException, InstantiationException{

		Class<?> structureAlignmentJmol = Class.forName(strucAligJmol);

		Object strucAligJ = structureAlignmentJmol.newInstance();

		Method setS = structureAlignmentJmol.getMethod("setStructure", new Class[] {Structure.class});

		setS.invoke(strucAligJ,structure);
	}
825051
public void align(Structure s1, Structure s2, StrucAligParameters params)
			throws StructureException {
		// step 1 convert the structures to Atom Arrays

		Atom[] ca1 = getAlignmentAtoms(s1);
		Atom[] ca2 = getAlignmentAtoms(s2);

		notifyStartingAlignment(s1.getName(), ca1, s2.getName(), ca2);
		align(ca1, ca2, params);
	}
1088852
private static int getAlignment() {
        RuntimeMXBean runtimeMxBean = ManagementFactory.getRuntimeMXBean();
        for (String arg : runtimeMxBean.getInputArguments()) {
            if (arg.startsWith("-XX:ObjectAlignmentInBytes=")) {
                try {
                    return Integer.parseInt(arg.substring("-XX:ObjectAlignmentInBytes=".length()));
                } catch (Exception e){}
            }
        }
        return 8;
    }
170650
public float angle() {
        float angle = (float) (2.0 * Math.acos(w));
        return (float) (angle <= Math.PI ? angle : Math.PI + Math.PI - angle);
    }
277200
public static final void rotate(Group group, double[][] rotationmatrix)
			throws StructureException {

		if ( rotationmatrix.length != 3 ) {
			throw new StructureException ("matrix does not have size 3x3 !");
		}
		AtomIterator iter = new AtomIterator(group) ;
		while (iter.hasNext()) {
			Atom atom = null ;

			atom = iter.next() ;
			rotate(atom,rotationmatrix);

		}
	}