void saveParams ( ostream& os, ParameterList& paramList )
{
	init_html ( os, "Saving Batch-Tag Parameters" );
	paramList.removeName ( "save_params" );
	ParameterList cookieParamList ( "", false, false );		// Create empty parameter set
	cookieParamList.appendParameters ( paramList );
	//cookieParamList.removeName ( "accession_nums" );
	cookieParamList.removeName ( "data_source" );
	cookieParamList.removeName ( "max_hits" );
	cookieParamList.removeName ( "output_filename" );
	cookieParamList.removeName ( "password" );
	cookieParamList.removeName ( "project_name" );
	cookieParamList.removeName ( "report_title" );
	cookieParamList.removeName ( "script_filename" );
	cookieParamList.removeName ( "search_name" );
	cookieParamList.removeName ( "upload_data_filename" );
	cookieParamList.removeName ( "upload_data_filepath" );
	cookieParamList.removeName ( "user" );
	cookieParamList.removeName ( "version" );
	if ( paramList.getStringValue ( "data_source" ) == "List of Files" )	// Batch-Tag rather than Batch-Tag Web
		cookieParamList.removeName ( "instrument_name" );
	else
		genUnlink ( paramList.getStringValue ( "upload_data_filepath" ) );	// Delete any uploaded file 
	bool ret = cookieParamList.copyToCookie ( os, "batchtag_params" );
	if ( !ret ) {
		ErrorHandler::genError ()->error ( "Could not save the parameters as their length exceeds the maximum cookie length.\n" );
	}
	os << "<p>Settings saved</p>" << endl;
	os << "<input type=\"button\" value=\"Search Form\" onclick=\"history.go(-1)\">" << endl;
}
ImportProject::ImportProject ( const ParameterList& paramList ) :
	newProjectName ( paramList.getStringValue ( "new_project_name" ) )
{
	init ( paramList );
	try {												// These are the files with the database entries
		dpi = new DatabaseProjectImport ( uploadName );
	}
	catch ( runtime_error e ) {
		genUnlinkDirectory ( uploadName );
		throw e;
	}
	bool rawDataIncluded = getDataFiles ();
	getProjectFiles ();
	try {
		ipf = new ImportProjectFile ( uploadName + SLASH + "project" + SLASH + projFile, rawDataIncluded );
	}
	catch ( runtime_error e ) {
		genUnlinkDirectory ( uploadName );
		throw e;
	}
	if ( dataFiles.empty () ) {
		if ( !ipf->checkDataFiles () ) {
			genUnlinkDirectory ( uploadName );
			throw runtime_error ( "One or more of the data files in the uploaded project is not present." );
		}
	}
	getResultsFiles ();
}
void SQLiteMGF::insert ()
{
	v1 [3] = "";
	v1 [4] = "1";
	v1 [5] = "0";
	char* info = getFileAsCharPtr ( MsparamsDir::instance ().getParamPath ( fileName ) );

	StringVector xparams = XMLParser::getStringVectorValue ( info, "mgf_type" );
	for ( StringVectorSizeType i = 0 ; i < xparams.size () ; i++ ) {
		ParameterList pList ( xparams [i], false, false, false );
		StringVector pNames;
		StringVectorVector pValues;
		pList.getParams ( pNames, pValues );
		v1 [0] = pList.getStringValue ( "name" );
		for ( StringVectorSizeType j = 0 ; j < pNames.size () ; j++ ) {
			if ( pNames [j] != "name" ) {
				v1 [1] = pNames [j];
				for ( StringVectorSizeType k = 0 ; k < pValues [j].size () ; k++ ) {
					v1 [2] = pValues [j] [k];
					insertTable ( tableName, n1, v1 );
				}
			}
		}
	}

	delete [] info;
}
void SQLiteQuanMSMSPurity::insert ()
{
	v1 [5] = "";
	v1 [6] = "1";
	v1 [7] = "0";
	StringVector quanTypes = QuanMSMSXMLData::instance ().getQuanMSMSNames ();

	for ( StringVectorSizeType i = 0 ; i < quanTypes.size () ; i++ ) {
		v1 [0] = quanTypes [i];
		string purityPath = MsparamsDir::instance ().getParamPath (  v1 [0] + ".txt" );
		if ( genFileExists ( purityPath ) ) {
			GenCommentedIFStream ifs ( purityPath );
			while ( ifs.getUncommentedLine ( v1 [1] ) ) {
				ParameterList p ( ifs );
				StringVector sv = p.getNameList ();
				int numQuanPeaks = p.size ();
				for ( int j = 0 ; j < numQuanPeaks ; j++ ) {
					v1 [2] = sv [j];
					istringstream ist ( p.getStringValue ( sv [j] ) );
					for ( int k = 1 ; k <= 4 ; k++ ) {
						v1 [3] = "coefficient" + gen_itoa ( k );
						ist >> v1 [4];
						insertTable ( tableName, n1, v1 );
					}
				}
			}
		}
	}
}
PurityCorrection::PurityCorrection ( const ParameterList* params )
{
	string quanType = params->getStringValue ( "quan_type", "" );
	if ( isQuanMSMS ( quanType ) ) {	// This is an MSMS quantitation type
		string purityName = params->getStringValue ( "purity_correction", "" );
		string purityFile = quanType + ".txt";
		string purityPath = MsparamsDir::instance ().getParamPath ( purityFile );
		if ( purityName == FROM_FORMULAE ) {
			numQuanPeaks = QuanMSMSXMLData::instance ().getNumQuanPeaks ( quanType );
			matrix = QuanMSMSXMLData::instance ().getFormulaPurityCoefficients ( quanType );
		}
		else if ( purityName == NO_CORRECTION ) {
			numQuanPeaks = QuanMSMSXMLData::instance ().getNumQuanPeaks ( quanType );
			matrix.resize ( numQuanPeaks );
			for ( int i = 0 ; i < numQuanPeaks ; i++ ) {
				for ( int j = 0 ; j < 4 ; j++ ) {
					matrix [i].push_back ( 0.0 );
				}
			}
		}
		else {
			if ( purityName != DEFAULT ) {
				if ( isPrefix ( purityName, quanType ) ) {
					purityName = purityName.substr ( quanType.length () + 1 );
				}
				else {
					ErrorHandler::genError ()->error ( "Invalid purity name.\n" );
				}
			}
			GenIFStream fromFile ( purityPath );
			string line;
			bool flag = false;
			while ( getline ( fromFile, line ) ) {
				if ( line == purityName ) {
					ParameterList p ( fromFile );
					StringVector sv = p.getNameList ();
					numQuanPeaks = p.size ();
					matrix.resize ( numQuanPeaks );
					for ( int i = 0 ; i < numQuanPeaks ; i++ ) {
						istringstream ist ( p.getStringValue ( sv [i] ) );
						double num;
						while ( ist >> num ) {
							matrix [i].push_back ( num / 100.0 );
						}
					}
					flag = true;
					break;
				}
			}
			if ( !flag ) {
				ErrorHandler::genError ()->error ( "Invalid purity name.\n" );
			}
		}
		a = nrmatrix ( 1, numQuanPeaks, 1, numQuanPeaks );
		loadA ();
		b = nrmatrix ( 1, numQuanPeaks, 1, 1 );
	}
void ImportProject::init ( const ParameterList& paramList )
{
	string fpath = paramList.getStringValue ( "upload_temp_filepath" );
	string user = paramList.getStringValue ( "user" );
	if ( user == "root" ) {
		genUnlink ( fpath );
		throw runtime_error ( "Root user can't create projects." );
	}
	UserInfo* userInfo = MySQLPPSDDBase::instance ().getUserInfo ( user );
	if ( !userInfo ) {
		genUnlink ( fpath );
		throw runtime_error ( "Unknown user." );
	}
	userID = userInfo->getUserID ();
	if ( !newProjectName.empty () && MySQLPPSDDBase::instance ().checkProject ( userID, newProjectName ) ) {
		genUnlink ( fpath );
		throw runtime_error ( "Project already exists." );
	}
	reposit = new UserRepository ( "batchtag", userInfo->getDirectoryName () );	// Where to put files given a user. Also creates the directories.
	uploadName = genPreprocessFile ( fpath );
}
void batchSubmission ( ostream& os, ParameterList& paramList )
{
	init_html ( os, "Batch Submission" );
	if ( paramList.empty () ) {
		ErrorHandler::genError ()->error ( "No parameters passed to Prospector program.\n" );
	}
	string user = paramList.getStringValue ( "user" );
	os << "<p>Creating Prospector files.</p>" << endl;
	string searchKey = genRandomString ( 16 );			// Selects a unique string for the search
	string searchName = paramList.getStringValue ( "search_name" );					// Program (eg batchtag)
	string uploadFpath = paramList.getStringValue ( "upload_data_filepath" );	// This is the full path name of the uploaded file as named by PP
	string resultsName = paramList.getStringValue ( "output_filename" );
	bool searchKeyProblem;
	try {
		checkConstantAndVariableModCompatibility ( &paramList );
	}
	catch ( runtime_error e ) {		// Catch database login problems
		genUnlink ( uploadFpath );
		ErrorHandler::genError ()->error ( e );
	}
	try {
		searchKeyProblem = MySQLPPSDDBase::instance ().checkSearchKey ( searchKey );// Checks it is unique
	}
	catch ( runtime_error e ) {		// Catch database login problems
		genUnlink ( uploadFpath );
		ErrorHandler::genError ()->error ( e );
	}
	if ( searchKeyProblem ) {
		genUnlink ( uploadFpath );
		ErrorHandler::genError ()->error ( "Search key not unique.\n" );// The search key has to be unique to carry on.
	}
	if ( resultsName.empty () ) {
		genUnlink ( uploadFpath );
		ErrorHandler::genError ()->error ( "No results name has been chosen.\n" );
	}
	string password;
	bool passwordFlag = paramList.getValue ( "password", password );
	UserInfo* userInfo = MySQLPPSDDBase::instance ().getUserInfo ( user );
	if ( !userInfo || ( passwordFlag && userInfo->getPassword () != password ) ) {													// Get the user information
		genUnlink ( uploadFpath );
		ErrorHandler::genError ()->error ( "Unknown user and/or password.\n" );
	}
	if ( user == "root" ) {													// Get the user information
		genUnlink ( uploadFpath );
		ErrorHandler::genError ()->error ( "Root user can't do searches.\n" );
	}
	if ( userInfo->getIsGuest () ) {
		genUnlink ( uploadFpath );
		ErrorHandler::genError ()->error ( "Guest users can't do searches.\n" );
	}
	if ( !InfoParams::instance ().getBoolValue ( "btag_daemon_remote" ) ) {
		try {
			startDaemonIfNecessary ();
		}
		catch ( runtime_error e ) {
			genUnlink ( uploadFpath );
			ErrorHandler::genError ()->error ( e );
		}
	}
	string userID = userInfo->getUserID ();
	Repository* reposit = new UserRepository ( searchName, userInfo->getDirectoryName () );	// Where to put files given a user. Also creates the directories.
	string projectName;
	if ( uploadFpath.empty () ) {		// The project already exists
		projectName = paramList.getStringValue ( "project_name" );	// From a form with a project name option.
	}
	else {
		string uploadFname = paramList.getStringValue ( "upload_data_filename" );	// This is the original file name.
		string instrument = paramList.getStringValue ( "instrument_name" );
		uploadFname = genFilenameFromPath ( uploadFname );						// IE gives the full path whereas Mozilla give the filename (what we want)
		projectName = getProjectName ( uploadFname );	// The project is named after the uploaded file. This has to be unique.
		if ( projectName.length () > 58 ) {
			genUnlink ( uploadFpath );
			ErrorHandler::genError ()->error ( "The project name " + projectName + " is too long.\n" );
		}
		if ( MySQLPPSDDBase::instance ().checkProject ( userID, projectName ) ) {
			genUnlink ( uploadFpath );
			ErrorHandler::genError ()->error ( "Project already exists.\n" );
		}
		paramList.setValue ( "data_source", "List of Files" );
		paramList.setValue ( "project_name", projectName );
		paramList.removeName ( "upload_data_filename" );
		paramList.removeName ( "upload_data_filepath" );
		string uploadName = genPreprocessFile ( uploadFpath );
		if ( uploadName == uploadFpath || isCompressedUpload ( uploadName ) ) {		// If the file hasn't been preprocessed or it has just been uncompressed it must be a single file
			string shortName = genShortFilenameFromPath ( uploadName );
			string newDir = genDirectoryFromPath ( uploadName ) + SLASH + shortName;
			if ( newDir == uploadName ) {
				newDir += "_1";
			}
			genCreateDirectory ( newDir );
			string newUploadName;
			if ( isCompressedUpload ( uploadName ) )
				newUploadName = newDir + SLASH + genShortFilenameFromPath ( uploadFname );
			else
				newUploadName = newDir + SLASH + uploadFname;
			genRename ( uploadName, newUploadName );
			uploadName = newDir;
		}
		PPProject ppp ( userInfo->getMaxMSMSSpectra (), userInfo->getAllowRaw (), projectName, uploadName, searchKey, reposit, MSMSDataSetInfo::setChargeRange ( &paramList ) );
		if ( ppp.initialised () ) {
			int err = genRename ( uploadName, reposit->getFullDataPath () + SLASH + searchKey );
			if ( err ) {
				genUnlink ( uploadName );
				string e = gen_itoa ( err );
				ErrorHandler::genError ()->error ( "Failed to move uploaded file to repository.\nError code = " + e + "\n" );
			}
			ppp.createProjectFile ( reposit->getFullProjectPath () + SLASH + projectName + ".xml" );
			string projectPath = reposit->getProjectPath ();
			MySQLPPSDDBase::instance ().submitProject ( userID, projectName, projectName + ".xml", reposit->getProjectPath (), instrument );
		}
		else {
			string err = ppp.getErrMessage ();
			if ( ppp.getDeleteFlag () ) {		// Known error - delete the upload directory
				genUnlinkDirectory ( uploadName );
			}
			if ( err.empty () )
				ErrorHandler::genError ()->error ( "Upload file has an invalid format.\n" );
			else
				ErrorHandler::genError ()->error ( err + "\n" );
		}
	}
	paramList.removeName ( "user" );
	paramList.removeName ( "password" );
	paramList.removeName ( "project_name" );
	paramList.removeName ( "output_filename" );					// Search results file.
	paramList.removeName ( "msms_mod_AA_list" );				// These options are used to load the variable mods
	paramList.removeName ( "msms_mod_AA_types" );				// and shouldn't be saved.
	paramList.removeName ( "mod_AA_limit" );
	paramList.removeName ( "mod_AA_file" );
	paramList.removeName ( "motif_offset" );
	paramList.removeName ( "motif" );
	string projectID = MySQLPPSDDBase::instance ().getProjectID ( userID, projectName );
	if ( projectID.empty () ) {
		genUnlink ( uploadFpath );
		ErrorHandler::genError ()->error ( "Project doesn't exist.\n" );
	}
	if ( MySQLPPSDDBase::instance ().checkResults ( userID, projectID, resultsName ) ) {
		genUnlink ( uploadFpath );
		ErrorHandler::genError ()->error ( "Results file of this name already exists for this project.\n" );
	}
	paramList.XMLParameterFile ( reposit->getFullResultsPath () + SLASH + searchKey + ".xml" );	// This is the search parameter file
	MySQLPPSDDBase::instance ().submitSearch ( searchKey, projectID, resultsName, searchKey + ".xml", reposit->getResultsPath () );
	MySQLPPSDDBase::instance ().updateProjectRecordUpdated ( projectID );

	genSleep ( 5000 );
	ParameterList pList ( "jobStatus", false, false, false, false, false );
	pList.addName ( "search_key", searchKey );
	refreshJavascript ( os, 0, pList.getURL (), true );
}