Beispiel #1
0
//Display the results of a fit in a LaTeX table using cout
void ResultFormatter::ReviewOutput( FitResult * OutputData )
{
	ResultParameterSet * outputParameters = OutputData->GetResultParameterSet();
	vector<string> allNames = outputParameters->GetAllNames();
	vector<string>::iterator nameIterator;

	cout << endl << endl;
	cout << "--------------------------------------------------" <<endl;
	cout << "\nFit Review:\t\tStatus:\t" <<OutputData->GetFitStatus()<<"\t\tNLL:\t"<<setprecision(10)<<OutputData->GetMinimumValue()<<endl<<endl;

	//Ouput each parameter
	for( nameIterator = allNames.begin(); nameIterator != allNames.end(); ++nameIterator )
	{
		ResultParameter * outputParameter = outputParameters->GetResultParameter( *nameIterator );
		double fitValue = outputParameter->GetValue();
		double fitError = outputParameter->GetError();
		string unit = outputParameter->GetUnit();
		string name = *nameIterator;
		cout << setw(25) << name << " : "
			<< setw(13) << setprecision(5) << fitValue;
		if( outputParameter->GetAssym() )
		{
			cout << "  +  " << setprecision(5) << setw(8) << outputParameter->GetErrHi() << "  -  " << setw(6) << outputParameter->GetErrLow() << endl;
		}
		else
		{
			cout << "  ±  " << setw(13) << setprecision(5) << fitError << endl;
		}
	}
	cout << endl;
	cout << "--------------------------------------------------" <<endl;
	cout << endl <<endl;
}
Beispiel #2
0
void ResultFormatter::LatexMinimumFitResultTable( FitResult * OutputData, stringstream& latex )
{
	ResultFormatter::TableHeader( latex, 2 );
	latex << "Parameter & Fit result and error  \\\\ \\hline \\hline\n" << endl;

	ResultParameterSet * outputParameters = OutputData->GetResultParameterSet();
	vector<string> allNames = outputParameters->GetAllNames();
	for( vector<string>::iterator nameIterator = allNames.begin(); nameIterator != allNames.end(); ++nameIterator )
	{
		ResultParameter * outputParameter = outputParameters->GetResultParameter( *nameIterator );

		double fitValue = outputParameter->GetValue();
		double fitError = outputParameter->GetError();
		string unit = outputParameter->GetUnit();
		string name = *nameIterator;

		latex << setw(20) << EdStyle::GetParamLatexName(name) << " & "
			<< setw(12) << setprecision(3) << fitValue;
		if( outputParameter->GetAssym() )
		{
			latex << " + " << outputParameter->GetErrHi() << " - " << outputParameter->GetErrLow() << " ";
		}
		else
		{
			latex << " \\pm " << setw(10) << fitError << " ";
		}
		latex << setw(15) << EdStyle::GetParamLatexUnit(unit)  << "\\\\" << endl;
	}

	ResultFormatter::TableFooter( latex );
}
Beispiel #3
0
//Add a new fit result
bool FitResultVector::AddFitResult( FitResult * NewResult, const bool with_clock )
{
	vector<double> newParameterValues, newParameterErrors, newParameterPulls, newParameterGenValues;
	vector<string>::iterator nameIterator;
	ResultParameterSet * newSet = NewResult->GetResultParameterSet();

	//Check all expected parameters are found
	for ( nameIterator = allNames.begin(); nameIterator != allNames.end(); ++nameIterator )
	{
		ResultParameter * newResult = newSet->GetResultParameter( *nameIterator );
		if ( newResult->GetUnit() == "NameNotFoundError" )
		{
			//If any parameter is not found, fail
			cerr << "Expected fitted parameter \"" << *nameIterator << "\" not found" << endl;
			return false;
		}
		else
		{
			//Retrieve the parameter information
			newParameterValues.push_back( newResult->GetValue() );
			newParameterErrors.push_back( newResult->GetError() );
			newParameterPulls.push_back( newResult->GetPull() );
			newParameterGenValues.push_back( newResult->GetOriginalValue() );
		}
	}

	//If you've got this far, all the parameters have been found, so add them to the record
	allResults.push_back(NewResult);
	for (unsigned int nameIndex = 0; nameIndex < allNames.size(); ++nameIndex )
	{
		allValues[nameIndex].push_back( newParameterValues[nameIndex] );
		allErrors[nameIndex].push_back( newParameterErrors[nameIndex] );
		allPulls[nameIndex].push_back( newParameterPulls[nameIndex] );
		allGenValues[nameIndex].push_back( newParameterGenValues[nameIndex] );
	}

	if( with_clock && clock != NULL )
	{
		//Store the duration
		#ifdef RAPIDFIT_USETGLTIMER
		double thisTime = gl_clock->End();
		allGLTimes.push_back( thisTime );
		#endif
		clock->Stop();
		allRealTimes.push_back( clock->RealTime() );
		allCPUTimes.push_back( clock->CpuTime() );
	}

	return true;
}
Beispiel #4
0
//Display the results of a fit using cout
void ResultFormatter::DebugOutputFitResult( FitResult * OutputData )
{
	cout << "Fit status: " << OutputData->GetFitStatus() << endl;
	cout << "Minimum function value: " << OutputData->GetMinimumValue() << endl;
	cout << "Name | Value | Minimum | Maximum" << endl;

	//Ouput each parameter
	ResultParameterSet * outputParameters = OutputData->GetResultParameterSet();
	vector<string> allNames = outputParameters->GetAllNames();
	vector<string>::iterator nameIterator;
	for ( nameIterator = allNames.begin(); nameIterator != allNames.end(); ++nameIterator )
	{
		ResultParameter * outputParameter = outputParameters->GetResultParameter( *nameIterator );
		cout << *nameIterator << " | " << outputParameter->GetValue() << " | ";
		cout << outputParameter->GetMinimum() << " | " << outputParameter->GetMaximum() << endl;
	}
}
Beispiel #5
0
//Use Migrad to minimise the given function
void FumiliWrapper::Minimise()
{
	ParameterSet * newParameters = RapidFunction->GetParameterSet();
	vector<string> allNames = newParameters->GetAllNames();
	//	int numParams = allNames.size();

	/*
	// Fill a vector of doubles for each set of physics parameters that you
	// want to sample. What about case where Apara_sq + Aperp_sq > 1?
	vector< vector<double> > positions;
	PhysicsBottle* bottle = NewFunction->GetPhysicsBottle();
	ParameterSet* parameters = bottle->GetParameterSet();
	vector<string> names = parameters->GetAllNames();
	double nsteps = 1;
	for( int k = 0; k < names.size(); ++k)
	{
	for( int j = 0; j < nsteps; ++j)
	{
	vector<double> tempPos;
	for( int i = 0; i < names.size(); ++i )
	{
	double value;
	if ( i != k )
	{
	value = parameters->GetPhysicsParameter(names[i])->GetValue();
	}
	else
	{
	double min = parameters->GetPhysicsParameter(names[i])->GetMinimum();
	double max = parameters->GetPhysicsParameter(names[i])->GetMaximum();
	double step = (max - min)/nsteps;
	value = min + j * step;
	}
	tempPos.push_back(value);
	}
	positions.push_back(tempPos);
	}
	}
	*/

	// Fill a vector of doubles for each set of observables
	vector< vector<double> > positions;
	PhysicsBottle* bottle = RapidFunction->GetPhysicsBottle();
	PhaseSpaceBoundary* boundary = bottle->GetResultDataSet(0)->GetBoundary();
	vector<string> names = boundary->GetAllNames();

	vector<double> observableSteps;
	int nsteps = 10;

	// Could make this faster...
	for ( int step = 0; step < nsteps; ++step)
	{
		vector<double> tempPos;
		for( unsigned int observable = 0; observable < names.size(); ++observable )
		{
			if ( !boundary->GetConstraint(names[observable])->IsDiscrete() )
			{
				double min = boundary->GetConstraint(names[observable])->GetMinimum();
				double max = boundary->GetConstraint(names[observable])->GetMinimum();
				double delta = (max - min)/nsteps;
				double position = min + step*delta;
				tempPos.push_back( position );
			}
			else
			{
				double value = boundary->GetConstraint(names[observable])->CreateObservable()->GetValue();
				tempPos.push_back( value );
			}
		}
		positions.push_back(tempPos);
	}

	// Now, get the FumiliFCNBase function which will be passed to the Fumili minimiser
	FumiliStandardMaximumLikelihoodFCN fumFCN( *function, positions );

	// Setup the minimiser
	MnFumiliMinimize fumili( fumFCN, *( function->GetMnUserParameters() ), (unsigned)Quality);//MINUIT_QUALITY);

	// Do the minimisation
	FunctionMinimum minimum = fumili( (unsigned)maxSteps, bestTolerance );//(int)MAXIMUM_MINIMISATION_STEPS, FINAL_GRADIENT_TOLERANCE );

	// Once we have the FunctionMinimum, code same as in other Wrappers
	//Create the fit results
	const MnUserParameters * minimisedParameters = &minimum.UserParameters();
	ResultParameterSet * fittedParameters = new ResultParameterSet( allNames );
	for ( unsigned int nameIndex = 0; nameIndex < allNames.size(); ++nameIndex)
	{
		string parameterName = allNames[nameIndex];
		PhysicsParameter * oldParameter = newParameters->GetPhysicsParameter( parameterName );
		double parameterValue = minimisedParameters->Value( parameterName.c_str() );
		double parameterError = minimisedParameters->Error( parameterName.c_str() );

		fittedParameters->SetResultParameter( parameterName, parameterValue, oldParameter->GetOriginalValue(), parameterError,
				-oldParameter->GetMinimum(), oldParameter->GetMaximum(),
				oldParameter->GetType(), oldParameter->GetUnit() );
	}

	int fitStatus;
	if ( !minimum.HasCovariance() )
	{
		fitStatus = 0;
	}
	else if ( !minimum.HasAccurateCovar() )
	{
		fitStatus = 1;
	}
	else if ( minimum.HasMadePosDefCovar() )
	{
		fitStatus = 2;
	}
	else
	{
		fitStatus = 3;
	}

	PhysicsBottle* newBottle = RapidFunction->GetPhysicsBottle();
	fitResult = new FitResult( minimum.Fval(), fittedParameters, fitStatus, newBottle  );
}
Beispiel #6
0
//Display the results of a fit in a LaTeX table using cout
void ResultFormatter::LatexOutputFitResult( FitResult * OutputData )
{
	//.............................................
	// Standard table for MC toys with pulls
	cout << "Fit result for MC toys with pulls" << endl;
	cout << "\n\\begin{center}" << endl;
	cout << "Fit status: " << OutputData->GetFitStatus() << endl;
	cout << setprecision(8) << "Minimum function value: " << OutputData->GetMinimumValue() << endl;
	cout << "\\begin{tabular}{|c|c|c|} \n\\hline" << endl;
	cout << setw(20) << "Parameter"<< " & " << setw(25) << "Fit result and error" << setw(21) << " & " << setw(20) << "$\\sigma$ from input \\\\ \t\t\\hline \\hline\n" << endl;

	//Ouput each parameter
	ResultParameterSet * outputParameters = OutputData->GetResultParameterSet();
	vector<string> allNames = outputParameters->GetAllNames();
	vector<string>::iterator nameIterator;
	for ( nameIterator = allNames.begin(); nameIterator != allNames.end(); ++nameIterator )
	{
		ResultParameter * outputParameter = outputParameters->GetResultParameter( *nameIterator );

		double fitValue = outputParameter->GetValue();
		//		double minValue = outputParameter->GetMinimum();
		//		double inputValue = outputParameter->GetOriginalValue();
		double fitError = outputParameter->GetError();
		double sigmaFromInputValue = outputParameter->GetPull();
		string unit = outputParameter->GetUnit();
		//if (fitError > 0.0) sigmaFromInputValue = (fitValue - inputValue)/fitError;

		//boost::regex pattern ("_",boost::regex_constants::icase|boost::regex_constants::perl);
		//string replace ("\\_");
		//string newName = boost::regex_replace (*nameIterator, pattern, replace);

		//string name = FindAndReplaceString( *nameIterator );
		//string name = StringProcessing::ReplaceString( *nameIterator, "_", "\\_" );
		string name = *nameIterator;
		cout << setw(20) << EdStyle::GetParamLatexName(name) << " & "
			<< setw(12) << setprecision(5) << fitValue << " $\\pm$ "
			<< setw(10) <<  		  fitError << " " << setw(15) << EdStyle::GetParamLatexUnit(unit) << " & "
			<< setw(20) << setprecision(2) << sigmaFromInputValue << "\\\\" << endl;
	}

	cout << "\\hline \n\\end{tabular}" << endl;
	cout << "\\end{center}\n" << endl;

	//.................................................
	//longer table for MC pull fits with absolute offsets
	cout << endl ;
	cout << "Fit result - for MC toys with pulls and absolute offsets " << endl;
	cout << "\n\\begin{center}" << endl;
	cout << "Fit status: " << OutputData->GetFitStatus() << endl;
	cout << setprecision(8) << "Minimum function value: " << OutputData->GetMinimumValue() << endl;
	cout << "\\begin{tabular}{|c|c|c|c|} \n\\hline" << endl;
	cout << setw(20)<< "Parameter"<< " & " << setw(25) << "Fit result and error" << setw(21) << " & "<< setw(20) <<"$\\sigma$ from input" << " & " << setw(20) << "Abs from input \\\\ \t\t\\hline \\hline\n" << endl;

	//Ouput each parameter
	for ( nameIterator = allNames.begin(); nameIterator != allNames.end(); ++nameIterator )
	{
		ResultParameter * outputParameter = outputParameters->GetResultParameter( *nameIterator );

		double fitValue = outputParameter->GetValue();
		//		double minValue = outputParameter->GetMinimum();
		double inputValue = outputParameter->GetOriginalValue();
		double fitError = outputParameter->GetError();
		double sigmaFromInputValue = outputParameter->GetPull();
		string unit = outputParameter->GetUnit();
		//if (fitError > 0.0) sigmaFromInputValue = (fitValue - inputValue)/fitError;

		//boost::regex pattern ("_",boost::regex_constants::icase|boost::regex_constants::perl);
		//string replace ("\\_");
		//string newName = boost::regex_replace (*nameIterator, pattern, replace);

		//string name = FindAndReplaceString( *nameIterator );
		//string name = StringProcessing::ReplaceString( *nameIterator, "_", "\\_" );
		string name = *nameIterator;
		cout << setw(20) << EdStyle::GetParamLatexName(name) << " & "
			<< setw(12) << setprecision(5) << fitValue << " $\\pm$ "
			<< setw(10) <<  		  fitError << " " << setw(15) << EdStyle::GetParamLatexUnit(unit) << " & "
			<< setw(20) << setprecision(2) << sigmaFromInputValue << " & "
			<< setw(15) << setprecision(5) << fitValue-inputValue << "\\\\" << endl;
	}

	cout << "\\hline \n\\end{tabular}" << endl;
	cout << "\\end{center}\n" << endl;

	//........................................
	//short table for data fits
	cout << endl ;
	cout << "\n\\begin{center}" << endl;
	cout << "Fit result - for Data fits" << endl;
	cout << "Fit status: " << OutputData->GetFitStatus() << endl;
	cout << setprecision(8) << "Minimum function value: " << OutputData->GetMinimumValue() << endl;
	cout << "\\begin{tabular}{|c|c|} \n\\hline" << endl;
	cout << setw(20) << "Parameter" << " & " << setw(21) << "Fit result and error" << setw(21) << " " << " \\\\ \\hline \\hline\n" << endl;

	//Will need to do some comparisons
	//	double Rperp =0, Rzp =0, ePerp =0 , eZp=0;

	//Ouput each parameter
	for ( nameIterator = allNames.begin(); nameIterator != allNames.end(); ++nameIterator )
	{
		ResultParameter * outputParameter = outputParameters->GetResultParameter( *nameIterator );

		double fitValue = outputParameter->GetValue();
		//		double minValue = outputParameter->GetMinimum();
		//		double inputValue = outputParameter->GetOriginalValue();
		double fitError = outputParameter->GetError();
		//		double sigmaFromInputValue = outputParameter->GetPull();
		string unit = outputParameter->GetUnit();
		//string name = StringProcessing::ReplaceString( *nameIterator, "_", "\\_" );
		string name = *nameIterator;
		cout << setw(20) << EdStyle::GetParamLatexName(name) << " & "
			<< setw(12) << setprecision(3) << fitValue << " $\\pm$ "
			<< setw(10) <<  		  fitError << " " << setw(15) << EdStyle::GetParamLatexUnit(unit)  << "\\\\" << endl;
	}
	cout << "\\hline \n\\end{tabular}" << endl;
	cout << "\\end{center}\n" << endl;

}
Beispiel #7
0
//Make pull plots from the output of a toy study
void ResultFormatter::WriteFlatNtuple( const string FileName, const FitResultVector* ToyResult, const vector<string> inputXML, const vector<string> runtimeArgs, const string XMLForProjections, const string XMLForToys )
{
	TFile * rootFile = TFile::Open( FileName.c_str(), "RECREATE" );
	rootFile->SetCompressionLevel( 9 );

	//cout << "Storing Fit Result Vector" << endl;

	//	Important!
	//	The output from this is typically run through the RapidPlot file
	//	For sake of backwards compatibility the RapidPlot tool makes use of the ability to look for the 'first' TTree in a ROOT file for some of it's internal logic
	//	KEEP THIS TREE AS THE FIRST TREE CREATED AND WRITTEN TO THE FILE TO BE ABLE TO KEEP USING THIS TOOL!!!
	TTree* outputTree = new TTree( "RapidFitResult", "RapidFitResult" );

	ResultParameterSet* resultSet = ToyResult->GetFitResult( 0 )->GetResultParameterSet();

	vector<string> allNames = resultSet->GetAllNames();

	for( unsigned int param_i=0; param_i< allNames.size(); ++param_i )
	{
		string thisParamName( allNames[param_i] );

		vector<double> ParameterValues, ParameterErrors, ParameterOriginalValues;
		vector<double> ParameterPulls, ParameterStepSizes;
		vector<double> ParameterErrorsHigh, ParameterErrorsLow;
		vector<double> ParameterMinimums, ParameterMaximums;
		vector<int> ParameterScanStatus, ParameterFixedStatus;
		for( unsigned int resultNum=0; resultNum< (unsigned)ToyResult->NumberResults(); ++resultNum )
		{
			ResultParameter* thisParam = ToyResult->GetFitResult( (unsigned)resultNum )->GetResultParameterSet()->GetResultParameter( thisParamName );

			ParameterValues.push_back( thisParam->GetValue() );
			ParameterErrors.push_back( thisParam->GetError() );
			ParameterPulls.push_back( thisParam->GetPull() );
			ParameterMinimums.push_back( thisParam->GetMinimum() );
			ParameterMaximums.push_back( thisParam->GetMaximum() );
			ParameterOriginalValues.push_back( thisParam->GetOriginalValue() );

			if( thisParam->GetType() == "Fixed" )
			{
				ParameterFixedStatus.push_back( 1 );
			}
			else
			{
				ParameterFixedStatus.push_back( 0 );
			}

			//if( thisParam->GetScanStatus() ) cout << "Scanned: " << string(thisParamName) << endl;

			if( thisParam->GetScanStatus() )
			{
				ParameterScanStatus.push_back( 1 );
			}
			else
			{
				ParameterScanStatus.push_back( 0 );
			}

			if( thisParam->GetAssym() )
			{
				ParameterErrorsHigh.push_back( thisParam->GetErrHi() );
				ParameterErrorsLow.push_back( thisParam->GetErrLow() );
			} else {
				ParameterErrorsHigh.push_back( 0. );
				ParameterErrorsLow.push_back( 0. );
			}
			ParameterStepSizes.push_back( thisParam->GetStepSize() );
		}
		string BranchName=allNames[param_i];
		ResultFormatter::AddBranch( outputTree, BranchName+"_value", ParameterValues );
		bool fixed_param = ToyResult->GetFitResult(0)->GetResultParameterSet()->GetResultParameter(thisParamName)->GetType() == "Fixed";
		bool scanned_param = ToyResult->GetFitResult(0)->GetResultParameterSet()->GetResultParameter(thisParamName)->GetScanStatus();
		if( (!fixed_param) || (scanned_param) )
		{
			ResultFormatter::AddBranch( outputTree, BranchName+"_error", ParameterErrors );
			ResultFormatter::AddBranch( outputTree, BranchName+"_gen", ParameterOriginalValues );
			ResultFormatter::AddBranch( outputTree, BranchName+"_pull", ParameterPulls );
			ResultFormatter::AddBranch( outputTree, BranchName+"_max", ParameterMaximums );
			ResultFormatter::AddBranch( outputTree, BranchName+"_min", ParameterMinimums );
			ResultFormatter::AddBranch( outputTree, BranchName+"_step", ParameterStepSizes );
			ResultFormatter::AddBranch( outputTree, BranchName+"_errHi", ParameterErrorsHigh );
			ResultFormatter::AddBranch( outputTree, BranchName+"_errLo", ParameterErrorsLow );
		}
		ResultFormatter::AddBranch( outputTree, BranchName+"_scan", ParameterScanStatus );
		ResultFormatter::AddBranch( outputTree, BranchName+"_fix", ParameterFixedStatus );
	}

	//cout << "Stored Parameters" << endl;

	ResultFormatter::AddBranch( outputTree, "Fit_RealTime", ToyResult->GetAllRealTimes() );
	ResultFormatter::AddBranch( outputTree, "Fit_CPUTime", ToyResult->GetAllCPUTimes() );
	ResultFormatter::AddBranch( outputTree, "Fit_GLTime", ToyResult->GetAllGLTimes() );

	vector<int> fitStatus;
	vector<double> NLL_Values, RealTimes, CPUTimes;
	for( unsigned int i=0; i< (unsigned) ToyResult->NumberResults(); ++i )
	{
		fitStatus.push_back( ToyResult->GetFitResult( (int)i )->GetFitStatus() );
		NLL_Values.push_back(  ToyResult->GetFitResult( (int)i )->GetMinimumValue() );
	}

	ResultFormatter::AddBranch( outputTree, "Fit_Status", fitStatus );
	ResultFormatter::AddBranch( outputTree, "NLL", NLL_Values );

	outputTree->Write("",TObject::kOverwrite);

	//ResultFormatter::AddBranch( outputTree, "Fit_RealTime", RealTimes );
	//ResultFormatter::AddBranch( outputTree, "Fit_CPUTime", CPUTimes );

	//	Ntuples are 'stupid' objects in ROOT and the basic one can only handle float type objects
	/*TNtuple * parameterNTuple;
	  parameterNTuple = new TNtuple("RapidFitResult", "RapidFitResult", ToyResult->GetFlatResultHeader());
	  Float_t * resultArr;
	  for( int resultIndex = 0; resultIndex < ToyResult->NumberResults(); ++resultIndex )
	  {
	  vector<double> result = ToyResult->GetFlatResult(resultIndex);
	  resultArr = new Float_t [result.size()];
	  copy( result.begin(), result.end(), resultArr);
	  parameterNTuple->Fill( resultArr );
	  delete [] resultArr;
	  }*/

	//cout << "Storing Correlation Matrix" << endl;

	if( ToyResult->GetFitResult(0)->GetResultParameterSet() != NULL )
	{
		if( !ToyResult->GetFitResult(0)->GetResultParameterSet()->GetAllFloatNames().empty() )
		{
			vector<double> MatrixElements; vector<string> MatrixNames;
			TTree * tree = new TTree("corr_matrix", "Elements from Correlation Matricies");
			tree->Branch("MartrixElements", "std::vector<double>", &MatrixElements );
			tree->Branch("MartrixNames", "std::vector<string>", &MatrixNames );
			for( int resultIndex = 0; resultIndex < ToyResult->NumberResults(); ++resultIndex )
			{
				TMatrixDSym* thisMatrix = ToyResult->GetFitResult(resultIndex)->GetCovarianceMatrix()->thisMatrix;
				if( thisMatrix == NULL ) continue;
				MatrixNames = ToyResult->GetFitResult(resultIndex)->GetCovarianceMatrix()->theseParameters;
				if( MatrixNames.empty() ) continue;
				double* MatrixArray = thisMatrix->GetMatrixArray();
				if( MatrixArray == NULL ) continue;
				MatrixElements.clear();
				for( unsigned int i=0; i< (unsigned) thisMatrix->GetNoElements(); ++i )
				{
					MatrixElements.push_back( MatrixArray[i] );
				}
				if( thisMatrix->GetNoElements() > 0 ) tree->Fill();
			}
			tree->Write("",TObject::kOverwrite);
		}
	}

	//cout << "Saving XML and runtime" << endl;

	if( !inputXML.empty() )
	{
		TTree* XMLTree = new TTree( "FittingXML", "FittingXML" );

		vector<string> thisXML = inputXML;

		XMLTree->Branch( "FittingXML", "std::vector<string>", &thisXML );

		XMLTree->Fill();

		XMLTree->Write("",TObject::kOverwrite);
	}
	if( !runtimeArgs.empty() )
	{
		TTree* RuntimeTree = new TTree( "RuntimeArgs", "RuntimeArgs" );

		vector<string> thisRuntime = runtimeArgs;

		RuntimeTree->Branch( "RuntimeArgs", "std::vector<string>", &thisRuntime );

		RuntimeTree->Fill();

		RuntimeTree->Write("",TObject::kOverwrite);
	}

	if( !XMLForProjections.empty() )
	{
		TTree* ProjectionXML = new TTree( "XMLForProjections", "XMLForProjections" );

		string thisXML = XMLForProjections;

		ProjectionXML->Branch( "ProjectionXML", "std::string", &thisXML );

		ProjectionXML->Fill();

		ProjectionXML->Write("",TObject::kOverwrite);
	}

        if( !XMLForToys.empty() )
        {
                TTree* ToyXML = new TTree( "XMLForToys", "XMLForToys" );

                string thisXML = XMLForToys;

                ToyXML->Branch( "ToyXML", "std::string", &thisXML );

                ToyXML->Fill();

                ToyXML->Write("",TObject::kOverwrite);
        }

	rootFile->Write("",TObject::kOverwrite);
	rootFile->Close();

	//	THIS SHOULD BE SAFE... BUT THIS IS ROOT so 'of course' it isn't...
	//delete parameterNTuple;
	//delete rootFile;
}