예제 #1
0
파일: shapes.cpp 프로젝트: mxmlnkn/Octree
    /********************************************
     *     _:_     _:_     :  : /:\ :  :        *
     *    | : | * | : |  = :  /  :  \  :        *
     *    | : |   | : |    :/ :  :  : \:        *
     * r:-1 0 1     x   r:-2 -1  0  1  2        *
     *  j=-1:j=0             j=-1:j=0  :j=2     *
     *           j==section         :j=1        *
     * section <= x <= section+1                *
     ********************************************/
    Pol1Var Weighting( int order, int section ) {
        Pol1Var result("x"); /* need order+1 powers ! */
        if ( order == 1 )
        {
            if ( section == -1 or section == 0 )
                result = "1";
            else
                result = "0";
        }
        else
        {
            Pol1Var tmp("x");
            Pol1Var intoldvar("x");
            Pol2Vars integrand("x,r");

            integrand = Weighting( order-1, section-1 ).renameVariables("x","r");
            result    = integrand.integrate( "r", "x-1", toString(section) );

            integrand = Weighting( order-1, section ).renameVariables("x","r");
            result   += integrand.integrate( "r", toString(section), toString(section+1) );

            integrand = Weighting( order-1, section+1 ).renameVariables("x","r");
            result   += integrand.integrate( "r", toString(section+1), "x+1" );
        }
        return result;
    }
예제 #2
0
void WSMSGridder::gridMeasurementSet(MSData &msData)
{
	const MultiBandData selectedBand(msData.SelectedBand());
	_gridder->PrepareBand(selectedBand);
	std::vector<std::complex<float>> modelBuffer(selectedBand.MaxChannels());
	std::vector<float> weightBuffer(selectedBand.MaxChannels());
	
	lane_write_buffer<InversionWorkItem> writeBuffer(&*_inversionWorkLane, 128);
	
	size_t rowsRead = 0;
	msData.msProvider->Reset();
	while(msData.msProvider->CurrentRowAvailable())
	{
		size_t dataDescId;
		double uInMeters, vInMeters, wInMeters;
		msData.msProvider->ReadMeta(uInMeters, vInMeters, wInMeters, dataDescId);
		const BandData& curBand(selectedBand[dataDescId]);
		const double
			w1 = wInMeters / curBand.LongestWavelength(),
			w2 = wInMeters / curBand.SmallestWavelength();
		if(_gridder->IsInLayerRange(w1, w2))
		{
			InversionWorkItem newItem;
			newItem.u = uInMeters;
			newItem.v = vInMeters;
			newItem.w = wInMeters;
			newItem.dataDescId = dataDescId;
			newItem.data = new std::complex<float>[curBand.ChannelCount()];
			
			if(DoImagePSF())
			{
				msData.msProvider->ReadWeights(newItem.data);
				if(_denormalPhaseCentre)
				{
					double lmsqrt = sqrt(1.0-_phaseCentreDL*_phaseCentreDL- _phaseCentreDM*_phaseCentreDM);
					double shiftFactor = 2.0*M_PI* (newItem.w * (lmsqrt-1.0));
					rotateVisibilities(curBand, shiftFactor, newItem.data);
				}
			}
			else {
				msData.msProvider->ReadData(newItem.data);
			}
			
			if(DoSubtractModel())
			{
				msData.msProvider->ReadModel(modelBuffer.data());
				std::complex<float>* modelIter = modelBuffer.data();
				for(std::complex<float>* iter = newItem.data; iter!=newItem.data+curBand.ChannelCount(); ++iter)
				{
					*iter -= *modelIter;
					modelIter++;
				}
			}
			msData.msProvider->ReadWeights(weightBuffer.data());
			switch(VisibilityWeightingMode())
			{
				case NormalVisibilityWeighting:
					// The MS provider has already preweighted the
					// visibilities for their weight, so we do not
					// have to do anything.
					break;
				case SquaredVisibilityWeighting:
					for(size_t ch=0; ch!=curBand.ChannelCount(); ++ch)
						newItem.data[ch] *= weightBuffer[ch];
					break;
				case UnitVisibilityWeighting:
					for(size_t ch=0; ch!=curBand.ChannelCount(); ++ch)
					{
						if(weightBuffer[ch] == 0.0)
							newItem.data[ch] = 0.0;
						else
							newItem.data[ch] /= weightBuffer[ch];
					}
					break;
			}
			switch(Weighting().Mode())
			{
				case WeightMode::UniformWeighted:
				case WeightMode::BriggsWeighted:
				case WeightMode::NaturalWeighted:
				{
					std::complex<float>* dataIter = newItem.data;
					float* weightIter = weightBuffer.data();
					for(size_t ch=0; ch!=curBand.ChannelCount(); ++ch)
					{
						double
							u = newItem.u / curBand.ChannelWavelength(ch),
							v = newItem.v / curBand.ChannelWavelength(ch),
							weight = PrecalculatedWeightInfo()->GetWeight(u, v);
						*dataIter *= weight;
						_totalWeight += weight * *weightIter;
						++dataIter;
						++weightIter;
					}
				} break;
				case WeightMode::DistanceWeighted:
				{
					float* weightIter = weightBuffer.data();
					double mwaWeight = sqrt(newItem.u*newItem.u + newItem.v*newItem.v + newItem.w*newItem.w);
					for(size_t ch=0; ch!=curBand.ChannelCount(); ++ch)
					{
						_totalWeight += *weightIter * mwaWeight;
						++weightIter;
					}
				} break;
			}
			
			writeBuffer.write(newItem);
			
			++rowsRead;
		}
		
		msData.msProvider->NextRow();
	}
	
	if(Verbose())
		std::cout << "Rows that were required: " << rowsRead << '/' << msData.matchingRows << '\n';
	msData.totalRowsProcessed += rowsRead;
}