1 /*
2  *  The Janocchio program is (C) 2007 Eli Lilly and Co.
3  *  Authors: David Evans and Gary Sharman
4  *  Contact : janocchio-users@lists.sourceforge.net.
5  *
6  *  It is derived in part from Jmol
7  *  (C) 2002-2006 The Jmol Development Team
8  *
9  *  This program is free software; you can redistribute it and/or
10  *  modify it under the terms of the GNU Lesser General Public License
11  *  as published by the Free Software Foundation; either version 2.1
12  *  of the License, or (at your option) any later version.
13  *  All we ask is that proper credit is given for our work, which includes
14  *  - but is not limited to - adding the above copyright notice to the beginning
15  *  of your source code files, and to any copyright notice that you may distribute
16  *  with programs based on this work.
17  *
18  *  This program is distributed in the hope that it will be useful, on an 'as is' basis,
19  *  WITHOUT ANY WARRANTY; without even the implied warranty of
20  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  *  GNU Lesser General Public License for more details.
22  *
23  *  You should have received a copy of the GNU Lesser General Public License
24  *  along with this program; if not, write to the Free Software
25  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
26  */
27 
28 package org.openscience.jmol.app.janocchio;
29 
30 import java.io.File;
31 import java.io.FileInputStream;
32 import java.io.FileOutputStream;
33 import java.io.FileWriter;
34 import java.io.IOException;
35 import java.io.PrintWriter;
36 import java.text.DecimalFormat;
37 import java.util.Hashtable;
38 import java.util.Map;
39 import java.util.Vector;
40 import java.util.zip.ZipEntry;
41 import java.util.zip.ZipOutputStream;
42 
43 import javajs.util.BS;
44 import javajs.util.Lst;
45 
46 import javax.swing.JCheckBoxMenuItem;
47 
48 import org.jmol.util.JSONWriter;
49 
50 public class LoadMeasureThreadJSON extends LoadMeasureThread {
51 
52   Map<String, Object> data;
53 
LoadMeasureThreadJSON(NMR_JmolPanel nmrPanel, Map<String, Object> jsonData)54   public LoadMeasureThreadJSON(NMR_JmolPanel nmrPanel,
55       Map<String, Object> jsonData) {
56     this.nmrPanel = nmrPanel;
57     this.data = jsonData;
58   }
59 
60   @SuppressWarnings("unchecked")
61   @Override
setMore()62   protected void setMore() {
63     if (!data.containsKey("NamfisPopulation"))
64       return;
65     Lst<Object> populations = (Lst<Object>) data.get("NamfisPopulation");
66     if (populations.size() > 0) {
67       int nmodel = ((NMR_Viewer) nmrPanel.vwr).getModelCount();
68       double[] population = new double[nmodel + 1];
69       for (int i = 0; i <= nmodel; i++) {
70         population[i] = 0.0;
71       }
72       for (int i = 0; i < populations.size(); i++) {
73         Map<String, Object> p = (Map<String, Object>) populations.get(i);
74         int index = getInt(p, "index");
75         double pop = getDouble(p, "p");
76         population[index] = pop;
77       }
78       nmrPanel.populationDisplay.addPopulation(population);
79       JCheckBoxMenuItem mi = (JCheckBoxMenuItem) nmrPanel
80           .getMenuItem("NMR.populationDisplayCheck");
81       mi.setSelected(true);
82     }
83   }
84 
85   @SuppressWarnings("unchecked")
86   @Override
setNOEs()87   protected void setNOEs() {
88     if (!data.containsKey("NOEs")) {
89       return;
90     }
91     Lst<Object> noes = (Lst<Object>) data.get("NOEs");
92     // Noes
93 
94     for (int i = 0; i < noes.size(); i++) {
95       Map<String, Object> noe = (Map<String, Object>) noes.get(i);
96       int ia = getInt(noe, "a");
97       int ib = getInt(noe, "b");
98       String exp = (String) noe.get("exp");
99       String expd = (String) noe.get("expd");
100       addNOE(ia, ib, exp, expd);
101     }
102     if (data.containsKey("RefNOE")) {
103       int[] noeNPrefIndices = new int[2];
104 
105       Map<String, Object> refNOE = (Map<String, Object>) data.get("RefNOE");
106       noeNPrefIndices[0] = getInt(refNOE, "a");
107       noeNPrefIndices[1] = getInt(refNOE, "b");
108       nmrPanel.noeTable.setNoeNPrefIndices(noeNPrefIndices);
109     }
110 
111     if (data.containsKey("ExpRefNOEValue")) {
112       double expRefValue = getDouble(data, "ExpRefNOEValue");
113       nmrPanel.noeTable.setNoeExprefValue(expRefValue);
114     }
115 
116     if (data.containsKey("CorrelationTime")) {
117       double dval = getDouble(data, "CorrelationTime");
118       nmrPanel.noeTable.setCorrelationTime(dval);
119       nmrPanel.noeTable.noeParameterSelectionPanel.getTauField().setText(
120           String.valueOf(dval));
121     }
122 
123     if (data.containsKey("MixingTime")) {
124       double dval = getDouble(data, "MixingTime");
125       nmrPanel.noeTable.setMixingTime(dval);
126       nmrPanel.noeTable.noeParameterSelectionPanel.gettMixField().setText(
127           String.valueOf(dval));
128     }
129 
130     if (data.containsKey("NMRfreq")) {
131       double dval = getDouble(data, "NMRfreq");
132       nmrPanel.noeTable.setNMRfreq(dval);
133       nmrPanel.noeTable.noeParameterSelectionPanel.getFreqField().setText(
134           String.valueOf(dval));
135     }
136 
137     if (data.containsKey("RhoStar")) {
138       double dval = getDouble(data, "RhoStar");
139       nmrPanel.noeTable.setRhoStar(dval);
140       nmrPanel.noeTable.noeParameterSelectionPanel.getRhoStarField().setText(
141           String.valueOf(dval));
142     }
143 
144     if (data.containsKey("NoeYellowValue")) {
145       double dval = getDouble(data, "NoeYellowValue");
146       nmrPanel.noeTable.setYellowValue(dval);
147       nmrPanel.noeTable.noeColourSelectionPanel.getYellowField().setText(
148           String.valueOf(dval));
149     }
150 
151     if (data.containsKey("NoeRedValue")) {
152       double dval = getDouble(data, "NoeRedValue");
153       nmrPanel.noeTable.setRedValue(dval);
154       nmrPanel.noeTable.noeColourSelectionPanel.getRedField().setText(
155           String.valueOf(dval));
156     }
157 
158     if (data.containsKey("CoupleYellowValue")) {
159       double dval = getDouble(data, "CoupleYellowValue");
160       nmrPanel.coupleTable.setYellowValue(dval);
161       nmrPanel.coupleTable.coupleColourSelectionPanel.getYellowField()
162           .setText(String.valueOf(dval));
163     }
164 
165     if (data.containsKey("CoupleRedValue")) {
166       double dval = getDouble(data, "CoupleRedValue");
167       nmrPanel.coupleTable.setRedValue(dval);
168       nmrPanel.coupleTable.coupleColourSelectionPanel.getRedField().setText(
169           String.valueOf(dval));
170     }
171 
172 
173   }
174 
175   @SuppressWarnings("unchecked")
176   @Override
setCouples()177   protected void setCouples() {
178     if (!data.containsKey("Couples"))
179       return;
180 
181       Lst<Object> couples = (Lst<Object>) data.get("Couples");
182       // Couples
183 
184       for (int i = 0; i < couples.size(); i++) {
185         Map<String, Object> couple = (Map<String, Object>) couples.get(i);
186         int ia = getInt(couple, "a");
187         int ib = getInt(couple, "b");
188         int ic = getInt(couple, "c");
189         int id = getInt(couple, "d");
190         String exp = (String) couple.get("exp");
191         addCouple(ia, ib, ic, id, exp);
192       }
193 
194   }
195 
196   @SuppressWarnings("unchecked")
197   @Override
setLabels()198   protected boolean setLabels() {
199     if (!data.containsKey("Labels"))
200       return false;
201     Lst<Object> labels = (Lst<Object>) data.get("Labels");
202     // labels
203     for (int i = 0; i < labels.size(); i++) {
204       Map<String, Object> label = (Map<String, Object>) labels.get(i);
205 
206       int j = getInt(label, "index");
207       String l = (String) label.get("label");
208       addCommand(j - 1, l);
209     }
210     return true;
211   }
212 
getDouble(Map<String, Object> p, String key)213   private double getDouble(Map<String, Object> p, String key) {
214     return ((Number) p.get(key)).doubleValue();
215   }
216 
getInt(Map<String, Object> noe, String key)217   private static int getInt(Map<String, Object> noe, String key) {
218     return ((Number) noe.get(key)).intValue();
219   }
220 
221   @SuppressWarnings("unchecked")
writeNamfisFiles(String name)222   public void writeNamfisFiles(String name) {
223 
224     /*
225      * Namfis file .in1 contains the calculated distances and J's for each conformer
226      * .in2 contains the experimental measurements and uncertainties
227      */
228 
229     File namfis1 = new File(name + ".in1");
230     File namfis2 = new File(name + ".in2");
231     File namfis3 = new File(name + ".in3");
232     File namfisout = new File(name + ".out");
233     String parent = namfis1.getParent();
234     File filename = new File(parent + "/filename.dat");
235     File optionfile = new File(parent + "/optionfile");
236     String zipFileName = name + ".zip";
237 
238     Map<String, Object> nmrdata;
239     Lst<Object> noes = new Lst<Object>();
240     Lst<Object> couples = new Lst<Object>();
241     try {
242       nmrdata = getNmrDataJSON();
243       noes = (Lst<Object>) nmrdata.get("NOEs");
244       couples = (Lst<Object>) nmrdata.get("Couples");
245     } catch (Exception e) {
246       //
247       nmrdata = new Hashtable<String, Object>();
248     }
249 
250     try {
251       BS[] mols = nmrPanel.getAllMolecules();
252       PrintWriter out1 = new PrintWriter(new FileWriter(namfis1));
253       String[] labelArray = nmrPanel.labelSetter.getLabelArray();
254       for (int base = 0, i = 0; i < mols.length; base += mols[i].cardinality(), i++) {
255         NmrMolecule props = nmrPanel.getDistanceJMolecule(mols[i],
256             labelArray, true);
257         props.calcNOEs();
258 
259         for (int n = 0; n < noes.size(); n++) {
260           Map<String, Object> noe = (Map<String, Object>) noes.get(n);
261           String a = (String) noe.get("a");
262           String b = (String) noe.get("b");
263 
264           if (noe.containsKey("expd")) {
265             String exp = (String) noe.get("expd");
266             if (exp != null) {
267               int j = (new Integer(a)).intValue() - 1;
268               int k = (new Integer(b)).intValue() - 1;
269               props.addJmolDistance(j + base, k + base);
270             }
271           }
272         }
273 
274         for (int n = 0; n < couples.size(); n++) {
275           Map<String, Object> couple = (Map<String, Object>) couples.get(n);
276           String a = (String) couple.get("a");
277           String b = (String) couple.get("b");
278           String c = (String) couple.get("c");
279           String d = (String) couple.get("d");
280           if (couple.containsKey("exp")) {
281             String exp = (String) couple.get("exp");
282             if (exp != null) {
283               int j = (new Integer(a)).intValue() - 1;
284               int k = (new Integer(b)).intValue() - 1;
285               int l = (new Integer(c)).intValue() - 1;
286               int m = (new Integer(d)).intValue() - 1;
287               props.addJmolCouple(j + base, k + base, l + base, m + base);
288             }
289           }
290         }
291         // NAMFIS has problems on some systems if there are zero noes or couplings
292         // Always add dummy variable
293         Vector<Double> vec = props.getDistances();
294         vec.add(new Double(1.0));
295         writeVector(vec, out1);
296 
297         vec = props.getCouples();
298         vec.add(new Double(1.0));
299         writeVector(vec, out1);
300 
301       }
302       out1.flush();
303       out1.close();
304 
305       PrintWriter out2 = new PrintWriter(new FileWriter(namfis2));
306       DecimalFormat df = new DecimalFormat("#0.00  ");
307       out2.print("-1\n");
308 
309       int nnoe = 0;
310       for (int i = 0; i < noes.size(); i++) {
311         Map<String, Object> noe = (Map<String, Object>) noes.get(i);
312         if (noe.containsKey("expd")) {
313           nnoe++;
314         }
315       }
316       int ncouple = 0;
317       for (int i = 0; i < couples.size(); i++) {
318         Map<String, Object> couple = (Map<String, Object>) couples.get(i);
319         if (couple.containsKey("exp")) {
320           ncouple++;
321         }
322       }
323 
324       // Add dummy variables
325       nnoe++;
326       ncouple++;
327 
328       // if (nnoe > 0) {
329       out2.print(ncouple + " " + nnoe + " 0\n");
330       for (int i = 0; i < noes.size(); i++) {
331         Map<String, Object> noe = (Map<String, Object>) noes.get(i);
332 
333         if (noe.containsKey("expd")) {
334           String exp = (String) noe.get("expd");
335           if (exp != null) {
336             out2.print(df.format(Double.valueOf(exp)) + " " + 0.4 + "\n");
337           }
338         }
339 
340       }
341       out2.print("1.0 0.4\n"); // Dummy variable
342       // }
343 
344       out2.print("\n");
345       for (int i = 0; i < couples.size(); i++) {
346         Map<String, Object> couple = (Map<String, Object>) couples.get(i);
347         if (couple.containsKey("exp")) {
348           String exp = (String) couple.get("exp");
349           out2.print(exp + " ");
350         }
351       }
352       out2.print(1.0); // Dummy variable
353       out2.print("\n");
354       for (int i = 0; i < couples.size(); i++) {
355         Map<String, Object> couple = (Map<String, Object>) couples.get(i);
356         if (couple.containsKey("exp")) {
357           out2.print(2.0 + " ");
358         }
359       }
360       out2.print(0.5); // Dummy variable
361 
362       out2.print("\n");
363       out2.print("\n");
364       out2.print("1.0 1.0\n");
365       out2.print("5.0\n");
366       out2.print("0\n");
367 
368       out2.flush();
369       out2.close();
370 
371       PrintWriter out3 = new PrintWriter(new FileWriter(namfis3));
372       out3.flush();
373       out3.close();
374 
375       PrintWriter out4 = new PrintWriter(new FileWriter(filename));
376       /*
377        * String head = name.replaceFirst(parent,""); head = head.replaceFirst("/","");
378        * out4.println(head + ".in1"); out4.println(head + ".in2"); out4.println(head +
379        * ".out"); out4.println(head + ".in3");
380        */
381       out4.print(namfis1.getName() + "\n");
382       out4.print(namfis2.getName() + "\n");
383       out4.print(namfisout.getName() + "\n");
384       out4.print(namfis3.getName() + "\n");
385       out4.flush();
386       out4.close();
387 
388       PrintWriter out5 = new PrintWriter(new FileWriter(optionfile));
389       out5.print("  Begin\n");
390       out5.print("    NoList\n");
391       out5.print("    Derivative level          3\n");
392       out5.print("    Verify                   No\n");
393       out5.print("    Infinite step size      1.0d+20\n");
394       out5.print("    step limit              1.0d-02\n");
395       out5.print("    Major iterations limit    200\n");
396       out5.print("    Minor iterations limit   2000\n");
397       out5.print("    Major print level         10\n");
398       out5.print("    Function precision        1.0d-20\n");
399       out5.print("    Optimality Tolerance      1.0d-20\n");
400       out5.print("    Linear Feasibility Tolerance 1.0d-2\n");
401       out5.print("  end\n");
402       out5.flush();
403       out5.close();
404 
405       // Write zip file
406 
407       Vector<String> inputFileNames = new Vector<String>();
408       inputFileNames.add(namfis1.getAbsolutePath());
409       inputFileNames.add(namfis2.getAbsolutePath());
410       inputFileNames.add(namfis3.getAbsolutePath());
411       inputFileNames.add(filename.getAbsolutePath());
412       inputFileNames.add(optionfile.getAbsolutePath());
413 
414       writeZip(inputFileNames, zipFileName);
415     } catch (Exception e) {
416       //
417       e.printStackTrace();
418     }
419   }
420 
writeVector(Vector<?> vector, PrintWriter out)421   private void writeVector(Vector<?> vector, PrintWriter out) {
422     DecimalFormat df = new DecimalFormat("0.000  ");
423     int count = 0;
424     for (int j = 0; j < vector.size(); j++) {
425       out.print(df.format(vector.get(j)));
426       if (count++ == 10) {
427         out.print("\n");
428         count = 0;
429       }
430     }
431     if (count != 0) {
432       out.print("\n");
433     }
434   }
435 
writeZip(Vector<String> v, String outFilename)436   private void writeZip(Vector<String> v, String outFilename) {
437     // Create a buffer for reading the files
438     byte[] buf = new byte[2048];
439     try {
440       // Create the ZIP file
441       ZipOutputStream out = new ZipOutputStream(new FileOutputStream(
442           outFilename));
443       // Compress the files
444       for (int i = 0; i < v.size(); i++) {
445         FileInputStream in = new FileInputStream(v.get(i));
446 
447         // Add ZIP entry to output stream.
448         out.putNextEntry(new ZipEntry(v.get(i)));
449 
450         // Transfer bytes from the file to the ZIP file
451         int len;
452         while ((len = in.read(buf)) > 0) {
453           out.write(buf, 0, len);
454         }
455 
456         // Complete the entry
457         out.closeEntry();
458         in.close();
459       }
460       // Complete the ZIP file
461       out.close();
462     } catch (IOException e) {
463       System.out.println("Error Writing zip....");
464       e.printStackTrace();
465     }
466   }
467 
writeNmrDataJSON(File file)468   public void writeNmrDataJSON(File file) throws Exception {
469     JSONWriter writer = new JSONWriter();
470     writer.setStream(new FileOutputStream(file));
471     writer.writeMap(getNmrDataJSON());
472     writer.closeStream();
473   }
474 
475   @SuppressWarnings("boxing")
getNmrDataJSON()476   public Map<String, Object> getNmrDataJSON() {
477     Map<String, Object> data = new Hashtable<String, Object>();
478     data.put("StructureFile", nmrPanel.vwr.getModelSetPathName());
479 
480     Lst<Object> labels = new Lst<Object>();
481     String[] labelArray = nmrPanel.labelSetter.getLabelArray();
482     for (int i = 0; i < labelArray.length; i++) {
483       if (labelArray[i] != null) {
484         Map<String, Object> l = new Hashtable<String, Object>();
485         l.put("index", String.valueOf(i + 1));
486         l.put("label", labelArray[i]);
487         labels.addLast(l);
488       }
489     }
490     data.put("Labels", labels);
491 
492     NoeTable noeTable = nmrPanel.noeTable;
493 
494     Lst<Object> noes = new Lst<Object>();
495     int noeCount = noeTable.getRowCount();
496     for (int i = 0; i < noeCount; i++) {
497       int[] atomIndices = noeTable.getMeasurementCountPlusIndices(i);
498       Map<String, Object> n = new Hashtable<String, Object>();
499       n.put("a", String.valueOf(atomIndices[1] + 1));
500       n.put("b", String.valueOf(atomIndices[2] + 1));
501       n.put("exp", noeTable.getExpNoe(atomIndices[1], atomIndices[2]));
502       n.put("expd", noeTable.getExpDist(atomIndices[1], atomIndices[2]));
503 
504       noes.addLast(n);
505     }
506     data.put("NOEs", noes);
507 
508     CoupleTable coupleTable = nmrPanel.coupleTable;
509 
510     int coupleCount = coupleTable.getRowCount();
511     Lst<Object> couples = new Lst<Object>();
512     for (int i = 0; i < coupleCount; i++) {
513       int[] atomIndices = coupleTable.getMeasurementCountPlusIndices(i);
514       Map<String, Object> c = new Hashtable<String, Object>();
515       c.put("a", String.valueOf(atomIndices[1] + 1));
516       c.put("b", String.valueOf(atomIndices[2] + 1));
517       c.put("c", String.valueOf(atomIndices[3] + 1));
518       c.put("d", String.valueOf(atomIndices[4] + 1));
519       c.put("exp", coupleTable.getExpCouple(atomIndices[1], atomIndices[4]));
520       couples.addLast(c);
521     }
522     data.put("Couples", couples);
523 
524     int[] noeNPrefIndices = noeTable.getnoeNPrefIndices();
525     Map<String, Object> refNOE = new Hashtable<String, Object>();
526     refNOE.put("a", new Integer(noeNPrefIndices[0]));
527     refNOE.put("b", new Integer(noeNPrefIndices[1]));
528     data.put("RefNOE", refNOE);
529 
530     double noeExprefValue = noeTable.getNoeExprefValue();
531     data.put("ExpRefNOEValue", Double.toString(noeExprefValue));
532 
533     data.put("CorrelationTime", Double.toString(noeTable.getCorrelationTime()));
534     data.put("MixingTime", Double.toString(noeTable.getMixingTime()));
535     data.put("NMRfreq", Double.toString(noeTable.getNMRfreq()));
536     data.put("Cutoff", Double.toString(noeTable.getCutoff()));
537     data.put("RhoStar", Double.toString(noeTable.getRhoStar()));
538 
539     data.put("NoeRedValue", Double.toString(noeTable.getRedValue()));
540     data.put("NoeYellowValue", Double.toString(noeTable.getYellowValue()));
541 
542     data.put("CoupleRedValue", Double.toString(coupleTable.getRedValue()));
543     data.put("CoupleYellowValue", Double.toString(coupleTable.getYellowValue()));
544 
545     double[] population = nmrPanel.populationDisplay.getPopulation();
546     int populationLength = 0;
547     if (population != null) {
548       populationLength = population.length;
549     }
550 
551     Lst<Object> populations = new Lst<Object>();
552     for (int i = 0; i < populationLength; i++) {
553       if (population[i] > 0.0) {
554         Map<String, Object> p = new Hashtable<String, Object>();
555         p.put("index", i);
556         p.put("p", String.valueOf(population[i]));
557         populations.addLast(p);
558       }
559 
560     }
561     data.put("NamfisPopulation", populations);
562 
563     return data;
564   }
565 
566   @SuppressWarnings("unchecked")
jumpBestFrame()567   public int jumpBestFrame() {
568 
569     Map<String, Object> nmrdata = new LoadMeasureThreadJSON(nmrPanel, null)
570         .getNmrDataJSON();
571 
572     Lst<Object> noes = (Lst<Object>) nmrdata.get("NOEs");
573     Lst<Object> couples = (Lst<Object>) nmrdata.get("Couples");
574     try {
575       BS[] mols = nmrPanel.getAllMolecules();
576       String[] labelArray = nmrPanel.labelSetter.getLabelArray();
577       double noeWeight = nmrPanel.frameDeltaDisplay.getNoeWeight();
578       double coupleWeight = nmrPanel.frameDeltaDisplay.getCoupleWeight();
579       boolean lexpNoes = nmrPanel.noeTable.getlexpNoes();
580       double minDiff = Double.MAX_VALUE;
581       int minFrame = -1;
582       for (int base = 0, i = 0; i < mols.length; base += mols[i].cardinality(), i++) {
583         NmrMolecule props = nmrPanel.getDistanceJMolecule(mols[i],
584             labelArray, true);
585         props.calcNOEs();
586         double diffDist = 0.0;
587         double diffNoe = 0.0;
588         double diffCouple = 0.0;
589         for (int n = 0; n < noes.size(); n++) {
590           Map<String, Object> noe = (Map<String, Object>) noes.get(n);
591           String a = (String) noe.get("a");
592           String b = (String) noe.get("b");
593 
594           if (noe.containsKey("expd")) {
595             String exp = (String) noe.get("expd");
596             if (exp != null) {
597               int j = (new Integer(a)).intValue() - 1;
598               int k = (new Integer(b)).intValue() - 1;
599               double cDist = props.getJmolDistance(j + base, k + base);
600               MeasureDist measure = new MeasureDist(exp, cDist);
601               diffDist += measure.getDiff();
602             }
603           }
604           if (noe.containsKey("exp")) {
605             String exp = (String) noe.get("exp");
606             if (exp != null) {
607               int j = (new Integer(a)).intValue() - 1;
608               int k = (new Integer(b)).intValue() - 1;
609               double cNoe = props.getJmolNoe(j + base, k + base);
610               MeasureNoe measure = new MeasureNoe(exp, cNoe);
611               diffNoe += measure.getDiff();
612             }
613           }
614         }
615 
616         for (int n = 0; n < couples.size(); n++) {
617           Map<String, Object> couple = (Map<String, Object>) couples.get(n);
618           String a = (String) couple.get("a");
619           String b = (String) couple.get("b");
620           String c = (String) couple.get("c");
621           String d = (String) couple.get("d");
622           if (couple.containsKey("exp")) {
623             String exp = (String) couple.get("exp");
624             if (exp != null) {
625               int j = (new Integer(a)).intValue() - 1;
626               int k = (new Integer(b)).intValue() - 1;
627               int l = (new Integer(c)).intValue() - 1;
628               int m = (new Integer(d)).intValue() - 1;
629               double[] cCouple = props.calcJmolCouple(j + base, k + base, l + base, m + base);
630               MeasureCouple measure = new MeasureCouple(exp, cCouple[1]);
631               diffCouple += measure.getDiff();
632             }
633           }
634         }
635 
636         double diff = diffCouple * coupleWeight;
637         if (lexpNoes) {
638           diff += diffNoe * noeWeight;
639 
640         } else {
641           diff += diffDist * noeWeight;
642         }
643         if (diff < minDiff) {
644           minDiff = diff;
645           minFrame = i;
646         }
647       }
648       return minFrame + 1;
649     } catch (Exception e) {
650       //
651       e.printStackTrace();
652       return -1;
653     }
654   }
655 
656 }
657