void Morphology::calculateHorizontalCounts(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; } } for(size_t i=mask->Width()-length;i<mask->Width();++i) { values[y][i] = length; } } }
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 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 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::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 IterationsPlot::Add(TimeFrequencyData &data, TimeFrequencyMetaDataCPtr) { Item item; Mask2DCPtr mask = data.GetSingleMask(); item.mode = ThresholdTools::Mode(data.GetSingleImage(), mask); item.winsorizedMode = ThresholdTools::WinsorizedMode(data.GetSingleImage(), mask); item.flaggedRatio = (double) mask->GetCount<true>() / ((double) mask->Width() * (double) mask->Height()); _stats.push_back(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::ThresholdTime(Mask2DCPtr mask, int **flagMarks, int **sums, int thresholdLevel, int width) { int halfWidthL = (width-1) / 2; int halfWidthR = (width-1) / 2; for(size_t y=0;y<mask->Height();++y) { const int *column = sums[y]; for(size_t x=halfWidthL;x<mask->Width() - halfWidthR;++x) { if(column[x] > thresholdLevel) { const unsigned right = x+halfWidthR+1; ++flagMarks[y][x-halfWidthL]; if(right < mask->Width()) --flagMarks[y][right]; } } } }
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; } } }
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); }
num_t TimeFrequencyStatistics::GetFlaggedRatio() { size_t total = 0, flagged = 0; for(size_t i=0;i<_data.MaskCount();++i) { Mask2DCPtr mask = _data.GetMask(i); flagged += mask->GetCount<true>(); total += mask->Width() * mask->Height(); } if(total != 0) return (num_t) flagged / (num_t) total; else return 0; }
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 StatisticalFlagger::ThresholdFrequency(Mask2DCPtr mask, int **flagMarks, int **sums, int thresholdLevel, int width) { int halfWidthT = (width-1) / 2; int halfWidthB = (width-1) / 2; for(size_t y=halfWidthT;y<mask->Height() - halfWidthB;++y) { int *column = sums[y]; for(size_t x=0;x<mask->Width();++x) { if(column[x] > thresholdLevel) { const unsigned bottom = y+halfWidthB+1; ++flagMarks[y-halfWidthT][x]; if(bottom < mask->Height()) --flagMarks[bottom][x]; } } } }
void Morphology::SegmentByLengthRatio(Mask2DCPtr mask, SegmentedImagePtr output) { Mask2DPtr maskCopy = Mask2D::CreateCopy(mask); //StatisticalFlagger::EnlargeFlags(maskCopy, 2, 2); Mask2DPtr matrices[3]; for(size_t i=0;i<3;++i) matrices[i] = Mask2D::CreateUnsetMaskPtr(mask->Width(), mask->Height()); int **hCounts = new int*[mask->Height()], **vCounts = new int*[mask->Height()]; for(size_t y=0;y<mask->Height();++y) { hCounts[y] = new int[mask->Width()]; vCounts[y] = new int[mask->Width()]; } // Calculate convolved counts calculateHorizontalCounts(maskCopy, hCounts); calculateVerticalCounts(maskCopy, vCounts); calculateOpenings(maskCopy, matrices, hCounts, vCounts); for(size_t y=0;y<mask->Height();++y) { for(size_t x=0;x<mask->Width();++x) output->SetValue(x, y, 0); } StatisticalFlagger::EnlargeFlags(matrices[0], _hLineEnlarging, 0); StatisticalFlagger::EnlargeFlags(matrices[2], 0, _vLineEnlarging); StatisticalFlagger::DensityTimeFlagger(matrices[0], _hDensityEnlargeRatio); StatisticalFlagger::DensityFrequencyFlagger(matrices[2], _vDensityEnlargeRatio); // Calculate counts again with new matrices calculateHorizontalCounts(matrices[0], hCounts); calculateVerticalCounts(matrices[2], vCounts); for(size_t z=0;z<3;z+=2) { for(size_t y=0;y<mask->Height();++y) { for(size_t x=0;x<mask->Width();++x) { if(matrices[z]->Value(x, y) && output->Value(x, y)==0) { floodFill(mask, output, matrices, x, y, z, output->NewSegmentValue(), hCounts, vCounts); } } } } for(size_t y=0;y<mask->Height();++y) { delete[] hCounts[y]; delete[] vCounts[y]; } delete[] hCounts; delete[] vCounts; }
void TimeFrequencyImager::WriteNewFlags(Mask2DCPtr newXX, Mask2DCPtr newXY, Mask2DCPtr newYX, Mask2DCPtr newYY) { WriteNewFlagsPart(newXX, newXY, newYX, newYY, _antenna1Select, _antenna2Select, _spectralWindowSelect, 0, newXX->Width()); }
void TimeFrequencyImager::WriteNewFlags(Mask2DCPtr newXX, Mask2DCPtr newXY, Mask2DCPtr newYX, Mask2DCPtr newYY, int antenna1, int antenna2, int spectralWindow) { WriteNewFlagsPart(newXX, newXY, newYX, newYY, antenna1, antenna2, spectralWindow, 0, newXX->Width()); }
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; }