//----------------------------------------------------------------------------
GoUctFeatureKnowledgeFactory::GoUctFeatureKnowledgeFactory() : m_weights(0, 0)
{
    ReadWeights();
}
void TimeFrequencyImager::image(size_t antenna1Select, size_t antenna2Select, size_t spectralWindowSelect, size_t startIndex, size_t endIndex)
{
	size_t timeCount = _observationTimes.size();
	int frequencyCount = _measurementSet->FrequencyCount();

	initializePolarizations();
	checkPolarizations();

	if(_sortedTable == 0)
	{
		casa::Table *rawTable = _measurementSet->OpenTable();
		casa::Block<casa::String> names(4);
		names[0] = "DATA_DESC_ID";
		names[1] = "ANTENNA1";
		names[2] = "ANTENNA2";
		names[3] = "TIME";
		_sortedTable = new casa::Table(rawTable->sort(names));
		delete rawTable;
	}

	casa::Block<casa::String> selectionNames(3);
	selectionNames[0] = "DATA_DESC_ID";
	selectionNames[1] = "ANTENNA1";
	selectionNames[2] = "ANTENNA2";
	casa::TableIterator iter(*_sortedTable, selectionNames, casa::TableIterator::Ascending, casa::TableIterator::NoSort);
	while(!iter.pastEnd())
	{
		casa::Table table = iter.table();
		casa::ScalarColumn<int> antenna1(table, "ANTENNA1"); 
		casa::ScalarColumn<int> antenna2(table, "ANTENNA2");
		casa::ScalarColumn<int> windowColumn(table, "DATA_DESC_ID");
		if(table.nrow() > 0 && windowColumn(0) == (int) spectralWindowSelect && antenna1(0) == (int) antenna1Select && antenna2(0) == (int) antenna2Select)
		{
			break;
		} else {
			iter.next();
		}
	}
	if(iter.pastEnd())
	{
		throw std::runtime_error("Baseline not found");
	}

	casa::Table table = iter.table();

	if(startIndex > timeCount)
	{
		std::cerr << "Warning: startIndex > timeCount" << std::endl;
	}
	if(endIndex > timeCount)
	{
		endIndex = timeCount;
		std::cerr << "Warning: endIndex > timeCount" << std::endl;
	}

	size_t width = endIndex-startIndex;
	if(width == 0 || frequencyCount == 0)
		return;

	ClearImages();

	if(_readData) {
		if(_realXX==0 && _readXX)
		{
			_realXX = Image2D::CreateZeroImagePtr(width, frequencyCount);
			_imaginaryXX = Image2D::CreateZeroImagePtr(width, frequencyCount);
		}
		if(_realXY == 0 && _readXY)
		{
			_realXY = Image2D::CreateZeroImagePtr(width, frequencyCount);
			_imaginaryXY = Image2D::CreateZeroImagePtr(width, frequencyCount);
		}
		if(_realYX == 0 && _readYX)
		{
			_realYX = Image2D::CreateZeroImagePtr(width, frequencyCount);
			_imaginaryYX = Image2D::CreateZeroImagePtr(width, frequencyCount);
		}
		if(_realYY == 0 && _readYY)
		{
			_realYY = Image2D::CreateZeroImagePtr(width, frequencyCount);
			_imaginaryYY = Image2D::CreateZeroImagePtr(width, frequencyCount);
		}
		if(_realStokesI == 0 && _readStokesI)
		{
			_realStokesI = Image2D::CreateZeroImagePtr(width, frequencyCount);
			_imaginaryStokesI = Image2D::CreateZeroImagePtr(width, frequencyCount);
		}
	}
	if(_readFlags) {
		// The flags should be initialized to true, as this baseline might
		// miss some time scans that other baselines do have, and these
		// should be flagged.
		if(_flagXX==0 && _readXX)
			_flagXX = Mask2D::CreateSetMaskPtr<true>(width, frequencyCount);
		if(_flagXY==0 && _readXY)
			_flagXY = Mask2D::CreateSetMaskPtr<true>(width, frequencyCount);
		if(_flagYX==0 && _readYX)
			_flagYX = Mask2D::CreateSetMaskPtr<true>(width, frequencyCount);
		if(_flagYY==0 && _readYY)
			_flagYY = Mask2D::CreateSetMaskPtr<true>(width, frequencyCount);
		if(_flagCombined==0 && _readStokesI)
			_flagCombined = Mask2D::CreateSetMaskPtr<true>(width, frequencyCount);
	}
	_uvw.resize(width);

	casa::ScalarColumn<int> antenna1(table, "ANTENNA1"); 
	casa::ScalarColumn<int> antenna2(table, "ANTENNA2");
	casa::ScalarColumn<int> windowColumn(table, "DATA_DESC_ID");
	casa::ScalarColumn<double> timeColumn(table, "TIME");
	casa::ArrayColumn<float> weightColumn(table, "WEIGHT");
	casa::ArrayColumn<double> uvwColumn(table, "UVW");

	casa::ArrayColumn<casa::Complex> *dataColumn = 0;
	if(_readData)
		dataColumn = CreateDataColumn(_dataKind, table);

	ArrayColumnIterator<casa::Complex> *modelIter;
	if(_dataKind == ResidualData) {
		casa::ArrayColumn<casa::Complex> *modelColumn;
		modelColumn = new casa::ArrayColumn<casa::Complex>(table, "MODEL_DATA");
		modelIter = new ArrayColumnIterator<casa::Complex>(ArrayColumnIterator<casa::Complex>::First(*modelColumn));
	} else {
		modelIter = 0;
	}
	casa::ArrayColumn<bool> flagColumn(table, "FLAG");

	ScalarColumnIterator<int> antenna1Iter = ScalarColumnIterator<int>::First(antenna1);
	ScalarColumnIterator<int> antenna2Iter = ScalarColumnIterator<int>::First(antenna2);
	ScalarColumnIterator<int> windowIter = ScalarColumnIterator<int>::First(windowColumn);
	ScalarColumnIterator<double> timeIter = ScalarColumnIterator<double>::First(timeColumn);
	ArrayColumnIterator<double> uvwIter = ArrayColumnIterator<double>::First(uvwColumn);
	ArrayColumnIterator<float> weightIter = ArrayColumnIterator<float>::First(weightColumn);
	ArrayColumnIterator<casa::Complex> dataIter = 
		ArrayColumnIterator<casa::Complex>::First(*dataColumn);
	ArrayColumnIterator<bool> flagIter = 
		ArrayColumnIterator<bool>::First(flagColumn);

	for(size_t i=0;i<table.nrow();++i) {
		double time = *timeIter;
		size_t timeIndex = _observationTimes.find(time)->second;
		bool timeIsSelected = timeIndex>=startIndex && timeIndex<endIndex;
		if(_readData && timeIsSelected) {
			if(_dataKind == WeightData)
				ReadWeights(timeIndex-startIndex, frequencyCount, *weightIter);
			else if(modelIter == 0)
				ReadTimeData(timeIndex-startIndex, frequencyCount, *dataIter, 0);
			else {
				const casa::Array<casa::Complex> model = **modelIter; 
				ReadTimeData(timeIndex-startIndex, frequencyCount, *dataIter, &model);
			}
		}
		if(_readFlags && timeIsSelected) {
			const casa::Array<bool> flag = *flagIter;
			ReadTimeFlags(timeIndex-startIndex, frequencyCount, flag);
		}
		if(timeIsSelected) {
			casa::Array<double> arr = *uvwIter;
			casa::Array<double>::const_iterator i = arr.begin();
			_uvw[timeIndex-startIndex].u = *i;
			++i;
			_uvw[timeIndex-startIndex].v = *i;
			++i;
			_uvw[timeIndex-startIndex].w = *i;
		}

		if(_readData)
		{
			++dataIter;
			if(modelIter != 0)
				++(*modelIter);
		}
		if(_readFlags)
		{
			++flagIter;
		}

		++weightIter;
		++antenna1Iter;
		++antenna2Iter;
		++timeIter;
		++uvwIter;
		++windowIter;
	}
	if(dataColumn != 0)
		delete dataColumn;
}