void ZGridStrategy::normalize_grid()
{
    float min = 100.0F,    // set large start value
          norm_offset = 0;

    // find minimum value in offset grid
    for (int i = 0; i < probe_points; i++)
        if (this->pData[i] < min)
          min = this->pData[i];

    // creates addition offset to set minimum value to zero.
    norm_offset = -min;

    // adds the offset to create a table of deltas, normalzed to minimum zero
    for (int i = 0; i < probe_points; i++)
        this->pData[i] += norm_offset;

   // add the offset to the current Z homing offset to preserve full probed offset.
   this->setZoffset(getZhomeoffset() + norm_offset);
}
bool ZGridStrategy::doProbing(StreamOutput *stream)  // probed calibration
{
    // home first using selected mode: NOHOME, HOMEXY, HOMEXYZ
    this->homexyz();

    // deactivate correction during moves
    this->setAdjustFunction(false);

    for (int i=0; i<probe_points; i++) {
        this->pData[i] = 0.0F;        // Clear the ZGrid
    }

    if (this->wait_for_probe) {

        this->cal[X_AXIS] = this->probe_x;  //bed_x/2.0f;
        this->cal[Y_AXIS] = this->probe_y;  //bed_y/2.0f;
        this->cal[Z_AXIS] = this->probe_z;  //bed_z/2.0f;           // Position head for probe attachment
        this->move(this->cal, slow_rate);                           // Move to probe attachment point

        stream->printf("*** Ensure probe is attached and press probe when done ***\n");

        while(!zprobe->getProbeStatus()) {           // Wait for button press
            THEKERNEL->call_event(ON_IDLE);
        };
    }

    this->in_cal = true;                         // In calbration mode

    this->cal[X_AXIS] = 0.0f;                    // Clear calibration position
    this->cal[Y_AXIS] = 0.0f;
    this->cal[Z_AXIS] = std::get<Z_AXIS>(this->probe_offsets) + zprobe->getProbeHeight();

    this->move(this->cal, slow_rate);            // Move to probe start point

    for (int probes = 0; probes < probe_points; probes++) {
        int pindex = 0;

        // z = z home offset - probed distance
        float z = getZhomeoffset() -zprobe->probeDistance((this->cal[X_AXIS] + this->cal_offset_x)-std::get<X_AXIS>(this->probe_offsets),
                  (this->cal[Y_AXIS] + this->cal_offset_y)-std::get<Y_AXIS>(this->probe_offsets));

        pindex = int(this->cal[X_AXIS]/this->bed_div_x + 0.25)*this->numCols + int(this->cal[Y_AXIS]/this->bed_div_y + 0.25);

        this->next_cal();                                        // Calculate next calibration position

        this->pData[pindex] = z ;                                // save the offset
    }

    stream->printf("\nCalibration done.\n");
    if (this->wait_for_probe) {                                  // Only do this it the config calls for probe removal position
        this->cal[X_AXIS] = this->bed_x/2.0f;
        this->cal[Y_AXIS] = this->bed_y/2.0f;
        this->cal[Z_AXIS] = this->bed_z/2.0f;                    // Position head for probe removal
        this->move(this->cal, slow_rate);

        stream->printf("Please remove probe\n");

    }

    // activate correction
    //this->normalize_grid();
    this->normalize_grid_2home();
    this->setAdjustFunction(true);

    this->in_cal = false;

    return true;
}
bool ZGridStrategy::saveGrid(std::string args)
{
    args = "/sd/Zgrid." + args;
    StreamOutput *ZMap_file = new FileStream(args.c_str());

    ZMap_file->printf("P%i %i %i %1.3f\n", probe_points, this->numRows, this->numCols, getZhomeoffset());    // Store probe points to prevent loading undefined grid files

    for (int pos = 0; pos < probe_points; pos++) {
        ZMap_file->printf("%1.3f\n", this->pData[pos]);
    }
    delete ZMap_file;

    return true;

}