basic_queries.py 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. #%%
  2. from .parsing_utilities import interpreter, inizialeraddoppiata, list_normalize
  3. # Basic data provider class; can be instantiated to handle different kinds
  4. # of data-providing connections or interfaces based on config options
  5. from .data_interface.data_providers_setup import queryHandlerFactory
  6. import pandas as pd
  7. # Main class for basic queries contains:
  8. # - a data provider instance
  9. # - methods to submit queries to the data provider instance
  10. class basicQueries:
  11. def __init__(self, dataConfig):
  12. self.queryHandler = queryHandlerFactory(dataConfig)
  13. self.listOcc = dataConfig.get('listOcc')
  14. # Prepares and sends query OBJECTS which will be processed by the data provider
  15. def sendBasicQuery(self, text, queryType, espansa, raddoppiata, pandas=False, dbFile=None):
  16. entries = interpreter(text)
  17. data = entries
  18. dataNorm = []
  19. if raddoppiata==1:
  20. data = entries + inizialeraddoppiata(entries)
  21. if espansa==1 and raddoppiata==0:
  22. dataNorm = list_normalize(entries)
  23. elif espansa==1 and raddoppiata==1:
  24. dataNorm = entries + list_normalize(inizialeraddoppiata(entries))
  25. return self.queryHandler.query({'data': data, 'dataNorm': dataNorm, 'queryType': queryType}, pandas, dbFile)
  26. #%% ha in input le funzioni di ricerca, cerca nell'occorrenziario i puntatori ai contesti e altri elementi ad essi associati.
  27. #l'attributo type definisce il tipo di ricerca in input (0 per forme, 1 per lemmi, 2 per lemmi con opzione "mostra occorrenze non lemmatizzate")
  28. def findtexts(self, type, df, index = None):
  29. if index is None:
  30. df = pd.DataFrame(df)
  31. else:
  32. if isinstance(index, range):
  33. index = list(index)
  34. elif not isinstance(index, list):
  35. index = [index]
  36. df = pd.DataFrame(df.loc[index])
  37. textlist = pd.DataFrame()
  38. codList = list(df["cod"])
  39. listOcc = self.listOcc
  40. queryData = {'queryType': 'texts', 'querySubtype': type, 'codList': codList}
  41. for table in listOcc:
  42. queryData['table'] = table
  43. if type==2:
  44. subQueryData = {'queryType': 'pfl', 'codList': codList}
  45. subdf = self.queryHandler.query(subQueryData, pandas=True)
  46. queryData['formCodList'] = list(subdf['codForma'])
  47. extendequeryReponse = self.queryHandler.query(queryData, pandas=True)
  48. textlist = pd.concat([textlist, extendequeryReponse])
  49. return textlist
  50. # %% ha in input findtexts, restituisce i contesti associati agli elementi localizzati.
  51. # Il range dei contesti è impostato di default a 30 parole e può essere rimodulato nel passaggio al contesto singolo.
  52. def findcontexts(self, textlist):
  53. parole = 31
  54. listOcc = self.listOcc
  55. contexts = []
  56. for ind, row in textlist.iterrows():
  57. sigla = row["sigla"]
  58. queryData = {'queryType': 'contexts', 'ntxlocal': row["ntx"], 'mappalocal': row['mappa'], 'parole': parole}
  59. pointerlist = pd.DataFrame()
  60. for table in listOcc:
  61. queryData['table'] = table
  62. queryresponse = self.queryHandler.query(queryData, pandas=True)
  63. pointerlist = pd.concat([pointerlist, queryresponse])
  64. fileQueryData = {'sigla': sigla, 'minChar': pointerlist["pitxt"].min(), 'maxChar': pointerlist["pitxt"].max()}
  65. cont = self.queryHandler.textQuery(fileQueryData)
  66. contexts.append(cont)
  67. textlist['contesto'] = contexts
  68. return (textlist.reset_index(drop=True))
  69. # %% Ha in input findcontexts, associa i riferimenti bibliografici ad ogni contesto.
  70. def findbib(self, contexts):
  71. infobib = pd.DataFrame()
  72. rif_org = pd.DataFrame()
  73. for ind, row in contexts.iterrows():
  74. queryData = {'queryType': 'bib', 'row': row}
  75. bib = self.queryHandler.query(queryData, pandas=True, dbFile='bibliografia/BiblioTLIO.db')
  76. infobib = pd.concat([infobib, bib])
  77. queryData = {'queryType': 'rif', 'row': row}
  78. rif = self.queryHandler.query(queryData, pandas=True)
  79. rif_org = pd.concat([rif_org, rif])
  80. annoiniz = list(infobib['Anno iniziale'])
  81. annofin = list(infobib['Anno finale'])
  82. datacod = list(infobib['Data codificata'])
  83. datadesc = list(infobib['Data descrittiva'])
  84. titoloabb = list(infobib['Titolo Abbreviato'])
  85. autore = list(infobib['Autore'])
  86. titolo = list(infobib['Titolo'])
  87. curatore = list(infobib['Curatore'])
  88. areagen = list(infobib['Area generica'])
  89. areaspec = list(infobib['Area specifica'])
  90. genere = list(infobib['Genere'])
  91. forma = list(infobib['Forma'])
  92. tipo = list(infobib['Tipo'])
  93. iq = list(infobib['IQ'])
  94. rif1 = list(rif_org['Rif_organico'])
  95. rif2 = list(rif_org['Rif_completo'])
  96. contexts['Anno iniziale'] = annoiniz
  97. contexts['Anno finale'] = annofin
  98. contexts['Data codificata'] = datacod
  99. contexts['Data descrittiva'] = datadesc
  100. contexts['Autore'] = autore
  101. contexts['Titolo Abbreviato'] = titoloabb
  102. contexts['Titolo'] = titolo
  103. contexts['Curatore'] = curatore
  104. contexts['Area generica'] = areagen
  105. contexts['Area specifica'] = areaspec
  106. contexts['Genere'] = genere
  107. contexts['Forma'] = forma
  108. contexts['Tipo'] = tipo
  109. contexts ['IQ'] = iq
  110. contexts['Rif_organico'] = rif1
  111. contexts['Rig_completo'] = rif2
  112. contexts.pag = contexts.pag.astype(int)
  113. chrono = contexts.sort_values(by=['Anno iniziale', 'Rif_organico', 'pag'])
  114. cols = ['links','Titolo Abbreviato', 'Rif_organico', 'tipostanza', 'stanza', 'verso', 'pag', 'riga', 'IQ', 'lemma', 'cat_gr', 'disambiguatore', 'contesto', 'Autore', 'Titolo', 'Anno iniziale', 'Anno finale', 'Data codificata', 'Data descrittiva', 'Area generica', 'Area specifica', 'Genere', 'Forma', 'Tipo', 'Curatore', 'ntx', 'pitxt', 'elemlen', 'mappa', 'numperiod', 'numorg', 'sigla', 'vol', 'col', 'numbrano', 'Rig_completo', 'cod']
  115. clean_df = chrono.reindex(columns=cols + list(chrono.columns.difference(cols)))
  116. return (clean_df.reset_index(drop=True))
  117. #%% funzione stringa/stringhe da evidenziare
  118. def highlight (self, bibliocontexts):
  119. index = 0
  120. for col in bibliocontexts.columns:
  121. forme = []
  122. if col.startswith('cod'):
  123. for ind, row in bibliocontexts.iterrows():
  124. queryData = {'queryType': 'highlight', 'row': row, 'col': col}
  125. forma = self.queryHandler.query(queryData, pandas=True)
  126. forme += list(forma['highlight'])
  127. if index == 0:
  128. bibliocontexts['highlight'] = forme
  129. else:
  130. bibliocontexts['highlight'+str(index)] = forme
  131. index += 1
  132. highlight_cols = bibliocontexts.filter(regex='^highlight')
  133. create_array = lambda row: highlight_cols.loc[row.name].values.tolist()
  134. bibliocontexts['highlights_combined'] = highlight_cols.apply(create_array, axis=1)
  135. return bibliocontexts
  136. #%% funzione contesti multipli cumulativa
  137. def contestimultipli (self, tipo_ricerca, ricerca, index = None):
  138. ricercadf = pd.DataFrame(ricerca)
  139. textlist = self.findtexts(tipo_ricerca, ricercadf, index)
  140. contexts = self.findcontexts (textlist)
  141. bibliocontexts = self.findbib (contexts)
  142. highlights = self.highlight(bibliocontexts)
  143. return highlights.to_dict(orient='records')
  144. #%% funzione reperimento e raffinamento contesti singoli
  145. def singlecontexts(self, textlist, index, parole, periodi, brani):
  146. context = textlist.iloc[index]
  147. contexts = []
  148. formats = []
  149. listOcc = self.listOcc
  150. sigla = textlist.loc[index, "sigla"]
  151. periodlocal = textlist.loc[index, "numperiod"]
  152. ntxlocal = textlist.loc[index, "ntx"]
  153. mappalocal = textlist.loc[index, "mappa"]
  154. linkslocal = textlist.loc[index, "links"]
  155. numbranolocal = textlist.loc[index, "numbrano"]
  156. if parole != 0:
  157. pointerlist = pd.DataFrame()
  158. for table in listOcc:
  159. print(listOcc)
  160. queryData = {'queryType': 'singlecontext', 'querySubtype': 'parole', 'parole': parole, 'periodi': periodi, 'brani': brani, 'table': table, 'ntxlocal': ntxlocal, 'mappalocal': mappalocal, 'periodlocal': periodlocal, 'numbranolocal': numbranolocal}
  161. queryresponse = self.queryHandler.query(queryData, pandas=True)
  162. pointerlist = pd.concat([pointerlist, queryresponse])
  163. print(pointerlist)
  164. fileQueryData = {'sigla': sigla, 'minChar': pointerlist["pitxt"].min(), 'maxChar': pointerlist["pitxt"].max()}
  165. cont = self.queryHandler.textQuery(fileQueryData)
  166. contexts.append(cont)
  167. form = self.queryHandler.formatQuery(fileQueryData)
  168. formats.append(form)
  169. context ['piniz'] = pointerlist["pitxt"].min()
  170. context ['pfin'] = pointerlist["pitxt"].max()
  171. elif periodi != 0:
  172. queryData = {'queryType': 'singlecontext', 'querySubtype': 'parole', 'parole': parole, 'periodi': periodi, 'brani': brani, 'table': table, 'ntxlocal': ntxlocal, 'mappalocal': mappalocal, 'periodlocal': periodlocal, 'numbranolocal': numbranolocal}
  173. queryresponse = self.queryHandler.query(queryData, pandas=True)
  174. fileQueryData = {'sigla': sigla, 'minChar': pointerlist["pitxt"].min(), 'maxChar': pointerlist["pitxt"].max()}
  175. cont = self.queryHandler.textQuery(fileQueryData)
  176. contexts.append(cont)
  177. form = self.queryHandler.formatQuery(fileQueryData)
  178. formats.append(form)
  179. context ['piniz'] = queryresponse["piniz"].min()
  180. context ['pfin'] = queryresponse["pfin"].max()
  181. elif brani != 0:
  182. if linkslocal == 0 or linkslocal == 1:
  183. return "Nessun brano associato a questo contesto"
  184. else:
  185. queryData = {'queryType': 'singlecontext', 'querySubtype': 'brani', 'parole': parole, 'periodi': periodi, 'brani': brani, 'table': table, 'ntxlocal': ntxlocal, 'mappalocal': mappalocal, 'periodlocal': periodlocal, 'numbranolocal': numbranolocal}
  186. queryresponse = self.queryHandler.query(queryData, pandas=True)
  187. fileQueryData = {'sigla': sigla, 'minChar': pointerlist["pitxt"].min(), 'maxChar': pointerlist["pitxt"].max()}
  188. cont = self.queryHandler.textQuery(fileQueryData)
  189. contexts.append(cont)
  190. form = self.queryHandler.formatQuery(fileQueryData)
  191. formats.append(form)
  192. context ['piniz'] = queryresponse["piniz"].min()
  193. context ['pfin'] = queryresponse["pfin"].max()
  194. context['contesto'] = contexts [0]
  195. context['formattazione'] = formats
  196. return pd.DataFrame(context).T.reset_index(drop=True)
  197. #%% funzione reperimento note e brani associati
  198. def findlinks (self, context):
  199. linkslocal = context.loc[0, "links"]
  200. siglalocal = context.loc[0, "sigla"]
  201. ntxlocal = context.loc[0, "ntx"]
  202. pitxtlocal = context.loc[0, "pitxt"]
  203. pinizlocal = context.loc[0, "piniz"]
  204. pfinlocal = context.loc[0, "pfin"]
  205. if linkslocal == 0:
  206. return context
  207. if linkslocal == 1:
  208. queryData = {'queryType': 'links', 'querySubtype': 'nota', 'ntxlocal': ntxlocal, 'pinizlocal': pinizlocal, 'pitxtlocal': pitxtlocal, 'pfinlocal': pfinlocal}
  209. queryresponse = self.queryHandler.query(queryData, pandas=True)
  210. fileQueryData = {'sigla': siglalocal, 'minChar': queryresponse["piniz"].min(), 'maxChar': queryresponse["pfin"].max()}
  211. cont = self.queryHandler.textQuery(fileQueryData)
  212. context['nota'] = cont
  213. return context
  214. if linkslocal == 2:
  215. queryData = {'queryType': 'links', 'querySubtype': 'testo_associato', 'ntxlocal': ntxlocal, 'pinizlocal': pinizlocal, 'pitxtlocal': pitxtlocal, 'pfinlocal': pfinlocal}
  216. queryresponse = self.queryHandler.query(queryData, pandas=True)
  217. fileQueryData = {'sigla': siglalocal, 'minChar': queryresponse["piniz"].min(), 'maxChar': queryresponse["pfin"].max()}
  218. cont = self.queryHandler.textQuery(fileQueryData)
  219. context['testo associato'] = cont
  220. if linkslocal == 3:
  221. queryData = {'queryType': 'links', 'querySubtype': 'nota', 'ntxlocal': ntxlocal, 'pinizlocal': pinizlocal, 'pitxtlocal': pitxtlocal, 'pfinlocal': pfinlocal}
  222. queryresponse = self.queryHandler.query(queryData, pandas=True)
  223. fileQueryData = {'sigla': siglalocal, 'minChar': queryresponse["piniz"].min(), 'maxChar': queryresponse["pfin"].max()}
  224. cont = self.queryHandler.textQuery(fileQueryData)
  225. context['nota'] = cont
  226. queryData2 = {'queryType': 'links', 'querySubtype': 'testo_associato', 'ntxlocal': ntxlocal, 'pinizlocal': pinizlocal, 'pitxtlocal': pitxtlocal, 'pfinlocal': pfinlocal}
  227. queryresponse2 = self.queryHandler.query(queryData2, pandas=True)
  228. fileQueryData2 = {'sigla': siglalocal, 'minChar': queryresponse2["piniz"].min(), 'maxChar': queryresponse2["pfin"].max()}
  229. cont2 = self.queryHandler.textQuery(fileQueryData2)
  230. context['testo associato'] = cont2
  231. return context
  232. #%% funzione contesti singoli cumulativa
  233. def contestosingolo (self, contestimultipli, indice, parole, periodi, brani):
  234. contestimultiplidf = pd.DataFrame(contestimultipli)
  235. print(contestimultiplidf)
  236. contestosingolo = self.singlecontexts(contestimultiplidf, indice, parole, periodi, brani)
  237. braniassociati = self.findlinks(contestosingolo)
  238. contestosingoloclean = self.findbib (braniassociati)
  239. return contestosingoloclean.to_dict(orient='records')