source: src/Fragmentation/Summation/SetValues/unittests/FragmentUnitTest.cpp@ a844d8

Candidate_v1.6.1
Last change on this file since a844d8 was 6829d2, checked in by Frederik Heber <heber@…>, 8 years ago

MPQCData additionally stores the atomic number per nuclei.

  • in case of DoSampleValenceOnly the charge does not represent the atomic number and moreover it is no longer unique. However, we need this unique association for fitting potentials to the fragment results.
  • TESTFIX: set all tests to XFAIL that parse either fragmentation results or homologies.
  • TESTFIX: needed to adapt HomologyContainerUnitTest which uses FragmentStub.
  • TESTFIX: needed to adapt FragmentUnitTest.
  • Property mode set to 100644
File size: 17.4 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2012 University of Bonn. All rights reserved.
5 * Copyright (C) 2013 Frederik Heber. All rights reserved.
6 *
7 *
8 * This file is part of MoleCuilder.
9 *
10 * MoleCuilder is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation, either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * MoleCuilder is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with MoleCuilder. If not, see <http://www.gnu.org/licenses/>.
22 */
23
24/*
25 * FragmentUnitTest.cpp
26 *
27 * Created on: Aug 09, 2012
28 * Author: heber
29 */
30
31// include config.h
32#ifdef HAVE_CONFIG_H
33#include <config.h>
34#endif
35
36using namespace std;
37
38#include <cppunit/CompilerOutputter.h>
39#include <cppunit/extensions/TestFactoryRegistry.h>
40#include <cppunit/ui/text/TestRunner.h>
41
42// include headers that implement a archive in simple text format
43#include <boost/archive/text_oarchive.hpp>
44#include <boost/archive/text_iarchive.hpp>
45
46#include "FragmentUnitTest.hpp"
47
48#include <algorithm>
49#include <limits>
50
51#include <boost/assign.hpp>
52#include <boost/foreach.hpp>
53
54#include <sstream>
55
56#include "CodePatterns/Assert.hpp"
57
58#ifdef HAVE_TESTRUNNER
59#include "UnitTestMain.hpp"
60#endif /*HAVE_TESTRUNNER*/
61
62using namespace boost::assign;
63
64/********************************************** Test classes **************************************/
65
66// Registers the fixture into the 'registry'
67CPPUNIT_TEST_SUITE_REGISTRATION( FragmentTest );
68
69
70void FragmentTest::setUp()
71{
72 // failing asserts should be thrown
73 ASSERT_DO(Assert::Throw);
74
75 Fragment::position_t pos(3,0.);
76 positions += pos;
77 pos[0] = 1.;
78 positions += pos;
79 pos[1] = 1.;
80 positions += pos;
81 pos[2] = 1.;
82 positions += pos;
83 atomicnumbers += 1, 2, 3, 4;
84 charges += 1., 2., 3., 4.;
85 CPPUNIT_ASSERT_EQUAL( (size_t)3, pos.size() );
86 CPPUNIT_ASSERT( positions.size() == charges.size() );
87 CPPUNIT_ASSERT( atomicnumbers.size() == charges.size() );
88
89 fragment = new Fragment(positions, atomicnumbers, charges);
90}
91
92
93void FragmentTest::tearDown()
94{
95 delete fragment;
96}
97
98/** UnitTest for isPositionEqual()
99 */
100void FragmentTest::isPositionEqual_Test()
101{
102 // same position
103 for (Fragment::positions_t::const_iterator iter = positions.begin();
104 iter != positions.end(); ++iter)
105 CPPUNIT_ASSERT( Fragment::isPositionEqual(*iter, *iter) );
106
107 // other position
108 Fragment::position_t unequalpos(3,2.);
109 for (Fragment::positions_t::const_iterator iter = positions.begin();
110 iter != positions.end(); ++iter)
111 CPPUNIT_ASSERT( !Fragment::isPositionEqual(*iter, unequalpos) );
112}
113
114static Fragment::nuclei_t createNucleiFromTriple(
115 const Fragment::positions_t &_positions,
116 const Fragment::atomicnumbers_t &_atomicnumbers,
117 const Fragment::charges_t &_charges
118 )
119{
120 Fragment::nuclei_t returnnuclei;
121 Fragment::positions_t::const_iterator piter = _positions.begin();
122 Fragment::atomicnumbers_t::const_iterator aiter = _atomicnumbers.begin();
123 Fragment::charges_t::const_iterator citer = _charges.begin();
124 for (;piter != _positions.end(); ++piter)
125 returnnuclei.push_back( Fragment::createNucleus(*piter, *aiter, *citer) );
126 return returnnuclei;
127}
128
129/** UnitTest for containsNuclei()
130 */
131void FragmentTest::containsNuclei_Test()
132{
133 {
134 // tests present ones for containment
135 Fragment::nuclei_t validnuclei( createNucleiFromTriple(positions, atomicnumbers, charges) );
136 BOOST_FOREACH( Fragment::nucleus_t nucleus, validnuclei) {
137 CPPUNIT_ASSERT( fragment->containsNuclei(nucleus) );
138 }
139 }
140
141 {
142 // test some others
143 Fragment::nuclei_t invalidnuclei;
144 Fragment::position_t pos(3, -1.);
145 invalidnuclei += Fragment::createNucleus(pos, 1, 1.);
146 pos[0] = 0.;
147 invalidnuclei += Fragment::createNucleus(pos, 1, 1.);
148 pos[1] = 0.;
149 invalidnuclei += Fragment::createNucleus(pos, 1, 1.);
150 pos[2] = -std::numeric_limits<double>::epsilon()*1e+4;
151 invalidnuclei += Fragment::createNucleus(pos, 1, 1.);
152 BOOST_FOREACH( Fragment::nucleus_t nucleus, invalidnuclei) {
153 CPPUNIT_ASSERT( !fragment->containsNuclei(nucleus) );
154 }
155 }
156}
157
158/** UnitTest for removeNuclei()
159 */
160void FragmentTest::removeNuclei_Test()
161{
162 {
163 // tests present ones for removal
164 size_t size = fragment->nuclei.size();
165 Fragment::nuclei_t validnuclei( createNucleiFromTriple(positions, atomicnumbers, charges) );
166 BOOST_FOREACH( Fragment::nucleus_t nucleus, validnuclei) {
167 CPPUNIT_ASSERT_NO_THROW( fragment->removeNuclei(nucleus) );
168 CPPUNIT_ASSERT_EQUAL( --size, fragment->nuclei.size() );
169 }
170 }
171 {
172 // test some others
173 Fragment::nuclei_t invalidnuclei;
174 Fragment::position_t pos(3, -1.);
175 invalidnuclei += Fragment::createNucleus(pos, 1, 1.);
176 pos[0] = 0;
177 invalidnuclei += Fragment::createNucleus(pos, 1, 1.);
178 pos[1] = 0;
179 invalidnuclei += Fragment::createNucleus(pos, 1, 1.);
180 pos[2] = -std::numeric_limits<double>::epsilon()*1e+4;
181 invalidnuclei += Fragment::createNucleus(pos, 1, 1.);
182 BOOST_FOREACH( Fragment::nucleus_t nucleus, invalidnuclei) {
183 CPPUNIT_ASSERT_NO_THROW( fragment->removeNuclei(nucleus) );
184 }
185 }
186}
187
188/** UnitTest for operator==() for Fragment::nucleus_t
189 */
190void FragmentTest::equalityNucleus_Test()
191{
192 Fragment::nuclei_t validnuclei( createNucleiFromTriple(positions, atomicnumbers, charges) );
193 {
194 // create some nuclei
195 BOOST_FOREACH( Fragment::nucleus_t nucleus, validnuclei) {
196 CPPUNIT_ASSERT( nucleus == nucleus );
197 }
198 }
199
200 {
201 // create nucleus at other position
202 Fragment::position_t pos(3, 2.);
203 Fragment::nucleus_t unequalposnucleus( Fragment::createNucleus(pos, 1, 1.) );
204 BOOST_FOREACH( Fragment::nucleus_t nucleus, validnuclei) {
205 CPPUNIT_ASSERT( nucleus != unequalposnucleus );
206 }
207 }
208
209 {
210 // create nucleus with different charge
211 Fragment::position_t pos(3, 1.);
212 Fragment::nucleus_t unequalchargenucleus( Fragment::createNucleus(pos, 5, 5.) );
213 BOOST_FOREACH( Fragment::nucleus_t nucleus, validnuclei) {
214 CPPUNIT_ASSERT( nucleus != unequalchargenucleus );
215 }
216 }
217}
218
219/** UnitTest for operator==()
220 */
221void FragmentTest::equality_Test()
222{
223 // create different fragment
224 Fragment::positions_t otherpositions;
225 Fragment::position_t otherpos(3, 2.);
226 otherpositions += otherpos;
227 otherpos[0] = 0.;
228 otherpositions += otherpos;
229 otherpos[1] = 0.;
230 otherpositions += otherpos;
231 Fragment::atomicnumbers_t otheratomicnumbers;
232 otheratomicnumbers += 1, 2, 3;
233 Fragment::charges_t othercharges;
234 othercharges += 1., 2., 3.;
235 Fragment otherfragment(otherpositions, otheratomicnumbers, othercharges);
236
237 CPPUNIT_ASSERT( !(*fragment == otherfragment) );
238 CPPUNIT_ASSERT( *fragment != otherfragment );
239
240 // test against empty fragment
241 Fragment emptyfragment;
242 CPPUNIT_ASSERT( !(*fragment == emptyfragment) );
243 CPPUNIT_ASSERT( *fragment != emptyfragment );
244
245 // tests against themselves
246 CPPUNIT_ASSERT( *fragment == *fragment );
247 CPPUNIT_ASSERT( otherfragment == otherfragment );
248 CPPUNIT_ASSERT( emptyfragment == emptyfragment );
249
250 // check against ZeroInstance
251 CPPUNIT_ASSERT( *fragment != ZeroInstance<Fragment>() );
252 CPPUNIT_ASSERT( otherfragment != ZeroInstance<Fragment>() );
253}
254
255/** UnitTest for operator+=()
256 */
257void FragmentTest::assignment_Test()
258{
259 // create different fragment
260 Fragment::positions_t otherpositions;
261 Fragment::position_t otherpos(3, 2.);
262 otherpositions += otherpos;
263 otherpos[0] = 0.;
264 otherpositions += otherpos;
265 otherpos[1] = 0.;
266 otherpositions += otherpos;
267 Fragment::atomicnumbers_t otheratomicnumbers;
268 otheratomicnumbers += 1, 2, 3;
269 Fragment::charges_t othercharges;
270 othercharges += 1., 2., 3.;
271 Fragment otherfragment(otherpositions, otheratomicnumbers, othercharges);
272
273 // check for inequality
274 CPPUNIT_ASSERT( otherfragment.nuclei.size() != fragment->nuclei.size() );
275 CPPUNIT_ASSERT( otherfragment != *fragment );
276
277 //assign
278 otherfragment = *fragment;
279
280 // check for equality
281 CPPUNIT_ASSERT( otherfragment.nuclei.size() == fragment->nuclei.size() );
282 CPPUNIT_ASSERT( otherfragment == *fragment );
283}
284
285/** UnitTest for operator+=()
286 */
287void FragmentTest::operatorPlusEqual_NonOverlapping_Test()
288{
289 {
290 // create non-overlapping set
291 Fragment::positions_t otherpositions;
292 Fragment::position_t otherpos(3, 2.);
293 otherpositions += otherpos;
294 otherpos[0] = 0.;
295 otherpositions += otherpos;
296 otherpos[1] = 0.;
297 otherpositions += otherpos;
298 Fragment::atomicnumbers_t otheratomicnumbers;
299 otheratomicnumbers += 1, 2, 3;
300 Fragment::charges_t othercharges;
301 othercharges += 1., 2., 3.;
302 Fragment otherfragment(otherpositions, otheratomicnumbers, othercharges);
303 const size_t othersize = otherfragment.nuclei.size();
304 const size_t size = fragment->nuclei.size();
305 *fragment += otherfragment;
306 CPPUNIT_ASSERT_EQUAL( othersize, otherfragment.nuclei.size() );
307 CPPUNIT_ASSERT_EQUAL( size+othersize, fragment->nuclei.size() );
308 {
309 // tests all for containment
310 Fragment::nuclei_t validnuclei( createNucleiFromTriple(positions, atomicnumbers, charges) );
311 Fragment::nuclei_t othervalidnuclei( createNucleiFromTriple(otherpositions, otheratomicnumbers, othercharges) );
312 validnuclei.insert(validnuclei.end(), othervalidnuclei.begin(), othervalidnuclei.end());
313 BOOST_FOREACH( Fragment::nucleus_t nucleus, validnuclei) {
314 CPPUNIT_ASSERT( fragment->containsNuclei(nucleus) );
315 }
316 }
317 {
318 // tests positions for no containment in otherfragment
319 Fragment::nuclei_t invalidnuclei( createNucleiFromTriple(positions, atomicnumbers, charges) );
320 BOOST_FOREACH( Fragment::nucleus_t nucleus, invalidnuclei) {
321 CPPUNIT_ASSERT( !otherfragment.containsNuclei(nucleus) );
322 }
323 }
324 {
325 // tests otherpositions for containment in otherfragment
326 Fragment::nuclei_t validnuclei( createNucleiFromTriple(otherpositions, otheratomicnumbers, othercharges) );
327 BOOST_FOREACH( Fragment::nucleus_t nucleus, validnuclei) {
328 CPPUNIT_ASSERT( otherfragment.containsNuclei(nucleus) );
329 }
330 }
331 }
332}
333
334/** UnitTest for operator+=()
335 */
336void FragmentTest::operatorPlusEqual_Test()
337{
338 {
339 // create overlapping set (first overlaps)
340 Fragment::positions_t otherpositions;
341 Fragment::position_t otherpos(3, 1.);
342 otherpositions += otherpos;
343 otherpos[0] = 2.;
344 otherpositions += otherpos;
345 otherpos[1] = 2.;
346 otherpositions += otherpos;
347 Fragment::atomicnumbers_t otheratomicnumbers;
348 otheratomicnumbers += 1, 2, 3;
349 Fragment::charges_t othercharges;
350 othercharges += 1., 2., 3.;
351 Fragment otherfragment(otherpositions, otheratomicnumbers, othercharges);
352 const size_t othersize = otherfragment.nuclei.size();
353 const size_t size = fragment->nuclei.size();
354 *fragment += otherfragment;
355 CPPUNIT_ASSERT_EQUAL( othersize, otherfragment.nuclei.size() );
356 CPPUNIT_ASSERT_EQUAL( size+othersize-1, fragment->nuclei.size() ); // one for already present
357 {
358 // tests all for containment
359 Fragment::nuclei_t validnuclei( createNucleiFromTriple(positions, atomicnumbers, charges) );
360 Fragment::nuclei_t othervalidnuclei( createNucleiFromTriple(otherpositions, otheratomicnumbers, othercharges) );
361 validnuclei.insert(validnuclei.end(), othervalidnuclei.begin(), othervalidnuclei.end());
362 BOOST_FOREACH( Fragment::nucleus_t nucleus, validnuclei) {
363 CPPUNIT_ASSERT( fragment->containsNuclei(nucleus) );
364 }
365 }
366 {
367 // tests positions for no containment in otherfragment (but last)
368 Fragment::positions_t lesspositions(positions.begin(), --positions.end());
369 Fragment::atomicnumbers_t lessatomicnumbers(atomicnumbers.begin(), --atomicnumbers.end());
370 Fragment::charges_t lesscharges(charges.begin(), --charges.end());
371 Fragment::nuclei_t invalidnuclei( createNucleiFromTriple(lesspositions, lessatomicnumbers, lesscharges) );
372 BOOST_FOREACH( Fragment::nucleus_t nucleus, invalidnuclei) {
373 CPPUNIT_ASSERT( !otherfragment.containsNuclei(nucleus) );
374 }
375 }
376 {
377 // tests otherpositions for containment in otherfragment
378 Fragment::nuclei_t validnuclei( createNucleiFromTriple(otherpositions, otheratomicnumbers, othercharges) );
379 BOOST_FOREACH( Fragment::nucleus_t nucleus, validnuclei) {
380 CPPUNIT_ASSERT( otherfragment.containsNuclei(nucleus) );
381 }
382 }
383 }
384}
385
386/** UnitTest for operator-=()
387 */
388void FragmentTest::operatorMinusEqual_NonOverlapping_Test()
389{
390 {
391 // create non-overlapping set
392 Fragment::positions_t otherpositions;
393 Fragment::position_t otherpos(3, 2.);
394 otherpositions += otherpos;
395 otherpos[0] = 0.;
396 otherpositions += otherpos;
397 otherpos[1] = 0.;
398 otherpositions += otherpos;
399 Fragment::atomicnumbers_t otheratomicnumbers;
400 otheratomicnumbers += 1, 2, 3;
401 Fragment::charges_t othercharges;
402 othercharges += 1., 2., 3.;
403 Fragment otherfragment(otherpositions, otheratomicnumbers, othercharges);
404 const size_t othersize = otherfragment.nuclei.size();
405 const size_t size = fragment->nuclei.size();
406 *fragment -= otherfragment;
407 CPPUNIT_ASSERT_EQUAL( othersize, otherfragment.nuclei.size() );
408 CPPUNIT_ASSERT_EQUAL( size, fragment->nuclei.size() );
409 {
410 // tests positions for containment
411 Fragment::nuclei_t validnuclei( createNucleiFromTriple(positions, atomicnumbers, charges) );
412 BOOST_FOREACH( Fragment::nucleus_t nucleus, validnuclei) {
413 CPPUNIT_ASSERT( fragment->containsNuclei(nucleus) );
414 }
415 }
416 {
417 // tests otherpositions for no containment
418 Fragment::nuclei_t invalidnuclei( createNucleiFromTriple(otherpositions, otheratomicnumbers, othercharges) );
419 BOOST_FOREACH( Fragment::nucleus_t nucleus, invalidnuclei) {
420 CPPUNIT_ASSERT( !fragment->containsNuclei(nucleus) );
421 }
422 }
423 {
424 // tests positions for no containment in otherfragment
425 Fragment::nuclei_t invalidnuclei( createNucleiFromTriple(positions, atomicnumbers, charges) );
426 BOOST_FOREACH( Fragment::nucleus_t nucleus, invalidnuclei) {
427 CPPUNIT_ASSERT( !otherfragment.containsNuclei(nucleus) );
428 }
429 }
430 {
431 // tests otherpositions for containment in otherfragment
432 Fragment::nuclei_t validnuclei( createNucleiFromTriple(otherpositions, otheratomicnumbers, othercharges) );
433 BOOST_FOREACH( Fragment::nucleus_t nucleus, validnuclei) {
434 CPPUNIT_ASSERT( otherfragment.containsNuclei(nucleus) );
435 }
436 }
437 }
438}
439
440/** UnitTest for operator-=()
441 */
442void FragmentTest::operatorMinusEqual_Test()
443{
444 {
445 // create overlapping set (first overlaps although with different charge)
446 Fragment::positions_t otherpositions;
447 Fragment::position_t otherpos(3, 1.);
448 otherpositions += otherpos;
449 otherpos[0] = 2.;
450 otherpositions += otherpos;
451 otherpos[1] = 2.;
452 otherpositions += otherpos;
453 Fragment::atomicnumbers_t otheratomicnumbers;
454 otheratomicnumbers += 1, 2, 3;
455 Fragment::charges_t othercharges;
456 othercharges += 1., 2., 3.;
457 Fragment otherfragment(otherpositions, otheratomicnumbers, othercharges);
458 const size_t othersize = otherfragment.nuclei.size();
459 const size_t size = fragment->nuclei.size();
460 CPPUNIT_ASSERT( Fragment::isPositionEqual(otherpositions[0],positions[3]) );
461 *fragment -= otherfragment;
462 CPPUNIT_ASSERT_EQUAL( othersize, otherfragment.nuclei.size() );
463 CPPUNIT_ASSERT_EQUAL( size-1, fragment->nuclei.size() ); // just one overlaps
464 {
465 // tests all but last for containment
466 Fragment::nuclei_t validnuclei( createNucleiFromTriple(positions, atomicnumbers, charges) );
467 BOOST_FOREACH( Fragment::nucleus_t nucleus, validnuclei) {
468 if (Fragment::isPositionEqual(nucleus.first, otherpositions[0])) // only test position
469 CPPUNIT_ASSERT( !fragment->containsNuclei(nucleus) );
470 else
471 CPPUNIT_ASSERT( fragment->containsNuclei(nucleus) );
472 }
473 }
474 {
475 // tests positions for no containment in otherfragment
476 Fragment::positions_t lesspositions(positions.begin(), --positions.end());
477 Fragment::atomicnumbers_t lessatomicnumbers(atomicnumbers.begin(), --atomicnumbers.end());
478 Fragment::charges_t lesscharges(charges.begin(), --charges.end());
479 Fragment::nuclei_t invalidnuclei( createNucleiFromTriple(lesspositions, lessatomicnumbers, lesscharges) );
480 BOOST_FOREACH( Fragment::nucleus_t nucleus, invalidnuclei) {
481 CPPUNIT_ASSERT( !otherfragment.containsNuclei(nucleus) );
482 }
483 }
484 {
485 // tests otherpositions for containment in otherfragment
486 Fragment::nuclei_t validnuclei( createNucleiFromTriple(otherpositions, otheratomicnumbers, othercharges) );
487 BOOST_FOREACH( Fragment::nucleus_t nucleus, validnuclei) {
488 CPPUNIT_ASSERT( otherfragment.containsNuclei(nucleus) );
489 }
490 }
491 }
492}
493
494
495
496/** UnitTest for serialization
497 */
498void FragmentTest::serializeTest()
499{
500 // serialize
501 std::stringstream outputstream;
502 boost::archive::text_oarchive oa(outputstream);
503 oa << fragment;
504
505 // deserialize
506 Fragment *samefragment = NULL;
507 std::stringstream returnstream(outputstream.str());
508 boost::archive::text_iarchive ia(returnstream);
509 ia >> samefragment;
510
511 CPPUNIT_ASSERT( samefragment != NULL );
512 CPPUNIT_ASSERT( *fragment == *samefragment );
513
514 delete samefragment;
515}
Note: See TracBrowser for help on using the repository browser.