Exemple #1
0
// Write SettingsBlock keywords
bool UChromaSession::writeSettingsBlock(LineParser& parser)
{
	parser.writeLineF("%s\n", UChromaSession::inputBlock(UChromaSession::SettingsBlock));
	parser.writeLineF("  %s \"%s\" %i %i %s %i\n", UChromaSession::settingsKeyword(UChromaSession::ImageExportKeyword), qPrintable(imageExportFileName_), imageExportWidth_, imageExportHeight_, UChromaSession::imageFormatExtension(imageExportFormat_), imageExportMaintainAspect_);
	parser.writeLineF("%s\n", UChromaSession::settingsKeyword(UChromaSession::EndSettingsKeyword));

	return true;
}
Exemple #2
0
// Write ViewBlock keywords
bool UChromaSession::writeViewBlock(LineParser& parser)
{
	parser.writeLineF("%s\n", UChromaSession::inputBlock(UChromaSession::ViewBlock));
	parser.writeLineF("  %s %i %i\n", UChromaSession::viewKeyword(UChromaSession::GridKeyword), viewLayout_.nColumns(), viewLayout_.nRows());

	// Loop over defined panes
	for (ViewPane* pane = viewLayout_.panes(); pane != NULL; pane = pane->next) writeViewPaneBlock(parser, pane);

	parser.writeLineF("%s\n", UChromaSession::viewKeyword(UChromaSession::EndViewKeyword));

	return true;
}
Exemple #3
0
// Write FitResultsBlock keywords
bool UChromaSession::writeFitResultsBlock(LineParser& parser, DataSpaceRange* range, int rangeID, int indentLevel)
{
	// Construct indent string
	char* indent = new char[indentLevel*2+1];
	for (int n=0; n<indentLevel*2; ++n) indent[n] = ' ';
	indent[indentLevel*2] = '\0';

	parser.writeLineF("%s  %s %i\n", indent, UChromaSession::fitParametersKeyword(UChromaSession::FitResultsBlockKeyword), rangeID);
	for (NamedValue* value = range->fittedValues(); value != NULL; value = value->next) parser.writeLineF("%s    %s %s %e\n", indent, UChromaSession::fitResultsKeyword(UChromaSession::FittedValueKeyword), qPrintable(value->name()), value->value());
	parser.writeLineF("%s  %s\n", indent, UChromaSession::fitResultsKeyword(UChromaSession::EndFitResultsKeyword));

	return true;
}
Exemple #4
0
// Execute Method
bool Export::process(DUQ& duq, ProcessPool& procPool)
{
	/*
	* Export data from the target Configuration(s)
	 */

	// Loop over target Configurations
	for (RefListItem<Configuration,bool>* ri = targetConfigurations_.first(); ri != NULL; ri = ri->next)
	{
		// Grab Configuration pointer
		Configuration* cfg = ri->item;

		// Retrieve control parameters from Configuration
		const char* saveTrajectory = variableAsChar(cfg, "SaveTrajectory");

		/*
		 * Save XYZ Trajectory
		 */
		if (!DUQSys::isEmpty(saveTrajectory))
		{
			Messenger::print("Export: Appending to trajectory output file '%s'...\n", cfg->outputCoordinatesFile());

			// Only the pool master saves the data
			if (procPool.isMaster())
			{
				// Open the file
				LineParser parser;
				if (!parser.appendOutput(saveTrajectory))
				{
					parser.closeFiles();
					procPool.stop();
					return false;
				}
				else if (!writeConfigurationXYZ(parser, cfg, cfg->name()))
				{
					Messenger::print("Export: Failed to append to trajectory file.\n");
					parser.closeFiles();
					procPool.stop();
					return false;
				}

				procPool.proceed();
			}
			else if (!procPool.decision()) return false;

			Messenger::print("Export: Finished appending trajectory file.\n");
		}
	}

	return true;
}
Exemple #5
0
// Write Configuration as CONFIG
bool Export::writeConfigurationDLPOLY(LineParser& parser, Configuration* cfg, const char* header)
{
	// Write title
	parser.writeLineF("%s\n", header);

	// Write keytrj and imcon
	if (cfg->box()->type() == Box::NonPeriodicBox) parser.writeLineF("%10i%10i\n", 0, 0);
	else if (cfg->box()->type() == Box::CubicBox) parser.writeLineF("%10i%10i\n", 0, 1);
	else if (cfg->box()->type() == Box::OrthorhombicBox) parser.writeLineF("%10i%10i\n", 0, 2);
	else parser.writeLineF("%10i%10i\n", 0, 3);
	
	// Write Cell
	if (cfg->box()->type() != Box::NonPeriodicBox)
	{
		Matrix3 axes = cfg->box()->axes();
		parser.writeLineF("%20.12f%20.12f%20.12f\n", axes[0], axes[1], axes[2]);
		parser.writeLineF("%20.12f%20.12f%20.12f\n", axes[3], axes[4], axes[5]);
		parser.writeLineF("%20.12f%20.12f%20.12f\n", axes[6], axes[7], axes[8]);
	}

	// Write Atoms
	for (int n=0; n<cfg->nAtoms(); ++n)
	{
		Atom* i = cfg->atom(n);
		parser.writeLineF("%-6s%10i%20.10f\n%20.12f%20.12f%20.12f\n", cfg->type(i->localTypeIndex())->name(), n+1, PeriodicTable::element(i->element()).isotope(0)->atomicWeight(), i->r().x, i->r().y, i->r().z);
	}

	Messenger::print("Export: Finished writing model CONFIG file.\n");

	return true;
}
Exemple #6
0
// Write Configuration as XYZ
bool Export::writeConfigurationXYZ(LineParser& parser, Configuration* cfg, const char* header)
{
	// Write number of atoms and title
	if (!parser.writeLineF("%i\n", cfg->nAtoms())) return false;
	if (!parser.writeLineF("%s\n", header)) return false;
	
	// Write Atoms
	for (int n=0; n<cfg->nAtoms(); ++n)
	{
		Atom* i = cfg->atom(n);
		if (!parser.writeLineF("%-3s   %10.4f  %10.4f  %10.4f\n", PeriodicTable::element(i->element()).symbol(), i->r().x, i->r().y, i->r().z)) return false;
	}

	return true;
}
void FileSelectorWidget::on_FilesEdit_textChanged(QString textChanged)
{
	if (refreshing_) return;

	// Split current string into separate arguments
	LineParser parser;
	parser.getArgsDelim(Parser::UseQuotes, ui.FilesEdit->text());

	selectedFilenames_.clear();
	for (int n = 0; n < parser.nArgs(); ++n) selectedFilenames_ << parser.argc(n);

	// If we are updating filter/plugin based on the name, do it here
	bool formatOk = true;
	if (updatePluginFromFilename_ && (selectedFilenames_.count() > 0)) formatOk = updatePluginFromCurrentFilename() != NULL;
	
	emit(selectionValid((selectedFilenames_.count() > 0) && formatOk));
}
Exemple #8
0
// Write DataSetBlock keywords
bool UChromaSession::writeDataSetBlock(LineParser& parser, DataSet* dataSet, int indentLevel)
{
	// Construct indent string
	char* indent = new char[indentLevel*2+1];
	for (int n=0; n<indentLevel*2; ++n) indent[n] = ' ';
	indent[indentLevel*2] = '\0';

	parser.writeLineF("%s  %s '%s'\n", indent, UChromaSession::collectionKeyword(UChromaSession::DataSetDefinitionKeyword), qPrintable(dataSet->name()));
	if (dataSet->dataSource() == DataSet::FileSource) parser.writeLineF("%s    %s %s '%s'\n", indent, UChromaSession::dataSetKeyword(UChromaSession::SourceKeyword), DataSet::dataSource(dataSet->dataSource()), qPrintable(dataSet->sourceFileName()));
	else parser.writeLineF("%s    %s %s\n", indent, UChromaSession::dataSetKeyword(UChromaSession::SourceKeyword), DataSet::dataSource(dataSet->dataSource()));
	parser.writeLineF("%s    %s %f\n", indent, UChromaSession::dataSetKeyword(UChromaSession::ZKeyword), dataSet->data().z());
	parser.writeLineF("%s    %s\n", indent, UChromaSession::dataSetKeyword(UChromaSession::DataKeyword));
	for (int n=0; n< dataSet->data().nPoints(); ++n) parser.writeLineF("%s      %f  %f\n", indent, dataSet->data().x(n), dataSet->data().y(n));
	parser.writeLineF("%s    End%s\n", indent, UChromaSession::dataSetKeyword(UChromaSession::DataKeyword));
	parser.writeLineF("%s  %s\n", indent, UChromaSession::dataSetKeyword(UChromaSession::EndDataSetKeyword));

	return true;
}
Exemple #9
0
// Load Species information from XYZ file
bool Species::loadFromXYZ(const char* filename)
{
	Messenger::print("Loading XYZ data from file '%s'\n", filename);
	
	// Open the specified file...
	LineParser parser;
	parser.openInput(filename);
	if (!parser.isFileGoodForReading())
	{
		Messenger::error("Couldn't open XYZ file '%s'.\n", filename);
		return false;
	}

	// Clear any existing data
	clear();

	// Simple format - first line is number of atoms, next line is title, then follow atoms/coordinates, one atom per line
	parser.getArgsDelim(LineParser::Defaults);
	int nAtoms = parser.argi(0);
	parser.readNextLine(LineParser::Defaults);
	name_ = parser.line();
	int el, success;
	for (int n=0; n<nAtoms; ++n)
	{
		success = parser.getArgsDelim(LineParser::Defaults);
		if (success != 0)
		{
			parser.closeFiles();
			Messenger::error("Couldn't read Atom %i from file '%s'\n", n+1, filename);
			return false;
		}
		el = PeriodicTable::find(parser.argc(0));
		if (el == -1) el = 0;
		SpeciesAtom* i = addAtom(el, parser.argd(1), parser.argd(2),parser.argd(3));
		if (parser.hasArg(4)) i->setCharge(parser.argd(4));
	}

	Messenger::print("Succesfully loaded XYZ data from file '%s'.\n", filename);
	parser.closeFiles();
	return true;
}
// Parse Simulation block
bool SimulationBlock::parse(LineParser& parser, DUQ* duq)
{
	Messenger::print("\nParsing %s block...\n", InputBlocks::inputBlock(InputBlocks::SimulationBlock));

	bool blockDone = false, error = false;

	while (!parser.eofOrBlank(duq->worldPool()))
	{
		// Read in a line, which should contain a keyword and a minimum number of arguments
		parser.getArgsDelim(duq->worldPool(), LineParser::SkipBlanks+LineParser::UseQuotes);
		SimulationBlock::SimulationKeyword simKeyword = SimulationBlock::keyword(parser.argc(0));
		if ((simKeyword != SimulationBlock::nSimulationKeywords) && ((parser.nArgs()-1) < SimulationBlock::nArguments(simKeyword)))
		{
			Messenger::error("Not enough arguments given to '%s' keyword.\n", SimulationBlock::keyword(simKeyword));
			error = true;
			break;
		}
		switch (simKeyword)
		{
			case (SimulationBlock::BoxNormalisationPointsKeyword):
				duq->setBoxNormalisationPoints(parser.argi(1));
				break;
			case (SimulationBlock::EndSimulationKeyword):
				Messenger::print("Found end of %s block.\n", InputBlocks::inputBlock(InputBlocks::SimulationBlock));
				blockDone = true;
				break;
			case (SimulationBlock::MaxIterationsKeyword):
				duq->setMaxIterations(parser.argi(1));
				break;
			case (SimulationBlock::ParallelStrategyKeyword):
				if (DUQ::parallelStrategy(parser.argc(1)) == DUQ::nParallelStrategies)
				{
					Messenger::error("Unrecognised parallel strategy '%s'.\n", parser.argc(1));
					error = true;
				}
				else duq->setParallelStrategy(DUQ::parallelStrategy(parser.argc(1)));
				break;
			case (SimulationBlock::SeedKeyword):
				duq->setSeed(parser.argi(1));
				break;
			case (SimulationBlock::WindowFunctionKeyword):
				if (Data2D::windowFunction(parser.argc(1)) == Data2D::nWindowFunctions)
				{
					Messenger::error("Unrecognised window function '%s'.\n", parser.argc(1));
					error = true;
				}
				else duq->setWindowFunction(Data2D::windowFunction(parser.argc(1)));
				break;
			case (SimulationBlock::nSimulationKeywords):
				Messenger::print("Unrecognised %s block keyword found - '%s'\n", InputBlocks::inputBlock(InputBlocks::SimulationBlock), parser.argc(0));
				InputBlocks::printValidKeywords(InputBlocks::SimulationBlock);
				error = true;
				break;
			default:
				printf("DEV_OOPS - %s block keyword '%s' not accounted for.\n", InputBlocks::inputBlock(InputBlocks::SimulationBlock), SimulationBlock::keyword(simKeyword));
				error = true;
				break;
		}
		
		// Error encountered?
		if (error) break;
		
		// End of block?
		if (blockDone) break;
	}

	return (!error);
}
Exemple #11
0
/*
 * \brief Perform some MD
 * \details Evolve the current Configuration using a simple molecular dynamics algorithm.
 * 
 * This is a parallel routine, with processes operating in process groups.
 */
bool DUQ::md(Configuration& cfg, double cutoffDistance, int nSteps, double deltaT)
{
	// Check input values if necessary
	if (cutoffDistance < 0.0) cutoffDistance = pairPotentialRange_;
	const double cutoffSq = cutoffDistance * cutoffDistance;
	const double temperature = cfg.temperature();
	bool writeTraj = false;
	bool calcEnergy = true;
	int writeFreq = 10;

	// Print summary of parameters
	Messenger::print("MD: Number of steps = %i\n", nSteps);
	Messenger::print("MD: Cutoff distance is %f\n", cutoffDistance);
	Messenger::print("MD: Timestep = %10.3e ps\n", deltaT);
	if (writeTraj) Messenger::print("MD: Trajectory file '%s' will be appended.\n");
	else Messenger::print("MD: Trajectory file off.\n");
	Messenger::print("MD: Energy %s be calculated at each step.\n", calcEnergy ? "will" : "will not");
	Messenger::print("MD: Summary will be written every %i step(s).\n", writeFreq);

	// Create force arrays as simple double arrays (easier to sum with MPI) - others are Vec3<double> arrays
	Array<double> mass(cfg.nAtoms()), fx(cfg.nAtoms()), fy(cfg.nAtoms()), fz(cfg.nAtoms());
	Array< Vec3<double> > a(cfg.nAtoms()), v(cfg.nAtoms()), deltaR(cfg.nAtoms());

	// Variables
	int n, maxDeltaId;
	Atom* atoms = cfg.atoms();
	Atom* i;
	double maxDelta, deltaSq, massSum, tInstant, ke, tScale, pe;
	double deltaTSq = deltaT*deltaT;
	Vec3<double> vCom;
	double maxForce = 100.0;

	/*
	 * Calculation Begins
	 */
	
	// Assign random velocities to start... (grab atomic masses at the same time...)
	Messenger::print("Assigning random velocities...\n");
	vCom.zero();
	massSum = 0.0;
	for (n=0; n<cfg.nAtoms(); ++n)
	{
		i = cfg.atom(n);
		v[n].x = exp(DUQMath::random()-0.5) / sqrt(TWOPI);
		v[n].y = exp(DUQMath::random()-0.5) / sqrt(TWOPI);
		v[n].z = exp(DUQMath::random()-0.5) / sqrt(TWOPI);
		mass[n] = PeriodicTable::element(i->element()).isotope(0)->atomicWeight();
		vCom += v[n] * mass[n];
		massSum += mass[n];
	}

	// Remove velocity shift
	vCom /= massSum;
	v -= vCom;

	// Calculate instantaneous temperature
        // J = kg m2 s-2  -->   10 J = g Ang2 ps-2
        // If ke is in units of [g mol-1 Angstroms2 ps-2] then must use kb in units of 10 J mol-1 K-1 (= 0.8314462)
	const double kb = 0.8314462;
	ke = 0.0;
	pe = 0.0;
	for (n=0; n<cfg.nAtoms(); ++n) ke += 0.5 * mass[n] * v[n].dp(v[n]);
	tInstant = ke * 2.0 / (3.0 * cfg.nAtoms() * kb);
	
	// Rescale velocities for desired temperature
	tScale = sqrt(temperature / tInstant);
	for (n=0; n<cfg.nAtoms(); ++n) v[n] *= tScale;

	// Open trajectory file (if requested)
	LineParser trajParser;
	if (writeTraj)
	{
		Dnchar trajectoryFile = cfg.name();
		trajectoryFile.strcat(".md.xyz");
		if (Comm.master())
		{
			if ((!trajParser.openOutput(trajectoryFile, true)) || (!trajParser.isFileGoodForWriting()))
			{
				Messenger::error("Failed to open MD trajectory output file '%s'.\n", trajectoryFile.get());
				Comm.decide(false);
				return false;
			}
			Comm.decide(true);
		}
		else if (!Comm.decision()) return false;
	}

	// Write header to screen
	if (calcEnergy) Messenger::print("  Step             T(K)      K.E.(kJ/mol) P.E.(kJ/mol) Etot(kJ/mol)\n");
	else Messenger::print("  Step             T(K)      K.E.(kj/mol)\n");

	// Start a timer
	Timer timer;

	// Ready to do MD propagation of system
	timer.start();
	Comm.resetAccumulatedTime();
	for (int step=0; step<nSteps; ++step)
	{
// 		 deltaT = 0.001;
// 		 deltaTSq = deltaT*deltaT;
// 		// Velocity Verlet first stage (A) and zero forces
// 		// A:  r(t+dt) = r(t) + v(t)*dt + 0.5*a(t)*dt**2
// 		// A:  v(t+dt/2) = v(t) + 0.5*a(t)*dt
// 		// B:  a(t+dt) = F(t+dt)/m
// 		// B:  v(t+dt) = v(t+dt/2) + 0.5*a(t+dt)*dt
// 		maxDelta = 0.0;
// 		maxDeltaId = -1;
// 		for (n=0; n<cfg.nAtoms(); ++n)
// 		{
// 			// Calculate position deltas and determine maximum displacement for current timestep
// 			deltaR[n] = v[n]*deltaT + a[n]*0.5*deltaTSq;
// 			deltaSq = deltaR[n].magnitudeSq();
// 			if (deltaSq > maxDelta)
// 			{
// 				maxDelta = deltaSq;
// 				maxDeltaId = n;
// 			}
// 		}
// 		maxDelta = sqrt(maxDelta);
// 		Messenger::print("Current timestep (%e) will give a maximum displacement of %f Angstroms\n", deltaT, maxDelta);
// 		if (step > 0)
// 		{
// 			do
// 			{
// 				deltaT *= (v[maxDeltaId]*deltaT + a[maxDeltaId]*0.5*deltaTSq).magnitude() > maxDisplacement ? 0.99 : 1.01;
// 				deltaTSq = deltaT*deltaT;
// 			} while (fabs((v[maxDeltaId]*deltaT + a[maxDeltaId]*0.5*deltaTSq).magnitude() - maxDisplacement) > (maxDisplacement*0.05));
// 			// Adjust timestep to give maximum movement and avoid explosion
// 			// dR/dT = v + a*deltaT
// // 			printf("Deriv = %f %f\n", (v[maxDeltaId]+a[maxDeltaId]*deltaT).magnitude(), (v[maxDeltaId]+a[maxDeltaId]*deltaT).magnitude() / (maxDelta - 0.1));
// // 			deltaT = 1.0 / ((v[maxDeltaId]+a[maxDeltaId]*deltaT).magnitude() / 0.1);
// // 			printf("xxx = %f %f\n", 1.0 / deltaT, (maxDelta/maxDisplacement) * (v[maxDeltaId]+a[maxDeltaId]*deltaT).magnitude());
// // // 			deltaT = 0.000564480;
// // 			deltaT = 1.0 / ((maxDelta/maxDisplacement) * (v[maxDeltaId]+a[maxDeltaId]*deltaT).magnitude());
// // 			deltaT = deltaT/2.0;
// 			printf("New DeltaT = %f\n", deltaT);
// 		}

// 		// TEST - Check max displacement with new deltaT
// 		maxDelta = 0.0;
// 		for (n=0; n<cfg.nAtoms(); ++n)
// 		{
// 			// Calculate position deltas and determine maximum displacement for current timestep
// 			deltaR[n] = v[n]*deltaT + a[n]*0.5*deltaTSq;
// 			deltaSq = deltaR[n].magnitudeSq();
// 			if (deltaSq > maxDelta) maxDelta = deltaSq;
// 		}
// 		printf("New max delta = %f\n", sqrt(maxDelta));
		
		for (n=0; n<cfg.nAtoms(); ++n)
		{
			i = cfg.atom(n);

			// Propagate positions (by whole step)...
			i->translateCoordinates(v[n]*deltaT + a[n]*0.5*deltaTSq);

			// ...velocities (by half step)...
			v[n] += a[n]*0.5*deltaT;
			
			// Zero force ready for next calculation
			fx[n] = 0.0;
			fy[n] = 0.0;
			fz[n] = 0.0;
		}

		// Grain coordinates will have changed...
		cfg.updateGrains();

		// Calculate forces - must multiply by 100.0 to convert from kJ/mol to 10J/mol (internal MD units)
		totalForces(cfg, fx, fy, fz, cutoffSq);
		fx *= 100.0;
		fy *= 100.0;
		fz *= 100.0;

// 		// Cap forces
// 		for (n=0; n<cfg.nAtoms(); ++n)
// 		{
// 			// Calculate position deltas and determine maximum displacement for current timestep
// 			if (fx[n] < maxForce) fx[n] = -maxForce;
// 			else if (fx[n] > maxForce) fx[n] = maxForce;
// 			if (fy[n] < maxForce) fy[n] = -maxForce;
// 			else if (fy[n] > maxForce) fy[n] = maxForce;
// 			if (fz[n] < maxForce) fz[n] = -maxForce;
// 			else if (fz[n] > maxForce) fz[n] = maxForce;
// 		}

		// Velocity Verlet second stage (B) and velocity scaling
		// A:  r(t+dt) = r(t) + v(t)*dt + 0.5*a(t)*dt**2
		// A:  v(t+dt/2) = v(t) + 0.5*a(t)*dt
		// B:  a(t+dt) = F(t+dt)/m
		// B:  v(t+dt) = v(t+dt/2) + 0.5*a(t+dt)*dt
		ke = 0.0;
		for (n=0; n<cfg.nAtoms(); ++n)
		{
			// Determine new accelerations
			a[n].set(fx[n], fy[n], fz[n]);
			a[n] /= mass[n];

			// ..and finally velocities again (by second half-step)
			v[n] += a[n]*0.5*deltaT;
			
			ke += 0.5 * mass[n] * v[n].dp(v[n]);
		}

		// Rescale velocities for desired temperature
		tInstant = ke * 2.0 / (3.0 * cfg.nAtoms() * kb);
		tScale = sqrt(temperature / tInstant);
		v *= tScale;
		
		// Convert ke from 10J mol-1 to kJ/mol
		ke *= 0.01;

		// Calculate step energy
		if (calcEnergy) pe = intergrainEnergy(cfg) + intramolecularEnergy(cfg);
		
		// Write step summary?
		if (step%writeFreq == 0)
		{
			if (calcEnergy) Messenger::print("  %-10i    %10.3e   %10.3e   %10.3e   %10.3e\n", step+1, tInstant, ke, pe, ke+pe);
			else Messenger::print("  %-10i    %10.3e   %10.3e\n", step+1, tInstant, ke);
		}

		// Save trajectory frame
		if (writeTraj)
		{
			if (Comm.master())
			{
				// Write number of atoms
				trajParser.writeLineF("%i\n", cfg.nAtoms());

				// Construct and write header
				Dnchar header(-1, "Step %i of %i, T = %10.3e, ke = %10.3e", step+1, nSteps, tInstant, ke);
				if (calcEnergy) header.strcatf(", pe = %10.3e, tot = %10.3e", pe, ke+pe);
				trajParser.writeLineF("%s\n", header.get());
				// Write Atoms
				for (int n=0; n<cfg.nAtoms(); ++n)
				{
					i = cfg.atom(n);
					trajParser.writeLineF("%-3s   %10.3f  %10.3f  %10.3f\n", PeriodicTable::element(i->element()).symbol(), i->r().x, i->r().y, i->r().z);
				}
			}
			else if (!Comm.decision()) return false;
		}
        }
        timer.stop();

	// Close trajectory file
	if (writeTraj && Comm.master()) trajParser.closeFiles();

        Messenger::print("%i molecular dynamics steps performed (%s work, %s comms)\n", nSteps, timer.timeString(), Comm.accumulatedTimeString());

	// Increment configuration changeCount_
	cfg.incrementCoordinateIndex();

	/*
	 * Calculation End
	 */
	
	return true;
}
Exemple #12
0
// Write CollectionBlock keywords
bool UChromaSession::writeCollectionBlock(LineParser& parser, Collection* collection, Collection::CollectionType type, int indentLevel)
{
	// Construct indent string
	char* indent = new char[indentLevel*2+1];
	for (int n=0; n<indentLevel*2; ++n) indent[n] = ' ';
	indent[indentLevel*2] = '\0';

	if (type == Collection::MasterCollection) parser.writeLineF("%s%s '%s'\n", indent, UChromaSession::inputBlock(UChromaSession::CollectionBlock), qPrintable(collection->name()));
	else if (type == Collection::FitCollection) parser.writeLineF("%s%s '%s'\n", indent, UChromaSession::collectionKeyword(UChromaSession::FitBlockKeyword), qPrintable(collection->name()));
	else if (type == Collection::ExtractedCollection) parser.writeLineF("%s%s '%s'\n", indent, UChromaSession::collectionKeyword(UChromaSession::SliceBlockKeyword), qPrintable(collection->name()));
	parser.writeLineF("%s  %s \"%s\"\n", indent, UChromaSession::collectionKeyword(UChromaSession::DataDirectoryKeyword), qPrintable(collection->dataFileDirectory().absolutePath()));

	// -- Transforms
	parser.writeLineF("%s  %s %s %s\n", indent, UChromaSession::collectionKeyword(UChromaSession::TransformXKeyword), stringBool(collection->transformEnabled(0)), qPrintable(collection->transformEquation(0)));
	parser.writeLineF("%s  %s %s %s\n", indent, UChromaSession::collectionKeyword(UChromaSession::TransformYKeyword), stringBool(collection->transformEnabled(1)), qPrintable(collection->transformEquation(1)));
	parser.writeLineF("%s  %s %s %s\n", indent, UChromaSession::collectionKeyword(UChromaSession::TransformZKeyword), stringBool(collection->transformEnabled(2)), qPrintable(collection->transformEquation(2)));

	// -- Interpolation
	parser.writeLineF("%s  %s %s %s\n", indent, UChromaSession::collectionKeyword(UChromaSession::InterpolateKeyword), stringBool(collection->interpolate(0)), stringBool(collection->interpolate(2)));
	parser.writeLineF("%s  %s %s %s\n", indent, UChromaSession::collectionKeyword(UChromaSession::InterpolateConstrainKeyword), stringBool(collection->interpolateConstrained(0)), stringBool(collection->interpolateConstrained(2)));
	parser.writeLineF("%s  %s %f %f\n", indent, UChromaSession::collectionKeyword(UChromaSession::InterpolateStepKeyword), collection->interpolationStep(0), collection->interpolationStep(2));

	// Colour Setup
	parser.writeLineF("%s  %s '%s'\n", indent, UChromaSession::collectionKeyword(UChromaSession::ColourSourceKeyword), Collection::colourSource(collection->colourSource()));
	ColourScalePoint* csp;
	QColor colour;
	double value;
	// -- Single Colour
	colour = collection->colourScalePointColour(Collection::SingleColourSource);
	parser.writeLineF("%s  %s %i %i %i %i\n", indent, UChromaSession::collectionKeyword(UChromaSession::ColourSingleKeyword), colour.red(), colour.green(), colour.blue(), colour.alpha());
	// -- RGB Gradient
	colour = collection->colourScalePointColour(Collection::RGBGradientSource, 0);
	value = collection->colourScalePointValue(Collection::RGBGradientSource, 0);
	parser.writeLineF("%s  %s %f %i %i %i %i\n", indent, UChromaSession::collectionKeyword(UChromaSession::ColourRGBGradientAKeyword), value, colour.red(), colour.green(), colour.blue(), colour.alpha());
	colour = collection->colourScalePointColour(Collection::RGBGradientSource, 1);
	value = collection->colourScalePointValue(Collection::RGBGradientSource, 1);
	parser.writeLineF("%s  %s %f %i %i %i %i\n", indent, UChromaSession::collectionKeyword(UChromaSession::ColourRGBGradientBKeyword), value, colour.red(), colour.green(), colour.blue(), colour.alpha());
	// -- HSV Gradient
	colour = collection->colourScalePointColour(Collection::HSVGradientSource, 0);
	value = collection->colourScalePointValue(Collection::HSVGradientSource, 0);
	parser.writeLineF("%s  %s %f %i %i %i %i\n", indent, UChromaSession::collectionKeyword(UChromaSession::ColourHSVGradientAKeyword), value, colour.hue(), colour.saturation(), colour.value(), colour.alpha());
	colour = collection->colourScalePointColour(Collection::HSVGradientSource, 1);
	value = collection->colourScalePointValue(Collection::HSVGradientSource, 1);
	parser.writeLineF("%s  %s %f %i %i %i %i\n", indent, UChromaSession::collectionKeyword(UChromaSession::ColourHSVGradientBKeyword), value, colour.hue(), colour.saturation(), colour.value(), colour.alpha());
	// -- Custom Gradient
	for (csp = collection->customColourScalePoints(); csp != NULL; csp = csp->next)
	{
		parser.writeLineF("%s  %s %f %i %i %i %i\n", indent, UChromaSession::collectionKeyword(UChromaSession::ColourCustomGradientKeyword), csp->value(), csp->colour().red(), csp->colour().green(), csp->colour().blue(), csp->colour().alpha());
	}
	// -- Alpha control
	parser.writeLineF("%s  %s '%s'\n", indent, UChromaSession::collectionKeyword(UChromaSession::ColourAlphaControlKeyword), Collection::alphaControl(collection->alphaControl()));
	parser.writeLineF("%s  %s %f\n", indent, UChromaSession::collectionKeyword(UChromaSession::ColourAlphaFixedKeyword), collection->fixedAlpha());

	// Display
	parser.writeLineF("%s  %s %f '%s'\n", indent, UChromaSession::collectionKeyword(UChromaSession::LineStyleKeyword), collection->displayLineStyle().width(), LineStipple::stipple[collection->displayLineStyle().stipple()].name);
	parser.writeLineF("%s  %s %f\n", indent, UChromaSession::collectionKeyword(UChromaSession::ShininessKeyword), collection->displaySurfaceShininess());
	parser.writeLineF("%s  %s %s\n", indent, UChromaSession::collectionKeyword(UChromaSession::StyleKeyword), Collection::displayStyle(collection->displayStyle()));
	parser.writeLineF("%s  %s %s\n", indent, UChromaSession::collectionKeyword(UChromaSession::VisibleCollectionKeyword), stringBool(collection->visible()));

	// Loop over datasets
	for (DataSet* dataSet = collection->dataSets(); dataSet != NULL; dataSet = dataSet->next) writeDataSetBlock(parser, dataSet, indentLevel);

	// Write FitKernel data if present
	if (collection->fitKernel()) writeFitParametersBlock(parser, collection->fitKernel(), indentLevel);

	// Additional data
	// -- Fits
	for (Collection* fit = collection->fits(); fit != NULL; fit = fit->next) writeCollectionBlock(parser, fit, Collection::FitCollection, indentLevel+1);
	// -- Extracted Data
	for (Collection* extract = collection->slices(); extract != NULL; extract = extract->next) writeCollectionBlock(parser, extract, Collection::ExtractedCollection, indentLevel+1);

	parser.writeLineF("%s%s\n", indent, UChromaSession::collectionKeyword(UChromaSession::EndCollectionKeyword));

	return true;
}
Exemple #13
0
// Write AxisBlock keywords
bool UChromaSession::writeAxisBlock(LineParser& parser, Axes& axes, int axis)
{
	parser.writeLineF("    %s %i\n", UChromaSession::viewPaneKeyword(UChromaSession::AxisBlockKeyword), axis);
	parser.writeLineF("      %s %s\n", UChromaSession::axisKeyword(UChromaSession::AutoScaleKeyword), Axes::autoScaleMethod(axes.autoScale(axis)));
	parser.writeLineF("      %s %s\n", UChromaSession::axisKeyword(UChromaSession::AutoTicksKeyword), stringBool(axes.autoTicks(axis)));
	parser.writeLineF("      %s %f\n", UChromaSession::axisKeyword(UChromaSession::FirstTickKeyword), axes.tickFirst(axis));
	parser.writeLineF("      %s %s\n", UChromaSession::axisKeyword(UChromaSession::FractionalPositioningKeyword), stringBool(axes.positionIsFractional(axis)));
	parser.writeLineF("      %s %s %s %s\n", UChromaSession::axisKeyword(UChromaSession::GridLinesKeyword), stringBool(axes.gridLinesMajor(axis)), stringBool(axes.gridLinesMinor(axis)), stringBool(axes.gridLinesFull(axis)));
	LineStyle style = axes.gridLineMajorStyle(axis);
	parser.writeLineF("      %s %f '%s' %f %f %f %f\n", UChromaSession::axisKeyword(UChromaSession::GridLineMajorStyleKeyword), style.width(), LineStipple::stipple[style.stipple()].name, style.colour().redF(), style.colour().greenF(), style.colour().blueF(), style.colour().alphaF());
	style = axes.gridLineMinorStyle(axis);
	parser.writeLineF("      %s %f '%s' %f %f %f %f\n", UChromaSession::axisKeyword(UChromaSession::GridLineMinorStyleKeyword), style.width(), LineStipple::stipple[style.stipple()].name, style.colour().redF(), style.colour().greenF(), style.colour().blueF(), style.colour().alphaF());
	parser.writeLineF("      %s %s\n", UChromaSession::axisKeyword(UChromaSession::InvertKeyword), stringBool(axes.inverted(axis)));
	parser.writeLineF("      %s %s\n", UChromaSession::axisKeyword(UChromaSession::LabelAnchorKeyword), TextPrimitive::textAnchor(axes.labelAnchor(axis)));
	parser.writeLineF("      %s %f %f %f\n", UChromaSession::axisKeyword(UChromaSession::LabelOrientationKeyword), axes.labelOrientation(axis).x, axes.labelOrientation(axis).y, axes.labelOrientation(axis).z);
	parser.writeLineF("      %s %f %f\n", UChromaSession::axisKeyword(UChromaSession::LimitsKeyword), axes.min(axis), axes.max(axis));
	parser.writeLineF("      %s %s\n", UChromaSession::axisKeyword(UChromaSession::LogarithmicKeyword), stringBool(axes.logarithmic(axis)));
	parser.writeLineF("      %s %i\n", UChromaSession::axisKeyword(UChromaSession::MinorTicksKeyword), axes.minorTicks(axis));
	NumberFormat fmt = axes.numberFormat(axis);
	parser.writeLineF("      %s '%s' %i %s %s\n", UChromaSession::axisKeyword(UChromaSession::NumberFormatKeyword), NumberFormat::formatType(fmt.type()), fmt.nDecimals(), stringBool(fmt.useUpperCaseExponent()), stringBool(fmt.forcePrecedingPlus()));
	parser.writeLineF("      %s %f %f %f\n", UChromaSession::axisKeyword(UChromaSession::PositionFractionalKeyword), axes.positionFractional(axis).x, axes.positionFractional(axis).y, axes.positionFractional(axis).z);
	parser.writeLineF("      %s %f %f %f\n", UChromaSession::axisKeyword(UChromaSession::PositionRealKeyword), axes.positionReal(axis).x, axes.positionReal(axis).y, axes.positionReal(axis).z);
	parser.writeLineF("      %s %f\n", UChromaSession::axisKeyword(UChromaSession::StretchKeyword), axes.stretch(axis));
	parser.writeLineF("      %s %f\n", UChromaSession::axisKeyword(UChromaSession::TickDeltaKeyword), axes.tickDelta(axis));
	parser.writeLineF("      %s %f %f %f\n", UChromaSession::axisKeyword(UChromaSession::TickDirectionKeyword), axes.tickDirection(axis).x, axes.tickDirection(axis).y, axes.tickDirection(axis).z);
	parser.writeLineF("      %s %s\n", UChromaSession::axisKeyword(UChromaSession::TitleAnchorKeyword), TextPrimitive::textAnchor(axes.titleAnchor(axis)));
	parser.writeLine(QString("      ")+UChromaSession::axisKeyword(UChromaSession::TitleKeyword)+" '"+axes.title(axis)+"'\n");
	parser.writeLineF("      %s %f %f %f %f\n", UChromaSession::axisKeyword(UChromaSession::TitleOrientationKeyword), axes.titleOrientation(axis).x, axes.titleOrientation(axis).y, axes.titleOrientation(axis).z, axes.titleOrientation(axis).w);
	parser.writeLineF("      %s %s\n", UChromaSession::axisKeyword(UChromaSession::VisibleAxisKeyword), stringBool(axes.visible(axis)));
	parser.writeLineF("    %s\n", UChromaSession::axisKeyword(UChromaSession::EndAxisKeyword));

	return true;
}
Exemple #14
0
// Write ViewPaneBlock keywords
bool UChromaSession::writeViewPaneBlock(LineParser& parser, ViewPane* pane)
{
	parser.writeLineF("  %s '%s'\n", UChromaSession::viewKeyword(UChromaSession::ViewPaneBlockKeyword), qPrintable(pane->name()));
	parser.writeLineF("    %s %s\n", UChromaSession::viewPaneKeyword(UChromaSession::AutoPositionTitlesKeyword), stringBool(pane->axes().autoPositionTitles()));
	for (int axis=0; axis < 3; ++axis) writeAxisBlock(parser, pane->axes(), axis);
	parser.writeLineF("    %s %i\n", UChromaSession::viewPaneKeyword(UChromaSession::BoundingBoxKeyword), pane->boundingBox());
	parser.writeLineF("    %s %f\n", UChromaSession::viewPaneKeyword(UChromaSession::BoundingBoxPlaneYKeyword), pane->boundingBoxPlaneY());
	parser.writeLineF("    %s %s\n", UChromaSession::viewPaneKeyword(UChromaSession::FlatLabelsKeyword), stringBool(pane->flatLabels()));
	parser.writeLineF("    %s %i %i %i %i\n", UChromaSession::viewPaneKeyword(UChromaSession::GeometryKeyword), pane->bottomEdge(), pane->leftEdge(), pane->width(), pane->height()); 
	parser.writeLineF("    %s %f\n", UChromaSession::viewPaneKeyword(UChromaSession::LabelPointSizeKeyword), pane->labelPointSize());
	parser.writeLineF("    %s %f\n", UChromaSession::viewPaneKeyword(UChromaSession::TitlePointSizeKeyword), pane->titlePointSize());
	Matrix mat = pane->viewRotation();
	Vec3<double> trans = pane->viewTranslation();
	parser.writeLineF("    %s %f %f %f\n", UChromaSession::viewPaneKeyword(UChromaSession::RotationXKeyword), mat[0], mat[1], mat[2]);
	parser.writeLineF("    %s %f %f %f\n", UChromaSession::viewPaneKeyword(UChromaSession::RotationYKeyword), mat[4], mat[5], mat[6]);
	parser.writeLineF("    %s %f %f %f\n", UChromaSession::viewPaneKeyword(UChromaSession::RotationZKeyword), mat[8], mat[9], mat[10]);
	parser.writeLineF("    %s %f %f %f\n", UChromaSession::viewPaneKeyword(UChromaSession::TranslationKeyword), trans.x, trans.y, trans.z);
	parser.writeLineF("    %s %s\n", UChromaSession::viewPaneKeyword(UChromaSession::PerspectiveKeyword), stringBool(pane->hasPerspective()));
	parser.writeLineF("    %s '%s'\n", UChromaSession::viewPaneKeyword(UChromaSession::RoleKeyword), ViewPane::paneRole(pane->role()));
	for (TargetData* target = pane->collectionTargets(); target != NULL; target = target->next)
	{
		if (!Collection::objectValid(target->collection(), "collection in UChromaSession::writeViewPaneBlock")) continue;
		parser.writeLineF("    %s '%s'\n", UChromaSession::viewPaneKeyword(UChromaSession::RoleTargetCollectionKeyword), qPrintable(target->collection()->locator()));
	}
	for (RefListItem<ViewPane,bool>* ri = pane->paneTargets(); ri != NULL; ri = ri->next) parser.writeLineF("    %s '%s'\n", UChromaSession::viewPaneKeyword(UChromaSession::RoleTargetPaneKeyword), qPrintable(ri->item->name()));
	parser.writeLineF("    %s %s\n", UChromaSession::viewPaneKeyword(UChromaSession::UseBestFlatViewKeyword), stringBool(pane->axes().useBestFlatView()));
	parser.writeLineF("    %s '%s'\n", UChromaSession::viewPaneKeyword(UChromaSession::ViewTypeKeyword), ViewPane::viewType(pane->viewType()));
	parser.writeLineF("  %s\n", UChromaSession::viewPaneKeyword(UChromaSession::EndViewPaneKeyword));

	return true;
}
Exemple #15
0
ATEN_USING_NAMESPACE

// Load includes
void Aten::loadEncoderDefinitions()
{
	Messenger::enter("Aten::loadEncoderDefinitions");

	QString encoderDefsFile = dataDirectoryFile("external/encoders.txt");
	Messenger::print(Messenger::Verbose, "Looking for encoder definitions (%s)...", qPrintable(encoderDefsFile));
	
	LineParser parser;
	parser.openInput(encoderDefsFile);
	if (!parser.isFileGoodForReading())
	{
		Messenger::print("Unable to open encoder definitions file.\n");
		return;
	}

	// Read in encoder definitions from file
	QString keyword;
	EncoderDefinition::EncoderDefinitionKeyword edk;
	EncoderDefinition* encoder = NULL;
	ExternalCommand* command = NULL;
	while (!parser.eofOrBlank())
	{
		// Read first argument from file, which is our keyword
		parser.getArgsDelim(Parser::SkipBlanks + Parser::StripComments + Parser::UseQuotes);
		keyword = parser.argc(0);
		edk = EncoderDefinition::encoderDefinitionKeyword(keyword);
		if (edk == EncoderDefinition::nEncoderDefinitionKeywords)
		{
			Messenger::print("Unrecognised encoder definition keyword '%s'. Ignoring...\n", qPrintable(keyword));
			continue;
		}

		// Deal with remaining keywords
		switch (edk)
		{
			// Command Name
			case (EncoderDefinition::CommandNameKeyword):
				if (!encoder)
				{
					Messenger::error("No encoder definition yet created in which to set name data (use 'Name' keyword before all others).\n");
					continue;
				}
				command = encoder->addCommand();
				command->setName(parser.argc(1));
				break;
			// Command
			case (EncoderDefinition::CommandKeyword):
				if (!command)
				{
					Messenger::error("No command definition yet created in which to set command data (use 'CommandName' keyword before its siblings).\n");
					continue;
				}
				command->setExecutable(parser.argc(1));
				break;
			// Command arguments
			case (EncoderDefinition::CommandArgumentsKeyword):
				if (!command)
				{
					Messenger::error("No command definition yet created in which to set argument data (use 'CommandName' keyword before its siblings).\n");
					continue;
				}
				command->setArguments(parser.argc(1));
				break;
			case (EncoderDefinition::CommandSearchPathsKeyword):
				if (!command)
				{
					Messenger::error("No command definition yet created in which to set searchpath data (use 'CommandName' keyword before its siblings).\n");
					continue;
				}
				for (int n=1; n<parser.nArgs(); ++n) command->addSearchPath(parser.argc(n));
				break;
			// Name (create new object)
			case (EncoderDefinition::NameKeyword):
				encoder = encoders_.add();
				encoder->setName(parser.argc(1));
				break;
			case (EncoderDefinition::NicknameKeyword):
				if (!encoder)
				{
					Messenger::error("No encoder definition yet created in which to set data (use 'Name' keyword before all others).\n");
					continue;
				}
				encoder->setNickname(parser.argc(1));
				break;
      default:
        break;  
		}
	}
	parser.closeFiles();

	Messenger::exit("Aten::loadEncoderDefinitions");
}
Exemple #16
0
OGRGeometry * cvct2gdal::CVCT2GDALGeometry ( VCTGeometry & oVCTGeometry )
{
	OGRGeometry * poOGRGeometry = NULL;
	Geometry * poGeometry = NULL;

	if ( oVCTGeometry.geotype == GT_POINT )
	{
		PointParser oParser ( poVCTFile, poVCTDataSource );
		poGeometry = oParser.Parse ( oVCTGeometry );
		Geometry & cGeometry = *poGeometry;
		OGRGeometry * poPoint = new OGRPoint (cGeometry[0]->operator[](0).X,
		                                      cGeometry[0]->operator[](0).Y);
		poOGRGeometry = poPoint;
	}

	else if ( oVCTGeometry.geotype == GT_LINE )
	{
		LineParser  oParser ( poVCTFile, poVCTDataSource );
		poGeometry = oParser.Parse ( oVCTGeometry );
		Geometry & cGeometry = *poGeometry;
		OGRLineString * poLine = new OGRLineString();

		for ( auto iter = cGeometry[0]->begin();
		        iter != cGeometry[0]->end(); ++iter )
		{
			poLine->addPoint ( iter->X, iter->Y );
		}

		poOGRGeometry = poLine;
	}

	else if ( oVCTGeometry.geotype == GT_POLYGON )
	{
		PolyParser oParser ( poVCTFile, poVCTDataSource );
		poGeometry = oParser.Parse ( oVCTGeometry );
		Geometry & cGeometry = *poGeometry;
		int nParts = cGeometry.size();

		if (nParts == 1)
		{
			OGRPolygon * poOGRPoly = NULL;
			OGRLinearRing * poRing = NULL;
			poOGRGeometry = poOGRPoly = new OGRPolygon();
			poRing = CreateLinearRing(*cGeometry[0]);
			poOGRPoly->addRingDirectly(poRing);
		}

		else
		{
			OGRPolygon ** tabPolygons = new OGRPolygon*[nParts];

			for ( int iRing = 0; iRing != nParts; ++iRing )
			{
				tabPolygons[iRing] = new OGRPolygon();
				tabPolygons[iRing]->addRingDirectly ( CreateLinearRing ( *cGeometry[iRing] ) );
			}

			int isValidGeometry;
			const char * papszOptions[] = { "METHOD=ONLY_CCW", NULL };
			poOGRGeometry = OGRGeometryFactory::organizePolygons (
			                    ( OGRGeometry ** ) tabPolygons, nParts, &isValidGeometry, papszOptions );

			delete[] tabPolygons;
		}
	}

	DestroyGeometry(poGeometry);

	return poOGRGeometry;
}
Exemple #17
0
// Write FitParametersBlock keywords
bool UChromaSession::writeFitParametersBlock(LineParser& parser, FitKernel* fitKernel, int indentLevel)
{
	// Construct indent string
	char* indent = new char[indentLevel*2+1];
	for (int n=0; n<indentLevel*2; ++n) indent[n] = ' ';
	indent[indentLevel*2] = '\0';

	parser.writeLineF("%s  %s\n", indent, UChromaSession::collectionKeyword(UChromaSession::FitParametersBlockKeyword));
	for (RefListItem<ReferenceVariable,bool>* ri = fitKernel->usedReferences(); ri != NULL; ri = ri->next)
	{
		ReferenceVariable* refVar = ri->item;
		parser.writeLineF("%s    %s %s %s %i %i %s %i %i '%s'\n", indent, UChromaSession::fitParametersKeyword(UChromaSession::ReferenceKeyword), qPrintable(refVar->name()), IndexData::indexType(refVar->xIndex().type()), refVar->xIndex().index(), refVar->xIndex().offset(), IndexData::indexType(refVar->zIndex().type()), refVar->zIndex().index(), refVar->zIndex().offset(), qPrintable(refVar->zDataSetName()));
	}
	parser.writeLineF("%s    %s '%s'\n", indent, UChromaSession::fitParametersKeyword(UChromaSession::EquationKeyword), qPrintable(fitKernel->equationText()));
	parser.writeLineF("%s    %s %s\n", indent, UChromaSession::fitParametersKeyword(UChromaSession::GlobalKeyword), stringBool(fitKernel->global()));
	parser.writeLineF("%s    %s %s\n", indent, UChromaSession::fitParametersKeyword(UChromaSession::OrthogonalKeyword), stringBool(fitKernel->orthogonal()));
	parser.writeLineF("%s    %s %f\n", indent, UChromaSession::fitParametersKeyword(UChromaSession::LimitStrengthKeyword), fitKernel->limitStrength());
	for (RefListItem<EquationVariable,bool>* ri = fitKernel->usedVariables(); ri != NULL; ri = ri->next)
	{
		EquationVariable* eqVar = ri->item;
		parser.writeLineF("%s    %s %s %s %f %s %f %s %f\n", indent, UChromaSession::fitParametersKeyword(UChromaSession::VariableKeyword), qPrintable(eqVar->name()), stringBool(eqVar->fit()), eqVar->value(), stringBool(eqVar->maximumLimitEnabled()), eqVar->minimumLimit(), stringBool(eqVar->maximumLimitEnabled()), eqVar->maximumLimit());
	}
	parser.writeLineF("%s    %s %s\n", indent, UChromaSession::fitParametersKeyword(UChromaSession::XRangeTypeKeyword), FitKernel::rangeType(fitKernel->xRange()));
	parser.writeLineF("%s    %s %f %f\n", indent, UChromaSession::fitParametersKeyword(UChromaSession::XRangeAbsoluteKeyword), fitKernel->absoluteXMin(), fitKernel->absoluteXMax());
	parser.writeLineF("%s    %s %i %i\n", indent, UChromaSession::fitParametersKeyword(UChromaSession::XRangeIndexKeyword), fitKernel->indexXMin()+1, fitKernel->indexXMax()+1);
	parser.writeLineF("%s    %s %i\n", indent, UChromaSession::fitParametersKeyword(UChromaSession::XRangeIndexSingleKeyword), fitKernel->indexXSingle()+1);
	parser.writeLineF("%s    %s %s\n", indent, UChromaSession::fitParametersKeyword(UChromaSession::ZRangeTypeKeyword), FitKernel::rangeType(fitKernel->zRange()));
	parser.writeLineF("%s    %s %f %f\n", indent, UChromaSession::fitParametersKeyword(UChromaSession::ZRangeAbsoluteKeyword), fitKernel->absoluteZMin(), fitKernel->absoluteZMax());
	parser.writeLineF("%s    %s %i %i\n", indent, UChromaSession::fitParametersKeyword(UChromaSession::ZRangeIndexKeyword), fitKernel->indexZMin()+1, fitKernel->indexZMax()+1);
	parser.writeLineF("%s    %s %i\n", indent, UChromaSession::fitParametersKeyword(UChromaSession::ZRangeIndexSingleKeyword), fitKernel->indexZSingle()+1);

	// Write fit results for each range
	int count = 1;
	for (DataSpaceRange* range = fitKernel->dataSpaceRanges(); range != NULL; range = range->next) writeFitResultsBlock(parser, range, count++, indentLevel+1);

	parser.writeLineF("%s  %s\n", indent, UChromaSession::fitParametersKeyword(UChromaSession::EndFitParametersKeyword));

	return true;
}