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; } } } }
void Morphology::calculateOpenings(Mask2DCPtr mask, int **values) { for(size_t y=0;y<mask->Height();++y) { size_t length = 0; for(size_t x=0;x<mask->Width();++x) { if(mask->Value(x, y)) { ++length; } else if(length > 0) { for(size_t i=x-length;i<x;++i) { values[y][i] = length; } length = 0; values[y][x] = 0; } else { values[y][x] = 0; } } if(length > 0) { for(size_t i=mask->Width()-length;i<mask->Width();++i) { values[y][i] = length; } } } for(size_t x=0;x<mask->Width();++x) { size_t length = 0; for(size_t y=0;y<mask->Height();++y) { if(mask->Value(x, y)) { ++length; } else if(length > 0) { for(size_t i=y-length;i<y;++i) { if(values[i][x] < (int) length) values[i][x] = -(int) length; } length = 0; } } if(length > 0) { for(size_t i=mask->Height()-length;i<mask->Height();++i) { if(values[i][x] < (int) length) values[i][x] = -(int) length; } } } }
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); }
void Compress::Write(std::ofstream &stream, Image2DCPtr image, Mask2DCPtr mask) { const num_t max = ThresholdTools::MaxValue(image, mask), min = ThresholdTools::MinValue(image, mask), mid = (min + max) / 2.0; const num_t normalizeFactor = (num_t) ((2<<22) + ((2<<22)-1)) / (max - min); const uint32_t width = image->Width(), height = image->Height(); const char mode = 0; 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)); 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) - mid) * normalizeFactor); stream.write(reinterpret_cast<char*>(&value)+1, 3); } } } }
void Morphology::calculateVerticalCounts(Mask2DCPtr mask, int **values) { for(size_t x=0;x<mask->Width();++x) { size_t length = 0; for(size_t y=0;y<mask->Height();++y) { if(mask->Value(x, y)) { ++length; } else if(length > 0) { for(size_t i=y-length;i<y;++i) { values[i][x] = length; } length = 0; values[y][x] = 0; } else { values[y][x] = 0; } } for(size_t i=mask->Height()-length;i<mask->Height();++i) { values[i][x] = length; } } }
std::pair<TimeFrequencyData,TimeFrequencyMetaDataPtr> RSPReader::ReadSingleBeamlet(unsigned long timestepStart, unsigned long timestepEnd, unsigned beamletCount, unsigned beamletIndex) { std::pair<TimeFrequencyData,TimeFrequencyMetaDataPtr> data = ReadAllBeamlets(timestepStart, timestepEnd, beamletCount); const unsigned width = timestepEnd - timestepStart; Image2DPtr realX = Image2D::CreateZeroImagePtr(width, 1); Image2DPtr imaginaryX = Image2D::CreateZeroImagePtr(width, 1); Image2DPtr realY = Image2D::CreateZeroImagePtr(width, 1); Image2DPtr imaginaryY = Image2D::CreateZeroImagePtr(width, 1); Mask2DPtr mask = Mask2D::CreateUnsetMaskPtr(width, 1); 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 maskWithBeamlets = data.first.GetSingleMask(); for(unsigned x=0;x<width;++x) { realX->SetValue(x, 0, xr->Value(x, beamletIndex)); imaginaryX->SetValue(x, 0, xi->Value(x, beamletIndex)); realY->SetValue(x, 0, yr->Value(x, beamletIndex)); imaginaryY->SetValue(x, 0, yi->Value(x, beamletIndex)); mask->SetValue(x, 0, maskWithBeamlets->Value(x, beamletIndex)); } data.first = TimeFrequencyData(Polarization::XX, realX, imaginaryX, Polarization::YY, realY, imaginaryY); data.first.SetGlobalMask(mask); BandInfo band = data.second->Band(); band.channels[0] = data.second->Band().channels[beamletIndex]; band.channels.resize(1); data.second->SetBand(band); return data; }
void Morphology::SegmentByMaxLength(Mask2DCPtr mask, SegmentedImagePtr output) { int **lengthWidthValues = new int*[mask->Height()]; for(size_t y=0;y<mask->Height();++y) lengthWidthValues[y] = new int[mask->Width()]; calculateOpenings(mask, lengthWidthValues); for(size_t y=0;y<mask->Height();++y) { for(size_t x=0;x<mask->Width();++x) output->SetValue(x,y,0); } for(size_t y=0;y<mask->Height();++y) { for(size_t x=0;x<mask->Width();++x) { if(mask->Value(x, y) && output->Value(x,y) == 0) { floodFill(mask, output, lengthWidthValues, x, y, output->NewSegmentValue()); } } } for(size_t y=0;y<mask->Height();++y) delete[] lengthWidthValues[y]; delete[] lengthWidthValues; }
void FrequencyFlagCountPlot::Add(class TimeFrequencyData &data, TimeFrequencyMetaDataCPtr meta) { _ignoreFirstChannel = _ignoreFirstChannel && data.ImageHeight() != 1; size_t yStart = _ignoreFirstChannel ? 1 : 0; for(size_t maskIndex=0;maskIndex<data.MaskCount();++maskIndex) { Mask2DCPtr mask = data.GetMask(maskIndex); for(size_t y=yStart;y<mask->Height();++y) { double frequency = meta->Band().channels[y].frequencyHz; size_t count = 0; for(size_t x=0;x<mask->Width();++x) { if(mask->Value(x, y)) ++count; } MapItem item = _counts[frequency]; item.count += count; item.total += mask->Width(); _counts[frequency] = item; } } }
void Morphology::floodFill(Mask2DCPtr mask, SegmentedImagePtr output, Mask2DPtr *matrices, size_t x, size_t y, size_t z, size_t value, int **hCounts, int **vCounts) { std::stack<MorphologyPoint3D> points; MorphologyPoint3D startPoint; startPoint.x = x; startPoint.y = y; startPoint.z = z; points.push(startPoint); do { MorphologyPoint3D p = points.top(); points.pop(); if(mask->Value(p.x, p.y)) { if(output->Value(p.x, p.y) == 0) { output->SetValue(p.x, p.y, value); } else { // now we need to decide whether to change this sample to the new segment or not if(hCounts[p.y][p.x] < vCounts[p.y][p.x] && p.z == 2) output->SetValue(p.x, p.y, value); } } Mask2DPtr matrix = matrices[p.z]; matrix->SetValue(p.x, p.y, false); if((p.z == 0 || p.z == 2) && matrices[1]->Value(p.x,p.y)) { MorphologyPoint3D newP; newP.x = p.x; newP.y = p.y; newP.z = 1; points.push(newP); } if(p.x > 0 && matrix->Value(p.x-1,p.y)) { MorphologyPoint3D newP; newP.x = p.x-1; newP.y = p.y; newP.z = p.z; points.push(newP); } if(p.x < mask->Width()-1 && matrix->Value(p.x+1,p.y)) { MorphologyPoint3D newP; newP.x = p.x+1; newP.y = p.y; newP.z = p.z; newP.z = p.z; points.push(newP); } if(p.y > 0 && matrix->Value(p.x,p.y-1)) { MorphologyPoint3D newP; newP.x = p.x; newP.y = p.y-1; newP.z = p.z; points.push(newP); } if(p.y < mask->Height()-1 && matrix->Value(p.x,p.y+1)) { MorphologyPoint3D newP; newP.x = p.x; newP.y = p.y+1; newP.z = p.z; points.push(newP); } } while(points.size() != 0); }
void StatisticalFlagger::MaskToInts(Mask2DCPtr mask, int **maskAsInt) { for(size_t y=0;y<mask->Height();++y) { int *column = maskAsInt[y]; for(size_t x=0;x<mask->Width();++x) { column[x] = mask->Value(x, y) ? 1 : 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; }
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 ImagerAction::Perform(ArtifactSet &artifacts, ProgressListener &progress) { boost::mutex::scoped_lock lock(_imagerMutex); UVImager *imager = artifacts.Imager(); if(imager == 0) throw BadUsageException("No imager available to create image."); TimeFrequencyData &data = artifacts.ContaminatedData(); TimeFrequencyMetaDataCPtr metaData = artifacts.MetaData(); if(data.PolarisationCount() > 1) { TimeFrequencyData *tmp = data.CreateTFData(StokesIPolarisation); data = *tmp; delete tmp; } bool btPlaneImager = true; if(btPlaneImager) { typedef double ImagerNumeric; BaselineTimePlaneImager<ImagerNumeric> btImager; BandInfo band = metaData->Band(); Image2DCPtr inputReal = data.GetRealPart(), inputImag = data.GetImaginaryPart(); Mask2DCPtr mask = data.GetSingleMask(); size_t width = inputReal->Width(); for(size_t t=0;t!=width;++t) { UVW uvw = metaData->UVW()[t]; size_t channelCount = inputReal->Height(); std::vector<std::complex<ImagerNumeric> > data(channelCount); for(size_t ch=0;ch!=channelCount;++ch) { if(mask->Value(t, ch)) data[ch] = std::complex<ImagerNumeric>(0.0, 0.0); else data[ch] = std::complex<ImagerNumeric>(inputReal->Value(t, ch), inputImag->Value(t, ch)); } btImager.Image(uvw.u, uvw.v, uvw.w, band.channels[0].frequencyHz, band.channels[1].frequencyHz-band.channels[0].frequencyHz, channelCount, &(data[0]), imager->FTReal()); } } else { progress.OnStartTask(*this, 0, 1, "Imaging baseline"); for(size_t y=0;y<data.ImageHeight();++y) { imager->Image(data, metaData, y); progress.OnProgress(*this, y, data.ImageHeight()); } progress.OnEndTask(*this); } }
void Morphology::calculateOpenings(Mask2DCPtr mask, Mask2DPtr *values, int **hCounts, int **vCounts) { //const int zThreshold = 5; for(size_t y=0;y<mask->Height();++y) { for(size_t x=0;x<mask->Width();++x) { bool v = mask->Value(x, y); values[0]->SetValue(x, y, v && (hCounts[y][x] > vCounts[y][x])); values[1]->SetValue(x, y, v && false); //values[1]->SetValue(x, y, v && (abs(hCounts[y][x] - vCounts[y][x]) < zThreshold)); values[2]->SetValue(x, y, v && (hCounts[y][x] <= vCounts[y][x])); } } }
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)); } } } }
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); } } } }
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)); } } } }
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); } } } }
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; } }
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); } } }
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; }
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; }