1 /* Copyright (C) 2014  Tomas Pluskal <plusik@gmail.com>
2  *
3  * Contact: cdk-devel@lists.sourceforge.net
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public License
7  * as published by the Free Software Foundation; either version 2.1
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 package org.openscience.cdk.formula;
20 
21 import org.junit.Assert;
22 import org.junit.Test;
23 import org.openscience.cdk.CDKTestCase;
24 import org.openscience.cdk.config.IsotopeFactory;
25 import org.openscience.cdk.config.Isotopes;
26 import org.openscience.cdk.interfaces.IChemObjectBuilder;
27 import org.openscience.cdk.interfaces.IIsotope;
28 import org.openscience.cdk.interfaces.IMolecularFormula;
29 import org.openscience.cdk.interfaces.IMolecularFormulaSet;
30 import org.openscience.cdk.silent.SilentChemObjectBuilder;
31 import org.openscience.cdk.tools.manipulator.MolecularFormulaManipulator;
32 
33 /**
34  * Checks the functionality of the MolecularFormulaGenerator.
35  *
36  * @cdk.module test-formula
37  */
38 public class MolecularFormulaGeneratorTest extends CDKTestCase {
39 
40     private final IChemObjectBuilder builder = SilentChemObjectBuilder
41             .getInstance();
42 
43     /**
44      * Test the getNextFormula() method
45      */
46     @Test
testGetNextFormula()47     public void testGetNextFormula() throws Exception {
48 
49         IsotopeFactory ifac = Isotopes.getInstance();
50         IIsotope c = ifac.getMajorIsotope("C");
51         IIsotope h = ifac.getMajorIsotope("H");
52         IIsotope n = ifac.getMajorIsotope("N");
53         IIsotope o = ifac.getMajorIsotope("O");
54 
55         MolecularFormulaRange mfRange = new MolecularFormulaRange();
56         mfRange.addIsotope(c, 0, 10);
57         mfRange.addIsotope(h, 0, 10);
58         mfRange.addIsotope(o, 0, 10);
59         mfRange.addIsotope(n, 0, 10);
60 
61         double minMass = 100.0;
62         double maxMass = 100.05;
63 
64         MolecularFormulaGenerator gen = new MolecularFormulaGenerator(builder,
65                 minMass, maxMass, mfRange);
66         IMolecularFormula f = gen.getNextFormula();
67         Assert.assertNotNull(f);
68 
69     }
70 
71     /**
72      * Test the getAllFormulas() method
73      */
74     @Test
testGetAllFormulas()75     public void testGetAllFormulas() throws Exception {
76 
77         IsotopeFactory ifac = Isotopes.getInstance();
78         IIsotope c = ifac.getMajorIsotope("C");
79         IIsotope h = ifac.getMajorIsotope("H");
80         IIsotope n = ifac.getMajorIsotope("N");
81         IIsotope o = ifac.getMajorIsotope("O");
82 
83         MolecularFormulaRange mfRange = new MolecularFormulaRange();
84         mfRange.addIsotope(c, 0, 10);
85         mfRange.addIsotope(h, 0, 10);
86         mfRange.addIsotope(o, 0, 10);
87         mfRange.addIsotope(n, 0, 10);
88 
89         double minMass = 100.0;
90         double maxMass = 100.05;
91 
92         MolecularFormulaGenerator gen = new MolecularFormulaGenerator(builder,
93                 minMass, maxMass, mfRange);
94         IMolecularFormulaSet mfSet = gen.getAllFormulas();
95 
96         Assert.assertNotNull(mfSet);
97         Assert.assertNotEquals(0, mfSet.size());
98     }
99 
100     /**
101      * Test the getFinishedPercentage() method
102      */
103     @Test
testGetFinishedPercentage()104     public void testGetFinishedPercentage() throws Exception {
105 
106         IsotopeFactory ifac = Isotopes.getInstance();
107         IIsotope c = ifac.getMajorIsotope("C");
108         IIsotope h = ifac.getMajorIsotope("H");
109         IIsotope n = ifac.getMajorIsotope("N");
110         IIsotope o = ifac.getMajorIsotope("O");
111 
112         MolecularFormulaRange mfRange = new MolecularFormulaRange();
113         mfRange.addIsotope(c, 0, 10);
114         mfRange.addIsotope(h, 0, 10);
115         mfRange.addIsotope(o, 0, 10);
116         mfRange.addIsotope(n, 0, 10);
117 
118         double minMass = 100.0;
119         double maxMass = 100.05;
120 
121         MolecularFormulaGenerator gen = new MolecularFormulaGenerator(builder,
122                 minMass, maxMass, mfRange);
123 
124         double finishedPerc, lastFinishedPerc = 0d;
125 
126         // The initial value must be 0
127         finishedPerc = gen.getFinishedPercentage();
128         Assert.assertEquals(0d, finishedPerc, 0.0001);
129 
130         // The value must increase after each generated formula
131         while (gen.getNextFormula() != null) {
132             finishedPerc = gen.getFinishedPercentage();
133             Assert.assertTrue(finishedPerc > lastFinishedPerc);
134             lastFinishedPerc = finishedPerc;
135         }
136 
137         // The final value must be 1
138         finishedPerc = gen.getFinishedPercentage();
139         Assert.assertEquals(1d, finishedPerc, 0.0001);
140 
141     }
142 
143     /**
144      * Test the cancel() method called from another thread. This test must
145      * finish in 1000 ms.
146      */
147     @Test(timeout = 1000)
testCancel()148     public void testCancel() throws Exception {
149 
150         IsotopeFactory ifac = Isotopes.getInstance();
151         IIsotope c = ifac.getMajorIsotope("C");
152         IIsotope h = ifac.getMajorIsotope("H");
153         IIsotope n = ifac.getMajorIsotope("N");
154         IIsotope o = ifac.getMajorIsotope("O");
155         IIsotope p = ifac.getMajorIsotope("P");
156         IIsotope s = ifac.getMajorIsotope("S");
157 
158         MolecularFormulaRange mfRange = new MolecularFormulaRange();
159         mfRange.addIsotope(c, 0, 1000);
160         mfRange.addIsotope(h, 0, 1000);
161         mfRange.addIsotope(o, 0, 1000);
162         mfRange.addIsotope(n, 0, 1000);
163         mfRange.addIsotope(p, 0, 1000);
164         mfRange.addIsotope(s, 0, 1000);
165 
166         double minMass = 100000.0;
167         double maxMass = 100000.001;
168 
169         final MolecularFormulaGenerator gen = new MolecularFormulaGenerator(
170                 builder, minMass, maxMass, mfRange);
171 
172         Runnable cancelThread = new Runnable() {
173             @Override
174             public void run() {
175                 try {
176                     Thread.sleep(5);
177                 } catch (InterruptedException e) {
178                     e.printStackTrace();
179                 }
180                 gen.cancel();
181             }
182         };
183         new Thread(cancelThread).run();
184 
185         // We will get stuck in the next method call until the cancel thread
186         // calls the cancel() method
187         gen.getAllFormulas();
188 
189         // Next getNextFormula() call should return null
190         IMolecularFormula f = gen.getNextFormula();
191         Assert.assertNull(f);
192     }
193 
194     /**
195      * Test empty molecular formula range
196      *
197      */
198     @Test(expected = IllegalArgumentException.class)
testEmptyMFRange()199     public void testEmptyMFRange() throws Exception {
200         new MolecularFormulaGenerator(builder, 0, 100,
201                 new MolecularFormulaRange());
202     }
203 
204     /**
205      * Test negative mass
206      */
207     @Test(expected = IllegalArgumentException.class)
testNegativeMass()208     public void testNegativeMass() throws Exception {
209 
210         IsotopeFactory ifac = Isotopes.getInstance();
211         IIsotope c = ifac.getMajorIsotope("C");
212 
213         MolecularFormulaRange mfRange = new MolecularFormulaRange();
214         mfRange.addIsotope(c, 0, 100);
215         new MolecularFormulaGenerator(builder, -20, -10,
216                 new MolecularFormulaRange());
217     }
218 
219     /**
220      * Test if the generator respects minimal element counts
221      *
222      */
223     @Test
testMinCounts()224     public void testMinCounts() throws Exception {
225 
226         IsotopeFactory ifac = Isotopes.getInstance();
227         IIsotope c = ifac.getMajorIsotope("C");
228         IIsotope h = ifac.getMajorIsotope("H");
229         IIsotope n = ifac.getMajorIsotope("N");
230         IIsotope o = ifac.getMajorIsotope("O");
231 
232         MolecularFormulaRange mfRange = new MolecularFormulaRange();
233         mfRange.addIsotope(c, 5, 20);
234         mfRange.addIsotope(h, 5, 20);
235         mfRange.addIsotope(o, 5, 20);
236         mfRange.addIsotope(n, 5, 20);
237 
238         // The minimal formula MF=C5H5O5N5 MW=215.0290682825
239         double minMass = 100;
240         double maxMass = 250;
241 
242         MolecularFormulaGenerator gen = new MolecularFormulaGenerator(builder,
243                 minMass, maxMass, mfRange);
244         IMolecularFormulaSet mfSet = gen.getAllFormulas();
245 
246         // Check that all element counts in the formula are >= 5
247         for (IMolecularFormula f : mfSet.molecularFormulas()) {
248             for (IIsotope i : f.isotopes()) {
249                 int count = f.getIsotopeCount(i);
250                 Assert.assertTrue(count >= 5);
251             }
252         }
253 
254     }
255 
256     /**
257      * Test if the generator respects maximal element counts
258      *
259      */
260     @Test
testMaxCounts()261     public void testMaxCounts() throws Exception {
262 
263         IsotopeFactory ifac = Isotopes.getInstance();
264         IIsotope c = ifac.getMajorIsotope("C");
265         IIsotope h = ifac.getMajorIsotope("H");
266         IIsotope n = ifac.getMajorIsotope("N");
267         IIsotope o = ifac.getMajorIsotope("O");
268 
269         MolecularFormulaRange mfRange = new MolecularFormulaRange();
270         mfRange.addIsotope(c, 3, 7);
271         mfRange.addIsotope(h, 3, 7);
272         mfRange.addIsotope(o, 3, 7);
273         mfRange.addIsotope(n, 3, 7);
274 
275         // The maximal formula MF=C7H7O7N7 MW=301.0406955954
276         double minMass = 250;
277         double maxMass = 400;
278 
279         MolecularFormulaGenerator gen = new MolecularFormulaGenerator(builder,
280                 minMass, maxMass, mfRange);
281         IMolecularFormulaSet mfSet = gen.getAllFormulas();
282 
283         // Check that all element counts in the formula are <= 7
284         for (IMolecularFormula f : mfSet.molecularFormulas()) {
285             for (IIsotope i : f.isotopes()) {
286                 int count = f.getIsotopeCount(i);
287                 Assert.assertTrue(count <= 7);
288             }
289         }
290     }
291 
292     /**
293      * Test to find a single carbon.
294      */
295     @Test
testSingleCarbon()296     public void testSingleCarbon() throws Exception {
297 
298         IsotopeFactory ifac = Isotopes.getInstance();
299         IIsotope c = ifac.getMajorIsotope("C");
300 
301         MolecularFormulaRange mfRange = new MolecularFormulaRange();
302         mfRange.addIsotope(c, 0, 100);
303 
304         double minMass = 5;
305         double maxMass = 15;
306 
307         MolecularFormulaGenerator gen = new MolecularFormulaGenerator(builder,
308                 minMass, maxMass, mfRange);
309         IMolecularFormulaSet mfSet = gen.getAllFormulas();
310 
311         Assert.assertNotNull(mfSet);
312         Assert.assertEquals(1, mfSet.size());
313         Assert.assertEquals("C", MolecularFormulaManipulator.getString(mfSet
314                 .getMolecularFormula(0)));
315     }
316 
317     /**
318      * Test to find MF=C10000, MW=120000.0 using only carbons.
319      */
320     @Test
testCarbons()321     public void testCarbons() throws Exception {
322 
323         IsotopeFactory ifac = Isotopes.getInstance();
324         IIsotope c = ifac.getMajorIsotope("C");
325 
326         MolecularFormulaRange mfRange = new MolecularFormulaRange();
327         mfRange.addIsotope(c, 0, 100000);
328 
329         double minMass = 120000.0 - 1;
330         double maxMass = 120000.0 + 1;
331 
332         MolecularFormulaGenerator gen = new MolecularFormulaGenerator(builder,
333                 minMass, maxMass, mfRange);
334         IMolecularFormulaSet mfSet = gen.getAllFormulas();
335 
336         Assert.assertNotNull(mfSet);
337         Assert.assertEquals(1, mfSet.size());
338         Assert.assertEquals("C10000", MolecularFormulaManipulator
339                 .getString(mfSet.getMolecularFormula(0)));
340     }
341 
342     /**
343      * Test to find H2O in a range of 1-20.
344      */
345     @Test
testWater()346     public void testWater() throws Exception {
347 
348         IsotopeFactory ifac = Isotopes.getInstance();
349         IIsotope c = ifac.getMajorIsotope("C");
350         IIsotope h = ifac.getMajorIsotope("H");
351         IIsotope n = ifac.getMajorIsotope("N");
352         IIsotope o = ifac.getMajorIsotope("O");
353         IIsotope p = ifac.getMajorIsotope("P");
354         IIsotope s = ifac.getMajorIsotope("S");
355 
356         MolecularFormulaRange mfRange = new MolecularFormulaRange();
357         mfRange.addIsotope(c, 0, 10);
358         mfRange.addIsotope(h, 0, 10);
359         mfRange.addIsotope(o, 0, 10);
360         mfRange.addIsotope(n, 0, 10);
361         mfRange.addIsotope(p, 0, 10);
362         mfRange.addIsotope(s, 0, 10);
363 
364         double minMass = 1;
365         double maxMass = 20;
366 
367         MolecularFormulaGenerator gen = new MolecularFormulaGenerator(builder,
368                 minMass, maxMass, mfRange);
369         IMolecularFormulaSet mfSet = gen.getAllFormulas();
370 
371         Assert.assertNotNull(mfSet);
372 
373         boolean found = false;
374         for (IMolecularFormula formula : mfSet.molecularFormulas()) {
375             String mf = MolecularFormulaManipulator.getString(formula);
376             if (mf.equals("H2O")) {
377                 found = true;
378                 break;
379             }
380         }
381         Assert.assertTrue("The molecular formula H2O should be found", found);
382     }
383 
384     /**
385      * MolecularFormulaGenerator should use full enumeration method when smallest element has large weight
386      */
387     @Test
testUseFullEnumerationWhenNoHydrogen()388     public void testUseFullEnumerationWhenNoHydrogen() throws Exception {
389         IsotopeFactory ifac = Isotopes.getInstance();
390         IIsotope c = ifac.getMajorIsotope("C");
391         IIsotope n = ifac.getMajorIsotope("N");
392         IIsotope o = ifac.getMajorIsotope("O");
393 
394         MolecularFormulaRange mfRange = new MolecularFormulaRange();
395         mfRange.addIsotope(c, 0, 50);
396         mfRange.addIsotope(o, 0, 30);
397         mfRange.addIsotope(n, 0, 10);
398 
399         MolecularFormulaGenerator generator = new MolecularFormulaGenerator(builder, 1023.000, 1023.002, mfRange);
400         Assert.assertTrue("generator implementation should be instance of FullEnumerationFormulaGenerator", generator.formulaGenerator instanceof FullEnumerationFormulaGenerator);
401     }
402 
403     /**
404      * MolecularFormulaGenerator should use full enumeration method when the mass deviation is very large (i.e. as
405      * large as the smallest weight)
406      */
407     @Test
testUseFullEnumerationWhenSuperLargeMassDeviation()408     public void testUseFullEnumerationWhenSuperLargeMassDeviation() throws Exception {
409         IsotopeFactory ifac = Isotopes.getInstance();
410         IIsotope c = ifac.getMajorIsotope("C");
411         IIsotope h = ifac.getMajorIsotope("H");
412         IIsotope n = ifac.getMajorIsotope("N");
413         IIsotope o = ifac.getMajorIsotope("O");
414 
415         MolecularFormulaRange mfRange = new MolecularFormulaRange();
416         mfRange.addIsotope(c, 0, 20);
417         mfRange.addIsotope(h, 0, 30);
418         mfRange.addIsotope(o, 0, 15);
419         mfRange.addIsotope(n, 0, 10);
420 
421         MolecularFormulaGenerator generator = new MolecularFormulaGenerator(builder, 13, 14, mfRange);
422         Assert.assertTrue("generator implementation should be instance of FullEnumerationFormulaGenerator", generator.formulaGenerator instanceof FullEnumerationFormulaGenerator);
423     }
424 
425 
426     /**
427      * MolecularFormulaGenerator should use full enumeration method when mass to decompose is too large to encode
428      * it as 32 bit integer with default blowup factor
429      */
430     @Test
testUseFullEnumerationWhenExceedIntegerSpace()431     public void testUseFullEnumerationWhenExceedIntegerSpace() throws Exception {
432         IsotopeFactory ifac = Isotopes.getInstance();
433         IIsotope c = ifac.getMajorIsotope("C");
434         IIsotope h = ifac.getMajorIsotope("H");
435         IIsotope n = ifac.getMajorIsotope("N");
436         IIsotope o = ifac.getMajorIsotope("O");
437 
438         MolecularFormulaRange mfRange = new MolecularFormulaRange();
439         mfRange.addIsotope(c, 0, 20);
440         mfRange.addIsotope(h, 0, 30);
441         mfRange.addIsotope(o, 0, 15);
442         mfRange.addIsotope(n, 0, 10);
443 
444         MolecularFormulaGenerator generator = new MolecularFormulaGenerator(builder, 1300000, 1300000.1, mfRange);
445         Assert.assertTrue("generator implementation should be instance of FullEnumerationFormulaGenerator", generator.formulaGenerator instanceof FullEnumerationFormulaGenerator);
446     }
447 
448 
449     /**
450      * MolecularFormulaGenerator should use Round Robin when using proper input
451      */
452     @Test
testUseRoundRobinWheneverPossible()453     public void testUseRoundRobinWheneverPossible() throws Exception {
454         IsotopeFactory ifac = Isotopes.getInstance();
455         IIsotope c = ifac.getMajorIsotope("C");
456         IIsotope h = ifac.getMajorIsotope("H");
457         IIsotope n = ifac.getMajorIsotope("N");
458         IIsotope o = ifac.getMajorIsotope("O");
459 
460         MolecularFormulaRange mfRange = new MolecularFormulaRange();
461         mfRange.addIsotope(c, 0, 20);
462         mfRange.addIsotope(h, 0, 30);
463         mfRange.addIsotope(o, 0, 15);
464         mfRange.addIsotope(n, 0, 10);
465 
466         MolecularFormulaGenerator generator = new MolecularFormulaGenerator(builder, 230.002, 230.004, mfRange);
467         Assert.assertTrue("generator implementation should be instance of RoundRobinFormulaGenerator", generator.formulaGenerator instanceof RoundRobinFormulaGenerator);
468     }
469 
470     /**
471      * Test to find MF=C5H11N2O, MW=115.08714
472      */
473     @Test
testSmallMass()474     public void testSmallMass() throws Exception {
475 
476         IsotopeFactory ifac = Isotopes.getInstance();
477         IIsotope c = ifac.getMajorIsotope("C");
478         IIsotope h = ifac.getMajorIsotope("H");
479         IIsotope n = ifac.getMajorIsotope("N");
480         IIsotope o = ifac.getMajorIsotope("O");
481 
482         MolecularFormulaRange mfRange = new MolecularFormulaRange();
483         mfRange.addIsotope(c, 0, 20);
484         mfRange.addIsotope(h, 0, 30);
485         mfRange.addIsotope(o, 0, 15);
486         mfRange.addIsotope(n, 0, 10);
487 
488         double minMass = 115.08714 - 0.0001;
489         double maxMass = 115.08714 + 0.0001;
490 
491         MolecularFormulaGenerator gen = new MolecularFormulaGenerator(builder,
492                 minMass, maxMass, mfRange);
493         IMolecularFormulaSet mfSet = gen.getAllFormulas();
494 
495         Assert.assertNotNull(mfSet);
496         Assert.assertEquals(1, mfSet.size());
497         Assert.assertEquals("C5H11N2O", MolecularFormulaManipulator
498                 .getString(mfSet.getMolecularFormula(0)));
499     }
500 
501     /**
502      * Test to find pentacarboxyporphyrin, MF=C37H38N4O10 MW=698.25879
503      *
504      */
505     @Test
testMiddleMass()506     public void testMiddleMass() throws Exception {
507 
508         IsotopeFactory ifac = Isotopes.getInstance();
509         IIsotope c = ifac.getMajorIsotope("C");
510         IIsotope h = ifac.getMajorIsotope("H");
511         IIsotope n = ifac.getMajorIsotope("N");
512         IIsotope o = ifac.getMajorIsotope("O");
513 
514         MolecularFormulaRange mfRange = new MolecularFormulaRange();
515         mfRange.addIsotope(c, 0, 50);
516         mfRange.addIsotope(h, 0, 100);
517         mfRange.addIsotope(o, 0, 30);
518         mfRange.addIsotope(n, 0, 10);
519 
520         double minMass = 698.25879 - 0.0001;
521         double maxMass = 698.25879 + 0.0001;
522 
523         MolecularFormulaGenerator gen = new MolecularFormulaGenerator(builder,
524                 minMass, maxMass, mfRange);
525         IMolecularFormulaSet mfSet = gen.getAllFormulas();
526 
527         Assert.assertNotNull(mfSet);
528         Assert.assertEquals(1, mfSet.size());
529         Assert.assertEquals("C37H38N4O10", MolecularFormulaManipulator
530                 .getString(mfSet.getMolecularFormula(0)));
531     }
532 
533     /**
534      * Test to find ubiquitin: MF=C374H623N103O116S MW=8445.573784
535      *
536      */
537     @Test
testHighMass()538     public void testHighMass() throws Exception {
539 
540         IsotopeFactory ifac = Isotopes.getInstance();
541         IIsotope c = ifac.getMajorIsotope("C");
542         IIsotope h = ifac.getMajorIsotope("H");
543         IIsotope n = ifac.getMajorIsotope("N");
544         IIsotope o = ifac.getMajorIsotope("O");
545         IIsotope s = ifac.getMajorIsotope("S");
546 
547         MolecularFormulaRange mfRange = new MolecularFormulaRange();
548         mfRange.addIsotope(c, 350, 400);
549         mfRange.addIsotope(h, 620, 650);
550         mfRange.addIsotope(o, 100, 150);
551         mfRange.addIsotope(n, 100, 150);
552         mfRange.addIsotope(s, 0, 10);
553 
554         double minMass = 8445.573784 - 0.00001;
555         double maxMass = 8445.573784 + 0.00001;
556 
557         MolecularFormulaGenerator gen = new MolecularFormulaGenerator(builder,
558                 minMass, maxMass, mfRange);
559         IMolecularFormulaSet mfSet = gen.getAllFormulas();
560 
561         Assert.assertNotNull(mfSet);
562         Assert.assertEquals(1, mfSet.size());
563         Assert.assertEquals("C374H623N103O116S", MolecularFormulaManipulator
564                 .getString(mfSet.getMolecularFormula(0)));
565 
566 
567         //////////////////
568     }
569 
570     /**
571      *
572      *
573      * Test if formula MF=C4H11NO4 MW=137.06881 is found in mass range
574      * 137-137.2.
575      *
576      */
577     @Test
testFormulaFoundInRange()578     public void testFormulaFoundInRange() throws Exception {
579         IsotopeFactory ifac = Isotopes.getInstance();
580         IIsotope c = ifac.getMajorIsotope("C");
581         IIsotope h = ifac.getMajorIsotope("H");
582         IIsotope n = ifac.getMajorIsotope("N");
583         IIsotope o = ifac.getMajorIsotope("O");
584 
585         MolecularFormulaRange mfRange = new MolecularFormulaRange();
586         mfRange.addIsotope(c, 1, 50);
587         mfRange.addIsotope(h, 1, 100);
588         mfRange.addIsotope(o, 1, 50);
589         mfRange.addIsotope(n, 1, 50);
590 
591         double minMass = 137.0;
592         double maxMass = 137.2;
593 
594         MolecularFormulaGenerator gen = new MolecularFormulaGenerator(builder,
595                 minMass, maxMass, mfRange);
596         IMolecularFormulaSet mfSet = gen.getAllFormulas();
597 
598         Assert.assertEquals(48, mfSet.size());
599         boolean found = false;
600         for (IMolecularFormula formula : mfSet.molecularFormulas()) {
601             String mf = MolecularFormulaManipulator.getString(formula);
602             if (mf.equals("C4H11NO4")) {
603                 found = true;
604                 break;
605             }
606         }
607         Assert.assertTrue("The molecular formula C4H11NO4 should be found",
608                 found);
609     }
610 
611     /**
612      * Test if formula MF=C11H10NO2 MW=188.07115 is found in mass range 187-189.
613      *
614      */
615     @Test
testFormulaFoundInRange2()616     public void testFormulaFoundInRange2() throws Exception {
617 
618         IsotopeFactory ifac = Isotopes.getInstance();
619         IIsotope c = ifac.getMajorIsotope("C");
620         IIsotope h = ifac.getMajorIsotope("H");
621         IIsotope n = ifac.getMajorIsotope("N");
622         IIsotope o = ifac.getMajorIsotope("O");
623 
624         MolecularFormulaRange mfRange = new MolecularFormulaRange();
625         mfRange.addIsotope(c, 1, 50);
626         mfRange.addIsotope(h, 1, 100);
627         mfRange.addIsotope(o, 1, 50);
628         mfRange.addIsotope(n, 1, 50);
629 
630         double minMass = 187;
631         double maxMass = 189;
632 
633         MolecularFormulaGenerator gen = new MolecularFormulaGenerator(builder,
634                 minMass, maxMass, mfRange);
635         IMolecularFormulaSet mfSet = gen.getAllFormulas();
636 
637         Assert.assertEquals(528, mfSet.size());
638         boolean found = false;
639         for (IMolecularFormula formula : mfSet.molecularFormulas()) {
640             String mf = MolecularFormulaManipulator.getString(formula);
641             if (mf.equals("C11H10NO2")) {
642                 found = true;
643                 break;
644             }
645         }
646         Assert.assertTrue("The molecular formula C11H10NO2 should be found",
647                 found);
648     }
649 
650     /**
651      * Test if formula with 7 different elements is found in a narrow mass
652      * range. MF=C8H9Cl3NO2PS MW=318.915719
653      *
654      */
655     @Test
testCompoundWith7Elements()656     public void testCompoundWith7Elements() throws Exception {
657 
658         IsotopeFactory ifac = Isotopes.getInstance();
659         IIsotope c = ifac.getMajorIsotope("C");
660         IIsotope h = ifac.getMajorIsotope("H");
661         IIsotope n = ifac.getMajorIsotope("N");
662         IIsotope o = ifac.getMajorIsotope("O");
663         IIsotope s = ifac.getMajorIsotope("S");
664         IIsotope p = ifac.getMajorIsotope("P");
665         IIsotope cl = ifac.getMajorIsotope("Cl");
666 
667         MolecularFormulaRange mfRange = new MolecularFormulaRange();
668         mfRange.addIsotope(c, 7, 9);
669         mfRange.addIsotope(h, 8, 10);
670         mfRange.addIsotope(o, 1, 3);
671         mfRange.addIsotope(n, 0, 2);
672         mfRange.addIsotope(s, 0, 2);
673         mfRange.addIsotope(p, 0, 2);
674         mfRange.addIsotope(cl, 2, 4);
675 
676         double minMass = 318.915719 - 0.0001;
677         double maxMass = 318.915719 + 0.0001;
678 
679         MolecularFormulaGenerator gen = new MolecularFormulaGenerator(builder,
680                 minMass, maxMass, mfRange);
681         IMolecularFormulaSet mfSet = gen.getAllFormulas();
682 
683         Assert.assertNotNull(mfSet);
684         Assert.assertEquals(1, mfSet.size());
685         Assert.assertEquals("C8H9Cl3NO2PS", MolecularFormulaManipulator
686                 .getString(mfSet.getMolecularFormula(0)));
687 
688     }
689 
690     /**
691      * Test if C13 isotope-containing formula is found. MF=C(^12)3C(^13)H5
692      */
693     @Test
testDifferentIsotopes()694     public void testDifferentIsotopes() throws Exception {
695 
696         IsotopeFactory ifac = Isotopes.getInstance();
697         IIsotope c = ifac.getMajorIsotope("C");
698         IIsotope[] carbons = ifac.getIsotopes("C");
699         IIsotope c13 = carbons[5]; // 13
700         IIsotope h = ifac.getMajorIsotope("H");
701 
702         MolecularFormulaRange mfRange = new MolecularFormulaRange();
703         mfRange.addIsotope(c, 0, 11);
704         mfRange.addIsotope(c13, 0, 10);
705         mfRange.addIsotope(h, 0, 10);
706 
707         double minMass = 54.04193 - 0.001;
708         double maxMass = 54.04193 + 0.001;
709 
710         MolecularFormulaGenerator gen = new MolecularFormulaGenerator(builder,
711                 minMass, maxMass, mfRange);
712         IMolecularFormulaSet mfSet = gen.getAllFormulas();
713 
714         Assert.assertNotNull(mfSet);
715         Assert.assertEquals(1, mfSet.size());
716 
717         IMolecularFormula trueFormula = new MolecularFormula(); // C3CH5
718         trueFormula.addIsotope(c, 3);
719         trueFormula.addIsotope(c13, 1);
720         trueFormula.addIsotope(h, 5);
721 
722         Assert.assertEquals(trueFormula.getIsotopeCount(), mfSet
723                 .getMolecularFormula(0).getIsotopeCount());
724         Assert.assertEquals(trueFormula.getIsotopeCount(c), mfSet
725                 .getMolecularFormula(0).getIsotopeCount(c));
726         Assert.assertEquals(trueFormula.getIsotopeCount(c13), mfSet
727                 .getMolecularFormula(0).getIsotopeCount(c13));
728 
729     }
730 
731     /**
732      * Test if formula MF=C7H15N2O4 MW=191.10318 is found properly if we fix the
733      * element counts
734      */
735     @Test
testFixedElementCounts()736     public void testFixedElementCounts() throws Exception {
737 
738         IsotopeFactory ifac = Isotopes.getInstance();
739         IIsotope c = ifac.getMajorIsotope("C");
740         IIsotope h = ifac.getMajorIsotope("H");
741         IIsotope n = ifac.getMajorIsotope("N");
742         IIsotope o = ifac.getMajorIsotope("O");
743 
744         MolecularFormulaRange mfRange = new MolecularFormulaRange();
745         mfRange.addIsotope(c, 7, 7);
746         mfRange.addIsotope(h, 15, 15);
747         mfRange.addIsotope(o, 4, 4);
748         mfRange.addIsotope(n, 2, 2);
749 
750         double massMin = 10d;
751         double massMax = 1000d;
752         MolecularFormulaGenerator gen = new MolecularFormulaGenerator(builder,
753                 massMin, massMax, mfRange);
754 
755         IMolecularFormulaSet mfSet = gen.getAllFormulas();
756 
757         Assert.assertNotNull(mfSet);
758         Assert.assertEquals(1, mfSet.size());
759         Assert.assertEquals("C7H15N2O4", MolecularFormulaManipulator
760                 .getString(mfSet.getMolecularFormula(0)));
761 
762     }
763 
764     /**
765      * Test if zero results are returned in case the target mass range is too
766      * high
767      */
768     @Test
testMassRangeTooHigh()769     public void testMassRangeTooHigh() throws Exception {
770 
771         IsotopeFactory ifac = Isotopes.getInstance();
772         IIsotope c = ifac.getMajorIsotope("C");
773         IIsotope h = ifac.getMajorIsotope("H");
774         IIsotope n = ifac.getMajorIsotope("N");
775         IIsotope o = ifac.getMajorIsotope("O");
776 
777         MolecularFormulaRange mfRange = new MolecularFormulaRange();
778         mfRange.addIsotope(c, 0, 10);
779         mfRange.addIsotope(h, 0, 10);
780         mfRange.addIsotope(o, 0, 10);
781         mfRange.addIsotope(n, 0, 10);
782 
783         double massMin = 1000d;
784         double massMax = 2000d;
785         MolecularFormulaGenerator gen = new MolecularFormulaGenerator(builder,
786                 massMin, massMax, mfRange);
787 
788         IMolecularFormulaSet mfSet = gen.getAllFormulas();
789 
790         Assert.assertNotNull(mfSet);
791         Assert.assertEquals(0, mfSet.size());
792 
793     }
794 
795     /**
796      * Test if zero results are returned in case the target mass range is too
797      * low
798      */
799     @Test
testMassRangeTooLow()800     public void testMassRangeTooLow() throws Exception {
801 
802         IsotopeFactory ifac = Isotopes.getInstance();
803         IIsotope c = ifac.getMajorIsotope("C");
804         IIsotope h = ifac.getMajorIsotope("H");
805         IIsotope n = ifac.getMajorIsotope("N");
806         IIsotope o = ifac.getMajorIsotope("O");
807 
808         MolecularFormulaRange mfRange = new MolecularFormulaRange();
809         mfRange.addIsotope(c, 100, 200);
810         mfRange.addIsotope(h, 100, 200);
811         mfRange.addIsotope(o, 100, 200);
812         mfRange.addIsotope(n, 100, 200);
813 
814         double massMin = 50d;
815         double massMax = 100d;
816         MolecularFormulaGenerator gen = new MolecularFormulaGenerator(builder,
817                 massMin, massMax, mfRange);
818 
819         IMolecularFormulaSet mfSet = gen.getAllFormulas();
820         Assert.assertNotNull(mfSet);
821         Assert.assertEquals(0, mfSet.size());
822 
823     }
824 
825 }
826