Index: src/LevMartester.cpp
===================================================================
--- src/LevMartester.cpp	(revision e36ba235524a399519656926a7dd7087945bbbd5)
+++ src/LevMartester.cpp	(revision 05f4378468313b6aa270bc13f5fe8cc378ae33b1)
@@ -221,23 +221,4 @@
 
       // Afterwards we go through all of this type and gather the distance and the energy value
-      Fragment::charges_t h2o;
-      h2o += 8,1,1;
-      TrainingData AngleData(
-          boost::bind(&Extractors::gatherDistancesFromFragment,
-              boost::bind(&Fragment::getPositions, _1),
-              boost::bind(&Fragment::getCharges, _1),
-              boost::cref(h2o),
-              _2)
-          );
-      AngleData(homologies.getHomologousGraphs(graph));
-      LOG(1, "INFO: I gathered the following training data: " << AngleData);
-      // NOTICE that distance are in bohrradi as they come from MPQC!
-
-      // now perform the function approximation by optimizing the model function
-      FunctionModel::parameters_t params(PairPotential_Angle::MAXPARAMS, 0.);
-      params[PairPotential_Angle::energy_offset] =
-          AngleData.getTrainingOutputAverage()[0];// -1.;
-      params[PairPotential_Angle::spring_constant] = 2e+0*rand()/(double)RAND_MAX - 1.;// 1.;
-      params[PairPotential_Angle::equilibrium_distance] = 1e+0*rand()/(double)RAND_MAX;// 0.2;
       PairPotential_Angle::ParticleTypes_t types =
             boost::assign::list_of<PairPotential_Angle::ParticleType_t>
@@ -245,11 +226,19 @@
           ;
       PairPotential_Angle angle(types);
-      LOG(0, "INFO: Initial parameters are " << params << ".");
-      angle.setParameters(params);
+      Fragment::charges_t h2o;
+      h2o += 8,1,1;
+      TrainingData AngleData(angle.getFragmentSpecificExtractor(h2o));
+      AngleData(homologies.getHomologousGraphs(graph));
+      LOG(1, "INFO: I gathered the following training data: " << AngleData);
+      // NOTICE that distance are in bohrradi as they come from MPQC!
+
+      // now perform the function approximation by optimizing the model function
       FunctionModel &model = angle;
       FunctionApproximation approximator(AngleData, model);
       if (model.isBoxConstraint() && approximator.checkParameterDerivatives()) {
         // we set parameters here because we want to test with default ones
-        angle.setParameters(params);
+        srand((unsigned)time(0)); // seed with current time
+        model.setParametersToRandomInitialValues(AngleData);
+        LOG(0, "INFO: Initial parameters are " << angle.getParameters() << ".");
         approximator(FunctionApproximation::ParameterDerivative);
       } else {
@@ -275,16 +264,4 @@
       Fragment::charges_t h2o;
       h2o += 8,1;
-      TrainingData MorseData(
-          boost::bind(&Extractors::gatherDistancesFromFragment,
-              boost::bind(&Fragment::getPositions, _1),
-              boost::bind(&Fragment::getCharges, _1),
-              boost::cref(h2o),
-              _2)
-          );
-      MorseData(homologies.getHomologousGraphs(graph));
-      LOG(1, "INFO: I gathered the following training data: " << MorseData);
-      // NOTICE that distance are in bohrradi as they come from MPQC!
-
-      // now perform the function approximation by optimizing the model function
       PairPotential_Morse::ParticleTypes_t types =
             boost::assign::list_of<PairPotential_Morse::ParticleType_t>
@@ -292,14 +269,17 @@
           ;
       PairPotential_Morse morse(types);
+      TrainingData MorseData(morse.getFragmentSpecificExtractor(h2o));
+      MorseData(homologies.getHomologousGraphs(graph));
+      LOG(1, "INFO: I gathered the following training data: " << MorseData);
+      // NOTICE that distance are in bohrradi as they come from MPQC!
+
+      // now perform the function approximation by optimizing the model function
       FunctionModel &model = morse;
-      FunctionApproximation approximator(MorseData, model);
-      FunctionModel::triplefunction_t triplefunction =
-          boost::bind(&getTripleFromArgument, boost::cref(MorseData.getTrainingInputs()), _1, _2);
+      FunctionApproximation approximator(MorseData, model); // we only give CC distance, hence 1 input dim
       if (model.isBoxConstraint() && approximator.checkParameterDerivatives()) {
         // we set parameters here because we want to test with default ones
         srand((unsigned)time(0)); // seed with current time
         model.setParametersToRandomInitialValues(MorseData);
-        model.setTriplefunction(triplefunction);
-        LOG(0, "INFO: Initial parameters are " << model.getParameters() << ".");
+        LOG(0, "INFO: Initial parameters are " << morse.getParameters() << ".");
         approximator(FunctionApproximation::ParameterDerivative);
       } else {
@@ -325,26 +305,19 @@
       Fragment::charges_t h2o;
       h2o += 8,1,1;
-      TrainingData TersoffData(
-          boost::bind(&Extractors::gatherDistancesFromFragment,
-              boost::bind(&Fragment::getPositions, _1),
-              boost::bind(&Fragment::getCharges, _1),
-              boost::cref(h2o),
-              _2)
-          );
-//          TrainingData::extractor_t(&Extractors::gatherAllSymmetricDistances) // gather first carbon pair
-//          );
-      TersoffData( homologies.getHomologousGraphs(graph) );
-      LOG(1, "INFO: I gathered the following training data: " << TersoffData);
-      // NOTICE that distance are in bohrradi as they come from MPQC!
-
-      // now perform the function approximation by optimizing the model function
-      boost::function< std::vector<FunctionModel::arguments_t>(const argument_t &, const double)> triplefunction =
-          boost::bind(&getTripleFromArgument, boost::cref(TersoffData.getTrainingInputs()), _1, _2);
       SaturationPotential::ParticleTypes_t types =
             boost::assign::list_of<SaturationPotential::ParticleType_t>
             (8)(1)
           ;
-
       SaturationPotential saturation(types);
+      TrainingData TersoffData(saturation.getFragmentSpecificExtractor(h2o));
+      boost::function< std::vector<FunctionModel::arguments_t>(const argument_t &, const double)> triplefunction =
+          boost::bind(&getTripleFromArgument, boost::cref(TersoffData.getTrainingInputs()), _1, _2);
+      saturation.setTriplefunction(triplefunction);
+
+      TersoffData( homologies.getHomologousGraphs(graph) );
+      LOG(1, "INFO: I gathered the following training data: " << TersoffData);
+      // NOTICE that distance are in bohrradi as they come from MPQC!
+
+      // now perform the function approximation by optimizing the model function
       FunctionModel &model = saturation;
       FunctionApproximation approximator(TersoffData, model); // CH4 has 5 atoms, hence 5*4/2 distances
@@ -353,5 +326,4 @@
         srand((unsigned)time(0)); // seed with current time
         model.setParametersToRandomInitialValues(TersoffData);
-        model.setTriplefunction(triplefunction);
         approximator(FunctionApproximation::ParameterDerivative);
       } else {
@@ -362,20 +334,4 @@
       LOG(0, "RESULT: " << saturation << ".");
 
-  //    std::cout << "\tsaturationparticle:";
-  //    std::cout << "\tparticle_type=C,";
-  //    std::cout << "\tA=" << params[SaturationPotential::A] << ",";
-  //    std::cout << "\tB=" << params[SaturationPotential::B] << ",";
-  //    std::cout << "\tlambda=" << params[SaturationPotential::lambda] << ",";
-  //    std::cout << "\tmu=" << params[SaturationPotential::mu] << ",";
-  //    std::cout << "\tbeta=" << params[SaturationPotential::beta] << ",";
-  //    std::cout << "\tn=" << params[SaturationPotential::n] << ",";
-  //    std::cout << "\tc=" << params[SaturationPotential::c] << ",";
-  //    std::cout << "\td=" << params[SaturationPotential::d] << ",";
-  //    std::cout << "\th=" << params[SaturationPotential::h] << ",";
-  ////    std::cout << "\toffset=" << params[SaturationPotential::offset] << ",";
-  //    std::cout << "\tR=" << saturation.R << ",";
-  //    std::cout << "\tS=" << saturation.S << ";";
-  //    std::cout << std::endl;
-
       // check L2 and Lmax error against training set
       LOG(1, "INFO: L2sum = " << TersoffData.getL2Error(model)
