Aligns the structures, duplicating ca2 regardless of
{@link CECPParameters.getDuplicationHint() param.getDuplicationHint}.
@param ca1
@param ca2
@param cpparams
@return
@throws StructureException
190
private AFPChain alignRight(Atom[] ca1, Atom[] ca2, CECPParameters cpparams)
			throws StructureException {
		long startTime = System.currentTimeMillis();

		Atom[] ca2m = StructureTools.duplicateCA2(ca2);

		if(debug) {
			System.out.format("Duplicating ca2 took %s ms\n",System.currentTimeMillis()-startTime);
			startTime = System.currentTimeMillis();
		}

		// Do alignment
		AFPChain afpChain = super.align(ca1, ca2m,params);

		// since the process of creating ca2m strips the name info away, set it explicitely
		try {
			afpChain.setName2(ca2[0].getGroup().getChain().getStructure().getName());
		} catch( Exception e) {}

		if(debug) {
			System.out.format("Running %dx2*%d alignment took %s ms\n",ca1.length,ca2.length,System.currentTimeMillis()-startTime);
			startTime = System.currentTimeMillis();
		}
		afpChain = postProcessAlignment(afpChain, ca1, ca2m, calculator, cpparams);

		if(debug) {
			System.out.format("Finding CP point took %s ms\n",System.currentTimeMillis()-startTime);
			startTime = System.currentTimeMillis();
		}

		return afpChain;
	}
642498
public static void checkAssignability(Class<?> c1, Class<?> c2) {
		COMPARISON_TYPE ct1 = COMPARISON_TYPE.fromClass(c1);
		COMPARISON_TYPE ct2 = COMPARISON_TYPE.fromClass(c2);
		try {
			COMPARISON_TYPE.fromOperands(ct1, ct2);
		} catch (Exception e) {
			throw DBLogger.newUser("Cannot assign " + c2 + " to " + c1, e);
		}
	}
194041
private double getDensity(Atom[] ca1subset, Atom[] ca2subset ) throws StructureException{

		Atom centroid1 =  Calc.getCentroid(ca1subset);
		Atom centroid2 = Calc.getCentroid(ca2subset);

		// get Average distance to centroid ...

		double d1 = 0;
		double d2 = 0;

		for ( int i = 0 ; i < ca1subset.length;i++){
			double dd1 = Calc.getDistance(centroid1, ca1subset[i]);
			double dd2 = Calc.getDistance(centroid2, ca2subset[i]);

			d1 += dd1;
			d2 += dd2;

		}

		double avd1 = d1 / ca1subset.length;
		double avd2 = d2 / ca2subset.length;

		return Math.min(avd1,avd2);
	}
1298321
public static void main(String[] args) throws Exception {
		// UPDATE THE FOLLOWING LINES TO MATCH YOUR SETUP

		PDBFileReader pdbr = new PDBFileReader();
		pdbr.setPath("/Users/andreas/WORK/PDB/");

		// String pdb1 = "1crl";
		// String pdb2 = "1ede";

		String pdb1 = "1buz";
		String pdb2 = "1ali";
		String outputfile = "/tmp/alig_" + pdb1 + "_" + pdb2 + ".pdb";

		// NO NEED TO DO CHANGE ANYTHING BELOW HERE...

		StructurePairAligner sc = new StructurePairAligner();

		// step1 : read molecules

		logger.info("aligning {} vs. {}", pdb1, pdb2);

		Structure s1 = pdbr.getStructureById(pdb1);
		Structure s2 = pdbr.getStructureById(pdb2);

		// step 2 : do the calculations
		sc.align(s1, s2);

		AlternativeAlignment[] aligs = sc.getAlignments();

		// cluster similar results together
		ClusterAltAligs.cluster(aligs);

		// print the result:
		// the AlternativeAlignment object gives also access to rotation
		// matrices / shift vectors.
		for (AlternativeAlignment aa : aligs) {
			logger.info("Alternative Alignment: ", aa);
		}

		// convert AlternativeAlignemnt 1 to PDB file, so it can be opened with
		// a viewer (e.g. Jmol, Rasmol)

		if (aligs.length > 0) {
			AlternativeAlignment aa1 = aligs[0];
			String pdbstr = aa1.toPDB(s1, s2);

			logger.info("writing alignment to {}", outputfile);
			FileOutputStream out = new FileOutputStream(outputfile);
			PrintStream p = new PrintStream(out);

			p.println(pdbstr);

			p.close();
			out.close();
		}

		// display the alignment in Jmol
		// only will work if Jmol is in the Classpath

		if (aligs.length > 0) {

			if (!GuiWrapper.isGuiModuleInstalled()) {
				logger.error("Could not find structure-gui modules in classpath, please install first!");
			}

		}

	}
519147
public static <S extends Sequence<S>> Alignment<S> alignLocal(AlignmentScoring<S> alignmentScoring,
                                                                  S seq1, S seq2) {
        if (alignmentScoring instanceof AffineGapAlignmentScoring)
            return alignLocalAffine((AffineGapAlignmentScoring<S>) alignmentScoring, seq1, seq2);
        if (alignmentScoring instanceof LinearGapAlignmentScoring)
            return alignLocalLinear((LinearGapAlignmentScoring<S>) alignmentScoring, seq1, seq2);
        throw new RuntimeException("Unknown scoring type.");
    }
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);

	}
280223
public static List<Atom[]> getRotatedAtoms(MultipleAlignment multAln)
			throws StructureException {

		int size = multAln.size();

		List<Atom[]> atomArrays = multAln.getAtomArrays();
		for (int i = 0; i < size; i++) {
			if (atomArrays.get(i).length < 1)
				throw new StructureException(
						"Length of atoms arrays is too short! Size: "
								+ atomArrays.get(i).length);
		}

		List<Atom[]> rotatedAtoms = new ArrayList<Atom[]>();

		// TODO implement independent BlockSet superposition of the structure
		List<Matrix4d> transf = multAln.getBlockSet(0).getTransformations();

		if (transf == null) {

			logger.error("Alignment Transformations are not calculated. "
					+ "Superimposing to first structure as reference.");

			multAln = multAln.clone();
			MultipleSuperimposer imposer = new ReferenceSuperimposer();
			imposer.superimpose(multAln);
			transf = multAln.getBlockSet(0).getTransformations();
			assert (transf != null);
		}

		// Rotate the atom coordinates of all the structures
		for (int i = 0; i < size; i++) {
			// TODO handle BlockSet-level transformations
			// make sure this method has the same behavior as the other display.
			// -SB 2015-06

			// Assume all atoms are from the same structure
			Structure displayS = atomArrays.get(i)[0].getGroup().getChain()
					.getStructure().clone();

			// Get all the atoms and include ligands and hetatoms
			Atom[] rotCA = StructureTools.getRepresentativeAtomArray(displayS);
			List<Group> hetatms = StructureTools.getUnalignedGroups(rotCA);
			int index = rotCA.length;
			rotCA = Arrays.copyOf(rotCA, rotCA.length + hetatms.size());
			for (Group g : hetatms) {
				rotCA[index] = g.getAtom(0);
				index++;
			}

			// Transform the structure to ensure a full rotation in the display
			Calc.transform(displayS, transf.get(i));
			rotatedAtoms.add(rotCA);
		}

		return rotatedAtoms;
	}
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));
	}
112958
public List<Subunit> getAlignedSubunits2() {

		List<Subunit> aligned = new ArrayList<Subunit>(subunitMap.size());

		for (Integer key : subunitMap.keySet())
			aligned.add(subunits2.get(subunitMap.get(key)));

		return aligned;
	}
530857
public static Atom[] duplicateCA2(Atom[] ca2) {
		// we don't want to rotate input atoms, do we?
		Atom[] ca2clone = new Atom[ca2.length * 2];

		int pos = 0;

		Chain c = null;
		String prevChainId = "";
		for (Atom a : ca2) {
			Group g = (Group) a.getGroup().clone(); // works because each group
			// has only a single atom

			if (c == null) {
				c = new ChainImpl();
				Chain orig = a.getGroup().getChain();
				c.setId(orig.getId());
				c.setName(orig.getName());
			} else {
				Chain orig = a.getGroup().getChain();
				if (!orig.getId().equals(prevChainId)) {
					c = new ChainImpl();
					c.setId(orig.getId());
					c.setName(orig.getName());
				}
			}

			c.addGroup(g);
			ca2clone[pos] = g.getAtom(a.getName());

			pos++;
		}

		// Duplicate ca2!
		c = null;
		prevChainId = "";
		for (Atom a : ca2) {
			Group g = (Group) a.getGroup().clone();

			if (c == null) {
				c = new ChainImpl();
				Chain orig = a.getGroup().getChain();
				c.setId(orig.getId());
				c.setName(orig.getName());
			} else {
				Chain orig = a.getGroup().getChain();
				if (!orig.getId().equals(prevChainId)) {
					c = new ChainImpl();
					c.setId(orig.getId());
					c.setName(orig.getName());
				}
			}

			c.addGroup(g);
			ca2clone[pos] = g.getAtom(a.getName());

			pos++;
		}

		return ca2clone;

	}
36986
private static AFPChain partitionAFPchain(AFPChain afpChain,
			Atom[] ca1, Atom[] ca2, int order) throws StructureException{

		int[][][] newAlgn = new int[order][][];
		int repeatLen = afpChain.getOptLength()/order;

		//Extract all the residues considered in the first chain of the alignment
		List<Integer> alignedRes = new ArrayList<Integer>();
		for (int su=0; su<afpChain.getBlockNum(); su++){
			for (int i=0; i<afpChain.getOptLen()[su]; i++){
				alignedRes.add(afpChain.getOptAln()[su][0][i]);
			}
		}

		//Build the new alignment
		for (int su=0; su<order; su++){
			newAlgn[su] = new int[2][];
			newAlgn[su][0] = new  int[repeatLen];
			newAlgn[su][1] = new  int[repeatLen];
			for (int i=0; i<repeatLen; i++){
				newAlgn[su][0][i] = alignedRes.get(repeatLen*su+i);
				newAlgn[su][1][i] = alignedRes.get(
						(repeatLen*(su+1)+i)%alignedRes.size());
			}
		}

		return AlignmentTools.replaceOptAln(newAlgn, afpChain, ca1, ca2);
	}
3754
void align_static(Bindings bindings1) {
        bindings1.addAttribute(VAR_CONSUMED_NAME, prim(ROLE_IMG));
        bindings1.addAttribute(VAR_CONSUMED_NAME, prim(ROLE_HDR));
        bindings1.addAttribute(VAR_CONSUMED_NAME, prim(ROLE_IMG_REF));
        bindings1.addAttribute(VAR_CONSUMED_NAME, prim(ROLE_HDR_REF));     
        bindings1.addAttribute(VAR_CONSUMED_TYPE, prim(FILE));
        bindings1.addAttribute(VAR_CONSUMED_TYPE, prim(FILE));
        bindings1.addAttribute(VAR_CONSUMED_TYPE, prim(FILE));
        bindings1.addAttribute(VAR_CONSUMED_TYPE, prim(FILE));
        
        bindings1.addAttribute(VAR_BLOCK_TYPE,    prim(ALIGN_WARP));
        bindings1.addAttribute(VAR_PRODUCED_TYPE, prim(FILE));
        bindings1.addAttribute(VAR_PRODUCED_NAME, prim(ROLE_OUT));


        
    }
579037
public void set( double p1_x , double p1_y , double p2_x , double p2_y ) {
		this.p1.set(p1_x,p1_y);
		this.p2.set(p2_x,p2_y);
	}
550430
public synchronized static void toXML(AFPChain afpChain, StringWriter swriter,Atom[] ca1, Atom[]ca2) throws IOException{

		PrintWriter writer = new PrintWriter(swriter);
		PrettyXMLWriter xml = new PrettyXMLWriter(writer);

		xml.openTag("AFPChain");

		printXMLHeader(xml,afpChain);


		// that is the initial alignment...
		// we don't serialize that at the present.
		//int[] blockResSize = afpChain.getBlockResSize();
		//int[][][] blockResList = afpChain.getBlockResList();


		// get the alignment blocks
		int blockNum = afpChain.getBlockNum();
		//int[] optLen       = afpChain.getOptLen();
		//int[] blockSize    = afpChain.getBlockSize();
		for(int bk = 0; bk < blockNum; bk ++) {

			xml.openTag("block");

			printXMLBlockHeader(xml,afpChain, bk);

			if ( ca1 == null || ca2 == null) {
				try {
					printXMLEQRKnownPositions(xml,afpChain,bk);
				} catch (StructureException ex ){
					throw new IOException(ex.getMessage());
				}
			}
			else
				printXMLEQRInferPositions(xml, afpChain,bk,ca1,ca2);

			printXMLMatrixShift(xml, afpChain, bk);

			xml.closeTag("block");
		}

		xml.closeTag("AFPChain");

		writer.close();


	}
969763
public static CeSymmResult analyze(Atom[] atoms) throws StructureException {
		CESymmParameters params = new CESymmParameters();
		return analyze(atoms, params);
	}
861084
@SuppressWarnings({"checkstyle:cyclomaticcomplexity", "checkstyle:npathcomplexity", "checkstyle:nestedifdepth"})
	protected void checkSuperConstructor(
			XtendTypeDeclaration container,
			EStructuralFeature feature,
			Collection<ActionParameterTypes> defaultSignatures) {
		final JvmDeclaredType jvmElement = this.associations.getInferredType(container);
		if (jvmElement != null) {
			final Map<ActionParameterTypes, JvmConstructor> superConstructors =
					CollectionLiterals.newTreeMap((Comparator<ActionParameterTypes>) null);
			final JvmTypeReference typeRef = jvmElement.getExtendedClass();
			final JvmType supertype = (typeRef == null) ? null : typeRef.getType();
			if (supertype instanceof JvmGenericType) {
				final JvmGenericType jvmSuperElement = (JvmGenericType) supertype;
				for (final JvmConstructor superConstructor : jvmSuperElement.getDeclaredConstructors()) {
					final ActionParameterTypes sig = this.sarlActionSignatures.createParameterTypesFromJvmModel(
							superConstructor.isVarArgs(), superConstructor.getParameters());
					superConstructors.put(sig, superConstructor);
				}
			}

			final ActionParameterTypes voidKey = this.sarlActionSignatures.createParameterTypesForVoid();
			//boolean hasDeclaredConstructor = false;

			for (final XtendMember member : container.getMembers()) {
				if (member instanceof SarlConstructor) {
					final SarlConstructor constructor = (SarlConstructor) member;
					//hasDeclaredConstructor = true;
					boolean invokeDefaultConstructor = true;
					final XExpression body = constructor.getExpression();
					if (body instanceof XBlockExpression) {
						final XBlockExpression block = (XBlockExpression) body;
						if (!block.getExpressions().isEmpty()) {
							final XExpression firstStatement = block.getExpressions().get(0);
							if (firstStatement instanceof XConstructorCall || isDelegateConstructorCall(firstStatement)) {
								invokeDefaultConstructor = false;
							}
						}
					} else if (body instanceof XConstructorCall || isDelegateConstructorCall(body)) {
						invokeDefaultConstructor = false;
					}
					if (invokeDefaultConstructor && !superConstructors.containsKey(voidKey)) {
						final List<String> issueData = new ArrayList<>();
						for (final ActionParameterTypes defaultSignature : defaultSignatures) {
							issueData.add(defaultSignature.toString());
						}
						error(Messages.SARLValidator_33,
								member,
								null,
								ValidationMessageAcceptor.INSIGNIFICANT_INDEX,
								MUST_INVOKE_SUPER_CONSTRUCTOR,
								toArray(issueData, String.class));
					}
				}
			}

			// The following code is no more needed because of the constructor inheritance mechanism which
			// is implemented into the JVM model inferrer.
			/*if (!hasDeclaredConstructor) {
				for (final ActionParameterTypes defaultSignature : defaultSignatures) {
					if (!superConstructors.containsKey(defaultSignature)) {
						final List<String> issueData = new ArrayList<>();
						for (final JvmConstructor superConstructor : superConstructors.values()) {
							issueData.add(EcoreUtil.getURI(superConstructor).toString());
							issueData.add(doGetReadableSignature(container.getName(), superConstructor.getParameters()));
						}
						error(Messages.SARLValidator_33,
								container, feature, MISSING_CONSTRUCTOR, toArray(issueData, String.class));
					}
				}
			}*/
		}
	}
57863
public static AFPChain replaceOptAln(int[][][] newAlgn, AFPChain afpChain, Atom[] ca1, Atom[] ca2) throws StructureException {

		//The order is the number of groups in the newAlgn
		int order = newAlgn.length;

		//Calculate the alignment length from all the subunits lengths
		int[] optLens = new int[order];
		for(int s=0;s<order;s++) {
			optLens[s] = newAlgn[s][0].length;
		}
		int optLength = 0;
		for(int s=0;s<order;s++) {
			optLength += optLens[s];
		}

		//Create a copy of the original AFPChain and set everything needed for the structure update
		AFPChain copyAFP = (AFPChain) afpChain.clone();

		//Set the new parameters of the optimal alignment
		copyAFP.setOptLength(optLength);
		copyAFP.setOptLen(optLens);
		copyAFP.setOptAln(newAlgn);

		//Set the block information of the new alignment
		copyAFP.setBlockNum(order);
		copyAFP.setBlockSize(optLens);
		copyAFP.setBlockResList(newAlgn);
		copyAFP.setBlockResSize(optLens);
		copyAFP.setBlockGap(calculateBlockGap(newAlgn));

		//Recalculate properties: superposition, tm-score, etc
		Atom[] ca2clone = StructureTools.cloneAtomArray(ca2); // don't modify ca2 positions
		AlignmentTools.updateSuperposition(copyAFP, ca1, ca2clone);

		//It re-does the sequence alignment strings from the OptAlgn information only
		copyAFP.setAlnsymb(null);
		AFPAlignmentDisplay.getAlign(copyAFP, ca1, ca2clone);

		return copyAFP;
	}