void ProgValidationNonTilt::run()
{
    //Clustering Tendency and Cluster Validity Stephen D. Scott
    randomize_random_generator();
    MetaData md,mdGallery,mdOut,mdOut2,mdSort;
    MDRow row;

    FileName fnOut,fnOut2, fnGallery;
    fnOut = fnDir+"/clusteringTendency.xmd";
    fnGallery = fnDir+"/gallery.doc";
    fnOut2 = fnDir+"/validation.xmd";
    size_t nSamplesRandom = 500;

    md.read(fnParticles);
    mdGallery.read(fnGallery);
    mdSort.sort(md,MDL_IMAGE_IDX,true,-1,0);

    size_t maxNImg;
    size_t sz = md.size();

    if (useSignificant)
    	mdSort.getValue(MDL_IMAGE_IDX,maxNImg,sz);
    else
    {
    	mdSort.getValue(MDL_ITEM_ID,maxNImg,sz);
    }

    String expression;
    MDRow rowP,row2;
    SymList SL;
    int symmetry, sym_order;
    SL.readSymmetryFile(fnSym.c_str());
    SL.isSymmetryGroup(fnSym.c_str(), symmetry, sym_order);

/*
    double non_reduntant_area_of_sphere = SL.nonRedundantProjectionSphere(symmetry,sym_order);
    double area_of_sphere_no_symmetry = 4.*PI;
    double correction = std::sqrt(non_reduntant_area_of_sphere/area_of_sphere_no_symmetry);
*/
    double correction = 1;
    double validation = 0;
    double num_images = 0;

	MetaData tempMd;
	std::vector<double> sum_u(nSamplesRandom);
	double sum_w=0;
	std::vector<double> H0(nSamplesRandom);
	std::vector<double> H(nSamplesRandom);
	std::vector<double> p(nSamplesRandom);

	if (rank==0)
		init_progress_bar(maxNImg);

	for (size_t idx=0; idx<=maxNImg;idx++)
	{
		if ((idx)%Nprocessors==rank)
		{
			if (useSignificant)
				expression = formatString("imageIndex == %lu",idx);
			else
				expression = formatString("itemId == %lu",idx);

			tempMd.importObjects(md, MDExpression(expression));


			if (tempMd.size()==0)
				continue;

			//compute H_0 from noise
			obtainSumU_2(mdGallery, tempMd,sum_u,H0);
			//compute H from experimental
			obtainSumW(tempMd,sum_w,sum_u,H,correction);

			std::sort(H0.begin(),H0.end());
			std::sort(H.begin(),H.end());

			double P = 0;
			for(size_t j=0; j<sum_u.size();j++)
			{
				//P += H0.at(j)/H.at(j);
				P += H0.at(size_t((1-significance_noise)*nSamplesRandom))/H.at(j);
				p.at(j) = H0.at(j)/H.at(j);
			}

			P /= (nSamplesRandom);

			if (useSignificant)
				rowP.setValue(MDL_IMAGE_IDX,idx);
			else
				rowP.setValue(MDL_ITEM_ID,idx);

			rowP.setValue(MDL_WEIGHT,P);
			mdPartial.addRow(rowP);
			tempMd.clear();

			if (rank==0)
				progress_bar(idx+1);
		}
	}

	if (rank==0)
		progress_bar(maxNImg);

	synchronize();
	gatherClusterability();

	if (rank == 0)
	{
		mdPartial.write(fnOut);
		std::vector<double> P;
		mdPartial.getColumnValues(MDL_WEIGHT,P);

		for (size_t idx=0; idx< P.size();idx++)
		{
			if (P[idx] > 1)
				validation += 1.;
			num_images += 1.;
		}
		validation /= (num_images);

		row2.setValue(MDL_IMAGE,fnInit);
		row2.setValue(MDL_WEIGHT,validation);
		mdOut2.addRow(row2);
		mdOut2.write(fnOut2);
	}
}
void ProgValidationNonTilt::run()
{
    //Clustering Tendency and Cluster Validity Stephen D. Scott
    randomize_random_generator();
    //char buffer[400];
    //sprintf(buffer, "xmipp_reconstruct_significant -i %s  --initvolumes %s --odir %s --sym  %s --iter 1 --alpha0 %f --angularSampling %f",fnIn.c_str(), fnInit.c_str(),fnDir.c_str(),fnSym.c_str(),alpha0,angularSampling);
    //system(buffer);

    MetaData md,mdOut,mdOut2;
    FileName fnMd,fnOut,fnOut2;
    fnMd = fnDir+"/angles_iter001_00.xmd";
    fnOut = fnDir+"/clusteringTendency.xmd";
    fnOut2 = fnDir+"/validation.xmd";
    size_t nSamplesRandom = 250;

    md.read(fnMd);
    size_t maxNImg;
    size_t sz = md.size();
    md.getValue(MDL_IMAGE_IDX,maxNImg,sz);

    String expression;
    MDRow rowP,row2;
    SymList SL;
    int symmetry, sym_order;
    SL.readSymmetryFile(fnSym.c_str());
    SL.isSymmetryGroup(fnSym.c_str(), symmetry, sym_order);

    double non_reduntant_area_of_sphere = SL.nonRedundantProjectionSphere(symmetry,sym_order);
    double area_of_sphere_no_symmetry = 4.*PI;
    double correction = std::sqrt(non_reduntant_area_of_sphere/area_of_sphere_no_symmetry);
    double validation = 0;

	MetaData tempMd;
	std::vector<double> sum_u(nSamplesRandom);
	//std::vector<double> sum_w(nSamplesRandom);
	double sum_w=0;
	std::vector<double> H0(nSamplesRandom);
	std::vector<double> H(nSamplesRandom);

	if (rank==0)
		init_progress_bar(maxNImg);

	for (size_t idx=0; idx<=maxNImg;idx++)
	{
		if ((idx+1)%Nprocessors==rank)
		{
			expression = formatString("imageIndex == %lu",idx);
			tempMd.importObjects(md, MDExpression(expression));

			if (tempMd.size()==0)
				continue;

			//compute H_0 from noise
			obtainSumU(tempMd,sum_u,H0);
			//compute H from experimental
			obtainSumW(tempMd,sum_w,sum_u,H,correction);

			std::sort(H0.begin(),H0.end());
			std::sort(H.begin(),H.end());

			double P = 0;
			for(size_t j=0; j<sum_u.size();j++)
				P += H0.at(j)/H.at(j);

			P /= (nSamplesRandom);
			rowP.setValue(MDL_IMAGE_IDX,idx);
			rowP.setValue(MDL_WEIGHT,P);
			mdPartial.addRow(rowP);

			//sum_u.clear();
			//sum_w.clear();
			//H0.clear();
			//H.clear();
			tempMd.clear();

			if (rank==0)
				progress_bar(idx+1);
		}
	}

	if (rank==0)
		progress_bar(maxNImg);

	synchronize();
	gatherClusterability();

	if (rank == 0)
	{
		mdPartial.write(fnOut);
		std::vector<double> P;
		mdPartial.getColumnValues(MDL_WEIGHT,P);
		for (size_t idx=0; idx< P.size();idx++)
		{
		if (P[idx] > 1)
				
			validation += 1;

	        }

		validation /= (maxNImg+1);

	}

    row2.setValue(MDL_IMAGE,fnInit);
    row2.setValue(MDL_WEIGHT,validation);
    mdOut2.addRow(row2);
    mdOut2.write(fnOut2);
}