Skip to content

Commit a695eb2

Browse files
committed
Merge remote-tracking branch 'upstream/bugfix/pubmed-citations' into bugfix/pubmed-citations
2 parents 0a041cf + 874db5e commit a695eb2

4 files changed

Lines changed: 118 additions & 64 deletions

File tree

server/workers/common/common/utils.py

Lines changed: 50 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -128,30 +128,49 @@ def push_metadata_to_queue(
128128
redis_store: redis.Redis,
129129
params: Dict[str, Union[str, List[str]]],
130130
metadata: pd.DataFrame,
131-
source: Literal["crossref", "altmetric"]
131+
source_list: List[str]
132132
) -> str:
133133
"""
134134
Sending metadata for processing into Redis queue and returning the request_id.
135135
136136
:param redis_store: Object of the Redis store.
137137
:param params: Request params.
138138
:param metadata: DataFrame with default metadata.
139-
:param source: define from which service additional metadata will be received.
139+
:param source_list: define from which service additional metadata will be received (available values: "crossref", "altmetric").
140140
:return: request_id for the receiving of the request result.
141141
"""
142+
# Checks that valid values are specified in the source array
143+
check_metadata_enrichment_source(source_list)
142144

145+
# Creates a new unique request identifier that will then be used to retrieve the result
143146
request_id = str(uuid.uuid4())
144-
params["metrics_sources"] = [source]
147+
148+
# Specifies from which sources to obtain information
149+
params["metrics_sources"] = source_list
150+
151+
# Payload object creation
145152
task_data = json.dumps({
146153
"id": request_id,
147154
"params": params,
148155
"metadata": metadata.to_json(orient="records"),
149156
})
150157

158+
# Pushing request to Redis and returning request id
151159
redis_store.rpush("metrics", task_data)
152160
return request_id
153161

154162

163+
def check_metadata_enrichment_source(source_list: List[str]) -> None:
164+
"""
165+
Checks that valid values are specified in the source array.
166+
167+
:param source_list: List of sources from where metadata will be enriched.
168+
:return: None.
169+
"""
170+
if not all(source in ("crossref", "altmetric") for source in source_list):
171+
raise ValueError("Source list must contain only 'crossref' or 'altmetric'")
172+
173+
155174
def fetch_enriched_metadata(redis_store: redis.Redis, request_id: str, timeout: int = 600) -> pd.DataFrame:
156175
"""
157176
Getting enriched metadata from Redis.
@@ -161,23 +180,29 @@ def fetch_enriched_metadata(redis_store: redis.Redis, request_id: str, timeout:
161180
:param timeout: Results waiting time (default - 600 seconds).
162181
:return: Enriched DataFrame with metadata.
163182
"""
183+
# Getting result of metadata enrichment from Redis
164184
result = get_key(redis_store, request_id, timeout)
165185
return pd.DataFrame(result["input_data"])
166186

167187

168-
def get_metadata_columns_for_integration(integration: Literal["pubmed", "orcid"]):
188+
def get_metadata_columns_for_source(source_list: List[str]) -> List[str]:
169189
"""
170-
Returning required metadata columns for different integrations.
190+
Returning required metadata columns for different sources.
171191
172-
:param integration: integration service.
192+
:param source_list: List of sources from where metadata received.
173193
:return: array with required metadata columns.
174194
"""
195+
# Checks that valid values are specified in the source array
196+
check_metadata_enrichment_source(source_list)
197+
198+
# Define required metadata columns for different sources and return them
199+
result = []
175200

176-
if integration == 'pubmed':
177-
return ["citation_count"]
178-
elif integration == 'orcid':
179-
return [
180-
"citation_count",
201+
if "crossref" in source_list:
202+
result.extend(["citation_count"])
203+
204+
if "altmetric" in source_list:
205+
result.extend([
181206
"cited_by_wikipedia_count",
182207
"cited_by_msm_count",
183208
"cited_by_policies_count",
@@ -190,21 +215,24 @@ def get_metadata_columns_for_integration(integration: Literal["pubmed", "orcid"]
190215
"cited_by_qna_count",
191216
"cited_by_tweeters_count",
192217
"cited_by_videos_count"
193-
]
218+
])
194219

195-
return []
220+
return result
196221

197222

198-
def ensure_required_columns(metadata: pd.DataFrame, integration: Literal["pubmed", "orcid"]) -> pd.DataFrame:
223+
def ensure_required_columns(metadata: pd.DataFrame, source_list: List[str]) -> pd.DataFrame:
199224
"""
200225
Checks that all necessary columns are available or adding them with NaN value.
201226
202227
:param metadata: DataFrame with metadata.
203-
:param integration: integration service.
228+
:param source_list: List of sources from where metadata received.
204229
:return: Updated DataFrame.
205230
"""
231+
# Checks that valid values are specified in the source array
232+
check_metadata_enrichment_source(source_list)
206233

207-
columns = get_metadata_columns_for_integration(integration)
234+
# Gets metadata columns that must be received from source(-s)
235+
columns = get_metadata_columns_for_source(source_list)
208236
for column in columns:
209237
if column not in metadata.columns:
210238
metadata[column] = np.NaN
@@ -216,26 +244,27 @@ def enrich_metadata(
216244
redis: redis.Redis,
217245
params: Dict[str, Union[str, List[str]]],
218246
metadata: pd.DataFrame,
219-
source: Literal["crossref", "altmetric"],
220-
integration: Literal["pubmed", "orcid"]
247+
source_list: List[str],
221248
) -> pd.DataFrame:
222249
"""
223250
Enriching metadata - adding information about citations from Redis.
224251
225252
:param redis: store object of Redis.
226253
:param params: params of the request.
227254
:param metadata: DataFrame with default metadata.
228-
:param source: define from which service additional metadata will be received.
255+
:param source: define from which service additional metadata will be received (available values: "crossref", "altmetric").
229256
:return: Enriched DataFrame with metadata.
230257
"""
258+
# Checks that valid values are specified in the source array
259+
check_metadata_enrichment_source(source_list)
231260

232261
# Creates a request to metrics for metadata enrichment
233262
# and returns request_id for receiving the result later
234-
request_id = push_metadata_to_queue(redis, params, metadata, source)
263+
request_id = push_metadata_to_queue(redis, params, metadata, source_list)
235264

236265
# Getting the result after metadata enrichment at metrics
237266
enriched_metadata = fetch_enriched_metadata(redis, request_id)
238267

239268
# Checks that all necessary columns are available or adding them with NaN value
240-
enriched_metadata = ensure_required_columns(enriched_metadata, integration)
269+
enriched_metadata = ensure_required_columns(enriched_metadata, source_list)
241270
return enriched_metadata

server/workers/orcid/src/orcid_service.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -388,9 +388,10 @@ def _retrieve_author_info_and_metadata(self, orcid: Orcid) -> Tuple[AuthorInfo,
388388

389389
def _process_metadata(self, metadata: pd.DataFrame, author_info: AuthorInfo, params: Dict[str, str]) -> pd.DataFrame:
390390
metadata["authors"] = metadata["authors"].replace("", author_info.author_name)
391-
source_for_metadata_enrichment = "crossref"
392-
integration = 'orcid'
393-
metadata = enrich_metadata(self.redis_store, params, metadata, source_for_metadata_enrichment, integration)
391+
392+
source_for_metadata_enrichment = ["crossref", "altmetric"]
393+
metadata = enrich_metadata(self.redis_store, params, metadata, source_for_metadata_enrichment)
394+
394395
self.logger.debug(f'metadata shape after base enrichment: {metadata.shape}')
395396
author_info = self.enrich_author_info(author_info, metadata, params)
396397
self.logger.debug(f'metadata shape after enrichment: {metadata.shape}')

server/workers/pubmed/src/pubmed.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,9 @@ def execute_search(self, params):
4141
return raw_metadata
4242

4343
metadata = pd.DataFrame(raw_metadata)
44-
source_for_metadata_enrichment = "crossref"
45-
integration = 'pubmed'
4644

47-
metadata = enrich_metadata(self.redis_store, params, metadata, source_for_metadata_enrichment, integration)
45+
source_for_metadata_enrichment = ["crossref"]
46+
metadata = enrich_metadata(self.redis_store, params, metadata, source_for_metadata_enrichment)
4847

4948
text = pd.DataFrame(raw_text)
5049

vis/js/templates/Paper.tsx

Lines changed: 62 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ const orderPriorityMap = {
1515
cited_by_accounts_count: "social",
1616
references: "references",
1717
readers: "readers",
18-
tweets: "tweets"
19-
}
18+
tweets: "tweets",
19+
};
2020

2121
class Paper extends React.Component {
2222
constructor(props) {
@@ -108,18 +108,35 @@ class Paper extends React.Component {
108108
}
109109

110110
render() {
111-
const { data, zoom, selected, hovered, maxSize, enlargeFactor, onClick, onMouseOver, onMouseOut } = this.props;
111+
const {
112+
data,
113+
zoom,
114+
selected,
115+
hovered,
116+
maxSize,
117+
enlargeFactor,
118+
onClick,
119+
onMouseOver,
120+
onMouseOut,
121+
} = this.props;
112122

113123
const {
114124
title,
115125
authors_string: authors,
116126
authors_list: authors_list,
117127
year,
118128
area,
119-
published_in: publisher
129+
published_in: publisher,
120130
} = data;
121131

122-
const { x, y, width: baseWidth, height: baseHeight, path: basePath, dogEar: baseDogEar } = this.state;
132+
const {
133+
x,
134+
y,
135+
width: baseWidth,
136+
height: baseHeight,
137+
path: basePath,
138+
dogEar: baseDogEar,
139+
} = this.state;
123140

124141
const {
125142
showSocialMedia,
@@ -135,14 +152,7 @@ class Paper extends React.Component {
135152
tweetsLabel,
136153
} = this.props;
137154

138-
const {
139-
// num_readers:
140-
readers,
141-
tweets,
142-
citations,
143-
social,
144-
references,
145-
} = data;
155+
const { readers, tweets, citations, social, references } = data;
146156

147157
let { width: realWidth, height: realHeight } =
148158
this.getCoordinatesAndDimensions();
@@ -226,11 +236,10 @@ class Paper extends React.Component {
226236
value: citations,
227237
label: citationsLabel,
228238
},
229-
// consider to refactor and retrieve correct data from the backend side instead of doing this hack with citations for pubmed
230239
{
231240
id: "citations pubmed",
232241
show: showPubmedCitations,
233-
value: readers,
242+
value: citations,
234243
label: citationsLabel,
235244
},
236245
{
@@ -257,15 +266,14 @@ class Paper extends React.Component {
257266
value: tweets,
258267
label: tweetsLabel,
259268
},
260-
].filter(stat => stat.show)
269+
].filter((stat) => stat.show);
261270

262271
let sortedStats = stats;
263272

264273
if (this.props.scaleValue) {
265274
const { scaleValue } = this.props;
266275

267-
268-
const tagPreference = orderPriorityMap[scaleValue]
276+
const tagPreference = orderPriorityMap[scaleValue];
269277

270278
sortedStats = tagPreference
271279
? [...stats].sort((a, b) => {
@@ -354,20 +362,35 @@ class Paper extends React.Component {
354362
)}
355363
</p>
356364
</div>
357-
{(hovered ? sortedStats : sortedStats.slice(0, 1)).map(({ value, label, id }) => (
358-
<div key={id} className="stat" style={{
359-
textWrap: 'nowrap'
360-
}}>
361-
<p id="stat" className={sizeModifierClass}>
362-
<span style={{
363-
textWrap: 'nowrap'
364-
}} className="num-stat">{value || value === 0 ? value : "n/a"} </span>
365-
<span style={{
366-
textWrap: 'nowrap'
367-
}}>{label}</span>
368-
</p>
369-
</div>
370-
))}
365+
{(hovered ? sortedStats : sortedStats.slice(0, 1)).map(
366+
({ value, label, id }) => (
367+
<div
368+
key={id}
369+
className="stat"
370+
style={{
371+
textWrap: "nowrap",
372+
}}
373+
>
374+
<p id="stat" className={sizeModifierClass}>
375+
<span
376+
style={{
377+
textWrap: "nowrap",
378+
}}
379+
className="num-stat"
380+
>
381+
{value || value === 0 ? value : "n/a"}{" "}
382+
</span>
383+
<span
384+
style={{
385+
textWrap: "nowrap",
386+
}}
387+
>
388+
{label}
389+
</span>
390+
</p>
391+
</div>
392+
)
393+
)}
371394
</div>
372395
</div>
373396
</foreignObject>
@@ -506,8 +529,9 @@ const DOGEAR_WIDTH = 0.15;
506529
const DOGEAR_HEIGHT = 0.15;
507530

508531
const getDogEar = ({ x, y, width: w, height: h }) => {
509-
return `M ${x + (1 - DOGEAR_WIDTH) * w} ${y} v ${DOGEAR_HEIGHT * h} h ${DOGEAR_WIDTH * w
510-
}`;
532+
return `M ${x + (1 - DOGEAR_WIDTH) * w} ${y} v ${DOGEAR_HEIGHT * h} h ${
533+
DOGEAR_WIDTH * w
534+
}`;
511535
};
512536

513537
const getRoundedPath = ({ x, y, width, height }) => {
@@ -527,8 +551,9 @@ const getRoundedPath = ({ x, y, width, height }) => {
527551
};
528552

529553
const getSquarePath = ({ x, y, width: w, height: h }) => {
530-
return `M ${x} ${y} h ${(1 - DOGEAR_WIDTH) * w} l ${DOGEAR_HEIGHT * w} ${DOGEAR_WIDTH * h
531-
} v ${(1 - DOGEAR_HEIGHT) * h} h ${-w} v ${-h}`;
554+
return `M ${x} ${y} h ${(1 - DOGEAR_WIDTH) * w} l ${DOGEAR_HEIGHT * w} ${
555+
DOGEAR_WIDTH * h
556+
} v ${(1 - DOGEAR_HEIGHT) * h} h ${-w} v ${-h}`;
532557
};
533558

534559
const getEnlargeFactor = (offsetWidth, scrollHeight) => {
@@ -551,7 +576,7 @@ const getEnlargeFactor = (offsetWidth, scrollHeight) => {
551576

552577
const getMetadataHeight = (realHeight, numOfLabels, isZoomed) => {
553578
let readersHeight = 0;
554-
579+
555580
if (numOfLabels && isZoomed) {
556581
readersHeight += numOfLabels * 12 + 10;
557582
}

0 commit comments

Comments
 (0)