public static void main(String[] args) throws MinimizerException, LineSearchException {
   init(args);
   CommandList commands = new CommandList(commandsFileName);
   Protein prot = new Protein(new AtomList(modelFileName), new ResidueExtendedAtoms(ADD_ATOMS));
   for (int cc = 0; cc < prot.atoms().size(); cc++) prot.atoms().atomAt(cc).setChain(" ");
   PutHydrogens.adjustHydrogens(commands, prot);
   AtomList shiftedList = createShiftedThreading(commands, prot, delta);
   try {
     shiftedList.print(new MeshiWriter(outputFileName));
   } catch (Exception e) {
     System.out.print("\nThere was a problem writing the PDB:\n" + e + "\n\nContinuing...\n\n");
   }
 }
  public static AtomList createShiftedThreading(CommandList commands, Protein prot, int delta) {
    AtomList newList = new AtomList();
    Protein newProt;
    DistanceMatrix dm;
    DunbrackLib lib = new DunbrackLib(commands, 1.0, 90);

    // Copying the coordiantes to the new atoms.
    for (int resNum =
            Math.max(
                prot.residues().firstNonDummyResidueNumber(),
                prot.residues().firstNonDummyResidueNumber() - delta);
        resNum
            <= Math.min(
                ((Residue) prot.residues().last()).number,
                ((Residue) prot.residues().last()).number - delta);
        resNum++) {
      Atom atom = prot.atoms().findAtomInList("N", resNum + delta);
      if (atom != null) {
        Atom newAtom =
            new Atom(
                atom.x(),
                atom.y(),
                atom.z(),
                "N",
                prot.residue(resNum).nameThreeLetters(),
                resNum,
                -1);
        newList.add(newAtom);
      }
      atom = prot.atoms().findAtomInList("CA", resNum + delta);
      if (atom != null) {
        Atom newAtom =
            new Atom(
                atom.x(),
                atom.y(),
                atom.z(),
                "CA",
                prot.residue(resNum).nameThreeLetters(),
                resNum,
                -1);
        newList.add(newAtom);
      }
      atom = prot.atoms().findAtomInList("C", resNum + delta);
      if (atom != null) {
        Atom newAtom =
            new Atom(
                atom.x(),
                atom.y(),
                atom.z(),
                "C",
                prot.residue(resNum).nameThreeLetters(),
                resNum,
                -1);
        newList.add(newAtom);
      }
      atom = prot.atoms().findAtomInList("O", resNum + delta);
      if (atom != null) {
        Atom newAtom =
            new Atom(
                atom.x(),
                atom.y(),
                atom.z(),
                "O",
                prot.residue(resNum).nameThreeLetters(),
                resNum,
                -1);
        newList.add(newAtom);
      }
      atom = prot.atoms().findAtomInList("H", resNum + delta);
      if (atom != null) {
        Atom newAtom =
            new Atom(
                atom.x(),
                atom.y(),
                atom.z(),
                "H",
                prot.residue(resNum).nameThreeLetters(),
                resNum,
                -1);
        newList.add(newAtom);
      }
    }

    // Filling the atoms
    newProt = new Protein(newList, new ResidueExtendedAtoms(ADD_ATOMS));

    // adjusting hydrogens and SCMODing
    dm = new DistanceMatrix(newProt.atoms(), 5.5, 2.0, 4);
    double[][] pp = RotamericTools.putIntoRot1(newProt, dm, lib);
    PutHydrogens.adjustHydrogens(commands, prot);
    newProt.defrost();
    try {
      newProt.atoms().print(new MeshiWriter(outputFileName + ".rot1.pdb"));
    } catch (Exception e) {
      System.out.print("\nThere was a problem writing the PDB:\n" + e + "\n\nContinuing...\n\n");
    }
    SCMOD.scmod(commands, lib, newProt, 2, 0.0, pp);

    // Final minimzation
    EnergyCreator[] energyCreators = {
      new BondCreator(1.0),
      new AngleCreator(1.0),
      new PlaneCreator(10.0),
      new OutOfPlaneCreator(1.0),
      new LennardJonesCreator(0.4),
      new SimpleHydrogenBond_Dahiyat_HighAccuracy_Creator(3.0),
      new RamachandranSidechainEnergyCreator(1.0)
    };

    newProt.atoms().freeze(new AtomList.BackboneFilter());
    dm = new DistanceMatrix(newProt.atoms(), 5.5, 2.0, 4);
    TotalEnergy energy = new TotalEnergy(newProt, dm, energyCreators, commands);
    Minimizer minimizer = new LBFGS(energy, 0.001, 50000, 1000);
    try {
      System.out.println(minimizer.minimize());
    } catch (Exception e) {
      throw new RuntimeException("ERROR in minimization");
    }

    // printing a LJ values histogram - Start
    // --------------------------------------
    double firstBin = -1.0;
    double lastBin = 4.0;
    double binSpacing = 0.05;
    int[] bins = new int[(int) Math.ceil((lastBin - firstBin) / binSpacing)];
    for (int c = 0; c < bins.length; c++) bins[c] = 0;
    energy.resetAtomEnergies();
    LennardJones lj = (LennardJones) energy.getEnergyTerm(new LennardJones());
    lj.evaluateAtoms();
    double Elj = 0.0;
    int ind = 0;
    for (int at = 0; at < newProt.atoms().size(); at++) {
      Elj = newProt.atoms().atomAt(at).energy();
      ind = (int) Math.round((Elj - firstBin) / binSpacing);
      if (ind < 0) ind = 0;
      if (ind >= bins.length) ind = bins.length - 1;
      bins[ind]++;
    }
    Elj = firstBin;
    for (int c = 0; c < bins.length; c++) {
      System.out.println("000 " + Elj + " " + bins[c]);
      Elj += binSpacing;
    }
    // --------------------------------------
    // printing the LJ values histogram - END

    return newProt.atoms();
  }
  public static void main(String[] args) {
    init(args);

    Protein model = new ExtendedAtomsProtein(modelFileName, DO_NOT_ADD_ATOMS);
    boolean[] goodRes = new boolean[model.residues().size() + 1];
    for (int c = 0; c < goodRes.length; c++) goodRes[c] = false;
    Protein compareTo = new ExtendedAtomsProtein(compareToFileName, DO_NOT_ADD_ATOMS);
    String[] gaps = File2StringArray.f2a(gapsFileName);
    for (int gapC = 0; gapC < gaps.length; gapC++) {
      StringTokenizer st = new StringTokenizer(gaps[gapC]);
      int gapFrom = (new Integer(st.nextToken())).intValue();
      int gapTo = (new Integer(st.nextToken())).intValue();
      for (int predC = 0; predC < NumPredToConsider; predC++) {
        if ((new File(loopDirPath + "/Loop_" + gapFrom + "_" + gapTo + "/phase2/" + predC + ".pdb"))
            .exists()) {
          boolean[] goodInLoop = new boolean[gapTo + 1];
          AtomList gapAtoms =
              new AtomList(
                  loopDirPath + "/Loop_" + gapFrom + "_" + gapTo + "/phase2/" + predC + ".pdb");
          // Finding consistent atoms between loop and the 'compareTo' protein
          for (int resInLoop = gapFrom; resInLoop <= gapTo; resInLoop++) {
            if (compareTo.atoms().findAtomInList("CA", resInLoop) == null) {
              goodInLoop[resInLoop] = false;
            } else {
              goodInLoop[resInLoop] = false;
              if (compareTo.atoms().findAtomInList("CB", resInLoop) != null) { // NOT a Glycin
                if ((compareTo
                            .atoms()
                            .findAtomInList("CA", resInLoop)
                            .distanceFrom(gapAtoms.findAtomInList("CA", resInLoop))
                        < goodCutoff)
                    && (compareTo
                            .atoms()
                            .findAtomInList("CB", resInLoop)
                            .distanceFrom(gapAtoms.findAtomInList("CB", resInLoop))
                        < goodCutoff)) {
                  goodInLoop[resInLoop] = true;
                } else {
                  goodInLoop[resInLoop] = false;
                }
              } else {
                if (compareTo
                        .atoms()
                        .findAtomInList("CA", resInLoop)
                        .distanceFrom(gapAtoms.findAtomInList("CA", resInLoop))
                    < goodCutoff) {
                  goodInLoop[resInLoop] = true;
                } else {
                  goodInLoop[resInLoop] = false;
                }
              }
            }
          }

          // Analyzing data - is there a consistent pattern between the loops and the 'compareTo'
          // Protein.
          for (int resInLoop = gapFrom + 4; resInLoop <= (gapTo - 4); resInLoop++) {
            if (goodInLoop[resInLoop - 1] && goodInLoop[resInLoop] && goodInLoop[resInLoop + 1]) {
              goodRes[resInLoop - 1] = true;
              goodRes[resInLoop] = true;
              goodRes[resInLoop + 1] = true;
              System.out.println(
                  "The residues "
                      + (resInLoop - 1)
                      + " "
                      + (resInLoop)
                      + " "
                      + (resInLoop + 1)
                      + " were indicated by model "
                      + predC
                      + " from loop: "
                      + gapFrom
                      + "_"
                      + gapTo);
            }
          }
        }
      }
    }

    AtomList finalList = new AtomList();
    for (int c = 0; c < compareTo.atoms().size(); c++) {
      if (goodRes[compareTo.atoms().atomAt(c).residueNumber()])
        finalList.add(compareTo.atoms().atomAt(c));
    }

    try {
      finalList.print(new MeshiWriter(modelFileName + ".common.pdb"));
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }