calculates  scores for this alignment ( %id )
@param ca1 set of Atoms for molecule 1
@param ca2 set of Atoms for molecule 2
432250
public void calcScores(Atom[] ca1, Atom[] ca2){
		eqr0 = idx1.length;
		gaps0 = count_gaps(idx1,idx2);

		percId = 0;
		// calc the % id
		for (int i=0 ; i< idx1.length; i++){
			Atom a1 = ca1[idx1[i]];
			Atom a2 = ca2[idx2[i]];

			Group g1 = a1.getGroup();
			Group g2 = a2.getGroup();
			if ( g1.getPDBName().equals(g2.getPDBName())){
				percId++;
			}

		}
	}
217298
@Override
    public DescriptorValue calculate(IAtomContainer container) {
        IAtomContainer atomContainer;
        try {
            atomContainer = (IAtomContainer) container.clone();
        } catch (CloneNotSupportedException e) {
            DoubleArrayResult kierValues = new DoubleArrayResult(3);
            kierValues.add(Double.NaN);
            kierValues.add(Double.NaN);
            kierValues.add(Double.NaN);
            return new DescriptorValue(getSpecification(), getParameterNames(), getParameters(), kierValues,
                    getDescriptorNames());
        }
        atomContainer = AtomContainerManipulator.removeHydrogens(atomContainer);

        //org.openscience.cdk.interfaces.IAtom[] atoms = atomContainer.getAtoms();
        java.util.List firstAtomNeighboors;
        java.util.List secondAtomNeighboors;
        java.util.List thirdAtomNeighboors;
        DoubleArrayResult kierValues = new DoubleArrayResult(3);
        double bond1;
        double bond2;
        double bond3;
        double kier1;
        double kier2;
        double kier3;
        double atomsCount = atomContainer.getAtomCount();
        ArrayList<Double> singlePaths = new ArrayList<Double>();
        ArrayList<String> doublePaths = new ArrayList<String>();
        ArrayList<String> triplePaths = new ArrayList<String>();
        double[] sorterFirst = new double[2];
        double[] sorterSecond = new double[3];
        String tmpbond2;
        String tmpbond3;

        for (int a1 = 0; a1 < atomsCount; a1++) {
            bond1 = 0;
            firstAtomNeighboors = atomContainer.getConnectedAtomsList(atomContainer.getAtom(a1));
            for (int a2 = 0; a2 < firstAtomNeighboors.size(); a2++) {
                bond1 = atomContainer.indexOf(atomContainer.getBond(atomContainer.getAtom(a1), (IAtom) firstAtomNeighboors.get(a2)));
                if (!singlePaths.contains(new Double(bond1))) {
                    singlePaths.add(bond1);
                    java.util.Collections.sort(singlePaths);
                }
                secondAtomNeighboors = atomContainer.getConnectedAtomsList((IAtom) firstAtomNeighboors.get(a2));
                for (int a3 = 0; a3 < secondAtomNeighboors.size(); a3++) {
                    bond2 = atomContainer.indexOf(atomContainer.getBond((IAtom) firstAtomNeighboors.get(a2),
                            (IAtom) secondAtomNeighboors.get(a3)));
                    if (!singlePaths.contains(new Double(bond2))) {
                        singlePaths.add(bond2);
                    }
                    sorterFirst[0] = bond1;
                    sorterFirst[1] = bond2;
                    java.util.Arrays.sort(sorterFirst);

                    tmpbond2 = sorterFirst[0] + "+" + sorterFirst[1];

                    if (!doublePaths.contains(tmpbond2) && (bond1 != bond2)) {
                        doublePaths.add(tmpbond2);
                    }
                    thirdAtomNeighboors = atomContainer.getConnectedAtomsList((IAtom) secondAtomNeighboors.get(a3));
                    for (int a4 = 0; a4 < thirdAtomNeighboors.size(); a4++) {
                        bond3 = atomContainer.indexOf(atomContainer.getBond((IAtom) secondAtomNeighboors.get(a3),
                                (IAtom) thirdAtomNeighboors.get(a4)));
                        if (!singlePaths.contains(new Double(bond3))) {
                            singlePaths.add(bond3);
                        }
                        sorterSecond[0] = bond1;
                        sorterSecond[1] = bond2;
                        sorterSecond[2] = bond3;
                        java.util.Arrays.sort(sorterSecond);

                        tmpbond3 = sorterSecond[0] + "+" + sorterSecond[1] + "+" + sorterSecond[2];
                        if (!triplePaths.contains(tmpbond3)) {
                            if ((bond1 != bond2) && (bond1 != bond3) && (bond2 != bond3)) {
                                triplePaths.add(tmpbond3);
                            }
                        }
                    }
                }
            }
        }

        if (atomsCount == 1) {
            kier1 = 0;
            kier2 = 0;
            kier3 = 0;
        } else {
            kier1 = (((atomsCount) * ((atomsCount - 1) * (atomsCount - 1))) / (singlePaths.size() * singlePaths.size()));
            if (atomsCount == 2) {
                kier2 = 0;
                kier3 = 0;
            } else {
                if (doublePaths.size() == 0)
                    kier2 = Double.NaN;
                else
                    kier2 = (((atomsCount - 1) * ((atomsCount - 2) * (atomsCount - 2))) / (doublePaths.size() * doublePaths
                            .size()));
                if (atomsCount == 3) {
                    kier3 = 0;
                } else {
                    if (atomsCount % 2 != 0) {
                        if (triplePaths.size() == 0)
                            kier3 = Double.NaN;
                        else
                            kier3 = (((atomsCount - 1) * ((atomsCount - 3) * (atomsCount - 3))) / (triplePaths.size() * triplePaths
                                    .size()));
                    } else {
                        if (triplePaths.size() == 0)
                            kier3 = Double.NaN;
                        else
                            kier3 = (((atomsCount - 3) * ((atomsCount - 2) * (atomsCount - 2))) / (triplePaths.size() * triplePaths
                                    .size()));
                    }
                }
            }
        }

        kierValues.add(kier1);
        kierValues.add(kier2);
        kierValues.add(kier3);
        return new DescriptorValue(getSpecification(), getParameterNames(), getParameters(), kierValues,
                getDescriptorNames());
    }
561835
private double initScore() {
        double score = 0;
        final int n = atoms.length;
        for (int i = 0; i < n; i++) {
            final Point2d p1 = atoms[i].getPoint2d();
            for (int j = i + 1; j < n; j++) {
                if (contribution[i][j] < 0) continue;
                final Point2d p2 = atoms[j].getPoint2d();
                final double x = p1.x - p2.x;
                final double y = p1.y - p2.y;
                final double len2 = x * x + y * y;
                score += contribution[j][i] = contribution[i][j] = 1 / Math.max(len2, MIN_SCORE);
            }
        }
        return score;
    }
1067887
public final float[] score( String names[], String domains[][], boolean exact, double row[] ) {
    return score(adapt(names,domains,exact),row,new float[nclasses()]);
  }
35347
public double compare(IsotopePattern isoto1, IsotopePattern isoto2) {

        IsotopePattern iso1 = IsotopePatternManipulator.sortAndNormalizedByIntensity(isoto1);
        IsotopePattern iso2 = IsotopePatternManipulator.sortAndNormalizedByIntensity(isoto2);

        /* charge to add */
        if (isoto1.getCharge() == 1)
            chargeToAdd = massE;
        else if (isoto1.getCharge() == -1)
            chargeToAdd = -massE;
        else
            chargeToAdd = 0;

        for (IsotopeContainer isoC : iso1.getIsotopes()) {
            double mass = isoC.getMass();
            isoC.setMass(mass + chargeToAdd);
        }

        double diffMass, diffAbun, factor, totalFactor = 0d;
        double score = 0d, tempScore;
        // Maximum number of isotopes to be compared according predicted isotope
        // pattern. It is assumed that this will have always more isotopeContainers
        int length = iso1.getNumberOfIsotopes();

        for (int i = 0; i < length; i++) {
            IsotopeContainer isoContainer = iso1.getIsotopes().get(i);
            factor = isoContainer.getIntensity();
            totalFactor += factor;

            // Search for the closest isotope in the second pattern (detected) to the
            // current isotope (predicted pattern)
            int closestDp = getClosestDataDiff(isoContainer, iso2);
            if (closestDp == -1) continue;

            diffMass = isoContainer.getMass() - iso2.getIsotopes().get(closestDp).getMass();
            diffMass = Math.abs(diffMass);

            diffAbun = 1.0d - (isoContainer.getIntensity() / iso2.getIsotopes().get(closestDp).getIntensity());
            diffAbun = Math.abs(diffAbun);

            tempScore = 1 - (diffMass + diffAbun);

            if (tempScore < 0) tempScore = 0;

            score += (tempScore * factor);

        }

        return score / totalFactor;
    }
1335574
public static String toFatCatCore(
			AFPChain afpChain,
			Atom[] ca1,
			Atom[] ca2,
			boolean printLegend, boolean longHeader, boolean showHTML, boolean showAlignmentBlock){

		//TODO The sequence numbers are inaccurate if a !afpChain.isSequential()

		String name1 = afpChain.getName1();
		String name2 = afpChain.getName2();
		int ca1Length = afpChain.getCa1Length();
		int ca2Length = afpChain.getCa2Length();

		int blockNum = afpChain.getBlockNum();
		int totalLenIni = afpChain.getTotalLenIni();
		double totalRmsdIni = afpChain.getTotalRmsdIni();
		int optLength = afpChain.getOptLength();
		double totalRmsdOpt = afpChain.getTotalRmsdOpt();
		double chainRmsd = afpChain.getChainRmsd();
		double alignScore = afpChain.getAlignScore();
		int alnLength = afpChain.getAlnLength();
		int gapLen = afpChain.getGapLen();
		List<AFP> afpSet = afpChain.getAfpSet();

		double similarity = afpChain.getSimilarity();
		double identity = afpChain.getIdentity();

		if (similarity <0  || identity < 0){
			afpChain.calcSimilarity();
			similarity = afpChain.getSimilarity();
			identity = afpChain.getIdentity();
		}



		String algorithmName = afpChain.getAlgorithmName();
		//String version = afpChain.getVersion();

		double probability = afpChain.getProbability();


		int afpNum = afpSet.size();

		int[] blockGap = afpChain.getBlockGap();


		double[] blockScore = afpChain.getBlockScore();
		double[] blockRmsd = afpChain.getBlockRmsd();
		int[] blockSize = afpChain.getBlockSize();


		int alnbeg1 = afpChain.getAlnbeg1();
		int alnbeg2 = afpChain.getAlnbeg2();

		char[] alnseq1 = afpChain.getAlnseq1();
		char[] alnseq2 = afpChain.getAlnseq2();
		char[] alnsymb = afpChain.getAlnsymb();

		// == end of extractation of data values from afpChain
		////////////////////////////////

		StringBuffer txt = new StringBuffer();

		if ( longHeader) {
			txt.append(String.format("Align %s.pdb %d with %s.pdb %d", name1, ca1Length, name2, ca2Length));
		}
		else {
			txt.append(String.format("Align %s.pdb Length1: %d with %s.pdb Length2: %d", name1, ca1Length, name2, ca2Length));
		}
		txt.append(newline);
		if ( afpChain.isShortAlign()){
			txt.append("Short match");
			return txt.toString();
		}
		//txt.append(String.format("raw-score: %.2f norm.-score: %.2f ", alignScore, normAlignScore));

		if ( longHeader ) {
			txt.append(String.format( "Twists %d ini-len %d ini-rmsd %.2f opt-equ %d opt-rmsd %.2f chain-rmsd %.2f Score %.2f align-len %d gaps %d (%.2f%%)",
					blockNum - 1, totalLenIni, totalRmsdIni, optLength, totalRmsdOpt, chainRmsd, alignScore,
					alnLength, gapLen, (100.0 * gapLen/alnLength)) );
			txt.append(newline);

		}  else {

			if ( ! longHeader)
				printScore(txt,algorithmName,probability,longHeader);

			printScoresInLines(afpChain, blockNum, optLength, totalRmsdOpt, alignScore, alnLength, gapLen, identity, similarity,txt);
		}


		//txt.append(String.format("P-value %.2e Afp-num %d Identity %.2f%% Similarity %.2f%% norm.-score: %.2f"+newline, probability, afpNum, identity * 100, similarity * 100, normAlignScore));

		if ( longHeader) {
			printScore(txt,algorithmName,probability,longHeader);

			txt.append(String.format("Afp-num %d Identity %.2f%% Similarity %.2f%%", afpNum, identity * 100, similarity * 100));
			txt.append(newline);
		}

		int i;
		double gap;

		if ( longHeader ){
			int fragLen = 8 ; // FatCatParameters.DEFAULT_FRAGLEN;
			for(i = 0; i < blockNum; i ++)  {
				gap = blockGap[i] /( (double)blockGap[i] + fragLen * blockSize[i]);
				txt.append(String.format( "Block %2d afp %2d score %5.2f rmsd %5.2f gap %d (%.2f%%)",
						i, blockSize[i], blockScore[i], blockRmsd[i], blockGap[i], gap));
				txt.append(newline);
			}
		}

		int     linelen = 70;
		String a;
		String b;
		String c;


		int     t = 0;
		int     ap = alnbeg1;
		int     bp = alnbeg2;
		int     k, len;

		//System.out.println(alnseq1.length + " " + alnseq1.toString());

		while((alnLength - t) > 0)      {
			if(alnLength - t > linelen)     len = linelen;
			else    len = alnLength - t;

			if ( ap >= ca1.length)
				break;
			if ( bp >= ca2.length)
				break;

			String pdb1 = ca1[ap].getGroup().getResidueNumber().toString();
			String pdb2 = ca2[bp].getGroup().getResidueNumber().toString();


			//System.err.println("t,len:"+t+":"+len);
			String lseq1 = new String(alnseq1).substring(t,t+len);
			String lseq2 = new String(alnseq2).substring(t,t+len);
			String lsymb = new String(alnsymb).substring(t,t+len);

			//System.err.println("B:" + b);


			// check conservation and color accordingly, if requested by user.
			if ( showHTML ) {
				a = "";
				b = "";
				c = "";

				//	<span class=\"m\">|</span> ... Structurally equivalent and identical residues
				//  <span class=\"sm\">:</span> ... Structurally equivalent and similar residues
				//  <span class=\"qg\">.</span> ... Structurally equivalent, but not similar residues.

				for (int pos = 0 ; pos < lseq1.length() ; pos ++){
					char c1 = lseq1.charAt(pos);
					char c2 = lseq2.charAt(pos);
					char cl = lsymb.charAt(pos);
					int block = -1 ;
					if ( cl != ' ') {
						try {
							block = Integer.parseInt(String.valueOf(cl));
						} catch (Exception e){
							//
						}
					}
					if ( cl != ' ' ){

						if ( showAlignmentBlock && block > -1 ) {
							a += "<span class=\"alignmentBlock1"+block+"\">" + c1 + "</span>";
							b += "<span class=\"alignmentBlock2"+block+"\">" + c2 + "</span>";
							c += "<span class=\"m\">" + cl + "</span>";
						} else {
							a += getPrefix(c1, c2, 0, block, false).toString() + c1 + "</span>";
							b += getPrefix(c1, c2, 1, block, false).toString() + c2 + "</span>";
							c += "<span class=\"m\">" + cl + "</span>";
						}

					} else if ( c1 != '-' && c2 != '-') {

						a += "<span class=\"sm\">" + c1 + "</span>";
						b += "<span class=\"sm\">" + c2 + "</span>";
						c += "<span class=\"sm\">" + cl + "</span>";


					} else {

						a += "<span class=\"qg\">" + c1 + "</span>";
						b += "<span class=\"qg\">" + c2 + "</span>";
						c += "<span class=\"qg\">" + cl + "</span>";

					}

					if(c1 != '-') ap ++;
					if(c2 != '-') bp ++;
				}


			} else {

				a = lseq1;
				b = lseq2;
				c = lsymb;
			}

			txt.append(newline);
			if ( longHeader )
				txt.append(String.format("%14s", " "));
			else
				txt.append(String.format("%14s", " "));

			if (  longHeader ) {
				for(k = 10; k <= len; k += 10)
					txt.append("    .    :");
				if(k <= len + 5) txt.append("    .");

			} else {

				for(k = 10; k <= len; k += 10)
					txt.append("----+----|");
				if(k <= len + 5) txt.append("----+");


			}



			txt.append(newline);
			txt.append(String.format("Chain 1:%5s %s"+newline +"%14s%s"+newline+"Chain 2:%5s %s",
					pdb1, a, " ", c, pdb2, b));

			txt.append(newline);

			if ( ! showHTML){
				for(k = 0; k < len; k ++)       {
					if(a.charAt(k) != '-') ap ++;
					if(b.charAt(k) != '-') bp ++;
				}
			}
			t += len;



		}
		txt.append(newline);
		if ( printLegend ){
			if ( algorithmName.equalsIgnoreCase(CeMain.algorithmName) ||
					algorithmName.equalsIgnoreCase(SmithWaterman3Daligner.algorithmName)){
				txt.append("Note: positions are from PDB; | means alignment of identical amino acids, : of similar amino acids ");

			} else {
				txt.append("Note: positions are from PDB; the numbers between alignments are block index");
			}
			txt.append(newline);

		}
		return txt.toString();

	}

	public static void printScoresInLines(AFPChain afpChain, int blockNum, int optLength, double totalRmsdOpt, double alignScore,
			int alnLength, int gapLen, double identity, double similarity, StringBuffer txt)
	{
		if ( blockNum - 1 > 0) {
			txt.append(String.format( "Twists %d ", blockNum -1 ));
			txt.append(newline);
		}

		txt.append(String.format("Equ: %d ", optLength));
		txt.append(newline);
		txt.append(String.format("RMSD: %.2f ", totalRmsdOpt));
		txt.append(newline);
		txt.append(String.format("Score: %.2f ", alignScore));
		txt.append(newline);
		txt.append(String.format("Align-len: %d ", alnLength));
		txt.append(newline);
		txt.append(String.format("Gaps: %d (%.2f%%)",
				gapLen, (100.0 * gapLen/alnLength)) );
		txt.append(newline);
		if ( afpChain.getTMScore() >= 0) {
			txt.append(String.format("TM-score: %.2f",afpChain.getTMScore()));
			txt.append(newline);
		}
		txt.append(newline);
		txt.append(String.format("Identity: %.2f%% ", identity * 100 ));
		txt.append(newline);
		txt.append(String.format("Similarity: %.2f%%", similarity * 100));
		txt.append(newline);
	}

	private static void printScore(StringBuffer txt,
			String algorithmName,
			double probability,
			boolean longHeader)
	{
		if ( algorithmName.equalsIgnoreCase(CeMain.algorithmName) || algorithmName.equalsIgnoreCase(CeSideChainMain.algorithmName) ){
			txt.append(String.format("Z-score %.2f ", probability));
			if ( ! longHeader)
				txt.append(newline);
		} else if ( algorithmName.equalsIgnoreCase(SmithWaterman3Daligner.algorithmName)) {

		} else {
			if ( longHeader ){
				txt.append(String.format("P-value %.2e ",probability));
			}  else {
				txt.append(String.format("P-value: %.2e ",probability));
				txt.append(newline);
			}
		}



	}

	/**
	 * Prints the afpChain as a nicely formatted alignment, including alignment
	 * statistics, the aligned sequences themselves, and information about the
	 * superposition.
	 * @param afpChain
	 * @param ca1
	 * @param ca2
	 * @return a String representation as it is used on the RCSB PDB web site for display.
	 */
	public static String toWebSiteDisplay(AFPChain afpChain, Atom[] ca1, Atom[] ca2 ){
		boolean showAlignmentBlock   = true;
		return toWebSiteDisplay(afpChain, ca1, ca2, showAlignmentBlock);
	}

	/**
	 * Prints the afpChain as a nicely formatted alignment, including alignment
	 * statistics, the aligned sequences themselves, and information about the
	 * superposition.
	 * @param afpChain
	 * @param ca1
	 * @param ca2
	 *
	 * @return a String representation as it is used on the RCSB PDB web site for display.
	 */
	public static String toWebSiteDisplay(AFPChain afpChain, Atom[] ca1, Atom[] ca2, boolean showAlignmentBlock){

		boolean printLegend = true;
		boolean longHeader  = true;
		boolean showHTML = true;

		if ( afpChain.getAlgorithmName().equalsIgnoreCase(FatCatFlexible.algorithmName)) {


			String msg =  toFatCatCore(afpChain,ca1,ca2,printLegend,longHeader,showHTML, showAlignmentBlock);

			return msg;
		}

		boolean showSeq = true;

		AFPAlignmentDisplay.getAlign(afpChain, ca1, ca2, showSeq);


		//      String msg= toFatCatCore(afpChain,ca1,ca2, printLegend,longHeader);
		//


		String msg = toPrettyAlignment(afpChain, ca1, ca2, showHTML, showAlignmentBlock);


		msg = msg + newline +
		"     <span class=\"m\">|</span> ... Structurally equivalent and identical residues " + newline +
		"     <span class=\"sm\">:</span> ... Structurally equivalent and similar residues " + newline +
		"     <span class=\"qg\">.</span> ... Structurally equivalent, but not similar residues. " + newline;

		msg += newline;
		msg += "     To calculate the coordinates of chain 2 aligned on chain 1 apply the following transformation: ";
		msg += newline;
		msg += newline;
		msg += toRotMat(afpChain);
		return msg;


	}

	public static String toPrettyAlignment(AFPChain afpChain, Atom[] ca1, Atom[] ca2, boolean showHTML, boolean showAlignmentBlock) {
		String name1 = afpChain.getName1();
		String name2 = afpChain.getName2();
		int ca1Length = afpChain.getCa1Length();
		int ca2Length = afpChain.getCa2Length();

		int blockNum = afpChain.getBlockNum();


		int optLength = afpChain.getOptLength();
		double totalRmsdOpt = afpChain.getTotalRmsdOpt();

		double alignScore = afpChain.getAlignScore();
		int alnLength = afpChain.getAlnLength();
		int gapLen = afpChain.getGapLen();


		double similarity = afpChain.getSimilarity();
		double identity = afpChain.getIdentity();

		if (similarity <0  || identity < 0){
			afpChain.calcSimilarity();
			similarity = afpChain.getSimilarity();
			identity = afpChain.getIdentity();
		}


		String algorithmName = afpChain.getAlgorithmName();
		//String version = afpChain.getVersion();

		double probability = afpChain.getProbability();


		// == end of extractation of data values from afpChain

		StringBuffer txt = new StringBuffer();

		txt.append(String.format("Align %s.pdb Length1: %d with %s.pdb Length2: %d", name1, ca1Length, name2, ca2Length));

		txt.append(newline);

		if ( afpChain.isShortAlign()){
			txt.append("Short match");
			return txt.toString();
		}

		printScore(txt, algorithmName, probability, false);
		printScoresInLines(afpChain, blockNum, optLength, totalRmsdOpt, alignScore, alnLength, gapLen,identity, similarity, txt);
		txt.append(newline);

		int[] optLen = afpChain.getOptLen();
		int[][][] optAln = afpChain.getOptAln();


		int i, j,p1, p2;

		int k;
		int p1b = 0;
		int p2b = 0;

		int     len = 0;
		StringWriter alnseq1 = new StringWriter();
		StringWriter alnseq2 = new StringWriter();
		StringWriter alnsymb = new StringWriter();
		StringWriter header1  = new StringWriter();
		StringWriter footer1  = new StringWriter();
		StringWriter header2  = new StringWriter();
		StringWriter footer2  = new StringWriter();
		StringWriter block    = new StringWriter();

		int aligPos = -1;
		for(i = 0; i < blockNum; i ++)  {

			for(j = 0; j < optLen[i]; j ++) {

				p1 = optAln[i][0][j];
				p2 = optAln[i][1][j];
				aligPos++;

				//               System.out.println(p1 + " " + p2 + " " +  footer2.toString());

				if ( len == 0){
					//the first position of sequence in alignment
					formatStartingText(p1,p2,header1,header2,footer1,footer2,ca1,ca2);
				} else {
					// check for gapped region
					int lmax = (p1 - p1b - 1)>(p2 - p2b - 1)?(p1 - p1b - 1):(p2 - p2b - 1);
					for(k = 0; k < lmax; k ++)      {


						formatGappedRegion(ca1, ca2, txt, p1, p2, k, p1b, p2b, alnseq1, alnseq2, alnsymb, header1, footer1, header2,
								footer2, block,len, showHTML);
						len++;
						doLenCheck(len,txt,header1,header2,alnseq1,alnsymb,alnseq2,footer1, footer2,block, showHTML)  ;
					}
				}

				// ALIGNED REGION
				//           System.out.println(len + " >" + header1.toString() +"< ");
				//           System.out.println(len + " >" + header2.toString() +"< ");
				//           System.out.println(len + " >" + alnseq1.toString() +"< ");
				//           System.out.println(len + " >" + alnsymb.toString() +"< ");
				//           System.out.println(len + " >" + alnseq2.toString() +"< ");
				//           System.out.println(len + " >" + footer1.toString() +"< ");
				formatAlignedRegion(afpChain, ca1, ca2, p1, p2, alnseq1, alnseq2, alnsymb, header1, footer1, header2, footer2, block,len, aligPos, showHTML, showAlignmentBlock);
				//            System.out.println(len + " >" + header1.toString() +"< ");
				//            System.out.println(len + " >" + header2.toString() +"< ");
				//            System.out.println(len + " >" + alnseq1.toString() +"< ");
				//            System.out.println(len + " >" + alnsymb.toString() +"< ");
				//            System.out.println(len + " >" + alnseq2.toString() +"< ");
				//            System.out.println(len + " >" + footer1.toString() +"< ");

				len++;

				doLenCheck(len,txt,header1,header2,alnseq1,alnsymb,alnseq2,footer1, footer2,block, showHTML)  ;

				p1b = p1;
				p2b = p2;

				//header1.append(newline);
				//header2.append(newline);

			}

		}

		alnLength = len;

		doLenCheck(LINELENGTH,txt,header1,header2,alnseq1,alnsymb,alnseq2,footer1, footer2,block, showHTML);
		return txt.toString();
	}

	/**
	 * Prints the alignment in the simplest form: a list of aligned residues.
	 * Format is one line per residue pair, tab delimited:
	 * <ul><li>1. PDB number. Includes insertion code</li>
	 * <li>1. Chain.</li>
	 * <li>1. Amino Acid. Three letter code.</li>
	 * <li>2. PDB number.</li>
	 * <li>2. Chain.</li>
	 * <li>2. Amino Acid.</li>
	 * </ul>
	 * example:
	 * <code>152	A	ALA	161S	A	VAL</code>
	 * <p>Note that this format loses information about blocks.
	 * @param afpChain
	 * @param ca1
	 * @param ca2
	 * @return a String representation of the aligned pairs.
	 */
	public static String toAlignedPairs(AFPChain afpChain, Atom[] ca1, Atom[] ca2) {
		StringWriter pairs = new StringWriter();

		//Write structure names & PDB codes
		pairs.append("#Struct1:\t");
		pairs.append(afpChain.getName1());
		pairs.append("\n");
		pairs.append("#Struct2:\t");
		pairs.append(afpChain.getName2());
		pairs.append("\n");

		//Write optimally aligned pairs
		pairs.append("#Num1\tChain1\tAA1\tNum2\tChain2\tAA2\n");
		int[][][] optAln = afpChain.getOptAln();
		int[] blockLen = afpChain.getOptLen();
		for( int block=0;block<afpChain.getBlockNum(); block++) {
			for(int i=0;i<blockLen[block];i++) {
				Atom atom1 = ca1[ optAln[block][0][i] ];
				Atom atom2 = ca2[ optAln[block][1][i] ];

				pairs.append(atom1.getGroup().getResidueNumber().toString());
				pairs.append('\t');
				pairs.append(atom1.getGroup().getChain().getName());
				pairs.append('\t');
				pairs.append(atom1.getGroup().getPDBName());
				pairs.append('\t');
				pairs.append(atom2.getGroup().getResidueNumber().toString());
				pairs.append('\t');
				pairs.append(atom2.getGroup().getChain().getName());
				pairs.append('\t');
				pairs.append(atom2.getGroup().getPDBName());
				pairs.append('\n');
			}
		}

		return pairs.toString();
	}

	private static void formatGappedRegion(Atom[] ca1, Atom[] ca2, StringBuffer txt, int p1, int p2, int k, int p1b, int p2b,
			StringWriter alnseq1, StringWriter alnseq2, StringWriter alnsymb, StringWriter header1, StringWriter footer1,
			StringWriter header2, StringWriter footer2, StringWriter block, int len, boolean formatHTML)	{

		// DEAL WITH GAPS
		int tmppos = (p1 - p1b - 1);
		block.append("g");

		int  pos1=p1b+1+k ;
		char oneletter1 = ' ';
		try {
			oneletter1 = getOneLetter(ca1[pos1].getGroup());
		} catch (Exception e){}
		int pos2=p2b+1+k;
		char oneletter2 = ' ';
		try {
			oneletter2 = getOneLetter(ca2[pos2].getGroup());
		} catch (Exception e){}


		if(k >= tmppos) {
			//alnseq1[len] = '-';
			if (  formatHTML){
				alnseq1.append("<span class=\"qg\">-</span>");
				header1.append(" ");
				header2.append(" ");


			} else {
				alnseq1.append('-');
				header1.append(" ");
				header2.append(" ");
			}

		}
		else {
			if ( formatHTML){
				alnseq1.append(getPrefix(oneletter1,oneletter2,0,-1, false));
			}
			alnseq1.append(oneletter1);
			if (formatHTML){
				alnseq1.append("</span>");
			}
			formatPosition(pos1,ca1, len, header1, header2);

		}

		if(k >= (p2 - p2b - 1)) {
			//alnseq2[len] = '-';
			if ( formatHTML){
				alnseq2.append("<span class=\"qg\">-</span>");
				footer1.append(" ");
				footer2.append(" ");
			} else {
				alnseq2.append('-');
				footer1.append(" ");
				footer2.append(" ");
			}

		}
		else  {
			if ( formatHTML){
				alnseq2.append(getPrefix(oneletter1,oneletter2,1, -1, false));
			}
			alnseq2.append(oneletter2);
			if (formatHTML){
				alnseq2.append("</span>");
			}
			formatPosition(pos2, ca2, len, footer1, footer2);

		}
		//alnsymb[len ++] = ' ';
		alnsymb.append(' ');

	}
1335091
@Override
    public DescriptorValue calculate(IAtomContainer container) {
        //System.out.println("FragmentComplexityDescriptor");
        int a = 0;
        double h = 0;
        for (int i = 0; i < container.getAtomCount(); i++) {
            if (!container.getAtom(i).getSymbol().equals("H")) {
                a++;
            }
            if (!container.getAtom(i).getSymbol().equals("H") && !container.getAtom(i).getSymbol().equals("C")) {
                h++;
            }
        }
        int b = container.getBondCount() + AtomContainerManipulator.getImplicitHydrogenCount(container);
        double c = Math.abs(b * b - a * a + a) + (h / 100);
        return new DescriptorValue(getSpecification(), getParameterNames(), getParameters(), new DoubleResult(c),
                getDescriptorNames());
    }
1331024
private static void permuteOptAln(AFPChain afpChain, int cp)
	{
		int ca2len = afpChain.getCa2Length();

		if( ca2len <= 0) {
			throw new IllegalArgumentException("No Ca2Length specified in "+afpChain);
		}

		// Allow negative cp points for convenience.
		if(cp == 0) {
			return;
		}
		if(cp <= -ca2len || cp >= ca2len) {
			// could just take cp%ca2len, but probably its a bug if abs(cp)>=ca2len
			throw new ArrayIndexOutOfBoundsException( String.format(
					"Permutation point %d must be between %d and %d for %s",
					cp, 1-ca2len,ca2len-1, afpChain.getName2() ) );
		}
		if(cp < 0) {
			cp = cp + ca2len;
		}

		// the unprocessed alignment
		int[][][] optAln = afpChain.getOptAln();
		int[] optLen = afpChain.getOptLen();

		// the processed alignment
		List<List<List<Integer>>> blocks = new ArrayList<List<List<Integer>>>(afpChain.getBlockNum()*2);

		//Update residue indices
		// newi = (oldi-cp) % N
		for(int block = 0; block < afpChain.getBlockNum(); block++) {
			if(optLen[block]<1)
				continue;

			// set up storage for the current block
			List<List<Integer>> currBlock = new ArrayList<List<Integer>>(2);
			currBlock.add( new ArrayList<Integer>());
			currBlock.add( new ArrayList<Integer>());
			blocks.add(currBlock);

			// pos = 0 case
			currBlock.get(0).add( optAln[block][0][0] );
			currBlock.get(1).add( (optAln[block][1][0]+cp ) % ca2len);

			for(int pos = 1; pos < optLen[block]; pos++) {
				//check if we need to start a new block
				//this happens when the new alignment crosses the protein terminus
				if( optAln[block][1][pos-1]+cp<ca2len &&
						optAln[block][1][pos]+cp >= ca2len) {
					currBlock = new ArrayList<List<Integer>>(2);
					currBlock.add( new ArrayList<Integer>());
					currBlock.add( new ArrayList<Integer>());
					blocks.add(currBlock);
				}
				currBlock.get(0).add( optAln[block][0][pos] );
				currBlock.get(1).add( (optAln[block][1][pos]+cp ) % ca2len);
			}
		}

		// save permuted blocks to afpChain
		assignOptAln(afpChain,blocks);
	}
297055
def pw_score_cosine(self, s1 : ClassId, s2 : ClassId) -> SimScore:
        
        df = self.assoc_df
        slice1 = df.loc[s1].values
        slice2 = df.loc[s2].values
        return 1 - cosine(slice1, slice2)
171431
public void set( Point2D_F64 p1 , Point2D_F64 p2 ) {
		this.p1.set(p1);
		this.p2.set(p2);
	}
1123537
@Override
    protected double scoreImpl(List<Word> words1, List<Word> words2) {
        if(words1.isEmpty() && words2.isEmpty()){
            return 1.0;
        }
        //转变为不重复的集合
        Set<Word> words1Set = new HashSet<>(words1);
        Set<Word> words2Set = new HashSet<>(words2);
        // 两个集合的大小
        int set1Size = words1Set.size();
        int set2Size = words2Set.size();

        // 求交集（去重），计算交集的不重复词的个数
        words1Set.retainAll(words2Set);
        int intersectionSize = words1Set.size();

        //相似度分值
        double score = 2*intersectionSize / (double)(set1Size+set2Size);
        if(LOGGER.isDebugEnabled()) {
            LOGGER.debug("集合1：" + words1);
            LOGGER.debug("集合2：" + words2);
            LOGGER.debug("集合1的大小：" + set1Size);
            LOGGER.debug("集合2的大小：" + set2Size);
            LOGGER.debug("交集的大小：" + intersectionSize);
            LOGGER.debug("相似度分值=2*" + intersectionSize + "/(double)(" + set1Size + "+" + set2Size + ")=" + score);
        }
        return score;
    }
1051020
@Override
    public DescriptorValue calculate(IAtomContainer container) {
        if (!GeometryUtil.has3DCoordinates(container))
            return getDummyDescriptorValue(new CDKException("Molecule must have 3D coordinates"));

        IsotopeFactory factory = null;
        double mass1;
        double mass2;
        try {
            factory = Isotopes.getInstance();
        } catch (Exception e) {
            logger.debug(e);
        }

        double sum = 0;
        for (int i = 0; i < container.getBondCount(); i++) {
            IBond bond = container.getBond(i);

            if (bond.getAtomCount() != 2) {
                return getDummyDescriptorValue(new CDKException("GravitationalIndex: Only handles 2 center bonds"));
            }

            mass1 = factory.getMajorIsotope(bond.getBegin().getSymbol()).getMassNumber();
            mass2 = factory.getMajorIsotope(bond.getEnd().getSymbol()).getMassNumber();

            Point3d p1 = bond.getBegin().getPoint3d();
            Point3d p2 = bond.getEnd().getPoint3d();

            double x1 = p1.x;
            double y1 = p1.y;
            double z1 = p1.z;
            double x2 = p2.x;
            double y2 = p2.y;
            double z2 = p2.z;

            double dist = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) + (z1 - z2) * (z1 - z2);
            sum += (mass1 * mass2) / dist;
        }

        // heavy atoms only
        double heavysum = 0;
        for (int i = 0; i < container.getBondCount(); i++) {
            IBond b = container.getBond(i);

            if (b.getAtomCount() != 2) {
                return getDummyDescriptorValue(new CDKException("GravitationalIndex: Only handles 2 center bonds"));
            }

            if (b.getBegin().getSymbol().equals("H") || b.getEnd().getSymbol().equals("H")) continue;

            mass1 = factory.getMajorIsotope(b.getBegin().getSymbol()).getMassNumber();
            mass2 = factory.getMajorIsotope(b.getEnd().getSymbol()).getMassNumber();

            Point3d point0 = b.getBegin().getPoint3d();
            Point3d point1 = b.getEnd().getPoint3d();

            double x1 = point0.x;
            double y1 = point0.y;
            double z1 = point0.z;
            double x2 = point1.x;
            double y2 = point1.y;
            double z2 = point1.z;

            double dist = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) + (z1 - z2) * (z1 - z2);
            heavysum += (mass1 * mass2) / dist;
        }

        // all pairs
        ArrayList<Integer> x = new ArrayList<Integer>();
        for (int i = 0; i < container.getAtomCount(); i++) {
            if (!container.getAtom(i).getSymbol().equals("H")) x.add(i);
        }
        int npair = x.size() * (x.size() - 1) / 2;
        pair[] p = new pair[npair];
        for (int i = 0; i < npair; i++)
            p[i] = new pair();
        int pcount = 0;
        for (int i = 0; i < x.size() - 1; i++) {
            for (int j = i + 1; j < x.size(); j++) {
                int present = 0;
                int a = x.get(i);
                int b = x.get(j);
                for (int k = 0; k < pcount; k++) {
                    if ((p[k].x == a && p[k].y == b) || (p[k].y == a && p[k].x == b)) present = 1;
                }
                if (present == 1) continue;
                p[pcount].x = a;
                p[pcount].y = b;
                pcount += 1;
            }
        }
        double allheavysum = 0;
        for (pair aP : p) {
            int atomNumber1 = aP.x;
            int atomNumber2 = aP.y;

            mass1 = factory.getMajorIsotope(container.getAtom(atomNumber1).getSymbol()).getMassNumber();
            mass2 = factory.getMajorIsotope(container.getAtom(atomNumber2).getSymbol()).getMassNumber();

            double x1 = container.getAtom(atomNumber1).getPoint3d().x;
            double y1 = container.getAtom(atomNumber1).getPoint3d().y;
            double z1 = container.getAtom(atomNumber1).getPoint3d().z;
            double x2 = container.getAtom(atomNumber2).getPoint3d().x;
            double y2 = container.getAtom(atomNumber2).getPoint3d().y;
            double z2 = container.getAtom(atomNumber2).getPoint3d().z;

            double dist = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) + (z1 - z2) * (z1 - z2);
            allheavysum += (mass1 * mass2) / dist;
        }

        DoubleArrayResult retval = new DoubleArrayResult(9);
        retval.add(heavysum);
        retval.add(Math.sqrt(heavysum));
        retval.add(Math.pow(heavysum, 1.0 / 3.0));

        retval.add(sum);
        retval.add(Math.sqrt(sum));
        retval.add(Math.pow(sum, 1.0 / 3.0));

        retval.add(allheavysum);
        retval.add(Math.sqrt(allheavysum));
        retval.add(Math.pow(allheavysum, 1.0 / 3.0));

        return new DescriptorValue(getSpecification(), getParameterNames(), getParameters(), retval,
                getDescriptorNames());
    }
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;

	}
1013232
@Override
    public DescriptorValue calculate(IAtomContainer container) {
        if (!GeometryUtil.has3DCoordinates(container))
            return getDummyDescriptorValue(new CDKException("Molecule must have 3D coordinates"));

        IAtomContainer clone;
        IsotopeFactory factory;
        try {
            clone = (IAtomContainer) container.clone();
            factory = Isotopes.getInstance();
            factory.configureAtoms(clone);
        } catch (CloneNotSupportedException | IOException e) {
            logger.debug(e);
            return getDummyDescriptorValue(e);
        }

        DoubleArrayResult retval = new DoubleArrayResult(7);

        double ccf = 1.000138;
        double eps = 1e-5;

        double[][] imat = new double[3][3];
        Point3d centerOfMass = GeometryUtil.get3DCentreOfMass(clone);

        double xdif;
        double ydif;
        double zdif;
        double xsq;
        double ysq;
        double zsq;
        for (int i = 0; i < clone.getAtomCount(); i++) {
            IAtom currentAtom = clone.getAtom(i);

            Double mass = factory.getMajorIsotope(currentAtom.getSymbol()).getExactMass();
            if (mass == null)
                mass = factory.getNaturalMass(currentAtom);

            xdif = currentAtom.getPoint3d().x - centerOfMass.x;
            ydif = currentAtom.getPoint3d().y - centerOfMass.y;
            zdif = currentAtom.getPoint3d().z - centerOfMass.z;
            xsq = xdif * xdif;
            ysq = ydif * ydif;
            zsq = zdif * zdif;

            imat[0][0] += mass * (ysq + zsq);
            imat[1][1] += mass * (xsq + zsq);
            imat[2][2] += mass * (xsq + ysq);

            imat[1][0] += -1 * mass * ydif * xdif;
            imat[0][1] = imat[1][0];

            imat[2][0] += -1 * mass * xdif * zdif;
            imat[0][2] = imat[2][0];

            imat[2][1] += -1 * mass * ydif * zdif;
            imat[1][2] = imat[2][1];
        }

        // diagonalize the MI tensor
        Matrix tmp = new Matrix(imat);
        EigenvalueDecomposition eigenDecomp = tmp.eig();
        double[] eval = eigenDecomp.getRealEigenvalues();

        retval.add(eval[2]);
        retval.add(eval[1]);
        retval.add(eval[0]);

        double etmp = eval[0];
        eval[0] = eval[2];
        eval[2] = etmp;

        if (Math.abs(eval[1]) > 1e-3)
            retval.add(eval[0] / eval[1]);
        else
            retval.add(1000);

        if (Math.abs(eval[2]) > 1e-3) {
            retval.add(eval[0] / eval[2]);
            retval.add(eval[1] / eval[2]);
        } else {
            retval.add(1000);
            retval.add(1000);
        }

        // finally get the radius of gyration
        double pri;
        IMolecularFormula formula = MolecularFormulaManipulator.getMolecularFormula(clone);
        if (Math.abs(eval[2]) > eps)
            pri = Math.pow(eval[0] * eval[1] * eval[2], 1.0 / 3.0);
        else
            pri = Math.sqrt(eval[0] * ccf / MolecularFormulaManipulator.getTotalExactMass(formula));
        retval.add(Math.sqrt(Math.PI * 2 * pri * ccf / MolecularFormulaManipulator.getTotalExactMass(formula)));

        return new DescriptorValue(getSpecification(), getParameterNames(), getParameters(), retval,
                getDescriptorNames());
    }
28173
public static final Structure getAlignedStructure(Atom[] ca1, Atom[] ca2) throws StructureException{

		/* Previous implementation commented

		Structure s = new StructureImpl();


		List<Chain>model1 = getAlignedModel(ca1);
		List<Chain>model2 = getAlignedModel(ca2);
		s.addModel(model1);
		s.addModel(model2);

		return s;*/

		Structure s = new StructureImpl();

		List<Chain>model1 = getAlignedModel(ca1);
		s.addModel(model1);
		List<Chain> model2 = getAlignedModel(ca2);
		s.addModel(model2);

		return s;
	}
383119
public int calculateScore(AlignmentScoring<S> scoring) {
        return AlignmentUtils.calculateScore(sequence1, sequence1Range, mutations, scoring);
    }
1367916
@Override
    public DescriptorValue calculate(IBond bond, IAtomContainer atomContainer) {
        double value = 0;
        // FIXME: for now I'll cache a few modified atomic properties, and restore them at the end of this method
        String originalAtomtypeName1 = bond.getBegin().getAtomTypeName();
        Integer originalNeighborCount1 = bond.getBegin().getFormalNeighbourCount();
        IAtomType.Hybridization originalHybridization1 = bond.getBegin().getHybridization();
        Integer originalValency1 = bond.getBegin().getValency();
        String originalAtomtypeName2 = bond.getEnd().getAtomTypeName();
        Integer originalNeighborCount2 = bond.getEnd().getFormalNeighbourCount();
        IAtomType.Hybridization originalHybridization2 = bond.getEnd().getHybridization();
        Integer originalValency2 = bond.getEnd().getValency();
        Double originalBondOrderSum1 = bond.getBegin().getBondOrderSum();
        Order originalMaxBondOrder1 = bond.getBegin().getMaxBondOrder();
        Double originalBondOrderSum2 = bond.getEnd().getBondOrderSum();
        Order originalMaxBondOrder2 = bond.getEnd().getMaxBondOrder();

        if (!isCachedAtomContainer(atomContainer)) {
            try {
                AtomContainerManipulator.percieveAtomTypesAndConfigureAtoms(atomContainer);
                LonePairElectronChecker lpcheck = new LonePairElectronChecker();
                lpcheck.saturate(atomContainer);
            } catch (CDKException e) {
                return getDummyDescriptorValue(e);
            }

        }
        if (!bond.getOrder().equals(IBond.Order.SINGLE)) {
            try {
                value = IonizationPotentialTool.predictIP(atomContainer, bond);
            } catch (CDKException e) {
                return getDummyDescriptorValue(e);
            }
        }
        bond.getBegin().setAtomTypeName(originalAtomtypeName1);
        bond.getBegin().setHybridization(originalHybridization1);
        bond.getBegin().setValency(originalValency1);
        bond.getBegin().setFormalNeighbourCount(originalNeighborCount1);
        bond.getEnd().setAtomTypeName(originalAtomtypeName2);
        bond.getEnd().setHybridization(originalHybridization2);
        bond.getEnd().setValency(originalValency2);
        bond.getEnd().setFormalNeighbourCount(originalNeighborCount2);
        bond.getBegin().setMaxBondOrder(originalMaxBondOrder1);
        bond.getBegin().setBondOrderSum(originalBondOrderSum1);
        bond.getEnd().setMaxBondOrder(originalMaxBondOrder2);
        bond.getEnd().setBondOrderSum(originalBondOrderSum2);

        return new DescriptorValue(getSpecification(), getParameterNames(), getParameters(), new DoubleResult(value),
                DESCRIPTOR_NAMES);
    }