Proposed new field for transmitter - type

Hello all,

I think given the amount of information around transmitters we hold , we should amend the current transmitter model in our DB to add a field that would store the transmitter type. Options should be:

  • Transmitter (in UI we display only downlink_low field as Downlink)
  • Transceiver (in UI we display only downlink_low and uplink_low as Downlink and Uplink)
  • Transponder (in UI we display all fields, downlink_low downlink_high uplink_low uplink high)

Also while we are at it @cshields do you think we should add a file-field to store kaitai struct type ?

Another addition should be to have an intended and observed distinction for all 4 frequencies. In order not to break compatibility with existing usages of our DB we should add 4 frequency fields (down low/high, up low/high) for “published” (vs observed) frequencies. Thus we will be eliminating a lot of “drifted” transmitter entries.

One issue with the drifted transmitters is that currently on network we don’t save separately the observed frequency but we connect the observation with the transmitter.

This means that if we schedule observation with a transmitter at 145.800 MHz and in the future we change this to 145.850MHz, then the first ones will show falsely that the observation happened at 145.850MHz instead of the real frequency at 145.800MHz.

For that reason we should store in the observation the snapshot of the transmitter data (along with the foreign key to the transmitter)

1 Like

Looks good and good idea with the published vs. observed frequency.

How do transponders work during observations? Do we tune to the center or one of the edges?

No need as we will use the Telemetry model to store these. Good call though!

For transmitters and transceivers a match of {downlink,uplink}_low and {downlink,uplink}_high frequencies (instead of _high just being NULL) would better indicate a zero transponder bandwidth.

I think it would be better if we store the drift instead of the frequencies. A zero drift would then be the default.

How do we all feel about this diff then?

diff --git a/db/base/models.py b/db/base/models.py
index 6565cd5..48a65ba 100644
--- a/db/base/models.py
+++ b/db/base/models.py
@@ -15,6 +15,7 @@ from db.base.helpers import gridsquare
 
 DATA_SOURCES = ['manual', 'network', 'sids']
 SATELLITE_STATUS = ['alive', 'dead', 're-entered']
+TRANSMITTER_TYPE = ['transmitter', 'transceiver', 'transponder']
 
 
 def _name_payload_frame(instance, filename):
@@ -107,10 +108,16 @@ class Transmitter(models.Model):
     uuid = ShortUUIDField(db_index=True, unique=True)
     description = models.TextField()
     alive = models.BooleanField(default=True)
-    uplink_low = models.PositiveIntegerField(blank=True, null=True)
-    uplink_high = models.PositiveIntegerField(blank=True, null=True)
-    downlink_low = models.PositiveIntegerField(blank=True, null=True)
-    downlink_high = models.PositiveIntegerField(blank=True, null=True)
+    type = models.CharField(choices=zip(TRANSMITTER_TYPE, TRANSMITTER_TYPE),
+                            max_length=11, default='transmitter')
+    uplink_low = models.BigIntegerField(blank=True, null=True)
+    uplink_low_drift = models.IntegerField(blank=True, null=True)
+    uplink_high = models.BigIntegerField(blank=True, null=True)
+    uplink_high_drift = models.IntegerField(blank=True, null=True)
+    downlink_low = models.BigIntegerField(blank=True, null=True)
+    downlink_low_drift = models.IntegerField(blank=True, null=True)
+    downlink_high = models.BigIntegerField(blank=True, null=True)
+    downlink_high_drift = models.IntegerField(blank=True, null=True)
     mode = models.ForeignKey(Mode, blank=True, null=True,
                              on_delete=models.SET_NULL, related_name='transmitters')
     invert = models.BooleanField(default=False)

I would think it is unnecessary to have both low_drift and high_drift as they will follow each other. @Acinonyx’s suggestion to store up_drift and down_drift sounds good.

Really good point @csete . New diff based on your suggestions:

diff --git a/db/base/models.py b/db/base/models.py
index 8edfd7e..4225cd5 100644
--- a/db/base/models.py
+++ b/db/base/models.py
@@ -15,6 +15,7 @@ from db.base.helpers import gridsquare
 
 DATA_SOURCES = ['manual', 'network', 'sids']
 SATELLITE_STATUS = ['alive', 'dead', 're-entered']
+TRANSMITTER_TYPE = ['transmitter', 'transceiver', 'transponder']
 
 
 def _name_payload_frame(instance, filename):
@@ -108,10 +109,14 @@ class Transmitter(models.Model):
     uuid = ShortUUIDField(db_index=True, unique=True)
     description = models.TextField()
     alive = models.BooleanField(default=True)
-    uplink_low = models.PositiveIntegerField(blank=True, null=True)
-    uplink_high = models.PositiveIntegerField(blank=True, null=True)
-    downlink_low = models.PositiveIntegerField(blank=True, null=True)
-    downlink_high = models.PositiveIntegerField(blank=True, null=True)
+    type = models.CharField(choices=zip(TRANSMITTER_TYPE, TRANSMITTER_TYPE),
+                            max_length=11, default='transmitter')
+    uplink_low = models.BigIntegerField(blank=True, null=True)
+    uplink_high = models.BigIntegerField(blank=True, null=True)
+    uplink_drift = models.IntegerField(blank=True, null=True)
+    downlink_low = models.BigIntegerField(blank=True, null=True)
+    downlink_high = models.BigIntegerField(blank=True, null=True)
+    downlink_drift = models.IntegerField(blank=True, null=True)
     mode = models.ForeignKey(Mode, blank=True, null=True,
                              on_delete=models.SET_NULL, related_name='transmitters')
     invert = models.BooleanField(default=False)

How about storing the drifting history? It could be extremely useful and perhaps interesting correlations may come up!

Every drift update could be stored with the corresponding date. For the observations the latest drift should be taken into consideration.

1 Like

IMHO, there is no point in using the drift history parameter for any correlation. This is a value suggested by the user for future observations and does not necessarily match the actual drift observed. If we want to keep records of the actual drift, that should be an attribute related to the observations and not the transmitter (which just provides input for it).

It is useful though, to have logs of edits for the whole transmitter object to be able to revert errors or check when somethings changes from administrative point of view.

I can find at least 4-5 uses cases which such information may used for scientific research. Do we want the SatNOGS DB to be the source for such cases? If yes, we should start to think about possible such cases.

User suggestion does not mean acceptance right? What is the process currently for accepting a drifting suggestion? Even if the user observed a drift, we cannot take it for sure (old TLE, mis-configured SDR, etc)

Now regarding the low and high frequency, I think that is a bit odd such naming. Which is the actual carrier frequency? (up - low)/2.0 ?
The most common AFAIK is the (center frequency, bandwidth) scheme.

I just wanted to mention that there are linear transponders, too. At the moment there is not much use case to observe a linear transponder, but might be considerable with birds like Es’hail-2.

@surligas historicity of frequencies will be derived by checking the past artifacts (since observed freq is one of their attribute). No need to track this in our model since this should be coming from actual observations done (and also vetting of them).

Can you expand on that a bit? How would that affect the proposed model changes?

Hm, it was more about (high - low) / 2 for the carrier. There might be several “carriers” on a linear transponder.