<commit_before>/*
 *  despot2_main.cpp
 *
 *  Created by Tobias Wood on 23/01/2012.
 *  Copyright (c) 2012-2013 Tobias Wood.
 *
 *  This Source Code Form is subject to the terms of the Mozilla Public
 *  License, v. 2.0. If a copy of the MPL was not distributed with this
 *  file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 */

#include <getopt.h>
#include <iostream>
#include <atomic>
#include <Eigen/Dense>
#include "unsupported/Eigen/NonLinearOptimization"
#include "unsupported/Eigen/NumericalDiff"

#include "Nifti/Nifti.h"
#include "QUIT/QUIT.h"
#include "DESPOT.h"
#include "DESPOT_Functors.h"

using namespace std;
using namespace Eigen;
using namespace QUIT;

//******************************************************************************
// Arguments / Usage
//******************************************************************************
const string usage {
"Usage is: despot2 [options] T1_map ssfp_file\n\
\n\
Options:\n\
	--help, -h        : Print this message.\n\
	--mask, -m file   : Mask input with specified file.\n\
	--out, -o path    : Add a prefix to the output filenames.\n\
	--B1 file         : B1 Map file.\n\
	--elliptical, -e  : Input is band-free elliptical data.\n\
	--verbose, -v     : Print slice processing times.\n\
	--no-prompt, -n   : Suppress input prompts.\n\
	--algo, -a l      : LLS algorithm (default)\n\
	           w      : WLLS algorithm\n\
	           n      : NLLS (Levenberg-Marquardt)\n\
	--its, -i N       : Max iterations for WLLS (default 4)\n\
	--threads, -T N   : Use N threads (default=hardware limit)\n"
};

enum class Algos { LLS, WLLS, NLLS };
static int verbose = false, prompt = true, elliptical = false;
static size_t nIterations = 4;
static Algos algo;
static string outPrefix;
static struct option long_options[] =
{
	{"B1", required_argument, 0, '1'},
	{"elliptical", no_argument, 0, 'e'},
	{"help", no_argument, 0, 'h'},
	{"mask", required_argument, 0, 'm'},
	{"verbose", no_argument, 0, 'v'},
	{"no-prompt", no_argument, 0, 'n'},
	{"algo", required_argument, 0, 'a'},
	{"its", required_argument, 0, 'i'},
	{"threads", required_argument, 0, 'T'},
	{0, 0, 0, 0}
};

//******************************************************************************
// Main
//******************************************************************************
int main(int argc, char **argv)
{
	try { // To fix uncaught exceptions on Mac

	Nifti::File maskFile, B0File, B1File;
	MultiArray<double, 3> maskVol, B1Vol;
	ThreadPool threads;
	string procPath;

	int indexptr = 0, c;
	while ((c = getopt_long(argc, argv, "hm:o:b:vna:i:T:e", long_options, &indexptr)) != -1) {
		switch (c) {
			case 'o':
				outPrefix = optarg;
				if (verbose) cout << "Output prefix will be: " << outPrefix << endl;
				break;
			case 'm':
				cout << "Reading mask file " << optarg << endl;
				maskFile.open(optarg, Nifti::Mode::Read);
				maskVol.resize(maskFile.matrix());
				maskFile.readVolumes(maskVol.begin(), maskVol.end(), 0, 1);
				break;
			case 'b':
				cout << "Reading B1 file: " << optarg << endl;
				B1File.open(optarg, Nifti::Mode::Read);
				B1Vol.resize(B1File.matrix());
				B1File.readVolumes(B1Vol.begin(), B1Vol.end(), 0, 1);
				break;
			case 'a':
				switch (*optarg) {
					case 'l': algo = Algos::LLS;  if (verbose) cout << "LLS algorithm selected." << endl; break;
					case 'w': algo = Algos::WLLS; if (verbose) cout << "WLLS algorithm selected." << endl; break;
					case 'n': algo = Algos::NLLS; if (verbose) cout << "NLLS algorithm selected." << endl; break;
					default:
						cout << "Unknown algorithm type " << optarg << endl;
						return EXIT_FAILURE;
						break;
				} break;
			case 'i':
				nIterations = atoi(optarg);
				break;
			case 'v': verbose = true; break;
			case 'n': prompt = false; break;
			case 'e': elliptical = true; break;
			case 'T':
				threads.resize(atoi(optarg));
				break;
			case 0:
				// Just a flag
				break;
			case '?': // getopt will print an error message
			case 'h':
				cout << usage << endl;
				return EXIT_SUCCESS;
		}
	}
	if (verbose) cout << version << endl << credit_shared << endl;
	Eigen::initParallel();
	if ((argc - optind) != 2) {
		cout << "Wrong number of arguments. Need a T1 map and 1 SSFP file." << endl;
		cout << usage << endl;
		return EXIT_FAILURE;
	}
	if (verbose) cout << "Reading T1 Map from: " << argv[optind] << endl;
	Nifti::File T1File(argv[optind++]);
	MultiArray<double, 3> T1Vol(T1File.matrix());
	T1File.readVolumes(T1Vol.begin(), T1Vol.end(), 0, 1);
	//**************************************************************************
	// Gather SSFP Data
	//**************************************************************************
	Sequences ssfp(Scale::None);
	if (verbose) cout << "Opening SSFP file: " << argv[optind] << endl;
	Nifti::File SSFPFile(argv[optind++]);
	if (verbose) cout << "Checking headers for consistency." << endl;
	checkHeaders(SSFPFile.header(), {T1File, maskFile, B1File});
	if (verbose) cout << "Checking for ProcPar." << endl;
	Agilent::ProcPar pp; ReadPP(SSFPFile, pp);
	if (verbose) cout << "Reading sequence parameters." << endl;
	if (elliptical) {
		ssfp.addSequence(SequenceType::SSFP_Ellipse, prompt, pp);
	} else {
		ssfp.addSequence(SequenceType::SSFP, prompt, pp);
	}
	if (ssfp.size() != SSFPFile.header().dim(4)) {
		throw(std::runtime_error("The specified number of flip-angles and phase-cycles does not match the input file: " + SSFPFile.imagePath()));
	}
	if (verbose) {
		cout << ssfp;
		cout << "Reading data." << endl;
	}
	MultiArray<complex<double>, 4> ssfpVols(SSFPFile.header().fulldims().head(4));
	SSFPFile.readVolumes(ssfpVols.begin(), ssfpVols.end());
	//**************************************************************************
	// Do the fitting
	//**************************************************************************
	const auto dims = SSFPFile.matrix();
	double TR = ssfp.sequence(0)->m_TR;
	MultiArray<float, 3> T2Vol(dims), PDVol(dims), offResVol(dims), SoSVol(dims);
	time_t startTime;
	if (verbose)
		startTime = printStartTime();
	clock_t startClock = clock();
	int voxCount = 0;
	for (size_t k = 0; k < dims(2); k++) {
		if (verbose)
			cout << "Starting slice " << k << "..." << flush;
		clock_t loopStart = clock();
		atomic<int> sliceCount{0};
		function<void (const int&)> process = [&] (const int &j) {
			for (size_t i = 0; i < dims(0); i++) {
				if (!maskFile || (maskVol[{i,j,k}])) {
					sliceCount++;
					double B1, T1, T2, E1, E2, PD, offRes, SoS;
					B1 = B1File ? B1Vol[{i,j,k}] : 1.;
					T1 = T1Vol[{i,j,k}];
					E1 = exp(-TR / T1);
					const ArrayXd localAngles(ssfp.sequence(0)->B1flip(B1));
					const ArrayXcd data = ssfpVols.slice<1>({i,j,k,0},{0,0,0,-1}).asArray().cast<complex<double>>();
					// Use phase of mean instead of mean of phase to avoid wrap issues
					const complex<double> mean_data = data.mean();
					offRes = arg(-mean_data) / (M_PI * TR);

					const ArrayXd s = data.abs();
					VectorXd Y = s / localAngles.sin();
					MatrixXd X(Y.rows(), 2);
					X.col(0) = s / localAngles.tan();
					X.col(1).setOnes();
					VectorXd b = (X.transpose() * X).partialPivLu().solve(X.transpose() * Y);
					if (elliptical) {
						T2 = 2. * TR / log((b[0]*E1 - 1.) / (b[0] - E1));
						E2 = exp(-TR / T2);
						PD = b[1] * (1. - E1*E2*E2) / (sqrt(E2) * (1. - E1));
					} else {
						T2 = TR / log((b[0]*E1 - 1.)/(b[0] - E1));
						E2 = exp(-TR / T2);
						PD = b[1] * (1. - E1*E2) / (1. - E1);
					}
					if (algo == Algos::WLLS) {
						VectorXd W(ssfp.size());
						for (size_t n = 0; n < nIterations; n++) {
							if (elliptical) {
								W = ((1. - E1*E2) * localAngles.sin() / (1. - E1*E2*E2 - (E1 - E2*E2)*localAngles.cos())).square();
							} else {
								W = ((1. - E1*E2) * localAngles.sin() / (1. - E1*E2 - (E1 - E2)*localAngles.cos())).square();
							}
							b = (X.transpose() * W.asDiagonal() * X).partialPivLu().solve(X.transpose() * W.asDiagonal() * Y);
							if (elliptical) {
								T2 = 2. * TR / log((b[0]*E1 - 1.) / (b[0] - E1));
								E2 = exp(-TR / T2);
								PD = b[1] * (1. - E1*E2*E2) / (sqrt(E2) * (1. - E1));
							} else {
								T2 = TR / log((b[0]*E1 - 1.)/(b[0] - E1));
								E2 = exp(-TR / T2);
								PD = b[1] * (1. - E1*E2) / (1. - E1);
							}
						}
					} else if (algo == Algos::NLLS) {
						D2Functor f(T1, ssfp, Pools::One, data, B1, true, false);
						NumericalDiff<D2Functor> nDiff(f);
						LevenbergMarquardt<NumericalDiff<D2Functor>> lm(nDiff);
						lm.parameters.maxfev = nIterations;
						VectorXd p(3);
						p << PD, T2, offRes;
						//cout << "Running LM..." << endl;
						//cout << "Start P: " << p.transpose() << endl;
						lm.lmder1(p);
						//cout << "End P: " << p.transpose() << endl;
						//cout << "Finished LM" << endl;
						PD = p(0); T2 = p(1); offRes = p(2);
						//exit(EXIT_SUCCESS);
					}
					ArrayXd theory = ssfp.signal(Pools::One, Vector4d(PD, T1, T2, offRes), B1).abs();
					SoS = (s - theory).abs2().sum() / ssfp.size();
					T2Vol[{i,j,k}]  = static_cast<float>(T2);
					PDVol[{i,j,k}]  = static_cast<float>(PD);
					offResVol[{i,j,k}] = static_cast<float>(offRes);
					SoSVol[{i,j,k}] = static_cast<float>(SoS);
				}
			}
		};
		threads.for_loop(process, dims(1));
		if (verbose) printLoopTime(loopStart, sliceCount);
		voxCount += sliceCount;
	}
	if (verbose) {
		printElapsedTime(startTime);
		cout << "Writing results." << endl;
	}
	printElapsedClock(startClock, voxCount);
	Nifti::Header outHdr = SSFPFile.header();
	outHdr.description = version;
	outHdr.setDim(4, 1);
	outHdr.setDatatype(Nifti::DataType::FLOAT32);
	outHdr.intent = Nifti::Intent::Estimate;
	outHdr.intent_name = "T2 (s)";
	Nifti::File outFile(outHdr, outPrefix + "D2_T2" + OutExt());
	outFile.writeVolumes(T2Vol.begin(), T2Vol.end());
	outFile.close();
	outHdr.intent_name = "PD (au)";
	outFile.open(outPrefix + "D2_PD" + OutExt(), Nifti::Mode::Write);
	outFile.writeVolumes(PDVol.begin(), PDVol.end());
	outFile.close();
	outHdr.intent_name = "Sum of Squared Residuals";
	outFile.open(outPrefix + "D2_SoS" + OutExt(), Nifti::Mode::Write);
	outFile.writeVolumes(SoSVol.begin(), SoSVol.end());
	outFile.close();
	outHdr.intent_name = "Off-resonance (Hz)";
	outFile.open(outPrefix + "D2_f0" + OutExt(), Nifti::Mode::Write);
	outFile.writeVolumes(offResVol.begin(), offResVol.end());
	outFile.close();

	if (verbose) cout << "All done." << endl;
	} catch (exception &e) {
		cerr << e.what() << endl;
		return EXIT_FAILURE;
	}
	return EXIT_SUCCESS;
}
<commit_msg>Added a switch to negate the phase before doing the off-resonance calculation.<commit_after>/*
 *  despot2_main.cpp
 *
 *  Created by Tobias Wood on 23/01/2012.
 *  Copyright (c) 2012-2013 Tobias Wood.
 *
 *  This Source Code Form is subject to the terms of the Mozilla Public
 *  License, v. 2.0. If a copy of the MPL was not distributed with this
 *  file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 */

#include <getopt.h>
#include <iostream>
#include <atomic>
#include <Eigen/Dense>
#include "unsupported/Eigen/NonLinearOptimization"
#include "unsupported/Eigen/NumericalDiff"

#include "Nifti/Nifti.h"
#include "QUIT/QUIT.h"
#include "DESPOT.h"
#include "DESPOT_Functors.h"

using namespace std;
using namespace Eigen;
using namespace QUIT;

//******************************************************************************
// Arguments / Usage
//******************************************************************************
const string usage {
"Usage is: despot2 [options] T1_map ssfp_file\n\
\n\
Options:\n\
	--help, -h        : Print this message.\n\
	--mask, -m file   : Mask input with specified file.\n\
	--out, -o path    : Add a prefix to the output filenames.\n\
	--B1 file         : B1 Map file.\n\
	--elliptical, -e  : Input is band-free elliptical data.\n\
	--negres, -r      : Negate data before calculating off-res.\n\
	--verbose, -v     : Print slice processing times.\n\
	--no-prompt, -n   : Suppress input prompts.\n\
	--algo, -a l      : LLS algorithm (default)\n\
	           w      : WLLS algorithm\n\
	           n      : NLLS (Levenberg-Marquardt)\n\
	--its, -i N       : Max iterations for WLLS (default 4)\n\
	--threads, -T N   : Use N threads (default=hardware limit)\n"
};

enum class Algos { LLS, WLLS, NLLS };
static int verbose = false, prompt = true, elliptical = false, neg_res = false;
static size_t nIterations = 4;
static Algos algo;
static string outPrefix;
static struct option long_options[] =
{
	{"B1", required_argument, 0, '1'},
	{"elliptical", no_argument, 0, 'e'},
	{"negres", no_argument, 0, 'r'},
	{"help", no_argument, 0, 'h'},
	{"mask", required_argument, 0, 'm'},
	{"verbose", no_argument, 0, 'v'},
	{"no-prompt", no_argument, 0, 'n'},
	{"algo", required_argument, 0, 'a'},
	{"its", required_argument, 0, 'i'},
	{"threads", required_argument, 0, 'T'},
	{0, 0, 0, 0}
};

//******************************************************************************
// Main
//******************************************************************************
int main(int argc, char **argv)
{
	try { // To fix uncaught exceptions on Mac

	Nifti::File maskFile, B0File, B1File;
	MultiArray<double, 3> maskVol, B1Vol;
	ThreadPool threads;
	string procPath;

	int indexptr = 0, c;
	while ((c = getopt_long(argc, argv, "hm:o:b:vna:i:T:er", long_options, &indexptr)) != -1) {
		switch (c) {
			case 'o':
				outPrefix = optarg;
				if (verbose) cout << "Output prefix will be: " << outPrefix << endl;
				break;
			case 'm':
				cout << "Reading mask file " << optarg << endl;
				maskFile.open(optarg, Nifti::Mode::Read);
				maskVol.resize(maskFile.matrix());
				maskFile.readVolumes(maskVol.begin(), maskVol.end(), 0, 1);
				break;
			case 'b':
				cout << "Reading B1 file: " << optarg << endl;
				B1File.open(optarg, Nifti::Mode::Read);
				B1Vol.resize(B1File.matrix());
				B1File.readVolumes(B1Vol.begin(), B1Vol.end(), 0, 1);
				break;
			case 'a':
				switch (*optarg) {
					case 'l': algo = Algos::LLS;  if (verbose) cout << "LLS algorithm selected." << endl; break;
					case 'w': algo = Algos::WLLS; if (verbose) cout << "WLLS algorithm selected." << endl; break;
					case 'n': algo = Algos::NLLS; if (verbose) cout << "NLLS algorithm selected." << endl; break;
					default:
						cout << "Unknown algorithm type " << optarg << endl;
						return EXIT_FAILURE;
						break;
				} break;
			case 'i':
				nIterations = atoi(optarg);
				break;
			case 'v': verbose = true; break;
			case 'n': prompt = false; break;
			case 'e': elliptical = true; break;
			case 'r': neg_res = true; break;
			case 'T':
				threads.resize(atoi(optarg));
				break;
			case 0:
				// Just a flag
				break;
			case '?': // getopt will print an error message
			case 'h':
				cout << usage << endl;
				return EXIT_SUCCESS;
		}
	}
	if (verbose) cout << version << endl << credit_shared << endl;
	Eigen::initParallel();
	if ((argc - optind) != 2) {
		cout << "Wrong number of arguments. Need a T1 map and 1 SSFP file." << endl;
		cout << usage << endl;
		return EXIT_FAILURE;
	}
	if (verbose) cout << "Reading T1 Map from: " << argv[optind] << endl;
	Nifti::File T1File(argv[optind++]);
	MultiArray<double, 3> T1Vol(T1File.matrix());
	T1File.readVolumes(T1Vol.begin(), T1Vol.end(), 0, 1);
	//**************************************************************************
	// Gather SSFP Data
	//**************************************************************************
	Sequences ssfp(Scale::None);
	if (verbose) cout << "Opening SSFP file: " << argv[optind] << endl;
	Nifti::File SSFPFile(argv[optind++]);
	if (verbose) cout << "Checking headers for consistency." << endl;
	checkHeaders(SSFPFile.header(), {T1File, maskFile, B1File});
	if (verbose) cout << "Checking for ProcPar." << endl;
	Agilent::ProcPar pp; ReadPP(SSFPFile, pp);
	if (verbose) cout << "Reading sequence parameters." << endl;
	if (elliptical) {
		ssfp.addSequence(SequenceType::SSFP_Ellipse, prompt, pp);
	} else {
		ssfp.addSequence(SequenceType::SSFP, prompt, pp);
	}
	if (ssfp.size() != SSFPFile.header().dim(4)) {
		throw(std::runtime_error("The specified number of flip-angles and phase-cycles does not match the input file: " + SSFPFile.imagePath()));
	}
	if (verbose) {
		cout << ssfp;
		cout << "Reading data." << endl;
	}
	MultiArray<complex<double>, 4> ssfpVols(SSFPFile.header().fulldims().head(4));
	SSFPFile.readVolumes(ssfpVols.begin(), ssfpVols.end());
	//**************************************************************************
	// Do the fitting
	//**************************************************************************
	const auto dims = SSFPFile.matrix();
	double TR = ssfp.sequence(0)->m_TR;
	MultiArray<float, 3> T2Vol(dims), PDVol(dims), offResVol(dims), SoSVol(dims);
	time_t startTime;
	if (verbose)
		startTime = printStartTime();
	clock_t startClock = clock();
	int voxCount = 0;
	for (size_t k = 0; k < dims(2); k++) {
		if (verbose)
			cout << "Starting slice " << k << "..." << flush;
		clock_t loopStart = clock();
		atomic<int> sliceCount{0};
		function<void (const int&)> process = [&] (const int &j) {
			for (size_t i = 0; i < dims(0); i++) {
				if (!maskFile || (maskVol[{i,j,k}])) {
					sliceCount++;
					double B1, T1, T2, E1, E2, PD, offRes, SoS;
					B1 = B1File ? B1Vol[{i,j,k}] : 1.;
					T1 = T1Vol[{i,j,k}];
					E1 = exp(-TR / T1);
					const ArrayXd localAngles(ssfp.sequence(0)->B1flip(B1));
					const ArrayXcd data = ssfpVols.slice<1>({i,j,k,0},{0,0,0,-1}).asArray().cast<complex<double>>();
					// Use phase of mean instead of mean of phase to avoid wrap issues
					const complex<double> mean_data = data.mean();
					if (neg_res)
						offRes = arg(-mean_data) / (M_PI * TR);
					else
						offRes = arg(mean_data) / (M_PI * TR);

					const ArrayXd s = data.abs();
					VectorXd Y = s / localAngles.sin();
					MatrixXd X(Y.rows(), 2);
					X.col(0) = s / localAngles.tan();
					X.col(1).setOnes();
					VectorXd b = (X.transpose() * X).partialPivLu().solve(X.transpose() * Y);
					if (elliptical) {
						T2 = 2. * TR / log((b[0]*E1 - 1.) / (b[0] - E1));
						E2 = exp(-TR / T2);
						PD = b[1] * (1. - E1*E2*E2) / (sqrt(E2) * (1. - E1));
					} else {
						T2 = TR / log((b[0]*E1 - 1.)/(b[0] - E1));
						E2 = exp(-TR / T2);
						PD = b[1] * (1. - E1*E2) / (1. - E1);
					}
					if (algo == Algos::WLLS) {
						VectorXd W(ssfp.size());
						for (size_t n = 0; n < nIterations; n++) {
							if (elliptical) {
								W = ((1. - E1*E2) * localAngles.sin() / (1. - E1*E2*E2 - (E1 - E2*E2)*localAngles.cos())).square();
							} else {
								W = ((1. - E1*E2) * localAngles.sin() / (1. - E1*E2 - (E1 - E2)*localAngles.cos())).square();
							}
							b = (X.transpose() * W.asDiagonal() * X).partialPivLu().solve(X.transpose() * W.asDiagonal() * Y);
							if (elliptical) {
								T2 = 2. * TR / log((b[0]*E1 - 1.) / (b[0] - E1));
								E2 = exp(-TR / T2);
								PD = b[1] * (1. - E1*E2*E2) / (sqrt(E2) * (1. - E1));
							} else {
								T2 = TR / log((b[0]*E1 - 1.)/(b[0] - E1));
								E2 = exp(-TR / T2);
								PD = b[1] * (1. - E1*E2) / (1. - E1);
							}
						}
					} else if (algo == Algos::NLLS) {
						D2Functor f(T1, ssfp, Pools::One, data, B1, true, false);
						NumericalDiff<D2Functor> nDiff(f);
						LevenbergMarquardt<NumericalDiff<D2Functor>> lm(nDiff);
						lm.parameters.maxfev = nIterations;
						VectorXd p(3);
						p << PD, T2, offRes;
						//cout << "Running LM..." << endl;
						//cout << "Start P: " << p.transpose() << endl;
						lm.lmder1(p);
						//cout << "End P: " << p.transpose() << endl;
						//cout << "Finished LM" << endl;
						PD = p(0); T2 = p(1); offRes = p(2);
						//exit(EXIT_SUCCESS);
					}
					ArrayXd theory = ssfp.signal(Pools::One, Vector4d(PD, T1, T2, offRes), B1).abs();
					SoS = (s - theory).abs2().sum() / ssfp.size();
					T2Vol[{i,j,k}]  = static_cast<float>(T2);
					PDVol[{i,j,k}]  = static_cast<float>(PD);
					offResVol[{i,j,k}] = static_cast<float>(offRes);
					SoSVol[{i,j,k}] = static_cast<float>(SoS);
				}
			}
		};
		threads.for_loop(process, dims(1));
		if (verbose) printLoopTime(loopStart, sliceCount);
		voxCount += sliceCount;
	}
	if (verbose) {
		printElapsedTime(startTime);
		cout << "Writing results." << endl;
	}
	printElapsedClock(startClock, voxCount);
	Nifti::Header outHdr = SSFPFile.header();
	outHdr.description = version;
	outHdr.setDim(4, 1);
	outHdr.setDatatype(Nifti::DataType::FLOAT32);
	outHdr.intent = Nifti::Intent::Estimate;
	outHdr.intent_name = "T2 (s)";
	Nifti::File outFile(outHdr, outPrefix + "D2_T2" + OutExt());
	outFile.writeVolumes(T2Vol.begin(), T2Vol.end());
	outFile.close();
	outHdr.intent_name = "PD (au)";
	outFile.open(outPrefix + "D2_PD" + OutExt(), Nifti::Mode::Write);
	outFile.writeVolumes(PDVol.begin(), PDVol.end());
	outFile.close();
	outHdr.intent_name = "Sum of Squared Residuals";
	outFile.open(outPrefix + "D2_SoS" + OutExt(), Nifti::Mode::Write);
	outFile.writeVolumes(SoSVol.begin(), SoSVol.end());
	outFile.close();
	outHdr.intent_name = "Off-resonance (Hz)";
	outFile.open(outPrefix + "D2_f0" + OutExt(), Nifti::Mode::Write);
	outFile.writeVolumes(offResVol.begin(), offResVol.end());
	outFile.close();

	if (verbose) cout << "All done." << endl;
	} catch (exception &e) {
		cerr << e.what() << endl;
		return EXIT_FAILURE;
	}
	return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>/**
 * This file is part of the "libstx" project
 *   Copyright (c) 2014 Paul Asmuth, Google Inc.
 *
 * libstx is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License v3.0. You should have received a
 * copy of the GNU General Public License along with this program. If not, see
 * <http://www.gnu.org/licenses/>.
 */
#include <assert.h>
#include <unistd.h>
#include <fcntl.h>
#include "stx/csv/CSVInputStream.h"
#include "stx/exception.h"
#include "stx/io/inputstream.h"

namespace stx {

std::unique_ptr<CSVInputStream> CSVInputStream::openFile(
    const std::string& file_path,
    char column_separator /* = ';' */,
    char row_separator /* = '\n' */,
    char quote_char /* = '"' */) {
  auto file = FileInputStream::openFile(file_path);
  file->readByteOrderMark();

  auto csv_file = new DefaultCSVInputStream(
      std::move(file),
      column_separator,
      row_separator,
      quote_char);

  return std::unique_ptr<CSVInputStream>(csv_file);
}

DefaultCSVInputStream::DefaultCSVInputStream(
    std::unique_ptr<RewindableInputStream>&& input_stream,
    char column_separator /* = ';' */,
    char row_separator /* = '\n' */,
    char quote_char /* = '"' */) :
    input_(std::move(input_stream)),
    column_separator_(column_separator),
    row_separator_(row_separator),
    quote_char_(quote_char) {}

// FIXPAUL quotechar unescaping...
bool DefaultCSVInputStream::readNextRow(std::vector<std::string>* target) {
  target->clear();

  bool eof = false;

  for (;;) {
    std::string column;
    char byte;
    bool quoted = false;

    for (;;) {
      if (!input_->readNextByte(&byte)) {
        eof = true;
        break;
      }

      if (!quoted && byte == column_separator_) {
        break;
      }

      if (!quoted && byte == row_separator_) {
        break;
      }

      if (byte == quote_char_) {
        quoted = !quoted;
      }

      column += byte;
    }

    target->emplace_back(column);

    if (eof || byte == row_separator_) {
      break;
    }
  }

  return !eof;
}

bool DefaultCSVInputStream::skipNextRow() {
  std::vector<std::string> devnull;
  return readNextRow(&devnull);
}

void DefaultCSVInputStream::rewind() {
  input_->rewind();
}

const RewindableInputStream& DefaultCSVInputStream::getInputStream() const {
  return *input_;
}

}
<commit_msg>strip quote chars in CSVInputStream<commit_after>/**
 * This file is part of the "libstx" project
 *   Copyright (c) 2014 Paul Asmuth, Google Inc.
 *
 * libstx is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License v3.0. You should have received a
 * copy of the GNU General Public License along with this program. If not, see
 * <http://www.gnu.org/licenses/>.
 */
#include <assert.h>
#include <unistd.h>
#include <fcntl.h>
#include "stx/csv/CSVInputStream.h"
#include "stx/exception.h"
#include "stx/io/inputstream.h"

namespace stx {

std::unique_ptr<CSVInputStream> CSVInputStream::openFile(
    const std::string& file_path,
    char column_separator /* = ';' */,
    char row_separator /* = '\n' */,
    char quote_char /* = '"' */) {
  auto file = FileInputStream::openFile(file_path);
  file->readByteOrderMark();

  auto csv_file = new DefaultCSVInputStream(
      std::move(file),
      column_separator,
      row_separator,
      quote_char);

  return std::unique_ptr<CSVInputStream>(csv_file);
}

DefaultCSVInputStream::DefaultCSVInputStream(
    std::unique_ptr<RewindableInputStream>&& input_stream,
    char column_separator /* = ';' */,
    char row_separator /* = '\n' */,
    char quote_char /* = '"' */) :
    input_(std::move(input_stream)),
    column_separator_(column_separator),
    row_separator_(row_separator),
    quote_char_(quote_char) {}

// FIXPAUL quotechar unescaping...
bool DefaultCSVInputStream::readNextRow(std::vector<std::string>* target) {
  target->clear();

  bool eof = false;

  for (;;) {
    std::string column;
    char byte;
    bool quoted = false;

    for (;;) {
      if (!input_->readNextByte(&byte)) {
        eof = true;
        break;
      }

      if (!quoted && byte == column_separator_) {
        break;
      }

      if (!quoted && byte == row_separator_) {
        break;
      }

      if (byte == quote_char_) {
        quoted = !quoted;
        continue;
      }

      column += byte;
    }

    target->emplace_back(column);

    if (eof || byte == row_separator_) {
      break;
    }
  }

  return !eof;
}

bool DefaultCSVInputStream::skipNextRow() {
  std::vector<std::string> devnull;
  return readNextRow(&devnull);
}

void DefaultCSVInputStream::rewind() {
  input_->rewind();
}

const RewindableInputStream& DefaultCSVInputStream::getInputStream() const {
  return *input_;
}

}
<|endoftext|>


<commit_before>/**
 * \file gaffe_main.cpp: GFA (Graph Alignment Format) Fast Emitter: a new mapper that will be *extremely* fast once we actually write it
 */

#include <omp.h>
#include <unistd.h>
#include <getopt.h>
#include <iostream>
#include <cassert>
#include <vector>
#include <unordered_set>
#include <chrono>

#include "subcommand.hpp"

#include "../seed_clusterer.hpp"
#include "../mapper.hpp"
#include "../annotation.hpp"
#include "../minimizer.hpp"
#include <vg/io/vpkg.hpp>
#include <vg/io/stream.hpp>
#include "../alignment_emitter.hpp"
#include "../gapless_extender.hpp"
#include "../minimizer_mapper.hpp"

//#define USE_CALLGRIND

#ifdef USE_CALLGRIND
#include <valgrind/callgrind.h>
#endif

using namespace std;
using namespace vg;
using namespace vg::subcommand;

void help_gaffe(char** argv) {
    cerr
    << "usage: " << argv[0] << " gaffe [options] > output.gam" << endl
    << "Map unpaired reads using minimizers and gapless extension." << endl
    << endl
    << "basic options:" << endl
    << "  -x, --xg-name FILE            use this xg index (required)" << endl
    << "  -H, --gbwt-name FILE          use this GBWT index (required)" << endl
    << "  -m, --minimizer-name FILE     use this minimizer index (required)" << endl
    << "  -s, --snarls FILE             cluster using these snarls (required)" << endl
    << "  -d, --dist-name FILE          cluster using this distance index (required)" << endl
    << "  -c, --hit-cap INT             ignore minimizers with more than this many locations [10]" << endl
    << "input options:" << endl
    << "  -G, --gam-in FILE             read and realign GAM-format reads from FILE (may repeat)" << endl
    << "  -f, --fastq-in FILE           read and align FASTQ-format reads from FILE (may repeat)" << endl
    << "output options:" << endl
    << "  -M, --max-multimaps INT       produce up to INT alignments for each read [1]"
    << "  -N, --sample NAME             add this sample name" << endl
    << "  -R, --read-group NAME         add this read group" << endl
    << "computational parameters:" << endl
    << "  -C, --no-chaining             disable seed chaining and all gapped alignment" << endl
    << "  -X, --xdrop                   use xdrop alignment for tails" << endl
    << "  -t, --threads INT             number of compute threads to use" << endl;
}

int main_gaffe(int argc, char** argv) {

    if (argc == 2) {
        help_gaffe(argv);
        return 1;
    }

    // initialize parameters with their default options
    string xg_name;
    string gbwt_name;
    string minimizer_name;
    string snarls_name;
    string distance_name;
    // How close should two hits be to be in the same cluster?
    size_t distance_limit = 1000;
    size_t hit_cap = 10;
    // Should we try chaining or just give up if we can't find a full length gapless alignment?
    bool do_chaining = true;
    // Whould we use the xdrop aligner for aligning tails?
    bool use_xdrop_for_tails = false;
    // What GAMs should we realign?
    vector<string> gam_filenames;
    // What FASTQs should we align.
    // Note: multiple FASTQs are not interpreted as paired.
    vector<string> fastq_filenames;
    // How many mappings per read can we emit?
    size_t max_multimaps = 1;
    // How many extended clusters should we align, max?
    size_t max_alignments = 48;
    // What sample name if any should we apply?
    string sample_name;
    // What read group if any should we apply?
    string read_group;

    int c;
    optind = 2; // force optind past command positional argument
    while (true) {
        static struct option long_options[] =
        {
            {"help", no_argument, 0, 'h'},
            {"xg-name", required_argument, 0, 'x'},
            {"gbwt-name", required_argument, 0, 'H'},
            {"minimizer-name", required_argument, 0, 'm'},
            {"snarls", required_argument, 0, 's'},
            {"dist-name", required_argument, 0, 'd'},
            {"hit-cap", required_argument, 0, 'c'},
            {"gam-in", required_argument, 0, 'G'},
            {"fastq-in", required_argument, 0, 'f'},
            {"max-multimaps", required_argument, 0, 'M'},
            {"sample", required_argument, 0, 'N'},
            {"read-group", required_argument, 0, 'R'},
            {"no-chaining", no_argument, 0, 'C'},
            {"xdrop", no_argument, 0, 'X'},
            {"threads", required_argument, 0, 't'},
            {0, 0, 0, 0}
        };

        int option_index = 0;
        c = getopt_long (argc, argv, "hx:H:m:s:d:c:G:f:M:CXt:",
                         long_options, &option_index);

        // Detect the end of the options.
        if (c == -1)
            break;

        switch (c)
        {
            case 'x':
                xg_name = optarg;
                if (xg_name.empty()) {
                    cerr << "error:[vg gaffe] Must provide XG file with -x." << endl;
                    exit(1);
                }
                break;

            case 'H':
                gbwt_name = optarg;
                if (gbwt_name.empty()) {
                    cerr << "error:[vg gaffe] Must provide GBWT file with -H." << endl;
                    exit(1);
                }
                break;

            case 'm':
                minimizer_name = optarg;
                if (minimizer_name.empty()) {
                    cerr << "error:[vg gaffe] Must provide minimizer file with -m." << endl;
                    exit(1);
                }
                break;

            case 's':
                snarls_name = optarg;
                if (snarls_name.empty()) {
                    cerr << "error:[vg gaffe] Must provide snarl file with -s." << endl;
                    exit(1);
                }
                break;

            case 'd':
                distance_name = optarg;
                if (distance_name.empty()) {
                    cerr << "error:[vg gaffe] Must provide distance index file with -d." << endl;
                    exit(1);
                }
                break;

            case 'c':
                hit_cap = parse<size_t>(optarg);
                break;

            case 'G':
                gam_filenames.push_back(optarg);
                break;

            case 'f':
                fastq_filenames.push_back(optarg);
                break;

            case 'M':
                max_multimaps = parse<size_t>(optarg);
                break;

            case 'N':
                sample_name = optarg;
                break;

            case 'R':
                read_group = optarg;
                break;

            case 'C':
                do_chaining = false;
                break;

            case 'X':
                use_xdrop_for_tails = true;
                break;

            case 't':
            {
                int num_threads = parse<int>(optarg);
                if (num_threads <= 0) {
                    cerr << "error:[vg gaffe] Thread count (-t) set to " << num_threads << ", must set to a positive integer." << endl;
                    exit(1);
                }
                omp_set_num_threads(num_threads);
            }
                break;

            case 'h':
            case '?':
            default:
                help_gaffe(argv);
                exit(1);
                break;
        }
    }

    if (xg_name.empty()) {
        cerr << "error:[vg gaffe] Mapping requires an XG index (-x)" << endl;
        exit(1);
    }

    if (gbwt_name.empty()) {
        cerr << "error:[vg gaffe] Mapping requires a GBWT index (-H)" << endl;
        exit(1);
    }

    if (minimizer_name.empty()) {
        cerr << "error:[vg gaffe] Mapping requires a minimizer index (-m)" << endl;
        exit(1);
    }

    if (snarls_name.empty()) {
        cerr << "error:[vg gaffe] Mapping requires snarls (-s)" << endl;
        exit(1);
    }

    if (distance_name.empty()) {
        cerr << "error:[vg gaffe] Mapping requires a distance index (-d)" << endl;
        exit(1);
    }

    // create in-memory objects
    unique_ptr<xg::XG> xg_index = vg::io::VPKG::load_one<xg::XG>(xg_name);
    unique_ptr<gbwt::GBWT> gbwt_index = vg::io::VPKG::load_one<gbwt::GBWT>(gbwt_name);
    unique_ptr<MinimizerIndex> minimizer_index = vg::io::VPKG::load_one<MinimizerIndex>(minimizer_name);
    unique_ptr<SnarlManager> snarl_manager = vg::io::VPKG::load_one<SnarlManager>(snarls_name);
    unique_ptr<DistanceIndex> distance_index = vg::io::VPKG::load_one<DistanceIndex>(distance_name);

    // Connect the DistanceIndex to the other things it needs to work.
    distance_index->setGraph(xg_index.get());
    distance_index->setSnarlManager(snarl_manager.get());

    // Set up the mapper
    MinimizerMapper minimizer_mapper(xg_index.get(), gbwt_index.get(), minimizer_index.get(), snarl_manager.get(), distance_index.get());

    minimizer_mapper.max_alignments = max_alignments;
    minimizer_mapper.max_multimaps = max_multimaps;
    minimizer_mapper.hit_cap = hit_cap;
    minimizer_mapper.distance_limit = distance_limit;
    minimizer_mapper.do_chaining = do_chaining;
    minimizer_mapper.use_xdrop_for_tails = use_xdrop_for_tails;
    minimizer_mapper.sample_name = sample_name;
    minimizer_mapper.read_group = read_group;

    // Set up output to an emitter that will handle serialization
    unique_ptr<AlignmentEmitter> alignment_emitter = get_alignment_emitter("-", "GAM", {});

#ifdef USE_CALLGRIND
    // We want to profile the alignment, not the loading.
    CALLGRIND_START_INSTRUMENTATION;
#endif

    // Define how to align and output a read, in a thread.
    auto map_read = [&](Alignment& aln) {
        // Map the read with the MinimizerMapper
        minimizer_mapper.map(aln, *alignment_emitter);
    };

    for (auto& gam_name : gam_filenames) {
        // For every GAM file to remap
        get_input_file(gam_name, [&](istream& in) {
            // Open it and map all the reads in parallel.
            vg::io::for_each_parallel<Alignment>(in, map_read);
        });
    }

    for (auto& fastq_name : fastq_filenames) {
        // For every FASTQ file to map, map all its reads in parallel.
        fastq_unpaired_for_each_parallel(fastq_name, map_read);
    }

    return 0;
}

// Register subcommand
static Subcommand vg_gaffe("gaffe", "Graph Alignment Format Fast Emitter", DEVELOPMENT, main_gaffe);

<commit_msg>Measure reads/second from the outside<commit_after>/**
 * \file gaffe_main.cpp: GFA (Graph Alignment Format) Fast Emitter: a new mapper that will be *extremely* fast once we actually write it
 */

#include <omp.h>
#include <unistd.h>
#include <getopt.h>
#include <iostream>
#include <cassert>
#include <vector>
#include <unordered_set>
#include <chrono>
#include <atomic>

#include "subcommand.hpp"

#include "../seed_clusterer.hpp"
#include "../mapper.hpp"
#include "../annotation.hpp"
#include "../minimizer.hpp"
#include <vg/io/vpkg.hpp>
#include <vg/io/stream.hpp>
#include "../alignment_emitter.hpp"
#include "../gapless_extender.hpp"
#include "../minimizer_mapper.hpp"

//#define USE_CALLGRIND

#ifdef USE_CALLGRIND
#include <valgrind/callgrind.h>
#endif

using namespace std;
using namespace vg;
using namespace vg::subcommand;

void help_gaffe(char** argv) {
    cerr
    << "usage: " << argv[0] << " gaffe [options] > output.gam" << endl
    << "Map unpaired reads using minimizers and gapless extension." << endl
    << endl
    << "basic options:" << endl
    << "  -x, --xg-name FILE            use this xg index (required)" << endl
    << "  -H, --gbwt-name FILE          use this GBWT index (required)" << endl
    << "  -m, --minimizer-name FILE     use this minimizer index (required)" << endl
    << "  -s, --snarls FILE             cluster using these snarls (required)" << endl
    << "  -d, --dist-name FILE          cluster using this distance index (required)" << endl
    << "  -c, --hit-cap INT             ignore minimizers with more than this many locations [10]" << endl
    << "input options:" << endl
    << "  -G, --gam-in FILE             read and realign GAM-format reads from FILE (may repeat)" << endl
    << "  -f, --fastq-in FILE           read and align FASTQ-format reads from FILE (may repeat)" << endl
    << "output options:" << endl
    << "  -M, --max-multimaps INT       produce up to INT alignments for each read [1]"
    << "  -N, --sample NAME             add this sample name" << endl
    << "  -R, --read-group NAME         add this read group" << endl
    << "computational parameters:" << endl
    << "  -C, --no-chaining             disable seed chaining and all gapped alignment" << endl
    << "  -X, --xdrop                   use xdrop alignment for tails" << endl
    << "  -t, --threads INT             number of compute threads to use" << endl;
}

int main_gaffe(int argc, char** argv) {

    if (argc == 2) {
        help_gaffe(argv);
        return 1;
    }

    // initialize parameters with their default options
    string xg_name;
    string gbwt_name;
    string minimizer_name;
    string snarls_name;
    string distance_name;
    // How close should two hits be to be in the same cluster?
    size_t distance_limit = 1000;
    size_t hit_cap = 10;
    // Should we try chaining or just give up if we can't find a full length gapless alignment?
    bool do_chaining = true;
    // Whould we use the xdrop aligner for aligning tails?
    bool use_xdrop_for_tails = false;
    // What GAMs should we realign?
    vector<string> gam_filenames;
    // What FASTQs should we align.
    // Note: multiple FASTQs are not interpreted as paired.
    vector<string> fastq_filenames;
    // How many mappings per read can we emit?
    size_t max_multimaps = 1;
    // How many extended clusters should we align, max?
    size_t max_alignments = 48;
    // What sample name if any should we apply?
    string sample_name;
    // What read group if any should we apply?
    string read_group;

    int c;
    optind = 2; // force optind past command positional argument
    while (true) {
        static struct option long_options[] =
        {
            {"help", no_argument, 0, 'h'},
            {"xg-name", required_argument, 0, 'x'},
            {"gbwt-name", required_argument, 0, 'H'},
            {"minimizer-name", required_argument, 0, 'm'},
            {"snarls", required_argument, 0, 's'},
            {"dist-name", required_argument, 0, 'd'},
            {"hit-cap", required_argument, 0, 'c'},
            {"gam-in", required_argument, 0, 'G'},
            {"fastq-in", required_argument, 0, 'f'},
            {"max-multimaps", required_argument, 0, 'M'},
            {"sample", required_argument, 0, 'N'},
            {"read-group", required_argument, 0, 'R'},
            {"no-chaining", no_argument, 0, 'C'},
            {"xdrop", no_argument, 0, 'X'},
            {"threads", required_argument, 0, 't'},
            {0, 0, 0, 0}
        };

        int option_index = 0;
        c = getopt_long (argc, argv, "hx:H:m:s:d:c:G:f:M:CXt:",
                         long_options, &option_index);

        // Detect the end of the options.
        if (c == -1)
            break;

        switch (c)
        {
            case 'x':
                xg_name = optarg;
                if (xg_name.empty()) {
                    cerr << "error:[vg gaffe] Must provide XG file with -x." << endl;
                    exit(1);
                }
                break;

            case 'H':
                gbwt_name = optarg;
                if (gbwt_name.empty()) {
                    cerr << "error:[vg gaffe] Must provide GBWT file with -H." << endl;
                    exit(1);
                }
                break;

            case 'm':
                minimizer_name = optarg;
                if (minimizer_name.empty()) {
                    cerr << "error:[vg gaffe] Must provide minimizer file with -m." << endl;
                    exit(1);
                }
                break;

            case 's':
                snarls_name = optarg;
                if (snarls_name.empty()) {
                    cerr << "error:[vg gaffe] Must provide snarl file with -s." << endl;
                    exit(1);
                }
                break;

            case 'd':
                distance_name = optarg;
                if (distance_name.empty()) {
                    cerr << "error:[vg gaffe] Must provide distance index file with -d." << endl;
                    exit(1);
                }
                break;

            case 'c':
                hit_cap = parse<size_t>(optarg);
                break;

            case 'G':
                gam_filenames.push_back(optarg);
                break;

            case 'f':
                fastq_filenames.push_back(optarg);
                break;

            case 'M':
                max_multimaps = parse<size_t>(optarg);
                break;

            case 'N':
                sample_name = optarg;
                break;

            case 'R':
                read_group = optarg;
                break;

            case 'C':
                do_chaining = false;
                break;

            case 'X':
                use_xdrop_for_tails = true;
                break;

            case 't':
            {
                int num_threads = parse<int>(optarg);
                if (num_threads <= 0) {
                    cerr << "error:[vg gaffe] Thread count (-t) set to " << num_threads << ", must set to a positive integer." << endl;
                    exit(1);
                }
                omp_set_num_threads(num_threads);
            }
                break;

            case 'h':
            case '?':
            default:
                help_gaffe(argv);
                exit(1);
                break;
        }
    }

    if (xg_name.empty()) {
        cerr << "error:[vg gaffe] Mapping requires an XG index (-x)" << endl;
        exit(1);
    }

    if (gbwt_name.empty()) {
        cerr << "error:[vg gaffe] Mapping requires a GBWT index (-H)" << endl;
        exit(1);
    }

    if (minimizer_name.empty()) {
        cerr << "error:[vg gaffe] Mapping requires a minimizer index (-m)" << endl;
        exit(1);
    }

    if (snarls_name.empty()) {
        cerr << "error:[vg gaffe] Mapping requires snarls (-s)" << endl;
        exit(1);
    }

    if (distance_name.empty()) {
        cerr << "error:[vg gaffe] Mapping requires a distance index (-d)" << endl;
        exit(1);
    }

    // create in-memory objects
    unique_ptr<xg::XG> xg_index = vg::io::VPKG::load_one<xg::XG>(xg_name);
    unique_ptr<gbwt::GBWT> gbwt_index = vg::io::VPKG::load_one<gbwt::GBWT>(gbwt_name);
    unique_ptr<MinimizerIndex> minimizer_index = vg::io::VPKG::load_one<MinimizerIndex>(minimizer_name);
    unique_ptr<SnarlManager> snarl_manager = vg::io::VPKG::load_one<SnarlManager>(snarls_name);
    unique_ptr<DistanceIndex> distance_index = vg::io::VPKG::load_one<DistanceIndex>(distance_name);

    // Connect the DistanceIndex to the other things it needs to work.
    distance_index->setGraph(xg_index.get());
    distance_index->setSnarlManager(snarl_manager.get());

    // Set up the mapper
    MinimizerMapper minimizer_mapper(xg_index.get(), gbwt_index.get(), minimizer_index.get(), snarl_manager.get(), distance_index.get());

    minimizer_mapper.max_alignments = max_alignments;
    minimizer_mapper.max_multimaps = max_multimaps;
    minimizer_mapper.hit_cap = hit_cap;
    minimizer_mapper.distance_limit = distance_limit;
    minimizer_mapper.do_chaining = do_chaining;
    minimizer_mapper.use_xdrop_for_tails = use_xdrop_for_tails;
    minimizer_mapper.sample_name = sample_name;
    minimizer_mapper.read_group = read_group;

    // Set up output to an emitter that will handle serialization
    unique_ptr<AlignmentEmitter> alignment_emitter = get_alignment_emitter("-", "GAM", {});

#ifdef USE_CALLGRIND
    // We want to profile the alignment, not the loading.
    CALLGRIND_START_INSTRUMENTATION;
#endif

    // Define how to align and output a read, in a thread.
    std::atomic<size_t> reads(0);
    auto map_read = [&](Alignment& aln) {
        // Map the read with the MinimizerMapper
        minimizer_mapper.map(aln, *alignment_emitter);
        reads++;
    };

    double start = gbwt::readTimer();

    for (auto& gam_name : gam_filenames) {
        // For every GAM file to remap
        get_input_file(gam_name, [&](istream& in) {
            // Open it and map all the reads in parallel.
            vg::io::for_each_parallel<Alignment>(in, map_read);
        });
    }

    for (auto& fastq_name : fastq_filenames) {
        // For every FASTQ file to map, map all its reads in parallel.
        fastq_unpaired_for_each_parallel(fastq_name, map_read);
    }

    double seconds = gbwt::readTimer() - start;
    size_t threads = omp_get_max_threads();
    double reads_second = reads / (seconds * threads);
    // FIXME show_progress
    std::cerr << reads << " reads in " << seconds << " seconds using " << threads << " threads (" << reads_second << " reads / second)" << std::endl;

    return 0;
}

// Register subcommand
static Subcommand vg_gaffe("gaffe", "Graph Alignment Format Fast Emitter", DEVELOPMENT, main_gaffe);

<|endoftext|>


<commit_before>#ifndef RENDERTARGET_HPP
#define RENDERTARGET_HPP
#include "../tools.hpp"
#include "Texture.hpp"

class RenderTarget {
	public:
		enum Attachment {
			DEPTH = GL_DEPTH_ATTACHMENT,
			STENCIL = GL_STENCIL_ATTACHMENT,
			DEPTH_STENCIL = GL_DEPTH_STENCIL_ATTACHMENT,
			COLOR0 = GL_COLOR_ATTACHMENT0,
			COLOR1 = GL_COLOR_ATTACHMENT1,
			COLOR2 = GL_COLOR_ATTACHMENT2,
			COLOR3 = GL_COLOR_ATTACHMENT3,
			COLOR4 = GL_COLOR_ATTACHMENT4,
			COLOR5 = GL_COLOR_ATTACHMENT5,
			COLOR6 = GL_COLOR_ATTACHMENT6,
			COLOR7 = GL_COLOR_ATTACHMENT7,
			COLOR8 = GL_COLOR_ATTACHMENT8,
			COLOR9 = GL_COLOR_ATTACHMENT9,
			COLOR10 = GL_COLOR_ATTACHMENT10,
			COLOR11 = GL_COLOR_ATTACHMENT11,
			COLOR12 = GL_COLOR_ATTACHMENT12,
			COLOR13 = GL_COLOR_ATTACHMENT13,
			COLOR14 = GL_COLOR_ATTACHMENT14,
			COLOR15 = GL_COLOR_ATTACHMENT15
		};

		RenderTarget(int width, int height);
		~RenderTarget();

		static void bind(RenderTarget* renderTarget);

		void setSize(int width, int height);
		void addRenderBuffer(Attachment target, Texture::Format format);
		void addTexture(Attachment target, Texture::Format format);

		Texture* getTextureForAttachment(Attachment attachment);

		void build();
		void destroy();

	private:

		class RenderBuffer {
			public:
				RenderBuffer(int width, int height, Texture::Format format);
				~RenderBuffer();

				void bind() const;
				GLuint getHandle() const;
			private:
				GLuint handle;
		};

		class RenderTargetEntry {
			public:
				enum Type {
					RenderBufferEntry,
					TextureEntry
				};

				RenderTargetEntry(Type type, RenderTarget::Attachment attachment, Texture::Format format) :
					type(type), attachment(attachment), format(format), texture(nullptr), renderBuffer(nullptr) {}

				Type type;
				RenderTarget::Attachment attachment;
				Texture::Format format;

				Texture* texture;
				RenderBuffer* renderBuffer;
		};

		static GLuint current;

		GLuint handle; // 0 if not built
		int width, height;
		std::map<Attachment, RenderTargetEntry> entries;
};

#endif // RENDERTARGET_HPP
<commit_msg>Add getWidth/getHeight.<commit_after>#ifndef RENDERTARGET_HPP
#define RENDERTARGET_HPP
#include "../tools.hpp"
#include "Texture.hpp"

class RenderTarget {
	public:
		enum Attachment {
			DEPTH = GL_DEPTH_ATTACHMENT,
			STENCIL = GL_STENCIL_ATTACHMENT,
			DEPTH_STENCIL = GL_DEPTH_STENCIL_ATTACHMENT,
			COLOR0 = GL_COLOR_ATTACHMENT0,
			COLOR1 = GL_COLOR_ATTACHMENT1,
			COLOR2 = GL_COLOR_ATTACHMENT2,
			COLOR3 = GL_COLOR_ATTACHMENT3,
			COLOR4 = GL_COLOR_ATTACHMENT4,
			COLOR5 = GL_COLOR_ATTACHMENT5,
			COLOR6 = GL_COLOR_ATTACHMENT6,
			COLOR7 = GL_COLOR_ATTACHMENT7,
			COLOR8 = GL_COLOR_ATTACHMENT8,
			COLOR9 = GL_COLOR_ATTACHMENT9,
			COLOR10 = GL_COLOR_ATTACHMENT10,
			COLOR11 = GL_COLOR_ATTACHMENT11,
			COLOR12 = GL_COLOR_ATTACHMENT12,
			COLOR13 = GL_COLOR_ATTACHMENT13,
			COLOR14 = GL_COLOR_ATTACHMENT14,
			COLOR15 = GL_COLOR_ATTACHMENT15
		};

		RenderTarget(int width, int height);
		~RenderTarget();

		static void bind(RenderTarget* renderTarget);

		int getWidth() const { return width; }
		int getHeight() const { return height; }
		void setSize(int width, int height);
		void addRenderBuffer(Attachment target, Texture::Format format);
		void addTexture(Attachment target, Texture::Format format);

		Texture* getTextureForAttachment(Attachment attachment);

		void build();
		void destroy();

	private:

		class RenderBuffer {
			public:
				RenderBuffer(int width, int height, Texture::Format format);
				~RenderBuffer();

				void bind() const;
				GLuint getHandle() const;
			private:
				GLuint handle;
		};

		class RenderTargetEntry {
			public:
				enum Type {
					RenderBufferEntry,
					TextureEntry
				};

				RenderTargetEntry(Type type, RenderTarget::Attachment attachment, Texture::Format format) :
					type(type), attachment(attachment), format(format), texture(nullptr), renderBuffer(nullptr) {}

				Type type;
				RenderTarget::Attachment attachment;
				Texture::Format format;

				Texture* texture;
				RenderBuffer* renderBuffer;
		};

		static GLuint current;

		GLuint handle; // 0 if not built
		int width, height;
		std::map<Attachment, RenderTargetEntry> entries;
};

#endif // RENDERTARGET_HPP
<|endoftext|>


<commit_before>#define THEWIZARDPLUSPLUS_WIZARD_PARSER_PARSER_MACROSES

#include "vendor/json.hpp"
#include "vendor/docopt/docopt.hpp"
#include "vendor/fmt/format.hpp"
#include <thewizardplusplus/wizard_parser/lexer/lexeme.hpp>
#include <thewizardplusplus/wizard_parser/lexer/token.hpp>
#include <thewizardplusplus/wizard_parser/parser/ast_node.hpp>
#include <thewizardplusplus/wizard_parser/parser/rule_parser.hpp>
#include <thewizardplusplus/wizard_parser/parser/dummy_parser.hpp>
#include <thewizardplusplus/wizard_parser/parser/typing_parser.hpp>
#include <thewizardplusplus/wizard_parser/parser/match_parser.hpp>
#include <thewizardplusplus/wizard_parser/parser/alternation_parser.hpp>
#include <thewizardplusplus/wizard_parser/parser/exception_parser.hpp>
#include <thewizardplusplus/wizard_parser/parser/concatenation_parser.hpp>
#include <thewizardplusplus/wizard_parser/parser/lookahead_parser.hpp>
#include <thewizardplusplus/wizard_parser/parser/repetition_parser.hpp>
#include <thewizardplusplus/wizard_parser/parser/eoi_parser.hpp>
#include <thewizardplusplus/wizard_parser/lexer/tokenize.hpp>
#include <thewizardplusplus/wizard_parser/parser/parse.hpp>
#include <thewizardplusplus/wizard_parser/exceptions/unexpected_entity_exception.hpp>
#include <regex>
#include <iostream>
#include <string>
#include <iterator>
#include <algorithm>
#include <cstdlib>
#include <exception>

using namespace thewizardplusplus::wizard_parser::lexer;
using namespace thewizardplusplus::wizard_parser::parser;
using namespace thewizardplusplus::wizard_parser::parser::operators;
using namespace thewizardplusplus::wizard_parser::exceptions;

const auto usage =
R"(Usage:
  ./example -h | --help
  ./example [-t | --tokens] [--] <expression>
  ./example [-t | --tokens] (-s | --stdin)

Options:
  -h, --help    - show this message;
  -t, --tokens  - show a token list instead an AST;
  -s, --stdin   - read an expression from stdin.)";
const auto lexemes = lexeme_group{
	{std::regex{"=="}, "equal"},
	{std::regex{"/="}, "not_equal"},
	{std::regex{"<="}, "less_or_equal"},
	{std::regex{"<"}, "less"},
	{std::regex{">="}, "great_or_equal"},
	{std::regex{">"}, "great"},
	{std::regex{R"(\+)"}, "plus"},
	{std::regex{"-"}, "minus"},
	{std::regex{R"(\*)"}, "star"},
	{std::regex{"/"}, "slash"},
	{std::regex{"%"}, "percent"},
	{std::regex{R"(\()"}, "opening_parenthesis"},
	{std::regex{R"(\))"}, "closing_parenthesis"},
	{std::regex{","}, "comma"},
	{std::regex{R"(\d+(?:\.\d+)?(?:e-?\d+)?)"}, "number"},
	{std::regex{R"([A-Za-z_]\w*)"}, "base_identifier"},
	{std::regex{R"(\s+)"}, "whitespace"}
};

namespace thewizardplusplus::wizard_parser {

namespace lexer {

void to_json(nlohmann::json& json, const token& some_token) {
	json = {
		{ "type", some_token.type },
		{ "value", some_token.value },
		{ "offset", some_token.offset }
	};
}

}

namespace parser {

void to_json(nlohmann::json& json, const ast_node& ast) {
	json = { { "type", ast.type } };
	if (!ast.value.empty()) {
		json["value"] = ast.value;
	}
	if (!ast.children.empty()) {
		json["children"] = ast.children;
	}
	if (ast.offset) {
		json["offset"] = *ast.offset;
	}
}

}

}

void stop(const int& code, std::ostream& stream, const std::string& message) {
	stream << fmt::format("{:s}\n", message);
	std::exit(code);
}

rule_parser::pointer make_parser() {
	const auto expression_dummy = dummy();
	RULE(number) = "number"_t;
	RULE(key_words) = "not"_v | "and"_v | "or"_v;
	RULE(identifier) = "base_identifier"_t - key_words;
	RULE(function_call) = identifier >> &"("_v >>
		-(expression_dummy >> *(&","_v >> expression_dummy))
	>> &")"_v;
	RULE(atom) = number
		| function_call
		| identifier
		| (&"("_v >> expression_dummy >> &")"_v);
	RULE(unary) = *("-"_v | "not"_v) >> atom;
	RULE(product) = unary >> *(("*"_v | "/"_v | "%"_v) >> unary);
	RULE(sum) = product >> *(("+"_v | "-"_v) >> product);
	RULE(comparison) = sum >> *(("<"_v | "<="_v | ">"_v | ">="_v) >> sum);
	RULE(equality) = comparison >> *(("=="_v | "/="_v) >> comparison);
	RULE(conjunction) = equality >> *(&"and"_v >> equality);
	RULE(disjunction) = conjunction >> *(&"or"_v >> conjunction);
	expression_dummy->set_parser(disjunction);

	RULE(expression) = disjunction >> eoi();
	return expression;
}

int main(int argc, char* argv[]) try {
	auto cleaned_tokens = token_group{};
	const auto options = docopt::docopt(usage, {argv+1, argv+argc}, true);
	const auto code = options.at("--stdin").asBool()
		? std::string{std::istreambuf_iterator<char>{std::cin}, {}}
		: options.at("<expression>").asString();
	const auto tokens = tokenize(lexemes, code);
	std::copy_if(
		std::cbegin(tokens),
		std::cend(tokens),
		std::back_inserter(cleaned_tokens),
		[] (const auto& token) { return token.type != "whitespace"; }
	);
	if (options.at("--tokens").asBool()) {
		stop(EXIT_SUCCESS, std::cout, nlohmann::json(cleaned_tokens).dump());
	}

	const auto parser = make_parser();
	try {
		const auto ast = parse(parser, cleaned_tokens);
		stop(EXIT_SUCCESS, std::cout, nlohmann::json(ast).dump());
	} catch (const unexpected_entity_exception<entity_type::eoi>& exception) {
		throw decltype(exception){code.size()};
	}
} catch (const std::exception& exception) {
	stop(EXIT_FAILURE, std::cerr, fmt::format("error: {:s}", exception.what()));
}
<commit_msg>Add an offset to a node: replace nodes offsets equal to the `parser::integral_infinity` constant to a code size in the example<commit_after>#define THEWIZARDPLUSPLUS_WIZARD_PARSER_PARSER_MACROSES

#include "vendor/json.hpp"
#include "vendor/docopt/docopt.hpp"
#include "vendor/fmt/format.hpp"
#include <thewizardplusplus/wizard_parser/lexer/lexeme.hpp>
#include <thewizardplusplus/wizard_parser/lexer/token.hpp>
#include <thewizardplusplus/wizard_parser/parser/ast_node.hpp>
#include <thewizardplusplus/wizard_parser/parser/rule_parser.hpp>
#include <thewizardplusplus/wizard_parser/parser/dummy_parser.hpp>
#include <thewizardplusplus/wizard_parser/parser/typing_parser.hpp>
#include <thewizardplusplus/wizard_parser/parser/match_parser.hpp>
#include <thewizardplusplus/wizard_parser/parser/alternation_parser.hpp>
#include <thewizardplusplus/wizard_parser/parser/exception_parser.hpp>
#include <thewizardplusplus/wizard_parser/parser/concatenation_parser.hpp>
#include <thewizardplusplus/wizard_parser/parser/lookahead_parser.hpp>
#include <thewizardplusplus/wizard_parser/parser/repetition_parser.hpp>
#include <thewizardplusplus/wizard_parser/parser/eoi_parser.hpp>
#include <thewizardplusplus/wizard_parser/lexer/tokenize.hpp>
#include <thewizardplusplus/wizard_parser/parser/parse.hpp>
#include <thewizardplusplus/wizard_parser/utilities/utilities.hpp>
#include <thewizardplusplus/wizard_parser/exceptions/unexpected_entity_exception.hpp>
#include <regex>
#include <iostream>
#include <string>
#include <functional>
#include <algorithm>
#include <iterator>
#include <cstdlib>
#include <exception>

using namespace thewizardplusplus::wizard_parser::lexer;
using namespace thewizardplusplus::wizard_parser::parser;
using namespace thewizardplusplus::wizard_parser::parser::operators;
using namespace thewizardplusplus::wizard_parser::utilities;
using namespace thewizardplusplus::wizard_parser::exceptions;

const auto usage =
R"(Usage:
  ./example -h | --help
  ./example [-t | --tokens] [--] <expression>
  ./example [-t | --tokens] (-s | --stdin)

Options:
  -h, --help    - show this message;
  -t, --tokens  - show a token list instead an AST;
  -s, --stdin   - read an expression from stdin.)";
const auto lexemes = lexeme_group{
	{std::regex{"=="}, "equal"},
	{std::regex{"/="}, "not_equal"},
	{std::regex{"<="}, "less_or_equal"},
	{std::regex{"<"}, "less"},
	{std::regex{">="}, "great_or_equal"},
	{std::regex{">"}, "great"},
	{std::regex{R"(\+)"}, "plus"},
	{std::regex{"-"}, "minus"},
	{std::regex{R"(\*)"}, "star"},
	{std::regex{"/"}, "slash"},
	{std::regex{"%"}, "percent"},
	{std::regex{R"(\()"}, "opening_parenthesis"},
	{std::regex{R"(\))"}, "closing_parenthesis"},
	{std::regex{","}, "comma"},
	{std::regex{R"(\d+(?:\.\d+)?(?:e-?\d+)?)"}, "number"},
	{std::regex{R"([A-Za-z_]\w*)"}, "base_identifier"},
	{std::regex{R"(\s+)"}, "whitespace"}
};

namespace thewizardplusplus::wizard_parser {

namespace lexer {

void to_json(nlohmann::json& json, const token& some_token) {
	json = {
		{ "type", some_token.type },
		{ "value", some_token.value },
		{ "offset", some_token.offset }
	};
}

}

namespace parser {

void to_json(nlohmann::json& json, const ast_node& ast) {
	json = { { "type", ast.type } };
	if (!ast.value.empty()) {
		json["value"] = ast.value;
	}
	if (!ast.children.empty()) {
		json["children"] = ast.children;
	}
	if (ast.offset) {
		json["offset"] = *ast.offset;
	}
}

}

}

void stop(const int& code, std::ostream& stream, const std::string& message) {
	stream << fmt::format("{:s}\n", message);
	std::exit(code);
}

rule_parser::pointer make_parser() {
	const auto expression_dummy = dummy();
	RULE(number) = "number"_t;
	RULE(key_words) = "not"_v | "and"_v | "or"_v;
	RULE(identifier) = "base_identifier"_t - key_words;
	RULE(function_call) = identifier >> &"("_v >>
		-(expression_dummy >> *(&","_v >> expression_dummy))
	>> &")"_v;
	RULE(atom) = number
		| function_call
		| identifier
		| (&"("_v >> expression_dummy >> &")"_v);
	RULE(unary) = *("-"_v | "not"_v) >> atom;
	RULE(product) = unary >> *(("*"_v | "/"_v | "%"_v) >> unary);
	RULE(sum) = product >> *(("+"_v | "-"_v) >> product);
	RULE(comparison) = sum >> *(("<"_v | "<="_v | ">"_v | ">="_v) >> sum);
	RULE(equality) = comparison >> *(("=="_v | "/="_v) >> comparison);
	RULE(conjunction) = equality >> *(&"and"_v >> equality);
	RULE(disjunction) = conjunction >> *(&"or"_v >> conjunction);
	expression_dummy->set_parser(disjunction);

	RULE(expression) = disjunction >> eoi();
	return expression;
}

ast_node walk_ast(
	const ast_node& ast,
	const std::function<ast_node(const ast_node&)>& handler
) {
	const auto new_ast = handler(ast);
	auto new_children = ast_node_group{};
	std::transform(
		std::cbegin(new_ast.children),
		std::cend(new_ast.children),
		std::back_inserter(new_children),
		[&] (const auto& ast) { return walk_ast(ast, handler); }
	);

	return {new_ast.type, new_ast.value, new_children, new_ast.offset};
}

int main(int argc, char* argv[]) try {
	auto cleaned_tokens = token_group{};
	const auto options = docopt::docopt(usage, {argv+1, argv+argc}, true);
	const auto code = options.at("--stdin").asBool()
		? std::string{std::istreambuf_iterator<char>{std::cin}, {}}
		: options.at("<expression>").asString();
	const auto tokens = tokenize(lexemes, code);
	std::copy_if(
		std::cbegin(tokens),
		std::cend(tokens),
		std::back_inserter(cleaned_tokens),
		[] (const auto& token) { return token.type != "whitespace"; }
	);
	if (options.at("--tokens").asBool()) {
		stop(EXIT_SUCCESS, std::cout, nlohmann::json(cleaned_tokens).dump());
	}

	const auto parser = make_parser();
	try {
		const auto ast = parse(parser, cleaned_tokens);
		const auto transformed_ast = walk_ast(ast, [&] (const auto& ast) {
			const auto offset = ast.offset && *ast.offset == integral_infinity
				? code.size()
				: ast.offset;
			return ast_node{ast.type, ast.value, ast.children, offset};
		});
		stop(EXIT_SUCCESS, std::cout, nlohmann::json(transformed_ast).dump());
	} catch (const unexpected_entity_exception<entity_type::eoi>& exception) {
		throw decltype(exception){code.size()};
	}
} catch (const std::exception& exception) {
	stop(EXIT_FAILURE, std::cerr, fmt::format("error: {:s}", exception.what()));
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: txtatr.hxx,v $
 *
 *  $Revision: 1.1.1.1 $
 *
 *  last change: $Author: hr $ $Date: 2000-09-18 17:14:29 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef _TXTATR_HXX
#define _TXTATR_HXX

#ifndef _SV_GEN_HXX
#include <tools/gen.hxx>
#endif
#ifndef _TOOLS_COLOR_HXX
#include <tools/color.hxx>
#endif
#ifndef _LANG_HXX
#include <tools/lang.hxx>
#endif
#ifndef _SV_FONTTYPE_HXX //autogen
#include <vcl/fonttype.hxx>
#endif
#ifndef _SVX_SVXENUM_HXX //autogen
#include <svx/svxenum.hxx>
#endif

#ifndef _TXATBASE_HXX
#include <txatbase.hxx>     // SwTxtAttr/SwTxtAttrEnd
#endif

class SwTxtNode;    // fuer SwTxtFld
class SvxFont;
class SwCharSetCol;

// ATT_FONT ***********************************************************

class SwTxtFont: public SwTxtAttrEnd
{
    // Hier werden die alten Werte aus dem Font bei ChgFnt() gemerkt.
    FontFamily ePrevFamily;
    FontPitch ePrevPitch;
    CharSet ePrevCharSet;
    String aPrevName;
    String aPrevStyleName;
public:
    SwTxtFont( const SvxFontItem& rAttr, xub_StrLen nStart, xub_StrLen nEnd );
    ~SwTxtFont( );

    virtual void ChgFnt(SwFont *);
    virtual void RstFnt(SwFont *);
    virtual void ChgTxtAttr( SwTxtAttr & );
    virtual void RstTxtAttr( SwTxtAttr & );
};

// ATT_POSTURE ***********************************************************

class SwTxtPosture : public SwTxtAttrEnd
{
    FontItalic ePrevPosture;
public:
    SwTxtPosture( const SvxPostureItem& rAttr, xub_StrLen nStart, xub_StrLen nEnd );

    virtual void ChgFnt(SwFont *);
    virtual void RstFnt(SwFont *);
    virtual void ChgTxtAttr( SwTxtAttr & );
    virtual void RstTxtAttr( SwTxtAttr & );
};

// ATT_WEIGHT ************************************************************

class SwTxtWeight : public SwTxtAttrEnd
{
    // Hier merkt es sich das SV-Attribut Weight aus dem Font.
    FontWeight ePrevWeight;
public:
    SwTxtWeight( const SvxWeightItem& rAttr, xub_StrLen nStart, xub_StrLen nEnd );

    virtual void ChgFnt(SwFont *);
    virtual void RstFnt(SwFont *);
    virtual void ChgTxtAttr( SwTxtAttr & );
    virtual void RstTxtAttr( SwTxtAttr & );
};

// ATT_SHADOWED **********************************************************

class SwTxtShadowed : public SwTxtAttrEnd
{
    BOOL bPrevShadow;
public:
    SwTxtShadowed( const SvxShadowedItem& rAttr, xub_StrLen nStart, xub_StrLen nEnd );

    virtual void ChgFnt(SwFont *);
    virtual void RstFnt(SwFont *);
    virtual void ChgTxtAttr( SwTxtAttr & );
    virtual void RstTxtAttr( SwTxtAttr & );
};

// ATT_AUTOKERN **********************************************************

class SwTxtAutoKern : public SwTxtAttrEnd
{
    BOOL bPrevAutoKern;
public:
    SwTxtAutoKern( const SvxAutoKernItem& rAttr, xub_StrLen nStart, xub_StrLen nEnd );

    virtual void ChgFnt(SwFont *);
    virtual void RstFnt(SwFont *);
};

// ATT_WORDLINEMODE **********************************************************

class SwTxtWordLineMode : public SwTxtAttrEnd
{
    BOOL bPrevWordLineMode;
public:
    SwTxtWordLineMode( const SvxWordLineModeItem& rAttr, xub_StrLen nStart, xub_StrLen nEnd );

    virtual void ChgFnt(SwFont *);
    virtual void RstFnt(SwFont *);
    virtual void ChgTxtAttr( SwTxtAttr & );
    virtual void RstTxtAttr( SwTxtAttr & );
};

// ATT_CONTOUR ***********************************************************

class SwTxtContour : public SwTxtAttrEnd
{
    BOOL bPrevContour;
public:
    SwTxtContour( const SvxContourItem& rAttr, xub_StrLen nStart, xub_StrLen nEnd );

    virtual void ChgFnt(SwFont *);
    virtual void RstFnt(SwFont *);
    virtual void ChgTxtAttr( SwTxtAttr & );
    virtual void RstTxtAttr( SwTxtAttr & );
};

// ATT_CROSSEDOUT ********************************************************

class SwTxtCrossedOut : public SwTxtAttrEnd
{
    FontStrikeout ePrevCrossedOut;
public:
    SwTxtCrossedOut( const SvxCrossedOutItem& rAttr, xub_StrLen nStart, xub_StrLen nEnd );

    virtual void ChgFnt(SwFont *);
    virtual void RstFnt(SwFont *);
    virtual void ChgTxtAttr( SwTxtAttr & );
    virtual void RstTxtAttr( SwTxtAttr & );
};

// ATT_UNDERLINE *********************************************************

class SwTxtUnderline : public SwTxtAttrEnd
{
    FontUnderline ePrevUnderline;
public:
    SwTxtUnderline( const SvxUnderlineItem& rAttr, xub_StrLen nStart, xub_StrLen nEnd );

    virtual void ChgFnt(SwFont *);
    virtual void RstFnt(SwFont *);
    virtual void ChgTxtAttr( SwTxtAttr & );
    virtual void RstTxtAttr( SwTxtAttr & );
};

// ATT_SIZE **************************************************************

class SwTxtSize : public SwTxtAttrEnd
{
    Size aPrevSize;
public:
    SwTxtSize( const SvxFontHeightItem& rAttr, xub_StrLen nStart, xub_StrLen nEnd );

    virtual void ChgFnt(SwFont *);
    virtual void RstFnt(SwFont *);
    virtual void ChgTxtAttr( SwTxtAttr & );
    virtual void RstTxtAttr( SwTxtAttr & );
};

// ATT_COLOR *************************************************************

class SwTxtColor : public SwTxtAttrEnd
{
    friend class SwTxtCharSetColor;
    Color aPrevColor;
public:
    SwTxtColor( const SvxColorItem& rAttr, xub_StrLen nStart, xub_StrLen nEnd );

    virtual void ChgFnt(SwFont *);
    virtual void RstFnt(SwFont *);
    virtual void ChgTxtAttr( SwTxtAttr & );
    virtual void RstTxtAttr( SwTxtAttr & );
};

// ATT_CHARSETCOLOR ******************************************************

class SwTxtCharSetColor : public SwTxtAttrEnd
{
    SwCharSetCol *pPrevCharSetCol;
public:
    SwTxtCharSetColor( const SvxCharSetColorItem& rAttr, xub_StrLen nStart, xub_StrLen nEnd );
    ~SwTxtCharSetColor();
    virtual void ChgFnt(SwFont *);
    virtual void RstFnt(SwFont *);
    virtual void ChgTxtAttr( SwTxtAttr & );
    virtual void RstTxtAttr( SwTxtAttr & );
};

// ATT_CHARFMT *********************************************

class SwTxtCharFmt : public SwTxtAttrEnd
{
    SvxFont* pPrevFont;
    const void* pFontNo;
    SwTxtNode* pMyTxtNd;
    Color* pPrevColor;
    USHORT nFntIndex;
    BOOL bPrevNoHyph    : 1;
    BOOL bPrevBlink     : 1;
    BOOL bPrevURL       : 1;
    BOOL bColor         : 1;

public:
    SwTxtCharFmt( const SwFmtCharFmt& rAttr, xub_StrLen nStart, xub_StrLen nEnd );
    ~SwTxtCharFmt( );

    virtual void ChgFnt(SwFont *);
    virtual void RstFnt(SwFont *);

    // werden vom SwFmtCharFmt hierher weitergeleitet
    virtual void Modify( SfxPoolItem*, SfxPoolItem* );    // SwClient
    virtual BOOL GetInfo( SfxPoolItem& rInfo ) const;

    // erfrage und setze den TxtNode Pointer
    inline const SwTxtNode& GetTxtNode() const;
    void ChgTxtNode( const SwTxtNode* pNew ) { pMyTxtNd = (SwTxtNode*)pNew; }

};

// ATT_KERNING ***********************************************************

class SwTxtKerning : public SwTxtAttrEnd
{
    short nPrevKern;
public:
    SwTxtKerning( const SvxKerningItem& rAttr, xub_StrLen nStart, xub_StrLen nEnd );

    virtual void ChgFnt(SwFont *);
    virtual void RstFnt(SwFont *);
    virtual void ChgTxtAttr( SwTxtAttr & );
    virtual void RstTxtAttr( SwTxtAttr & );
};

// ATT_CASEMAP ***********************************************************

class SwTxtCaseMap : public SwTxtAttrEnd
{
    SvxCaseMap ePrevCaseMap;
public:
    SwTxtCaseMap( const SvxCaseMapItem& rAttr, xub_StrLen nStart, xub_StrLen nEnd );

    virtual void ChgFnt(SwFont *);
    virtual void RstFnt(SwFont *);
    virtual void ChgTxtAttr( SwTxtAttr & );
    virtual void RstTxtAttr( SwTxtAttr & );
};

// ATT_LANGUAGE **********************************************************

class SwTxtLanguage : public SwTxtAttrEnd
{
    LanguageType ePrevLang;
public:
    SwTxtLanguage( const SvxLanguageItem& rAttr, xub_StrLen nStart, xub_StrLen nEnd );

    virtual void ChgFnt(SwFont *);
    virtual void RstFnt(SwFont *);
};

// ATT_ESCAPEMENT ********************************************************

class SwTxtEscapement : public SwTxtAttrEnd
{
    short   nPrevEsc;
    BYTE    nPrevPropr;

public:
    SwTxtEscapement( const SvxEscapementItem& rAttr, xub_StrLen nStart, xub_StrLen nEnd );

    virtual void ChgFnt(SwFont *);
    virtual void RstFnt(SwFont *);
    virtual void ChgTxtAttr( SwTxtAttr & );
    virtual void RstTxtAttr( SwTxtAttr & );
};

// ATT_BLINK ***********************

class SwTxtBlink : public SwTxtAttrEnd
{
    BOOL bPrev;
public:
    SwTxtBlink( const SvxBlinkItem& rAttr,
                        xub_StrLen nStart, xub_StrLen nEnd );

    virtual void ChgFnt(SwFont *);
    virtual void RstFnt(SwFont *);
    virtual void ChgTxtAttr( SwTxtAttr & );
    virtual void RstTxtAttr( SwTxtAttr & );
};

// ATT_BACKGROUND ***********************

class SwTxtBackground : public SwTxtAttrEnd
{
    Color *pPrevColor;
public:
    SwTxtBackground( const SvxBrushItem& rAttr,
                        xub_StrLen nStart, xub_StrLen nEnd );
    ~SwTxtBackground();
    virtual void ChgFnt(SwFont *);
    virtual void RstFnt(SwFont *);
    virtual void ChgTxtAttr( SwTxtAttr & );
    virtual void RstTxtAttr( SwTxtAttr & );
};

// ATT_NOHYPHENHERE **************************

class SwTxtNoHyphenHere : public SwTxtAttrEnd
{
    BOOL bPrev;
public:
    SwTxtNoHyphenHere( const SvxNoHyphenItem& rAttr,
                        xub_StrLen nStart, xub_StrLen nEnd );

    virtual void ChgFnt(SwFont *);
    virtual void RstFnt(SwFont *);
};

// ATT_HARDBLANK ******************************

class SwTxtHardBlank : public SwTxtAttr
{
    sal_Unicode cChar;
public:
    SwTxtHardBlank( const SwFmtHardBlank& rAttr, xub_StrLen nStart );
    inline sal_Unicode GetChar() const  { return cChar; }
};

// ATT_XNLCONTAINERITEM ******************************

class SwTxtXMLAttrContainer : public SwTxtAttrEnd
{
public:
    SwTxtXMLAttrContainer( const SvXMLAttrContainerItem& rAttr,
                        xub_StrLen nStart, xub_StrLen nEnd );
};

// --------------- Inline Implementierungen ------------------------

inline const SwTxtNode& SwTxtCharFmt::GetTxtNode() const
{
    ASSERT( pMyTxtNd, "SwTxtCharFmt:: wo ist mein TextNode?" );
    return *pMyTxtNd;
}

#endif
<commit_msg> Textattributs for Latin, CJK and CTL<commit_after>/*************************************************************************
 *
 *  $RCSfile: txtatr.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: ama $ $Date: 2000-09-25 12:00:00 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
#ifndef _TXTATR_HXX
#define _TXTATR_HXX

#ifndef _SV_GEN_HXX
#include <tools/gen.hxx>
#endif
#ifndef _TOOLS_COLOR_HXX
#include <tools/color.hxx>
#endif
#ifndef _LANG_HXX
#include <tools/lang.hxx>
#endif
#ifndef _SV_FONTTYPE_HXX //autogen
#include <vcl/fonttype.hxx>
#endif
#ifndef _SVX_SVXENUM_HXX //autogen
#include <svx/svxenum.hxx>
#endif

#ifndef _TXATBASE_HXX
#include <txatbase.hxx>     // SwTxtAttr/SwTxtAttrEnd
#endif

class SwTxtNode;    // fuer SwTxtFld
class SvxFont;
class SwCharSetCol;
class SwImplPrev;

// ATT_FONT ***********************************************************

class SwTxtFont: public SwTxtAttrEnd
{
    // Hier werden die alten Werte aus dem Font bei ChgFnt() gemerkt.
    String aPrevName;
    String aPrevStyleName;
    FontFamily ePrevFamily;
    FontPitch ePrevPitch;
    CharSet ePrevCharSet;
    BYTE nScript;
public:
    SwTxtFont( const SvxFontItem& rAttr, xub_StrLen nStart, xub_StrLen nEnd,
               const BYTE nScrpt );
    ~SwTxtFont( );

    virtual void ChgFnt(SwFont *);
    virtual void RstFnt(SwFont *);
    virtual void ChgTxtAttr( SwTxtAttr & );
    virtual void RstTxtAttr( SwTxtAttr & );
};

// ATT_POSTURE ***********************************************************

class SwTxtPosture : public SwTxtAttrEnd
{
    FontItalic ePrevPosture;
    BYTE nScript;
public:
    SwTxtPosture( const SvxPostureItem& rAttr, xub_StrLen nStart,
        xub_StrLen nEnd, const BYTE nScrpt );

    virtual void ChgFnt(SwFont *);
    virtual void RstFnt(SwFont *);
    virtual void ChgTxtAttr( SwTxtAttr & );
    virtual void RstTxtAttr( SwTxtAttr & );
};

// ATT_WEIGHT ************************************************************

class SwTxtWeight : public SwTxtAttrEnd
{
    // Hier merkt es sich das SV-Attribut Weight aus dem Font.
    FontWeight ePrevWeight;
    BYTE nScript;
public:
    SwTxtWeight( const SvxWeightItem& rAttr, xub_StrLen nStart, xub_StrLen nEnd,
        const BYTE nScrpt );

    virtual void ChgFnt(SwFont *);
    virtual void RstFnt(SwFont *);
    virtual void ChgTxtAttr( SwTxtAttr & );
    virtual void RstTxtAttr( SwTxtAttr & );
};

// ATT_SHADOWED **********************************************************

class SwTxtShadowed : public SwTxtAttrEnd
{
    BOOL bPrevShadow;
public:
    SwTxtShadowed( const SvxShadowedItem& rAttr, xub_StrLen nStart, xub_StrLen nEnd );

    virtual void ChgFnt(SwFont *);
    virtual void RstFnt(SwFont *);
    virtual void ChgTxtAttr( SwTxtAttr & );
    virtual void RstTxtAttr( SwTxtAttr & );
};

// ATT_AUTOKERN **********************************************************

class SwTxtAutoKern : public SwTxtAttrEnd
{
    BOOL bPrevAutoKern;
public:
    SwTxtAutoKern( const SvxAutoKernItem& rAttr, xub_StrLen nStart, xub_StrLen nEnd );

    virtual void ChgFnt(SwFont *);
    virtual void RstFnt(SwFont *);
};

// ATT_WORDLINEMODE **********************************************************

class SwTxtWordLineMode : public SwTxtAttrEnd
{
    BOOL bPrevWordLineMode;
public:
    SwTxtWordLineMode( const SvxWordLineModeItem& rAttr, xub_StrLen nStart, xub_StrLen nEnd );

    virtual void ChgFnt(SwFont *);
    virtual void RstFnt(SwFont *);
    virtual void ChgTxtAttr( SwTxtAttr & );
    virtual void RstTxtAttr( SwTxtAttr & );
};

// ATT_CONTOUR ***********************************************************

class SwTxtContour : public SwTxtAttrEnd
{
    BOOL bPrevContour;
public:
    SwTxtContour( const SvxContourItem& rAttr, xub_StrLen nStart, xub_StrLen nEnd );

    virtual void ChgFnt(SwFont *);
    virtual void RstFnt(SwFont *);
    virtual void ChgTxtAttr( SwTxtAttr & );
    virtual void RstTxtAttr( SwTxtAttr & );
};

// ATT_CROSSEDOUT ********************************************************

class SwTxtCrossedOut : public SwTxtAttrEnd
{
    FontStrikeout ePrevCrossedOut;
public:
    SwTxtCrossedOut( const SvxCrossedOutItem& rAttr, xub_StrLen nStart, xub_StrLen nEnd );

    virtual void ChgFnt(SwFont *);
    virtual void RstFnt(SwFont *);
    virtual void ChgTxtAttr( SwTxtAttr & );
    virtual void RstTxtAttr( SwTxtAttr & );
};

// ATT_UNDERLINE *********************************************************

class SwTxtUnderline : public SwTxtAttrEnd
{
    FontUnderline ePrevUnderline;
public:
    SwTxtUnderline( const SvxUnderlineItem& rAttr, xub_StrLen nStart, xub_StrLen nEnd );

    virtual void ChgFnt(SwFont *);
    virtual void RstFnt(SwFont *);
    virtual void ChgTxtAttr( SwTxtAttr & );
    virtual void RstTxtAttr( SwTxtAttr & );
};

// ATT_SIZE **************************************************************

class SwTxtSize : public SwTxtAttrEnd
{
    Size aPrevSize;
    BYTE nScript;
public:
    SwTxtSize( const SvxFontHeightItem& rAttr, xub_StrLen nStart,
        xub_StrLen nEnd, const BYTE nScrpt );

    virtual void ChgFnt(SwFont *);
    virtual void RstFnt(SwFont *);
    virtual void ChgTxtAttr( SwTxtAttr & );
    virtual void RstTxtAttr( SwTxtAttr & );
};

// ATT_COLOR *************************************************************

class SwTxtColor : public SwTxtAttrEnd
{
    friend class SwTxtCharSetColor;
    Color aPrevColor;
public:
    SwTxtColor( const SvxColorItem& rAttr, xub_StrLen nStart, xub_StrLen nEnd );

    virtual void ChgFnt(SwFont *);
    virtual void RstFnt(SwFont *);
    virtual void ChgTxtAttr( SwTxtAttr & );
    virtual void RstTxtAttr( SwTxtAttr & );
};

// ATT_CHARSETCOLOR ******************************************************

class SwTxtCharSetColor : public SwTxtAttrEnd
{
    SwCharSetCol *pPrevCharSetCol;
public:
    SwTxtCharSetColor( const SvxCharSetColorItem& rAttr, xub_StrLen nStart, xub_StrLen nEnd );
    ~SwTxtCharSetColor();
    virtual void ChgFnt(SwFont *);
    virtual void RstFnt(SwFont *);
    virtual void ChgTxtAttr( SwTxtAttr & );
    virtual void RstTxtAttr( SwTxtAttr & );
};

// ATT_CHARFMT *********************************************

class SwTxtCharFmt : public SwTxtAttrEnd
{
    SwImplPrev *pImpl;
    SwTxtNode* pMyTxtNd;
    BOOL bPrevNoHyph    : 1;
    BOOL bPrevBlink     : 1;
    BOOL bPrevURL       : 1;
    BOOL bColor         : 1;

public:
    SwTxtCharFmt( const SwFmtCharFmt& rAttr, xub_StrLen nStart, xub_StrLen nEnd );
    ~SwTxtCharFmt( );

    virtual void ChgFnt(SwFont *);
    virtual void RstFnt(SwFont *);

    // werden vom SwFmtCharFmt hierher weitergeleitet
    virtual void Modify( SfxPoolItem*, SfxPoolItem* );    // SwClient
    virtual BOOL GetInfo( SfxPoolItem& rInfo ) const;

    // erfrage und setze den TxtNode Pointer
    inline const SwTxtNode& GetTxtNode() const;
    void ChgTxtNode( const SwTxtNode* pNew ) { pMyTxtNd = (SwTxtNode*)pNew; }

};

// ATT_KERNING ***********************************************************

class SwTxtKerning : public SwTxtAttrEnd
{
    short nPrevKern;
public:
    SwTxtKerning( const SvxKerningItem& rAttr, xub_StrLen nStart, xub_StrLen nEnd );

    virtual void ChgFnt(SwFont *);
    virtual void RstFnt(SwFont *);
    virtual void ChgTxtAttr( SwTxtAttr & );
    virtual void RstTxtAttr( SwTxtAttr & );
};

// ATT_CASEMAP ***********************************************************

class SwTxtCaseMap : public SwTxtAttrEnd
{
    SvxCaseMap ePrevCaseMap;
public:
    SwTxtCaseMap( const SvxCaseMapItem& rAttr, xub_StrLen nStart, xub_StrLen nEnd );

    virtual void ChgFnt(SwFont *);
    virtual void RstFnt(SwFont *);
    virtual void ChgTxtAttr( SwTxtAttr & );
    virtual void RstTxtAttr( SwTxtAttr & );
};

// ATT_LANGUAGE **********************************************************

class SwTxtLanguage : public SwTxtAttrEnd
{
    LanguageType ePrevLang;
    BYTE nScript;
public:
    SwTxtLanguage( const SvxLanguageItem& rAttr, xub_StrLen nStart,
        xub_StrLen nEnd, const BYTE nScrpt );

    virtual void ChgFnt(SwFont *);
    virtual void RstFnt(SwFont *);
};

// ATT_ESCAPEMENT ********************************************************

class SwTxtEscapement : public SwTxtAttrEnd
{
    short   nPrevEsc;
    BYTE    nPrevPropr;

public:
    SwTxtEscapement( const SvxEscapementItem& rAttr, xub_StrLen nStart, xub_StrLen nEnd );

    virtual void ChgFnt(SwFont *);
    virtual void RstFnt(SwFont *);
    virtual void ChgTxtAttr( SwTxtAttr & );
    virtual void RstTxtAttr( SwTxtAttr & );
};

// ATT_BLINK ***********************

class SwTxtBlink : public SwTxtAttrEnd
{
    BOOL bPrev;
public:
    SwTxtBlink( const SvxBlinkItem& rAttr,
                        xub_StrLen nStart, xub_StrLen nEnd );

    virtual void ChgFnt(SwFont *);
    virtual void RstFnt(SwFont *);
    virtual void ChgTxtAttr( SwTxtAttr & );
    virtual void RstTxtAttr( SwTxtAttr & );
};

// ATT_BACKGROUND ***********************

class SwTxtBackground : public SwTxtAttrEnd
{
    Color *pPrevColor;
public:
    SwTxtBackground( const SvxBrushItem& rAttr,
                        xub_StrLen nStart, xub_StrLen nEnd );
    ~SwTxtBackground();
    virtual void ChgFnt(SwFont *);
    virtual void RstFnt(SwFont *);
    virtual void ChgTxtAttr( SwTxtAttr & );
    virtual void RstTxtAttr( SwTxtAttr & );
};

// ATT_NOHYPHENHERE **************************

class SwTxtNoHyphenHere : public SwTxtAttrEnd
{
    BOOL bPrev;
public:
    SwTxtNoHyphenHere( const SvxNoHyphenItem& rAttr,
                        xub_StrLen nStart, xub_StrLen nEnd );

    virtual void ChgFnt(SwFont *);
    virtual void RstFnt(SwFont *);
};

// ATT_HARDBLANK ******************************

class SwTxtHardBlank : public SwTxtAttr
{
    sal_Unicode cChar;
public:
    SwTxtHardBlank( const SwFmtHardBlank& rAttr, xub_StrLen nStart );
    inline sal_Unicode GetChar() const  { return cChar; }
};

// ATT_XNLCONTAINERITEM ******************************

class SwTxtXMLAttrContainer : public SwTxtAttrEnd
{
public:
    SwTxtXMLAttrContainer( const SvXMLAttrContainerItem& rAttr,
                        xub_StrLen nStart, xub_StrLen nEnd );
};

// --------------- Inline Implementierungen ------------------------

inline const SwTxtNode& SwTxtCharFmt::GetTxtNode() const
{
    ASSERT( pMyTxtNd, "SwTxtCharFmt:: wo ist mein TextNode?" );
    return *pMyTxtNd;
}

#endif
<|endoftext|>


<commit_before><commit_msg>queue_resize on fixedimage graphic change<commit_after><|endoftext|>