Repository: obspy/obspy

Issue:
obspy couldn't find a station in IRIS DMC
Hi
I use the latest obspy under python 3.6.0 and CentOS 6.9 x64:
```
$ python --version
Python 3.6.0 :: Anaconda custom (64-bit)
$ lsb_release -a
LSB Version:	:base-4.0-amd64:base-4.0-noarch:core-4.0-amd64:core-4.0-noarch
Distributor ID:	CentOS
Description:	CentOS release 6.9 (Final)
Release:	6.9
Codename:	Final
```

I try to download waveform of DK.DY2G using following python script:
```
import obspy
from obspy.clients.fdsn.mass_downloader import RectangularDomain, \
    Restrictions, MassDownloader
import os

domain = RectangularDomain(minlatitude=60, maxlatitude=80,
                           minlongitude=-75, maxlongitude=-15)

restrictions = Restrictions(
    
    starttime=obspy.UTCDateTime(2012, 1, 1, 0, 0, 0),
    endtime=obspy.UTCDateTime(2012, 2, 1, 0, 0, 0),
    
    network="DK", channel="BHZ", station="DY2G", location="01",
    reject_channels_with_gaps=False,
    sanitize=True,
    minimum_length=0.0,
    minimum_interstation_distance_in_m=100.0)

mdl = MassDownloader(providers=["IRIS"])
def get_mseed_storage(network, station, location, channel, starttime, endtime):
    return os.path.join("waveforms/", "%s.%s.%s.%s.mseed" % (network, station, location, channel))
mseed_storage = get_mseed_storage
tt = mdl.download(domain, restrictions, mseed_storage, stationxml_storage="stations")
```
However, obspy couldn't find this station:
```
[2017-12-24 20:16:01,445] - obspy.clients.fdsn.mass_downloader - INFO: Initializing FDSN client(s) for IRIS.
[2017-12-24 20:16:07,360] - obspy.clients.fdsn.mass_downloader - INFO: Successfully initialized 1 client(s): IRIS.
[2017-12-24 20:16:07,360] - obspy.clients.fdsn.mass_downloader - INFO: Total acquired or preexisting stations: 0
[2017-12-24 20:16:07,360] - obspy.clients.fdsn.mass_downloader - INFO: Client 'IRIS' - Requesting reliable availability.
[2017-12-24 20:16:07,975] - obspy.clients.fdsn.mass_downloader - INFO: Client 'IRIS' - Successfully requested availability (0.61 seconds)
[2017-12-24 20:16:07,976] - obspy.clients.fdsn.mass_downloader - INFO: Client 'IRIS' - Found 0 stations (0 channels).
[2017-12-24 20:16:07,977] - obspy.clients.fdsn.mass_downloader - INFO: Client 'IRIS' - No data available.
[2017-12-24 20:16:07,977] - obspy.clients.fdsn.mass_downloader - INFO: ============================== Final report
[2017-12-24 20:16:07,977] - obspy.clients.fdsn.mass_downloader - INFO: 0 MiniSEED files [0.0 MB] already existed.
[2017-12-24 20:16:07,977] - obspy.clients.fdsn.mass_downloader - INFO: 0 StationXML files [0.0 MB] already existed.
[2017-12-24 20:16:07,977] - obspy.clients.fdsn.mass_downloader - INFO: Client 'IRIS' - Acquired 0 MiniSEED files [0.0 MB].
[2017-12-24 20:16:07,977] - obspy.clients.fdsn.mass_downloader - INFO: Client 'IRIS' - Acquired 0 StationXML files [0.0 MB].
[2017-12-24 20:16:07,977] - obspy.clients.fdsn.mass_downloader - INFO: Downloaded 0.0 MB in tota
```
But the data of this station exist and are available in IRIS DMC:
[http://ds.iris.edu/mda/DK/DY2G/01/BHZ?timewindow=2011/05/19%2000:00:00-2012/06/07%2022:59:59](http://ds.iris.edu/mda/DK/DY2G/01/BHZ?timewindow=2011/05/19%2000:00:00-2012/06/07%2022:59:59)

I think it may be a bug of obspy. Could you please check it and fix if possible. Thanks.


Discussion:
Indeed, this looks like a bug. It seems the default ``location_priorities`` are still used although the ``Restrictions().location`` is defined, which results in an empty ``filtered_channels`` list at this line 

https://github.com/obspy/obspy/blob/master/obspy/clients/fdsn/mass_downloader/download_helpers.py#L1190

a workaround for you now is to add the:

```python
location_priorities=["01",],
```
to your ``Restrictions`` object.
Thanks for reporting!

Adding to Thomas: Another incarnation of this bug is described in #1810. A fix is prepared in #2028.
👍 Thanks !   Yesterday I found my mass_downloader script cannot download the waveform data of "DPZ" channel(such as 1B networks). 
With the similar solution, I add the code :
`channel_priorities=("DPZ",)` in my script ! It works now! 

Resolving patch:
diff --git a/obspy/clients/fdsn/mass_downloader/download_helpers.py b/obspy/clients/fdsn/mass_downloader/download_helpers.py
--- a/obspy/clients/fdsn/mass_downloader/download_helpers.py
+++ b/obspy/clients/fdsn/mass_downloader/download_helpers.py
@@ -1173,25 +1173,27 @@ def get_availability(self):
                         location=channel.location_code, channel=channel.code,
                         intervals=copy.deepcopy(intervals)))
 
-                # Group by locations and apply the channel priority filter to
-                # each.
-                filtered_channels = []
-
-                def get_loc(x):
-                    return x.location
-
-                for location, _channels in itertools.groupby(
-                        sorted(channels, key=get_loc), get_loc):
-                    filtered_channels.extend(utils.filter_channel_priority(
-                        list(_channels), key="channel",
-                        priorities=self.restrictions.channel_priorities))
-                channels = filtered_channels
-
-                # Filter to remove unwanted locations according to the priority
-                # list.
-                channels = utils.filter_channel_priority(
-                    channels, key="location",
-                    priorities=self.restrictions.location_priorities)
+                if self.restrictions.channel is None:
+                    # Group by locations and apply the channel priority filter
+                    # to each.
+                    filtered_channels = []
+
+                    def get_loc(x):
+                        return x.location
+
+                    for location, _channels in itertools.groupby(
+                            sorted(channels, key=get_loc), get_loc):
+                        filtered_channels.extend(utils.filter_channel_priority(
+                            list(_channels), key="channel",
+                            priorities=self.restrictions.channel_priorities))
+                    channels = filtered_channels
+
+                if self.restrictions.location is None:
+                    # Filter to remove unwanted locations according to the
+                    # priority list.
+                    channels = utils.filter_channel_priority(
+                        channels, key="location",
+                        priorities=self.restrictions.location_priorities)
 
                 if not channels:
                     continue


Test patch:
diff --git a/obspy/clients/fdsn/tests/data/uncommon_channel_location.txt b/obspy/clients/fdsn/tests/data/uncommon_channel_location.txt
new file mode 100644
--- /dev/null
+++ b/obspy/clients/fdsn/tests/data/uncommon_channel_location.txt
@@ -0,0 +1,5 @@
+#Network | Station | Location | Channel | Latitude | Longitude | Elevation | Depth | Azimuth | Dip | SensorDescription | Scale | ScaleFreq | ScaleUnits |  SampleRate | StartTime | EndTime
+AK|BAGLA|31|RST|60.4896|-142.0915|1470.0|0.0|0.0|-90.0|Nanometrics Trillium 240 Sec Response sn 400 and a|4.88233E8|0.02|M/S|1.0|2013-01-01T00:00:00|2599-12-31T23:59:59
+AK|BAGLB||RST|60.4896|-142.0915|1470.0|0.0|0.0|-90.0|Nanometrics Trillium 240 Sec Response sn 400 and a|4.88233E8|0.02|M/S|1.0|2013-01-01T00:00:00|2599-12-31T23:59:59
+AK|BAGLC|31|EHE|60.4896|-142.0915|1470.0|0.0|0.0|-90.0|Nanometrics Trillium 240 Sec Response sn 400 and a|4.88233E8|0.02|M/S|1.0|2013-01-01T00:00:00|2599-12-31T23:59:59
+AK|BAGLD||EHE|60.4896|-142.0915|1470.0|0.0|0.0|-90.0|Nanometrics Trillium 240 Sec Response sn 400 and a|4.88233E8|0.02|M/S|1.0|2013-01-01T00:00:00|2599-12-31T23:59:59
diff --git a/obspy/clients/fdsn/tests/test_mass_downloader.py b/obspy/clients/fdsn/tests/test_mass_downloader.py
--- a/obspy/clients/fdsn/tests/test_mass_downloader.py
+++ b/obspy/clients/fdsn/tests/test_mass_downloader.py
@@ -2351,6 +2351,76 @@ def test_excluding_networks_and_stations(self):
         self.assertEqual([("AK", "BAGL")],
                          sorted(c.stations.keys()))
 
+        # When 'channel' or 'location' are set they should override
+        # 'channel_priorities' and 'location_priorities'. If this isn't
+        # happening this test will fail, as we're requesting data
+        # with a channel and location what are not covered by the default
+        # priorities lists.
+        #
+        # The tests are a bit strange in the way that the availability
+        # filtering does not enforce the set "location" + "channel" but only
+        # the priority lists. Location + channel are already set at the queries
+        # to the datacenters so they can be assumed to be correct.
+        #
+        # The availability information contains uncommon channel + location
+        # combinations and only one station will be selected first.
+        self.restrictions = Restrictions(
+            starttime=obspy.UTCDateTime(2001, 1, 1),
+            endtime=obspy.UTCDateTime(2015, 1, 1),
+            # This will be ignored as soon as channel and location are being
+            # set.
+            channel_priorities=["EH*", "BH*"],
+            location_priorities=["", "01"])
+        c = self._init_client()
+        c.client.get_stations.return_value = obspy.read_inventory(
+            os.path.join(self.data, "uncommon_channel_location.txt"))
+        c.get_availability()
+        self.assertEqual([("AK", "BAGLD")], sorted(c.stations.keys()))
+
+        # With a set location, the channel priorities are still active.
+        self.restrictions = Restrictions(
+            starttime=obspy.UTCDateTime(2001, 1, 1),
+            endtime=obspy.UTCDateTime(2015, 1, 1),
+            channel_priorities=["EH*", "BH*"],
+            location_priorities=["", "01"],
+            location="31")
+        c = self._init_client()
+        c.client.get_stations.return_value = obspy.read_inventory(
+            os.path.join(self.data, "uncommon_channel_location.txt"))
+        c.get_availability()
+        self.assertEqual([("AK", "BAGLC"), ("AK", "BAGLD")],
+                         sorted(c.stations.keys()))
+
+        # Same with the set channel.
+        self.restrictions = Restrictions(
+            starttime=obspy.UTCDateTime(2001, 1, 1),
+            endtime=obspy.UTCDateTime(2015, 1, 1),
+            channel_priorities=["EH*", "BH*"],
+            location_priorities=["", "01"],
+            channel="RST")
+        c = self._init_client()
+        c.client.get_stations.return_value = obspy.read_inventory(
+            os.path.join(self.data, "uncommon_channel_location.txt"))
+        c.get_availability()
+        self.assertEqual([("AK", "BAGLB"), ("AK", "BAGLD")],
+                         sorted(c.stations.keys()))
+
+        # If both are set, the priorities are properly ignored.
+        self.restrictions = Restrictions(
+            starttime=obspy.UTCDateTime(2001, 1, 1),
+            endtime=obspy.UTCDateTime(2015, 1, 1),
+            channel_priorities=["EH*", "BH*"],
+            location_priorities=["", "01"],
+            location="31",
+            channel="RST")
+        c = self._init_client()
+        c.client.get_stations.return_value = obspy.read_inventory(
+            os.path.join(self.data, "uncommon_channel_location.txt"))
+        c.get_availability()
+        self.assertEqual([("AK", "BAGLA"), ("AK", "BAGLB"), ("AK", "BAGLC"),
+                          ("AK", "BAGLD")],
+                         sorted(c.stations.keys()))
+
     def test_excluding_networks_and_stations_with_an_inventory_object(self):
         """
         Tests the excluding of networks and stations with the help of an