basic_queries.py 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. #%%
  2. import json
  3. import polars as pl
  4. from .utilities.parsing_utilities import interpreter, inizialeraddoppiata, list_normalize
  5. from .data_interface.data_providers_setup import queryHandlerFactory
  6. # Main class for basic queries contains:
  7. # - a data provider instance
  8. # - methods to submit queries to the data provider instance
  9. class basicQueries:
  10. def __init__(self, dataConfig):
  11. self.queryHandler = queryHandlerFactory(dataConfig)
  12. self.listOcc = dataConfig.get('listOcc')
  13. # Prepares and sends query OBJECTS which will be processed by the data provider
  14. def sendBasicQuery(self, text, queryType, espansa, raddoppiata, polars=False, dbFile=None):
  15. entries = interpreter(text)
  16. data = entries
  17. dataNorm = []
  18. if raddoppiata == 1:
  19. data = entries + inizialeraddoppiata(entries)
  20. if espansa == 1 and raddoppiata == 0:
  21. dataNorm = list_normalize(entries)
  22. elif espansa == 1 and raddoppiata == 1:
  23. dataNorm = entries + list_normalize(inizialeraddoppiata(entries))
  24. return self.queryHandler.query({'data': data, 'dataNorm': dataNorm, 'queryType': queryType}, polars, dbFile)
  25. # Finds texts based on search functions, looks in the occurrence for pointers to contexts and other elements associated with them.
  26. def findtexts(self, type, df, index=None):
  27. # Check if the input is a DataFrame, and convert it if it is not
  28. if not isinstance(df, pl.DataFrame):
  29. df = pl.DataFrame(df)
  30. # If an index is provided, select the rows that correspond to the index
  31. if index is not None:
  32. if isinstance(index, range):
  33. index = list(index)
  34. elif not isinstance(index, list):
  35. index = [index]
  36. df = df.filter(pl.col('index').is_in(index))
  37. # Create a list of 'cod' values from the input DataFrame
  38. codList = df.select('cod').to_list()
  39. # Get the 'listOcc' values
  40. listOcc = self.listOcc
  41. # Create a dictionary with query information
  42. queryData = {'queryType': 'texts', 'querySubtype': type, 'codList': codList}
  43. # If 'type' is 2 (option "non lemmatizzate"), make an additional query to get form codes
  44. # NOTE: At this stage of development 'type 2' is default for "lemma" searches (this could be changed).
  45. if type == 2:
  46. subQueryData = {'queryType': 'pfl', 'codList': codList}
  47. subdf = self.queryHandler.query(subQueryData, polars=True)
  48. queryData['formCodList'] = subdf.select('codForma').to_list()
  49. # Make a query to each table in 'listOcc' and concatenate the results
  50. queryResponses = [self.queryHandler.query(dict(queryData, table=table), polars=True) for table in listOcc]
  51. textlist = pl.concat(queryResponses)
  52. return textlist
  53. # %% ha in input findtexts, restituisce i contesti associati agli elementi localizzati.
  54. # Il range dei contesti è impostato di default a 30 parole e può essere rimodulato nel passaggio al contesto singolo.
  55. def findcontexts(self, textlist):
  56. # Initialize lists to store context information
  57. contexts = []
  58. formats = []
  59. minChar_list = []
  60. maxChar_list = []
  61. # Iterate over each row in 'textlist'
  62. for _, row in textlist.iterrows():
  63. sigla = row["sigla"]
  64. if row["piniz"] is None or math.isnan(row["piniz"]):
  65. minChar = int(row["backup_piniz"])
  66. else:
  67. minChar = int(row["piniz"])
  68. if row["pfin"] is None or math.isnan(row["pfin"]):
  69. maxChar = int(row["backup_pfin"])
  70. else:
  71. maxChar = int(row["pfin"])
  72. fileQueryData = {'sigla': sigla, 'minChar': minChar, 'maxChar': maxChar}
  73. # Call 'textQuery' to get the context and format information
  74. cont, form = self.queryHandler.textQuery(fileQueryData, True)
  75. # Append the results to the respective lists
  76. minChar_list.append(minChar)
  77. maxChar_list.append(maxChar)
  78. contexts.append(cont)
  79. formats.append(json.dumps(form))
  80. # Add the context information to 'textlist' and reset the index
  81. textlist['piniz'] = minChar_list
  82. textlist['pifin'] = maxChar_list
  83. textlist['contesto'] = contexts
  84. textlist['formattazione contesto'] = formats
  85. return textlist.reset_index(drop=True)
  86. # %% Ha in input findcontexts, associa i riferimenti bibliografici ad ogni contesto dal db BiblioTLIO.
  87. def findbib(self, contexts):
  88. # Old, deprecated
  89. # infobib = pd.DataFrame()
  90. # rif_org = pd.DataFrame()
  91. # for ind, row in contexts.iterrows():
  92. # queryData = {'queryType': 'bib', 'row': row}
  93. # bib = self.queryHandler.query(queryData, pandas=True, dbFile='bibliografia/BiblioTLIO.db')
  94. # infobib = pd.concat([infobib, bib])
  95. # queryData = {'queryType': 'rif', 'row': row}
  96. # rif = self.queryHandler.query(queryData, pandas=True)
  97. # rif_org = pd.concat([rif_org, rif])
  98. # annoiniz = list(infobib['Anno iniziale'])
  99. # annofin = list(infobib['Anno finale'])
  100. # datacod = list(infobib['Data codificata'])
  101. # datadesc = list(infobib['Data descrittiva'])
  102. # titoloabb = list(infobib['Titolo Abbreviato'])
  103. # autore = list(infobib['Autore'])
  104. # titolo = list(infobib['Titolo'])
  105. # curatore = list(infobib['Curatore'])
  106. # areagen = list(infobib['Area generica'])
  107. # areaspec = list(infobib['Area specifica'])
  108. # genere = list(infobib['Genere'])
  109. # forma = list(infobib['Forma'])
  110. # tipo = list(infobib['Tipo'])
  111. # iq = list(infobib['IQ'])
  112. siglaList = list(contexts['sigla'])
  113. siglaSet = set(siglaList)
  114. queryData = {'queryType': 'bibAlt', 'siglaSet': siglaSet}
  115. infobib = self.queryHandler.query(queryData, pandas=True, dbFile='bibliografia/BiblioTLIO.db')
  116. infobib = infobib.set_index('Sigla')
  117. infobib2 = {sigla: infobib.loc[sigla].to_dict() for sigla in siglaSet}
  118. infobib = [infobib2[sigla] for sigla in siglaList]
  119. #
  120. annoiniz = [el['Anno iniziale'] for el in infobib]
  121. annofin = [el['Anno finale'] for el in infobib]
  122. datacod = [el['Data codificata'] for el in infobib]
  123. datadesc = [el['Data descrittiva'] for el in infobib]
  124. titoloabb = [el['Titolo Abbreviato'] for el in infobib]
  125. autore = [el['Autore'] for el in infobib]
  126. titolo = [el['Titolo'] for el in infobib]
  127. curatore = [el['Curatore'] for el in infobib]
  128. areagen = [el['Area generica'] for el in infobib]
  129. areaspec = [el['Area specifica'] for el in infobib]
  130. genere = [el['Genere'] for el in infobib]
  131. forma = [el['Forma'] for el in infobib]
  132. tipo = [el['Tipo'] for el in infobib]
  133. iq = [el['IQ'] for el in infobib]
  134. ntxList = list(contexts['ntx'])
  135. numOrgList = list(contexts['numorg'])
  136. coordsList = [(numorg, ntxList[ind]) for ind, numorg in enumerate(numOrgList)]
  137. coordsSet = set(coordsList)
  138. queryData = {'queryType': 'rifAlt', 'coordsSet': coordsSet}
  139. rif_org = self.queryHandler.query(queryData, pandas=True)
  140. rif_org = rif_org.set_index( ['numorg', 'ntx'] )
  141. rif_org2 = {coord: rif_org.loc[coord] for coord in coordsSet}
  142. rif_org = [rif_org2[coord] for coord in coordsList]
  143. rif1 = [rif['Rif_organico'] for rif in rif_org]
  144. rif2 = [rif['Rif_completo'] for rif in rif_org]
  145. contexts['Anno iniziale'] = annoiniz
  146. contexts['Anno finale'] = annofin
  147. contexts['Data codificata'] = datacod
  148. contexts['Data descrittiva'] = datadesc
  149. contexts['Autore'] = autore
  150. contexts['Titolo Abbreviato'] = titoloabb
  151. contexts['Titolo'] = titolo
  152. contexts['Curatore'] = curatore
  153. contexts['Area generica'] = areagen
  154. contexts['Area specifica'] = areaspec
  155. contexts['Genere'] = genere
  156. contexts['Forma'] = forma
  157. contexts['Tipo'] = tipo
  158. contexts ['IQ'] = iq
  159. contexts['Rif_organico'] = rif1
  160. contexts['Rig_completo'] = rif2
  161. chrono = contexts.sort_values(by=['Data codificata', 'Rif_organico'])
  162. return (chrono.reset_index(drop=True))