<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 If I forget dithers and just look at how many observations per field
Step1:  List of obsHistIDs with unique nights
Proposal 
Step2:  How much does it help our airmass distribution by choosing the lowest airmass of the available ones
Step3:  Our culled opsim that we shall try out first is now 'ourOpSim' . We can write this our to a csv file, or a database. We can also view the list of obsHistIDs
Step4:  Scratch
Find the obsHistIDs corresponding to the lowest airmass of visits
<ASSISTANT_TASK:>
Python Code:
full_survey = ds.cadence_plot(fieldID=1427, mjd_center=61404, mjd_range=[-1825, 1825], 
                              observedOnly=False, colorbar=True);
plt.close()
full_survey[0]
half_survey = ds.cadence_plot(fieldID=1427, mjd_center=61404, mjd_range=[-1825, 1], 
                              observedOnly=False, colorbar=True);
second_year = ds.cadence_plot(fieldID=1427, mjd_center=60200, mjd_range=[-150, 150], 
                              observedOnly=False, colorbar=True);
secondYearObs = ds.cadence_plot(fieldID=1427, mjd_center=60300, mjd_range=[-0, 30], observedOnly=False)
plt.close()
secondYearObs[0]
Explanation: If I forget dithers and just look at how many observations per field: 
- Look at the number of unique nights with different bands:  For the full survey this number of visits is 1680, see  figure in Input 13
- For half of the survey, the same quantity is 824, see figure 1nput 14
- For a year the number is ~150. See figure on input 15
End of explanation
df['obsID'] = df.index.values
uniqueObs = df.groupby(['night', 'filter'])
aa = uniqueObs['airmass'].agg({'myInds': lambda x: x.idxmin()}).myInds.astype(int).values
ourOpSim = df.ix[aa]
Explanation: List of obsHistIDs with unique nights
Proposal :
We want to select all the unique night and band combinations in the 10 years of Kraken. As we have seen above this is 1680 visits. 
We will give the phosim instance catalogs and seds for running phosim on the cluster, and we should run these in order of expMJD or night. If we run out of compute time at a 1000, then we will have a little more than half of the survey
When we get more (phoSim) simulation time, we can finish the 10 years. If we have more time than than, I suggest we fill in other observations in the 2nd year as shown in the above figure around 60300. This is another 500 observations. After than we can fill in the rest of the second year and then other years. The priority for the the second year (and could have been elsewhere) is because I can make sure that there a few supernovae that are at high redshift and 'visible' at that time. I need to know this ahead of time, and that is why I putting this out now.
End of explanation
axs = df.hist(by='filter', column='airmass', histtype='step', lw=2, alpha=1, color='k', normed=True);
axs = df.ix[aa].hist(by='filter', column='airmass', histtype='step', lw=2, alpha=1, color='r', ax=axs, normed=True)
df.obsID.unique().size, df.obsID.size
ourOpSim.head()
Explanation: How much does it help our airmass distribution by choosing the lowest airmass of the available ones
End of explanation
ourOpSim.obsID.values
ourOpSim.obsID.to_csv('FirstSet_obsHistIDs.csv')
ourOpSim.to_csv('SelectedKrakenVisits.csv')
xx = ourOpSim.groupby(['night', 'filter']).aggregate('count')
assert(all(xx.max() == 1))
Explanation: Our culled opsim that we shall try out first is now 'ourOpSim' . We can write this our to a csv file, or a database. We can also view the list of obsHistIDs
End of explanation
dff = uniqueObs['airmass'].agg({'myInds': lambda x: x.idxmin()})
aa = dff.myInds.astype(int).values
aa.sort()
l = []
for key in keys:
    l.append(uniqueObs.get_group(key).airmass.idxmin())
Explanation: Scratch
Find the obsHistIDs corresponding to the lowest airmass of visits
End of explanation
<END_TASK>