void Vpr::process(Context& context) { using std::floor; using std::min; const Segment& syn = context.getSegment(Constants::SEGMENT_SYN_COLLOCATED); const Segment& vgp = context.getSegment(Constants::SEGMENT_VGT); const Segment& vgpTiePoint = context.getSegment(Constants::SEGMENT_VGT_TP); setMapLats(context); setMapLons(context); setMapLatBounds(context); setMapLonBounds(context); setTpLats(context); setTpLons(context); setTpLatBounds(context); setTpLonBounds(context); const Grid& sourceGrid = syn.getGrid(); const Grid& targetGrid = vgp.getGrid(); const Grid& subsampledTargetGrid = vgpTiePoint.getGrid(); valarray<Accessor*> sourceAccessors(12); valarray<Accessor*> targetAccessors(12); sourceAccessors[0] = &syn.getAccessor("B0"); sourceAccessors[1] = &syn.getAccessor("B2"); sourceAccessors[2] = &syn.getAccessor("B3"); sourceAccessors[3] = &syn.getAccessor("MIR"); sourceAccessors[4] = &syn.getAccessor("SM"); sourceAccessors[5] = &syn.getAccessor("AG"); sourceAccessors[6] = &syn.getAccessor("OG"); sourceAccessors[7] = &syn.getAccessor("WVG"); sourceAccessors[8] = &syn.getAccessor("SAA"); sourceAccessors[9] = &syn.getAccessor("SZA"); sourceAccessors[10] = &syn.getAccessor("VAA"); sourceAccessors[11] = &syn.getAccessor("VZA"); targetAccessors[0] = &vgp.getAccessor("B0"); targetAccessors[1] = &vgp.getAccessor("B2"); targetAccessors[2] = &vgp.getAccessor("B3"); targetAccessors[3] = &vgp.getAccessor("MIR"); targetAccessors[4] = &vgp.getAccessor("SM"); targetAccessors[5] = &vgpTiePoint.getAccessor("AG"); targetAccessors[6] = &vgpTiePoint.getAccessor("OG"); targetAccessors[7] = &vgpTiePoint.getAccessor("WVG"); targetAccessors[8] = &vgpTiePoint.getAccessor("SAA"); targetAccessors[9] = &vgpTiePoint.getAccessor("SZA"); targetAccessors[10] = &vgpTiePoint.getAccessor("VAA"); targetAccessors[11] = &vgpTiePoint.getAccessor("VZA"); const long firstTargetL = context.getFirstComputableL(vgp, *this); context.getLogging().debug("Segment [" + vgp.toString() + "]: firstComputableL = " + lexical_cast<string>(firstTargetL), getId()); long lastTargetL = context.getLastComputableL(vgp, *this); context.getLogging().debug("Segment [" + vgp.toString() + "]: lastComputableL = " + lexical_cast<string>(lastTargetL), getId()); double minSourceLat = 90.0; double maxSourceLat = -90.0; double minTargetLat = 90.0; double maxTargetLat = -90.0; getMinMaxSourceLat(minSourceLat, maxSourceLat); getMinMaxTargetLat(minTargetLat, maxTargetLat, firstTargetL, lastTargetL); // Is the target region north of the source region, without overlap? if (minTargetLat - DEGREES_PER_TARGET_PIXEL * 1.5 > maxSourceLat) { // Yes. Processing is completed. context.setLastComputedL(vgp, *this, lastTargetL); return; } // Is the target region south of the source region, without overlap? if (maxTargetLat + DEGREES_PER_TARGET_PIXEL * 1.5 < minSourceLat && context.getLastComputableL(syn, *this) < sourceGrid.getMaxL()) { // Yes. Processing will be completed later. return; } const long lastComputedSourceL = context.getLastComputableL(syn, *this); long sourceK = 0; long sourceL = 0; long sourceM = 0; long firstRequiredSourceL = 0; PixelFinder pixelFinder(*this, 0.7 * DEGREES_PER_TARGET_PIXEL); for (long l = firstTargetL; l <= lastTargetL; l++) { context.getLogging().progress("Processing line l = " + lexical_cast<string>(l), getId()); firstRequiredSourceL = sourceGrid.getMaxInMemoryL() + 1; for (long k = targetGrid.getMinK(); k <= targetGrid.getMaxK(); k++) { for (long m = targetGrid.getMinM(); m <= targetGrid.getMaxM(); m++) { const double targetLat = getTargetLat(l); const double targetLon = getTargetLon(m); const bool sourcePixelFound = pixelFinder.findSourcePixel(targetLat, targetLon, sourceK, sourceL, sourceM); // 1. Is there a source pixel for the target pixel? if (!sourcePixelFound) { continue; } // 2. Update first required sourceL firstRequiredSourceL = min(sourceL, firstRequiredSourceL); // 3. Is the current source line beyond the last computed source line? if (sourceL > lastComputedSourceL) { // Yes. lastTargetL = min(l - 1, lastTargetL); continue; } const size_t sourceIndex = sourceGrid.getIndex(sourceK, sourceL, sourceM); // 4. Set the samples of the target pixel for (size_t i = 0; i < 5; i++) { Accessor* sourceAccessor = sourceAccessors[i]; Accessor* targetAccessor = targetAccessors[i]; if (!sourceAccessor->isFillValue(sourceIndex)) { setValue(sourceAccessor, targetAccessor, sourceIndex, targetGrid.getIndex(k, l, m)); } } // 5. Is the target pixel in the sub-sampled grid? if (l % 8 == 0 && m % 8 == 0) { // Yes, set the samples of the sub-sampled target pixel for (size_t i = 5; i < targetAccessors.size(); i++) { const size_t targetIndex = subsampledTargetGrid.getIndex(k, l / 8, m / 8); Accessor* sourceAccessor = sourceAccessors[i]; Accessor* targetAccessor = targetAccessors[i]; if (!sourceAccessor->isFillValue(sourceIndex)) { targetAccessor->setDouble(targetIndex, sourceAccessor->getDouble(sourceIndex)); } else { targetAccessor->setFillValue(targetIndex); } } } } } } context.setFirstRequiredL(syn, *this, firstRequiredSourceL); context.setFirstRequiredL(context.getSegment(Constants::SEGMENT_OLC), *this, firstRequiredSourceL); // TODO - needed for synchronizing OLC and SYN_COLLOCATED segments, better unite both segments into one context.setLastComputedL(vgp, *this, lastTargetL); }