// average.cpp : Defines the entry point for the console application.
// Developed by Alex E Pozhitkov, 2012, University of Washington

//#include "stdafx.h"
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <map>
#include <valarray>
#include <vector>
#include <string>

using namespace std;
typedef map<string, vector<double> > TableFloat;

inline double power2(double x)
{
	return x*x;
}

int main(int argc, char* argv[])
{
	if(argc == 1)
	{
		cerr << "average file1.txt id1 file2.txt id2... > out.txt\nid1, id2, etc are experiment IDs; for calibration use concentrations.";
		return -1;
	}
	try{
	for(int i=1; i < argc; i+=2)
	{
		if(i >= argc)
			throw 1;
		ifstream ifsRecords(argv[i]);
		if(ifsRecords.bad())
			throw 1;
		TableFloat tbf;
		while(!ifsRecords.eof())
		{
			string ProbeID;
			double fIntensity;
			ifsRecords >> ProbeID >> fIntensity;
			tbf[ProbeID].push_back(fIntensity);
		}
		for(TableFloat::const_iterator CI = tbf.begin(); CI != tbf.end(); CI++)
		{
			valarray<double> fIntensities(CI->second.size());
			copy(CI->second.begin(), CI->second.end(), &fIntensities[0]);
			int n = fIntensities.size();
			double mean = fIntensities.sum() / n;
			double sd = sqrt(((fIntensities - mean).apply(power2)).sum() / (n - 1)) ;
			cout << argv[i+1] << "\t" << CI->first << "\t" << mean << "\t" << sd / mean / sqrt((double)n) << "\n";
		}
	}
	}
	catch(int e)
	{
		if(e == 1)
			cerr << "\nInconsistent parameters";
		return 1;
	}
	return 0;
}

