function [output,MineralStruct,MineralList]= thefinder(controlstruct,thelabels,data,outstruct2,MineralStruct)
%function output= thefinder(thefile,themineralfile,MineralDirectory,maxerror,isgrid,verbose)
%This the mother function that performs the phase classification
%INPUT
%controlstruct = are structure that holds all of the options for this run (structure)
%thelabels = the column labels for the mineral analysis data (cell array of strings)
%data = the mineral analysis data (double array)
%outstruct2 = the general information required to convert from oxide to cation components (structure), this
%is the raw data read from the background file
%MineralStruct = a structure array the phase specific transformation information 

%OUTPUT
%output = A cell array that contains the raw data of the transformation
%MineralStruct = Same purpose as the input of the same name put has been substantially modified in
%PrepcompleteWeights2Cations
%MineralList = The key into the raw data of output
%
%Written by K. Steffen (ksteffen@unm.edu) at the University of New Mexico,
%Department of Earch and Planetary Science
%Copyright 2003 Kurt Steffen
%
%Last Modified June 13, 2003

	output = cell(0);
	Hcolumn = GetColumnsGeneral3(thelabels,{'H'});	%H must be present in all input data files
	Hcolumn = Hcolumn{2,1};
	[NumberPoints NumberCols] = size(data);  %getting the size of data 
	%Compilation of all background data needed
	[MineralStruct outstruct1] = PrepCompleteWeights2Cations(thelabels,controlstruct,1,outstruct2,MineralStruct);
	if isempty(MineralStruct)
		error(sprintf('No Valid Minerals were listed in file %s ',controlstruct.backgroundfile)); 
	end
	MineralList = cell(0);
	CurrentMinerals = cell(0);
	mintemp = cell(1,length(MineralStruct));
	for m = 1:length(MineralStruct)
		if ~isempty(MineralStruct(m).MineralName)
			mintemp(m) = MineralStruct(m).MineralName;
		end
	end

	controlstruct.phasechecktest = 0;  
	for k = 1:NumberPoints  %This is the loop through the analysis points that is performing the classification
		if mod(k,100) == 0
			disp(sprintf('%d analyses of %d completed',k,NumberPoints));
		end
		Difference = zeros(1,outstruct1.NumberMinerals); %initializing
		sumadditive = cell(1);
		sumcations = cell(1);
		sumcationsoriginal = cell(1);
		sumweightsoriginal = cell(1);
		sumweights = cell(1);
		sumorder = cell(1);
		endmembervaluessum = cell(1);
		endmemberssum = cell(1);
		OutOfLimitVector = zeros(1,outstruct1.NumberMinerals);
		sumAdditive = cell(1);
		for m = 1:outstruct1.NumberMinerals
			if ~isempty(mintemp(m))
				thelabelstemp = thelabels;  %labels are changed so must be copied
				thisdata = data(k,:); %data are changed each time so must be copied
				sumweightsoriginal(m)  = {thisdata};
				[cations,order,thelabelstemp,w2cstruct] = WeightsToCationsComplete(MineralStruct,...
				thelabelstemp,thisdata,outstruct1,m,controlstruct,1,1);
				sumcationsoriginal(m) = {cations};
				[Additive OutofLimits] = Cations2Additive(order,cations,MineralStruct,m,controlstruct);
        			sumAdditive(k) = {Additive};
				%creating endmembers 
 				Conversion = MineralStruct(m).Conversion;
				if length(Conversion) == 1
					SolidSolution = 0;
				else
					SolidSolution = 1;
				end
				SolidSolutionVector(m) = SolidSolution;
				Base = MineralStruct(m).Endbase;
   	 
				if SolidSolution
					EndMemberValues = Base + Additive'*Conversion;
				else
					EndMemberValues = Base;
				end
        

				if abs(sum(EndMemberValues) - 1) > .001
					temp = [MineralStruct(m).MineralName{:}];
					errorstring = sprintf('End Member Components sum to %d (should be 1), Likely error in input file for %s.',sum(EndMemberValues),temp);
					error(errorstring);
				end
				Molecular = MineralStruct(m).Molecular;
				
				EndmemberValuesMolecular = EndMemberValues.*Molecular/sum(EndMemberValues.*Molecular); %correcting for different molecular weight

				perfectweights = (MineralStruct(m).EndMemberWeights'*EndmemberValuesMolecular')';
        
				sumadditive(m) = {Additive};
				OutOfLimitVector(m) = OutofLimits;
				[inorder] = Additive2Cations(order,Additive,m,MineralStruct,thelabelstemp,NumberCols);
				sumorder(m) = {order};
				sumcations(m) = {inorder};
      
				sumtemp = sum(thisdata);

				weights = cations2weights(w2cstruct,inorder,sumtemp,order);
				newperfect = zeros(1,length(weights));
       
				newperfect(MineralStruct(m).mapping) = perfectweights;
        
				sumEndMembers(m) = {EndMemberValues};
				sumEndMembersmolecorrect(m) = {EndmemberValuesMolecular};
				sumweights(m) = {weights};
				sumperfectweights(m) = {newperfect};
				Difference(m) =  sum(abs(weights-thisdata));
				if Hcolumn ~= -1
					newperfect(Hcolumn) = [];
					thisdata(Hcolumn) = [];
					weights(Hcolumn) = [];
				end
				Difference(m) =  sum(abs(weights-thisdata));
				PerfectDifference(m) = sum(abs(newperfect-thisdata));
				endmembervaluessum(m) = {EndMemberValues};
				endmemberssum(m) = {MineralStruct(m).EndMembers};
			else

				OutOfLimitVector(m) = 1;
				Difference(m) = controlstruct.MaxError + 1;
				PerfectDifference(m) = controlstruct.MaxError + 1;
			end
		end
   
		[output MineralList CurrentMinerals controlstruct] = SelectMineral(output,Difference,OutOfLimitVector,...
		MineralStruct,sumadditive,k,controlstruct,sumcations,sumweights,sumorder,MineralList,CurrentMinerals,...
		mintemp,sumweightsoriginal,sumcationsoriginal,PerfectDifference,sumperfectweights,SolidSolutionVector,...
		endmembervaluessum,endmemberssum);
	end		

	if controlstruct.phasechecktest == 0
		disp('All calculated phase IDs agree with user supplied IDs');
		disp(' ');
		disp(' ');
	end

	if controlstruct.PhaseCheck == 1
		disp('Finished Phasecheck');

	end

