Example #1
0
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);
}