// --------------------------------------------------------------------------
//                   OpenMS -- Open-Source Mass Spectrometry               
// --------------------------------------------------------------------------
// Copyright The OpenMS Team -- Eberhard Karls University Tuebingen,
// ETH Zurich, and Freie Universitaet Berlin 2002-2013.
// 
// This software is released under a three-clause BSD license:
//  * Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
//  * Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in the
//    documentation and/or other materials provided with the distribution.
//  * Neither the name of any author or any participating institution 
//    may be used to endorse or promote products derived from this software 
//    without specific prior written permission.
// For a full list of authors, refer to the file AUTHORS. 
// --------------------------------------------------------------------------
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL ANY OF THE AUTHORS OR THE CONTRIBUTING 
// INSTITUTIONS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// 
// --------------------------------------------------------------------------
// $Maintainer: Andreas Bertsch $
// $Authors: Andreas Bertsch $
// --------------------------------------------------------------------------

#include <OpenMS/CONCEPT/ClassTest.h>

///////////////////////////
#include <OpenMS/KERNEL/MSChromatogram.h>
///////////////////////////

using namespace OpenMS;
using namespace std;

START_TEST(MSChromatogram, "$Id: MSChromatogram_test.C 10915 2013-04-04 20:14:57Z aiche $")

/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////

MSChromatogram<ChromatogramPeak>* ptr = 0;
MSChromatogram<ChromatogramPeak>* nullPointer = 0;
START_SECTION(MSChromatogram())
{
	ptr = new MSChromatogram<ChromatogramPeak>();
	TEST_NOT_EQUAL(ptr, nullPointer)
}
END_SECTION

START_SECTION(virtual ~MSChromatogram())
{
	delete ptr;
}
END_SECTION

ptr = new MSChromatogram<ChromatogramPeak>();
ChromatogramPeak p1;
p1.setIntensity(1.0f);
p1.setRT(2.0);

ChromatogramPeak p2;
p2.setIntensity(2.0f);
p2.setRT(10.0);

ChromatogramPeak p3;
p3.setIntensity(3.0f);
p3.setRT(30.0);


START_SECTION((const String& getName() const ))
{
  TEST_STRING_EQUAL(ptr->getName(), "")
	ptr->setName("my_fancy_name");
	TEST_STRING_EQUAL(ptr->getName(), "my_fancy_name")
}
END_SECTION

START_SECTION((void setName(const String &name)))
{
  NOT_TESTABLE // tested above
}
END_SECTION

START_SECTION((const FloatDataArrays& getFloatDataArrays() const ))
{
  MSChromatogram<> chrom;
	TEST_EQUAL(chrom.getFloatDataArrays().size(),0)
}
END_SECTION

START_SECTION((FloatDataArrays& getFloatDataArrays()))
{
	MSChromatogram<> chrom;
	chrom.getFloatDataArrays().resize(2);
	TEST_EQUAL(chrom.getFloatDataArrays().size(), 2)
}
END_SECTION

START_SECTION((const StringDataArrays& getStringDataArrays() const ))
{
  MSChromatogram<> chrom;
  TEST_EQUAL(chrom.getStringDataArrays().size(),0)
}
END_SECTION

START_SECTION((StringDataArrays& getStringDataArrays()))
{
  MSChromatogram<> chrom;
  chrom.getStringDataArrays().resize(2);
  TEST_EQUAL(chrom.getStringDataArrays().size(), 2)
}
END_SECTION

START_SECTION((const IntegerDataArrays& getIntegerDataArrays() const ))
{
	MSChromatogram<> chrom;
  TEST_EQUAL(chrom.getIntegerDataArrays().size(), 0)
}
END_SECTION

START_SECTION((IntegerDataArrays& getIntegerDataArrays()))
{
	MSChromatogram<> chrom;
  chrom.getIntegerDataArrays().resize(2);
  TEST_EQUAL(chrom.getIntegerDataArrays().size(), 2)
}
END_SECTION

START_SECTION((void sortByIntensity(bool reverse=false)))
{
  MSChromatogram<> ds;
  ChromatogramPeak p;
  MSChromatogram<>::FloatDataArray float_array;
  MSChromatogram<>::StringDataArray string_array;
  MSChromatogram<>::IntegerDataArray int_array;
  std::vector<DoubleReal> rts, intensities;
  MSChromatogram<>::IntegerDataArray in_array;
  intensities.push_back(201); rts.push_back(420.130); float_array.push_back(420.130f); string_array.push_back("420.13"); int_array.push_back(420);
  intensities.push_back(60);  rts.push_back(412.824); float_array.push_back(412.824f); string_array.push_back("412.82"); int_array.push_back(412);
  intensities.push_back(56);  rts.push_back(423.269); float_array.push_back(423.269f); string_array.push_back("423.27"); int_array.push_back(423);
  intensities.push_back(37);  rts.push_back(415.287); float_array.push_back(415.287f); string_array.push_back("415.29"); int_array.push_back(415);
  intensities.push_back(34);  rts.push_back(413.800); float_array.push_back(413.800f); string_array.push_back("413.80"); int_array.push_back(413);
  intensities.push_back(31);  rts.push_back(419.113); float_array.push_back(419.113f); string_array.push_back("419.11"); int_array.push_back(419);
  intensities.push_back(31);  rts.push_back(416.293); float_array.push_back(416.293f); string_array.push_back("416.29"); int_array.push_back(416);
  intensities.push_back(31);  rts.push_back(418.232); float_array.push_back(418.232f); string_array.push_back("418.23"); int_array.push_back(418);
  intensities.push_back(29);  rts.push_back(414.301); float_array.push_back(414.301f); string_array.push_back("414.30"); int_array.push_back(414);
  intensities.push_back(29);  rts.push_back(412.321); float_array.push_back(412.321f); string_array.push_back("412.32"); int_array.push_back(412);

  for (Size i = 0; i < rts.size(); ++i)
  {
    p.setIntensity(intensities[i]); 
		p.setRT(rts[i]);
    ds.push_back(p);
  }
  ds.sortByIntensity();
  std::vector<DoubleReal> intensities_copy(intensities);
  std::sort(intensities_copy.begin(),intensities_copy.end());
  MSChromatogram<>::iterator it_ds = ds.begin();
  for(std::vector<DoubleReal>::iterator it = intensities_copy.begin(); it != intensities_copy.end(); ++it)
  {
    if(it_ds == ds.end())
    {
      TEST_EQUAL(true,false)
    }
    TEST_EQUAL(it_ds->getIntensity(), *it);
    ++it_ds;
  }
  
	ds.clear(true);
  for (Size i = 0; i < rts.size(); ++i)
  {
    p.setIntensity(intensities[i]); 
		p.setRT(rts[i]);
    ds.push_back(p);
  }
  intensities_copy = intensities;
  std::sort(intensities_copy.begin(),intensities_copy.end());

  ds.getFloatDataArrays() = std::vector<MSChromatogram<>::FloatDataArray>(3,float_array);
  ds.getFloatDataArrays()[0].setName("f1");
  ds.getFloatDataArrays()[1].setName("f2");
  ds.getFloatDataArrays()[2].setName("f3");

  ds.getStringDataArrays() = std::vector<MSChromatogram<>::StringDataArray>(2, string_array);
  ds.getStringDataArrays()[0].setName("s1");
  ds.getStringDataArrays()[1].setName("s2");

  ds.getIntegerDataArrays() = std::vector<MSChromatogram<>::IntegerDataArray>(1, int_array);
  ds.getIntegerDataArrays()[0].setName("i1");

  ds.sortByIntensity();

  TEST_STRING_EQUAL(ds.getFloatDataArrays()[0].getName(),"f1")
  TEST_STRING_EQUAL(ds.getFloatDataArrays()[1].getName(),"f2")
  TEST_STRING_EQUAL(ds.getFloatDataArrays()[2].getName(),"f3")

  TEST_STRING_EQUAL(ds.getStringDataArrays()[0].getName(),"s1")
  TEST_STRING_EQUAL(ds.getStringDataArrays()[1].getName(),"s2")

  TEST_STRING_EQUAL(ds.getIntegerDataArrays()[0].getName(),"i1")

  MSChromatogram<>::iterator it1 = ds.begin();
  MSChromatogram<>::FloatDataArray::iterator it2 = ds.getFloatDataArrays()[1].begin();
  MSChromatogram<>::StringDataArray::iterator it3 = ds.getStringDataArrays()[0].begin();
  MSChromatogram<>::IntegerDataArray::iterator it4 = ds.getIntegerDataArrays()[0].begin();
  TOLERANCE_ABSOLUTE(0.0001)
  for(std::vector<DoubleReal>::iterator it = intensities_copy.begin(); it != intensities_copy.end(); ++it)
  {
    if(it1 != ds.end() && it2 != ds.getFloatDataArrays()[1].end() && it3 != ds.getStringDataArrays()[0].end() && it4 != ds.getIntegerDataArrays()[0].end())
    {
      //metadataarray values == mz values
      TEST_REAL_SIMILAR(it1->getIntensity(), *it);
      TEST_REAL_SIMILAR(*it2 , it1->getRT());
      TEST_STRING_EQUAL(*it3 , String::number(it1->getRT(),2));
      TEST_EQUAL(*it4 , (Int)floor(it1->getRT()));
      ++it1;
      ++it2;
      ++it3;
      ++it4;
    }
    else
    {
      TEST_EQUAL(true,false)
    }
  }
}
END_SECTION

START_SECTION((void sortByPosition()))
{
  MSChromatogram<> ds;
  ChromatogramPeak p;
  MSChromatogram<>::FloatDataArray float_array;
  MSChromatogram<>::StringDataArray string_array;
  MSChromatogram<>::IntegerDataArray int_array;
  std::vector<DoubleReal> rts, intensities;
  intensities.push_back(56);  rts.push_back(423.269); float_array.push_back(56);  string_array.push_back("56");  int_array.push_back(56);
  intensities.push_back(201); rts.push_back(420.130); float_array.push_back(201); string_array.push_back("201"); int_array.push_back(201);
  intensities.push_back(31);  rts.push_back(419.113); float_array.push_back(31);  string_array.push_back("31");  int_array.push_back(31);
  intensities.push_back(31);  rts.push_back(418.232); float_array.push_back(31);  string_array.push_back("31");  int_array.push_back(31);
  intensities.push_back(31);  rts.push_back(416.293); float_array.push_back(31);  string_array.push_back("31");  int_array.push_back(31);
  intensities.push_back(37);  rts.push_back(415.287); float_array.push_back(37);  string_array.push_back("37");  int_array.push_back(37);
  intensities.push_back(29);  rts.push_back(414.301); float_array.push_back(29);  string_array.push_back("29");  int_array.push_back(29);
  intensities.push_back(34);  rts.push_back(413.800); float_array.push_back(34);  string_array.push_back("34");  int_array.push_back(34);
  intensities.push_back(60);  rts.push_back(412.824); float_array.push_back(60);  string_array.push_back("60");  int_array.push_back(60);
  intensities.push_back(29);  rts.push_back(412.321); float_array.push_back(29);  string_array.push_back("29");  int_array.push_back(29);

  for (Size i = 0; i < rts.size(); ++i)
  {
    p.setIntensity(intensities[i]); p.setRT(rts[i]);
    ds.push_back(p);
  }
  ds.sortByPosition();
  MSChromatogram<>::iterator it = ds.begin();
  for(std::vector<DoubleReal>::reverse_iterator rit = intensities.rbegin(); rit != intensities.rend(); ++rit)
  {
    if(it == ds.end())
    {
      TEST_EQUAL(true,false)
    }
    TEST_EQUAL(it->getIntensity(), *rit);
    ++it;
  }
  ds.clear(true);
  for (Size i = 0; i < rts.size(); ++i)
  {
    p.setIntensity(intensities[i]); p.setRT(rts[i]);
    ds.push_back(p);
  }
  ds.getFloatDataArrays() = std::vector<MSChromatogram<>::FloatDataArray>(3,float_array);
  ds.getFloatDataArrays()[0].setName("f1");
  ds.getFloatDataArrays()[1].setName("f2");
  ds.getFloatDataArrays()[2].setName("f3");

  ds.getStringDataArrays() = std::vector<MSChromatogram<>::StringDataArray>(2, string_array);
  ds.getStringDataArrays()[0].setName("s1");
  ds.getStringDataArrays()[1].setName("s2");

  ds.getIntegerDataArrays() = std::vector<MSChromatogram<>::IntegerDataArray>(2, int_array);
  ds.getIntegerDataArrays()[0].setName("i1");

  ds.sortByPosition();

  TEST_STRING_EQUAL(ds.getFloatDataArrays()[0].getName(),"f1")
  TEST_STRING_EQUAL(ds.getFloatDataArrays()[1].getName(),"f2")
  TEST_STRING_EQUAL(ds.getFloatDataArrays()[2].getName(),"f3")

  TEST_STRING_EQUAL(ds.getStringDataArrays()[0].getName(),"s1")
  TEST_STRING_EQUAL(ds.getStringDataArrays()[1].getName(),"s2")

  TEST_STRING_EQUAL(ds.getIntegerDataArrays()[0].getName(),"i1")

  MSChromatogram<>::iterator it1 = ds.begin();
  MSChromatogram<>::FloatDataArray::iterator it2 = ds.getFloatDataArrays()[1].begin();
  MSChromatogram<>::StringDataArray::iterator it3 = ds.getStringDataArrays()[0].begin();
  MSChromatogram<>::IntegerDataArray::iterator it4 = ds.getIntegerDataArrays()[0].begin();
  for(std::vector<DoubleReal>::reverse_iterator rit = intensities.rbegin(); rit != intensities.rend(); ++rit)
  {
    if(it1 != ds.end() && it2 != ds.getFloatDataArrays()[1].end() && it3 != ds.getStringDataArrays()[0].end())
    {
      //metadataarray values == intensity values
      TEST_REAL_SIMILAR(it1->getIntensity(), *rit);
      TEST_REAL_SIMILAR(*it2 , *rit);
      TEST_STRING_EQUAL(*it3 , String::number(*rit,0));
      TEST_EQUAL(*it4 , (Int)floor(*rit));
      ++it1;
      ++it2;
      ++it3;
      ++it4;
    }
    else
    {
      TEST_EQUAL(true,false)
    }
  }

}
END_SECTION

START_SECTION((bool isSorted() const ))
{
  //make test dataset
  MSChromatogram<> spec;
  ChromatogramPeak p;
  p.setIntensity(1.0);
  p.setRT(1000.0);
  spec.push_back(p);

  p.setIntensity(1.0);
  p.setRT(1001.0);
  spec.push_back(p);

  p.setIntensity(1.0);
  p.setRT(1002.0);
  spec.push_back(p);

  TEST_EQUAL(spec.isSorted(),true)

  reverse(spec.begin(), spec.end());
  TEST_EQUAL(spec.isSorted(),false)

}
END_SECTION

START_SECTION((Size findNearest(CoordinateType rt) const ))
{
  MSChromatogram<> tmp;
  ChromatogramPeak p;
  p.setIntensity(29.0f); p.setRT(412.321); tmp.push_back(p); //0
  p.setIntensity(60.0f); p.setRT(412.824); tmp.push_back(p); //1
  p.setIntensity(34.0f); p.setRT(413.8); tmp.push_back(p); //2
  p.setIntensity(29.0f); p.setRT(414.301); tmp.push_back(p); //3
  p.setIntensity(37.0f); p.setRT(415.287); tmp.push_back(p); //4
  p.setIntensity(31.0f); p.setRT(416.293); tmp.push_back(p); //5
  p.setIntensity(31.0f); p.setRT(418.232); tmp.push_back(p); //6
  p.setIntensity(31.0f); p.setRT(419.113); tmp.push_back(p); //7
  p.setIntensity(201.0f); p.setRT(420.13); tmp.push_back(p); //8
  p.setIntensity(56.0f); p.setRT(423.269); tmp.push_back(p); //9
  p.setIntensity(34.0f); p.setRT(426.292); tmp.push_back(p); //10
  p.setIntensity(82.0f); p.setRT(427.28); tmp.push_back(p); //11
  p.setIntensity(87.0f); p.setRT(428.322); tmp.push_back(p); //12
  p.setIntensity(30.0f); p.setRT(430.269); tmp.push_back(p); //13
  p.setIntensity(29.0f); p.setRT(431.246); tmp.push_back(p); //14
  p.setIntensity(42.0f); p.setRT(432.289); tmp.push_back(p); //15
  p.setIntensity(32.0f); p.setRT(436.161); tmp.push_back(p); //16
  p.setIntensity(54.0f); p.setRT(437.219); tmp.push_back(p); //17
  p.setIntensity(40.0f); p.setRT(439.186); tmp.push_back(p); //18
  p.setIntensity(40); p.setRT(440.27); tmp.push_back(p); //19
  p.setIntensity(23.0f); p.setRT(441.224); tmp.push_back(p); //20

  //test outside mass range
  TEST_EQUAL(tmp.findNearest(400.0),0);
  TEST_EQUAL(tmp.findNearest(500.0),20);
  //test mass range borders
  TEST_EQUAL(tmp.findNearest(412.4),0);
  TEST_EQUAL(tmp.findNearest(441.224),20);
  //test inside scan
  TEST_EQUAL(tmp.findNearest(426.29),10);
  TEST_EQUAL(tmp.findNearest(426.3),10);
  TEST_EQUAL(tmp.findNearest(427.2),11);
  TEST_EQUAL(tmp.findNearest(427.3),11);

  //empty spectrum
  MSChromatogram<> tmp2;
  TEST_PRECONDITION_VIOLATED(tmp2.findNearest(427.3));
}
END_SECTION


START_SECTION((Iterator RTBegin(CoordinateType rt)))
{
  MSChromatogram<> tmp;
  MSChromatogram<>::PeakType rdp;
  rdp.getPosition()[0] = 1.0;
  tmp.push_back(rdp);
  rdp.getPosition()[0] = 2.0;
  tmp.push_back(rdp);
  rdp.getPosition()[0] = 3.0;
  tmp.push_back(rdp);
  rdp.getPosition()[0] = 4.0;
  tmp.push_back(rdp);
  rdp.getPosition()[0] = 5.0;
  tmp.push_back(rdp);
  rdp.getPosition()[0] = 6.0;
  tmp.push_back(rdp);
  rdp.getPosition()[0] = 7.0;
  tmp.push_back(rdp);

  MSChromatogram<>::Iterator it;

  it = tmp.RTBegin(4.5);
  TEST_EQUAL(it->getPosition()[0],5.0)
  it = tmp.RTBegin(5.0);
  TEST_EQUAL(it->getPosition()[0],5.0)
  it = tmp.RTBegin(5.5);
  TEST_EQUAL(it->getPosition()[0],6.0)
}
END_SECTION

START_SECTION((Iterator RTBegin(Iterator begin, CoordinateType rt, Iterator end)))
{
  MSChromatogram<> tmp;
  MSChromatogram<>::PeakType rdp;
  rdp.getPosition()[0] = 1.0;
  tmp.push_back(rdp);
  rdp.getPosition()[0] = 2.0;
  tmp.push_back(rdp);
  rdp.getPosition()[0] = 3.0;
  tmp.push_back(rdp);
  rdp.getPosition()[0] = 4.0;
  tmp.push_back(rdp);
  rdp.getPosition()[0] = 5.0;
  tmp.push_back(rdp);
  rdp.getPosition()[0] = 6.0;
  tmp.push_back(rdp);
  rdp.getPosition()[0] = 7.0;
  tmp.push_back(rdp);

  MSChromatogram<>::Iterator it;

  it = tmp.RTBegin(tmp.begin(), 4.5, tmp.end());
  TEST_EQUAL(it->getPosition()[0],5.0)
  it = tmp.RTBegin(tmp.begin(), 4.5, tmp.end());
  TEST_EQUAL(it->getPosition()[0],5.0)
  it = tmp.RTBegin(tmp.begin(), 4.5, tmp.begin());
  TEST_EQUAL(it->getPosition()[0],tmp.begin()->getPosition()[0])

}
END_SECTION

START_SECTION((Iterator RTEnd(CoordinateType rt)))
{
  MSChromatogram<> tmp;
  MSChromatogram<>::PeakType rdp;
  rdp.getPosition()[0] = 1.0;
  tmp.push_back(rdp);
  rdp.getPosition()[0] = 2.0;
  tmp.push_back(rdp);
  rdp.getPosition()[0] = 3.0;
  tmp.push_back(rdp);
  rdp.getPosition()[0] = 4.0;
  tmp.push_back(rdp);
  rdp.getPosition()[0] = 5.0;
  tmp.push_back(rdp);
  rdp.getPosition()[0] = 6.0;
  tmp.push_back(rdp);
  rdp.getPosition()[0] = 7.0;
  tmp.push_back(rdp);

  MSChromatogram<>::Iterator it;

  it = tmp.RTBegin(4.5);
  TEST_EQUAL(it->getPosition()[0],5.0)
  it = tmp.RTBegin(5.0);
  TEST_EQUAL(it->getPosition()[0],5.0)
  it = tmp.RTBegin(5.5);
  TEST_EQUAL(it->getPosition()[0],6.0)
}
END_SECTION

START_SECTION((Iterator RTEnd(Iterator begin, CoordinateType rt, Iterator end)))
{
  MSChromatogram<> tmp;
  MSChromatogram<>::PeakType rdp;
  rdp.getPosition()[0] = 1.0;
  tmp.push_back(rdp);
  rdp.getPosition()[0] = 2.0;
  tmp.push_back(rdp);
  rdp.getPosition()[0] = 3.0;
  tmp.push_back(rdp);
  rdp.getPosition()[0] = 4.0;
  tmp.push_back(rdp);
  rdp.getPosition()[0] = 5.0;
  tmp.push_back(rdp);
  rdp.getPosition()[0] = 6.0;
  tmp.push_back(rdp);
  rdp.getPosition()[0] = 7.0;
  tmp.push_back(rdp);

  MSChromatogram<>::Iterator it;

  it = tmp.RTBegin(tmp.begin(), 4.5, tmp.end());
  TEST_EQUAL(it->getPosition()[0],5.0)
  it = tmp.RTBegin(tmp.begin(), 4.5, tmp.end());
  TEST_EQUAL(it->getPosition()[0],5.0)
  it = tmp.RTBegin(tmp.begin(), 4.5, tmp.begin());
  TEST_EQUAL(it->getPosition()[0],tmp.begin()->getPosition()[0])
}
END_SECTION

START_SECTION((ConstIterator RTBegin(CoordinateType rt) const ))
{
  MSChromatogram<> tmp;
  MSChromatogram<>::PeakType rdp;
  rdp.getPosition()[0] = 1.0;
  tmp.push_back(rdp);
  rdp.getPosition()[0] = 2.0;
  tmp.push_back(rdp);
  rdp.getPosition()[0] = 3.0;
  tmp.push_back(rdp);
  rdp.getPosition()[0] = 4.0;
  tmp.push_back(rdp);
  rdp.getPosition()[0] = 5.0;
  tmp.push_back(rdp);
  rdp.getPosition()[0] = 6.0;
  tmp.push_back(rdp);
  rdp.getPosition()[0] = 7.0;
  tmp.push_back(rdp);

  MSChromatogram<>::ConstIterator it;

  it = tmp.RTEnd(4.5);
  TEST_EQUAL(it->getPosition()[0],5.0)
  it = tmp.RTEnd(5.0);
  TEST_EQUAL(it->getPosition()[0],6.0)
  it = tmp.RTEnd(5.5);
  TEST_EQUAL(it->getPosition()[0],6.0)

}
END_SECTION

START_SECTION((ConstIterator RTBegin(ConstIterator begin, CoordinateType rt, ConstIterator end) const ))
{
  MSChromatogram<> tmp;
  MSChromatogram<>::PeakType rdp;
  rdp.getPosition()[0] = 1.0;
  tmp.push_back(rdp);
  rdp.getPosition()[0] = 2.0;
  tmp.push_back(rdp);
  rdp.getPosition()[0] = 3.0;
  tmp.push_back(rdp);
  rdp.getPosition()[0] = 4.0;
  tmp.push_back(rdp);
  rdp.getPosition()[0] = 5.0;
  tmp.push_back(rdp);
  rdp.getPosition()[0] = 6.0;
  tmp.push_back(rdp);
  rdp.getPosition()[0] = 7.0;
  tmp.push_back(rdp);

  MSChromatogram<>::ConstIterator it;

  it = tmp.RTBegin(tmp.begin(), 4.5, tmp.end());
  TEST_EQUAL(it->getPosition()[0],5.0)
  it = tmp.RTBegin(tmp.begin(), 4.5, tmp.end());
  TEST_EQUAL(it->getPosition()[0],5.0)
  it = tmp.RTBegin(tmp.begin(), 4.5, tmp.begin());
  TEST_EQUAL(it->getPosition()[0],tmp.begin()->getPosition()[0])
}
END_SECTION

START_SECTION((ConstIterator RTEnd(CoordinateType rt) const ))
{
  MSChromatogram<> tmp;
  MSChromatogram<>::PeakType rdp;
  rdp.getPosition()[0] = 1.0;
  tmp.push_back(rdp);
  rdp.getPosition()[0] = 2.0;
  tmp.push_back(rdp);
  rdp.getPosition()[0] = 3.0;
  tmp.push_back(rdp);
  rdp.getPosition()[0] = 4.0;
  tmp.push_back(rdp);
  rdp.getPosition()[0] = 5.0;
  tmp.push_back(rdp);
  rdp.getPosition()[0] = 6.0;
  tmp.push_back(rdp);
  rdp.getPosition()[0] = 7.0;
  tmp.push_back(rdp);

  MSChromatogram<>::ConstIterator it;

  it = tmp.RTBegin(4.5);
  TEST_EQUAL(it->getPosition()[0],5.0)
  it = tmp.RTBegin(5.0);
  TEST_EQUAL(it->getPosition()[0],5.0)
  it = tmp.RTBegin(5.5);
  TEST_EQUAL(it->getPosition()[0],6.0)

}
END_SECTION

START_SECTION((ConstIterator RTEnd(ConstIterator begin, CoordinateType rt, ConstIterator end) const ))
{
  MSChromatogram<> tmp;
  MSChromatogram<>::PeakType rdp;
  rdp.getPosition()[0] = 1.0;
  tmp.push_back(rdp);
  rdp.getPosition()[0] = 2.0;
  tmp.push_back(rdp);
  rdp.getPosition()[0] = 3.0;
  tmp.push_back(rdp);
  rdp.getPosition()[0] = 4.0;
  tmp.push_back(rdp);
  rdp.getPosition()[0] = 5.0;
  tmp.push_back(rdp);
  rdp.getPosition()[0] = 6.0;
  tmp.push_back(rdp);
  rdp.getPosition()[0] = 7.0;
  tmp.push_back(rdp);

  MSChromatogram<>::ConstIterator it;

  it = tmp.RTEnd(tmp.begin(), 4.5, tmp.end());
  TEST_EQUAL(it->getPosition()[0],5.0)
  it = tmp.RTEnd(tmp.begin(), 5, tmp.end());
  TEST_EQUAL(it->getPosition()[0],6.0)
  it = tmp.RTEnd(tmp.begin(), 4.5, tmp.begin());
  TEST_EQUAL(it->getPosition()[0],tmp.begin()->getPosition()[0])
}
END_SECTION

START_SECTION((MSChromatogram(const MSChromatogram &source)))
{
  MSChromatogram<> tmp;
  tmp.getInstrumentSettings().getScanWindows().resize(1);
  tmp.setMetaValue("label",5.0);
	Product prod;
	prod.setMZ(7.0);
	tmp.setProduct(prod);
  tmp.setName("bla");
  //peaks
  MSChromatogram<>::PeakType peak;
  peak.getPosition()[0] = 47.11;
  tmp.push_back(peak);

  MSChromatogram<> tmp2(tmp);
  TEST_EQUAL(tmp2.getInstrumentSettings().getScanWindows().size(),1);
  TEST_REAL_SIMILAR(tmp2.getMetaValue("label"), 5.0)
  TEST_REAL_SIMILAR(tmp2.getMZ(), 7.0)
  TEST_EQUAL(tmp2.getName(),"bla")
  //peaks
  TEST_EQUAL(tmp2.size(),1);
  TEST_REAL_SIMILAR(tmp2[0].getPosition()[0],47.11);
  
}
END_SECTION

START_SECTION((MSChromatogram& operator=(const MSChromatogram &source)))
{
  MSChromatogram<> tmp;
  tmp.setMetaValue("label",5.0);
	Product prod;
	prod.setMZ(7.0);
	tmp.setProduct(prod);
  tmp.setName("bla");
  //peaks
  MSChromatogram<>::PeakType peak;
  peak.getPosition()[0] = 47.11;
  tmp.push_back(peak);

  //normal assignment
  MSChromatogram<> tmp2;
  tmp2 = tmp;
  TEST_REAL_SIMILAR(tmp2.getMetaValue("label"), 5.0)
  TEST_REAL_SIMILAR(tmp2.getMZ(), 7.0)
  TEST_EQUAL(tmp2.getName(),"bla")
  TEST_EQUAL(tmp2.size(),1);
  TEST_REAL_SIMILAR(tmp2[0].getPosition()[0],47.11);

  //Assignment of empty object
  //normal assignment
  tmp2 = MSChromatogram<>();
  TEST_EQUAL(tmp2.getInstrumentSettings().getScanWindows().size(),0);
  TEST_EQUAL(tmp2.metaValueExists("label"), false)
  TEST_REAL_SIMILAR(tmp2.getMZ(), 0.0)
  TEST_EQUAL(tmp2.getName(),"")
  TEST_EQUAL(tmp2.size(),0);
}
END_SECTION

START_SECTION((bool operator==(const MSChromatogram &rhs) const ))
{
  MSChromatogram<> edit, empty;

  TEST_EQUAL(edit==empty,true);

  edit = empty;
  edit.resize(1);
  TEST_EQUAL(edit==empty,false);

  edit = empty;
  edit.setMetaValue("label",String("bla"));
  TEST_EQUAL(empty==edit, false);

	Product prod;
	prod.setMZ(5);
	edit.setProduct(prod);
  TEST_EQUAL(empty==edit, false);

  edit = empty;
  edit.getFloatDataArrays().resize(5);
  TEST_EQUAL(empty==edit, false);

  edit = empty;
  edit.getStringDataArrays().resize(5);
  TEST_EQUAL(empty==edit, false);

  edit = empty;
  edit.getIntegerDataArrays().resize(5);
  TEST_EQUAL(empty==edit, false);

  //name is not checked => no change
  edit = empty;
  edit.setName("bla");
  TEST_EQUAL(empty==edit, true);

  edit = empty;
  edit.push_back(p1);
  edit.push_back(p2);
  edit.updateRanges();
  edit.clear(false);
  TEST_EQUAL(empty==edit, false);

}
END_SECTION

START_SECTION((bool operator!=(const MSChromatogram &rhs) const ))
{
  MSChromatogram<> edit, empty;

  TEST_EQUAL(edit!=empty,false);

  edit = empty;
  edit.getInstrumentSettings().getScanWindows().resize(1);
  TEST_EQUAL(edit!=empty,true);

  edit = empty;
  edit.resize(1);
  TEST_EQUAL(edit!=empty,true);

  edit = empty;
  edit.setMetaValue("label",String("bla"));
  TEST_EQUAL(edit!=empty,true);

	Product prod;
	prod.setMZ(5);
  edit.setProduct(prod);
  TEST_EQUAL(edit!=empty,true);

  edit = empty;
  edit.getFloatDataArrays().resize(5);
  TEST_EQUAL(edit!=empty,true);

  edit = empty;
  edit.getIntegerDataArrays().resize(5);
  TEST_EQUAL(edit!=empty,true);

  edit = empty;
  edit.getStringDataArrays().resize(5);
  TEST_EQUAL(edit!=empty,true);

  //name is not checked => no change
  edit = empty;
  edit.setName("bla");
  TEST_EQUAL(edit!=empty,false);

  edit = empty;
  edit.push_back(p1);
  edit.push_back(p2);
  edit.updateRanges();
  edit.clear(false);
  TEST_EQUAL(edit!=empty,true);
}
END_SECTION

START_SECTION((virtual void updateRanges()))
{
  MSChromatogram<> s;
  s.push_back(p1);
  s.push_back(p2);
  s.push_back(p1);

  s.updateRanges();
  s.updateRanges(); //second time to check the initialization

  TEST_REAL_SIMILAR(s.getMaxInt(),2)
  TEST_REAL_SIMILAR(s.getMinInt(),1)
  TEST_REAL_SIMILAR(s.getMax()[0],10)
  TEST_REAL_SIMILAR(s.getMin()[0],2)

  //test with only one peak

  s.clear(true);
  s.push_back(p1);
  s.updateRanges();
  TEST_REAL_SIMILAR(s.getMaxInt(),1)
  TEST_REAL_SIMILAR(s.getMinInt(),1)
  TEST_REAL_SIMILAR(s.getMax()[0],2)
  TEST_REAL_SIMILAR(s.getMin()[0],2)
}
END_SECTION

START_SECTION(void clear(bool clear_meta_data))
  MSChromatogram<> edit;
  edit.getInstrumentSettings().getScanWindows().resize(1);
  edit.resize(1);
  edit.setMetaValue("label",String("bla"));
  edit.getProduct().setMZ(5);
  edit.getFloatDataArrays().resize(5);
  edit.getIntegerDataArrays().resize(5);
  edit.getStringDataArrays().resize(5);

  edit.clear(false);
  TEST_EQUAL(edit.size(),0)
  TEST_EQUAL(edit==MSChromatogram<>(),false)

  edit.clear(true);
  TEST_EQUAL(edit==MSChromatogram<>(),true)
END_SECTION

START_SECTION((DoubleReal getMZ() const))
	MSChromatogram<> tmp;
	Product prod;
	prod.setMZ(0.1);
	TEST_REAL_SIMILAR(tmp.getMZ(), 0.0)
	tmp.setProduct(prod);
	TEST_REAL_SIMILAR(tmp.getMZ(), 0.1)
END_SECTION

START_SECTION(([MSChromatogram::MZLess] bool operator()(const MSChromatogram &a, const MSChromatogram &b) const))
{
    MSChromatogram<> a;
    Product pa;
    pa.setMZ(1000.0);
    a.setProduct(pa);

    MSChromatogram<> b;
    Product pb;
    pb.setMZ(1000.1);
    b.setProduct(pb);

    TEST_EQUAL(MSChromatogram<>::MZLess().operator ()(a,b), true)
    TEST_EQUAL(MSChromatogram<>::MZLess().operator ()(b,a), false)

    TEST_EQUAL(MSChromatogram<>::MZLess().operator ()(a,a), false)
}
END_SECTION

/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
END_TEST



