JNIEXPORT void JNICALL Java_org_adaptinet_sdk_fastcache_DataArray_init(JNIEnv *env, jobject _this, jint dt, jlong cel)
{
	try 
	{
		DATAARRAY * da = DataArray(dt,cel);
		setDataArray(env, _this, da);
	}
	catch(JNIException & ex)
	{
		JNIException::lastError = ex.getErrorCode();
	}
	catch(...)
	{
		ThrowFastCacheException(env,"DataItemChangeType failed",0);
	}
}
AveragingMSRowProvider::AveragingMSRowProvider(double nWavelengthsAveraging, const string& msPath, const MSSelection& selection, const std::map<size_t, size_t>& selectedDataDescIds, const string& dataColumnName, bool requireModel) :
	MSRowProvider(msPath, selection, selectedDataDescIds, dataColumnName, requireModel)
{
	casacore::MSAntenna antennaTable(_ms.antenna());
	_nAntennae = antennaTable.nrow();
	
	casacore::ROArrayColumn<double> positionColumn(antennaTable, casacore::MSAntenna::columnName(casacore::MSAntennaEnums::POSITION));
	std::vector<Pos> positions(_nAntennae);

	casacore::Array<double> posArr(casacore::IPosition(1, 3));
	for(size_t i=0; i!=_nAntennae; ++i)
	{
		positionColumn.get(i, posArr);
		positions[i] = Pos(posArr.data()[0], posArr.data()[1], posArr.data()[2]);
	}
	
	// dataDescId x ant x ant
	_nElements = selectedDataDescIds.size() * _nAntennae * _nAntennae;
	_averagingFactors.assign(_nElements, 0.0);
	_buffers.resize(_nElements);
	MultiBandData bands(_ms.spectralWindow(), _ms.dataDescription());
	
	double dt = (EndTime() - StartTime()) / (EndTimestep() - StartTimestep());
	Logger::Debug << "Assuming integration time of " << dt * (24.0*60.0*60.0) << " seconds.\n";
	
	size_t element = 0;
	size_t averagingSum = 0, minAvgFactor = std::numeric_limits<size_t>::max(), maxAvgFactor = 0;
	for(size_t a1=0; a1!=_nAntennae; ++a1)
	{
		Pos pos1 = positions[a1];
		for(size_t a2=0; a2!=_nAntennae; ++a2)
		{
			Pos pos2 = positions[a2];
			double dx = std::get<0>(pos1) - std::get<0>(pos2);
			double dy = std::get<1>(pos1) - std::get<1>(pos2);
			double dz = std::get<2>(pos1) - std::get<2>(pos2);
			double dist = sqrt(dx*dx + dy*dy + dz*dz);
			for(std::map<size_t, size_t>::const_iterator spwIter=selectedDataDescIds.begin();
					spwIter!=selectedDataDescIds.end(); ++spwIter)
			{
				BandData band = bands[spwIter->first];
				double lambda = band.SmallestWavelength();
				double nWavelengthsPerIntegration = 2.0 * M_PI * dist / lambda * dt;
				_averagingFactors[element] = std::max<size_t>(size_t(floor(nWavelengthsAveraging / nWavelengthsPerIntegration)), 1);
				averagingSum += _averagingFactors[element];
				if(a1 != a2)
				{
					minAvgFactor = std::min<size_t>(minAvgFactor, _averagingFactors[element]);
					maxAvgFactor = std::max<size_t>(maxAvgFactor, _averagingFactors[element]);
				}
				//Logger::Debug << a1 << '\t' << a2 << '\t' << _averagingFactors[element] << '\n';
				++element;
			}
		}
	}
	Logger::Info << "Averaging factor for longest baseline: " << minAvgFactor << " x . For the shortest: " << maxAvgFactor << " x \n";
	
	_spwIndexToDataDescId.resize(selectedDataDescIds.size());
	for(std::map<size_t, size_t>::const_iterator spwIter=selectedDataDescIds.begin();
		spwIter!=selectedDataDescIds.end(); ++spwIter)
	{
		_spwIndexToDataDescId[spwIter->second] = spwIter->first;
	}
	
	_averageFactorSum = 0.0;
	_rowCount = 0;
	_averagedRowCount = 0;

	_currentData = DataArray(DataShape());
	_currentModel = DataArray(DataShape());
	_currentFlags = FlagArray(DataShape());
	_currentWeights = WeightArray(DataShape());
	_averagedDataDescId = _currentDataDescId;
	_flushPosition = 0;
	
	if(!MSRowProvider::AtEnd())
	{
		bool timestepAvailable = processCurrentTimestep();
		if(!timestepAvailable)
			NextRow();
	}
}