cgspace-notes/docs/2023-03/index.html

397 lines
21 KiB
HTML
Raw Normal View History

2023-03-01 06:30:25 +01:00
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta property="og:title" content="March, 2023" />
<meta property="og:description" content="2023-03-01
Remove cg.subject.wle and cg.identifier.wletheme from CGSpace input form after confirming with IWMI colleagues that they no longer need them (WLE closed in 2021)
iso-codes 4.13.0 was released, which incorporates my changes to the common names for Iran, Laos, and Syria
2023-03-07 07:53:31 +01:00
I finally got through with porting the input form from DSpace 6 to DSpace 7
2023-03-01 06:30:25 +01:00
" />
<meta property="og:type" content="article" />
<meta property="og:url" content="https://alanorth.github.io/cgspace-notes/2023-03/" />
<meta property="article:published_time" content="2023-03-01T07:58:36+03:00" />
2023-03-09 15:01:50 +01:00
<meta property="article:modified_time" content="2023-03-08T18:53:32+03:00" />
2023-03-01 06:30:25 +01:00
<meta name="twitter:card" content="summary"/>
<meta name="twitter:title" content="March, 2023"/>
<meta name="twitter:description" content="2023-03-01
Remove cg.subject.wle and cg.identifier.wletheme from CGSpace input form after confirming with IWMI colleagues that they no longer need them (WLE closed in 2021)
iso-codes 4.13.0 was released, which incorporates my changes to the common names for Iran, Laos, and Syria
2023-03-07 07:53:31 +01:00
I finally got through with porting the input form from DSpace 6 to DSpace 7
2023-03-01 06:30:25 +01:00
"/>
<meta name="generator" content="Hugo 0.110.0">
<script type="application/ld+json">
{
"@context": "http://schema.org",
"@type": "BlogPosting",
"headline": "March, 2023",
"url": "https://alanorth.github.io/cgspace-notes/2023-03/",
2023-03-09 15:01:50 +01:00
"wordCount": "1433",
2023-03-01 06:30:25 +01:00
"datePublished": "2023-03-01T07:58:36+03:00",
2023-03-09 15:01:50 +01:00
"dateModified": "2023-03-08T18:53:32+03:00",
2023-03-01 06:30:25 +01:00
"author": {
"@type": "Person",
"name": "Alan Orth"
},
"keywords": "Notes"
}
</script>
<link rel="canonical" href="https://alanorth.github.io/cgspace-notes/2023-03/">
<title>March, 2023 | CGSpace Notes</title>
<!-- combined, minified CSS -->
<link href="https://alanorth.github.io/cgspace-notes/css/style.c6ba80bc50669557645abe05f86b73cc5af84408ed20f1551a267bc19ece8228.css" rel="stylesheet" integrity="sha256-xrqAvFBmlVdkWr4F&#43;GtzzFr4RAjtIPFVGiZ7wZ7Ogig=" crossorigin="anonymous">
<!-- minified Font Awesome for SVG icons -->
<script defer src="https://alanorth.github.io/cgspace-notes/js/fontawesome.min.f5072c55a0721857184db93a50561d7dc13975b4de2e19db7f81eb5f3fa57270.js" integrity="sha256-9QcsVaByGFcYTbk6UFYdfcE5dbTeLhnbf4HrXz&#43;lcnA=" crossorigin="anonymous"></script>
<!-- RSS 2.0 feed -->
</head>
<body>
<div class="blog-masthead">
<div class="container">
<nav class="nav blog-nav">
<a class="nav-link " href="https://alanorth.github.io/cgspace-notes/">Home</a>
</nav>
</div>
</div>
<header class="blog-header">
<div class="container">
<h1 class="blog-title" dir="auto"><a href="https://alanorth.github.io/cgspace-notes/" rel="home">CGSpace Notes</a></h1>
<p class="lead blog-description" dir="auto">Documenting day-to-day work on the <a href="https://cgspace.cgiar.org">CGSpace</a> repository.</p>
</div>
</header>
<div class="container">
<div class="row">
<div class="col-sm-8 blog-main">
<article class="blog-post">
<header>
<h2 class="blog-post-title" dir="auto"><a href="https://alanorth.github.io/cgspace-notes/2023-03/">March, 2023</a></h2>
<p class="blog-post-meta">
<time datetime="2023-03-01T07:58:36+03:00">Wed Mar 01, 2023</time>
in
<span class="fas fa-folder" aria-hidden="true"></span>&nbsp;<a href="/categories/notes/" rel="category tag">Notes</a>
</p>
</header>
<h2 id="2023-03-01">2023-03-01</h2>
<ul>
<li>Remove <code>cg.subject.wle</code> and <code>cg.identifier.wletheme</code> from CGSpace input form after confirming with IWMI colleagues that they no longer need them (WLE closed in 2021)</li>
<li><a href="https://salsa.debian.org/iso-codes-team/iso-codes/-/blob/main/CHANGELOG.md#4130-2023-02-28">iso-codes 4.13.0 was released</a>, which incorporates my changes to the common names for Iran, Laos, and Syria</li>
2023-03-07 07:53:31 +01:00
<li>I finally got through with porting the input form from DSpace 6 to DSpace 7</li>
2023-03-01 06:30:25 +01:00
</ul>
2023-03-07 07:53:31 +01:00
<ul>
<li>I can&rsquo;t put my finger on it, but the input form has to be formatted very particularly, for example if your rows have more than two fields in them with out a sufficient Bootstrap grid style, or if you use a <code>twobox</code>, etc, the entire form step appears blank</li>
</ul>
<h2 id="2023-03-02">2023-03-02</h2>
<ul>
<li>I did some experiments with the new <a href="https://datapythonista.me/blog/pandas-20-and-the-arrow-revolution-part-i">Pandas 2.0.0rc0 Apache Arrow support</a>
<ul>
<li>There is a change to the way nulls are handled and it causes my tests for <code>pd.isna(field)</code> to fail</li>
<li>I think we need consider blanks as null, but I&rsquo;m not sure</li>
</ul>
</li>
<li>I made some adjustments to the Discovery sidebar facets on DSpace 6 while I was looking at the DSpace 7 configuration
<ul>
<li>I downgraded CIFOR subject, Humidtropics subject, Drylands subject, ICARDA subject, and Language from DiscoverySearchFilterFacet to DiscoverySearchFilter in <code>discovery.xml</code> since we are no longer using them in sidebar facets</li>
</ul>
</li>
</ul>
<h2 id="2023-03-03">2023-03-03</h2>
<ul>
<li>Atmire merged one of my old pull requests into COUNTER-Robots:
<ul>
<li><a href="https://github.com/atmire/COUNTER-Robots/pull/54">COUNTER_Robots_list.json: Add new bots</a></li>
</ul>
</li>
<li>I will update the local ILRI overrides in our DSpace spider agents file</li>
</ul>
<h2 id="2023-03-04">2023-03-04</h2>
<ul>
<li>Submit a <a href="https://github.com/flyingcircusio/pycountry/pull/156">pull request on pycountry to use iso-codes 4.13.0</a></li>
</ul>
<h2 id="2023-03-05">2023-03-05</h2>
<ul>
<li>Start a harvest on AReS</li>
</ul>
<h2 id="2023-03-06">2023-03-06</h2>
<ul>
<li>Export CGSpace to do Initiative collection mappings
<ul>
<li>There were thirty-three that needed updating</li>
</ul>
</li>
<li>Send Abenet and Sam a list of twenty-one CAS publications that had been marked as &ldquo;multiple documents&rdquo; that we uploaded as metadata-only items
<ul>
<li>Goshu will download the PDFs for each and upload them to the items on CGSpace manually</li>
</ul>
</li>
<li>I spent some time trying to get csv-metadata-quality working with the new Arrow backend for Pandas 2.0.0rc0
<ul>
<li>It seems there is a problem recognizing empty strings as na with <code>pd.isna()</code></li>
<li>If I do <code>pd.isna(field) or field == &quot;&quot;</code> then it works as expected, but that feels hacky</li>
<li>I&rsquo;m going to test again on the next release&hellip;</li>
<li>Note that I had been setting both of these global options:</li>
</ul>
</li>
</ul>
<pre tabindex="0"><code>pd.options.mode.dtype_backend = &#39;pyarrow&#39;
pd.options.mode.nullable_dtypes = True
</code></pre><ul>
<li>Then reading the CSV like this:</li>
</ul>
<pre tabindex="0"><code>df = pd.read_csv(args.input_file, engine=&#39;pyarrow&#39;, dtype=&#39;string[pyarrow]&#39;
2023-03-07 08:05:12 +01:00
</code></pre><h2 id="2023-03-07">2023-03-07</h2>
2023-03-07 15:15:26 +01:00
<ul>
<li>Create a PostgreSQL 14 instance on my local environment to start testing compatibility with DSpace 6 as well as all my scripts:</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-console" data-lang="console"><span style="display:flex;"><span>$ podman pull docker.io/library/postgres:14-alpine
</span></span><span style="display:flex;"><span>$ podman run --name dspacedb14 -v dspacedb14_data:/var/lib/postgresql/data -e POSTGRES_PASSWORD<span style="color:#f92672">=</span>postgres -p 5432:5432 -d postgres:14-alpine
</span></span><span style="display:flex;"><span>$ createuser -h localhost -p <span style="color:#ae81ff">5432</span> -U postgres --pwprompt dspacetest
</span></span><span style="display:flex;"><span>$ createdb -h localhost -p <span style="color:#ae81ff">5432</span> -U postgres -O dspacetest --encoding<span style="color:#f92672">=</span>UNICODE dspacetest
</span></span></code></pre></div><ul>
<li>Peter sent me a list of items that had ILRI affiation on Altmetric, but that didn&rsquo;t have Handles
<ul>
<li>I ran a duplicate check on them to find if they exist or if we can import them</li>
<li>There were about ninety matches, but a few dozen of those were pre-prints!</li>
<li>After excluding those there were about sixty-one items we already have on CGSpace so I will add their DOIs to the existing items
<ul>
<li>After joining these with the records from CGSpace and inspecting the DOIs I found that only forty-four were new DOIs</li>
<li>Surprisingly some of the DOIs on Altmetric were not working, though we also had some that were not working (specifically the Journal of Agricultural Economics seems to have reassigned DOIs)</li>
</ul>
</li>
2023-03-08 16:53:32 +01:00
<li>For the rest of the ~359 items I extracted their DOIs and looked up the metadata on Crossref using my <code>crossref-doi-lookup.py</code> script
<ul>
<li>After spending some time cleaning the data in OpenRefine I realized we don&rsquo;t get access status from Crossref</li>
<li>We can imply it if the item is Creative Commons, but otherwise I might be able to use <a href="https://unpaywall.org/products/api">Unpaywall&rsquo;s API</a></li>
<li>I found some false positives in Unpaywall, so I might only use their data when it says the DOI is not OA&hellip;</li>
</ul>
</li>
2023-03-07 15:15:26 +01:00
</ul>
</li>
2023-03-08 16:53:32 +01:00
<li>During this process I updated my <code>crossref-doi-lookup.py</code> script to get more information from Crossref like ISSNs, ISBNs, full journal title, and subjects</li>
2023-03-07 15:15:26 +01:00
<li>An unscientific comparison of duplicate checking Peter&rsquo;s file with ~500 titles on PostgreSQL 12 and PostgreSQL 14:
<ul>
<li>PostgreSQL 12: <code>0.11s user 0.04s system 0% cpu 19:24.65 total</code></li>
<li>PostgreSQL 14: <code>0.12s user 0.04s system 0% cpu 18:13.47 total</code></li>
</ul>
</li>
</ul>
2023-03-08 16:53:32 +01:00
<h2 id="2023-03-08">2023-03-08</h2>
<ul>
<li>I am wondering how to speed up PostgreSQL trgm searches more
<ul>
<li>I see my local PostgreSQL is using vanilla configuration and I should update some configs:</li>
</ul>
</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-console" data-lang="console"><span style="display:flex;"><span>localhost/dspacetest= ☘ SELECT setting, unit FROM pg_settings WHERE name = &#39;shared_buffers&#39;;
</span></span><span style="display:flex;"><span> setting │ unit
</span></span><span style="display:flex;"><span>─────────┼──────
</span></span><span style="display:flex;"><span> 16384 │ 8kB
</span></span><span style="display:flex;"><span>(1 row)
</span></span></code></pre></div><ul>
<li>I re-created my PostgreSQL 14 container with some extra memory settings:</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-console" data-lang="console"><span style="display:flex;"><span>$ podman run --name dspacedb14 -v dspacedb14_data:/var/lib/postgresql/data -e POSTGRES_PASSWORD<span style="color:#f92672">=</span>postgres -p 5432:5432 -d postgres:14-alpine -c shared_buffers<span style="color:#f92672">=</span>1024MB -c random_page_cost<span style="color:#f92672">=</span>1.1
</span></span></code></pre></div><ul>
<li>Then I created a GiST <a href="https://alexklibisz.com/2022/02/18/optimizing-postgres-trigram-search">index on the <code>metadatavalue</code> table to try to speed up the trgm similarity operations</a>:</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-console" data-lang="console"><span style="display:flex;"><span>localhost/dspacetest= ☘ CREATE INDEX metadatavalue_text_value_trgm_gist_idx ON metadatavalue USING gist(text_value gist_trgm_ops(siglen=64)); # \di+ shows index size is 795MB
</span></span></code></pre></div><ul>
<li>That took a few minutes to build&hellip; then the duplicate checker ran in 12 minutes: <code>0.07s user 0.02s system 0% cpu 12:43.08 total</code></li>
<li>On a hunch, I tried with a GIN index:</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-console" data-lang="console"><span style="display:flex;"><span>localhost/dspacetest= ☘ CREATE INDEX metadatavalue_text_value_trgm_gin_idx ON metadatavalue USING gin(text_value gin_trgm_ops); # \di+ shows index size is 274MB
</span></span></code></pre></div><ul>
<li>This ran in 19 minutes: <code>0.08s user 0.01s system 0% cpu 19:49.73 total</code>
<ul>
<li>So clearly the GiST index is better for this task</li>
<li>I am curious if I increase the signature length in the GiST index from 64 to 256 (which will for sure increase the size taken):</li>
</ul>
</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-console" data-lang="console"><span style="display:flex;"><span>localhost/dspacetest= ☘ CREATE INDEX metadatavalue_text_value_trgm_gist_idx ON metadatavalue USING gist(text_value gist_trgm_ops(siglen=256)); # \di+ shows index size is 716MB, which is less than the previous GiST index...
</span></span></code></pre></div><ul>
<li>This one finished in ten minutes: <code>0.07s user 0.02s system 0% cpu 10:04.04 total</code></li>
<li>I might also want to <a href="https://stackoverflow.com/questions/43008382/postgresql-gin-index-slower-than-gist-for-pg-trgm">increase my <code>work_mem</code></a> (default 4MB):</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-console" data-lang="console"><span style="display:flex;"><span>localhost/dspacetest= ☘ SELECT setting, unit FROM pg_settings WHERE name = &#39;work_mem&#39;;
</span></span><span style="display:flex;"><span> setting │ unit
</span></span><span style="display:flex;"><span>─────────┼──────
</span></span><span style="display:flex;"><span> 4096 │ kB
</span></span><span style="display:flex;"><span>(1 row)
</span></span></code></pre></div><ul>
<li>After updating my Crossref lookup script and checking the remaining ~359 items I found a eight more duplicates already existing on CGSpace</li>
<li>Wow, I found a <a href="https://programminghistorian.org/en/lessons/fetch-and-parse-data-with-openrefine#example-1-fetching-and-parsing-html">really cool way to fetch URLs in OpenRefine</a>
<ul>
<li>I used this to fetch the open access status for each DOI from Unpaywall</li>
</ul>
</li>
<li>First, create a new column called &ldquo;url&rdquo; based on the DOI that builds the request URL. I used a Jython expression:</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span>unpaywall_baseurl <span style="color:#f92672">=</span> <span style="color:#e6db74">&#39;https://api.unpaywall.org/v2/&#39;</span>
</span></span><span style="display:flex;"><span>email <span style="color:#f92672">=</span> <span style="color:#e6db74">&#34;a.orth+unpaywall@cgiar.org&#34;</span>
</span></span><span style="display:flex;"><span>doi <span style="color:#f92672">=</span> value<span style="color:#f92672">.</span>replace(<span style="color:#e6db74">&#34;https://doi.org/&#34;</span>, <span style="color:#e6db74">&#34;&#34;</span>)
</span></span><span style="display:flex;"><span>request_url <span style="color:#f92672">=</span> unpaywall_baseurl <span style="color:#f92672">+</span> doi <span style="color:#f92672">+</span> <span style="color:#e6db74">&#39;?email=&#39;</span> <span style="color:#f92672">+</span> email
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">return</span> request_url
</span></span></code></pre></div><ul>
<li>Then create a new column based on fetching the values in that column. I called it &ldquo;unpaywall_status&rdquo;</li>
<li>Then you get a JSON blob in each and you can extract the Open Access status with a GREL like <code>value.parseJson()['is_oa']</code>
<ul>
<li>I checked a handful of results manually and found that the limited access status was more trustworthy from Unpaywall than the open access, so I will just tag the limited access ones</li>
</ul>
</li>
<li>I merged the funders and affiliations from Altmetric into my file, then used the same technique to get Crossref data for open access items directly into OpenRefine and parsed the abstracts
<ul>
<li>The syntax was hairy because it&rsquo;s marked up with tags like <code>&lt;jats:p&gt;</code>, but this got me most of the way there:</li>
</ul>
</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-console" data-lang="console"><span style="display:flex;"><span>value.replace(&#34;jats:p&#34;, &#34;jats-p&#34;).parseHtml().select(&#34;jats-p&#34;)[0].innerHtml()
</span></span><span style="display:flex;"><span>value.replace(&#34;&lt;jats:italic&gt;&#34;,&#34;&#34;).replace(&#34;&lt;/jats:italic&gt;&#34;, &#34;&#34;)
</span></span><span style="display:flex;"><span>value.replace(&#34;&lt;jats:sub&gt;&#34;,&#34;&#34;).replace(&#34;&lt;/jats:sub&gt;&#34;, &#34;&#34;).replace(&#34;&lt;jats:sup&gt;&#34;,&#34;&#34;).replace(&#34;&lt;/jats:sup&gt;&#34;, &#34;&#34;)
</span></span></code></pre></div><ul>
<li>I uploaded the 350 items to DSpace Test so Peter and Abenet can explore them</li>
2023-03-09 15:01:50 +01:00
<li>I exported a list of authors, affiliations, and funders from the new items to let Peter correct them:</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-console" data-lang="console"><span style="display:flex;"><span>$ csvcut -c dc.contributor.author /tmp/new-items.csv | sed -e 1d -e <span style="color:#e6db74">&#39;s/&#34;//g&#39;</span> -e <span style="color:#e6db74">&#39;s/||/\n/g&#39;</span> | sort | uniq -c | sort -nr | awk <span style="color:#e6db74">&#39;{$1=&#34;&#34;; print $0}&#39;</span> | sed -e <span style="color:#e6db74">&#39;s/^ //&#39;</span> &gt; /tmp/new-authors.csv
</span></span></code></pre></div><ul>
2023-03-08 16:53:32 +01:00
<li>Meeting with FAO AGRIS team about how to detect duplicates
<ul>
<li>They are currently using a sha256 hash on titles, which will work, but will only return exact matches</li>
<li>I told them to try to normalize the string, drop stop words, etc to increase the possibility that the hash matches</li>
</ul>
</li>
<li>Meeting with Abenet to discuss CGSpace issues
<ul>
<li>She reminded me about needing a metadata field for first author when the affiliation is ILRI</li>
<li>I said I prefer to write a small script for her that will check the first author and first affiliation&hellip; I could do it easily in Python, but would need to put a web frontend on it for her</li>
<li>Unless we could do that in AReS reports somehow</li>
</ul>
</li>
</ul>
2023-03-09 15:01:50 +01:00
<h2 id="2023-03-09">2023-03-09</h2>
<ul>
<li>Apply a bunch of corrections to authors, affiliations, and donors on the new items on DSpace Test</li>
<li>Meeting with Peter and Abenet about future OpenRXV developments, DSpace 7, etc
<ul>
<li>I submitted an <a href="https://github.com/CodeObia/MEL/issues/11173">issue on MEL asking them to add provenance metadata when submitting to CGSpace</a></li>
</ul>
</li>
</ul>
2023-03-07 08:05:12 +01:00
<!-- raw HTML omitted -->
2023-03-01 06:30:25 +01:00
</article>
</div> <!-- /.blog-main -->
<aside class="col-sm-3 ml-auto blog-sidebar">
<section class="sidebar-module">
<h4>Recent Posts</h4>
<ol class="list-unstyled">
<li><a href="/cgspace-notes/2023-03/">March, 2023</a></li>
<li><a href="/cgspace-notes/2023-02/">February, 2023</a></li>
<li><a href="/cgspace-notes/2023-01/">January, 2023</a></li>
<li><a href="/cgspace-notes/2022-12/">December, 2022</a></li>
<li><a href="/cgspace-notes/2022-11/">November, 2022</a></li>
</ol>
</section>
<section class="sidebar-module">
<h4>Links</h4>
<ol class="list-unstyled">
<li><a href="https://cgspace.cgiar.org">CGSpace</a></li>
<li><a href="https://dspacetest.cgiar.org">DSpace Test</a></li>
<li><a href="https://github.com/ilri/DSpace">CGSpace @ GitHub</a></li>
</ol>
</section>
</aside>
</div> <!-- /.row -->
</div> <!-- /.container -->
<footer class="blog-footer">
<p dir="auto">
Blog template created by <a href="https://twitter.com/mdo">@mdo</a>, ported to Hugo by <a href='https://twitter.com/mralanorth'>@mralanorth</a>.
</p>
<p>
<a href="#">Back to top</a>
</p>
</footer>
</body>
</html>