Use of MagneticFieldDetector

Hello everyone !
I am trying to use the EventDetector MagneticFieldDetector, to detect the frontier crossing of the south atlantic anomaly.
But, the MagneticFieldDetector does not return any events… I tested with different limit values and still nothing.
I have also no idea what to put in the limit parameter, in the documentation, it says:
limit - the threshold value of magnetic field at see level, ok but what is the unit?

Here is my code:

    def __init__(self):
        self.earth = OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS, 0.0, FramesFactory.getITRF(IERSConventions.IERS_2010, True))
        self.magnetic_model = GeoMagneticFieldFactory.FieldModel.WMM
        self.maxcheck = 60.0
        self.threshold = 0.1
        self.limit = 1.0

    def getVisibility(self, initial_date, duration, orbit):
        propagator = EcksteinHechlerPropagator(orbit,
                                               Constants.EIGEN5C_EARTH_EQUATORIAL_RADIUS,
                                               Constants.EIGEN5C_EARTH_MU,
                                               Constants.EIGEN5C_EARTH_C20,
                                               Constants.EIGEN5C_EARTH_C30,
                                               Constants.EIGEN5C_EARTH_C40,
                                               Constants.EIGEN5C_EARTH_C50,
                                               Constants.EIGEN5C_EARTH_C60)

        magnetic_detector = MagneticFieldDetector(self.maxcheck, self.threshold, self.limit, GeoMagneticFieldFactory.FieldModel.WMM, self.earth, True).withHandler(ContinueOnEvent())

        logger = EventsLogger()
        logged_detector = logger.monitorDetector(magnetic_detector)

        propagator.addEventDetector(logged_detector)
        state = propagator.propagate(initial_date, initial_date.shiftedBy(3600.0 * 24 * duration))
        state.getDate()

        events = logger.getLoggedEvents()
        events.size()

        start_time = None
        result = pd.DataFrame()

        for event in logger.getLoggedEvents():
            if event.isIncreasing():
                start_time = event.getState().getDate()
            elif start_time:
                stop_time = event.getState().getDate()
                result = result.append({"Start":absolutedate_to_datetime(start_time),
                                        "Stop":absolutedate_to_datetime(stop_time),
                                        "VisibilityDuration": stop_time.durationFrom(start_time)/60},
                                       ignore_index=True)
                start_time = None
        print(result)

an idea?

Thank you!

Hello @stronaut,

Welcome to the Orekit community !

The magnetic field is in SI units, soTesla. As a general rule (and unless stated otherwise), all units in Orekit are SI units.

If you think the unit should be added in the Javadoc for the limit parameter, please open an issue on the Orekit forge.

In your case, you should probably start with trying the limit of 32000nT at sea level for the SAA (see wikipedia/South Atlantic Anomaly).

Hope this helps,
Maxime

1 Like

Thank you @MaximeJ for the precisions.

I just checked with this value (32000nT), and still no event detection.
Maybe I use an incorrect model WMM.COF, but I just download it from the NOAA website (2020. version). And I don’t have any error on that…

ra = 500 * 1000         #  Apogee
rp = 400 * 1000         #  Perigee
i = radians(87.0)      # inclination
omega = radians(20.0)   # perigee argument
raan = radians(10.0)  # right ascension of ascending node
lv = radians(0.0)    # True anomaly

epochDate = AbsoluteDate(2020, 1, 1, 0, 0, 00.000, utc)
initial_date = epochDate

a = (rp + ra + 2 * Constants.WGS84_EARTH_EQUATORIAL_RADIUS) / 2.0
e = 1.0 - (rp + Constants.WGS84_EARTH_EQUATORIAL_RADIUS) / a

## Inertial frame where the satellite is defined
inertialFrame = FramesFactory.getEME2000()

## Orbit construction as Keplerian
initialOrbit = KeplerianOrbit(a, e, i, omega, raan, lv,
                              PositionAngle.TRUE,
                              inertialFrame, epochDate, Constants.WGS84_EARTH_MU)
propagator = KeplerianPropagator(initialOrbit)

ITRF = FramesFactory.getITRF(IERSConventions.IERS_2010, True)
earth = OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
                         Constants.WGS84_EARTH_FLATTENING,
                         ITRF)
mag_detector = MagneticFieldDetector(60.0, 0.1, 32000.0E-9, GeoMagneticFieldFactory.FieldModel.WMM, earth, True).withHandler(ContinueOnEvent())
logger = EventsLogger()
logged_detector = logger.monitorDetector(mag_detector)
propagator.addEventDetector(logged_detector)
state = propagator.propagate(initial_date, initial_date.shiftedBy(3600.0 * 24))
print(state.getDate())
events = logger.getLoggedEvents()
print(events.size())
start_time = None
result = pd.DataFrame()

for event in logger.getLoggedEvents():

    if event.isIncreasing():
        start_time = event.getState().getDate()
    elif start_time:
        stop_time = event.getState().getDate()
        result = result.append({"Start":absolutedate_to_datetime(start_time),
                                "Stop":absolutedate_to_datetime(stop_time),
                                "VisibilityDuration": stop_time.durationFrom(start_time)/60},
                               ignore_index=True)
        start_time = None
print(result)

Hi @stronaut,

My bad… I just realized the magnetic field limit in the MagneticFieldDetector must be set in nT (not just T).

Could you please open an issue on the Orekit Gitlab Issue Tracker so we don’t forget to fix the Javadoc for the next version ?

Using the value of 32000nT I found the following results with your example and the IGRF model:

                        Start                       Stop  VisibilityDuration
0  2020-01-01 01:29:41.886065 2020-01-01 02:58:47.283929           89.089964
1  2020-01-01 03:03:45.837592 2020-01-01 03:51:25.985726           47.669136
2  2020-01-01 04:02:10.697761 2020-01-01 05:24:03.299210           81.876691
3  2020-01-01 05:38:27.607447 2020-01-01 06:52:58.391158           74.513062
4  2020-01-01 07:12:30.454307 2020-01-01 08:25:31.196982           73.012378
5  2020-01-01 08:45:40.022674 2020-01-01 10:00:09.190739           74.486134
6  2020-01-01 10:18:11.867368 2020-01-01 11:35:05.097196           76.887164
7  2020-01-01 11:49:18.890247 2020-01-01 13:08:56.187757           79.621625
8  2020-01-01 13:17:43.813413 2020-01-01 14:42:04.819618           84.350103
9  2020-01-01 14:47:40.183100 2020-01-01 15:18:36.511697           30.938810
10 2020-01-01 15:26:58.232415 2020-01-01 16:15:32.993162           48.579346
11 2020-01-01 16:17:17.211727 2020-01-01 16:48:30.016659           31.213416
12 2020-01-01 17:02:17.270035 2020-01-01 18:21:34.819065           79.292484
13 2020-01-01 18:40:14.030781 2020-01-01 19:55:33.749106           75.328639
14 2020-01-01 20:15:15.668560 2020-01-01 21:30:05.977034           74.838475
15 2020-01-01 21:48:04.995943 2020-01-01 23:05:43.146098           77.635836

Sorry again for my first misleading answer.

Maxime

I think that instead of just changing the Javadoc, we should also change the unit in
order to be consistent with other choices in Orekit: i.e. to use SI units only.

This is an incompatible change (change a value by a factor 1billion), so it cannot be done before version 12.0.

Changing just the Javadoc could be done in the 11.X series, but perhaps adding a warning this unit will change.

I agree with you luc

Hello @MaximeJ, Yes it is working now, thank you.
I’ll report the issue.

Have a nice day