/******************************************** * _:_ _:_ : : /:\ : : * * | : | * | : | = : / : \ : * * | : | | : | :/ : : : \: * * 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; }
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; }