docs: def dalignbedannot2daggbyquery(cfg):
      """
      Aggregate annotations per alignment to annotations per query.
      step#10
  
      :param cfg: configuration dict
      """
      datatmpd=cfg['datatmpd']
  
      dalignbedannot=del_Unnamed(pd.read_csv(cfg['dalignbedannotp'],sep='\t',low_memory=False))
      
      daggbyqueryp=f'{datatmpd}/10_daggbyquery.tsv'      
      logging.info(basename(daggbyqueryp))
      if not exists(daggbyqueryp) or cfg['force']:
          dalignbedannot=dfliststr2dflist(dalignbedannot,
                                  ['type', 'gene name', 'gene id', 'transcript id', 'protein id', 'exon id'],
                                  colfmt='tuple')    
          dalignbedannot['alternate alignments count']=1
          import itertools
          from rohan.dandage.io_sets import unique
          def unique_dropna(l): return unique(l,drop='nan')
          def merge_unique_dropna(l): return unique(list(itertools.chain(*l)),drop='nan')
          cols2aggf={'id':unique_dropna,
           'type':merge_unique_dropna,
           'gene name':merge_unique_dropna,
           'gene id':merge_unique_dropna,
           'transcript id':merge_unique_dropna,
           'protein id':merge_unique_dropna,
           'exon id':merge_unique_dropna,
           'region':unique_dropna,
           'alternate alignments count':sum,
          }
          daggbyquery=dalignbedannot.groupby('query id').agg(cols2aggf)
          daggbyquery.to_csv(daggbyqueryp,sep='\t')
          daggbyquery.to_csv(cfg['dalignannotedp'],sep='\t')
      return cfg