<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Tutorial
This notebook is designed to show examples using the nexradaws python module.
The first thing we need to do is instantiate an instance of the NexradAwsInterface class. This class contains methods to query and download from the Nexrad Amazon S3 Bucket.
This notebook uses Python 3.6 for it's examples.
Step1:  Query methods
Next we will test out some of the available query methods. There are methods to get the available years, months, days, and radars.
Get available years
Step2:  Get available months in a year
Step3:  Get available days in a given year and month
Step4:  Get available radars in a given year, month, and day
Step5:  Query for available scans
There are two query methods to get available scans.
* get_avail_scans() - returns all scans for a particular radar on a particular day
* get_avail_scans_in_range() returns all scans for a particular radar between a start and end time
Both methods return a list of AwsNexradFile objects that contain metadata about the NEXRAD file on AWS. These objects can then be downloaded by passing them to the download method which we will discuss next.
Get all scans for a radar on a given day
Step6:  Get all scans for a radar between a start and end time
Now let's get all available scans between 5-7pm CST May 31, 2013 which is during the El Reno, OK tornado. The get_avail_scans_in_range method accepts datetime objects for the start and end time. 
If the passed datetime objects are timezone aware then it will convert them to UTC before query. If they are not timezone aware it will assume the passed datetime is in UTC.
Step7:  Downloading Files
Now let's download some radar files from our previous example. Let's download the first 4 scans from our query above.
There are two optional keyword arguments to the download method...
keep_aws_folders - Boolean (default is False)...if True then the AWS folder structure will be replicated underneath the basepath given to the method. i.e. if basepath is /tmp and keep_aws_folders is True then the full path would be 2013/05/31/KTLX/KTLX20130531_220114_V06.gz
threads - integer (default is 6) the number of threads to run concurrent downloads
Step8:  The download method returns a DownloadResult object. The success attribute returns a list of LocalNexradFile objects that were successfully downloaded. There is also an iter_success method that creates a generator for easily looping through the objects.
Step9:  You can check for any failed downloads using the failed_count attribute. You can get a list of the failed AwsNexradFile objects by calling the failed attribute. There is also a generator method called iter_failed that can be used to loop through the failed objects.
Step10:  Working with LocalNexradFile objects
Now that we have downloaded some files let's take a look at what is available with the LocalNexradFile objects.
These objects have attributes containing metadata about the local file including local filepath, last_modified (on AWS), filename, volume scan time, and radar id.
There are two methods available on the LocalNexradFile to open the local file.
open() - returns a file object. Be sure to close the file object when done.
open_pyart() - if pyart is installed this will return a pyart Radar object.
Let's look at an example of using pyart to open and plot our newly downloaded NEXRAD file from AWS. We will zoom into within 150km of the radar to see the storms a little better in these examples.
Step11:  Now lets plot velocity data for the same scans.
<ASSISTANT_TASK:>
Python Code:
import nexradaws
conn = nexradaws.NexradAwsInterface()
Explanation: Tutorial
This notebook is designed to show examples using the nexradaws python module.
The first thing we need to do is instantiate an instance of the NexradAwsInterface class. This class contains methods to query and download from the Nexrad Amazon S3 Bucket.
This notebook uses Python 3.6 for it's examples.
End of explanation
years = conn.get_avail_years()
print(years)
Explanation: Query methods
Next we will test out some of the available query methods. There are methods to get the available years, months, days, and radars.
Get available years
End of explanation
months = conn.get_avail_months('2013')
print(months)
Explanation: Get available months in a year
End of explanation
days = conn.get_avail_days('2013','05')
print(days)
Explanation: Get available days in a given year and month
End of explanation
radars = conn.get_avail_radars('2013','05','31')
print(radars)
Explanation: Get available radars in a given year, month, and day
End of explanation
availscans = conn.get_avail_scans('2013', '05', '31', 'KTLX')
print("There are {} NEXRAD files available for May 31st, 2013 for the KTLX radar.\n".format(len(availscans)))
print(availscans[0:4])
Explanation: Query for available scans
There are two query methods to get available scans.
* get_avail_scans() - returns all scans for a particular radar on a particular day
* get_avail_scans_in_range() returns all scans for a particular radar between a start and end time
Both methods return a list of AwsNexradFile objects that contain metadata about the NEXRAD file on AWS. These objects can then be downloaded by passing them to the download method which we will discuss next.
Get all scans for a radar on a given day
End of explanation
central_timezone = pytz.timezone('US/Central')
radar_id = 'KTLX'
start = central_timezone.localize(datetime(2013,5,31,17,0))
end = central_timezone.localize (datetime(2013,5,31,19,0))
scans = conn.get_avail_scans_in_range(start, end, radar_id)
print("There are {} scans available between {} and {}\n".format(len(scans), start, end))
print(scans[0:4])
Explanation: Get all scans for a radar between a start and end time
Now let's get all available scans between 5-7pm CST May 31, 2013 which is during the El Reno, OK tornado. The get_avail_scans_in_range method accepts datetime objects for the start and end time. 
If the passed datetime objects are timezone aware then it will convert them to UTC before query. If they are not timezone aware it will assume the passed datetime is in UTC.
End of explanation
results = conn.download(scans[0:4], templocation)
Explanation: Downloading Files
Now let's download some radar files from our previous example. Let's download the first 4 scans from our query above.
There are two optional keyword arguments to the download method...
keep_aws_folders - Boolean (default is False)...if True then the AWS folder structure will be replicated underneath the basepath given to the method. i.e. if basepath is /tmp and keep_aws_folders is True then the full path would be 2013/05/31/KTLX/KTLX20130531_220114_V06.gz
threads - integer (default is 6) the number of threads to run concurrent downloads
End of explanation
print(results.success)
for scan in results.iter_success():
    print ("{} volume scan time {}".format(scan.radar_id,scan.scan_time))
Explanation: The download method returns a DownloadResult object. The success attribute returns a list of LocalNexradFile objects that were successfully downloaded. There is also an iter_success method that creates a generator for easily looping through the objects.
End of explanation
print("{} downloads failed.".format(results.failed_count))
print(results.failed)
Explanation: You can check for any failed downloads using the failed_count attribute. You can get a list of the failed AwsNexradFile objects by calling the failed attribute. There is also a generator method called iter_failed that can be used to loop through the failed objects.
End of explanation
fig = plt.figure(figsize=(16,12))
for i,scan in enumerate(results.iter_success(),start=1):
    ax = fig.add_subplot(2,2,i)
    radar = scan.open_pyart()
    display = pyart.graph.RadarDisplay(radar)
    display.plot('reflectivity',0,ax=ax,title="{} {}".format(scan.radar_id,scan.scan_time))
    display.set_limits((-150, 150), (-150, 150), ax=ax)
Explanation: Working with LocalNexradFile objects
Now that we have downloaded some files let's take a look at what is available with the LocalNexradFile objects.
These objects have attributes containing metadata about the local file including local filepath, last_modified (on AWS), filename, volume scan time, and radar id.
There are two methods available on the LocalNexradFile to open the local file.
open() - returns a file object. Be sure to close the file object when done.
open_pyart() - if pyart is installed this will return a pyart Radar object.
Let's look at an example of using pyart to open and plot our newly downloaded NEXRAD file from AWS. We will zoom into within 150km of the radar to see the storms a little better in these examples.
End of explanation
fig = plt.figure(figsize=(16,12))
for i,scan in enumerate(results.iter_success(),start=1):
    ax = fig.add_subplot(2,2,i)
    radar = scan.open_pyart()
    display = pyart.graph.RadarDisplay(radar)
    display.plot('velocity',1,ax=ax,title="{} {}".format(scan.radar_id,scan.scan_time))
    display.set_limits((-150, 150), (-150, 150), ax=ax)
Explanation: Now lets plot velocity data for the same scans.
End of explanation
<END_TASK>