docs: def experiments(auth, label=None, project=None, subject=None):
      '''
      Retrieve Experiment tuples for experiments returned by this function.
      
      Example:
          >>> import yaxil
          >>> auth = yaxil.XnatAuth(url='...', username='...', password='...')
          >>> yaxil.experiment(auth, 'AB1234C')
          Experiment(uri=u'/data/experiments/XNAT_E0001', label=u'AB1234C', id=u'XNAT_E0001', 
              project=u'MyProject', subject_id=u'XNAT_S0001', subject_label='ABC')
  
      :param auth: XNAT authentication
      :type auth: :mod:`yaxil.XnatAuth`
      :param label: XNAT Experiment label
      :type label: str
      :param project: XNAT Experiment Project
      :type project: str
      :param subject: YAXIL Subject
      :type subject: :mod:`yaxil.Subject`
      :returns: Experiment object
      :rtype: :mod:`yaxil.Experiment`
      '''
      if subject and (label or project):
          raise ValueError('cannot provide subject with label or project')
      url = '{0}/data/experiments'.format(auth.url.rstrip('/'))
      logger.debug('issuing http request %s', url)
      # compile query string
      columns = [
          'ID',
          'label',
          'project',
          'xnat:subjectassessordata/subject_id',
          'subject_label',
          'insert_date'
      ]
      payload = {
          'columns': ','.join(columns)
      }
      if label:
          payload['label'] = label
      if project:
          payload['project'] = project
      if subject:
          payload['project'] = subject.project
          payload['xnat:subjectassessordata/subject_id'] = subject.id
      # submit request
      r = requests.get(url, params=payload, auth=(auth.username, auth.password), 
                       verify=CHECK_CERTIFICATE)
      # validate response
      if r.status_code != requests.codes.ok:
          raise AccessionError('response not ok ({0}) from {1}'.format(r.status_code, r.url))
      try:
          results = r.json()
          __quick_validate(results)
      except ResultSetError as e:
          raise ResultSetError('{0} from {1}'.format(e.message, r.url))
      results = results['ResultSet']
      if int(results['totalRecords']) == 0:
          raise NoExperimentsError('no records returned for {0}'.format(r.url))
      for item in results['Result']:
          yield Experiment(uri=item['URI'], 
                           id=item['ID'], 
                           project=item['project'], 
                           label=item['label'], 
                           subject_id=item['subject_ID'], 
                           subject_label=item['subject_label'], 
                           archived_date=item['insert_date'])