示例#1
0
文件: mask2d.cpp 项目: pkgw/aoflagger
void Mask2D::EnlargeVerticallyAndSet(Mask2DCPtr smallMask, int factor)
{
	for(size_t y=0;y<smallMask->Height();++y)
	{
		size_t binSize = factor;
		if(binSize + y*factor > _height)
			binSize = _height - y*factor;

		for(size_t x=0;x<_width;++x)
		{
			for(size_t binY=0;binY<binSize;++binY)
			{
				size_t curY = y*factor + binY;
				SetValue(x, curY, smallMask->Value(x, y));
			}
		}
	}
}
示例#2
0
文件: mask2d.cpp 项目: pkgw/aoflagger
void Mask2D::EnlargeHorizontallyAndSet(Mask2DCPtr smallMask, int factor)
{
	for(size_t x=0;x<smallMask->Width();++x)
	{
		size_t binSize = factor;
		if(binSize + x*factor > _width)
			binSize = _width - x*factor;

		for(size_t y=0;y<_height;++y)
		{
			for(size_t binX=0;binX<binSize;++binX)
			{
				size_t curX = x*factor + binX;
				SetValue(curX, y, smallMask->Value(x, y));
			}
		}
	}
}
示例#3
0
void StatisticalFlagger::ThresholdTime(Mask2DCPtr mask, int **flagMarks, int **sums, int thresholdLevel, int width)
{
	int halfWidthL = (width-1) / 2;
	int halfWidthR = (width-1) / 2;
	for(size_t y=0;y<mask->Height();++y)
	{
		const int *column = sums[y];
		for(size_t x=halfWidthL;x<mask->Width() - halfWidthR;++x)
		{
			if(column[x] > thresholdLevel)
			{
				const unsigned right = x+halfWidthR+1;
				++flagMarks[y][x-halfWidthL];
				if(right < mask->Width())
					--flagMarks[y][right];
			}
		}
	}
}
示例#4
0
void StatisticalFlagger::ThresholdFrequency(Mask2DCPtr mask, int **flagMarks, int **sums, int thresholdLevel, int width)
{
	int halfWidthT = (width-1) / 2;
	int halfWidthB = (width-1) / 2;
	for(size_t y=halfWidthT;y<mask->Height() - halfWidthB;++y)
	{
		int *column = sums[y];
		for(size_t x=0;x<mask->Width();++x)
		{
			if(column[x] > thresholdLevel)
			{
				const unsigned bottom = y+halfWidthB+1;
				++flagMarks[y-halfWidthT][x];
				if(bottom < mask->Height())
					--flagMarks[bottom][x];
			}
		}
	}
}
示例#5
0
bool StatisticalFlagger::SquareContainsFlag(Mask2DCPtr mask, size_t xLeft, size_t yTop, size_t xRight, size_t yBottom)
{
	for(size_t y=yTop;y<=yBottom;++y)
	{
		for(size_t x=xLeft;x<=xRight;++x)
		{
			if(mask->Value(x, y))
				return true;
		}
	}
	return false;
}
示例#6
0
void StatisticalFlagger::SumToTop(Mask2DCPtr mask, int **sums, size_t width, size_t step, bool reverse)
{
	if(reverse)
	{
		for(size_t y=width;y<mask->Height();++y)
		{
			int *column = sums[y];
			for(size_t x=0;x<mask->Width();++x)
			{
				if(mask->Value(x, y - width/2))
					column[x] += step;
			}
		}
	} else {
		for(size_t y=0;y<mask->Height() - width;++y)
		{
			int *column = sums[y];
			for(size_t x=0;x<mask->Width();++x)
			{
				if(mask->Value(x, y + width/2))
					column[x] += step;
			}
		}
	}
}
示例#7
0
	void ChangeResolutionAction::DecreaseTimeWithMask(TimeFrequencyData &data)
	{
		size_t polCount = data.PolarisationCount();
		for(size_t i=0;i<polCount;++i)
		{
			TimeFrequencyData *polData = data.CreateTFDataFromPolarisationIndex(i);
			Mask2DCPtr mask = polData->GetSingleMask();
			for(unsigned j=0;j<polData->ImageCount();++j)
			{
				Image2DCPtr image = polData->GetImage(j);
				polData->SetImage(j, ThresholdTools::ShrinkHorizontally(_timeDecreaseFactor, image, mask));
			}
			delete polData;
		}
		size_t maskCount = data.MaskCount();
		for(size_t i=0;i<maskCount;++i)
		{
			Mask2DCPtr mask = data.GetMask(i);
			Mask2DPtr newMask = mask->ShrinkHorizontallyForAveraging(_timeDecreaseFactor);
			data.SetMask(i, newMask);
		}
	}
示例#8
0
文件: uvimager.cpp 项目: jjdmol/LOFAR
void UVImager::Image(const TimeFrequencyData &data, TimeFrequencyMetaDataCPtr metaData, unsigned frequencyIndex)
{
	if(_uvReal == 0)
		Empty();

	Image2DCPtr
		real = data.GetRealPart(),
		imaginary = data.GetImaginaryPart();
	Mask2DCPtr
		flags = data.GetSingleMask();

	for(unsigned i=0;i<data.ImageWidth();++i) {
		switch(_imageKind) {
			case Homogeneous:
			if(flags->Value(i, frequencyIndex)==0.0L) {
				num_t
					vr = real->Value(i, frequencyIndex),
					vi = imaginary->Value(i, frequencyIndex);
				if(std::isfinite(vr) && std::isfinite(vi))
				{
					num_t u,v;
					GetUVPosition(u, v, i, frequencyIndex, metaData);
					SetUVValue(u, v, vr, vi, 1.0);
					SetUVValue(-u, -v, vr, -vi, 1.0);
				}
			} 
			break;
			case Flagging:
			if((flags->Value(i, frequencyIndex)!=0.0L && !_invertFlagging) ||
					(flags->Value(i, frequencyIndex)==0.0L && _invertFlagging)) {
				num_t u,v;
				GetUVPosition(u, v, i, frequencyIndex, metaData);
				SetUVValue(u, v, 1, 0, 1.0);
				SetUVValue(-u, -v, 1, 0, 1.0);
			}
			break;
		}
	}
}
	void ChangeResolutionAction::DecreaseTimeWithMask(TimeFrequencyData& data)
	{
		size_t polCount = data.PolarizationCount();
		for(size_t i=0;i<polCount;++i)
		{
			TimeFrequencyData polData(data.MakeFromPolarizationIndex(i));
			const Mask2DCPtr mask = polData.GetSingleMask();
			for(unsigned j=0;j<polData.ImageCount();++j)
			{
				const Image2DCPtr image = polData.GetImage(j);
				polData.SetImage(j, ThresholdTools::ShrinkHorizontally(_timeDecreaseFactor, image.get(), mask.get()));
			}
			data.SetPolarizationData(i, std::move(polData));
		}
		size_t maskCount = data.MaskCount();
		for(size_t i=0;i<maskCount;++i)
		{
			Mask2DCPtr mask = data.GetMask(i);
			Mask2DPtr newMask(new Mask2D(mask->ShrinkHorizontallyForAveraging(_timeDecreaseFactor)));
			data.SetMask(i, std::move(newMask));
		}
	}
示例#10
0
void FrequencyPowerPlot::Add(class TimeFrequencyData &data, TimeFrequencyMetaDataCPtr meta)
{
	Image2DCPtr image = data.GetSingleImage();
	Mask2DCPtr mask = data.GetSingleMask();
	for(size_t y=0;y<image->Height();++y)
	{
		double frequency = meta->Band().channels[y].frequencyHz;
		size_t count = 0;
		long double value = 0.0L;

		for(size_t x=0;x<image->Width();++x)
		{
			if(!mask->Value(x, y))
			{
				++count;
				value += image->Value(x, y);
			}
		}
		MapItem &item = _values[frequency];
		item.total += value;
		item.count += count;
	}
} 
	void ChangeResolutionAction::DecreaseTime(TimeFrequencyData &timeFrequencyData)
	{
		if(_useMaskInAveraging)
		{
			DecreaseTimeWithMask(timeFrequencyData);
		}
		else {
			size_t imageCount = timeFrequencyData.ImageCount();
			for(size_t i=0;i<imageCount;++i)
			{
				Image2DCPtr image = timeFrequencyData.GetImage(i);
				Image2DPtr newImage(new Image2D(image->ShrinkHorizontally(_timeDecreaseFactor)));
				timeFrequencyData.SetImage(i, std::move(newImage));
			}
			size_t maskCount = timeFrequencyData.MaskCount();
			for(size_t i=0;i<maskCount;++i)
			{
				Mask2DCPtr mask = timeFrequencyData.GetMask(i);
				Mask2DPtr newMask(new Mask2D(mask->ShrinkHorizontally(_timeDecreaseFactor)));
				timeFrequencyData.SetMask(i, std::move(newMask));
			}
		}
	}
示例#12
0
void Morphology::floodFill(Mask2DCPtr mask, SegmentedImagePtr output, const int *const *lengthWidthValues, size_t x, size_t y, size_t value)
{
	std::stack<MorphologyPoint2D> points;
	MorphologyPoint2D startPoint;
	startPoint.x = x;
	startPoint.y = y;
	points.push(startPoint);
	do {
		MorphologyPoint2D p = points.top();
		points.pop();
		output->SetValue(p.x, p.y, value);
		int z = lengthWidthValues[p.y][p.x];
		if(p.x > 0 && output->Value(p.x-1, p.y) == 0 && mask->Value(p.x-1,p.y))
		{
			int zl = lengthWidthValues[p.y][p.x-1];
			if((zl > 0 && z > 0) || (zl < 0 && z < 0))
			{
				MorphologyPoint2D newP;
				newP.x = p.x-1; newP.y = p.y;
				points.push(newP);
			}
		}
		if(p.x < mask->Width()-1 && output->Value(p.x+1, p.y)==0 && mask->Value(p.x+1,p.y))
		{
			int zr = lengthWidthValues[p.y][p.x+1];
			if((zr > 0 && z > 0) || (zr < 0 && z < 0))
			{
				MorphologyPoint2D newP;
				newP.x = p.x+1; newP.y = p.y;
				points.push(newP);
			}
		}
		if(p.y > 0 && output->Value(p.x, p.y-1)==0 && mask->Value(p.x,p.y-1))
		{
			int zt = lengthWidthValues[p.y-1][p.x];
			if((zt > 0 && z > 0) || (zt < 0 && z < 0))
			{
				MorphologyPoint2D newP;
				newP.x = p.x; newP.y = p.y-1;
				points.push(newP);
			}
		}
		if(p.y < mask->Height()-1 && output->Value(p.x, p.y+1)==0 && mask->Value(p.x,p.y+1))
		{
			int zb = lengthWidthValues[p.y+1][p.x];
			if((zb > 0 && z > 0) || (zb < 0 && z < 0))
			{
				MorphologyPoint2D newP;
				newP.x = p.x; newP.y = p.y+1;
				points.push(newP);
			}
		}
	} while(points.size() != 0);
}
示例#13
0
void HighPassFilter::setFlaggedValuesToZeroAndMakeWeights(const Image2DCPtr &inputImage, const Image2DPtr &outputImage, const Mask2DCPtr &inputMask, const Image2DPtr &weightsOutput)
{
	const size_t width = inputImage->Width();
	for(size_t y=0;y<inputImage->Height();++y)
	{
		for(size_t x=0;x<width;++x)
		{
			if(inputMask->Value(x, y) || !isfinite(inputImage->Value(x, y)))
			{
				outputImage->SetValue(x, y, 0.0);
				weightsOutput->SetValue(x, y, 0.0);
			} else {
				outputImage->SetValue(x, y, inputImage->Value(x, y));
				weightsOutput->SetValue(x, y, 1.0);
			}
		}
	}
}
示例#14
0
void HighPassFilter::setFlaggedValuesToZeroAndMakeWeightsSSE(const Image2DCPtr &inputImage, const Image2DPtr &outputImage, const Mask2DCPtr &inputMask, const Image2DPtr &weightsOutput)
{
	const size_t width = inputImage->Width();
	const __m128i zero4i = _mm_set_epi32(0, 0, 0, 0);
	const __m128 zero4 = _mm_set_ps(0.0, 0.0, 0.0, 0.0);
	const __m128 one4 = _mm_set_ps(1.0, 1.0, 1.0, 1.0);
	for(size_t y=0;y<inputImage->Height();++y)
	{
		const bool *rowPtr = inputMask->ValuePtr(0, y);
		const float *inputPtr = inputImage->ValuePtr(0, y);
		float *outputPtr = outputImage->ValuePtr(0, y);
		float *weightsPtr = weightsOutput->ValuePtr(0, y);
		const float *end = inputPtr + width;
		while(inputPtr < end)
		{
			
			// Assign each integer to one bool in the mask
			// Convert false to 0xFFFFFFFF and true to 0
			__m128 conditionMask = _mm_castsi128_ps(
				_mm_cmpeq_epi32(_mm_set_epi32(rowPtr[3] || !isfinite(inputPtr[3]), rowPtr[2] || !isfinite(inputPtr[2]),
																			rowPtr[1] || !isfinite(inputPtr[1]), rowPtr[0] || !isfinite(inputPtr[0])),
												zero4i));
			
			_mm_store_ps(weightsPtr, _mm_or_ps(
				_mm_and_ps(conditionMask, one4),
				_mm_andnot_ps(conditionMask, zero4)
			));
			_mm_store_ps(outputPtr, _mm_or_ps(
				_mm_and_ps(conditionMask, _mm_load_ps(inputPtr)),
				_mm_andnot_ps(conditionMask, zero4)
			));
			
			rowPtr += 4;
			outputPtr += 4;
			inputPtr += 4;
			weightsPtr += 4;
		}
	}
}
示例#15
0
void Compress::WriteSubtractFrequencies(std::ofstream &stream, Image2DCPtr image, Mask2DCPtr mask)
{
	const num_t
		max = ThresholdTools::MaxValue(image, mask),
		min = ThresholdTools::MinValue(image, mask);
	const num_t normalizeFactor = (num_t) ((2<<22) + ((2<<22)-1)) / (max - min);
	//const num_t normalizeFactor = 256.0;
	const uint32_t
		width = image->Width(),
		height = image->Height();
	const char mode = 1;

	stream.write(reinterpret_cast<const char*>(&max), sizeof(max));
	stream.write(reinterpret_cast<const char*>(&min), sizeof(min));
	stream.write(reinterpret_cast<const char*>(&width), sizeof(width));
	stream.write(reinterpret_cast<const char*>(&height), sizeof(height));
	stream.write(&mode, sizeof(mode));

	std::vector<int32_t> basis(width);
	for(size_t x=0;x<width;++x)
	{
		SampleRowPtr row = SampleRow::CreateFromColumn(image, x);
		basis[x] = (int32_t) round(row->Median() * normalizeFactor);
	}
	stream.write(reinterpret_cast<char*>(&basis[0]), sizeof(basis));

	for(unsigned y=0;y<height;++y)
	{
		for(unsigned x=0;x<width;++x)
		{
			if(!mask->Value(x, y))
			{
				int32_t value = (int32_t) (round(image->Value(x, y) * normalizeFactor) - basis[x]);
				stream.write(reinterpret_cast<char*>(&value)+1, 3);
			}
		}
	}
}
示例#16
0
Image2DPtr Compress::Read(std::ifstream &stream, Image2DPtr image, Mask2DCPtr mask)
{
	num_t max = 0.0, min = 0.0;
	size_t width = 0, height = 0;
	char mode = 0;
	stream.read(reinterpret_cast<char*>(&max), sizeof(max));
	stream.read(reinterpret_cast<char*>(&min), sizeof(min));
	stream.read(reinterpret_cast<char*>(&width), sizeof(width));
	stream.read(reinterpret_cast<char*>(&height), sizeof(height));
	stream.read(&mode, sizeof(mode));
	num_t normalizeFactor = (max - min) / (num_t) ((2<<22) + ((2<<22)-1));
	for(unsigned y=0;y<height;++y)
	{
		for(unsigned x=0;x<width;++x)
		{
			if(!mask->Value(x, y))
			{
				int32_t value;
				stream.read(reinterpret_cast<char*>(&value), 3);
				value >>= 8;
				image->SetValue(x, y, value / normalizeFactor + min);
			}
		}
	}
示例#17
0
std::pair<TimeFrequencyData,TimeFrequencyMetaDataPtr> RSPReader::ReadChannelBeamlet(unsigned long timestepStart, unsigned long timestepEnd, unsigned beamletCount, unsigned beamletIndex)
{
	const unsigned width = timestepEnd - timestepStart;
	
	std::pair<TimeFrequencyData,TimeFrequencyMetaDataPtr> data = ReadSingleBeamlet(timestepStart*(unsigned long) 256, timestepEnd*(unsigned long) 256, beamletCount, beamletIndex);

	TimeFrequencyData allX = data.first.Make(Polarization::XX);
	TimeFrequencyData allY = data.first.Make(Polarization::YY);
	Image2DCPtr xr = allX.GetRealPart();
	Image2DCPtr xi = allX.GetImaginaryPart();
	Image2DCPtr yr = allY.GetRealPart();
	Image2DCPtr yi = allY.GetImaginaryPart();
	Mask2DCPtr mask = data.first.GetSingleMask();
	
	Image2DPtr
		outXR = Image2D::CreateUnsetImagePtr(width, 256),
		outXI = Image2D::CreateUnsetImagePtr(width, 256),
		outYR = Image2D::CreateUnsetImagePtr(width, 256),
		outYI = Image2D::CreateUnsetImagePtr(width, 256);
	Mask2DPtr
		outMask = Mask2D::CreateUnsetMaskPtr(width, 256);
	
	std::vector<double> observationTimes;
	for(unsigned long timestep = 0;timestep < timestepEnd-timestepStart;++timestep)
	{
		unsigned long timestepIndex = timestep * 256;
		SampleRow
			realX = SampleRow::MakeFromRow(xr.get(), timestepIndex, 256, 0),
			imaginaryX = SampleRow::MakeFromRow(xi.get(), timestepIndex, 256, 0),
			realY = SampleRow::MakeFromRow(yr.get(), timestepIndex, 256, 0),
			imaginaryY = SampleRow::MakeFromRow(yi.get(), timestepIndex, 256, 0);
		
		FFTTools::FFT(realX, imaginaryX);
		FFTTools::FFT(realY, imaginaryY);
		
		realX.SetVerticalImageValues(outXR.get(), timestep);
		imaginaryX.SetVerticalImageValues(outXI.get(), timestep);
		realY.SetVerticalImageValues(outYR.get(), timestep);
		imaginaryY.SetVerticalImageValues(outYI.get(), timestep);
		
		observationTimes.push_back(data.second->ObservationTimes()[timestepIndex + 256/2]);

		size_t validValues = 0;
		for(unsigned y=0;y<256;++y)
		{
			if(!mask->Value(timestepIndex + y, 0))
				++validValues;
		}
		for(unsigned y=0;y<256;++y)
		{
			outMask->SetValue(timestep, y , validValues == 0);
		}
	}
	
	data.first = TimeFrequencyData(Polarization::XX, outXR, outXI, Polarization::YY, outYR, outYI);
	data.first.SetGlobalMask(outMask);
	BandInfo band = data.second->Band();
	band.channels.clear();
	for(unsigned i=0;i<256;++i)
	{
		ChannelInfo channel;
		channel.frequencyHz = i+1;
		channel.frequencyIndex = i;
		band.channels.push_back(channel);
	}
	data.second->SetBand(band);
	data.second->SetObservationTimes(observationTimes);
	return data;
}
示例#18
0
void Morphology::SegmentByLengthRatio(Mask2DCPtr mask, SegmentedImagePtr output)
{
	Mask2DPtr maskCopy = Mask2D::CreateCopy(mask);
	//StatisticalFlagger::EnlargeFlags(maskCopy, 2, 2);
	
	Mask2DPtr matrices[3];
	for(size_t i=0;i<3;++i)
		matrices[i] = Mask2D::CreateUnsetMaskPtr(mask->Width(), mask->Height());
	
	int
		**hCounts = new int*[mask->Height()],
		**vCounts = new int*[mask->Height()];
	for(size_t y=0;y<mask->Height();++y)
	{
		hCounts[y] = new int[mask->Width()];
		vCounts[y] = new int[mask->Width()];
	}
	
	// Calculate convolved counts
	calculateHorizontalCounts(maskCopy, hCounts);
	calculateVerticalCounts(maskCopy, vCounts);
	
	calculateOpenings(maskCopy, matrices, hCounts, vCounts);


	for(size_t y=0;y<mask->Height();++y)
	{
		for(size_t x=0;x<mask->Width();++x)
			output->SetValue(x, y, 0);
	}
	StatisticalFlagger::EnlargeFlags(matrices[0], _hLineEnlarging, 0);
	StatisticalFlagger::EnlargeFlags(matrices[2], 0, _vLineEnlarging);
	StatisticalFlagger::DensityTimeFlagger(matrices[0], _hDensityEnlargeRatio);
	StatisticalFlagger::DensityFrequencyFlagger(matrices[2], _vDensityEnlargeRatio);

	// Calculate counts again with new matrices
	calculateHorizontalCounts(matrices[0], hCounts);
	calculateVerticalCounts(matrices[2], vCounts);

	for(size_t z=0;z<3;z+=2)
	{
		for(size_t y=0;y<mask->Height();++y)
		{
			for(size_t x=0;x<mask->Width();++x)
			{
				if(matrices[z]->Value(x, y) && output->Value(x, y)==0)
				{
					floodFill(mask, output, matrices, x, y, z, output->NewSegmentValue(), hCounts, vCounts);
				}
			}
		}
	}
	
	for(size_t y=0;y<mask->Height();++y)
	{
		delete[] hCounts[y];
		delete[] vCounts[y];
	}
	delete[] hCounts;
	delete[] vCounts;
}
示例#19
0
void ImageWidget::update(Cairo::RefPtr<Cairo::Context> cairo, unsigned width, unsigned height)
{
	Image2DCPtr image = _image;
	Mask2DCPtr mask = GetActiveMask(), originalMask = _originalMask, alternativeMask = _alternativeMask;
	
	unsigned int
		startX = (unsigned int) round(_startHorizontal * image->Width()),
		startY = (unsigned int) round(_startVertical * image->Height()),
		endX = (unsigned int) round(_endHorizontal * image->Width()),
		endY = (unsigned int) round(_endVertical * image->Height());
	size_t
		imageWidth = endX - startX,
		imageHeight = endY - startY;
		
	if(imageWidth > 30000)
	{
		int shrinkFactor = (imageWidth + 29999) / 30000;
		image = image->ShrinkHorizontally(shrinkFactor);
		mask = mask->ShrinkHorizontally(shrinkFactor);
		if(originalMask != 0)
			originalMask = originalMask->ShrinkHorizontally(shrinkFactor);
		if(alternativeMask != 0)
			alternativeMask = alternativeMask->ShrinkHorizontally(shrinkFactor);
		startX /= shrinkFactor;
		endX /= shrinkFactor;
		imageWidth = endX - startX;
	}

	num_t min, max;
	findMinMax(image, mask, min, max);
	
	// If these are not yet created, they are 0, so ok to delete.
	delete _horiScale;
	delete _vertScale;
	delete _colorScale;
	delete _plotTitle;
		
	if(_showXYAxes)
	{
		_vertScale = new VerticalPlotScale();
		_vertScale->SetDrawWithDescription(_showYAxisDescription);
		_horiScale = new HorizontalPlotScale();
		_horiScale->SetDrawWithDescription(_showXAxisDescription);
	} else {
		_vertScale = 0;
		_horiScale = 0;
	}
	if(_showColorScale)
	{
		_colorScale = new ColorScale();
		_colorScale->SetDrawWithDescription(_showZAxisDescription);
	} else {
		_colorScale = 0;
	}
	if(_showXYAxes)
	{
		if(_metaData != 0 && _metaData->HasBand()) {
			_vertScale->InitializeNumericTicks(_metaData->Band().channels[startY].frequencyHz / 1e6, _metaData->Band().channels[endY-1].frequencyHz / 1e6);
			_vertScale->SetUnitsCaption("Frequency (MHz)");
		} else {
			_vertScale->InitializeNumericTicks(-0.5 + startY, 0.5 + endY - 1.0);
		}
		if(_metaData != 0 && _metaData->HasObservationTimes())
		{
			_horiScale->InitializeTimeTicks(_metaData->ObservationTimes()[startX], _metaData->ObservationTimes()[endX-1]);
			_horiScale->SetUnitsCaption("Time");
		} else {
			_horiScale->InitializeNumericTicks(-0.5 + startX, 0.5 + endX - 1.0);
		}
		if(_manualXAxisDescription)
			_horiScale->SetUnitsCaption(_xAxisDescription);
		if(_manualYAxisDescription)
			_vertScale->SetUnitsCaption(_yAxisDescription);
	}
	if(_metaData != 0) {
		if(_showColorScale && _metaData->ValueDescription()!="")
		{
			if(_metaData->ValueUnits()!="")
				_colorScale->SetUnitsCaption(_metaData->ValueDescription() + " (" + _metaData->ValueUnits() + ")");
			else
				_colorScale->SetUnitsCaption(_metaData->ValueDescription());
		}
	}
	if(_showColorScale)
	{
		if(_scaleOption == LogScale)
			_colorScale->InitializeLogarithmicTicks(min, max);
		else
			_colorScale->InitializeNumericTicks(min, max);
		if(_manualZAxisDescription)
			_colorScale->SetUnitsCaption(_zAxisDescription);
	}

	if(_showTitle && !actualTitleText().empty())
	{
		_plotTitle = new Title();
		_plotTitle->SetText(actualTitleText());
		_plotTitle->SetPlotDimensions(width, height, 0.0);
		_topBorderSize = _plotTitle->GetHeight(cairo);
	} else {
		_plotTitle = 0;
		_topBorderSize = 10.0;
	}
	// The scale dimensions are depending on each other. However, since the height of the horizontal scale is practically
	// not dependent on other dimensions, we give the horizontal scale temporary width/height, so that we can calculate its height:
	if(_showXYAxes)
	{
		_horiScale->SetPlotDimensions(width, height, 0.0, 0.0);
		_bottomBorderSize = _horiScale->GetHeight(cairo);
		_rightBorderSize = _horiScale->GetRightMargin(cairo);
	
		_vertScale->SetPlotDimensions(width - _rightBorderSize + 5.0, height - _topBorderSize - _bottomBorderSize, _topBorderSize);
		_leftBorderSize = _vertScale->GetWidth(cairo);
	} else {
		_bottomBorderSize = 0.0;
		_rightBorderSize = 0.0;
		_leftBorderSize = 0.0;
	}
	if(_showColorScale)
	{
		_colorScale->SetPlotDimensions(width - _rightBorderSize, height - _topBorderSize, _topBorderSize);
		_rightBorderSize += _colorScale->GetWidth(cairo) + 5.0;
	}
	if(_showXYAxes)
	{
		_horiScale->SetPlotDimensions(width - _rightBorderSize + 5.0, height -_topBorderSize - _bottomBorderSize, _topBorderSize, 	_vertScale->GetWidth(cairo));
	}

	class ColorMap *colorMap = createColorMap();
	
	const double
		minLog10 = min>0.0 ? log10(min) : 0.0,
		maxLog10 = max>0.0 ? log10(max) : 0.0;
	if(_showColorScale)
	{
		for(unsigned x=0;x<256;++x)
		{
			num_t colorVal = (2.0 / 256.0) * x - 1.0;
			num_t imageVal;
			if(_scaleOption == LogScale)
				imageVal = exp10((x / 256.0) * (log10(max) - minLog10) + minLog10);
			else 
				imageVal = (max-min) * x / 256.0 + min;
			double
				r = colorMap->ValueToColorR(colorVal),
				g = colorMap->ValueToColorG(colorVal),
				b = colorMap->ValueToColorB(colorVal);
			_colorScale->SetColorValue(imageVal, r/255.0, g/255.0, b/255.0);
		}
	}
	
	_imageSurface.clear();
	_imageSurface =
		Cairo::ImageSurface::create(Cairo::FORMAT_ARGB32, imageWidth, imageHeight);

	_imageSurface->flush();
	unsigned char *data = _imageSurface->get_data();
	size_t rowStride = _imageSurface->get_stride();

	Mask2DPtr highlightMask;
	if(_highlighting)
	{
		highlightMask = Mask2D::CreateSetMaskPtr<false>(image->Width(), image->Height());
		_highlightConfig->Execute(image, highlightMask, true, 10.0);
	}
	const bool
		originalActive = _showOriginalMask && originalMask != 0,
		altActive = _showAlternativeMask && alternativeMask != 0;
	for(unsigned long y=startY;y<endY;++y) {
		guint8* rowpointer = data + rowStride * (endY - y - 1);
		for(unsigned long x=startX;x<endX;++x) {
			int xa = (x-startX) * 4;
			unsigned char r,g,b,a;
			if(_highlighting && highlightMask->Value(x, y) != 0) {
				r = 255; g = 0; b = 0; a = 255;
			} else if(originalActive && originalMask->Value(x, y)) {
				r = 255; g = 0; b = 255; a = 255;
			} else if(altActive && alternativeMask->Value(x, y)) {
				r = 255; g = 255; b = 0; a = 255;
			} else {
				num_t val = image->Value(x, y);
				if(val > max) val = max;
				else if(val < min) val = min;

				if(_scaleOption == LogScale)
				{
					if(image->Value(x, y) <= 0.0)
						val = -1.0;
					else
						val = (log10(image->Value(x, y)) - minLog10) * 2.0 / (maxLog10 - minLog10) - 1.0;
				}
				else
					val = (image->Value(x, y) - min) * 2.0 / (max - min) - 1.0;
				if(val < -1.0) val = -1.0;
				else if(val > 1.0) val = 1.0;
				r = colorMap->ValueToColorR(val);
				g = colorMap->ValueToColorG(val);
				b = colorMap->ValueToColorB(val);
				a = colorMap->ValueToColorA(val);
			}
			rowpointer[xa]=b;
			rowpointer[xa+1]=g;
			rowpointer[xa+2]=r;
			rowpointer[xa+3]=a;
		}
	}
	delete colorMap;

	if(_segmentedImage != 0)
	{
		for(unsigned long y=startY;y<endY;++y) {
			guint8* rowpointer = data + rowStride * (y - startY);
			for(unsigned long x=startX;x<endX;++x) {
				if(_segmentedImage->Value(x,y) != 0)
				{
					int xa = (x-startX) * 4;
					rowpointer[xa]=IntMap::R(_segmentedImage->Value(x,y));
					rowpointer[xa+1]=IntMap::G(_segmentedImage->Value(x,y));
					rowpointer[xa+2]=IntMap::B(_segmentedImage->Value(x,y));
					rowpointer[xa+3]=IntMap::A(_segmentedImage->Value(x,y));
				}
			}
		}
	}
	_imageSurface->mark_dirty();

	while(_imageSurface->get_width() > (int) width || _imageSurface->get_height() > (int) height)
	{
		unsigned
			newWidth = _imageSurface->get_width(),
			newHeight = _imageSurface->get_height();
		if(newWidth > width)
			newWidth = width;
		if(newHeight > height)
			newHeight = height;
		downsampleImageBuffer(newWidth, newHeight);
	}

	_isInitialized = true;
	_initializedWidth = width;
	_initializedHeight = height;
	redrawWithoutChanges(cairo, width, height);
} 
void TimeFrequencyImager::WriteNewFlags(Mask2DCPtr newXX, Mask2DCPtr newXY, Mask2DCPtr newYX, Mask2DCPtr newYY)
{
	WriteNewFlagsPart(newXX, newXY, newYX, newYY, _antenna1Select, _antenna2Select, _spectralWindowSelect, 0, newXX->Width());
}
void TimeFrequencyImager::WriteNewFlags(Mask2DCPtr newXX, Mask2DCPtr newXY, Mask2DCPtr newYX, Mask2DCPtr newYY, int antenna1, int antenna2, int spectralWindow)
{
	WriteNewFlagsPart(newXX, newXY, newYX, newYY, antenna1, antenna2, spectralWindow, 0, newXX->Width());
}
void TimeFrequencyImager::WriteNewFlagsPart(Mask2DCPtr newXX, Mask2DCPtr newXY, Mask2DCPtr newYX, Mask2DCPtr newYY, int antenna1, int antenna2, int spectralWindow, size_t timeOffset, size_t timeEnd, size_t leftBorder, size_t rightBorder)
{
	initializePolarizations();
	checkPolarizations();

	size_t frequencyCount = _measurementSet->FrequencyCount();

	std::map<double,size_t> observationTimes;
	setObservationTimes(*_measurementSet, observationTimes);

	casa::Table *table = _measurementSet->OpenTable(true);
	casa::ScalarColumn<int> antenna1Column(*table, "ANTENNA1"); 
	casa::ScalarColumn<int> antenna2Column(*table, "ANTENNA2");
	casa::ScalarColumn<int> windowColumn(*table, "DATA_DESC_ID");
	casa::ScalarColumn<double> timeColumn(*table, "TIME");
	casa::ArrayColumn<bool> flagColumn(*table, "FLAG");

	ScalarColumnIterator<int> antenna1Iter = ScalarColumnIterator<int>::First(antenna1Column);
	ScalarColumnIterator<int> antenna2Iter = ScalarColumnIterator<int>::First(antenna2Column);
	ScalarColumnIterator<int> windowIter = ScalarColumnIterator<int>::First(windowColumn);
	ScalarColumnIterator<double> timeIter = ScalarColumnIterator<double>::First(timeColumn);
	ArrayColumnIterator<bool> flagIter = ArrayColumnIterator<bool>::First(flagColumn);

	if(frequencyCount != newXX->Height())
	{
		std::cerr << "The frequency count in the measurement set (" << frequencyCount << ") does not match the image!" << std::endl;
	}
	if(timeEnd - timeOffset != newXX->Width())
	{
		std::cerr << "The number of time scans to write in the measurement set (" << (timeEnd - timeOffset) << ") does not match the image (" << newXX->Width() << ") !" << std::endl;
	}

	size_t rowsWritten = 0;
	for(size_t i=0;i<table->nrow();++i) {
		if((*antenna1Iter) == (int) antenna1 &&
		   (*antenna2Iter) == (int) antenna2 &&
		   (*windowIter) == (int) spectralWindow)
		{
			double time = *timeIter;
			size_t timeIndex = observationTimes.find(time)->second;
			if(timeIndex >= timeOffset + leftBorder && timeIndex < timeEnd - rightBorder)
			{
				casa::Array<bool> flag = *flagIter;
				casa::Array<bool>::iterator j = flag.begin();
				for(size_t f=0;f<(size_t) frequencyCount;++f) {
					if(_stokesIIndex >= 0)
					{
						if(_readStokesIDirectly) *j = newXX->Value(timeIndex - timeOffset, f);
						++j;
					}
					if(_xxIndex >= 0)
					{
						if(_readXX) *j = newXX->Value(timeIndex - timeOffset, f);
						++j;
					}
					if(_xyIndex >= 0)
					{
						if(_readXY) *j = newXY->Value(timeIndex - timeOffset, f);
						++j;
					}
					if(_yxIndex >= 0)
					{
						if(_readYX) *j = newYX->Value(timeIndex - timeOffset, f);
						++j;
					}
					if(_yyIndex >= 0)
					{
						if(_readYY) *j = newYY->Value(timeIndex - timeOffset, f);
						++j;
					}
				}
				flagIter.Set(flag);
				++rowsWritten;
			}
		}

		++antenna1Iter;
		++antenna2Iter;
		++timeIter;
		++windowIter;
		++flagIter;
	}
	AOLogger::Debug << "Rows written: " << rowsWritten << '\n';

	delete table;
}