GeopackWrapper.hh 4.69 KB
#include "geopack.hh"


namespace AMDA {
namespace Parameters {
namespace Tsyganenko96 {
namespace geopack {
   
#define LMAX_VAL 2000
 
class GeopackWrapper {
public:
    

    static void initInGSM(int iyr, int iday, int ihour, int min, int isec) {
        // We use GSM coordinate frames
        float v_default_x = -400.0;
        float v_default_y = 0.0;
        float v_default_z = 0.0;
        
        recalc_08_(&iyr, &iday, &ihour, &min, &isec, &v_default_x, &v_default_y, &v_default_z);
    }
    
    static bool isInMagnetopause(float Pdyn_i, float sat_pos_X_GSM, float sat_pos_Y_GSM, float sat_pos_Z_GSM) {
        // We use dynamic pressure Pdyn
        float vel_mgnp = -1.0;
        
        float x_mgnp = 0.;
        float y_mgnp = 0.;
        float z_mgnp = 0.;
        float DIST_MGNP = 0.;
        int ID_MGNP = 0;
        
        t96_mgnp_08_(&Pdyn_i, &vel_mgnp, &sat_pos_X_GSM, &sat_pos_Y_GSM, &sat_pos_Z_GSM,
            &x_mgnp, &y_mgnp, &z_mgnp, &DIST_MGNP, &ID_MGNP);
            
        return (ID_MGNP == 1);
    }

    static bool computeGeomagneticFieldInGSM(float sat_pos_X_GSM, float sat_pos_Y_GSM, float sat_pos_Z_GSM,
        float Pdyn, float Dst, float B_Y_GSM, float B_Z_GSM,
	float &B_X_GSM_RES, float& B_Y_GSM_RES, float& B_Z_GSM_RES) {

	// COMPUTES T96 GEOMAGNETIC FIELD MODEL
	int IOPT = 0;
	float PARMOD[10];
	memset(PARMOD, 0, 10 * sizeof(float));
	PARMOD[0] = Pdyn;
	PARMOD[1] = Dst;
	PARMOD[2] = B_Y_GSM;
	PARMOD[3] = B_Z_GSM;

	float BX = 0;
	float BY = 0;
	float BZ = 0;
	t96_01_modified_(&IOPT, PARMOD, &sat_pos_X_GSM, &sat_pos_Y_GSM,
            &sat_pos_Z_GSM, &BX, &BY, &BZ);

	// COMPUTES GEODIPOLE MAGNETIC field
	float HX = 0.;
	float HY = 0.;
	float HZ = 0.;
	igrf_gsw_08_(&sat_pos_X_GSM, &sat_pos_Y_GSM, &sat_pos_Z_GSM, &HX, &HY, &HZ);

	B_X_GSM_RES = BX + HX;
	B_Y_GSM_RES = BY + HY;
	B_Z_GSM_RES = BZ + HZ;

	return true;
    }
    
    static bool computeGeomagneticFieldInGSE(float sat_pos_X_GSM, float sat_pos_Y_GSM, float sat_pos_Z_GSM,
        float Pdyn, float Dst, float B_Y_GSM, float B_Z_GSM,
        float &B_X_GSE_RES, float& B_Y_GSE_RES, float& B_Z_GSE_RES) {
	float B_X_GSM_RES, B_Y_GSM_RES, B_Z_GSM_RES;
	// COMPUTE GEOMAGNETIC FIELD IN GSM
	if (!GeopackWrapper::computeGeomagneticFieldInGSM(sat_pos_X_GSM, sat_pos_Y_GSM, sat_pos_Z_GSM, Pdyn, Dst, B_Y_GSM, B_Z_GSM, B_X_GSM_RES, B_Y_GSM_RES, B_Z_GSM_RES)) {
		return false;
	}
	// APPLY TRANSFORMATION FROM GSM TO GSE
	int transform_flag = 1;
        gswgse_08_(&B_X_GSM_RES, &B_Y_GSM_RES, &B_Z_GSM_RES , &B_X_GSE_RES, &B_Y_GSE_RES, &B_Z_GSE_RES, &transform_flag);
	return true;
    }


    static bool computeFootprint(bool south, float altitude, float sat_pos_X_GSM, float sat_pos_Y_GSM, float sat_pos_Z_GSM,
        float Pdyn, float Dst, float B_Y_GSM, float B_Z_GSM, float& FP_X_GSM, float& FP_Y_GSM, float& FP_Z_GSM) {
            
        float DIR = south ? 1.0 : -1.0;
        float DSMAX = 0.5;     // Upper limit of the stepsize
        float ERR   = 0.0001;  // Permissible step error
        float RLIM  = 50.0;    // Outter boundary radii
        float R0    = 1. + altitude;  // Inner boundary radii
        int   IOPT  = 0;       // Model index
        
        float PARMOD[10];
        memset(PARMOD, 0, 10 * sizeof(float));
        PARMOD[0] = Pdyn;
        PARMOD[1] = Dst;
        PARMOD[2] = B_Y_GSM;
        PARMOD[3] = B_Z_GSM;
        
        int LMAX = LMAX_VAL;
        
        float XX[LMAX_VAL];
        float YY[LMAX_VAL];
        float ZZ[LMAX_VAL];
        
        memset(XX, 0, LMAX * sizeof(float));
        memset(YY, 0, LMAX * sizeof(float));
        memset(ZZ, 0, LMAX * sizeof(float));
        
        int L = 0;
        
        trace_08_modified_(&sat_pos_X_GSM, &sat_pos_Y_GSM, &sat_pos_Z_GSM, &DIR,
            &DSMAX, &ERR, &RLIM, &R0, &IOPT, PARMOD, 
            &FP_X_GSM, &FP_Y_GSM, &FP_Z_GSM, XX, YY, ZZ, &L, &LMAX);
            
        return true;
    }
    
    static void toRLatLong(float FP_X_GSM, float FP_Y_GSM, float FP_Z_GSM, float& r, float& lat, float& lon) {
        int transform_flag = -1;
        
        float FP_GEO_X_i = 0.;
        float FP_GEO_Y_i = 0.;
        float FP_GEO_Z_i = 0.;
    
        geogsw_08_(&FP_GEO_X_i, &FP_GEO_Y_i, &FP_GEO_Z_i, 
                  &FP_X_GSM, &FP_Y_GSM, &FP_Z_GSM, 
                  &transform_flag);
                  
        float SQ = 0.;
        SQ=FP_GEO_X_i*FP_GEO_X_i + FP_GEO_Y_i*FP_GEO_Y_i;
        r=sqrt(SQ+FP_GEO_Z_i*FP_GEO_Z_i);
        SQ=sqrt(SQ);
        lon=atan2(FP_GEO_Y_i, FP_GEO_X_i);
        lat=atan2(FP_GEO_Z_i, SQ);
      
        if (lon < 0.) 
        {
            lon += 2.*M_PI;
        }
        
        lon *= (180./M_PI);
        lat *= (180./M_PI);
    }
};

} /* geopack */
} /* Tsyganenko96 */
} /* Parameters */
} /* AMDA */