text:
#include "estimator_22states.h"

#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void readIMUData();

void readGpsData();

void readMagData();

void readAirData();

void readAhrsData();

void readTimingData();

void readOnboardData();

void readFlowData();

void readDistData();

void WriteFilterOutput();

void CloseFiles();

float ConstrainFloat(float val, float min, float max);

bool endOfData = false; //boolean set to true when all files have returned data

// Estimated time delays (msec)
uint32_t msecVelDelay = 230;
uint32_t msecPosDelay = 210;
uint32_t msecHgtDelay = 350;
uint32_t msecRngDelay = 100;
uint32_t msecMagDelay = 30;
uint32_t msecTasDelay = 210;
uint32_t msecOptFlowDelay = 55;

// IMU input data variables
float imuIn;
float tempImu[8];
float IMUtimestamp;
static uint32_t IMUmsec = 0;
static uint64_t IMUusec = 0;

// Magnetometer input data variables
float magIn;
float tempMag[8];
float tempMagPrev[8];
float posNED[3];
float MAGtimestamp = 0;
uint32_t MAGmsec = 0;
uint32_t lastMAGmsec = 0;
bool newDataMag = false;

// AHRS input data variables
float ahrsIn;
float tempAhrs[7];
float tempAhrsPrev[7];
float AHRStimestamp = 0;
uint32_t AHRSmsec = 0;
uint32_t lastAHRStime = 0;
float ahrsEul[3];
float ahrsErrorRP;
float ahrsErrorYaw;
float eulerEst[3]; // Euler angles calculated from filter states
float eulerDif[3]; // difference between Euler angle estimated by EKF and the AHRS solution
float gpsRaw[7];

// ADS input data variables
float adsIn;
float tempAds[10];
float tempAdsPrev[10];
float ADStimestamp = 0;
uint32_t ADSmsec = 0;
uint32_t lastADSmsec = 0;
float Veas;
bool newAdsData = false;
bool newDataGps = false;
bool newOptFlowData = false;

float onboardTimestamp = 0;
uint32_t onboardMsec = 0;
uint32_t lastOnboardMsec = 0;
bool newOnboardData = false;

float onboardPosNED[3];
float onboardVelNED[3];
float onboardLat;
float onboardLon;
float onboardHgt;

uint32_t flowMsec = 0;
uint32_t lastFlowMsec = 0;
bool newFlowData = false;

float flowTimestamp;      // in seconds
float flowRawPixelX;       // in pixels
float flowRawPixelY;       // in pixels
float flowDistance;        // in meters
float flowQuality;   // distance normalized between 0 and 1
float flowSensorId;        // sensor ID
float flowGyroX = 0.0f;
float flowGyroY = 0.0f;
float flowGyroBiasX = 0.0f;
float flowGyroBiasY = 0.0f;

float flowRadX;
float flowRadY;

float flowRawGroundSpeedX;
float flowRawGroundSpeedY;

uint32_t distMsec = 0;
uint32_t lastDistMsec = 0;
bool newDistData = false;

float distTimestamp = 0.0f;
bool distValid = false;
float distGroundDistance;
float distLastValidReading;

// input data timing
uint64_t msecAlignTime;
uint64_t msecStartTime;
uint64_t msecEndTime;

float gpsGndSpd;
float gpsCourse;
float gpsVelD;

AttPosEKF                   *_ekf;

// Data file identifiers
FILE * pImuFile = nullptr;
FILE * pMagFile = nullptr;
FILE * pGpsFile = nullptr;
FILE * pAhrsFile = nullptr;
FILE * pAdsFile = nullptr;
FILE * pStateOutFile = nullptr;
FILE * pGlitchOutFile = nullptr;
FILE * pEulOutFile = nullptr;
FILE * pCovOutFile = nullptr;
FILE * pRefPosVelOutFile = nullptr;
FILE * pVelPosFuseFile = nullptr;
FILE * pMagFuseFile = nullptr;
FILE * pTasFuseFile = nullptr;
FILE * pRngFuseFile = nullptr;
FILE * pOptFlowFuseFile = nullptr;
FILE * pTimeFile = nullptr;
FILE * pGpsRawOUTFile = nullptr;
FILE * pGpsRawINFile = nullptr;
FILE * validationOutFile = nullptr;
FILE * pOnboardPosVelOutFile = nullptr;
FILE * pOnboardFile = nullptr;
FILE * pInFlowFile = nullptr;
FILE * pInDistFile = nullptr;
FILE * pOutFlowFile = nullptr;

FILE * open_with_exit(const char* filename, const char* flags)
{
    FILE *f = fopen(filename, flags);

    if (!f) {
        printf("FAILED TO OPEN FILE: %s\n", filename);
        exit(1);
    }

    return f;
}

int printstates() {
    printf("States:\n");
    unsigned i = 0;
    printf("Quaternion:\n");
    for (; i<4; i++)
    {
        printf(" %e", _ekf->states[i]);
    }
    printf("\n");
    for (; i<4+6; i++)
    {
        printf(" %e", _ekf->states[i]);
    }
    printf("\n");
    for (; i<4+6+6; i++)
    {
        printf(" %e", _ekf->states[i]);
    }
    printf("\n");
    for (; i < sizeof(_ekf->states) / sizeof(_ekf->states[0]); i++)
    {
        printf(" %e", _ekf->states[i]);
    }
    printf("\n");

    return 0;
}

int main(int argc, char *argv[])
{
    // Instantiate EKF
    _ekf = new AttPosEKF();

    // open data files
    pImuFile = open_with_exit ("IMU.txt","r");
    pMagFile = open_with_exit ("MAG.txt","r");
    pGpsFile = open_with_exit ("GPS.txt","r");
    pAhrsFile = open_with_exit ("ATT.txt","r");
    pAdsFile = open_with_exit ("NTUN.txt","r");
    pTimeFile = open_with_exit ("timing.txt","r");
    pGlitchOutFile = open_with_exit ("GlitchOffsetOut.txt","w");
    pStateOutFile = open_with_exit ("StateDataOut.txt","w");
    pEulOutFile = open_with_exit ("EulDataOut.txt","w");
    pCovOutFile = open_with_exit ("CovDataOut.txt","w");
    pRefPosVelOutFile = open_with_exit ("RefVelPosDataOut.txt","w");
    pVelPosFuseFile = open_with_exit ("VelPosFuse.txt","w");
    pMagFuseFile = open_with_exit ("MagFuse.txt","w");
    pTasFuseFile = open_with_exit ("TasFuse.txt","w");
    pRngFuseFile = open_with_exit ("RngFuse.txt","w");
    pOptFlowFuseFile = open_with_exit ("OptFlowFuse.txt","w");
    pGpsRawINFile = fopen ("GPSraw.txt","r");
    pGpsRawOUTFile = open_with_exit ("GPSrawOut.txt","w");
    validationOutFile = fopen("ValidationOut.txt", "w");
    pOnboardFile = fopen ("GPOSonboard.txt","r");
    pOnboardPosVelOutFile = open_with_exit ("OnboardVelPosDataOut.txt","w");

    pInFlowFile = fopen ("FLOW.txt","r");
    pInDistFile = fopen ("DIST.txt","r");
    pOutFlowFile = fopen ("FlowRawOut.txt","w");

    printf("Filter start\n");

    memset(gpsRaw, 0, sizeof(gpsRaw));

    readTimingData();

    printf("First data instances loaded\n");

    float dt = 0.0f; // time lapsed since last covariance prediction

    bool resetTests = false;

    // Test resets
    if (argc > 1 && (strcmp(argv[1], "reset") == 0)) {
        resetTests = true;
    }

    bool timeoutTested = false;
    bool nanTested = false;
    bool hgtTested = false;

    while (true) {

        // read test data from files for next timestamp
        unsigned nreads = 1;

        // Decide wether to perform any reset tests

        if (resetTests) {

            // Trigger a NaN reset after 25% of the log
            if (!nanTested && (IMUmsec > (msecEndTime - msecStartTime) / 4)) {
                _ekf->states[0] = 0.0f / 0.0f;
                _ekf->states[9] = 0.0f / 0.0f;
                nanTested = true;
                printf("WARNING: TRIGGERING NAN STATE ON PURPOSE!\n");
            }

            // Trigger a timeout at half the log
            if (!timeoutTested && (IMUmsec > (msecEndTime - msecStartTime) / 2)) {
                nreads = 20;
                timeoutTested = true;
                printf("WARNING: TRIGGERING SENSOR TIMEOUT ON PURPOSE!\n");
            }

            // Trigger a NaN altitude at 12.5% of the log
            if (!hgtTested && (IMUmsec > (msecEndTime - msecStartTime) / 8)) {
                _ekf->hgtMea = 0.0f / 0.0f;
                hgtTested = true;
                printf("WARNING: TRIGGERING NaN ALT MEASUREMENT ON PURPOSE!\n");
            }
        }

        // Supporting multiple reads at once to support timeout simulation.
        // The default is however to only read one dataset at a time

        // We need to re-do the dtIMU calculation here so that
        // dtIMU correctly skips if we skip readings.
        uint64_t IMUmsecPrev = IMUmsec;
        for (unsigned i = 0; i < nreads; i++) {
            readIMUData();
            readGpsData();
            readMagData();
            readAirData();
            readAhrsData();
            readOnboardData();
            readFlowData();
            readDistData();
        }

        // Apply dtIMU here after 1 or more reads, simulating skipped sensor
        // readings if desired.
        _ekf->dtIMU     = 0.001f*(IMUmsec - IMUmsecPrev);

        if (IMUmsec > msecEndTime || endOfData)
        {
            printf("Reached end at %8.4f seconds (end of logfile reached: %s)", IMUmsec/1000.0f, (endOfData) ? "YES" : "NO");
            CloseFiles();
            break;
        }

        if ((IMUmsec >= msecStartTime) && (IMUmsec <= msecEndTime))
        {
            // Initialise states, covariance and other data
            if ((IMUmsec > msecAlignTime) && !_ekf->statesInitialised && (_ekf->GPSstatus == 3))
            {
                if (pGpsRawINFile != nullptr)
                {
                    _ekf->velNED[0] = gpsRaw[4];
                    _ekf->velNED[1] = gpsRaw[5];
                    _ekf->velNED[2] = gpsRaw[6];
                }
                else
                {
                    calcvelNED(_ekf->velNED, gpsCourse, gpsGndSpd, gpsVelD);
                }
                _ekf->InitialiseFilter(_ekf->velNED, _ekf->gpsLat, _ekf->gpsLon, _ekf->gpsHgt, 0.0f);

            } else if ((IMUmsec > msecAlignTime) && !_ekf->statesInitialised) {

                float initVelNED[3];

                initVelNED[0] = 0.0f;
                initVelNED[1] = 0.0f;
                initVelNED[2] = 0.0f;
                _ekf->posNE[0] = posNED[0];
                _ekf->posNE[1] = posNED[1];

                _ekf->InitialiseFilter(initVelNED, 0.0, 0.0, 0.0f, 0.0f);

            } else if (_ekf->statesInitialised) {

                // Run the strapdown INS equations every IMU update
                _ekf->UpdateStrapdownEquationsNED();
                #if 1
                // debug code - could be turned into a filter monitoring/watchdog function
                float tempQuat[4];
                for (uint8_t j=0; j<4; j++) tempQuat[j] = _ekf->states[j];
                _ekf->quat2eul(eulerEst, tempQuat);
                for (uint8_t j=0; j<=2; j++) eulerDif[j] = eulerEst[j] - ahrsEul[j];
                if (eulerDif[2] > M_PI) eulerDif[2] -= 2 * M_PI;
                if (eulerDif[2] < -M_PI) eulerDif[2] += 2 * M_PI;
                #endif
                // store the predicted states for subsequent use by measurement fusion
                _ekf->StoreStates(IMUmsec);
                // Check if on ground - status is used by covariance prediction
                bool onground = (((AttPosEKF::sq(_ekf->velNED[0]) + AttPosEKF::sq(_ekf->velNED[1]) + AttPosEKF::sq(_ekf->velNED[2])) < 4.0f) && (_ekf->VtasMeas < 8.0f));

                _ekf->setOnGround(onground);
                // sum delta angles and time used by covariance prediction
                _ekf->summedDelAng = _ekf->summedDelAng + _ekf->correctedDelAng;
                _ekf->summedDelVel = _ekf->summedDelVel + _ekf->dVelIMU;
                dt += _ekf->dtIMU;
                // perform a covariance prediction if the total delta angle has exceeded the limit
                // or the time limit will be exceeded at the next IMU update
                if ((dt >= (_ekf->covTimeStepMax - _ekf->dtIMU)) || (_ekf->summedDelAng.length() > _ekf->covDelAngMax))
                {
                    _ekf->CovariancePrediction(dt);
                    _ekf->summedDelAng.zero();
                    _ekf->summedDelVel.zero();
                    dt = 0.0f;
                }

                // Set global time stamp used by EKF processes
                _ekf->globalTimeStamp_ms = IMUmsec;
            }

            // Fuse optical flow measurements
            if (newFlowData && _ekf->statesInitialised && _ekf->useOpticalFlow && flowQuality > 0.5 && _ekf->Tnb.z.z > 0.71f)
            {
                // recall states and angular rates stored at time of measurement after adjusting for delays
                _ekf->RecallStates(_ekf->statesAtFlowTime, (IMUmsec - msecOptFlowDelay));
                _ekf->RecallOmega(_ekf->omegaAcrossFlowTime, (IMUmsec - 2*msecOptFlowDelay));

                // Calculate bias errorsfor flow sensor internal gyro
                flowGyroBiasX = 0.999f * flowGyroBiasX + 0.001f * (flowGyroX - _ekf->omegaAcrossFlowTime[0]);
                flowGyroBiasY = 0.999f * flowGyroBiasY + 0.001f * (flowGyroY - _ekf->omegaAcrossFlowTime[1]);

                //use sensor internal rates corrected for bias errors
                _ekf->omegaAcrossFlowTime[0] = flowGyroX - flowGyroBiasX;
                _ekf->omegaAcrossFlowTime[1] = flowGyroY - flowGyroBiasY;

                // calculate rotation matrix
                // Copy required states to local variable names
                float q0 = _ekf->statesAtFlowTime[0];
                float q1 = _ekf->statesAtFlowTime[1];
                float q2 = _ekf->statesAtFlowTime[2];
                float q3 = _ekf->statesAtFlowTime[3];
                float q00 = _ekf->sq(q0);
                float q11 = _ekf->sq(q1);
                float q22 = _ekf->sq(q2);
                float q33 = _ekf->sq(q3);
                float q01 = q0 * q1;
                float q02 = q0 * q2;
                float q03 = q0 * q3;
                float q12 = q1 * q2;
                float q13 = q1 * q3;
                float q23 = q2 * q3;
                _ekf->Tnb_flow.x.x = q00 + q11 - q22 - q33;
                _ekf->Tnb_flow.y.y = q00 - q11 + q22 - q33;
                _ekf->Tnb_flow.z.z = q00 - q11 - q22 + q33;
                _ekf->Tnb_flow.y.x = 2*(q12 - q03);
                _ekf->Tnb_flow.z.x = 2*(q13 + q02);
                _ekf->Tnb_flow.x.y = 2*(q12 + q03);
                _ekf->Tnb_flow.z.y = 2*(q23 - q01);
                _ekf->Tnb_flow.x.z = 2*(q13 - q02);
                _ekf->Tnb_flow.y.z = 2*(q23 + q01);

                // scale from raw pixel flow rate to radians/second
                //float scaleFactor = 0.03f; // best value for quad106.zip data using the 16 mm lens
                //float scaleFactor = 0.06f; // best value for InputFilesPX4_flow.zip data
                //float scaleFactor = 0.882f; // best value for quad123.zip data which outputs flow rates that have already been scaled to rad/sec
                float scaleFactor = 1.000f; // best value for quadOptFlowLogData.zip data which outputs flow rates that have already been scaled to rad/sec
                flowRadX = flowRawPixelX * scaleFactor;
                flowRadY = flowRawPixelY * scaleFactor;

                // calculate motion compensated angular flow rates used for fusion in the main nav filter
                _ekf->flowRadXYcomp[0] = flowRadX/_ekf->flowStates[0] + _ekf->omegaAcrossFlowTime[0];
                _ekf->flowRadXYcomp[1] = flowRadY/_ekf->flowStates[0] + _ekf->omegaAcrossFlowTime[1];

                // these flow rates are not motion compensated and are used for focal length scale factor estimation
                _ekf->flowRadXY[0] = flowRadX;
                _ekf->flowRadXY[1] = flowRadY;

                // perform optical flow fusion
                _ekf->fuseOptFlowData = true;
                _ekf->fuseRngData = false;

                // don't try to estimate focal length scale factor if GPS is not being used or there is no range finder.
                if (_ekf->useGPS && _ekf->useRangeFinder) {
                    _ekf->OpticalFlowEKF();
                }
                _ekf->FuseOptFlow();
                _ekf->fuseOptFlowData = false;

                // estimate speed over ground for cross-check of data (debugging only)
                float tempQuat[4];
                float euler[3];
                for (uint8_t j=0; j<4; j++) tempQuat[j] = _ekf->states[j];
                _ekf->quat2eul(euler, tempQuat);
                float bx = (flowRadX - _ekf->angRate.x) * distLastValidReading;
                float by = (flowRadY - _ekf->angRate.y) * distLastValidReading;
                flowRawGroundSpeedY = cos(euler[2]) * bx + -sin(euler[2]) * by;
                flowRawGroundSpeedX = -(sin(euler[2]) * bx + cos(euler[2]) * by);
            } else {
                _ekf->fuseOptFlowData = false;
            }

            // Fuse Ground distance Measurements
            if (newDistData && _ekf->statesInitialised && _ekf->useRangeFinder)
            {
                if (distValid > 0.0f && _ekf->Tnb.z.z > 0.9f) {
                    distLastValidReading = distGroundDistance;
                    _ekf->rngMea = distGroundDistance;
                    _ekf->fuseRngData = true;
                    _ekf->fuseOptFlowData = false;
                    _ekf->RecallStates(_ekf->statesAtRngTime, (IMUmsec - msecRngDelay));
                    _ekf->OpticalFlowEKF();
                    _ekf->fuseRngData = false;
                }
            }

                // Fuse GPS Measurements
                if (newDataGps)
                {
                    // calculate a position offset which is applied to NE position and velocity wherever it is used throughout code to allow GPS position jumps to be accommodated gradually
                    _ekf->decayGpsOffset();

                    // Convert GPS measurements to Pos NE, hgt and Vel NED
                    if (pGpsRawINFile != nullptr)
                    {
                        _ekf->velNED[0] = gpsRaw[4];
                        _ekf->velNED[1] = gpsRaw[5];
                        _ekf->velNED[2] = gpsRaw[6];
                    }
                    else
                    {
                        calcvelNED(_ekf->velNED, gpsCourse, gpsGndSpd, gpsVelD);
                    }
                    calcposNED(posNED, _ekf->gpsLat, _ekf->gpsLon, _ekf->gpsHgt, _ekf->latRef, _ekf->lonRef, _ekf->hgtRef);

                    if (pOnboardFile != nullptr) {
                        calcposNED(onboardPosNED, onboardLat, onboardLon, onboardHgt, _ekf->latRef, _ekf->lonRef, _ekf->hgtRef);

                    }

                    _ekf->posNE[0] = posNED[0];
                    _ekf->posNE[1] = posNED[1];
                     // set fusion flags
                    _ekf->fuseVelData = true;
                    _ekf->fusePosData = true;
                    // recall states stored at time of measurement after adjusting for delays
                    _ekf->RecallStates(_ekf->statesAtVelTime, (IMUmsec - msecVelDelay));
                    _ekf->RecallStates(_ekf->statesAtPosTime, (IMUmsec - msecPosDelay));
                    // run the fusion step
                    _ekf->FuseVelposNED();
                    printf("FuseVelposNED at time = %e \n", IMUtimestamp);
                }
                else
                {
                    _ekf->fuseVelData = false;
                    _ekf->fusePosData = false;
                }
                calcposNED(posNED, _ekf->gpsLat, _ekf->gpsLon, _ekf->gpsHgt, _ekf->latRef, _ekf->lonRef, _ekf->hgtRef);

                if (pOnboardFile > 0) {
                    calcposNED(onboardPosNED, onboardLat, onboardLon, onboardHgt, _ekf->latRef, _ekf->lonRef, _ekf->hgtRef);
                }

                _ekf->posNE[0] = posNED[0];
                _ekf->posNE[1] = posNED[1];

                // fuse GPS
                if (_ekf->useGPS && IMUmsec < 1000) {
                    _ekf->fuseVelData = true;
                    _ekf->fusePosData = true;
                    _ekf->fuseHgtData = false;
                    // recall states stored at time of measurement after adjusting for delays
                    _ekf->RecallStates(_ekf->statesAtVelTime, (IMUmsec - msecVelDelay));
                    _ekf->RecallStates(_ekf->statesAtPosTime, (IMUmsec - msecPosDelay));
                    // record the last fix time
                    _ekf->lastFixTime_ms = IMUmsec;
                    // run the fusion step
                    _ekf->FuseVelposNED();
                } else {
                    _ekf->fuseVelData = false;
                    _ekf->fusePosData = false;
                    _ekf->fuseHgtData = false;
                }
            }
            else
            {
                _ekf->fuseVelData = false;
                _ekf->fusePosData = false;
                _ekf->fuseHgtData = false;
            }

            if (newAdsData && _ekf->statesInitialised)
            {
                // Could use a blend of GPS and baro alt data if desired
                _ekf->hgtMea = 1.0f*_ekf->baroHgt + 0.0f*_ekf->gpsHgt - _ekf->hgtRef - _ekf->baroHgtOffset;
                _ekf->fuseVelData = false;
                _ekf->fusePosData = false;
                _ekf->fuseHgtData = true;
                // recall states stored at time of measurement after adjusting for delays
                _ekf->RecallStates(_ekf->statesAtHgtTime, (IMUmsec - msecHgtDelay));
                // run the fusion step
                _ekf->FuseVelposNED();
//                printf("time = %e \n", IMUtimestamp);
            }
            else
            {
                _ekf->fuseVelData = false;
                _ekf->fusePosData = false;
                _ekf->fuseHgtData = false;
            }

            // Fuse Magnetometer Measurements
            if (newDataMag && _ekf->statesInitialised && _ekf->useCompass)
            {
                _ekf->fuseMagData = true;
                _ekf->RecallStates(_ekf->statesAtMagMeasTime, (IMUmsec - msecMagDelay)); // Assume 50 msec avg delay for magnetometer data
                _ekf->magstate.obsIndex = 0;
                _ekf->FuseMagnetometer();
                _ekf->FuseMagnetometer();
                _ekf->FuseMagnetometer();
            }
            else
            {
                _ekf->fuseMagData = false;
            }

            // Fuse Airspeed Measurements
            if (newAdsData && _ekf->statesInitialised && _ekf->VtasMeas > 8.0f && _ekf->useAirspeed)
            {
                _ekf->fuseVtasData = true;
                _ekf->RecallStates(_ekf->statesAtVtasMeasTime, (IMUmsec - msecTasDelay)); // assume 100 msec avg delay for airspeed data
                _ekf->FuseAirspeed();
            }
            else
            {
                _ekf->fuseVtasData = false;
            }

                struct ekf_status_report ekf_report;

                /*
                 *    CHECK IF THE INPUT DATA IS SANE
                 */
                int check = _ekf->CheckAndBound(&ekf_report);

                switch (check) {
                    case 0:
                        /* all ok */
                        break;
                    case 1:
                    {
                        printf("NaN in states, resetting\n");
                        printf("fail states: ");
                        for (unsigned i = 0; i < ekf_report.n_states; i++) {
                            printf("%f ",ekf_report.states[i]);
                        }
                        printf("\n");

                        printf("states after reset: ");
                        for (unsigned i = 0; i < ekf_report.n_states; i++) {
                            printf("%f ",_ekf->states[i]);
                        }
                        printf("\n");
                        break;
                    }
                    case 2:
                    {
                        printf("stale IMU data, resetting\n");
                        break;
                    }
                    case 3:
                    {
                        printf("switching to dynamic state\n");
                        break;
                    }
                    case 4:
                    {
                        printf("excessive gyro offsets\n");
                        break;
                    }
                    case 5:
                    {
                        printf("GPS velocity diversion\n");
                        break;
                    }
                    case 6:
                    {
                        printf("Excessive covariances\n");
                        break;
                    }

                    default:
                    {
                        printf("unknown reset condition\n");
                    }
                }

                if (check) {
                    printf("RESET OCCURED AT %d milliseconds\n", (int)IMUmsec);

                    if (!ekf_report.velHealth || !ekf_report.posHealth || !ekf_report.hgtHealth || ekf_report.gyroOffsetsExcessive) {
                    printf("health: VEL:%s POS:%s HGT:%s OFFS:%s\n",
                        ((ekf_report.velHealth) ? "OK" : "ERR"),
                        ((ekf_report.posHealth) ? "OK" : "ERR"),
                        ((ekf_report.hgtHealth) ? "OK" : "ERR"),
                        ((!ekf_report.gyroOffsetsExcessive) ? "OK" : "ERR"));
                    }

                    if (ekf_report.velTimeout || ekf_report.posTimeout || ekf_report.hgtTimeout || ekf_report.imuTimeout) {
                        printf("timeout: %s%s%s%s\n",
                            ((ekf_report.velTimeout) ? "VEL " : ""),
                            ((ekf_report.posTimeout) ? "POS " : ""),
                            ((ekf_report.hgtTimeout) ? "HGT " : ""),
                            ((ekf_report.imuTimeout) ? "IMU " : ""));
                    }
                }

                // debug output
                //printf("Euler Angle Difference = %3.1f , %3.1f , %3.1f deg\n", rad2deg*eulerDif[0],rad2deg*eulerDif[1],rad2deg*eulerDif[2]);
                if ((IMUmsec >= msecStartTime) && (IMUmsec <= msecEndTime))
                {
                	WriteFilterOutput();
                }

            }

            // State vector:
            // 0-3: quaternions (q0, q1, q2, q3)
            // 4-6: Velocity - m/sec (North, East, Down)
            // 7-9: Position - m (North, East, Down)
            // 10-12: Delta Angle bias - rad (X,Y,Z)
            // 13: Delta Velocity Z bias -m/s
            // 14-15: Wind Vector  - m/sec (North,East)
            // 16-18: Earth Magnetic Field Vector - milligauss (North, East, Down)
            // 19-21: Body Magnetic Field Vector - milligauss (X,Y,Z)
            // 22: Terrain Vertical Offset - m

            // printf("\n");
            // printf("dtIMU: %8.6f, dt: %8.6f, imuMsec: %u\n", _ekf->dtIMU, dt, IMUmsec);
            // printf("posNED: %8.4f, %8.4f, %8.4f, velNED: %8.4f, %8.4f, %8.4f\n", (double)_ekf->posNED[0], (double)_ekf->posNED[1], (double)_ekf->posNED[2],
            //     (double)_ekf->velNED[0], (double)_ekf->velNED[1], (double)_ekf->velNED[2]);
            // printf("vTAS: %8.4f baro alt: %8.4f\n", _ekf->VtasMeas, _ekf->hgtMea);
            // printf("mag: %8.4f, %8.4f, %8.4f\n", (double)_ekf->magData.x, (double)_ekf->magData.y, (double)_ekf->magData.z);
            // printf("states (quat)        [1-4]: %8.4f, %8.4f, %8.4f, %8.4f\n", (double)_ekf->states[0], (double)_ekf->states[1], (double)_ekf->states[2], (double)_ekf->states[3]);
            // printf("states (vel m/s)     [5-7]: %8.4f, %8.4f, %8.4f\n", (double)_ekf->states[4], (double)_ekf->states[5], (double)_ekf->states[6]);
            // printf("states (pos m)      [8-10]: %8.4f, %8.4f, %8.4f\n", (double)_ekf->states[7], (double)_ekf->states[8], (double)_ekf->states[9]);
            // printf("states (delta ang) [11-13]: %8.4f, %8.4f, %8.4f\n", (double)_ekf->states[10], (double)_ekf->states[11], (double)_ekf->states[12]);
            // printf("states (delta vel) [14]: %8.4ff\n", (double)_ekf->states[13]);
            // printf("states (wind)      [15-16]: %8.4f, %8.4f\n", (double)_ekf->states[14], (double)_ekf->states[15]);
            // printf("states (earth mag) [17-19]: %8.4f, %8.4f, %8.4f\n", (double)_ekf->states[16], (double)_ekf->states[17], (double)_ekf->states[18]);
            // printf("states (body mag)  [20-22]: %8.4f, %8.4f, %8.4f\n", (double)_ekf->states[19], (double)_ekf->states[20], (double)_ekf->states[21]);
            // printf("states (terain offset) [23]: %8.4ff\n", (double)_ekf->states[22]);
            // printf("states: %s %s %s %s %s %s %s %s %s\n",
            //     (_ekf->statesInitialised) ? "INITIALIZED" : "NON_INIT",
            //     (_ekf->onGround) ? "ON_GROUND" : "AIRBORNE",
            //     (_ekf->fuseVelData) ? "FUSE_VEL" : "INH_VEL",
            //     (_ekf->fusePosData) ? "FUSE_POS" : "INH_POS",
            //     (_ekf->fuseHgtData) ? "FUSE_HGT" : "INH_HGT",
            //     (_ekf->fuseMagData) ? "FUSE_MAG" : "INH_MAG",
            //     (_ekf->fuseVtasData) ? "FUSE_VTAS" : "INH_VTAS",
            //     (_ekf->useAirspeed) ? "USE_AIRSPD" : "IGN_AIRSPD",
            //     (_ekf->useCompass) ? "USE_COMPASS" : "IGN_COMPASS");

    delete _ekf;

    printf("\n\nSuccess: Finished processing complete dataset. Text files written.\n");
}

uint32_t millis()
{
    return IMUmsec;
}

uint64_t getMicros()
{
    return IMUusec;
}

void readIMUData()
{
    static Vector3f lastAngRate;
    static Vector3f lastAccel;
    for (uint8_t j=0; j<=7; j++)
    {
        if (fscanf(pImuFile, "%f", &imuIn) != EOF) tempImu[j] = imuIn;
        else endOfData = true;
    }
    if (!endOfData)
    {
        IMUtimestamp  = tempImu[0];
        _ekf->dtIMU     = 0.001f*(tempImu[1] - IMUmsec);
        IMUmsec   = tempImu[1];
        IMUusec = tempImu[0] * 1e6;
        _ekf->angRate.x = tempImu[2];
        _ekf->angRate.y = tempImu[3];
        _ekf->angRate.z = tempImu[4];
        _ekf->accel.x   = tempImu[5];
        _ekf->accel.y   = tempImu[6];
        _ekf->accel.z   = tempImu[7];
        _ekf->dAngIMU = 0.5f*(_ekf->angRate + lastAngRate)*_ekf->dtIMU;
        lastAngRate = _ekf->angRate;
        _ekf->dVelIMU = 0.5f*(_ekf->accel + lastAccel)*_ekf->dtIMU;
        lastAccel = _ekf->accel;
    }
}

void readGpsData()
{
    // wind data forward to one update past current IMU data time
    // and then take data from previous update

    float gpsIn;

    static uint32_t GPSmsec = 0;
    static uint32_t lastGPSmsec = 0;
    static float tempGps[14];
    static float tempGpsPrev[14];
    static float GPStimestamp = 0;

    while (GPStimestamp <= IMUtimestamp && !endOfData)
    {

        // Load APM GPS file format
        for (unsigned j = 0; j < 14; j++)
        {
            tempGpsPrev[j] = tempGps[j];
            if (fscanf(pGpsFile, "%f", &gpsIn) != EOF) {
                tempGps[j] = gpsIn;
            }
            else
            {
                endOfData = true;
                break;
            }
        }

        if (pGpsRawINFile != nullptr) {
            // Load RAW GPS file format in addition
            for (unsigned j = 0; j < sizeof(gpsRaw) / sizeof(gpsRaw[0]); j++)
            {
                if (fscanf(pGpsRawINFile, "%f", &gpsIn) != EOF) {
                    gpsRaw[j] = gpsIn;
                }
                else
                {
                    endOfData = true;
                    break;
                }
            }
        }

        if (!endOfData && (tempGps[1] > 2) /* 3 or more */)
        {
            float now = tempGps[0];
            float gpsDt = (now - GPStimestamp);
            _ekf->updateDtGpsFilt(gpsDt);

            GPStimestamp  = tempGps[0];
            GPSmsec = tempGpsPrev[2];
            _ekf->GPSstatus = tempGpsPrev[1];
            gpsCourse = deg2rad*tempGpsPrev[11];
            gpsGndSpd = tempGpsPrev[10];
            gpsVelD = tempGpsPrev[12];
            _ekf->gpsLat = deg2rad*tempGpsPrev[6];
            _ekf->gpsLon = deg2rad*tempGpsPrev[7] - M_PI;
            _ekf->gpsHgt = tempGpsPrev[8];
        } else if (endOfData) {
            break;
        }
    }
    if (GPSmsec > lastGPSmsec)
    {
        lastGPSmsec = GPSmsec;
        newDataGps = true;
    }
    else
    {
        newDataGps = false;
    }
}

void readMagData()
{
    // wind data forward to one update past current IMU data time
    // and then take data from previous update
    while (MAGtimestamp <= IMUtimestamp && !endOfData)
    {
        for (uint8_t j=0; j<=7; j++)
        {
            tempMagPrev[j] = tempMag[j];
            if (fscanf(pMagFile, "%f", &magIn) != EOF) tempMag[j] = magIn;
            else endOfData = true;
        }
        if (!endOfData)
        {
            MAGtimestamp  = tempMag[0];
            MAGmsec = tempMagPrev[1];
            _ekf->magData.x =  0.001f*(tempMagPrev[2] - tempMagPrev[5]);
            _ekf->magBias.x = -0.001f*tempMagPrev[5];
            _ekf->magData.y =  0.001f*(tempMagPrev[3] - tempMagPrev[6]);
            _ekf->magBias.y = -0.001f*tempMagPrev[6];
            _ekf->magData.z =  0.001f*(tempMagPrev[4] - tempMagPrev[7]);
            _ekf->magBias.z = -0.001f*tempMagPrev[7];
        } else {
            break;
        }
    }
    if (MAGmsec > lastMAGmsec)
    {
        lastMAGmsec = MAGmsec;
        newDataMag = true;
    }
    else
    {
        newDataMag = false;
    }
}

void readAirData()
{
    // wind data forward to one update past current IMU data time
    // and then take data from previous update
    while (ADStimestamp <= IMUtimestamp && !endOfData)
    {
        for (uint8_t j=0; j<=9; j++)
        {
            tempAdsPrev[j] = tempAds[j];
            if (fscanf(pAdsFile, "%f", &adsIn) != EOF) {
                tempAds[j] = adsIn;
            } else {
                endOfData = true;
                break;
            }
        }
        if (!endOfData)
        {
            float now = tempAds[0];
            float hgtDt = (now - ADStimestamp);
            _ekf->updateDtHgtFilt(hgtDt);

            ADStimestamp  = now;
            ADSmsec = tempAdsPrev[1];
            _ekf->VtasMeas = _ekf->EAS2TAS*tempAdsPrev[7];
            _ekf->baroHgt = tempAdsPrev[8];
        } else {
            break;
        }
    }
    if (ADSmsec > lastADSmsec)
    {
        lastADSmsec = ADSmsec;
        newAdsData = true;
    }
    else
    {
        newAdsData = false;
    }
}

void readDistData()
{
    if (pInDistFile == nullptr)
        return;

    float temp[3];

    // read in current value
    while (distTimestamp <= IMUtimestamp && !endOfData)
    {
        for (unsigned j = 0; j < (sizeof(temp) / sizeof(temp[0])); j++)
        {
            float in;
            if (fscanf(pInDistFile, "%f", &in) != EOF) temp[j] = in;
            else endOfData = true;
        }
        if (!endOfData)
        {
            // timestamp, distance, flags
            distTimestamp  = temp[0];       // in milliseconds
            distGroundDistance = temp[1];   // in meters
            distValid = (temp[2] > 0.0f);   // reading is valid

            distMsec = temp[0];
        }
    }
    if (distMsec > lastDistMsec && distValid)
    {
        lastDistMsec = distMsec;
        newDistData = true;
    }
    else
    {
        newDistData = false;
    }
}

void readOnboardData()
{
    if (pOnboardFile == nullptr)
        return;

    float tempOnboard[7];

    // wind data forward to one update past current IMU data time
    // and then take data from previous update
    while (onboardTimestamp <= IMUtimestamp && !endOfData)
    {
        for (uint8_t j = 0; j < 7; j++)
        {
            float onboardIn;
            if (fscanf(pOnboardFile, "%f", &onboardIn) != EOF) tempOnboard[j] = onboardIn;
            else endOfData = true;
        }
        if (!endOfData)
        {
            onboardTimestamp  = tempOnboard[0];
            onboardMsec = tempOnboard[0];
            onboardLat = deg2rad*tempOnboard[1];
            onboardLon = deg2rad*tempOnboard[2] - M_PI;
            onboardHgt = tempOnboard[3];
            onboardVelNED[0] = tempOnboard[4];
            onboardVelNED[1] = tempOnboard[5];
            onboardVelNED[2] = tempOnboard[6];
            //printf("velned onboard: %e %e %e %e %e %e\n", onboardLat, onboardLon, onboardHgt, onboardVelNED[0], onboardVelNED[1], onboardVelNED[2]);
        } else {
            break;
        }
    }
    if (onboardMsec > lastOnboardMsec)
    {
        lastOnboardMsec = onboardMsec;
        newOnboardData = true;
    }
    else
    {
        newOnboardData = false;
    }
}

void readAhrsData()
{
    // wind data forward to one update past current IMU data time
    // and then take data from previous update
    while (AHRStimestamp <= IMUtimestamp && !endOfData)
    {
        for (uint8_t j=0; j<=6; j++)
        {
            tempAhrsPrev[j] = tempAhrs[j];
            if (fscanf(pAhrsFile, "%f", &ahrsIn) != EOF) tempAhrs[j] = ahrsIn;
            else endOfData = true;
        }
        if (!endOfData)
        {
            AHRStimestamp  = tempAhrs[0];
            AHRSmsec = tempAhrsPrev[1];
            for (uint8_t j=0; j<=2; j++)
            {
                ahrsEul[j] = deg2rad*tempAhrsPrev[j+2];
            }
            ahrsErrorRP = tempAhrs[5];
            ahrsErrorYaw = tempAhrs[6];
        } else {
            break;
        }
    }
}

void readFlowData()
{
    if (pInFlowFile <= 0)
        return;

    float temp[8];

    // read in current value
    while (flowTimestamp <= IMUtimestamp && !endOfData)
    {
        for (unsigned j = 0; j < (sizeof(temp) / sizeof(temp[0])); j++)
        {
            float in;
            if (fscanf(pInFlowFile, "%f", &in) != EOF)
            {
                temp[j] = in;
            }
            else
            {
                endOfData = true;
            }
        }
        if (!endOfData)
        {
            // timestamp, rawx, rawy, distance, quality, sensor id, flowGyroX, flowGyroY
            flowTimestamp = temp[0];       // in milliseconds
            flowRawPixelX = temp[1];        // in pixels
            flowRawPixelY = temp[2];        // in pixels
            flowDistance  = temp[3];         // in meters
            // catch glitches in logged data
            if (flowRawPixelX > 200 || flowRawPixelY > 200 || flowRawPixelX < -200 || flowRawPixelY < -200) {
                flowQuality = 0.0f;    // quality normalized between 0 and 1
            } else {
                flowQuality = temp[4] / 255;    // quality normalized between 0 and 1
            }
            flowSensorId = temp[5];         // sensor ID
            flowGyroX = temp[6];
            flowGyroY = temp[7];

            flowMsec = temp[0];
        }
    }
    if (flowMsec > lastFlowMsec)
    {
        // assume 1/2 interval effective delay associated with averaging inside the sensor
        msecOptFlowDelay = (flowMsec - lastFlowMsec)/2;
        lastFlowMsec = flowMsec;
        newFlowData = true;
    }
    else
    {
        newFlowData = false;
    }
}

void WriteFilterOutput()
{
    unsigned n_states = sizeof(_ekf->states) / sizeof(_ekf->states[0]);

    float tempQuat[4];
    for (uint8_t j=0; j<4; j++) tempQuat[j] = _ekf->states[j];
    _ekf->quat2eul(eulerEst, tempQuat);

    // GPS glitch offset
    fprintf(pGlitchOutFile," %e", float(IMUmsec*0.001f));
    fprintf(pGlitchOutFile," %e %e %e", _ekf->velNED[0], _ekf->velNED[1], _ekf->velNED[2]);
    fprintf(pGlitchOutFile," %e %e %e", _ekf->posNE[0], _ekf->posNE[1], _ekf->posNE[2]);
    fprintf(pGlitchOutFile," %e %e", _ekf->gpsPosGlitchOffsetNE.x, _ekf->gpsPosGlitchOffsetNE.y);
    fprintf(pGlitchOutFile," %e %e\n", _ekf->gpsVelGlitchOffset.x, _ekf->gpsVelGlitchOffset.y);

    // filter states
    fprintf(pStateOutFile," %e", float(IMUmsec*0.001f));
    for (uint8_t i=0; i < n_states; i++)
    {
        fprintf(pStateOutFile," %e", _ekf->states[i]);
    }
    fprintf(pStateOutFile,"\n");
    // Euler angles from filter states, AHRS euler angles and AHRS error RP and error Yaw
    fprintf(pEulOutFile," %e", float(IMUmsec*0.001f));
    for (uint8_t i=0; i<=2; i++)
    {
        fprintf(pEulOutFile," %e %e", eulerEst[i], ahrsEul[i]);
    }
    fprintf(pEulOutFile," %e %e", ahrsErrorRP, ahrsErrorYaw);
    fprintf(pEulOutFile,"\n");
    // covariance matrix diagonals
    fprintf(pCovOutFile," %e", float(IMUmsec*0.001f));
    for (uint8_t i=0; i<n_states; i++)
    {
        fprintf(pCovOutFile," %e", _ekf->P[i][i]);
    }
    fprintf(pCovOutFile,"\n");
    // velocity, position and height observations used by the filter
    fprintf(pRefPosVelOutFile," %e", float(IMUmsec*0.001f));
    fprintf(pRefPosVelOutFile," %e %e %e %e %e %e", _ekf->velNED[0], _ekf->velNED[1], _ekf->velNED[2], _ekf->posNE[0], _ekf->posNE[1], -_ekf->hgtMea);
    fprintf(pRefPosVelOutFile,"\n");

    fprintf(pOnboardPosVelOutFile," %e", float(IMUmsec*0.001f));
    fprintf(pOnboardPosVelOutFile," %e %e %e %e %e %e", onboardPosNED[0], onboardPosNED[1], -onboardPosNED[2] + _ekf->hgtRef, onboardVelNED[0], onboardVelNED[1], onboardVelNED[2]);
    // printf("velned onboard out: %e %e %e %e %e %e\n", onboardPosNED[0], onboardPosNED[1], -onboardPosNED[2] + _ekf->hgtRef, onboardVelNED[0], onboardVelNED[1], onboardVelNED[2]);
    fprintf(pOnboardPosVelOutFile,"\n");

    fprintf(pOutFlowFile, " %e", float(IMUmsec*0.001f));
    fprintf(pOutFlowFile, " %e %e %e %e %e %e %e %e %e\n", flowRadX, flowRadY, _ekf->angRate.x, _ekf->angRate.y, flowRawGroundSpeedX, flowRawGroundSpeedY, gpsRaw[4], gpsRaw[5], distLastValidReading);

    // raw GPS outputs
    fprintf(pGpsRawOUTFile," %e", float(IMUmsec*0.001f));
    fprintf(pGpsRawOUTFile," %e %e %e %e %e %e", gpsRaw[1], gpsRaw[2], gpsRaw[3], gpsRaw[4], gpsRaw[5], gpsRaw[6]);
    fprintf(pGpsRawOUTFile,"\n");

    // raw GPS put into local frame and integrated gyros
    fprintf(validationOutFile," %e", float(IMUmsec*0.001f));
    fprintf(validationOutFile," %e %e %e %e %e %e", _ekf->delAngTotal.x, _ekf->delAngTotal.y, _ekf->delAngTotal.z, _ekf->posNE[0], _ekf->posNE[1], _ekf->hgtMea);
    fprintf(validationOutFile,"\n");

    // velocity and position innovations and innovation variances
    fprintf(pVelPosFuseFile," %e", float(IMUmsec*0.001f));
    for (uint8_t i=0; i<=5; i++)
    {
        fprintf(pVelPosFuseFile," %e %e", _ekf->innovVelPos[i], _ekf->varInnovVelPos[i]);
    }
    fprintf(pVelPosFuseFile,"\n");

    // magnetometer innovations and innovation variances
    fprintf(pMagFuseFile," %e", float(IMUmsec*0.001f));
    for (uint8_t i=0; i<=2; i++)
    {
        fprintf(pMagFuseFile," %e %e", _ekf->innovMag[i], _ekf->varInnovMag[i]);
    }
    fprintf(pMagFuseFile,"\n");

    // airspeed innovation and innovation variance
    fprintf(pTasFuseFile," %e", float(IMUmsec*0.001f));
    fprintf(pTasFuseFile," %e %e", _ekf->innovVtas, _ekf->varInnovVtas);
    fprintf(pTasFuseFile,"\n");

    // range finder innovation and innovation variance
    fprintf(pRngFuseFile," %e", float(IMUmsec*0.001f));
    fprintf(pRngFuseFile," %e %e %e %e %e %e %e %e", _ekf->innovRng, _ekf->varInnovRng, _ekf->flowStates[1], _ekf->rngMea, _ekf->hgtMea, -_ekf->statesAtRngTime[9], -_ekf->flowStates[1], -_ekf->states[9] - distGroundDistance);
    fprintf(pRngFuseFile,"\n");

    // optical flow innovation and innovation variance
    fprintf(pOptFlowFuseFile," %e", float(IMUmsec*0.001f));
    for (uint8_t i=0; i<=1; i++)
    {
        fprintf(pOptFlowFuseFile," %e %e", _ekf->innovOptFlow [i], _ekf->varInnovOptFlow[i]);
    }
    // focal length scale factor and height above ground estimate and innovations from optical flow rates
    fprintf(pOptFlowFuseFile," %e %e %e %e %e %e", _ekf->flowStates[0], _ekf->auxFlowObsInnov[0], _ekf->auxFlowObsInnov[1], _ekf->flowStates[1] - _ekf->states[9], distGroundDistance*_ekf->Tbn.z.z, - _ekf->states[9]);
    fprintf(pOptFlowFuseFile,"\n");
}

void readTimingData()
{
    float timeDataIn;
    float timeArray[9];
    for (uint8_t j=0; j<=8; j++)
    {
        if (fscanf(pTimeFile, "%f", &timeDataIn) != EOF)
        {
            timeArray[j] = timeDataIn;
        }
    }
    // we set the align time to start time
    // as we do not require an align time
    // any more with the sensor-based
    // filter init.
    // msecAlignTime = 1000*timeArray[0];
    msecStartTime = 1000*timeArray[1];
    msecAlignTime = msecStartTime;
    msecEndTime   = 1000*timeArray[2];
    msecVelDelay  = timeArray[3];
    msecPosDelay  = timeArray[4];
    msecHgtDelay  = timeArray[5];
    msecMagDelay  = timeArray[6];
    msecTasDelay  = timeArray[7];
    _ekf->EAS2TAS       = timeArray[8];

    printf("msecVelDelay %d\nmsecPosDelay %d\nmsecHgtDelay %d\nmsecMagDelay %d\nmsecTasDelay %d\n",
    		msecVelDelay, msecPosDelay, msecHgtDelay, msecMagDelay, msecTasDelay);
}

void CloseFiles()
{
    if (pImuFile)
        fclose (pImuFile);
    if (pMagFile)
        fclose (pMagFile);
    if (pGpsFile)
        fclose (pGpsFile);
    if (pAhrsFile)
        fclose (pAhrsFile);
    if (pAdsFile)
        fclose (pAdsFile);
    if (pStateOutFile)
        fclose (pStateOutFile);
    if (pEulOutFile)
        fclose (pEulOutFile);
    if (pCovOutFile)
        fclose (pCovOutFile);
    if (pRefPosVelOutFile)
        fclose (pRefPosVelOutFile);
    if (pVelPosFuseFile)
        fclose (pVelPosFuseFile);
    if (pMagFuseFile)
        fclose (pMagFuseFile);
    if (pTasFuseFile)
        fclose (pTasFuseFile);
    if (pTimeFile)
        fclose (pTimeFile);
    if (pGpsRawINFile)
        fclose (pGpsRawINFile);
    if (pGpsRawOUTFile)
        fclose (pGpsRawOUTFile);
    if (validationOutFile)
        fclose (validationOutFile);
    if (pOnboardPosVelOutFile)
        fclose (pOnboardPosVelOutFile);
    if (pOnboardFile)
        fclose (pOnboardFile);
    if (pOptFlowFuseFile)
        fclose (pOptFlowFuseFile);
    if (pRngFuseFile)
        fclose(pRngFuseFile);
}

float ConstrainFloat(float val, float min, float max)
{
    float ret;
    if (val > max) {
        ret = max;
        ekf_debug("> max: %8.4f, val: %8.4f", (double)max, (double)val);
    } else if (val < min) {
        ret = min;
        ekf_debug("< min: %8.4f, val: %8.4f", (double)min, (double)val);
    } else {
        ret = val;
    }

    if (!isfinite(val)) {
        ekf_debug("constrain: non-finite!");
    }

    return ret;
}


text:
int globalVar; // GOOD (not static)
static int staticVar1; // GOOD (used)
static int staticVar2; // GOOD (used)
static int staticVar3 = 3; // GOOD (used)
static int staticVar4 = staticVar3; // GOOD (used)
static int staticVar5; // BAD (unused)
static int staticVar6 = 6; // BAD (unused)
static __attribute__((__unused__)) int staticVar7; // GOOD (unused but this is expected)
const int constVar8 = 8; // BAD (const defaults to static)
extern const int constVar9 = 9; // GOOD
static int staticVar10 = 10; // GOOD [FALSE POSITIVE] (referenced in a never instantiated template)

void f()
{
	int *ptr = &staticVar4;

	staticVar1 = staticVar2;
	(*ptr) = 0;
}

template<class T>
class MyTemplateClass // never instantiated
{
public:
	MyTemplateClass(int param = staticVar10)
	{
		// ...
	}
};

redpajama_set_name: RedPajamaGithub


text:
package com.google.security.zynamics.binnavi.disassembly;

import java.math.BigInteger;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;

import com.google.common.collect.Lists;
import com.google.security.zynamics.binnavi.Common.CommonTestObjects;
import com.google.security.zynamics.binnavi.Database.CModuleViewGenerator;
import com.google.security.zynamics.binnavi.Database.Interfaces.SQLProvider;
import com.google.security.zynamics.binnavi.Database.MockClasses.MockSqlProvider;
import com.google.security.zynamics.binnavi.Tagging.CTag;
import com.google.security.zynamics.binnavi.Tagging.TagType;
import com.google.security.zynamics.binnavi.debug.debugger.DebuggerTemplate;
import com.google.security.zynamics.binnavi.disassembly.AddressSpaces.CAddressSpace;
import com.google.security.zynamics.binnavi.disassembly.Modules.CModule;
import com.google.security.zynamics.binnavi.disassembly.views.CView;
import com.google.security.zynamics.binnavi.disassembly.views.INaviView;
import com.google.security.zynamics.zylib.disassembly.CAddress;
import com.google.security.zynamics.zylib.disassembly.FunctionType;
import com.google.security.zynamics.zylib.disassembly.GraphType;
import com.google.security.zynamics.zylib.disassembly.IAddress;
import com.google.security.zynamics.zylib.disassembly.IOperandTree;
import com.google.security.zynamics.zylib.disassembly.IReference;
import com.google.security.zynamics.zylib.disassembly.ViewType;

public final class MockCreator {
  final static SecureRandom random = new SecureRandom();

  public static CAddressSpace createAddressSpace(final SQLProvider sql) {
    return new CAddressSpace(1, "AS Name", "AS Description", new Date(), new Date(),
        new HashMap<INaviModule, IAddress>(), null, sql, new MockProject());
  }

  public static DebuggerTemplate createDebuggerTemplate(final SQLProvider sql) {
    return new DebuggerTemplate(1, "Mock Debugger Template", "localhost", 1234, sql);
  }

  public static CFunction createFunction(final CModule module, final SQLProvider sql) {
    return new CFunction(module, new MockView(), new CAddress(0x1200), "Mock Function",
        "Mock Function", "Mock Function Description", 5, 6, 7, 8, FunctionType.NORMAL, null, 0,
        null, null, null, sql);
  }

  public static CFunction createFunction(final CModule module, final SQLProvider sql,
      final INaviView view) {
    return new CFunction(module, view, new CAddress(0x1200), "Mock Function", "Mock Function",
        "Mock Function Description", 5, 6, 7, 8, FunctionType.NORMAL, null, 0, null, null, null, sql);
  }

  public static CInstruction createInstruction(final CModule module, final SQLProvider sql) {
    return new CInstruction(false, module, new CAddress(0x123), "nop",
        Lists.newArrayList(new COperandTree(new COperandTreeNode(1,
            IOperandTree.NODE_TYPE_IMMEDIATE_INT_ID, "123", null, new ArrayList<IReference>(), sql,
            module.getTypeManager(), module.getContent().getTypeInstanceContainer()), sql, module
            .getTypeManager(), module.getContent().getTypeInstanceContainer())),
        new byte[] {(byte) 0x41}, "x86-32", sql);
  }

  public static CInstruction createInstructionWithOperand(final BigInteger address,
      final INaviModule module, final SQLProvider sql) {
    return new CInstruction(false, module, new CAddress(address), "inc",
        Lists.newArrayList(new COperandTree(new COperandTreeNode(1,
            IOperandTree.NODE_TYPE_REGISTER_ID, "eax", null, new ArrayList<IReference>(), sql,
            module.getTypeManager(), module.getContent().getTypeInstanceContainer()), sql, module
            .getTypeManager(), module.getContent().getTypeInstanceContainer())),
        new byte[] {(byte) 0x90}, "x86-32", sql);
  }

  public static CModule createModule() {
    return createModule(new MockSqlProvider());
  }

  public static CModule createModule(final SQLProvider sql) {
    return new CModule(123, "Mock Name", "Mock Comment", new Date(), new Date(),
        CommonTestObjects.MD5, CommonTestObjects.SHA1, 55, 66, new CAddress(0x555), new CAddress(
            0x666), null, null, Integer.MAX_VALUE, false, sql);
  }

  public static CView createNativeView(final SQLProvider sql, final CModule module) {
    final CModuleViewGenerator generator = new CModuleViewGenerator(sql, module);
    return generator.generate(1, "Mock View", "Mock View Description", ViewType.Native,
        GraphType.MIXED_GRAPH, new Date(), new Date(), 1, 1, new HashSet<CTag>(),
        new HashSet<CTag>(), false);
  }

  public static CProject createProject(final SQLProvider sql) {
    return new CProject(1, "Mock Project", "Mock Project Description", new Date(), new Date(), 0,
        new ArrayList<DebuggerTemplate>(), sql);
  }

  public static CView createView(final int id, final SQLProvider sql, final CModule module) {
    final CModuleViewGenerator generator = new CModuleViewGenerator(sql, module);
    return generator.generate(id, "Mock View", "Mock View Description", ViewType.NonNative,
        GraphType.MIXED_GRAPH, new Date(), new Date(), 1, 1, new HashSet<CTag>(),
        new HashSet<CTag>(), false);
  }

  public static CView createView(final SQLProvider sql, final CModule module) {
    final CModuleViewGenerator generator = new CModuleViewGenerator(sql, module);
    return generator.generate(new BigInteger(31, random).intValue(), "Mock View",
        "Mock View Description", ViewType.NonNative, GraphType.MIXED_GRAPH, new Date(), new Date(),
        1, 1, new HashSet<CTag>(), new HashSet<CTag>(), false);
  }

  public static CView createView(final SQLProvider sql, final CModule module, final ViewType type) {
    final CModuleViewGenerator generator = new CModuleViewGenerator(sql, module);
    return generator.generate(new BigInteger(31, random).intValue(), "Mock View",
        "Mock View Description", type, GraphType.MIXED_GRAPH, new Date(), new Date(), 1, 1,
        new HashSet<CTag>(), new HashSet<CTag>(), false);
  }

  public static CTag createViewTag(final SQLProvider sql) {
    return new CTag(1, "Mock Tag", "Mock Tag Description", TagType.VIEW_TAG, sql);
  }
}


text:
var indexOf = require('./indexOf');

/**
 * Combines an array with all the items of another.
 * Does not allow duplicates and is case and type sensitive.
 */
function combine(arr1, arr2) {
    if (arr2 == null) {
        return arr1;
    }

    var i = -1, len = arr2.length;
    while (++i < len) {
        if (indexOf(arr1, arr2[i]) === -1) {
            arr1.push(arr2[i]);
        }
    }

    return arr1;
}
module.exports = combine;


text:
'use strict';

// Declare internals
var internals = {};

// Defaults
internals.defaults = {};

exports.register = function(plugin, options, next) {

  plugin.route({
    method: 'GET',
    path: '/gergelyke',
    handler: function(request, reply) {
      reply('don\'t worry, be hapi!');
    }
  });

  next();
};

exports.register.attributes = {
  name: 'gergelyke',
  version: '0.0.0'
};


text: Personal Projects Homepage


text:
import json, re

from util import *
from collections import Counter
from operator import itemgetter
from sklearn.feature_extraction import DictVectorizer
from parse_html import clean_string, TAGS

def main():
    # load data
    path = 'generated/extracted_text'
    data = map(json.loads, file(path))

    # count word for every tag
    tags = TAGS + ['boilerplate', 'boilerpipe']
    counts_per_tag = {}

    for tag in tags:
        counts = map(count, get(tag, data))
        counts_per_tag[tag] = counts

    total = sum_up(counts_per_tag, len(data))

    # vectorize
    v = DictVectorizer()
    v.fit([total])

    features = {}
    for tag in tags:
        features[tag] = v.transform(counts_per_tag[tag])

    save('text_features', features)
    save('text_vectorizer', v)

def tokenize(string):
    string = re.sub(r'[0-9]', '0', string)
    words = re.split(r'\W+', string)

    return map(None, words)

def count(texts):
    counter = Counter()

    for text in texts:
        words = tokenize(text)
        counter.update(words)

    return counter

def get(tag, items):
    for item in items:
        yield item[tag] if (tag in item) else []

    total = Counter()

def sum_up(counts, n):
    tags = list(counts)
    total = Counter()

    for i in xrange(n):
        words = set()
        for tag in tags:
            words.update(set(counts[tag][i]))

        total.update(words)

    return total

if __name__ == "__main__":
    main()


text:
package org.apache.deltaspike.test.jpa.spi.descriptor.xml;

public class MappedId
{

    private Long id;

    public Long getId()
    {
        return id;
    }

    public void setId(Long id)
    {
        this.id = id;
    }

}


text:
title: WDC Samples
layout: docs
---

The Web Data Connector comes with sample connectors that you can use to learn about specific features of the WDC API.
The samples are in the `Examples` folder of the `webdataconnector` repository. You can see the repository
online [here](https://github.com/tableau/webdataconnector/tree/master).

-   **earthquakeUSGS**

    This is the default connector when you open the simulator. Instructions for building it are in the [Tutorial]({{ site.baseurl }}/docs/wdc_tutorial.html). It connects to the USGS Earthquake feed and gets data about earthquakes in the last week.

-   **earthquakeMultitable**

    This connector builds on the previous one to showcase how to get data into multiple tables from a data source.

-   **earthquakeMultilingual**

    This connector demonstrates how to use the locale property of the tableau object to localize content.

-   **StandardConnections**

    This connector gets data from multiple tables in a local JSON file and specifies how the tables should be joined in Tableau Desktop.

-   **StockQuoteConnector_promises**

    This connector gets stock quote data from Yahoo Finance and demonstrates how to use JavaScript
    promises to make several API requests.

-   **IncrementalRefreshConnector**

    This connector showcases how use the incremental refresh API to fetch data incrementally.

-   **MadMoneyScraper**

    This connector demonstrates how to scrape data from a table in a web page and bring that data back through
    the WDC API.

-   **OAuthProxyExample**

    This example shows you how to use OAuth as an authentication method.


text:
<?php namespace LinkThrow\LaravelSocialAggregator\Models;

class UserSocialPost extends \Eloquent {

	protected $table = 'user_social_post';

	protected $fillable = ['user_id', 'social_post_id'];

    public function getDates()
    {
        return array('created_at', 'updated_at');
    }
}


text:
import React, {
  Component,
  PropTypes
} from 'react';
import './LoginForm.css';

import { auth } from '../../utils/auth';

export class LoginForm extends Component {
  static propTypes = {
    onLogin: PropTypes.func.isRequired
  };

  constructor(props) {
    super(props);

    this.state = {
      email: '',
      password: '',
      passwordConfirm: '',
      showSignup: false
    };

    this.onSubmit = this.onSubmit.bind(this);
    this.onChange = this.onChange.bind(this);
    this.triggerSignup = this.triggerSignup.bind(this);
  }

  get confirmPassword() {
    return (
      <input
        className="form-control LoginForm__input"
        type="password"
        name="passwordConfirm"
        onChange={this.onChange}
        value={this.state.passwordConfirm}
        placeholder="Enter your password again"
      />
    );
  }

  get localLoginForm() {
    return (
      <form className="LoginForm" onSubmit={this.onSubmit}>

        <button
          className="btn btn-default btn-sm LoginForm__signup-trigger"
          onClick={this.triggerSignup}>Signup?! :)
        </button>

        <input
          className="form-control LoginForm__input"
          name="email"
          onChange={this.onChange}
          value={this.state.email}
          placeholder="Enter your email"
        />

        <input
          className="form-control LoginForm__input"
          type="password"
          name="password"
          onChange={this.onChange}
          value={this.state.password}
          placeholder="Enter your password"
        />

        {this.state.showSignup && this.confirmPassword}

        <button
          type="submit"
          className="btn btn-primary LoginForm__submit"
        >
          {this.state.showSignup ? 'Signup' : 'Login'}
        </button>
      </form>
    );
  }

  render() {

    return (
      <div className="loginPanel">
        <button className="btn btn-primary" onClick={auth.login.bind(this)}>login with auth0</button>
      </div>
    );
  }

  onSubmit(e) {
    e.preventDefault();

    this.props.onLogin(this.state);
  }

  onChange(e) {
    this.setState({
      [e.target.name]: e.target.value
    });
  }

  triggerSignup(e) {
    e.preventDefault();

    this.setState({
      showSignup: !this.state.showSignup
    });
  }

}


text:
import webbrowser
from random import randint

from PyQt5.QtCore import QDir, Qt, QModelIndex, QCoreApplication, pyqtSignal
from PyQt5.QtGui import QKeySequence, QBrush, QColor
from PyQt5.QtWidgets import QMainWindow, QFileSystemModel, QGraphicsScene, QDesktopWidget, QAbstractItemView, QShortcut, QMessageBox

from hitagilib.ui.hitagi import Ui_Hitagi

from hitagilib.model.settings import SettingsModel
from hitagilib.model.slideshow import SlideshowModel
from hitagilib.model.favorites import FavoritesModel
from hitagilib.controller.canvas import CanvasController
from hitagilib.controller.main import MainController

class MainView(QMainWindow):

    resizeCompleted = pyqtSignal()

    def __init__(self, model, controller, image_path):
        self.settings = SettingsModel()
        self.slideshow = SlideshowModel()

        self.model = model
        self.canvas = self.model.canvas
        self.main_controller = controller
        self.canvas_controller = CanvasController(self.canvas)
        super(MainView, self).__init__()
        self.build_ui()
        self.center_ui()

        # Resize timer to prevent laggy updates
        self.resize_timer = None
        self.resizeCompleted.connect(self.resize_completed)

        # Slideshow
        if self.settings.get('Slideshow', 'reverse') == 'True':
            self.slideshow.updateSignal.connect(self.on_previous_item)
        else:
            self.slideshow.updateSignal.connect(self.on_next_item)

        self.model.subscribe_update_func(self.update_ui_from_model)

        self.arguments = {
            'image_path': image_path
        }

    def build_ui(self):
        self.ui = Ui_Hitagi()
        self.ui.setupUi(self)

        # File menu
        self.ui.actionSet_as_wallpaper.triggered.connect(self.on_set_as_wallpaper)
        self.ui.actionCopy_to_clipboard.triggered.connect(self.on_clipboard)
        self.ui.actionOpen_current_directory.triggered.connect(self.on_current_dir)
        self.ui.actionOptions.triggered.connect(self.on_options)
        self.ui.actionExit.triggered.connect(self.on_close)

        # Folder menu
        self.ui.actionOpen_next.triggered.connect(self.on_next_item)
        self.ui.actionOpen_previous.triggered.connect(self.on_previous_item)
        self.ui.actionChange_directory.triggered.connect(self.on_change_directory)
        self.ui.actionSlideshow.triggered.connect(self.on_slideshow)

        # View menu
        self.ui.actionZoom_in.triggered.connect(self.on_zoom_in)
        self.ui.actionZoom_out.triggered.connect(self.on_zoom_out)
        self.ui.actionOriginal_size.triggered.connect(self.on_zoom_original)
        self.ui.actionRotate_clockwise.triggered.connect(self.on_rotate_clockwise)
        self.ui.actionRotate_counterclockwise.triggered.connect(self.on_rotate_counterclockwise)
        self.ui.actionFlip_horizontally.triggered.connect(self.on_flip_horizontal)
        self.ui.actionFlip_vertically.triggered.connect(self.on_flip_vertical)
        self.ui.actionFit_image_width.triggered.connect(self.on_scale_image_to_width)
        self.ui.actionFit_image_height.triggered.connect(self.on_scale_image_to_height)
        self.ui.actionFile_list.triggered.connect(self.on_toggle_filelist)
        self.ui.actionFullscreen.triggered.connect(self.on_fullscreen)

        # Favorite menu
        self.ui.actionAdd_to_favorites.triggered.connect(self.on_add_to_favorites)
        self.ui.actionRemove_from_favorites.triggered.connect(self.on_remove_from_favorites)

        # Help menu
        self.ui.actionChangelog.triggered.connect(self.on_changelog)
        self.ui.actionAbout.triggered.connect(self.on_about)

        # Load stylesheet
        stylesheet_dir = "resources/hitagi.stylesheet"
        with open(stylesheet_dir, "r") as sh:
            self.setStyleSheet(sh.read())

        # File listing
        self.file_model = QFileSystemModel()
        self.file_model.setFilter(QDir.NoDotAndDotDot | QDir.AllDirs | QDir.Files)
        self.file_model.setNameFilters(['*.bmp', '*.gif', '*.jpg', '*.jpeg', '*.png', '*.png', '*.pbm', '*.pgm', '*.ppm', '*.xbm', '*.xpm'])
        self.file_model.setNameFilterDisables(False)
        self.file_model.setRootPath(self.settings.get('Directory', 'default'))

        self.ui.treeView.setModel(self.file_model)
        self.ui.treeView.setColumnWidth(0, 120)
        self.ui.treeView.setColumnWidth(1, 120)
        self.ui.treeView.hideColumn(1)
        self.ui.treeView.hideColumn(2)

        # Double click
        self.ui.treeView.activated.connect(self.on_dir_list_activated)
        # Update file list
        self.ui.treeView.clicked.connect(self.on_dir_list_clicked)
        # Open parent
        self.ui.pushButton_open_parent.clicked.connect(self.on_open_parent)
        self.ui.pushButton_favorite.clicked.connect(self.on_manage_favorite)

        # Shortcuts
        _translate = QCoreApplication.translate
        self.ui.actionExit.setShortcut(_translate("Hitagi", self.settings.get('Hotkeys', 'Exit')))

        self.ui.actionOpen_next.setShortcut(_translate("Hitagi", self.settings.get('Hotkeys', 'Next')))
        self.ui.actionOpen_previous.setShortcut(_translate("Hitagi", self.settings.get('Hotkeys', 'Previous')))
        self.ui.actionChange_directory.setShortcut(_translate("Hitagi", self.settings.get('Hotkeys', 'Directory')))
        self.ui.actionAdd_to_favorites.setShortcut(_translate("Hitagi", self.settings.get('Hotkeys', 'Add to favorites')))
        self.ui.actionRemove_from_favorites.setShortcut(_translate("Hitagi", self.settings.get('Hotkeys', 'Remove from favorites')))
        self.ui.actionSlideshow.setShortcut(_translate("Hitagi", self.settings.get('Hotkeys', 'Slideshow')))

        self.ui.actionZoom_in.setShortcut(_translate("Hitagi", self.settings.get('Hotkeys', 'Zoom in')))
        self.ui.actionZoom_out.setShortcut(_translate("Hitagi", self.settings.get('Hotkeys', 'Zoom out')))
        self.ui.actionOriginal_size.setShortcut(_translate("Hitagi", self.settings.get('Hotkeys', 'Zoom original')))
        self.ui.actionRotate_clockwise.setShortcut(_translate("Hitagi", self.settings.get('Hotkeys', 'Rotate clockwise')))
        self.ui.actionRotate_counterclockwise.setShortcut(_translate("Hitagi", self.settings.get('Hotkeys', 'Rotate counterclockwise')))
        self.ui.actionFlip_horizontally.setShortcut(_translate("Hitagi", self.settings.get('Hotkeys', 'Flip horizontal')))
        self.ui.actionFlip_vertically.setShortcut(_translate("Hitagi", self.settings.get('Hotkeys', 'Flip vertical')))
        self.ui.actionFit_image_width.setShortcut(_translate("Hitagi", self.settings.get('Hotkeys', 'Fit to width')))
        self.ui.actionFit_image_height.setShortcut(_translate("Hitagi", self.settings.get('Hotkeys', 'Fit to height')))
        self.ui.actionFile_list.setShortcut(_translate("Hitagi", self.settings.get('Hotkeys', 'Toggle filelist')))
        self.ui.actionFullscreen.setShortcut(_translate("Hitagi", self.settings.get('Hotkeys', 'Fullscreen')))

        # Load favorites in UI
        self.load_favorites()

        # Background
        self.ui.graphicsView.setBackgroundBrush(QBrush(QColor(self.settings.get('Look', 'background')), Qt.SolidPattern))

        # Save current height for fullscreen mode
        self.default_menubar_height = self.ui.menubar.height()
        # Save current width for file list
        self.default_filelist_width = self.ui.fileWidget.width()

    def load_favorites(self):
        self.favorites = FavoritesModel()
        self.ui.menuFavorites.clear()
        for item in self.favorites.items():
            self.ui.menuFavorites.addAction(item).triggered.connect((lambda item: lambda: self.on_open_favorite(item))(item))

    def on_open_favorite(self, path):
        self.main_controller.change_directory(path)

    def center_ui(self):
        ui_geometry = self.frameGeometry()
        center_point = QDesktopWidget().availableGeometry().center()
        ui_geometry.moveCenter(center_point)
        self.move(ui_geometry.topLeft())

    # Qt show event
    def showEvent(self, event):
        self.main_controller.start(self.arguments['image_path']) # Arguments and starting behaviour

        # Start in fullscreen mode according to settings
        if self.settings.get('Misc', 'fullscreen_mode') == 'True':
            self.on_fullscreen()

        # Initialize container geometry to canvas
        self.canvas_controller.update(self.ui.graphicsView.width(), self.ui.graphicsView.height())
        self.main_controller.update_canvas()

    def update_resize_timer(self, interval=None):
        if self.resize_timer is not None:
            self.killTimer(self.resize_timer)
        if interval is not None:
            self.resize_timer = self.startTimer(interval)
        else:
            self.resize_timer = None

    # Qt resize event
    def resizeEvent(self, event):
        self.update_resize_timer(300)

    # Qt timer event
    def timerEvent(self, event):
        if event.timerId() == self.resize_timer:
            self.update_resize_timer()
            self.resizeCompleted.emit()

    def resize_completed(self):
        self.canvas_controller.update(self.ui.graphicsView.width(), self.ui.graphicsView.height())
        self.main_controller.update_canvas()

    # Additional static shortcuts
    def keyPressEvent(self, e):
        if e.key() == Qt.Key_Escape and self.model.is_fullscreen:
            self.main_controller.toggle_fullscreen()

    def on_open_parent(self):
        parent_index = self.file_model.parent(self.file_model.index(self.file_model.rootPath()))
        self.file_model.setRootPath(self.file_model.filePath(parent_index))
        self.ui.treeView.setRootIndex(parent_index)

        # Update directory path
        self.model.directory = self.file_model.filePath(parent_index)

        self.update_ui_from_model()

    def on_dir_list_activated(self, index):
        if self.file_model.isDir(index) is not False:
            self.file_model.setRootPath(self.file_model.filePath(index))
            self.ui.treeView.setRootIndex(index)

            # Save current path
            self.model.directory = self.file_model.filePath(index)
            self.update_ui_from_model()

    def on_dir_list_clicked(self, index):
        self.main_controller.open_image(self.file_model.filePath(index))

    # File menu
    def on_set_as_wallpaper(self):
        from hitagilib.view.WallpaperView import WallpaperDialog
        from hitagilib.controller.wallpaper import WallpaperController

        image = self.model.get_image()
        if image is not None:
            dialog = WallpaperDialog(self, None, WallpaperController(self.model), image)
            dialog.show()

    def on_clipboard(self):
        self.main_controller.copy_to_clipboard()

    def on_current_dir(self):
        if not self.main_controller.open_in_explorer():
            self.show_explorer_error()

    def on_options(self):
        from hitagilib.view.OptionsView import OptionDialog
        self.dialog = OptionDialog(self)
        self.dialog.show()

    def on_close(self):
        if self.slideshow.isRunning():
            self.slideshow.exit()
        self.close()

    # Folder menu
    def on_next_item(self):
        current_index = self.ui.treeView.currentIndex()

        # Slideshow restart - determine if we are at the end of our file list
        if self.slideshow.is_running and self.settings.get('Slideshow', 'restart') == 'True' and not self.ui.treeView.indexBelow(current_index).isValid():
            self.main_controller.open_image(self.file_model.filePath(current_index))
            self.on_slideshow_restart(0) # Restart slideshow
        elif self.slideshow.is_running and self.settings.get('Slideshow', 'random') == 'True':
            # Random index - moveCursor expects constants @http://doc.qt.io/qt-5/qabstractitemview.html#CursorAction-enum
            index = self.ui.treeView.moveCursor(randint(0,9), Qt.NoModifier)
            self.ui.treeView.setCurrentIndex(index)
            self.main_controller.open_image(self.file_model.filePath(index))
        else:
            # Proceed normally, scroll down
            index = self.ui.treeView.moveCursor(QAbstractItemView.MoveDown, Qt.NoModifier)
            self.ui.treeView.setCurrentIndex(index)
            self.main_controller.open_image(self.file_model.filePath(index))

    def on_previous_item(self):
        current_index = self.ui.treeView.currentIndex()

        # Slideshow restart (reverse) - determine if we are the the top of our file list
        if self.slideshow.is_running and self.settings.get('Slideshow', 'restart') == 'True' and not self.ui.treeView.indexAbove(current_index).isValid():
            self.main_controller.open_image(self.file_model.filePath(current_index))
            self.on_slideshow_restart(1) # Restart slideshow
        elif self.slideshow.is_running and self.settings.get('Slideshow', 'random') == 'True':
            # Random index
            index = self.ui.treeView.moveCursor(randint(0,9), Qt.NoModifier)
            self.ui.treeView.setCurrentIndex(index)
            self.main_controller.open_image(self.file_model.filePath(index))
        else:
            # Proceed normally, scroll up
            index = self.ui.treeView.moveCursor(QAbstractItemView.MoveUp, Qt.NoModifier)
            self.ui.treeView.setCurrentIndex(index)
            self.main_controller.open_image(self.file_model.filePath(index))

    def on_slideshow(self):
        if self.ui.actionSlideshow.isChecked():
            self.slideshow.start()
            self.slideshow.is_running = True
        else:
            self.slideshow.is_running = False
            self.slideshow.exit()

    def on_slideshow_restart(self, direction):
        # 0: Restart from top to bottom
        # 1: Restart from bottom to top
        if direction == 0:
            index = self.ui.treeView.moveCursor(QAbstractItemView.MoveHome, Qt.NoModifier)
            self.main_controller.open_image(self.file_model.filePath(index))
        else:
            index = self.ui.treeView.moveCursor(QAbstractItemView.MoveEnd, Qt.NoModifier)
            self.main_controller.open_image(self.file_model.filePath(index))

        self.ui.treeView.setCurrentIndex(index)

    def on_change_directory(self):
        self.main_controller.change_directory()

    # View menu
    def on_zoom_in(self):
        self.canvas_controller.scale_image(1.1)

    def on_zoom_out(self):
        self.canvas_controller.scale_image(0.9)

    def on_rotate_clockwise(self):
        self.canvas_controller.rotate_image(90)

    def on_rotate_counterclockwise(self):
        self.canvas_controller.rotate_image(-90)

    def on_flip_horizontal(self):
        self.canvas_controller.flip_image(0)

    def on_flip_vertical(self):
        self.canvas_controller.flip_image(1)

    def on_scale_image_to_width(self):
        self.canvas_controller.update_image(1)

    def on_scale_image_to_height(self):
        self.canvas_controller.update_image(2)

    def on_zoom_original(self):
        self.canvas_controller.update_image(3)

    def on_toggle_filelist(self):
        if self.ui.fileWidget.isHidden():
            self.ui.fileWidget.show()
        else:
            self.ui.fileWidget.hide()
        self.update_resize_timer(300)

    def on_fullscreen(self):
        self.main_controller.toggle_fullscreen()

        if self.model.is_fullscreen:
            self.showFullScreen()
            if self.settings.get('Misc', 'hide_menubar') == 'True':
                self.ui.menubar.setMaximumHeight(0) # Workaround to preserve shortcuts
        else:
            self.showNormal()
            if self.settings.get('Misc', 'hide_menubar') == 'True':
                self.ui.menubar.setMaximumHeight(self.default_menubar_height)
        self.canvas_controller.update(self.ui.graphicsView.width(), self.ui.graphicsView.height())
        self.main_controller.update_canvas()

    # Favorite button
    def on_manage_favorite(self):
        if self.main_controller.check_favorites(self.model.directory):
            self.on_remove_from_favorites()
        else:
            self.on_add_to_favorites()

    # Favorite menu
    def on_add_to_favorites(self):
        self.main_controller.add_to_favorites()
        self.load_favorites()
        self.update_ui_from_model()

    def on_remove_from_favorites(self):
        self.main_controller.remove_from_favorites()
        self.load_favorites()
        self.update_ui_from_model()

    # Help menu
    def on_changelog(self):
        webbrowser.open('https://github.com/gimu/hitagi-reader/releases')

    def on_about(self):
        from hitagilib.view.AboutView import AboutDialog
        dialog = AboutDialog(self, None, None)
        dialog.show()

    def on_fileWidget_visibilityChanged(self, visible):
        """On file list hide/show and de/attachment"""
        if visible:
            self.ui.actionFile_list.setChecked(True)
        else:
            self.ui.actionFile_list.setChecked(False)
        self.update_resize_timer(300)

    def show_explorer_error(self):
        notify = QMessageBox()
        notify.setWindowTitle("Error")
        notify.setText(QCoreApplication.translate('Hitagi', "Couldn't open the current directory with an appropriate filemanager!"))
        notify.exec_()

    def update_ui_from_model(self):
        """Update UI from model."""
        self.settings = SettingsModel()

        # On changing directory
        self.file_model.setRootPath(self.model.directory)
        self.ui.treeView.setRootIndex(self.file_model.index(self.model.directory))

        # Update favorite button
        if self.main_controller.check_favorites(self.model.directory):
            self.ui.pushButton_favorite.setText(QCoreApplication.translate('Hitagi', "Unfavorite"))
        else:
            self.ui.pushButton_favorite.setText(QCoreApplication.translate('Hitagi', "Favorite"))

        # Canvas update
        self.ui.graphicsView.setScene(self.canvas.scene)


text:
Windows 10 IoT Core sample code
===============

[Documentation for this sample](https://developer.microsoft.com/en-us/windows/iot/samples/arduino-wiring/arduinowiringcomponents)

This sample shows some of the power of being able to create WinRT libraries in an Arduino Wiring project and use those libraries from other UWP apps. In this case the Arduino Wiring app exposes basic APIs to control a 2-line LCD display. Arduino Wiring has built in libraries for these displays and so it is only a few lines of code, where as there is no existing UWP library for these and it would normally be hundreds of lines of code to duplicate in C# or your other language of choice.

By building a small WinRT library in this Arduino Wiring project a C# app is able to reference it and easily get access to the hardware. The code in the C# app is actually slightly smaller than in our C# headless blinky sample.

For full instructions on how to wire up the LCD display, see this sample: https://developer.microsoft.com/en-us/windows/iot/samples/arduino-wiring/lcdtextdisplay

## How to download:

Unfortunately, GitHub does not support downloading individual code.

Navigate to [ms-iot/samples](https://github.com/ms-iot/samples) and select **Clone or download** to download the whole repository.

## Additional resources
* [Windows 10 IoT Core home page](https://developer.microsoft.com/en-us/windows/iot/)
* [Documentation for all samples](https://developer.microsoft.com/en-us/windows/iot/samples)

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact opencode@microsoft.com with any additional questions or comments.

For general information and instructions for creating Arduino Wiring projects, see this page: https://developer.microsoft.com/en-us/windows/iot/win10/arduinowiringprojectguide


text:
<?xml version="1.0" encoding="utf-8"?>
<databaseChangeLog
    xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
    xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd
                        http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">

    <property name="now" value="now()" dbms="h2"/>

    <property name="now" value="now()" dbms="mysql"/>
    <property name="autoIncrement" value="true"/>

    <property name="floatType" value="float4" dbms="postgresql, h2"/>
    <property name="floatType" value="float" dbms="mysql, oracle, mssql"/>

    <!--
        Added the entity SonarInstance.
    -->
    <changeSet id="20180308115910-1" author="jhipster">
        <createTable tableName="sonar_instance">
            <column name="id" type="bigint" autoIncrement="${autoIncrement}">
                <constraints primaryKey="true" nullable="false"/>
            </column>
            <column name="sonar_instance_name" type="varchar(100)">
                <constraints nullable="false" />
            </column>

            <column name="sonar_instance_description" type="varchar(255)">
                <constraints nullable="true" />
            </column>

            <column name="sonar_instance_runner_path" type="varchar(255)">
                <constraints nullable="true" />
            </column>

            <column name="sonar_instance_enabled" type="bit">
                <constraints nullable="false" />
            </column>

            <!-- jhipster-needle-liquibase-add-column - JHipster will add columns here, do not remove-->
        </createTable>

    </changeSet>
    <!-- jhipster-needle-liquibase-add-changeset - JHipster will add changesets here, do not remove-->
</databaseChangeLog>


text:
package com.google.android.apps.common.testing.ui.espresso.action;

import static com.google.android.apps.common.testing.ui.espresso.matcher.ViewMatchers.isAssignableFrom;
import static com.google.android.apps.common.testing.ui.espresso.matcher.ViewMatchers.isDisplayed;
import static org.hamcrest.Matchers.allOf;

import com.google.android.apps.common.testing.ui.espresso.UiController;
import com.google.android.apps.common.testing.ui.espresso.ViewAction;

import android.view.View;
import android.widget.EditText;

import org.hamcrest.Matcher;

/**
 * Clears view text by setting {@link EditText}s text property to "".
 */
public final class ClearTextAction implements ViewAction {
  @SuppressWarnings("unchecked")
  @Override
  public Matcher<View> getConstraints() {
    return allOf(isDisplayed(), isAssignableFrom(EditText.class));
  }

  @Override
  public void perform(UiController uiController, View view) {
    ((EditText) view).setText("");
  }

  @Override
  public String getDescription() {
    return "clear text";
  }
}


text:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<TITLE>
BasicFactory
</TITLE>

<META NAME="date" CONTENT="2013-07-13">

<LINK REL ="stylesheet" TYPE="text/css" HREF="../../../../stylesheet.css" TITLE="Style">

      Overview
      Package
    Class
      Use
      Tree
      Deprecated
      Index
      Help

 PREV CLASS
 NEXT CLASS

  FRAMES
 NO FRAMES

  All Classes

  SUMMARY: NESTED | FIELD | CONSTR | METHOD

DETAIL: FIELD | CONSTR | METHOD

org.openflow.protocol.factory

Class BasicFactory

java.lang.Object
  org.openflow.protocol.factory.BasicFactory

All Implemented Interfaces:
OFActionFactory, OFMessageFactory, OFStatisticsFactory, OFVendorDataFactory

public class BasicFactory
extends java.lang.Object
implements OFMessageFactory, OFActionFactory, OFStatisticsFactory, OFVendorDataFactory

A basic OpenFlow factory that supports naive creation of both Messages and
 Actions.

Author:

David Erickson (daviderickson@cs.stanford.edu), Rob Sherwood (rob.sherwood@stanford.edu)

Constructor Summary

BasicFactory()

Method Summary

static java.lang.String
dumpBuffer(org.jboss.netty.buffer.ChannelBuffer data)

 OFAction
getAction(OFActionType t)

          Retrieves an OFAction instance corresponding to the specified
 OFActionType

 OFActionFactory
getActionFactory()

          Retrieves an OFActionFactory

 OFMessage
getMessage(OFType t)

          create and return a new instance of a message for OFType t.

 OFStatistics
getStatistics(OFType t,
              OFStatisticsType st)

          Retrieves an OFStatistics instance corresponding to the specified
 OFStatisticsType

 OFVendorData
getVendorData(OFVendorId vendorId,
              OFVendorDataType vendorDataType)

          Retrieves an OFVendorData instance corresponding to the specified
 OFVendorId and OFVendorDataType.

 java.util.List<OFAction>
parseActions(org.jboss.netty.buffer.ChannelBuffer data,
             int length)

          Attempts to parse and return all OFActions contained in the given
 ByteBuffer, beginning at the ByteBuffer's position, and ending at
 position+length.

 java.util.List<OFAction>
parseActions(org.jboss.netty.buffer.ChannelBuffer data,
             int length,
             int limit)

          Attempts to parse and return all OFActions contained in the given
 ByteBuffer, beginning at the ByteBuffer's position, and ending at
 position+length.

 java.util.List<OFMessage>
parseMessage(org.jboss.netty.buffer.ChannelBuffer data)

          Attempts to parse and return a OFMessages contained in the given
 ChannelBuffer, beginning at the ChannelBuffer's position, and ending at the
 after the first parsed message

 OFMessage
parseMessageOne(org.jboss.netty.buffer.ChannelBuffer data)

 java.util.List<OFStatistics>
parseStatistics(OFType t,
                OFStatisticsType st,
                org.jboss.netty.buffer.ChannelBuffer data,
                int length)

          Attempts to parse and return all OFStatistics contained in the given
 ByteBuffer, beginning at the ByteBuffer's position, and ending at
 position+length.

 java.util.List<OFStatistics>
parseStatistics(OFType t,
                OFStatisticsType st,
                org.jboss.netty.buffer.ChannelBuffer data,
                int length,
                int limit)

          Attempts to parse and return all OFStatistics contained in the given
 ByteBuffer, beginning at the ByteBuffer's position, and ending at
 position+length.

 OFVendorData
parseVendorData(int vendor,
                org.jboss.netty.buffer.ChannelBuffer data,
                int length)

          Attempts to parse and return the OFVendorData contained in the given
 ChannelBuffer, beginning right after the vendor id.

Methods inherited from class java.lang.Object

clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

Constructor Detail

BasicFactory

public BasicFactory()

Method Detail

getMessage

public OFMessage getMessage(OFType t)

create and return a new instance of a message for OFType t. Also injects
 factories for those message types that implement the *FactoryAware
 interfaces.

Specified by:
getMessage in interface OFMessageFactory

Parameters:
t - the type of the OFMessage to be retrieved

Returns:
a newly created instance that may be modified / used freely by
         the caller

parseMessage

public java.util.List<OFMessage> parseMessage(org.jboss.netty.buffer.ChannelBuffer data)
                                       throws MessageParseException

Description copied from interface: OFMessageFactory

Attempts to parse and return a OFMessages contained in the given
 ChannelBuffer, beginning at the ChannelBuffer's position, and ending at the
 after the first parsed message

Specified by:
parseMessage in interface OFMessageFactory

Parameters:
data - the ChannelBuffer to parse for an OpenFlow message

Returns:
a list of OFMessage instances

Throws:

MessageParseException

parseMessageOne

public OFMessage parseMessageOne(org.jboss.netty.buffer.ChannelBuffer data)
                          throws MessageParseException

Throws:

MessageParseException

getAction

public OFAction getAction(OFActionType t)

Description copied from interface: OFActionFactory

Retrieves an OFAction instance corresponding to the specified
 OFActionType

Specified by:
getAction in interface OFActionFactory

Parameters:
t - the type of the OFAction to be retrieved

Returns:
an OFAction instance

parseActions

public java.util.List<OFAction> parseActions(org.jboss.netty.buffer.ChannelBuffer data,
                                             int length)

Description copied from interface: OFActionFactory

Attempts to parse and return all OFActions contained in the given
 ByteBuffer, beginning at the ByteBuffer's position, and ending at
 position+length.

Specified by:
parseActions in interface OFActionFactory

Parameters:
data - the ChannelBuffer to parse for OpenFlow actions
length - the number of Bytes to examine for OpenFlow actions

Returns:
a list of OFAction instances

parseActions

public java.util.List<OFAction> parseActions(org.jboss.netty.buffer.ChannelBuffer data,
                                             int length,
                                             int limit)

Description copied from interface: OFActionFactory

Attempts to parse and return all OFActions contained in the given
 ByteBuffer, beginning at the ByteBuffer's position, and ending at
 position+length.

Specified by:
parseActions in interface OFActionFactory

Parameters:
data - the ChannelBuffer to parse for OpenFlow actions
length - the number of Bytes to examine for OpenFlow actions
limit - the maximum number of messages to return, 0 means no limit

Returns:
a list of OFAction instances

getActionFactory

public OFActionFactory getActionFactory()

Description copied from interface: OFMessageFactory

Retrieves an OFActionFactory

Specified by:
getActionFactory in interface OFMessageFactory

Returns:
an OFActionFactory

getStatistics

public OFStatistics getStatistics(OFType t,
                                  OFStatisticsType st)

Description copied from interface: OFStatisticsFactory

Retrieves an OFStatistics instance corresponding to the specified
 OFStatisticsType

Specified by:
getStatistics in interface OFStatisticsFactory

Parameters:
t - the type of the containing OFMessage, only accepts statistics
           request or reply
st - the type of the OFStatistics to be retrieved

Returns:
an OFStatistics instance

parseStatistics

public java.util.List<OFStatistics> parseStatistics(OFType t,
                                                    OFStatisticsType st,
                                                    org.jboss.netty.buffer.ChannelBuffer data,
                                                    int length)

Description copied from interface: OFStatisticsFactory

Attempts to parse and return all OFStatistics contained in the given
 ByteBuffer, beginning at the ByteBuffer's position, and ending at
 position+length.

Specified by:
parseStatistics in interface OFStatisticsFactory

Parameters:
t - the type of the containing OFMessage, only accepts statistics
           request or reply
st - the type of the OFStatistics to be retrieved
data - the ChannelBuffer to parse for OpenFlow Statistics
length - the number of Bytes to examine for OpenFlow Statistics

Returns:
a list of OFStatistics instances

parseStatistics

public java.util.List<OFStatistics> parseStatistics(OFType t,
                                                    OFStatisticsType st,
                                                    org.jboss.netty.buffer.ChannelBuffer data,
                                                    int length,
                                                    int limit)

Description copied from interface: OFStatisticsFactory

Attempts to parse and return all OFStatistics contained in the given
 ByteBuffer, beginning at the ByteBuffer's position, and ending at
 position+length.

Specified by:
parseStatistics in interface OFStatisticsFactory

Parameters:
t - OFMessage type: should be one of stats_request or stats_reply
st - statistics type of this message, e.g., DESC, TABLE
data - buffer to read from
length - length of statistics
limit - number of statistics to grab; 0 == all

Returns:
list of statistics

getVendorData

public OFVendorData getVendorData(OFVendorId vendorId,
                                  OFVendorDataType vendorDataType)

Description copied from interface: OFVendorDataFactory

Retrieves an OFVendorData instance corresponding to the specified
 OFVendorId and OFVendorDataType. There are 3 possible cases for
 how this will be called:

 1) If the vendor id in the OFVendor message is an unknown value,
    then this method is called with both vendorId and vendorDataType
    set to null. In this case typically the factory method should
    return an instance of OFGenericVendorData that just contains
    the raw byte array of the vendor data.

 2) If the vendor id is known but no vendor data type has been
    registered for the data in the message, then vendorId is set to
    the appropriate OFVendorId instance and OFVendorDataType is set
    to null. This would typically be handled the same way as #1

 3) If both the vendor id and and vendor data type are known, then
    typically you'd just call the method in OFVendorDataType to
    instantiate the appropriate subclass of OFVendorData.

Specified by:
getVendorData in interface OFVendorDataFactory

Parameters:
vendorId - the vendorId of the containing OFVendor message
vendorDataType - the type of the OFVendorData to be retrieved

Returns:
an OFVendorData instance

parseVendorData

public OFVendorData parseVendorData(int vendor,
                                    org.jboss.netty.buffer.ChannelBuffer data,
                                    int length)

Attempts to parse and return the OFVendorData contained in the given
 ChannelBuffer, beginning right after the vendor id.

Specified by:
parseVendorData in interface OFVendorDataFactory

Parameters:
vendor - the vendor id that was parsed from the OFVendor message.
data - the ChannelBuffer from which to parse the vendor data
length - the length to the end of the enclosing message.

Returns:
an OFVendorData instance

dumpBuffer

public static java.lang.String dumpBuffer(org.jboss.netty.buffer.ChannelBuffer data)

      Overview
      Package
    Class
      Use
      Tree
      Deprecated
      Index
      Help

 PREV CLASS
 NEXT CLASS

  FRAMES
 NO FRAMES

  All Classes

  SUMMARY: NESTED | FIELD | CONSTR | METHOD

DETAIL: FIELD | CONSTR | METHOD


text:
ACCEPTED

#### According to
Index Fungorum

#### Published in
in Bi, Loh & Zheng, Acta bot. Yunn. 4(1): 58 (1982)

#### Original name
Boletus puellaris C.S. Bi & Loh

### Remarks
null