El proceso rmfit
rmfit (/groups/rdeboer1/user/rdeboer1/R-matrix/rmfit/, README allí) hace lo que un
evaluador hace a mano -- pulir, invertir signos de interferencia, agregar o eliminar niveles, desactivar
conjuntos de datos sospechosos -- como pasos reanudables que un script ejecuta en un nodo de clúster y
una sesión nueva puede retomar desde STATUS.md. No está instalado como paquete:
export PYTHONPATH=/groups/rdeboer1/user/rdeboer1/R-matrix
python3 -m rmfit.cli <carpeta_campaña> <comando> [opciones]
Lea este archivo de arriba a abajo antes del primer comando en una reacción nueva; para reanudar una campaña, "Leer el estado" y "El bucle" son suficientes. Las mejoras van en el registro al final.
1. Leer el estado, nunca recalcularlo
Una carpeta de campaña lleva todo lo que una sesión nueva necesita:
STATUS.md-- mejor objetivo verificado por estructura, rondas recientes y líneas de registro. Regenerar constatus;status --jsonpara un volcado compacto.readme-- el cuaderno de laboratorio (rmfit añade un párrafo por ronda; agregue el suyo conlog "..."). Convención de archivo: léalo antes de tocar cualquier cosa.campaign.log-- cada línea que imprimió el controlador;rmfit_sge.log/rmfit_*.log-- registros de trabajos del clúster.ledger.sqlite+candidates/*.npz-- cada vector candidato y su puntuación. El incumbente es el mejor candidato con una puntuaciónverified(una evaluación de sesión única fresca del modelo completo). Los números fragmentados clasifican; los números verificados se reportan.campaign.json-- modelo base, banderas del motor, número de fragmentos, política de límites, configuración de búsqueda.<reacción>.azr+.sav-- la exportación revisable en GUI del incumbente.variants/-- archivos de fragmentos, modelos de ventana, archivos con/sin nivel (descartables).
qstat -u $USER primero: un comando de campaña a la vez por carpeta (comparten el
ledger y variants/). El nodo de inicio de sesión es para status, report, log, export,
pruebas cortas (<= 6 workers, <= 30 min). Todo lo demás se ejecuta como un trabajo.
2. Iniciar una campaña en una reacción nueva
Requisitos previos (hacerlos en la carpeta de ajuste de la reacción, no en la campaña):
- Un
.azrque se abra en la GUI, condata/, un directoriooutput/y unreadme. Conozca las banderas de modo CLI que usa esta reacción (--use-brune,--ignore-externals,--no-long-wavelength, ...): no están en el.azr, varían por reacción (~/R-matrix/CLAUDE.md), y rmfit las necesita como JSON--flags. - Reproduzca el último ajuste terminado antes de construir sobre él: cargue su
param.savpor nombre (pyazr), confirme que el objetivo coincida conchiSquared.out(chi2 + penalización de norma), luego hornéelo en un archivo limpio (rmfit.engine.bake) y verifíquelo con la CLI en modo 1 con un archivo externo en blanco. Nunca confíe en una horneada que fue "verificada" con el.savcomo archivo externo (eso anula<levels>), y nunca use parámetros de un ajuste en ejecución o bloqueado -- solo el último completado. Depure líneas de nivel inactivas. - Fusione cualquier nuevo conjunto de datos en el archivo horneado (
AzrModel.add_data_segment), limitado al rango de energía que cubre el esquema de niveles (set_segment_energy_range), con normalizaciones libres y un error sistemático que refleje el artículo. Mire cada archivo nuevo: una sola sección transversal negativa o con picos puede dominar el objetivo. - Registre todo eso en el
readmedel directorio de la reacción.
Primeros ajustes: construir parámetros iniciales antes de cualquier ajuste global (DeBoer, 2026-10-25 -- RE-EVALUAR MÁS TARDE)
Provisional. Esta es la sugerencia general de DeBoer, escrita antes de que se probara de principio a fin. Re-evalúela una vez
10B+α (la primera reacción en usarlo, 10B+a/10-25-26_Rmatrix_Claude) tenga un ajuste real: registre qué funcionó y qué
no aquí, y cambie o elimine el procedimiento en consecuencia.
DeBoer: "Fije las normas de un conjunto de datos representativo pero deje que los otros varíen. Esto proporciona entonces una escala más fija para las secciones transversales inicialmente, pero aún permite que conjuntos de datos con normas inconsistentes pero formas consistentes no dificulten el ajuste. En nuestro caso, como tenemos datos en todos los canales, sugeriría que fijemos nuestros datos al principio y dejemos que los otros varíen. Además, debemos asegurarnos de permitir que los canales l más bajos para cada par de partículas varíen, dándole un valor pequeño no nulo para cada nivel, incluso si la literatura no le da una rama a ese canal. También sugeriría comenzar en baja energía y hacer algunos pulidos en un nivel a la vez para ver qué tan bien puede coincidir con los datos. Luego volver e intentar agregar niveles donde las resonancias están claramente presentes que no coinciden con ninguno de los niveles conocidos en energía y/o ancho. No intentaría un ajuste real hasta que tenga parámetros iniciales razonablemente buenos."
Como procedimiento:
- Fije la escala con un conjunto de datos representativo. Fije sus normas en 1 (nuestros propios datos cuando cubren cada canal); deje que la norma de cada otro conjunto varíe. Los conjuntos con formas consistentes pero una escala diferente entonces no frenan el ajuste.
- Siembre el canal de L más bajo de cada par, para cada nivel. Asígnele una amplitud pequeña no nula (0.01 γ_W, configurada en el motor; marcadores de posición físicos diminutos, consulte la entrada de siembra del 2026-10-25), incluso donde la literatura no lista ninguna rama a ese canal.
- Cada canal que se abre dentro del rango de ajuste está en el modelo -- por defecto. Cada vez que se extiende el rango de ajuste
(una nueva ventana de energía, o un conjunto de datos que alcanza más alto), liste cada partición abierta por debajo del TOPE del
rango: cada estado excitado de cada núcleo residual (ENSDF) y las otras particiones de partículas ligeras (d, t,
³He, ...), con umbrales Ex = sepE + e2. Agregue un par para cada uno antes de ajustar, sin que se lo pidan: el L
permitido más bajo de cada espín de canal en cada nivel; sembrado según el punto 2 en niveles en o dentro de 0.5 MeV por debajo del
umbral y en polos de fondo, inerte (0, fijo) en otros lugares. Agregue las nuevas salidas a cada segmento sumado
(secciones transversales totales, total (n,p), (n,α), ...). NO limite una ventana de datos en un umbral en su lugar. Un límite es un
parche temporal: regístrelo en el readme con el canal que lo forzó, y lístelo para el evaluador.
(DeBoer 2026-10-30, extensión HE de ¹¹B+α: la sección transversal total de ¹⁴N+n de ELBE se había limitado a E_n 5.1 MeV porque
¹⁴N(n,n₄) no tenía par. Eso dejó la parte superior de 1.2 MeV del ajuste sin su restricción más fuerte, un total de norma fija.
Ejemplo de constructor:
11B+a/10-27-26_HE_claude/model/add_pairs_he.py, 7 pares n4 a3 d0 p1 n5 n6 p2.) - Nivel por nivel, desde baja energía hacia arriba. Pula un nivel a la vez (su energía y anchos, más las normas libres) contra los datos a su alrededor, y observe qué tan bien puede coincidir.
- Luego agregue niveles donde una resonancia está claramente presente y ningún nivel conocido coincide con ella en energía y/o ancho.
- Solo entonces un ajuste real (global):
initde una campaña en el resultado.
Por qué (etapa 1 de ¹⁰B+α, 2026-10-25): los pulidos globales desde un inicio pobre (χ²/N ≈ 200, niveles del 2-27-25 con nuevos
canales cerca de cero) intercambiaron la fuerza faltante por normalizaciones. Con cada norma libre, casi todas cayeron a
0.38-0.68 en 150 evaluaciones. Limitadas a 0.7-1.5, ocho se sentaron en un límite y el ajuste se estancó en χ²/N 12.7. Con
χ² ~ 10⁵, los priores de norma de unos pocos por ciento no costaron nada (10B+a/10-25-26_rmfit_stage1, _stage1b).
Luego, en un nuevo directorio de campaña con fecha (<reacción>/<M>-<D>-<YY>_rmfit_campaign/):
mkdir <dir> && cp <base>.azr <dir>/ && cp -r data <dir>/data && mkdir <dir>/output
python3 -m rmfit.cli <dir> init --base <dir>/<base>.azr [--sav <base>.sav] --nshards 24 \
--flags '{"use_long_wavelength": false, "ignore_externals": true, "use_brune": true}' \
--policy '{"theta2_cap": 1.0, "bg_theta2_cap": 3.0, "bg_energy": <Ex por encima de los datos>, "e_window": 0.3, "norm_range": [0.2, 5.0]}' \
--search '{"top_k": 6, "pairs_per_group": 4, "stage1_nfev": 30, "stage2_nfev": 60, "union_nfev": 100}'
--flags se pasa directamente a pyazr.azure2(), por lo que la parametrización se elige allí:
"use_brune": true (Brune, el predeterminado del archivo), "use_park": true (Park: el vector de ajuste
contiene las amplitudes de ancho reducido observadas, Gamma = 2 P gamma^2; consulte la habilidad de AZURE2 sobre
"Parametrización de Park"), "use_brune": false (Lane-Thomas estándar). Una base por
campaña -- los vectores del ledger, las instantáneas .npz y los acompañantes .sav están todos en ella.
Opcional --objective JSON (campaign.json objective, deBoer et al. 2017 Sec. sobre ajuste):
{"dataset_weight": "reduced", "dataset_key": "file", "loss": "sivia"}.
dataset_weight: reduced es el método de chi-cuadrado reducido (el chi-cuadrado de cada conjunto de datos
dividido por su número de puntos, reescalado por N/K para que el objetivo mantenga una magnitud de
chi-cuadrado; filas de penalización sin ponderar) -- evita que un conjunto grande con errores pequeños
domine; loss: sivia reemplaza el chi-cuadrado por el PDF más amplio de Sivia,
-2 log[(1 - e^{-R^2/2})/R^2] - 2 log 2 (~R^2/2 para residuos pequeños, ~2 log R^2 para valores atípicos:
los valores atípicos se ponderan hacia abajo como si su barra de error estuviera inflada). La pérdida de Sivia se aplica
a los residuos estandarizados por el chi2/N de referencia de cada conjunto de datos (loss_scale: dataset, escalas calculadas por init a partir de la línea base simple y almacenadas en campaign.json):
sin eso, en un modelo con chi2/N ~ 20-300 cada punto se sienta en la cola logarítmica,
los datos pierden ~10x su peso contra las penalizaciones cuadráticas de norma y el ajuste se desvía
(¹³C+a, 2026-09-08: chi2 simple 701k -> 1,190k en un pulido, MANA abandonado, normas ajustadas
al nominal). Ambos métodos son "estadísticamente incorrectos pero útiles cuando las barras de error están
subestimadas". El objetivo es una propiedad de una campaña: los candidatos verificados bajo diferentes objetivos no son
comparables, por lo que un cambio de objetivo significa un nuevo directorio de campaña (siémbrelo con la
exportación anterior). REPORT.md y segment_scores mantienen el chi-cuadrado simple por conjunto de datos
sea cual sea el objetivo. Verificado en rmfit/tests/test_objective_13n.py.
init verifica la línea base (una evaluación de modelo completo), registra la estructura,
escribe STATUS.md y el script de trabajo run_crc_rmfit (nodo long de 24 núcleos, envía correo a
[email protected], -m abe). Volver a ejecutar init mantiene una configuración existente a menos que se den nuevos valores.
Significados de la política: theta2_cap es el límite de Wigner para niveles físicos,
bg_theta2_cap para polos de fondo (niveles con Ex >= bg_energy, cuyas energías permanecen
fijas) -- 3.0 es una estimación inicial, no un valor predeterminado de física: verifique dónde están ya las amplitudes de fondo
de la línea base (la auditoría de límites de init) antes de confiar en él; la elástica ¹²C+alfa
necesitó ~100 (consulte la entrada de registro del 2026-09-30); e_window es la libertad de energía de un nivel por pulido (MeV); norm_range
multiplica la normalización nominal. narrow_window (opcional, p.ej.
{"gamma_kev": 5, "factor": 3, "min_kev": 1}) mantiene un nivel cuyos anchos parciales libres suman
menos de gamma_kev dentro de ±max(min_kev, factor·Γ) de su energía actual en lugar de
±e_window, por lo que un pulido no puede llevar un nivel estrecho lejos de su pico (el 9/2+
de ¹³C+a derivó 180 keV en un pulido de ajuste). Número de fragmentos = núcleos; la fragmentación es exacta
(chi-cuadrado es aditivo sobre segmentos), por lo que más fragmentos solo compran velocidad.
Verificación de costos en un modelo nuevo (campaign.log después de init): un objetivo fragmentado debería
ser de unos segundos y un Jacobiano de decenas de segundos. Si un segmento con convolución de efecto objetivo
domina (como lo hizo Cierjacks en ¹³C+a), rmfit lo pliega él mismo (model.ConvSpec);
se permiten segmentos "suma" compuestos como piezas de convolución.
2b. Especificación, auditoría, decisiones (2026-11-07; Fase 1 de R-matrix/rmfit/DESIGN.md)
Antes de init, escriba la especificación de la campaña (spec.json, plantilla rmfit/templates/SPEC_TEMPLATE.json, esquema en
rmfit/spec.py): cada conjunto de datos con su función (anchor = norma fija en el nominal; free con prior_sigma; excluded
con la razón; screen), la ventana de ajuste, el bloque congelado, los pares que deben existir, los límites / objetivo / búsqueda, lo que
el controlador puede hacer por su cuenta (pre_authorized: adopt_level verdadero / falso / reglas, flip_adopt, dataset_off_adopt, ...),
las reglas de parada y las decisiones en curso con su propietario y fecha. Luego:
python3 -m rmfit.audit <base>.azr --out AUDIT.md # pre-vuelo, sin sesión de motor: anchos libres cero, fusiones de 1 keV,
# normas nominales != 1, normError como FRACCIÓN, columnas FLAG como
# errores, errores diminutos, duplicados, picos, umbrales, <targetInt>
# en segmentos de prueba, nombres .sav heredados, ruta de salida, pin del motor
python3 -m rmfit.cli <dir> init --base ... --spec spec.json # flags/policy/search/objective/nshards de la especificación a menos que
# se den; desacuerdos HIGH con el .azr rechazan el init
python3 -m rmfit.cli <dir> spec check # en cualquier momento: SPEC_CHECK.md; spec render -> SPEC.md; audit -> AUDIT.md
Un hallazgo HIGH de auditoría se corrige (o se registra como aceptado en las decisiones en curso de la especificación) antes de la línea base. Durante
la campaña, cualquier cosa que la especificación no responda va a DECISIONS.md (rmfit decisions lista, rmfit decide D-003 "adopt" --by DeBoer responde); una adición de nivel cuyo accept la especificación no pre-autoriza se registra como accept-pending
con una decisión en cola y NO se adopta (la adopción automática anterior solo se aplica a campañas sin especificación). Borradores de
especificación para copiar: 10B+a/11-6-26_s5_highE/spec_draft.json, 13C+a/11-06-26_merged_regionD/spec_draft.json.
Las tres revisiones de tiempo de inactividad de la sección 3b se generan, no se escriben a mano, desde el 2026-11-07:
python3 -m rmfit.cli <dir> audit --kind all # audits/{input,data,literature}/PROMPT.md + FINDINGS.md vacío
# entregue cada PROMPT.md a un subagente de fondo (Herramienta Agent, un modelo más barato, como máximo tres a la vez); este escribe FINDINGS.md
python3 -m rmfit.cli <dir> audit --findings # filas no verificadas (candidatas) de cada FINDINGS.md
python3 -m rmfit.cli <dir> audit --status data 1 confirmed --note "linea 4007 check
... [truncado para traducción]