Class VerifyPublicationEvidenceCli

All Implemented Interfaces:
org.springframework.beans.factory.Aware, org.springframework.beans.factory.InitializingBean, org.springframework.context.ApplicationContextAware, org.springframework.context.EnvironmentAware, CLI

public class VerifyPublicationEvidenceCli extends ExpressionExperimentManipulatingCLI
Check Gemma's GEO-sourced primary publications against what GEO says today, and fill in the ones GEO has a paper for and Gemma does not.

V25 asserted a basis for every publication link that existed when it ran, and for a GEO-accessioned dataset that basis is an inference: the GEO importer is the only writer that sets a primary without a human in the loop, so a primary on a GEO dataset is taken to be GEO's !Series_pubmed_id. That is why those 23,066 rows carry IIA — inferred from imported annotation — and not TAS. This command is what turns the inference into a check.

Why acc.cgi and not a batched esummary

🛑 An agreement with esummary db=gds would not be evidence of anything, and it is the disagreements it hides that matter. The gds index lags the live GEO record (ExpressionExperimentBibRefFinder.locatePubMedId(String) documents this, and chose acc.cgi for the same reason). Follow a re-pointed series through:

GEO moves GSE123 from paper A to paper B
Gemma still holds A          (imported before the change)
esummary still reports A     (lagging)
  => A == A, "verified", stamped TAS -- on the one link that has actually drifted

A drifted link is exactly the shape of a false agreement, so re-checking only the disagreements would never revisit it. Lag makes false MISMATCHES, which are harmless and self-correcting, and false MATCHES, which are not. So every series is read from acc.cgi — one request each, paced, and the run is resumable because at that rate it is measured in hours.

What it will and will not write

  • Agreement — the assertion is re-stated with TAS and evidence saying it was checked against GEO on the day it ran. The link itself is not touched; only its basis.
  • Disagreementnothing is written. It splits two ways that no automated rule can separate: a curator corrected GEO, or GEO is wrong (GSE227854, where the submitter cross-linked the wrong one of their own two papers). Both land in the change log for a person to read.
  • Gemma has no primary and GEO has one — added, under --fill. This is the case that creates a link rather than describing one.
  • GEO lists more than one paper — first is the primary, the rest are other-relevant. parseSeriesPubMedIds has always read them; nothing could act on them before.

A curator's assertion outranks GEO, so apply() in PublicationAssociationService silently declines a promotion over one. Silently is not good enough for a run whose output is a record of what changed, so the held assertion is read first and a curator-held row is reported as skipped rather than attempted.

Author:
claude