Algunas notas sobre la implementación de referencias (véase, véase además) en el OPAC.
Seguramente hay material previo (¡del año 2003!) acerca de estas cuestiones; habría que rescatarlo de papeles que andan por ahí. También hay que ver el archivo cgi-bin/pft/headings.pft
pues allí ya se tenía en cuenta la visualización de referencias.
Comencemos por dejar en claro qué pretendemos lograr; luego iremos viendo posibles caminos que nos pueden llevar a lograrlo.
Si logramos estos dos objetivos, estaremos satisfechos.
Para lograr ambos objetivos necesitamos empezar por esto: cada base de encabezamientos debe contener tanto las formas autorizadas como las no autorizadas, con una marca que distinga unas de otras.
Además, cada forma no autorizada debe incluir un puntero a su respectiva forma autorizada, de manera de poder mostrar el link junto al encabezamiento. Podríamos usar justamente la presencia de ese puntero como la marca que permite reconocer una forma no autorizada.
¿Cómo llegan las formas no autorizadas a las bases de encabezamientos?
Aquí tenemos que considerar dos situaciones. En la situación ideal, tenemos una base de autoridades, formada por registros MARC de autoridades con campos 1xx y referencias en 4xx y 5xx. En la presente situación de transición, podríamos contar con una tabla que ponga en correspondencia algunos encabezamientos problemáticos con algunas formas alternativas.
En la situación actual, contamos con dos herramientas para extraer listas de encabezamientos a partir de una base bibliográfica: el script update_db.py
usado para generar las bases para el OPAC, y el script auto.py
usado para construir una base de registros de autoridad. El diagrama muestra a grandes rasgos el output de ambos procesos; el input en ambos casos es una base bibliográfica:
update_db.py base name base subj base title base biblio (c/ headings y punteros) ----------- ----------- ------------ ------------- 1 heading 1 heading 1 title 245 ...... 8 subcat 8 subcat 2 tag 260 ...... 9 ID 9 ID 13 sort indic. 700 ..... > 11 hits 11 hits 14 sort letter 700 ..... > auto.py base auto base biblio (c/punteros, s/headings) ----------- ------------- 1 heading 245 ...... 8 subcat 260 ...... 9 ID 700 > $4edt 11 hits 700 > $4edt
En el diagrama usamos “>” para indicar la presencia de un “puntero” a un registro en la base de headings; esto es, un subcampo $0 (o $9) que contiene el nro de control del registro asociado.
Si bien el segundo proceso se originó en las técnicas usadas para el primero, ambos están desvinculados en la práctica.
En el futuro, esperamos tener nuestros datos de origen en la forma generada por el 2do proceso, es decir, una base auto y una base biblio con punteros a auto. Por lo tanto, sería deseable que el proceso de actualización del OPAC tomase como datos iniciales justamente a ese par de bases.
TO-DO: analizar ambos procesos, para detectar elementos comunes, y posibles inconsistencias entre ellos.
Si partimos de esa estructura, tenemos este algoritmo:
para cada registro A en auto: crear un registro en la base name/subj, con campos: - 001 : campo 001 de A (ID) - 1xx : campo 1xx de A (heading) - 011 : hits (npost(['biblio']v1)) para cada campo 4xx en A: crear un registro en la base name/subj, con campos: - 001 : necesitamos un ID para cada referencia? - 1xx o 4xx : el campo 4xx de A (referencia) - x : campo 001 de A (ID del heading autorizado)
Usando mx, tendríamos algo así:
mx auto "pft=@all-headings.pft" now -all > all-headings.id id2i all-headings.id create=all-headings /* all-headings.pft */ '!ID 0'/ '!v001!',v001/ '!v100!',v100, v110, v111/ '!v011!',f(npost(['biblio']v1), 1, 0)/ ( '!ID 0'/ '!v001!',v001[1], '_', f(iocc, 1, 0)/ '!v100!',v400, v410, v411/ '!v019!',v1[1]/ /* esta es la marca que identifica el registro como "referencia" */ )
A esto debemos agregar detección y consolidación de duplicados, por si hubiese referencias múltiples (ver explicación más abajo).
Dado que ya contamos con una base de registros de autoridad, es natural preguntarse por qué no podemos usar en el OPAC esa misma base (quizás con alguna leve modificación), y en cambio vamos a crear una nueva base, con una estructura diferente: cada encabezamiento —autorizado o referencia— tendrá su propio registro.
Más arriba habíamos mencionado dos objetivos que deseamos lograr. El primero tiene que ver con la función de browsing, y dado que en el OPAC el browsing de las listas de encabezamientos está implementado mediante un mfnrage sobre una base ordenada alfabéticamente, la base de autoridad en su estado original no nos sirve: necesitamos que cada encabezamiento (autorizado o referencia) tenga su propio registro, para luego poder ordenarlos.
El segundo objetivo está relacionado con la función de searching; aquí no parece tan evidente que necesitemos un registro separado por cada referencia, pues bastaría con enviar al diccionario todos los encabezamientos que aparecen en un registro de autoridad, y al buscar por cualquiera de ellos recuperaríamos el registro de autoridad completo. Sin embargo, es importante que al mostrar los resultados de la búsqueda resaltemos los términos sobre los que se basó la recuperación; es decir, que de todo el registro de autoridad deberíamos mostrar el campo 4xx que nos interesa, y posiblemente ocultar todos los 4xx restantes. ¿Podríamos hacer esto fácilmente, sin recurrir a un registro por cada 4xx?
Hay al menos dos maneras de convertir los registros de autoridad en registros que nos resulten más útiles en el OPAC:
Partimos de estos dos registros de autoridad:
[RA1] 100 Encabezamiento autorizado A 400 Referencia A1 400 Referencia A2 [RA2] 100 Encabezamiento autorizado B
Como hay en total cuatro encabezamientos involucrados, y cada uno de ellos irá a un registro separado, generamos cuatro registros de encabezamientos.
[R1] 1 Encabezamiento autorizado A [R2] 1 Referencia A1 4 Encabezamiento autorizado A [R3] 1 Referencia A2 4 Heading autorizado A [R4] 1 Encabezamiento autorizado B
[R1'] 1 Encabezamiento autorizado A [R2'] 1 Encabezamiento autorizado A 4 Referencia A1 [R3'] 1 Encabezamiento autorizado A 4 Referencia A2 [R4'] 1 Encabezamiento autorizado B
De las dos opciones, parece más satisfactoria la primera, ya que pone en un mismo nivel a todos los términos del índice, ya sean encabezamientos autorizados o referencias. Así se simplifica, p.ej., la FST para la base de encabezamientos, ya que sólo nos interesará buscar por palabras en el campo 1.
Tomamos como muestra una de las bases de headings: subj. El caso de la base name es análogo.
Cómo se crea y se usa la base SUBJ en update_db.py Archivos auxiliares: - SUBJ.PFT - REGPUNT.PFT - HEADSORT.PFT - ELIMDUP2.PFT - HEADINGS.FST def build_subj_db(): # ------------------------------------------------------------------ # BASE SUBJ # ------------------------------------------------------------------ logger.info("-----------------------------------------------------") logger.info(" Base de encabezamientos tematicos") logger.info("-----------------------------------------------------") logger.info("Creamos el listado de encabezamientos tematicos...") run('''mx "seq=tmp/biblio2.id\\n" lw=1000 "pft=if getenv('SUBJ_TAGS') : v1*1.4 then @SUBJ.PFT fi" now tell=%s > tmp/subj1.id''' % TELL) logger.info("Convertimos el listado en una base (desordenada y con duplicados)...") run('''id2i tmp/subj1.id create/app=tmp/subj1 tell=%s''' % TELL) logger.info("Regularizamos la puntuacion final de los encabezamientos generados...") run('''mx tmp/subj1 "proc='d2a2¦',v1,'¦'" "proc='d1a1¦',@REGPUNT.PFT,'¦'" "proc='d2'" copy=tmp/subj1 now -all tell=%s''' % TELL) logger.info("Almacenamos en un campo auxiliar la clave de ordenacion...") run('''mx tmp/subj1 uctab=UC-ANSI.TAB "proc='d99a99¦',@HEADSORT.PFT,'¦'" copy=tmp/subj1 now -all tell=%s''' % TELL) logger.info("Ordenamos la base de encabezamientos tematicos...") run('''msrt tmp/subj1 100 v99 tell=%s''' % TELL) logger.info("Generamos la tabla para mapear los numeros de encabezamientos...") run('''mx tmp/subj1 "pft=if s(v1) <> ref(mfn-1,v1) then putenv('HEADING_CODE='v9) fi, v9,'|',getenv('HEADING_CODE')/" now -all tell=%s > tmp/subjcode.seq''' % TELL) logger.info("Eliminamos los encabezamientos duplicados...") run('''mx tmp/subj1 lw=1000 "pft=@ELIMDUP2.PFT" now tell=%s > tmp/subj.id''' % TELL) logger.info("Creamos la base de encabezamientos tematicos (ordenada y sin duplicados)...") run('''id2i tmp/subj.id create/app=subj tell=%s''' % TELL) en recode_headings_in_biblio() run('''mx seq=tmp/subjcode.seq create=tmp/subjcode now -all''') run('''mx tmp/subjcode "fst=1 0 v1" fullinv=tmp/subjcode''') en process_subcatalogs() run('''mx subj "proc='a8#', ref(['tmp/hs']l(['tmp/hs']v9), v2+|#a8#|) ,'#'" copy=subj now -all''') en fullinv() run('''mx subj fst=@HEADINGS.FST actab=AC-ANSI.TAB uctab=UC-ANSI.TAB fullinv=subj tell=%s''' % TELL) en compute_heading_postings() logger.info("Asignamos postings a los terminos del indice de temas.") run('''mx subj "proc='d11a11#',f(npost(['biblio']'_SUBJ_'v9),1,0),'#'" copy=subj now -all tell=%s''' % TELL) en build_agrep_dictionaries() run('''mx dict=subj "pft=v1^*/" k1=a k2=zz now > dictSUBJ.txt''')
1 - CONSTRUCCION DE BASE AUTO ARCHIVOS AUXILIARES: extract-headings.pft fix-tags-indicators.pft 008etc.pft auto.fst :: Si está presente el campo 240, creamos un campo auxiliar 1xx + $t (nombre/título) ::mx %BIBLIO% proc=@v240.pft create=%WORK%\biblio-240 now -all echo %PREFIX%>%WORK%\prefix :: Eliminamos campo 1106 y creamos una copia de trabajo de la base bibliográfica. mx %BIBLIO% "proc='d1106'" create=%WORK%\biblio now -all tell=%TELL% :: Cada campo de la base bibliográfica pasa a ser un registro de la base biblio-campos. i2id %WORK%\biblio >%WORK%\biblio.id mx "seq=%WORK%\biblio.id%SEQ_DELIM%" lw=%LW% create=%WORK%\biblio-campos now -all tell=%TELL% :: Eliminamos espacios en blanco en los extremos (¿a qué se deben esos espacios?) :: TO-DO: ¿vale la pena hacer la limpieza sobre toda la base, si solo nos interesan los encabezamientos? mxcp %WORK%\biblio-campos create=%WORK%\biblio-campos-clean clean log=%OUTPUT%\mxcp-biblio-campos.txt >nul tell=%TELL% :: Extraemos los campos con encabezamientos controlados, y creamos una base con ellos. :: ATENCION: para filtrar subcampos $e, $4, $5, podemos usar algo como name.pft del OPAC. (??) :: TO-DO: para uctab necesitamos usar una tabla ad hoc. mx %WORK%\biblio-campos-clean uctab=UC-ANSI.TAB lw=%LW% pft=@extract-headings.pft now tell=%TELL% >%WORK%\auto-dup.seq mx seq=%WORK%\auto-dup.seq create=%WORK%\auto-dup now -all tell=%TELL% :: Ordenamos la lista de encabezamientos. :: Usamos el formato "mpu,v1*4" para comparar en mayúsculas, ignorando los indicadores y el primer delimitador de subcampo. :: Necesitamos guardar la clave en un campo auxiliar (99) para poder usar la tabla correcta de conversión a mayúsculas. mx %WORK%\auto-dup uctab=UC-ANSI.TAB "proc='a99|',mpu,v1*4,'|'" copy=%WORK%\auto-dup now -all tell=%TELL% msrt %WORK%\auto-dup 1000 v99 :: Eliminamos encabezamientos duplicados. :: Usamos el formato "v1*2" para comparar encabezamientos ignorando los indicadores. :: La comparación es directa (sin conversión a mayúsculas ni de otro tipo), por lo tanto detecta *cualquier* diferencia. :: ATENCION: si normalizamos *antes* el 2do indicador de x00, x10, x11, ¿podemos acá incluir los indicadores en la comparación? mx %WORK%\auto-dup lw=%LW% "pft=if v1*2 <> ref(mfn-1,v1*2) then v1,'|',v2,'|',v3/ fi" now >%WORK%\auto-uniq.seq mx seq=%WORK%\auto-uniq.seq lw=%LW% create=%WORK%\auto-uniq now -all :: Reasignamos tags y ajustamos los indicadores en los registros de autoridades. mx %WORK%\auto-uniq "proc=@fix-tags-indicators.pft" create=%WORK%\auto now -all tell=%TELL% :: Agregamos campos a los registros de autoridades: leader, 005, 008, 999. mx %WORK%\auto "proc=@008etc.pft" copy=%WORK%\auto now -all :: Ordenamos por tag los campos de cada registro de autoridad. mx %WORK%\auto "proc='s'" create=%OUTPUT%\auto now -all :: Diccionario para la base de autoridades. mx %OUTPUT%\auto fst=@auto.fst actab=AC-ANSI.TAB uctab=UC-ANSI.TAB fullinv=%OUTPUT%\auto 3 - GENERACION DE LINKS ENTRE BIBLIO y AUTO ARCHIVOS AUXILIARES: create-subfield-0.pft update-subfield-0.pft :: Construimos tabla de mapeo de punteros a la base bibliográfica. mx %WORK%\auto-dup "pft=if v1*2 <> ref(mfn-1,v1*2) then putenv('PTR=',v2) fi, v2,'|',getenv('PTR')/" now -all >%WORK%\map.seq mx seq=%WORK%\map.seq create=%WORK%\map now -all :: Diccionario para map. mx %WORK%\map "fst=1 0 v1/" fullinv=%WORK%\map :: Creamos un subcampo $0 en cada punto de acceso. :: ¿Por qué subcampo $0? Ver http://www.loc.gov/marc/marbi/2007/2007-06.html mx %WORK%\biblio-campos-clean proc=@create-subfield-0.pft create=%WORK%\biblio-campos-ref1 now -all tell=%TELL% :: Consultamos la base map para reasignar punteros en la base bibliográfica. mx %WORK%\biblio-campos-ref1 proc=@update-subfield-0.pft create=%WORK%\biblio-campos-ref2 now -all tell=%TELL% :: Regeneramos la base bibliográfica. mx %WORK%\biblio-campos-ref2 lw=%LW% "pft=v1/" now -all tell=%TELL% >%WORK%\biblio-campos-ref2.id id2i %WORK%\biblio-campos-ref2.id create=%OUTPUT%\biblio-ref
No sé si “referencia múltiple” es el nombre correcto, pero la situación es ésta: una referencia puede ser compartida por varios encabezamientos autorizados. Un ejemplo que aparece en el libro de Maxwell es IBM:
110 International Business Machines 110 Instituto de Biología Marina 410 IBM 410 IBM
¿Cómo debiera aparecer IBM en el índice de nombres?
IBM véase: International Business Machines Instituto de Biología Marina
IBM véase: International Business Machines IBM véase: Instituto de Biología Marina
El primer caso, que parece el más atractivo, requiere que detectemos y consolidemos los duplicados que pudieran aparecer en la lista de nombres.
En el primer caso se hace más fácil lograr que todo el conjunto de referencias permanezca en una misma página.
NOTA: En un caso de referencias múltiples no podríamos usar el redireccionamiento automático (i.e., que una búsqueda por una de las variantes muestre directamente los resultados asociados a la forma autorizada, sin que el usuario deba volver a pedirlos explícitamente).
Ciertos nombres rusos presentan un problema particular, que posiblemente tenga relevancia para otras situaciones.
Tomemos el caso del matemático ruso Vladimir Arnold, cuyo nombre según Wikipedia es: Vladimir Igorevich Arnol'd or Arnold (Russian: Влади́мир И́горевич Арно́льд) (ver también Wikipedia rusa), y cuyo encabezamiento en LC es:
Arnolʹd, V. I. (Vladimir Igorevich), 1937-
Es usual encontrar el apellido en alguna de estas variantes: Arnold, Arnol'd, Arnol´d.
Repasemos de dónde proviene este apóstrofe. Según el artículo Soft sign en Wikipedia:
“[The soft sign] does not represent an individual sound but just indicates softening (palatalization) of the preceding consonant—or just has a traditional orthographic usage with no phonetic meaning…”
“In the romanization of Cyrillic words, soft signs are typically replaced with the prime symbol (or, alternatively, apostrophe) or just ignored…”
Al hacer una búsqueda en el catálogo bibliográfico de LC, usando
Author/Creator Keyword = vladimir arnold
encontramos el encabezamiento
Arnol'd, V. I. (Vladimir Igorevich), 1937-
Si buscamos usando el apóstrofe
Author/Creator Keyword = vladimir arnol'd
también llegamos al mismo resultado.
Pero no encontramos nada si usamos un acento agudo (que no es lo mismo que el símbolo de prima):
Author/Creator Keyword = vladimir arnol´d
Si exploramos el catálogo de autoridades de LC, vemos que Arnold y Arnol'd aparecen intercalados en el listado alfabético, es decir, el apóstrofe es ignorado a los fines del ordenamiento. Por otra parte, encontramos que el registro de autoridad para Vladimir Arnold contiene:
100 10 |a Arnol'd, V. I. |q (Vladimir Igorevich), |d 1937- 400 10 |w nnaa |a Arnol'd, Vladimir Igorevich 400 10 |a Arnol'd, Vladimir Igorevich, |d 1937-
donde podemos observar que LC no añade referencias para la variante sin apóstrofe.
Por lo tanto, la posibilidad de recuperar los nombres independientemente de la presencia o ausencia de este símbolo no depende de la presencia explícita de referencias en el catálogo, sino de la capacidad del sistema para:
cleanQuery
, que simplemente aplica una FST de una línea para extraer las “palabras”; con esta técnica, para un input de arnol'd obtendríamos dos palabras: ARNOL y D, o bien (si modificamos la tabla ACTAB) una única palabra ARNOL'D. Para lograr que desaparezca el apóstrofe (y dado que, hasta donde sé, la tabla UCTAB no nos permite eliminar un carácter al aplicar la conversión a mayúsculas) necesitamos recurrir a una sustitución, p.ej. mediante un gizmo o algo similar a esto:replace(query, "'"n9999, '')
También queremos (y así está funcionando) poder entrar al índice mediante el término d'amore
o damore
, y llegar a la misma posición en ambos casos.
Parece que esta técnica podría usarse tanto para nombres rusos como para cualquier otro nombre que contenga apóstrofes (o signos similares), p.ej.
D'Amico => DAMICO L'Hôpital => LHOPITAL O'Higgins => OHIGGINS O'Reilly => OREILLY
Sin embargo, no siempre un apóstrofe que aparezca como parte de un nombre puede omitirse para dar lugar a la fusión entre la partícula y la palabra que sigue, como puede verse en este ejemplo:
Bureau Régional de L'Unesco pour L'education en Asie et en Océanie
donde no queremos obtener LUNESCO
ni LEDUCATION
, y sí queremos UNESCO
y EDUCATION
. En el OPAC de LC notamos que una búsqueda por
Author/Creator Keyword = lunesco
recupera encabezamientos con el texto de l'UNESCO, y los mismos encabezamientos no se recuperan si la búsqueda usa el término unesco
.
Entonces una primera aproximación puede ser: aplicar la conversión solamente a nombres personales. Problema: en la base name
no hemos guardado el tipo de encabezamiento (100, 110, 111).
TO-DO: estudiar el uso del gizmo dictgiz, y ver qué relación tiene con este problema. Ver http://catalis.uns.edu.ar/dokuwiki/doku.php/notas/diccionario_del_opac
ATENCION: Tener en cuenta que el tratamiento que demos a los apóstrofes para la búsqueda por palabras en las bases de encabezamientos debe ser consistente con el que les demos al buscar en la base bibliográfica (dictgiz tiene que ver un poco). Esto es útil, por ejemplo, para que una búsqueda de “Darcy Thompson” hecha por error en el campo título nos permita obtener un link a la misma búsqueda (exitosa) en el campo autor (el autor es D'Arcy Wentworth Thompson). En el caso de la base bibliográfica, ¿en qué campos aplicamos la supresión de apóstrofes?
Veamos entonces cuál es el mecanismo que usaremos para resolver este problema en el OPAC.
Este es el comando que usamos en update_db.py
para generar el invertido de la base name
:
mx name fst=@HEADINGS.FST actab=AC-ANSI.TAB uctab=UC-ANSI.TAB fullinv=name
La parte de headings.fst
que afecta la búsqueda por palabras es:
0 0 /* Invertimos todos los subcampos, palabra por palabra */ 1 4 proc('a1002¦',replace(v1*1,'~','¦a1002¦'),'¦'), (v1002*1/)
Si queremos que al pasar al diccionario O'Reilly
se convierta en OREILLY
y Arnol´d
en ARNOLD
, necesitamos suprimir los apóstrofes y similares, antes de que entre en efecto el parámetro actab
para separar en palabras. Esto puede lograrse desde la misma FST (usando la función replace
), o bien usando un gizmo. Dado que nos interesa aplicar exactamente las mismas sustituciones tanto a los datos de la base como al input del usuario, parece conveniente usar un único gizmo que sea llamado desde update_db.py
y desde opac.xis
(función cleanQuery
).
Recordemos que en la versión 5.2 de la interfaz CISIS podemos aplicar un gizmo como parte de un proc; esto nos permite aplicar el gizmo al procesar la consulta del usuario con wxis. Ver en el manual de referencia de CISIS, Función G<gizmo_mf>[,<taglist>]. Otra novedad en esta versión: la limpieza que hacíamos con una FST se puede realizar usando “proc='Gsplit=1=words'”
(con la actab apropiada).
Un detalle que habría que revisar: el resaltado de los términos usados en la consulta no funciona correctamente; por ejemplo, al buscar arnold
se recupera Arnol´d
, pero no se resalta la cadena.
Las referencias de “véase además” se generan a partir de los campos 5xx de los registros de autoridad. Se emplean para conducir al usuario desde un encabezamiento autorizado a otro encabezamiento relacionado, también autorizado.
Usos típicos de estos campos (según Maxwell's guide to authority work):
La visualización de las referencias puede aparecer en al menos estos dos contextos:
En el caso 1 no tenemos opción: es indispensable que el usuario, al ver la lista de registros asociados al encabezamiento H1, sepa que el catálogo le puede ofrecer registros relacionados, asociados a otros encabezamientos.
En el caso 2 no resulta tan claro: podríamos optar entre presentar las referencias de véase además junto a los encabezamientos que las tengan, o bien diferir esa información hasta que el usuario haya efectuado una búsqueda usando uno de esos encabezamientos.
Veamos qué esperamos del OPAC en cada uno de estos casos.
Tomemos el caso de Lewis Carroll, para quien tenemos estos dos registros de autoridad:
100 1_ |a Carroll, Lewis, |d 1832-1898 400 1_ |a Karol, Luis, |d 1832-1898 500 1_ |a Dodgson, Charles Lutwidge, |d 1832-1898
100 1_ |a Dodgson, Charles Lutwidge, |d 1832-1898 400 1_ |a Dodgson, C. L. |q (Charles Lutwidge), |d 1832-1898 500 1_ |a Carroll, Lewis, |d 1832-1898
En el listado de autores podríamos presentar esta visualización:
... Carroll, Lewis, 1832-1898 ... Dodgson, C. L. (Charles Lutwidge), 1832-1898 véase: Dodgson, Charles Lutwidge, 1832-1898 ... Dodgson, Charles Lutwidge, 1832-1898 ... Karol, Luis, 1832-1898 véase: Carroll, Lewis, 1832-1898 ...
Allí sólo estamos mostrando las referencias de véase (de los campos 4xx).