Salma Hassan commited on
Commit
50e583f
·
1 Parent(s): cac235b
.gitattributes CHANGED
@@ -33,3 +33,6 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ *.json filter=lfs diff=lfs merge=lfs -text
37
+ *.jsonl filter=lfs diff=lfs merge=lfs -text
38
+
app.py ADDED
@@ -0,0 +1,687 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # import gradio as gr
2
+ # import os
3
+ # import json
4
+ # from openai import AzureOpenAI
5
+ # from trialgpt_retrieval.retriever import retrieve_trials
6
+ # from nltk.tokenize import sent_tokenize
7
+ # import nltk
8
+
9
+ # # Download required NLTK data
10
+ # try:
11
+ # nltk.download('punkt')
12
+ # nltk.download('punkt_tab')
13
+ # except Exception as e:
14
+ # print(f"Warning: Could not download NLTK data: {e}")
15
+ # print("The app may still work but tokenization might fail.")
16
+
17
+ # # Check environment variables
18
+ # if not os.getenv("OPENAI_ENDPOINT") or not os.getenv("OPENAI_API_KEY"):
19
+ # print("Warning: OPENAI_ENDPOINT and OPENAI_API_KEY environment variables are required.")
20
+ # print("Please set these environment variables before running the app.")
21
+
22
+ # # Initialize the Azure OpenAI client
23
+ # client = AzureOpenAI(
24
+ # api_version="2023-09-01-preview",
25
+ # azure_endpoint=os.getenv("OPENAI_ENDPOINT"),
26
+ # api_key=os.getenv("OPENAI_API_KEY"),
27
+ # )
28
+
29
+ # def generate_keywords(note):
30
+ # system = 'You are a helpful assistant and your task is to help search relevant clinical trials for a given patient description. Please first summarize the main medical problems of the patient. Then generate up to 32 key conditions for searching relevant clinical trials for this patient. The key condition list should be ranked by priority. Please output only a JSON dict formatted as Dict{{"summary": Str(summary), "conditions": List[Str(condition)]}}.'
31
+ # prompt = f"Here is the patient description: \\n{note}\\n\\nJSON output:"
32
+ # messages = [
33
+ # {"role": "system", "content": system},
34
+ # {"role": "user", "content": prompt}
35
+ # ]
36
+
37
+ # try:
38
+ # response = client.chat.completions.create(
39
+ # model="gpt-35-turbo",
40
+ # messages=messages,
41
+ # temperature=0,
42
+ # max_tokens=4086,
43
+ # )
44
+
45
+ # output = response.choices[0].message.content
46
+
47
+ # if output is None:
48
+ # return "Error: Received empty response from the model.", []
49
+
50
+ # try:
51
+ # start = output.find('{')
52
+ # end = output.rfind('}')
53
+ # if start != -1 and end > start:
54
+ # json_output = output[start:end+1]
55
+ # data = json.loads(json_output)
56
+ # return data["summary"], data["conditions"]
57
+ # else:
58
+ # return "Error: No JSON found in model response.", []
59
+ # except (json.JSONDecodeError, KeyError) as e:
60
+ # return f"Error parsing model output: {e}", []
61
+
62
+ # except Exception as e:
63
+ # return f"Error calling OpenAI API: {e}", []
64
+
65
+ # def parse_criteria(criteria):
66
+ # output = ""
67
+ # criteria = criteria.split("\\n\\n")
68
+
69
+ # idx = 0
70
+ # for criterion in criteria:
71
+ # criterion = criterion.strip()
72
+ # if "inclusion criteria" in criterion.lower() or "exclusion criteria" in criterion.lower():
73
+ # continue
74
+ # if len(criterion) < 5:
75
+ # continue
76
+ # output += f"{idx}. {criterion}\\n"
77
+ # idx += 1
78
+ # return output
79
+
80
+ # def print_trial(trial_info: dict, inc_exc: str) -> str:
81
+ # trial = f"Title: {trial_info.get('title', 'N/A')}\\n"
82
+
83
+ # # Safely get metadata fields
84
+ # metadata = trial_info.get('metadata', {})
85
+ # diseases_list = metadata.get('diseases_list', [])
86
+ # drugs_list = metadata.get('drugs_list', [])
87
+
88
+ # trial += f"Target diseases: {', '.join(diseases_list) if diseases_list else 'N/A'}\\n"
89
+ # trial += f"Interventions: {', '.join(drugs_list) if drugs_list else 'N/A'}\\n"
90
+ # trial += f"Summary: {trial_info.get('text', 'N/A')}\\n"
91
+
92
+ # if inc_exc == "inclusion":
93
+ # inclusion_criteria = metadata.get('inclusion_criteria', 'No inclusion criteria available')
94
+ # trial += "Inclusion criteria:\\n %s\\n" % parse_criteria(inclusion_criteria)
95
+ # elif inc_exc == "exclusion":
96
+ # exclusion_criteria = metadata.get('exclusion_criteria', 'No exclusion criteria available')
97
+ # trial += "Exclusion criteria:\\n %s\\n" % parse_criteria(exclusion_criteria)
98
+ # return trial
99
+
100
+ # def get_matching_prompt(trial_info: dict, inc_exc: str, patient: str) -> tuple[str, str]:
101
+ # """Output the prompt."""
102
+ # prompt = f"You are a helpful assistant for clinical trial recruitment. Your task is to compare a given patient note and the {inc_exc} criteria of a clinical trial to determine the patient's eligibility at the criterion level.\\n"
103
+
104
+ # if inc_exc == "inclusion":
105
+ # prompt += "The factors that allow someone to participate in a clinical study are called inclusion criteria. They are based on characteristics such as age, gender, the type and stage of a disease, previous treatment history, and other medical conditions.\\n"
106
+
107
+ # elif inc_exc == "exclusion":
108
+ # prompt += "The factors that disqualify someone from participating are called exclusion criteria. They are based on characteristics such as age, gender, the type and stage of a disease, previous treatment history, and other medical conditions.\\n"
109
+
110
+ # prompt += f"You should check the {inc_exc} criteria one-by-one, and output the following three elements for each criterion:\\n"
111
+ # prompt += f"\\tElement 1. For each {inc_exc} criterion, briefly generate your reasoning process: First, judge whether the criterion is not applicable (not very common), where the patient does not meet the premise of the criterion. Then, check if the patient note contains direct evidence. If so, judge whether the patient meets or does not meet the criterion. If there is no direct evidence, try to infer from existing evidence, and answer one question: If the criterion is true, is it possible that a good patient note will miss such information? If impossible, then you can assume that the criterion is not true. Otherwise, there is not enough information.\\n"
112
+ # prompt += f"\\tElement 2. If there is relevant information, you must generate a list of relevant sentence IDs in the patient note. If there is no relevant information, you must annotate an empty list.\\n"
113
+ # prompt += f"\\tElement 3. Classify the patient eligibility for this specific {inc_exc} criterion: "
114
+
115
+ # if inc_exc == "inclusion":
116
+ # prompt += 'the label must be chosen from {"not applicable", "not enough information", "included", "not included"}. "not applicable" should only be used for criteria that are not applicable to the patient. "not enough information" should be used where the patient note does not contain sufficient information for making the classification. Try to use as less "not enough information" as possible because if the note does not mention a medically important fact, you can assume that the fact is not true for the patient. "included" denotes that the patient meets the inclusion criterion, while "not included" means the reverse.\\n'
117
+ # elif inc_exc == "exclusion":
118
+ # prompt += 'the label must be chosen from {"not applicable", "not enough information", "excluded", "not excluded"}. "not applicable" should only be used for criteria that are not applicable to the patient. "not enough information" should be used where the patient note does not contain sufficient information for making the classification. Try to use as less "not enough information" as possible because if the note does not mention a medically important fact, you can assume that the fact is not true for the patient. "excluded" denotes that the patient meets the exclusion criterion and should be excluded in the trial, while "not excluded" means the reverse.\\n'
119
+
120
+ # prompt += "You should output only a JSON dict exactly formatted as: dict{str(criterion_number): list[str(element_1_brief_reasoning), list[int(element_2_sentence_id)], str(element_3_eligibility_label)]}."
121
+
122
+ # user_prompt = f"Here is the patient note, each sentence is led by a sentence_id:\\n{patient}\\n\\n"
123
+ # user_prompt += f"Here is the clinical trial:\\n{print_trial(trial_info, inc_exc)}\\n\\n"
124
+ # user_prompt += f"Plain JSON output:"
125
+
126
+ # return prompt, user_prompt
127
+
128
+
129
+ # def trialgpt_matching(trial: dict, patient: str, model: str):
130
+ # results = {}
131
+ # for inc_exc in ["inclusion", "exclusion"]:
132
+ # system_prompt, user_prompt = get_matching_prompt(trial, inc_exc, patient)
133
+ # messages = [
134
+ # {"role": "system", "content": system_prompt},
135
+ # {"role": "user", "content": user_prompt},
136
+ # ]
137
+ # response = client.chat.completions.create(
138
+ # model=model,
139
+ # messages=messages,
140
+ # temperature=0,
141
+ # )
142
+ # message = response.choices[0].message.content.strip()
143
+ # start = message.find('{')
144
+ # end = message.rfind('}')
145
+ # if start != -1 and end > start:
146
+ # message = message[start:end+1]
147
+ # try:
148
+ # results[inc_exc] = json.loads(message)
149
+ # except (json.JSONDecodeError, TypeError):
150
+ # results[inc_exc] = {"error": "Failed to parse model output", "raw": message}
151
+ # return results
152
+
153
+ # def load_corpus(corpus="sigir"):
154
+ # corpus_path = f"dataset/{corpus}/corpus.jsonl"
155
+ # corpus_map = {}
156
+ # with open(corpus_path, "r") as f:
157
+ # for line in f:
158
+ # entry = json.loads(line)
159
+ # corpus_map[entry["_id"]] = entry
160
+ # return corpus_map
161
+
162
+ # corpus_data = load_corpus()
163
+
164
+ # # --- Trial Ranking (from trialgpt_ranking/rank_results.py) ---
165
+
166
+ # eps = 1e-9
167
+
168
+ # def get_matching_score(matching):
169
+ # included, not_inc, na_inc, no_info_inc = 0, 0, 0, 0
170
+ # excluded, not_exc, na_exc, no_info_exc = 0, 0, 0, 0
171
+
172
+ # if "inclusion" in matching:
173
+ # for criteria, info in matching["inclusion"].items():
174
+ # if len(info) == 3:
175
+ # if info[2] == "included": included += 1
176
+ # elif info[2] == "not included": not_inc += 1
177
+ # elif info[2] == "not applicable": na_inc += 1
178
+ # elif info[2] == "not enough information": no_info_inc += 1
179
+
180
+ # if "exclusion" in matching:
181
+ # for criteria, info in matching["exclusion"].items():
182
+ # if len(info) == 3:
183
+ # if info[2] == "excluded": excluded += 1
184
+ # elif info[2] == "not excluded": not_exc += 1
185
+ # elif info[2] == "not applicable": na_exc += 1
186
+ # elif info[2] == "not enough information": no_info_exc += 1
187
+
188
+ # score = 0
189
+ # if (included + not_inc + no_info_inc) > 0:
190
+ # score += included / (included + not_inc + no_info_inc + eps)
191
+ # if not_inc > 0: score -= 1
192
+ # if excluded > 0: score -= 1
193
+
194
+ # return score
195
+
196
+ # def get_clinical_trials(patient_details):
197
+ # # Check if environment variables are set
198
+ # if not os.getenv("OPENAI_ENDPOINT") or not os.getenv("OPENAI_API_KEY"):
199
+ # return "**Error:** Please set OPENAI_ENDPOINT and OPENAI_API_KEY environment variables before using this app."
200
+
201
+ # if not patient_details or patient_details.strip() == "":
202
+ # return "**Error:** Please enter patient details."
203
+
204
+ # try:
205
+ # summary, conditions = generate_keywords(patient_details)
206
+ # if isinstance(summary, str) and summary.startswith("Error"):
207
+ # return f"**Error:** {summary}"
208
+
209
+ # if not conditions:
210
+ # return "## No Conditions Identified\n\nUnable to identify medical conditions from the patient description. Please provide more detailed medical information."
211
+
212
+ # retrieved_nctids = retrieve_trials(conditions)
213
+ # if not retrieved_nctids:
214
+ # return "## No Matching Clinical Trials Found\n\nNo clinical trials were found matching the patient's conditions. Please try with different search terms or broader criteria."
215
+
216
+ # top_n_trials = retrieved_nctids[:5]
217
+
218
+ # sents = sent_tokenize(patient_details)
219
+ # sents.append("The patient will provide informed consent, and will comply with the trial protocol without any practical issues.")
220
+ # patient_processed = "\\n".join([f"{idx}. {sent}" for idx, sent in enumerate(sents)])
221
+
222
+ # results = []
223
+ # for nctid in top_n_trials:
224
+ # if nctid in corpus_data:
225
+ # try:
226
+ # trial_info = corpus_data[nctid]
227
+ # matching_result = trialgpt_matching(trial_info, patient_processed, "gpt-4")
228
+ # score = get_matching_score(matching_result)
229
+ # title = trial_info.get('title', 'Unknown Title')
230
+ # results.append({"title": title, "nctid": nctid, "score": score})
231
+ # except Exception as e:
232
+ # print(f"Warning: Error processing trial {nctid}: {e}")
233
+ # continue
234
+
235
+ # # Sort results by score
236
+ # results.sort(key=lambda x: x["score"], reverse=True)
237
+
238
+ # # Format output as a table
239
+ # output_str = "## Matching Clinical Trials\n\n"
240
+ # output_str += "| Rank | Trial | NCT ID | Summary | Score | Link |\n"
241
+ # output_str += "|------|-------|--------|---------|-------|------|\n"
242
+
243
+ # for rank, res in enumerate(results):
244
+ # # Get trial info for summary
245
+ # trial_info = corpus_data.get(res['nctid'], {})
246
+ # metadata = trial_info.get('metadata', {})
247
+ # brief_summary = metadata.get('brief_summary', 'No summary available')
248
+
249
+ # # Truncate summary to ~100 characters
250
+ # if len(brief_summary) > 100:
251
+ # brief_summary = brief_summary[:97] + "..."
252
+
253
+ # # Color coding based on rank
254
+ # if rank == 0:
255
+ # color = "🟢" # Green for top rank
256
+ # elif rank == 1:
257
+ # color = "🟡" # Yellow for second rank
258
+ # elif rank == 2:
259
+ # color = "🟠" # Orange for third rank
260
+ # elif rank == 3:
261
+ # color = "🔴" # Red for fourth rank
262
+ # else:
263
+ # color = "⚫" # Black for fifth rank
264
+
265
+ # # Create ClinicalTrials.gov link
266
+ # ct_link = f"https://clinicaltrials.gov/study/{res['nctid']}"
267
+
268
+ # output_str += f"| {color} {rank+1} | {res['title']} | {res['nctid']} | {brief_summary} | {res['score']:.2f} | [View Trial]({ct_link}) |\n"
269
+
270
+ # return output_str
271
+
272
+ # except Exception as e:
273
+ # return f"**Error:** An unexpected error occurred: {str(e)}"
274
+
275
+ # if __name__ == "__main__":
276
+ # # Wrapper function for ChatInterface
277
+ # def chat_function(message, history):
278
+ # return get_clinical_trials(message)
279
+
280
+ # # Create chatbot using the new ChatInterface
281
+ # demo = gr.ChatInterface(
282
+ # fn=chat_function,
283
+ # title="Clinical Trial Matching Chatbot",
284
+ # description="AI-Powered Clinical Trial Matching Assistant. Describe a patient's condition and find matching clinical trials.",
285
+ # examples=[
286
+ # ["58-year-old African-American woman with hypertension and obesity presenting with new-onset episodic chest pain, radiating to the back, accompanied by nausea, diaphoresis, and mild dyspnea. EKG shows nonspecific changes."],
287
+ # ["45-year-old male with type 2 diabetes mellitus, HbA1c 8.2%, BMI 32, on metformin 1000mg twice daily. Recent diagnosis of diabetic neuropathy in both feet."],
288
+ # ["67-year-old female with stage III non-small cell lung cancer, ECOG performance status 1, no prior chemotherapy, EGFR mutation positive."]
289
+ # ],
290
+ # theme=gr.themes.Soft(
291
+ # primary_hue="blue",
292
+ # secondary_hue="gray",
293
+ # neutral_hue="slate"
294
+ # )
295
+ # )
296
+
297
+ # demo.launch(share=True)
298
+
299
+
300
+ import gradio as gr
301
+ import os
302
+ import json
303
+ import asyncio
304
+ import concurrent.futures
305
+ from openai import AzureOpenAI
306
+ from trialgpt_retrieval.retriever import retrieve_trials_gpu, create_retriever_session
307
+ from nltk.tokenize import sent_tokenize
308
+ import nltk
309
+ import hashlib
310
+ import time
311
+ from functools import lru_cache
312
+ from threading import Lock
313
+
314
+ # Download required NLTK data
315
+ try:
316
+ nltk.download('punkt')
317
+ nltk.download('punkt_tab')
318
+ except Exception as e:
319
+ print(f"Warning: Could not download NLTK data: {e}")
320
+
321
+ # Check environment variables
322
+ if not os.getenv("OPENAI_ENDPOINT") or not os.getenv("OPENAI_API_KEY"):
323
+ print("Warning: OPENAI_ENDPOINT and OPENAI_API_KEY environment variables are required.")
324
+
325
+ # Initialize the Azure OpenAI client
326
+ client = AzureOpenAI(
327
+ api_version="2023-09-01-preview",
328
+ azure_endpoint=os.getenv("OPENAI_ENDPOINT"),
329
+ api_key=os.getenv("OPENAI_API_KEY"),
330
+ )
331
+
332
+ # Global cache and locks for thread safety
333
+ cache = {}
334
+ cache_lock = Lock()
335
+ MAX_CACHE_SIZE = 1000
336
+
337
+ # Initialize persistent retriever session (major speedup)
338
+ print("Initializing GPU retriever session...")
339
+ retriever_session = create_retriever_session(use_gpu=True)
340
+ print("Retriever session ready!")
341
+
342
+ def get_cache_key(text):
343
+ """Generate cache key from text."""
344
+ return hashlib.md5(text.encode()).hexdigest()
345
+
346
+ def get_from_cache(key):
347
+ """Thread-safe cache retrieval."""
348
+ with cache_lock:
349
+ return cache.get(key)
350
+
351
+ def set_cache(key, value):
352
+ """Thread-safe cache storage with size limit."""
353
+ with cache_lock:
354
+ if len(cache) >= MAX_CACHE_SIZE:
355
+ # Remove oldest entries (simple FIFO)
356
+ oldest_keys = list(cache.keys())[:len(cache)//2]
357
+ for old_key in oldest_keys:
358
+ del cache[old_key]
359
+ cache[key] = value
360
+
361
+ @lru_cache(maxsize=100)
362
+ def generate_keywords_cached(note_hash, note):
363
+ """Cached keyword generation."""
364
+ system = 'You are a helpful assistant and your task is to help search relevant clinical trials for a given patient description. Please first summarize the main medical problems of the patient. Then generate up to 32 key conditions for searching relevant clinical trials for this patient. The key condition list should be ranked by priority. Please output only a JSON dict formatted as Dict{{"summary": Str(summary), "conditions": List[Str(condition)]}}.'
365
+ prompt = f"Here is the patient description: \\n{note}\\n\\nJSON output:"
366
+ messages = [
367
+ {"role": "system", "content": system},
368
+ {"role": "user", "content": prompt}
369
+ ]
370
+
371
+ try:
372
+ response = client.chat.completions.create(
373
+ model="gpt-35-turbo",
374
+ messages=messages,
375
+ temperature=0,
376
+ max_tokens=2048,
377
+ )
378
+
379
+ output = response.choices[0].message.content
380
+ if output is None:
381
+ return "Error: Received empty response from the model.", []
382
+
383
+ try:
384
+ start = output.find('{')
385
+ end = output.rfind('}')
386
+ if start != -1 and end > start:
387
+ json_output = output[start:end+1]
388
+ data = json.loads(json_output)
389
+ return data["summary"], data["conditions"]
390
+ else:
391
+ return "Error: No JSON found in model response.", []
392
+ except (json.JSONDecodeError, KeyError) as e:
393
+ return f"Error parsing model output: {e}", []
394
+
395
+ except Exception as e:
396
+ return f"Error calling OpenAI API: {e}", []
397
+
398
+ def generate_keywords(note):
399
+ """Wrapper for cached keyword generation."""
400
+ note_hash = get_cache_key(note)
401
+ return generate_keywords_cached(note_hash, note)
402
+
403
+ def parse_criteria(criteria):
404
+ output = ""
405
+ criteria = criteria.split("\\n\\n")
406
+
407
+ idx = 0
408
+ for criterion in criteria:
409
+ criterion = criterion.strip()
410
+ if "inclusion criteria" in criterion.lower() or "exclusion criteria" in criterion.lower():
411
+ continue
412
+ if len(criterion) < 5:
413
+ continue
414
+ output += f"{idx}. {criterion}\\n"
415
+ idx += 1
416
+ return output
417
+
418
+ def print_trial(trial_info: dict, inc_exc: str) -> str:
419
+ trial = f"Title: {trial_info.get('title', 'N/A')}\\n"
420
+
421
+ metadata = trial_info.get('metadata', {})
422
+ diseases_list = metadata.get('diseases_list', [])
423
+ drugs_list = metadata.get('drugs_list', [])
424
+
425
+ trial += f"Target diseases: {', '.join(diseases_list) if diseases_list else 'N/A'}\\n"
426
+ trial += f"Interventions: {', '.join(drugs_list) if drugs_list else 'N/A'}\\n"
427
+ trial += f"Summary: {trial_info.get('text', 'N/A')}\\n"
428
+
429
+ if inc_exc == "inclusion":
430
+ inclusion_criteria = metadata.get('inclusion_criteria', 'No inclusion criteria available')
431
+ trial += "Inclusion criteria:\\n %s\\n" % parse_criteria(inclusion_criteria)
432
+ elif inc_exc == "exclusion":
433
+ exclusion_criteria = metadata.get('exclusion_criteria', 'No exclusion criteria available')
434
+ trial += "Exclusion criteria:\\n %s\\n" % parse_criteria(exclusion_criteria)
435
+ return trial
436
+
437
+ def get_matching_prompt(trial_info: dict, inc_exc: str, patient: str) -> tuple[str, str]:
438
+ """Output the prompt."""
439
+ prompt = f"You are a helpful assistant for clinical trial recruitment. Your task is to compare a given patient note and the {inc_exc} criteria of a clinical trial to determine the patient's eligibility at the criterion level.\\n"
440
+
441
+ if inc_exc == "inclusion":
442
+ prompt += "The factors that allow someone to participate in a clinical study are called inclusion criteria. They are based on characteristics such as age, gender, the type and stage of a disease, previous treatment history, and other medical conditions.\\n"
443
+ elif inc_exc == "exclusion":
444
+ prompt += "The factors that disqualify someone from participating are called exclusion criteria. They are based on characteristics such as age, gender, the type and stage of a disease, previous treatment history, and other medical conditions.\\n"
445
+
446
+ prompt += f"You should check the {inc_exc} criteria one-by-one, and output the following three elements for each criterion:\\n"
447
+ prompt += f"\\tElement 1. For each {inc_exc} criterion, briefly generate your reasoning process: First, judge whether the criterion is not applicable (not very common), where the patient does not meet the premise of the criterion. Then, check if the patient note contains direct evidence. If so, judge whether the patient meets or does not meet the criterion. If there is no direct evidence, try to infer from existing evidence, and answer one question: If the criterion is true, is it possible that a good patient note will miss such information? If impossible, then you can assume that the criterion is not true. Otherwise, there is not enough information.\\n"
448
+ prompt += f"\\tElement 2. If there is relevant information, you must generate a list of relevant sentence IDs in the patient note. If there is no relevant information, you must annotate an empty list.\\n"
449
+ prompt += f"\\tElement 3. Classify the patient eligibility for this specific {inc_exc} criterion: "
450
+
451
+ if inc_exc == "inclusion":
452
+ prompt += 'the label must be chosen from {"not applicable", "not enough information", "included", "not included"}. "not applicable" should only be used for criteria that are not applicable to the patient. "not enough information" should be used where the patient note does not contain sufficient information for making the classification. Try to use as less "not enough information" as possible because if the note does not mention a medically important fact, you can assume that the fact is not true for the patient. "included" denotes that the patient meets the inclusion criterion, while "not included" means the reverse.\\n'
453
+ elif inc_exc == "exclusion":
454
+ prompt += 'the label must be chosen from {"not applicable", "not enough information", "excluded", "not excluded"}. "not applicable" should only be used for criteria that are not applicable to the patient. "not enough information" should be used where the patient note does not contain sufficient information for making the classification. Try to use as less "not enough information" as possible because if the note does not mention a medically important fact, you can assume that the fact is not true for the patient. "excluded" denotes that the patient meets the exclusion criterion and should be excluded in the trial, while "not excluded" means the reverse.\\n'
455
+
456
+ prompt += "You should output only a JSON dict exactly formatted as: dict{str(criterion_number): list[str(element_1_brief_reasoning), list[int(element_2_sentence_id)], str(element_3_eligibility_label)]}."
457
+
458
+ user_prompt = f"Here is the patient note, each sentence is led by a sentence_id:\\n{patient}\\n\\n"
459
+ user_prompt += f"Here is the clinical trial:\\n{print_trial(trial_info, inc_exc)}\\n\\n"
460
+ user_prompt += f"Plain JSON output:"
461
+
462
+ return prompt, user_prompt
463
+
464
+ def trialgpt_matching_single(trial: dict, patient: str, inc_exc: str, model: str):
465
+ """Single matching call for parallel processing."""
466
+ cache_key = get_cache_key(f"{trial.get('_id', '')}-{inc_exc}-{get_cache_key(patient)}")
467
+ cached_result = get_from_cache(cache_key)
468
+ if cached_result:
469
+ return inc_exc, cached_result
470
+
471
+ system_prompt, user_prompt = get_matching_prompt(trial, inc_exc, patient)
472
+ messages = [
473
+ {"role": "system", "content": system_prompt},
474
+ {"role": "user", "content": user_prompt},
475
+ ]
476
+
477
+ try:
478
+ response = client.chat.completions.create(
479
+ model=model,
480
+ messages=messages,
481
+ temperature=0,
482
+ )
483
+ message = response.choices[0].message.content.strip()
484
+ start = message.find('{')
485
+ end = message.rfind('}')
486
+ if start != -1 and end > start:
487
+ message = message[start:end+1]
488
+
489
+ result = json.loads(message)
490
+ set_cache(cache_key, result)
491
+ return inc_exc, result
492
+ except (json.JSONDecodeError, TypeError, Exception) as e:
493
+ result = {"error": f"Failed to parse model output: {e}", "raw": message if 'message' in locals() else "No response"}
494
+ return inc_exc, result
495
+
496
+ def trialgpt_matching_parallel(trial: dict, patient: str, model: str):
497
+ """Parallel processing of inclusion and exclusion criteria."""
498
+ with concurrent.futures.ThreadPoolExecutor(max_workers=2) as executor:
499
+ futures = [
500
+ executor.submit(trialgpt_matching_single, trial, patient, "inclusion", model),
501
+ executor.submit(trialgpt_matching_single, trial, patient, "exclusion", model)
502
+ ]
503
+
504
+ results = {}
505
+ for future in concurrent.futures.as_completed(futures):
506
+ try:
507
+ inc_exc, result = future.result(timeout=30) # 30 second timeout
508
+ results[inc_exc] = result
509
+ except concurrent.futures.TimeoutError:
510
+ print(f"Timeout for trial matching")
511
+ results[inc_exc] = {"error": "Timeout"}
512
+ except Exception as e:
513
+ print(f"Error in parallel matching: {e}")
514
+ results[inc_exc] = {"error": str(e)}
515
+
516
+ return results
517
+
518
+ # Load corpus once at startup
519
+ print("Loading corpus data...")
520
+ def load_corpus(corpus="sigir"):
521
+ corpus_path = f"dataset/{corpus}/corpus.jsonl"
522
+ corpus_map = {}
523
+ with open(corpus_path, "r") as f:
524
+ for line in f:
525
+ entry = json.loads(line)
526
+ corpus_map[entry["_id"]] = entry
527
+ return corpus_map
528
+
529
+ corpus_data = load_corpus()
530
+ print(f"Corpus loaded with {len(corpus_data)} trials")
531
+
532
+ # --- Optimized Trial Ranking ---
533
+ eps = 1e-9
534
+
535
+ def get_matching_score(matching):
536
+ included, not_inc, na_inc, no_info_inc = 0, 0, 0, 0
537
+ excluded, not_exc, na_exc, no_info_exc = 0, 0, 0, 0
538
+
539
+ if "inclusion" in matching:
540
+ for criteria, info in matching["inclusion"].items():
541
+ if len(info) == 3:
542
+ if info[2] == "included": included += 1
543
+ elif info[2] == "not included": not_inc += 1
544
+ elif info[2] == "not applicable": na_inc += 1
545
+ elif info[2] == "not enough information": no_info_inc += 1
546
+
547
+ if "exclusion" in matching:
548
+ for criteria, info in matching["exclusion"].items():
549
+ if len(info) == 3:
550
+ if info[2] == "excluded": excluded += 1
551
+ elif info[2] == "not excluded": not_exc += 1
552
+ elif info[2] == "not applicable": na_exc += 1
553
+ elif info[2] == "not enough information": no_info_exc += 1
554
+
555
+ score = 0
556
+ if (included + not_inc + no_info_inc) > 0:
557
+ score += included / (included + not_inc + no_info_inc + eps)
558
+ if not_inc > 0: score -= 1
559
+ if excluded > 0: score -= 1
560
+
561
+ return score
562
+
563
+ def get_clinical_trials(patient_details):
564
+ start_time = time.time()
565
+
566
+ # Check environment variables
567
+ if not os.getenv("OPENAI_ENDPOINT") or not os.getenv("OPENAI_API_KEY"):
568
+ return "**Error:** Please set OPENAI_ENDPOINT and OPENAI_API_KEY environment variables before using this app."
569
+
570
+ if not patient_details or patient_details.strip() == "":
571
+ return "**Error:** Please enter patient details."
572
+
573
+ try:
574
+ # Step 1: Generate keywords (cached)
575
+ keyword_start = time.time()
576
+ summary, conditions = generate_keywords(patient_details)
577
+ keyword_time = time.time() - keyword_start
578
+
579
+ if isinstance(summary, str) and summary.startswith("Error"):
580
+ return f"**Error:** {summary}"
581
+
582
+ if not conditions:
583
+ return "## No Conditions Identified\n\nUnable to identify medical conditions from the patient description."
584
+
585
+ # Step 2: Fast GPU-accelerated trial retrieval
586
+ retrieval_start = time.time()
587
+ retrieved_nctids = retrieve_trials_gpu(
588
+ conditions,
589
+ corpus="sigir",
590
+ top_k=5,
591
+ use_gpu=True,
592
+ retriever=retriever_session # Use persistent session
593
+ )
594
+ retrieval_time = time.time() - retrieval_start
595
+
596
+ if not retrieved_nctids:
597
+ return "## No Matching Clinical Trials Found\n\nNo clinical trials were found matching the patient's conditions."
598
+
599
+ # Step 3: Preprocess patient data once
600
+ processing_start = time.time()
601
+ sents = sent_tokenize(patient_details)
602
+ sents.append("The patient will provide informed consent, and will comply with the trial protocol without any practical issues.")
603
+ patient_processed = "\\n".join([f"{idx}. {sent}" for idx, sent in enumerate(sents)])
604
+ processing_time = time.time() - processing_start
605
+
606
+ # Step 4: Parallel trial matching
607
+ matching_start = time.time()
608
+ results = []
609
+
610
+ # Process trials in parallel batches
611
+ with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor:
612
+ future_to_nctid = {
613
+ executor.submit(
614
+ trialgpt_matching_parallel,
615
+ corpus_data[nctid],
616
+ patient_processed,
617
+ "gpt-4"
618
+ ): nctid
619
+ for nctid in retrieved_nctids[:5]
620
+ if nctid in corpus_data
621
+ }
622
+
623
+ for future in concurrent.futures.as_completed(future_to_nctid):
624
+ nctid = future_to_nctid[future]
625
+ try:
626
+ matching_result = future.result(timeout=60) # 60 second timeout per trial
627
+ score = get_matching_score(matching_result)
628
+ title = corpus_data[nctid].get('title', 'Unknown Title')
629
+ results.append({"title": title, "nctid": nctid, "score": score})
630
+ except Exception as e:
631
+ print(f"Warning: Error processing trial {nctid}: {e}")
632
+ continue
633
+
634
+ matching_time = time.time() - matching_start
635
+
636
+ # Step 5: Sort and format results
637
+ results.sort(key=lambda x: x["score"], reverse=True)
638
+
639
+ total_time = time.time() - start_time
640
+
641
+ # Format output
642
+ output_str = f"## Matching Clinical Trials\n\n"
643
+ output_str += f"*Processing time: {total_time:.1f}s (Keywords: {keyword_time:.1f}s, Retrieval: {retrieval_time:.1f}s, Matching: {matching_time:.1f}s)*\n\n"
644
+ output_str += "| Rank | Trial | NCT ID | Summary | Score | Link |\n"
645
+ output_str += "|------|-------|--------|---------|-------|------|\n"
646
+
647
+ for rank, res in enumerate(results):
648
+ trial_info = corpus_data.get(res['nctid'], {})
649
+ metadata = trial_info.get('metadata', {})
650
+ brief_summary = metadata.get('brief_summary', 'No summary available')
651
+
652
+ if len(brief_summary) > 100:
653
+ brief_summary = brief_summary[:97] + "..."
654
+
655
+ colors = ["🟢", "🟡", "🟠", "🔴", "⚫"]
656
+ color = colors[min(rank, len(colors)-1)]
657
+
658
+ ct_link = f"https://clinicaltrials.gov/study/{res['nctid']}"
659
+ output_str += f"| {color} {rank+1} | {res['title']} | {res['nctid']} | {brief_summary} | {res['score']:.2f} | [View Trial]({ct_link}) |\n"
660
+
661
+ return output_str
662
+
663
+ except Exception as e:
664
+ return f"**Error:** An unexpected error occurred: {str(e)}"
665
+
666
+ if __name__ == "__main__":
667
+ def chat_function(message, history):
668
+ return get_clinical_trials(message)
669
+
670
+ # Create optimized chatbot
671
+ demo = gr.ChatInterface(
672
+ fn=chat_function,
673
+ title="⚡ Fast Clinical Trial Matching Chatbot",
674
+ description="AI-Powered Clinical Trial Matching with GPU acceleration and parallel processing. Describe a patient's condition to find matching trials quickly.",
675
+ examples=[
676
+ ["A 39-year-old Thai male presents for study screening. He received his second dose of an approved mRNA COVID-19 vaccine (Pfizer) over 4 months ago and has remained in good health since. He has no history of COVID-19 infection, confirmed by a negative SARS-CoV-2 rapid antigen test today. He denies any chronic illness, does not take any medications, and has never had an adverse reaction to vaccines. He is sexually active and reports consistent condom use with his partner. He is interested in participating in a study assessing immune response to a new booster dose."],
677
+ ["A 19-year-old pregnant patient, receiving prenatal care at Johns Hopkins Hospital, is 28 weeks gestation and preparing to receive her first mRNA COVID-19 vaccine dose. She has no previous history of COVID-19 and no significant medical history. She meets eligibility criteria and is interested in contributing to research on pregnancy and vaccine-related immune responses."],
678
+ ["A 67-year-old male with relapsed/refractory multiple myeloma presents for enrollment into a post-trial access study. He previously participated in a Pfizer-sponsored parent study evaluating elranatamab, during which he achieved a partial response and remained clinically stable. At the time the parent trial ended, he was continuing on elranatamab with no evidence of disease progression or significant toxicity. He reports no history of psychiatric illness or lab abnormalities, and he wishes to continue treatment through this access program."]
679
+ ],
680
+ theme=gr.themes.Soft(
681
+ primary_hue="blue",
682
+ secondary_hue="gray",
683
+ neutral_hue="slate"
684
+ )
685
+ )
686
+
687
+ demo.launch(share=True)
dataset/sigir/corpus.jsonl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:eac4586f7bbba85701d947a3e5f29982bab5c13d0872152dbe88f7c734c0541a
3
+ size 16439575
dataset/sigir/id2queries.json ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7ca512ed2544fc598426e244ee5fe5d1095bea771c482102d6e84dda71de878a
3
+ size 77704
dataset/sigir/id2queries_old.json ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:787f959fa2d9121249e232d4aa675b95bac9614c6bcdf92548c1a78f1a9979c6
3
+ size 83410
dataset/sigir/qrels/test.tsv ADDED
@@ -0,0 +1,2144 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ query-id corpus-id score
2
+ sigir-20141 NCT00000408 0
3
+ sigir-20141 NCT00000492 1
4
+ sigir-20141 NCT00000501 0
5
+ sigir-20141 NCT00001853 0
6
+ sigir-20141 NCT00004727 0
7
+ sigir-20141 NCT00005127 2
8
+ sigir-20141 NCT00005485 2
9
+ sigir-20141 NCT00005757 2
10
+ sigir-20141 NCT00077948 0
11
+ sigir-20141 NCT00108381 0
12
+ sigir-20141 NCT00124969 0
13
+ sigir-20141 NCT00129233 1
14
+ sigir-20141 NCT00134160 0
15
+ sigir-20141 NCT00141583 1
16
+ sigir-20141 NCT00143195 2
17
+ sigir-20141 NCT00149227 1
18
+ sigir-20141 NCT00162344 1
19
+ sigir-20141 NCT00166231 0
20
+ sigir-20141 NCT00175279 2
21
+ sigir-20141 NCT00185120 0
22
+ sigir-20141 NCT00190489 0
23
+ sigir-20141 NCT00202566 0
24
+ sigir-20141 NCT00225355 1
25
+ sigir-20141 NCT00252421 0
26
+ sigir-20141 NCT00285649 0
27
+ sigir-20141 NCT00337116 0
28
+ sigir-20141 NCT00348803 0
29
+ sigir-20141 NCT00356707 0
30
+ sigir-20141 NCT00373828 2
31
+ sigir-20141 NCT00375089 0
32
+ sigir-20141 NCT00413712 0
33
+ sigir-20141 NCT00418392 0
34
+ sigir-20141 NCT00424021 0
35
+ sigir-20141 NCT00454662 0
36
+ sigir-20141 NCT00462241 0
37
+ sigir-20141 NCT00479908 1
38
+ sigir-20141 NCT00486954 0
39
+ sigir-20141 NCT00536224 0
40
+ sigir-20141 NCT00598728 0
41
+ sigir-20141 NCT00623454 0
42
+ sigir-20141 NCT00624273 0
43
+ sigir-20141 NCT00644319 0
44
+ sigir-20141 NCT00683813 2
45
+ sigir-20141 NCT00705952 0
46
+ sigir-20141 NCT00736333 0
47
+ sigir-20141 NCT00745043 0
48
+ sigir-20141 NCT00752674 0
49
+ sigir-20141 NCT00780260 0
50
+ sigir-20141 NCT00797953 1
51
+ sigir-20141 NCT00802230 1
52
+ sigir-20141 NCT00808652 1
53
+ sigir-20141 NCT00809029 2
54
+ sigir-20141 NCT00832442 2
55
+ sigir-20141 NCT00840593 0
56
+ sigir-20141 NCT00848250 0
57
+ sigir-20141 NCT00883987 0
58
+ sigir-20141 NCT00896285 0
59
+ sigir-20141 NCT00925119 0
60
+ sigir-20141 NCT00932867 0
61
+ sigir-20141 NCT00937365 0
62
+ sigir-20141 NCT00951808 0
63
+ sigir-20141 NCT00952744 2
64
+ sigir-20141 NCT00974116 0
65
+ sigir-20141 NCT00979199 1
66
+ sigir-20141 NCT00986180 0
67
+ sigir-20141 NCT00992927 0
68
+ sigir-20141 NCT01028534 0
69
+ sigir-20141 NCT01056367 0
70
+ sigir-20141 NCT01080274 0
71
+ sigir-20141 NCT01087723 0
72
+ sigir-20141 NCT01134328 0
73
+ sigir-20141 NCT01162902 1
74
+ sigir-20141 NCT01167205 0
75
+ sigir-20141 NCT01171911 0
76
+ sigir-20141 NCT01175889 0
77
+ sigir-20141 NCT01203696 1
78
+ sigir-20141 NCT01211171 0
79
+ sigir-20141 NCT01216020 0
80
+ sigir-20141 NCT01228123 0
81
+ sigir-20141 NCT01231165 1
82
+ sigir-20141 NCT01250262 0
83
+ sigir-20141 NCT01253486 2
84
+ sigir-20141 NCT01276548 0
85
+ sigir-20141 NCT01284179 0
86
+ sigir-20141 NCT01290770 0
87
+ sigir-20141 NCT01293019 0
88
+ sigir-20141 NCT01332188 0
89
+ sigir-20141 NCT01334203 0
90
+ sigir-20141 NCT01365286 0
91
+ sigir-20141 NCT01397994 1
92
+ sigir-20141 NCT01407146 1
93
+ sigir-20141 NCT01429194 1
94
+ sigir-20141 NCT01444833 0
95
+ sigir-20141 NCT01450020 0
96
+ sigir-20141 NCT01484912 0
97
+ sigir-20141 NCT01494870 0
98
+ sigir-20141 NCT01506999 0
99
+ sigir-20141 NCT01559948 0
100
+ sigir-20141 NCT01561001 0
101
+ sigir-20141 NCT01576978 0
102
+ sigir-20141 NCT01657136 0
103
+ sigir-20141 NCT01658033 0
104
+ sigir-20141 NCT01660594 1
105
+ sigir-20141 NCT01675362 0
106
+ sigir-20141 NCT01682057 1
107
+ sigir-20141 NCT01719952 0
108
+ sigir-20141 NCT01724567 2
109
+ sigir-20141 NCT01724996 0
110
+ sigir-20141 NCT01736306 0
111
+ sigir-20141 NCT01770080 0
112
+ sigir-20141 NCT01829659 1
113
+ sigir-20141 NCT01838616 0
114
+ sigir-20141 NCT01847014 0
115
+ sigir-20141 NCT01879293 0
116
+ sigir-20141 NCT01904695 0
117
+ sigir-20141 NCT02001545 1
118
+ sigir-20141 NCT02011646 0
119
+ sigir-20141 NCT02015858 0
120
+ sigir-20141 NCT02062424 1
121
+ sigir-20141 NCT02072694 0
122
+ sigir-20141 NCT02078921 0
123
+ sigir-20141 NCT02105220 0
124
+ sigir-20141 NCT02144636 1
125
+ sigir-20141 NCT02148289 0
126
+ sigir-20141 NCT02158962 0
127
+ sigir-20141 NCT02159625 0
128
+ sigir-20141 NCT02190123 0
129
+ sigir-20141 NCT02226510 0
130
+ sigir-20141 NCT02232607 0
131
+ sigir-20141 NCT02271568 1
132
+ sigir-20141 NCT02272920 1
133
+ sigir-20141 NCT02319161 0
134
+ sigir-20141 NCT02347111 0
135
+ sigir-20141 NCT02357212 1
136
+ sigir-20141 NCT02381340 2
137
+ sigir-20141 NCT02390323 0
138
+ sigir-20141 NCT02408263 0
139
+ sigir-20141 NCT02472938 0
140
+ sigir-20141 NCT02507050 0
141
+ sigir-20141 NCT02516839 0
142
+ sigir-20141 NCT02532699 2
143
+ sigir-20141 NCT02608255 1
144
+ sigir-20141 NCT02626741 0
145
+ sigir-201410 NCT00043277 0
146
+ sigir-201410 NCT00102037 0
147
+ sigir-201410 NCT00154674 0
148
+ sigir-201410 NCT00171054 0
149
+ sigir-201410 NCT00314002 0
150
+ sigir-201410 NCT00324233 0
151
+ sigir-201410 NCT00392639 0
152
+ sigir-201410 NCT00471289 0
153
+ sigir-201410 NCT00497094 0
154
+ sigir-201410 NCT00533156 1
155
+ sigir-201410 NCT00633503 0
156
+ sigir-201410 NCT00667381 1
157
+ sigir-201410 NCT00674778 1
158
+ sigir-201410 NCT00736086 1
159
+ sigir-201410 NCT00742014 0
160
+ sigir-201410 NCT00827957 0
161
+ sigir-201410 NCT00838175 0
162
+ sigir-201410 NCT00843297 0
163
+ sigir-201410 NCT00846846 0
164
+ sigir-201410 NCT00970476 0
165
+ sigir-201410 NCT01001663 0
166
+ sigir-201410 NCT01108120 0
167
+ sigir-201410 NCT01121510 1
168
+ sigir-201410 NCT01133119 1
169
+ sigir-201410 NCT01297387 0
170
+ sigir-201410 NCT01397175 0
171
+ sigir-201410 NCT01443104 0
172
+ sigir-201410 NCT01479153 0
173
+ sigir-201410 NCT01556373 0
174
+ sigir-201410 NCT01599195 2
175
+ sigir-201410 NCT01600482 1
176
+ sigir-201410 NCT01631448 0
177
+ sigir-201410 NCT01683448 0
178
+ sigir-201410 NCT01691911 2
179
+ sigir-201410 NCT01745692 0
180
+ sigir-201410 NCT01776151 0
181
+ sigir-201410 NCT01855698 0
182
+ sigir-201410 NCT01868698 0
183
+ sigir-201410 NCT01870310 0
184
+ sigir-201410 NCT01943344 1
185
+ sigir-201410 NCT02033720 0
186
+ sigir-201410 NCT02069275 0
187
+ sigir-201410 NCT02074371 0
188
+ sigir-201410 NCT02097186 2
189
+ sigir-201410 NCT02163031 0
190
+ sigir-201410 NCT02200783 1
191
+ sigir-201410 NCT02216305 0
192
+ sigir-201410 NCT02237430 0
193
+ sigir-201410 NCT02241642 1
194
+ sigir-201410 NCT02264964 1
195
+ sigir-201410 NCT02341196 0
196
+ sigir-201410 NCT02389023 1
197
+ sigir-201410 NCT02419053 0
198
+ sigir-201410 NCT02426710 0
199
+ sigir-201410 NCT02453321 0
200
+ sigir-201410 NCT02519933 0
201
+ sigir-201410 NCT02525926 0
202
+ sigir-201410 NCT02583906 0
203
+ sigir-201410 NCT02626156 0
204
+ sigir-201410 NCT02634138 2
205
+ sigir-201411 NCT00243152 0
206
+ sigir-201411 NCT00322621 0
207
+ sigir-201411 NCT00382421 1
208
+ sigir-201411 NCT00413855 0
209
+ sigir-201411 NCT00760903 0
210
+ sigir-201411 NCT00769275 0
211
+ sigir-201411 NCT00929773 0
212
+ sigir-201411 NCT00944333 1
213
+ sigir-201411 NCT01184846 0
214
+ sigir-201411 NCT01188993 0
215
+ sigir-201411 NCT01200628 0
216
+ sigir-201411 NCT01219023 0
217
+ sigir-201411 NCT01296789 1
218
+ sigir-201411 NCT01464671 1
219
+ sigir-201411 NCT01526382 1
220
+ sigir-201411 NCT01533519 0
221
+ sigir-201411 NCT01539161 0
222
+ sigir-201411 NCT01558206 2
223
+ sigir-201411 NCT01665521 0
224
+ sigir-201411 NCT01672697 0
225
+ sigir-201411 NCT01723137 2
226
+ sigir-201411 NCT01792336 0
227
+ sigir-201411 NCT01827007 0
228
+ sigir-201411 NCT01839786 0
229
+ sigir-201411 NCT01890044 0
230
+ sigir-201411 NCT01973907 0
231
+ sigir-201411 NCT01997047 0
232
+ sigir-201411 NCT02011477 0
233
+ sigir-201411 NCT02072538 0
234
+ sigir-201411 NCT02099071 0
235
+ sigir-201411 NCT02104050 0
236
+ sigir-201411 NCT02168998 0
237
+ sigir-201411 NCT02177188 0
238
+ sigir-201411 NCT02214030 1
239
+ sigir-201411 NCT02258243 0
240
+ sigir-201411 NCT02302534 0
241
+ sigir-201411 NCT02336542 0
242
+ sigir-201411 NCT02353793 0
243
+ sigir-201411 NCT02481076 0
244
+ sigir-201411 NCT02502513 0
245
+ sigir-201411 NCT02517944 0
246
+ sigir-201411 NCT02623556 0
247
+ sigir-201412 NCT00011102 0
248
+ sigir-201412 NCT00111735 0
249
+ sigir-201412 NCT00124384 0
250
+ sigir-201412 NCT00194259 0
251
+ sigir-201412 NCT00261898 0
252
+ sigir-201412 NCT00264901 0
253
+ sigir-201412 NCT00271427 2
254
+ sigir-201412 NCT00360074 1
255
+ sigir-201412 NCT00497575 2
256
+ sigir-201412 NCT00565890 0
257
+ sigir-201412 NCT00593736 0
258
+ sigir-201412 NCT00606840 2
259
+ sigir-201412 NCT00646451 0
260
+ sigir-201412 NCT00686426 2
261
+ sigir-201412 NCT00715572 2
262
+ sigir-201412 NCT00759993 0
263
+ sigir-201412 NCT00812162 0
264
+ sigir-201412 NCT00819624 0
265
+ sigir-201412 NCT00915642 0
266
+ sigir-201412 NCT00948610 0
267
+ sigir-201412 NCT01041261 0
268
+ sigir-201412 NCT01131429 0
269
+ sigir-201412 NCT01197183 2
270
+ sigir-201412 NCT01221935 0
271
+ sigir-201412 NCT01260532 0
272
+ sigir-201412 NCT01280292 0
273
+ sigir-201412 NCT01307618 0
274
+ sigir-201412 NCT01319370 0
275
+ sigir-201412 NCT01551498 1
276
+ sigir-201412 NCT01574859 0
277
+ sigir-201412 NCT01576705 0
278
+ sigir-201412 NCT01739972 0
279
+ sigir-201412 NCT01835236 0
280
+ sigir-201412 NCT01840332 1
281
+ sigir-201412 NCT01848171 0
282
+ sigir-201412 NCT01874704 0
283
+ sigir-201412 NCT01986140 0
284
+ sigir-201412 NCT02015936 0
285
+ sigir-201412 NCT02027077 0
286
+ sigir-201412 NCT02086799 0
287
+ sigir-201412 NCT02094079 0
288
+ sigir-201412 NCT02126683 0
289
+ sigir-201412 NCT02190214 0
290
+ sigir-201412 NCT02201069 0
291
+ sigir-201412 NCT02290405 0
292
+ sigir-201412 NCT02316418 0
293
+ sigir-201412 NCT02379728 0
294
+ sigir-201412 NCT02399423 0
295
+ sigir-201412 NCT02491567 1
296
+ sigir-201412 NCT02548715 0
297
+ sigir-201412 NCT02575001 0
298
+ sigir-201412 NCT02597582 0
299
+ sigir-201412 NCT02627937 0
300
+ sigir-201413 NCT00067691 0
301
+ sigir-201413 NCT00163709 2
302
+ sigir-201413 NCT00302601 1
303
+ sigir-201413 NCT00314548 0
304
+ sigir-201413 NCT00318071 0
305
+ sigir-201413 NCT00341848 0
306
+ sigir-201413 NCT00356551 0
307
+ sigir-201413 NCT00522977 0
308
+ sigir-201413 NCT00573053 0
309
+ sigir-201413 NCT00692198 0
310
+ sigir-201413 NCT00712998 0
311
+ sigir-201413 NCT00782912 1
312
+ sigir-201413 NCT00839124 0
313
+ sigir-201413 NCT00848731 1
314
+ sigir-201413 NCT00974337 0
315
+ sigir-201413 NCT01004939 0
316
+ sigir-201413 NCT01095406 1
317
+ sigir-201413 NCT01097928 1
318
+ sigir-201413 NCT01098851 0
319
+ sigir-201413 NCT01232387 0
320
+ sigir-201413 NCT01262742 0
321
+ sigir-201413 NCT01274637 0
322
+ sigir-201413 NCT01321788 0
323
+ sigir-201413 NCT01428817 0
324
+ sigir-201413 NCT01463202 0
325
+ sigir-201413 NCT01468194 0
326
+ sigir-201413 NCT01498094 0
327
+ sigir-201413 NCT01535248 0
328
+ sigir-201413 NCT01566058 1
329
+ sigir-201413 NCT01620723 0
330
+ sigir-201413 NCT01621685 0
331
+ sigir-201413 NCT01630655 0
332
+ sigir-201413 NCT01684592 0
333
+ sigir-201413 NCT01689961 0
334
+ sigir-201413 NCT01692821 1
335
+ sigir-201413 NCT01787773 1
336
+ sigir-201413 NCT01828697 0
337
+ sigir-201413 NCT01858129 1
338
+ sigir-201413 NCT01870830 0
339
+ sigir-201413 NCT01935141 2
340
+ sigir-201413 NCT01959009 0
341
+ sigir-201413 NCT01991886 0
342
+ sigir-201413 NCT02010840 0
343
+ sigir-201413 NCT02043223 0
344
+ sigir-201413 NCT02094547 0
345
+ sigir-201413 NCT02150616 0
346
+ sigir-201413 NCT02210702 0
347
+ sigir-201413 NCT02221895 1
348
+ sigir-201413 NCT02231398 0
349
+ sigir-201413 NCT02258958 0
350
+ sigir-201413 NCT02264769 1
351
+ sigir-201413 NCT02307201 0
352
+ sigir-201413 NCT02309489 0
353
+ sigir-201413 NCT02372461 0
354
+ sigir-201413 NCT02399774 0
355
+ sigir-201413 NCT02447731 0
356
+ sigir-201413 NCT02449928 0
357
+ sigir-201413 NCT02458625 1
358
+ sigir-201413 NCT02523586 1
359
+ sigir-201413 NCT02526433 2
360
+ sigir-201413 NCT02600260 0
361
+ sigir-201413 NCT02615834 0
362
+ sigir-201413 NCT02616991 1
363
+ sigir-201414 NCT00006196 0
364
+ sigir-201414 NCT00094952 0
365
+ sigir-201414 NCT00182884 0
366
+ sigir-201414 NCT00189046 0
367
+ sigir-201414 NCT00302692 1
368
+ sigir-201414 NCT00419874 2
369
+ sigir-201414 NCT00424736 0
370
+ sigir-201414 NCT00450047 0
371
+ sigir-201414 NCT00482001 0
372
+ sigir-201414 NCT00493714 0
373
+ sigir-201414 NCT00512655 0
374
+ sigir-201414 NCT00613886 0
375
+ sigir-201414 NCT00760734 0
376
+ sigir-201414 NCT00906711 0
377
+ sigir-201414 NCT00928915 0
378
+ sigir-201414 NCT00928941 0
379
+ sigir-201414 NCT01075035 2
380
+ sigir-201414 NCT01162343 0
381
+ sigir-201414 NCT01182961 0
382
+ sigir-201414 NCT01196299 2
383
+ sigir-201414 NCT01199276 0
384
+ sigir-201414 NCT01263067 0
385
+ sigir-201414 NCT01316965 0
386
+ sigir-201414 NCT01331512 0
387
+ sigir-201414 NCT01392820 0
388
+ sigir-201414 NCT01397643 0
389
+ sigir-201414 NCT01470040 0
390
+ sigir-201414 NCT01564303 0
391
+ sigir-201414 NCT01574950 0
392
+ sigir-201414 NCT01619293 2
393
+ sigir-201414 NCT01624545 2
394
+ sigir-201414 NCT01633593 0
395
+ sigir-201414 NCT01674140 0
396
+ sigir-201414 NCT01774240 0
397
+ sigir-201414 NCT01804426 0
398
+ sigir-201414 NCT01836848 0
399
+ sigir-201414 NCT01862952 0
400
+ sigir-201414 NCT01869855 1
401
+ sigir-201414 NCT01922115 0
402
+ sigir-201414 NCT01947959 0
403
+ sigir-201414 NCT01991405 0
404
+ sigir-201414 NCT02028260 0
405
+ sigir-201414 NCT02035436 0
406
+ sigir-201414 NCT02039999 0
407
+ sigir-201414 NCT02051270 0
408
+ sigir-201414 NCT02086981 2
409
+ sigir-201414 NCT02120664 0
410
+ sigir-201414 NCT02131181 0
411
+ sigir-201414 NCT02172625 0
412
+ sigir-201414 NCT02199093 0
413
+ sigir-201414 NCT02213380 0
414
+ sigir-201414 NCT02227225 0
415
+ sigir-201414 NCT02237703 0
416
+ sigir-201414 NCT02266563 0
417
+ sigir-201414 NCT02267538 0
418
+ sigir-201414 NCT02323984 0
419
+ sigir-201414 NCT02355483 0
420
+ sigir-201414 NCT02366299 0
421
+ sigir-201414 NCT02394418 0
422
+ sigir-201414 NCT02404181 0
423
+ sigir-201414 NCT02465307 1
424
+ sigir-201414 NCT02477007 0
425
+ sigir-201414 NCT02505061 0
426
+ sigir-201414 NCT02513316 0
427
+ sigir-201414 NCT02518646 1
428
+ sigir-201414 NCT02527499 0
429
+ sigir-201414 NCT02531542 1
430
+ sigir-201414 NCT02558777 0
431
+ sigir-201414 NCT02564939 0
432
+ sigir-201414 NCT02577731 0
433
+ sigir-201414 NCT02591043 0
434
+ sigir-201414 NCT02603731 0
435
+ sigir-201414 NCT02631304 0
436
+ sigir-201415 NCT00003702 1
437
+ sigir-201415 NCT00044876 0
438
+ sigir-201415 NCT00150644 1
439
+ sigir-201415 NCT00156208 0
440
+ sigir-201415 NCT00166790 2
441
+ sigir-201415 NCT00180739 1
442
+ sigir-201415 NCT00190918 2
443
+ sigir-201415 NCT00237965 0
444
+ sigir-201415 NCT00248144 0
445
+ sigir-201415 NCT00277680 2
446
+ sigir-201415 NCT00288938 0
447
+ sigir-201415 NCT00340288 1
448
+ sigir-201415 NCT00361036 0
449
+ sigir-201416 NCT00001252 2
450
+ sigir-201416 NCT00001552 1
451
+ sigir-201416 NCT00001986 1
452
+ sigir-201416 NCT00061139 0
453
+ sigir-201416 NCT00080366 0
454
+ sigir-201416 NCT00102596 0
455
+ sigir-201416 NCT00393926 0
456
+ sigir-201416 NCT00432666 0
457
+ sigir-201416 NCT00462449 0
458
+ sigir-201416 NCT00565201 0
459
+ sigir-201416 NCT00597701 0
460
+ sigir-201416 NCT00656097 0
461
+ sigir-201416 NCT00703521 0
462
+ sigir-201416 NCT00740090 0
463
+ sigir-201416 NCT00906971 0
464
+ sigir-201416 NCT00948272 0
465
+ sigir-201416 NCT00955838 0
466
+ sigir-201416 NCT01025726 1
467
+ sigir-201416 NCT01044199 0
468
+ sigir-201416 NCT01047839 0
469
+ sigir-201416 NCT01060748 0
470
+ sigir-201416 NCT01075269 0
471
+ sigir-201416 NCT01081275 0
472
+ sigir-201416 NCT01228383 0
473
+ sigir-201416 NCT01281475 0
474
+ sigir-201416 NCT01286493 1
475
+ sigir-201416 NCT01373879 0
476
+ sigir-201416 NCT01387074 0
477
+ sigir-201416 NCT01388400 0
478
+ sigir-201416 NCT01466387 0
479
+ sigir-201416 NCT01603875 0
480
+ sigir-201416 NCT01635647 0
481
+ sigir-201416 NCT01683838 0
482
+ sigir-201416 NCT01767480 0
483
+ sigir-201416 NCT01827917 0
484
+ sigir-201416 NCT01930357 0
485
+ sigir-201416 NCT01932463 0
486
+ sigir-201416 NCT01936298 0
487
+ sigir-201416 NCT01949909 0
488
+ sigir-201416 NCT02043145 0
489
+ sigir-201416 NCT02074150 0
490
+ sigir-201416 NCT02122159 0
491
+ sigir-201416 NCT02177032 0
492
+ sigir-201416 NCT02199015 0
493
+ sigir-201416 NCT02238756 1
494
+ sigir-201416 NCT02241135 0
495
+ sigir-201416 NCT02339896 0
496
+ sigir-201416 NCT02359253 0
497
+ sigir-201416 NCT02359812 0
498
+ sigir-201416 NCT02374814 1
499
+ sigir-201416 NCT02418858 0
500
+ sigir-201416 NCT02420106 0
501
+ sigir-201416 NCT02427854 0
502
+ sigir-201416 NCT02491541 0
503
+ sigir-201416 NCT02547727 0
504
+ sigir-201416 NCT02552290 0
505
+ sigir-201416 NCT02564471 0
506
+ sigir-201416 NCT02596659 0
507
+ sigir-201418 NCT00001676 0
508
+ sigir-201418 NCT00004496 0
509
+ sigir-201418 NCT00004696 1
510
+ sigir-201418 NCT00006137 0
511
+ sigir-201418 NCT00027417 0
512
+ sigir-201418 NCT00226369 0
513
+ sigir-201418 NCT00231322 0
514
+ sigir-201418 NCT00232401 0
515
+ sigir-201418 NCT00298454 1
516
+ sigir-201418 NCT00313807 0
517
+ sigir-201418 NCT00362869 0
518
+ sigir-201418 NCT00539292 0
519
+ sigir-201418 NCT00549107 1
520
+ sigir-201418 NCT00555321 0
521
+ sigir-201418 NCT00556491 0
522
+ sigir-201418 NCT00557219 2
523
+ sigir-201418 NCT00572715 1
524
+ sigir-201418 NCT00577525 1
525
+ sigir-201418 NCT00624637 0
526
+ sigir-201418 NCT00738283 0
527
+ sigir-201418 NCT00747864 1
528
+ sigir-201418 NCT00770705 0
529
+ sigir-201418 NCT00774137 1
530
+ sigir-201418 NCT00776646 0
531
+ sigir-201418 NCT00778349 0
532
+ sigir-201418 NCT00821522 1
533
+ sigir-201418 NCT00908037 0
534
+ sigir-201418 NCT00934843 0
535
+ sigir-201418 NCT00952263 0
536
+ sigir-201418 NCT00974337 1
537
+ sigir-201418 NCT01062828 0
538
+ sigir-201418 NCT01084980 0
539
+ sigir-201418 NCT01142115 0
540
+ sigir-201418 NCT01143246 0
541
+ sigir-201418 NCT01156428 0
542
+ sigir-201418 NCT01219998 1
543
+ sigir-201418 NCT01233869 0
544
+ sigir-201418 NCT01243996 0
545
+ sigir-201418 NCT01260259 0
546
+ sigir-201418 NCT01260883 2
547
+ sigir-201418 NCT01309477 0
548
+ sigir-201418 NCT01569698 1
549
+ sigir-201418 NCT01641289 0
550
+ sigir-201418 NCT01700231 0
551
+ sigir-201418 NCT01795638 0
552
+ sigir-201418 NCT01869933 0
553
+ sigir-201418 NCT01870011 0
554
+ sigir-201418 NCT01918618 0
555
+ sigir-201418 NCT01973088 0
556
+ sigir-201418 NCT02016053 0
557
+ sigir-201418 NCT02046135 0
558
+ sigir-201418 NCT02081235 0
559
+ sigir-201418 NCT02081261 0
560
+ sigir-201418 NCT02081274 0
561
+ sigir-201418 NCT02147470 0
562
+ sigir-201418 NCT02195713 0
563
+ sigir-201418 NCT02213757 0
564
+ sigir-201418 NCT02233010 0
565
+ sigir-201418 NCT02276170 0
566
+ sigir-201418 NCT02282930 1
567
+ sigir-201418 NCT02306642 0
568
+ sigir-201418 NCT02311530 0
569
+ sigir-201418 NCT02312115 0
570
+ sigir-201418 NCT02313636 0
571
+ sigir-201418 NCT02338895 0
572
+ sigir-201418 NCT02361736 0
573
+ sigir-201418 NCT02415049 0
574
+ sigir-201418 NCT02443389 0
575
+ sigir-201418 NCT02489669 0
576
+ sigir-201418 NCT02495220 0
577
+ sigir-201418 NCT02495909 0
578
+ sigir-201418 NCT02531412 0
579
+ sigir-201418 NCT02560584 0
580
+ sigir-201418 NCT02599155 1
581
+ sigir-201419 NCT00002711 1
582
+ sigir-201419 NCT00002897 1
583
+ sigir-201419 NCT00002930 1
584
+ sigir-201419 NCT00021320 1
585
+ sigir-201419 NCT00040287 0
586
+ sigir-201419 NCT00193882 1
587
+ sigir-201419 NCT00256529 2
588
+ sigir-201419 NCT00306501 0
589
+ sigir-201419 NCT00308399 0
590
+ sigir-201419 NCT00336609 1
591
+ sigir-201419 NCT00352391 0
592
+ sigir-201419 NCT00375180 1
593
+ sigir-201419 NCT00402987 0
594
+ sigir-201419 NCT00408590 0
595
+ sigir-201419 NCT00412490 0
596
+ sigir-201419 NCT00465907 1
597
+ sigir-201419 NCT00506324 1
598
+ sigir-201419 NCT00525044 0
599
+ sigir-201419 NCT00591175 0
600
+ sigir-201419 NCT00608205 1
601
+ sigir-201419 NCT00628368 1
602
+ sigir-201419 NCT00647829 0
603
+ sigir-201419 NCT00662662 1
604
+ sigir-201419 NCT00727376 1
605
+ sigir-201419 NCT00773227 0
606
+ sigir-201419 NCT00816634 1
607
+ sigir-201419 NCT00826813 1
608
+ sigir-201419 NCT00827671 1
609
+ sigir-201419 NCT00861094 1
610
+ sigir-201419 NCT00873535 0
611
+ sigir-201419 NCT00880906 0
612
+ sigir-201419 NCT00897364 0
613
+ sigir-201419 NCT00898495 1
614
+ sigir-201419 NCT00905385 0
615
+ sigir-201419 NCT00908817 0
616
+ sigir-201419 NCT00918307 0
617
+ sigir-201419 NCT00934453 0
618
+ sigir-201419 NCT01023828 0
619
+ sigir-201419 NCT01052038 0
620
+ sigir-201419 NCT01054274 1
621
+ sigir-201419 NCT01125384 0
622
+ sigir-201419 NCT01131429 0
623
+ sigir-201419 NCT01137123 1
624
+ sigir-201419 NCT01199185 0
625
+ sigir-201419 NCT01243398 1
626
+ sigir-201419 NCT01252225 0
627
+ sigir-201419 NCT01279824 0
628
+ sigir-201419 NCT01291823 0
629
+ sigir-201419 NCT01335269 0
630
+ sigir-201419 NCT01359397 1
631
+ sigir-201419 NCT01366833 1
632
+ sigir-201419 NCT01396707 1
633
+ sigir-201419 NCT01450748 0
634
+ sigir-201419 NCT01453400 0
635
+ sigir-201419 NCT01471249 1
636
+ sigir-201419 NCT01514552 0
637
+ sigir-201419 NCT01578018 0
638
+ sigir-201419 NCT01586962 0
639
+ sigir-201419 NCT01651975 2
640
+ sigir-201419 NCT01688700 1
641
+ sigir-201419 NCT01704690 1
642
+ sigir-201419 NCT01723358 0
643
+ sigir-201419 NCT01724411 0
644
+ sigir-201419 NCT01731847 0
645
+ sigir-201419 NCT01742312 1
646
+ sigir-201419 NCT01745107 1
647
+ sigir-201419 NCT01809756 1
648
+ sigir-201419 NCT01862809 0
649
+ sigir-201419 NCT01863264 0
650
+ sigir-201419 NCT01867983 0
651
+ sigir-201419 NCT01900392 0
652
+ sigir-201419 NCT01923831 0
653
+ sigir-201419 NCT01954407 0
654
+ sigir-201419 NCT01986361 0
655
+ sigir-201419 NCT01988350 0
656
+ sigir-201419 NCT02011035 0
657
+ sigir-201419 NCT02017288 0
658
+ sigir-201419 NCT02045342 0
659
+ sigir-201419 NCT02130011 1
660
+ sigir-201419 NCT02144545 0
661
+ sigir-201419 NCT02206971 2
662
+ sigir-201419 NCT02296528 0
663
+ sigir-201419 NCT02304250 0
664
+ sigir-201419 NCT02322411 0
665
+ sigir-201419 NCT02333201 0
666
+ sigir-201419 NCT02375581 0
667
+ sigir-201419 NCT02405832 0
668
+ sigir-201419 NCT02445209 1
669
+ sigir-201419 NCT02483663 0
670
+ sigir-201419 NCT02492646 0
671
+ sigir-201419 NCT02494960 0
672
+ sigir-201419 NCT02509286 1
673
+ sigir-201419 NCT02591784 1
674
+ sigir-20142 NCT00000932 0
675
+ sigir-20142 NCT00086879 0
676
+ sigir-20142 NCT00094887 0
677
+ sigir-20142 NCT00095316 0
678
+ sigir-20142 NCT00096772 0
679
+ sigir-20142 NCT00132951 0
680
+ sigir-20142 NCT00161772 0
681
+ sigir-20142 NCT00161798 0
682
+ sigir-20142 NCT00161824 0
683
+ sigir-20142 NCT00161863 0
684
+ sigir-20142 NCT00161967 0
685
+ sigir-20142 NCT00163540 0
686
+ sigir-20142 NCT00163618 0
687
+ sigir-20142 NCT00237016 1
688
+ sigir-20142 NCT00311441 0
689
+ sigir-20142 NCT00385632 0
690
+ sigir-20142 NCT00386035 0
691
+ sigir-20142 NCT00432003 0
692
+ sigir-20142 NCT00455468 0
693
+ sigir-20142 NCT00460486 0
694
+ sigir-20142 NCT00498654 0
695
+ sigir-20142 NCT00503529 0
696
+ sigir-20142 NCT00507871 0
697
+ sigir-20142 NCT00513500 0
698
+ sigir-20142 NCT00617344 0
699
+ sigir-20142 NCT00680836 0
700
+ sigir-20142 NCT00694655 0
701
+ sigir-20142 NCT00711399 2
702
+ sigir-20142 NCT00740155 0
703
+ sigir-20142 NCT00840801 0
704
+ sigir-20142 NCT00851487 0
705
+ sigir-20142 NCT00894686 0
706
+ sigir-20142 NCT01017081 2
707
+ sigir-20142 NCT01070732 0
708
+ sigir-20142 NCT01075204 0
709
+ sigir-20142 NCT01087892 0
710
+ sigir-20142 NCT01099943 1
711
+ sigir-20142 NCT01147445 0
712
+ sigir-20142 NCT01177657 0
713
+ sigir-20142 NCT01201252 0
714
+ sigir-20142 NCT01202201 0
715
+ sigir-20142 NCT01241201 0
716
+ sigir-20142 NCT01253967 0
717
+ sigir-20142 NCT01253980 1
718
+ sigir-20142 NCT01269554 1
719
+ sigir-20142 NCT01359020 0
720
+ sigir-20142 NCT01521403 0
721
+ sigir-20142 NCT01589926 0
722
+ sigir-20142 NCT01627327 0
723
+ sigir-20142 NCT01663155 0
724
+ sigir-20142 NCT01670149 0
725
+ sigir-20142 NCT01707485 2
726
+ sigir-20142 NCT01739673 0
727
+ sigir-20142 NCT02052934 0
728
+ sigir-20142 NCT02139163 0
729
+ sigir-20142 NCT02269761 2
730
+ sigir-20142 NCT02380352 2
731
+ sigir-20142 NCT02383680 0
732
+ sigir-20142 NCT02391909 0
733
+ sigir-20142 NCT02441699 0
734
+ sigir-20142 NCT02618655 1
735
+ sigir-20142 NCT02625129 0
736
+ sigir-201421 NCT00001789 1
737
+ sigir-201421 NCT00005436 1
738
+ sigir-201421 NCT00006055 2
739
+ sigir-201421 NCT00008749 2
740
+ sigir-201421 NCT00036491 1
741
+ sigir-201421 NCT00065806 2
742
+ sigir-201421 NCT00071175 2
743
+ sigir-201421 NCT00071487 1
744
+ sigir-201421 NCT00074373 0
745
+ sigir-201421 NCT00119678 1
746
+ sigir-201421 NCT00125307 2
747
+ sigir-201421 NCT00172666 2
748
+ sigir-201421 NCT00181298 1
749
+ sigir-201421 NCT00215800 1
750
+ sigir-201421 NCT00222183 1
751
+ sigir-201421 NCT00230035 1
752
+ sigir-201421 NCT00275899 2
753
+ sigir-201421 NCT00282347 1
754
+ sigir-201421 NCT00297284 1
755
+ sigir-201421 NCT00342329 1
756
+ sigir-201421 NCT00343187 0
757
+ sigir-201421 NCT00364728 2
758
+ sigir-201421 NCT00371501 2
759
+ sigir-201421 NCT00392093 0
760
+ sigir-201421 NCT00413361 1
761
+ sigir-201421 NCT00430677 1
762
+ sigir-201421 NCT00470522 1
763
+ sigir-201421 NCT00504244 1
764
+ sigir-201421 NCT00512694 1
765
+ sigir-201421 NCT00539799 1
766
+ sigir-201421 NCT00581763 2
767
+ sigir-201421 NCT00582465 2
768
+ sigir-201421 NCT00611663 1
769
+ sigir-201421 NCT00637819 2
770
+ sigir-201421 NCT00731302 1
771
+ sigir-201421 NCT00760669 0
772
+ sigir-201421 NCT00779194 1
773
+ sigir-201421 NCT00866229 1
774
+ sigir-201421 NCT00908037 0
775
+ sigir-201421 NCT00965809 0
776
+ sigir-201421 NCT00982670 2
777
+ sigir-201421 NCT00997100 1
778
+ sigir-201421 NCT01018238 1
779
+ sigir-201421 NCT01031797 1
780
+ sigir-201421 NCT01076101 1
781
+ sigir-201421 NCT01101802 1
782
+ sigir-201421 NCT01176643 2
783
+ sigir-201421 NCT01187927 2
784
+ sigir-201421 NCT01230827 0
785
+ sigir-201421 NCT01266915 2
786
+ sigir-201421 NCT01276782 0
787
+ sigir-201421 NCT01330368 2
788
+ sigir-201421 NCT01381536 1
789
+ sigir-201421 NCT01413100 1
790
+ sigir-201421 NCT01413230 2
791
+ sigir-201421 NCT01421316 0
792
+ sigir-201421 NCT01440231 1
793
+ sigir-201421 NCT01512277 0
794
+ sigir-201421 NCT01520155 2
795
+ sigir-201421 NCT01549184 2
796
+ sigir-201421 NCT01551069 0
797
+ sigir-201421 NCT01597622 0
798
+ sigir-201421 NCT01632241 1
799
+ sigir-201421 NCT01649765 0
800
+ sigir-201421 NCT01689025 2
801
+ sigir-201421 NCT01689350 2
802
+ sigir-201421 NCT01705977 1
803
+ sigir-201421 NCT01729455 1
804
+ sigir-201421 NCT01784523 1
805
+ sigir-201421 NCT01923415 2
806
+ sigir-201421 NCT01924000 0
807
+ sigir-201421 NCT01931150 0
808
+ sigir-201421 NCT01946880 1
809
+ sigir-201421 NCT01950780 1
810
+ sigir-201421 NCT01992666 1
811
+ sigir-201421 NCT02006784 0
812
+ sigir-201421 NCT02034344 2
813
+ sigir-201421 NCT02074020 0
814
+ sigir-201421 NCT02080195 1
815
+ sigir-201421 NCT02119156 1
816
+ sigir-201421 NCT02176148 0
817
+ sigir-201421 NCT02239731 0
818
+ sigir-201421 NCT02260934 0
819
+ sigir-201421 NCT02284984 1
820
+ sigir-201421 NCT02444728 0
821
+ sigir-201421 NCT02455089 0
822
+ sigir-201421 NCT02477254 1
823
+ sigir-201421 NCT02530944 2
824
+ sigir-201421 NCT02554019 1
825
+ sigir-201421 NCT02558517 0
826
+ sigir-201421 NCT02591355 0
827
+ sigir-201421 NCT02633163 1
828
+ sigir-201422 NCT00172822 1
829
+ sigir-201422 NCT00236912 2
830
+ sigir-201422 NCT00674726 2
831
+ sigir-201422 NCT00677989 0
832
+ sigir-201422 NCT00723788 2
833
+ sigir-201422 NCT00908804 2
834
+ sigir-201422 NCT00913445 0
835
+ sigir-201422 NCT01022567 0
836
+ sigir-201422 NCT01024439 0
837
+ sigir-201422 NCT01027455 0
838
+ sigir-201422 NCT01068288 0
839
+ sigir-201422 NCT01096927 2
840
+ sigir-201422 NCT01115153 1
841
+ sigir-201422 NCT01192620 2
842
+ sigir-201422 NCT01610193 0
843
+ sigir-201422 NCT01678365 0
844
+ sigir-201422 NCT01698099 1
845
+ sigir-201422 NCT01718171 2
846
+ sigir-201422 NCT01825863 0
847
+ sigir-201422 NCT01925014 1
848
+ sigir-201422 NCT01953289 2
849
+ sigir-201422 NCT01979029 0
850
+ sigir-201422 NCT02004470 0
851
+ sigir-201422 NCT02017951 1
852
+ sigir-201422 NCT02018016 1
853
+ sigir-201422 NCT02029781 0
854
+ sigir-201422 NCT02047786 0
855
+ sigir-201422 NCT02134652 0
856
+ sigir-201422 NCT02137603 1
857
+ sigir-201422 NCT02194140 0
858
+ sigir-201422 NCT02271932 1
859
+ sigir-201422 NCT02375529 0
860
+ sigir-201422 NCT02439593 0
861
+ sigir-201422 NCT02447224 2
862
+ sigir-201422 NCT02469935 0
863
+ sigir-201422 NCT02507674 2
864
+ sigir-201422 NCT02535962 0
865
+ sigir-201422 NCT02574364 2
866
+ sigir-201422 NCT02624089 1
867
+ sigir-201422 NCT02633735 2
868
+ sigir-201423 NCT00018408 1
869
+ sigir-201423 NCT00084266 0
870
+ sigir-201423 NCT00108823 1
871
+ sigir-201423 NCT00116584 0
872
+ sigir-201423 NCT00170222 1
873
+ sigir-201423 NCT00181272 1
874
+ sigir-201423 NCT00181285 1
875
+ sigir-201423 NCT00190437 2
876
+ sigir-201423 NCT00263380 2
877
+ sigir-201423 NCT00274222 2
878
+ sigir-201423 NCT00440687 1
879
+ sigir-201423 NCT00441649 0
880
+ sigir-201423 NCT00455468 0
881
+ sigir-201423 NCT00476736 1
882
+ sigir-201423 NCT00512954 1
883
+ sigir-201423 NCT00595114 1
884
+ sigir-201423 NCT00605007 2
885
+ sigir-201423 NCT00628225 1
886
+ sigir-201423 NCT00774176 1
887
+ sigir-201423 NCT00788645 1
888
+ sigir-201423 NCT00791505 1
889
+ sigir-201423 NCT00807469 1
890
+ sigir-201423 NCT00839189 1
891
+ sigir-201423 NCT00860938 1
892
+ sigir-201423 NCT00883701 1
893
+ sigir-201423 NCT00893009 1
894
+ sigir-201423 NCT00974064 0
895
+ sigir-201423 NCT00981851 1
896
+ sigir-201423 NCT00985244 1
897
+ sigir-201423 NCT01091493 1
898
+ sigir-201423 NCT01213693 1
899
+ sigir-201423 NCT01232140 1
900
+ sigir-201423 NCT01248507 1
901
+ sigir-201423 NCT01252225 0
902
+ sigir-201423 NCT01254032 1
903
+ sigir-201423 NCT01296477 0
904
+ sigir-201423 NCT01297790 1
905
+ sigir-201423 NCT01314807 1
906
+ sigir-201423 NCT01337336 1
907
+ sigir-201423 NCT01344005 0
908
+ sigir-201423 NCT01381367 1
909
+ sigir-201423 NCT01395875 1
910
+ sigir-201423 NCT01396798 0
911
+ sigir-201423 NCT01431911 1
912
+ sigir-201423 NCT01460082 1
913
+ sigir-201423 NCT01589926 0
914
+ sigir-201423 NCT01621685 0
915
+ sigir-201423 NCT01694069 0
916
+ sigir-201423 NCT01701869 1
917
+ sigir-201423 NCT01710488 1
918
+ sigir-201423 NCT01742338 1
919
+ sigir-201423 NCT01798420 1
920
+ sigir-201423 NCT01801657 0
921
+ sigir-201423 NCT01877707 0
922
+ sigir-201423 NCT01892488 1
923
+ sigir-201423 NCT01950936 1
924
+ sigir-201423 NCT01997047 0
925
+ sigir-201423 NCT02092675 0
926
+ sigir-201423 NCT02136875 1
927
+ sigir-201423 NCT02181023 1
928
+ sigir-201423 NCT02209974 1
929
+ sigir-201423 NCT02219360 2
930
+ sigir-201423 NCT02220387 1
931
+ sigir-201423 NCT02264483 1
932
+ sigir-201423 NCT02269644 1
933
+ sigir-201423 NCT02282436 1
934
+ sigir-201423 NCT02284295 1
935
+ sigir-201423 NCT02299375 1
936
+ sigir-201423 NCT02333812 2
937
+ sigir-201423 NCT02386735 1
938
+ sigir-201423 NCT02490358 1
939
+ sigir-201423 NCT02534766 2
940
+ sigir-201423 NCT02605122 0
941
+ sigir-201423 NCT02619903 1
942
+ sigir-201423 NCT02633033 0
943
+ sigir-201424 NCT00115128 0
944
+ sigir-201424 NCT00222651 0
945
+ sigir-201424 NCT00228111 0
946
+ sigir-201424 NCT00344149 0
947
+ sigir-201424 NCT00424736 0
948
+ sigir-201424 NCT00440830 0
949
+ sigir-201424 NCT00587132 0
950
+ sigir-201424 NCT00625053 0
951
+ sigir-201424 NCT00625092 0
952
+ sigir-201424 NCT00630513 0
953
+ sigir-201424 NCT00726544 0
954
+ sigir-201424 NCT00754806 0
955
+ sigir-201424 NCT00769873 0
956
+ sigir-201424 NCT00775528 0
957
+ sigir-201424 NCT00778362 0
958
+ sigir-201424 NCT00870766 0
959
+ sigir-201424 NCT00950625 0
960
+ sigir-201424 NCT00965744 0
961
+ sigir-201424 NCT00970515 0
962
+ sigir-201424 NCT00997633 0
963
+ sigir-201424 NCT01013428 0
964
+ sigir-201424 NCT01044173 0
965
+ sigir-201424 NCT01074112 0
966
+ sigir-201424 NCT01103999 0
967
+ sigir-201424 NCT01113645 0
968
+ sigir-201424 NCT01196715 0
969
+ sigir-201424 NCT01265004 0
970
+ sigir-201424 NCT01276561 2
971
+ sigir-201424 NCT01279369 0
972
+ sigir-201424 NCT01297725 0
973
+ sigir-201424 NCT01322828 0
974
+ sigir-201424 NCT01376466 0
975
+ sigir-201424 NCT01387828 0
976
+ sigir-201424 NCT01412684 0
977
+ sigir-201424 NCT01441492 0
978
+ sigir-201424 NCT01451931 0
979
+ sigir-201424 NCT01518816 0
980
+ sigir-201424 NCT01594385 0
981
+ sigir-201424 NCT01632774 0
982
+ sigir-201424 NCT01762761 0
983
+ sigir-201424 NCT01771861 1
984
+ sigir-201424 NCT01816256 0
985
+ sigir-201424 NCT01828749 0
986
+ sigir-201424 NCT01852773 0
987
+ sigir-201424 NCT01869049 0
988
+ sigir-201424 NCT01887028 0
989
+ sigir-201424 NCT01895127 0
990
+ sigir-201424 NCT01911702 2
991
+ sigir-201424 NCT01944397 0
992
+ sigir-201424 NCT02029339 0
993
+ sigir-201424 NCT02073890 0
994
+ sigir-201424 NCT02140710 0
995
+ sigir-201424 NCT02149472 0
996
+ sigir-201424 NCT02198885 0
997
+ sigir-201424 NCT02217956 0
998
+ sigir-201424 NCT02229695 2
999
+ sigir-201424 NCT02232191 2
1000
+ sigir-201424 NCT02233569 0
1001
+ sigir-201424 NCT02269878 0
1002
+ sigir-201424 NCT02302664 0
1003
+ sigir-201424 NCT02310854 0
1004
+ sigir-201424 NCT02331134 0
1005
+ sigir-201424 NCT02376192 0
1006
+ sigir-201424 NCT02378311 0
1007
+ sigir-201424 NCT02399150 2
1008
+ sigir-201424 NCT02494232 0
1009
+ sigir-201424 NCT02505347 0
1010
+ sigir-201424 NCT02513316 0
1011
+ sigir-201424 NCT02527031 0
1012
+ sigir-201424 NCT02584777 0
1013
+ sigir-201424 NCT02624089 0
1014
+ sigir-201425 NCT00035139 2
1015
+ sigir-201425 NCT00040339 0
1016
+ sigir-201425 NCT00061399 0
1017
+ sigir-201425 NCT00163774 0
1018
+ sigir-201425 NCT00174980 0
1019
+ sigir-201425 NCT00178711 0
1020
+ sigir-201425 NCT00222742 2
1021
+ sigir-201425 NCT00282269 2
1022
+ sigir-201425 NCT00451789 0
1023
+ sigir-201425 NCT00490997 0
1024
+ sigir-201425 NCT00754481 0
1025
+ sigir-201425 NCT00810940 0
1026
+ sigir-201425 NCT00908063 0
1027
+ sigir-201425 NCT00915928 0
1028
+ sigir-201425 NCT01056146 2
1029
+ sigir-201425 NCT01279928 0
1030
+ sigir-201425 NCT01315379 0
1031
+ sigir-201425 NCT01463878 0
1032
+ sigir-201425 NCT01512277 0
1033
+ sigir-201425 NCT01595906 0
1034
+ sigir-201425 NCT01613235 0
1035
+ sigir-201425 NCT01619943 0
1036
+ sigir-201425 NCT01632813 0
1037
+ sigir-201425 NCT01692769 2
1038
+ sigir-201425 NCT01712477 0
1039
+ sigir-201425 NCT01753921 0
1040
+ sigir-201425 NCT01763892 0
1041
+ sigir-201425 NCT01785797 0
1042
+ sigir-201425 NCT01796886 0
1043
+ sigir-201425 NCT01819597 0
1044
+ sigir-201425 NCT01869855 0
1045
+ sigir-201425 NCT01933217 0
1046
+ sigir-201425 NCT01942564 0
1047
+ sigir-201425 NCT01990768 0
1048
+ sigir-201425 NCT02024373 0
1049
+ sigir-201425 NCT02054117 0
1050
+ sigir-201425 NCT02064959 0
1051
+ sigir-201425 NCT02119533 0
1052
+ sigir-201425 NCT02192320 0
1053
+ sigir-201425 NCT02203968 0
1054
+ sigir-201425 NCT02282228 0
1055
+ sigir-201425 NCT02304328 0
1056
+ sigir-201425 NCT02309242 0
1057
+ sigir-201425 NCT02318290 0
1058
+ sigir-201425 NCT02362321 0
1059
+ sigir-201425 NCT02378311 2
1060
+ sigir-201425 NCT02392975 0
1061
+ sigir-201425 NCT02415257 0
1062
+ sigir-201425 NCT02416752 0
1063
+ sigir-201425 NCT02475226 1
1064
+ sigir-201425 NCT02477007 0
1065
+ sigir-201425 NCT02485873 0
1066
+ sigir-201425 NCT02568124 0
1067
+ sigir-201427 NCT00026468 1
1068
+ sigir-201427 NCT00055848 0
1069
+ sigir-201427 NCT00140894 2
1070
+ sigir-201427 NCT00224679 1
1071
+ sigir-201427 NCT00253812 0
1072
+ sigir-201427 NCT00319007 0
1073
+ sigir-201427 NCT00485069 0
1074
+ sigir-201427 NCT00525655 2
1075
+ sigir-201427 NCT00586053 0
1076
+ sigir-201427 NCT00641147 0
1077
+ sigir-201427 NCT00663819 0
1078
+ sigir-201427 NCT00685568 1
1079
+ sigir-201427 NCT00728026 2
1080
+ sigir-201427 NCT00748449 1
1081
+ sigir-201427 NCT00770991 1
1082
+ sigir-201427 NCT00808743 1
1083
+ sigir-201427 NCT00823836 0
1084
+ sigir-201427 NCT00843375 0
1085
+ sigir-201427 NCT00900016 0
1086
+ sigir-201427 NCT00905710 0
1087
+ sigir-201427 NCT01173250 0
1088
+ sigir-201427 NCT01187901 2
1089
+ sigir-201427 NCT01245816 0
1090
+ sigir-201427 NCT01422577 0
1091
+ sigir-201427 NCT01483144 2
1092
+ sigir-201427 NCT01495806 0
1093
+ sigir-201427 NCT01647776 0
1094
+ sigir-201427 NCT01713881 2
1095
+ sigir-201427 NCT01722149 0
1096
+ sigir-201427 NCT01725490 2
1097
+ sigir-201427 NCT01729416 0
1098
+ sigir-201427 NCT01737567 0
1099
+ sigir-201427 NCT01761279 2
1100
+ sigir-201427 NCT01767870 0
1101
+ sigir-201427 NCT01960348 1
1102
+ sigir-201427 NCT02016326 0
1103
+ sigir-201427 NCT02081742 0
1104
+ sigir-201427 NCT02113202 1
1105
+ sigir-201427 NCT02470416 0
1106
+ sigir-201427 NCT02521727 0
1107
+ sigir-201427 NCT02538406 2
1108
+ sigir-201429 NCT00000402 0
1109
+ sigir-201429 NCT00000430 0
1110
+ sigir-201429 NCT00001720 0
1111
+ sigir-201429 NCT00001951 0
1112
+ sigir-201429 NCT00010686 0
1113
+ sigir-201429 NCT00010712 1
1114
+ sigir-201429 NCT00011323 0
1115
+ sigir-201429 NCT00021827 1
1116
+ sigir-201429 NCT00073190 1
1117
+ sigir-201429 NCT00092053 0
1118
+ sigir-201429 NCT00145080 1
1119
+ sigir-201429 NCT00170339 0
1120
+ sigir-201429 NCT00224991 0
1121
+ sigir-201429 NCT00226031 0
1122
+ sigir-201429 NCT00273260 0
1123
+ sigir-201429 NCT00280943 0
1124
+ sigir-201429 NCT00301353 1
1125
+ sigir-201429 NCT00303485 0
1126
+ sigir-201429 NCT00327847 1
1127
+ sigir-201429 NCT00347737 0
1128
+ sigir-201429 NCT00376662 0
1129
+ sigir-201429 NCT00386022 0
1130
+ sigir-201429 NCT00432692 0
1131
+ sigir-201429 NCT00540267 0
1132
+ sigir-201429 NCT00545779 0
1133
+ sigir-201429 NCT00575250 0
1134
+ sigir-201429 NCT00578981 1
1135
+ sigir-201429 NCT00609830 0
1136
+ sigir-201429 NCT00698984 0
1137
+ sigir-201429 NCT00703417 2
1138
+ sigir-201429 NCT00762775 2
1139
+ sigir-201429 NCT00787904 0
1140
+ sigir-201429 NCT00846638 1
1141
+ sigir-201429 NCT00860964 0
1142
+ sigir-201429 NCT00982371 0
1143
+ sigir-201429 NCT01035177 0
1144
+ sigir-201429 NCT01128257 0
1145
+ sigir-201429 NCT01141972 0
1146
+ sigir-201429 NCT01152580 1
1147
+ sigir-201429 NCT01206491 2
1148
+ sigir-201429 NCT01227369 0
1149
+ sigir-201429 NCT01232647 0
1150
+ sigir-201429 NCT01314807 0
1151
+ sigir-201429 NCT01341067 1
1152
+ sigir-201429 NCT01360424 0
1153
+ sigir-201429 NCT01440803 0
1154
+ sigir-201429 NCT01452243 0
1155
+ sigir-201429 NCT01512446 0
1156
+ sigir-201429 NCT01607775 0
1157
+ sigir-201429 NCT01677637 2
1158
+ sigir-201429 NCT01698463 0
1159
+ sigir-201429 NCT01821885 1
1160
+ sigir-201429 NCT01846533 1
1161
+ sigir-201429 NCT01854086 0
1162
+ sigir-201429 NCT01870557 1
1163
+ sigir-201429 NCT01928134 0
1164
+ sigir-201429 NCT01934400 0
1165
+ sigir-201429 NCT01935232 1
1166
+ sigir-201429 NCT01978834 2
1167
+ sigir-201429 NCT01998737 2
1168
+ sigir-201429 NCT02066480 0
1169
+ sigir-201429 NCT02115711 1
1170
+ sigir-201429 NCT02164552 0
1171
+ sigir-201429 NCT02184962 1
1172
+ sigir-201429 NCT02273128 0
1173
+ sigir-201429 NCT02347865 0
1174
+ sigir-201429 NCT02422069 2
1175
+ sigir-201429 NCT02472782 0
1176
+ sigir-201429 NCT02534714 0
1177
+ sigir-201429 NCT02551315 2
1178
+ sigir-201429 NCT02594592 2
1179
+ sigir-20143 NCT00001776 1
1180
+ sigir-20143 NCT00001777 0
1181
+ sigir-20143 NCT00003562 1
1182
+ sigir-20143 NCT00003859 0
1183
+ sigir-20143 NCT00005666 0
1184
+ sigir-20143 NCT00006087 0
1185
+ sigir-20143 NCT00024908 1
1186
+ sigir-20143 NCT00047801 1
1187
+ sigir-20143 NCT00049543 0
1188
+ sigir-20143 NCT00088569 0
1189
+ sigir-20143 NCT00124761 2
1190
+ sigir-20143 NCT00128986 0
1191
+ sigir-20143 NCT00172575 1
1192
+ sigir-20143 NCT00181272 0
1193
+ sigir-20143 NCT00188279 0
1194
+ sigir-20143 NCT00188435 0
1195
+ sigir-20143 NCT00193765 0
1196
+ sigir-20143 NCT00202176 0
1197
+ sigir-20143 NCT00303901 1
1198
+ sigir-20143 NCT00339066 0
1199
+ sigir-20143 NCT00382707 0
1200
+ sigir-20143 NCT00423332 0
1201
+ sigir-20143 NCT00466947 0
1202
+ sigir-20143 NCT00517959 0
1203
+ sigir-20143 NCT00578084 2
1204
+ sigir-20143 NCT00579852 1
1205
+ sigir-20143 NCT00591838 0
1206
+ sigir-20143 NCT00613041 0
1207
+ sigir-20143 NCT00629460 0
1208
+ sigir-20143 NCT00633035 2
1209
+ sigir-20143 NCT00643318 0
1210
+ sigir-20143 NCT00757120 0
1211
+ sigir-20143 NCT00839488 0
1212
+ sigir-20143 NCT00852644 0
1213
+ sigir-20143 NCT00894569 0
1214
+ sigir-20143 NCT00897650 2
1215
+ sigir-20143 NCT00907543 0
1216
+ sigir-20143 NCT00918320 2
1217
+ sigir-20143 NCT00963651 2
1218
+ sigir-20143 NCT00992966 0
1219
+ sigir-20143 NCT01028417 0
1220
+ sigir-20143 NCT01085864 1
1221
+ sigir-20143 NCT01109147 0
1222
+ sigir-20143 NCT01141842 1
1223
+ sigir-20143 NCT01149187 1
1224
+ sigir-20143 NCT01152463 1
1225
+ sigir-20143 NCT01152788 0
1226
+ sigir-20143 NCT01201824 1
1227
+ sigir-20143 NCT01221493 1
1228
+ sigir-20143 NCT01272622 0
1229
+ sigir-20143 NCT01349400 0
1230
+ sigir-20143 NCT01351870 0
1231
+ sigir-20143 NCT01354912 0
1232
+ sigir-20143 NCT01452971 2
1233
+ sigir-20143 NCT01465425 2
1234
+ sigir-20143 NCT01561729 0
1235
+ sigir-20143 NCT01566682 1
1236
+ sigir-20143 NCT01572571 0
1237
+ sigir-20143 NCT01572584 0
1238
+ sigir-20143 NCT01586611 0
1239
+ sigir-20143 NCT01605214 0
1240
+ sigir-20143 NCT01649752 0
1241
+ sigir-20143 NCT01654887 0
1242
+ sigir-20143 NCT01663155 0
1243
+ sigir-20143 NCT01668459 0
1244
+ sigir-20143 NCT01669135 0
1245
+ sigir-20143 NCT01696292 0
1246
+ sigir-20143 NCT01696968 0
1247
+ sigir-20143 NCT01700257 0
1248
+ sigir-20143 NCT01739881 2
1249
+ sigir-20143 NCT01802125 0
1250
+ sigir-20143 NCT01803542 0
1251
+ sigir-20143 NCT01847209 1
1252
+ sigir-20143 NCT01863069 0
1253
+ sigir-20143 NCT01864538 0
1254
+ sigir-20143 NCT01908933 0
1255
+ sigir-20143 NCT01951846 1
1256
+ sigir-20143 NCT02013063 0
1257
+ sigir-20143 NCT02022371 0
1258
+ sigir-20143 NCT02050724 1
1259
+ sigir-20143 NCT02051868 0
1260
+ sigir-20143 NCT02081105 1
1261
+ sigir-20143 NCT02095808 2
1262
+ sigir-20143 NCT02096445 0
1263
+ sigir-20143 NCT02137291 0
1264
+ sigir-20143 NCT02225392 0
1265
+ sigir-20143 NCT02289144 0
1266
+ sigir-20143 NCT02374242 0
1267
+ sigir-20143 NCT02434107 0
1268
+ sigir-20143 NCT02439086 0
1269
+ sigir-20143 NCT02441478 0
1270
+ sigir-20143 NCT02445183 0
1271
+ sigir-20143 NCT02448225 0
1272
+ sigir-20143 NCT02490059 1
1273
+ sigir-20143 NCT02501668 2
1274
+ sigir-20143 NCT02505750 0
1275
+ sigir-20143 NCT02519972 2
1276
+ sigir-20143 NCT02563691 0
1277
+ sigir-20143 NCT02623712 1
1278
+ sigir-201430 NCT00005134 0
1279
+ sigir-201430 NCT00005254 0
1280
+ sigir-201430 NCT00005338 0
1281
+ sigir-201430 NCT00118560 0
1282
+ sigir-201430 NCT00171054 0
1283
+ sigir-201430 NCT00173602 0
1284
+ sigir-201430 NCT00185068 1
1285
+ sigir-201430 NCT00262470 1
1286
+ sigir-201430 NCT00310752 0
1287
+ sigir-201430 NCT00311805 0
1288
+ sigir-201430 NCT00368095 1
1289
+ sigir-201430 NCT00471289 0
1290
+ sigir-201430 NCT00481741 0
1291
+ sigir-201430 NCT00485329 0
1292
+ sigir-201430 NCT00603590 1
1293
+ sigir-201430 NCT00721006 2
1294
+ sigir-201430 NCT00725881 0
1295
+ sigir-201430 NCT00739596 0
1296
+ sigir-201430 NCT00753025 0
1297
+ sigir-201430 NCT00762086 0
1298
+ sigir-201430 NCT00768495 0
1299
+ sigir-201430 NCT00781950 0
1300
+ sigir-201430 NCT00883246 1
1301
+ sigir-201430 NCT00926770 0
1302
+ sigir-201430 NCT00931112 0
1303
+ sigir-201430 NCT00996281 0
1304
+ sigir-201430 NCT01002235 0
1305
+ sigir-201430 NCT01019681 1
1306
+ sigir-201430 NCT01041729 1
1307
+ sigir-201430 NCT01076738 0
1308
+ sigir-201430 NCT01118000 0
1309
+ sigir-201430 NCT01250275 1
1310
+ sigir-201430 NCT01289548 0
1311
+ sigir-201430 NCT01335022 0
1312
+ sigir-201430 NCT01362283 0
1313
+ sigir-201430 NCT01382277 1
1314
+ sigir-201430 NCT01397474 0
1315
+ sigir-201430 NCT01422343 1
1316
+ sigir-201430 NCT01475097 1
1317
+ sigir-201430 NCT01475786 0
1318
+ sigir-201430 NCT01499134 0
1319
+ sigir-201430 NCT01505738 1
1320
+ sigir-201430 NCT01624519 0
1321
+ sigir-201430 NCT01625832 1
1322
+ sigir-201430 NCT01691911 0
1323
+ sigir-201430 NCT01698853 0
1324
+ sigir-201430 NCT01741896 0
1325
+ sigir-201430 NCT01801592 1
1326
+ sigir-201430 NCT01902654 0
1327
+ sigir-201430 NCT01970332 1
1328
+ sigir-201430 NCT02003781 0
1329
+ sigir-201430 NCT02051088 1
1330
+ sigir-201430 NCT02057328 0
1331
+ sigir-201430 NCT02097186 0
1332
+ sigir-201430 NCT02110251 1
1333
+ sigir-201430 NCT02123004 0
1334
+ sigir-201430 NCT02133911 0
1335
+ sigir-201430 NCT02217501 1
1336
+ sigir-201430 NCT02254356 2
1337
+ sigir-201430 NCT02273232 2
1338
+ sigir-201430 NCT02406131 1
1339
+ sigir-201430 NCT02427464 0
1340
+ sigir-201430 NCT02427867 0
1341
+ sigir-201430 NCT02431819 1
1342
+ sigir-201430 NCT02433990 0
1343
+ sigir-201430 NCT02436200 0
1344
+ sigir-201430 NCT02516072 1
1345
+ sigir-20144 NCT00044239 0
1346
+ sigir-20144 NCT00053456 0
1347
+ sigir-20144 NCT00100126 0
1348
+ sigir-20144 NCT00162032 0
1349
+ sigir-20144 NCT00254930 0
1350
+ sigir-20144 NCT00271570 2
1351
+ sigir-20144 NCT00305201 0
1352
+ sigir-20144 NCT00591916 0
1353
+ sigir-20144 NCT00604786 0
1354
+ sigir-20144 NCT00643149 0
1355
+ sigir-20144 NCT00793403 0
1356
+ sigir-20144 NCT00841789 2
1357
+ sigir-20144 NCT01050062 0
1358
+ sigir-20144 NCT01173939 0
1359
+ sigir-20144 NCT01212770 0
1360
+ sigir-20144 NCT01244217 0
1361
+ sigir-20144 NCT01281969 0
1362
+ sigir-20144 NCT01307423 0
1363
+ sigir-20144 NCT01433861 0
1364
+ sigir-20144 NCT01440075 0
1365
+ sigir-20144 NCT01491776 0
1366
+ sigir-20144 NCT01494792 0
1367
+ sigir-20144 NCT01596335 2
1368
+ sigir-20144 NCT01917721 1
1369
+ sigir-20144 NCT02031120 0
1370
+ sigir-20144 NCT02063789 0
1371
+ sigir-20144 NCT02247765 0
1372
+ sigir-20144 NCT02317913 2
1373
+ sigir-20144 NCT02390596 1
1374
+ sigir-20144 NCT02439996 2
1375
+ sigir-20144 NCT02457403 0
1376
+ sigir-20144 NCT02557334 0
1377
+ sigir-20144 NCT02624882 0
1378
+ sigir-20145 NCT00000566 1
1379
+ sigir-20145 NCT00003674 0
1380
+ sigir-20145 NCT00005351 0
1381
+ sigir-20145 NCT00041509 0
1382
+ sigir-20145 NCT00043927 0
1383
+ sigir-20145 NCT00075179 0
1384
+ sigir-20145 NCT00083772 0
1385
+ sigir-20145 NCT00123734 2
1386
+ sigir-20145 NCT00138099 0
1387
+ sigir-20145 NCT00163709 1
1388
+ sigir-20145 NCT00178789 2
1389
+ sigir-20145 NCT00182364 0
1390
+ sigir-20145 NCT00196417 0
1391
+ sigir-20145 NCT00203970 2
1392
+ sigir-20145 NCT00264901 0
1393
+ sigir-20145 NCT00277394 1
1394
+ sigir-20145 NCT00314548 0
1395
+ sigir-20145 NCT00321048 1
1396
+ sigir-20145 NCT00329433 0
1397
+ sigir-20145 NCT00361959 0
1398
+ sigir-20145 NCT00365950 2
1399
+ sigir-20145 NCT00368836 0
1400
+ sigir-20145 NCT00455468 0
1401
+ sigir-20145 NCT00456196 1
1402
+ sigir-20145 NCT00618579 0
1403
+ sigir-20145 NCT00714597 0
1404
+ sigir-20145 NCT00719784 2
1405
+ sigir-20145 NCT00726570 0
1406
+ sigir-20145 NCT00726947 1
1407
+ sigir-20145 NCT00743106 0
1408
+ sigir-20145 NCT00756145 0
1409
+ sigir-20145 NCT00771563 0
1410
+ sigir-20145 NCT00789399 0
1411
+ sigir-20145 NCT00816920 0
1412
+ sigir-20145 NCT00997737 0
1413
+ sigir-20145 NCT01137578 0
1414
+ sigir-20145 NCT01164046 1
1415
+ sigir-20145 NCT01183026 2
1416
+ sigir-20145 NCT01212757 0
1417
+ sigir-20145 NCT01258725 0
1418
+ sigir-20145 NCT01298986 0
1419
+ sigir-20145 NCT01300832 0
1420
+ sigir-20145 NCT01307423 0
1421
+ sigir-20145 NCT01317160 0
1422
+ sigir-20145 NCT01318174 0
1423
+ sigir-20145 NCT01344954 0
1424
+ sigir-20145 NCT01394107 0
1425
+ sigir-20145 NCT01444612 0
1426
+ sigir-20145 NCT01535248 0
1427
+ sigir-20145 NCT01542723 0
1428
+ sigir-20145 NCT01542762 0
1429
+ sigir-20145 NCT01557725 0
1430
+ sigir-20145 NCT01559532 0
1431
+ sigir-20145 NCT01604538 2
1432
+ sigir-20145 NCT01662843 2
1433
+ sigir-20145 NCT01708239 0
1434
+ sigir-20145 NCT01724996 0
1435
+ sigir-20145 NCT01729559 2
1436
+ sigir-20145 NCT01752673 0
1437
+ sigir-20145 NCT01770912 0
1438
+ sigir-20145 NCT01793194 0
1439
+ sigir-20145 NCT01849406 0
1440
+ sigir-20145 NCT01856842 0
1441
+ sigir-20145 NCT01899339 1
1442
+ sigir-20145 NCT01935141 2
1443
+ sigir-20145 NCT01940328 0
1444
+ sigir-20145 NCT01956955 1
1445
+ sigir-20145 NCT01959529 0
1446
+ sigir-20145 NCT01970202 0
1447
+ sigir-20145 NCT02070354 0
1448
+ sigir-20145 NCT02102828 0
1449
+ sigir-20145 NCT02134652 0
1450
+ sigir-20145 NCT02356120 2
1451
+ sigir-20145 NCT02369263 2
1452
+ sigir-20145 NCT02393963 0
1453
+ sigir-20145 NCT02406885 0
1454
+ sigir-20145 NCT02447731 0
1455
+ sigir-20145 NCT02507180 0
1456
+ sigir-20145 NCT02553200 0
1457
+ sigir-20145 NCT02584725 0
1458
+ sigir-20146 NCT00004572 0
1459
+ sigir-20146 NCT00006426 1
1460
+ sigir-20146 NCT00013286 1
1461
+ sigir-20146 NCT00015626 1
1462
+ sigir-20146 NCT00034788 2
1463
+ sigir-20146 NCT00095446 2
1464
+ sigir-20146 NCT00117364 0
1465
+ sigir-20146 NCT00134550 0
1466
+ sigir-20146 NCT00235196 0
1467
+ sigir-20146 NCT00269100 0
1468
+ sigir-20146 NCT00289497 0
1469
+ sigir-20146 NCT00304733 1
1470
+ sigir-20146 NCT00311922 2
1471
+ sigir-20146 NCT00338702 0
1472
+ sigir-20146 NCT00355602 0
1473
+ sigir-20146 NCT00358059 0
1474
+ sigir-20146 NCT00399425 2
1475
+ sigir-20146 NCT00410449 0
1476
+ sigir-20146 NCT00446823 1
1477
+ sigir-20146 NCT00469105 2
1478
+ sigir-20146 NCT00477022 0
1479
+ sigir-20146 NCT00512538 0
1480
+ sigir-20146 NCT00519493 0
1481
+ sigir-20146 NCT00519935 1
1482
+ sigir-20146 NCT00521027 0
1483
+ sigir-20146 NCT00621608 2
1484
+ sigir-20146 NCT00655044 1
1485
+ sigir-20146 NCT00754741 1
1486
+ sigir-20146 NCT00789646 0
1487
+ sigir-20146 NCT00807664 0
1488
+ sigir-20146 NCT00830453 0
1489
+ sigir-20146 NCT00839865 0
1490
+ sigir-20146 NCT00866424 0
1491
+ sigir-20146 NCT00916500 0
1492
+ sigir-20146 NCT00950040 1
1493
+ sigir-20146 NCT00955669 0
1494
+ sigir-20146 NCT00970697 1
1495
+ sigir-20146 NCT00990522 1
1496
+ sigir-20146 NCT00999635 1
1497
+ sigir-20146 NCT01005264 0
1498
+ sigir-20146 NCT01013792 0
1499
+ sigir-20146 NCT01028404 0
1500
+ sigir-20146 NCT01043354 1
1501
+ sigir-20146 NCT01094899 1
1502
+ sigir-20146 NCT01181453 0
1503
+ sigir-20146 NCT01211236 1
1504
+ sigir-20146 NCT01217463 0
1505
+ sigir-20146 NCT01217567 0
1506
+ sigir-20146 NCT01237392 0
1507
+ sigir-20146 NCT01259206 2
1508
+ sigir-20146 NCT01263288 0
1509
+ sigir-20146 NCT01285973 0
1510
+ sigir-20146 NCT01319123 0
1511
+ sigir-20146 NCT01339637 0
1512
+ sigir-20146 NCT01356459 0
1513
+ sigir-20146 NCT01370837 0
1514
+ sigir-20146 NCT01396304 1
1515
+ sigir-20146 NCT01396837 0
1516
+ sigir-20146 NCT01417208 1
1517
+ sigir-20146 NCT01432925 0
1518
+ sigir-20146 NCT01449422 0
1519
+ sigir-20146 NCT01477047 0
1520
+ sigir-20146 NCT01480414 0
1521
+ sigir-20146 NCT01531517 0
1522
+ sigir-20146 NCT01542463 2
1523
+ sigir-20146 NCT01580917 1
1524
+ sigir-20146 NCT01583465 0
1525
+ sigir-20146 NCT01584817 0
1526
+ sigir-20146 NCT01586481 0
1527
+ sigir-20146 NCT01657318 0
1528
+ sigir-20146 NCT01666093 1
1529
+ sigir-20146 NCT01716624 0
1530
+ sigir-20146 NCT01733524 0
1531
+ sigir-20146 NCT01796548 0
1532
+ sigir-20146 NCT01827683 0
1533
+ sigir-20146 NCT01865292 0
1534
+ sigir-20146 NCT01912976 0
1535
+ sigir-20146 NCT01924806 0
1536
+ sigir-20146 NCT01951768 1
1537
+ sigir-20146 NCT01966380 2
1538
+ sigir-20146 NCT01986205 0
1539
+ sigir-20146 NCT01998932 0
1540
+ sigir-20146 NCT02007824 0
1541
+ sigir-20146 NCT02052817 0
1542
+ sigir-20146 NCT02073188 0
1543
+ sigir-20146 NCT02087215 0
1544
+ sigir-20146 NCT02136654 0
1545
+ sigir-20146 NCT02144142 0
1546
+ sigir-20146 NCT02169167 0
1547
+ sigir-20146 NCT02217722 0
1548
+ sigir-20146 NCT02222376 2
1549
+ sigir-20146 NCT02235935 1
1550
+ sigir-20146 NCT02251418 1
1551
+ sigir-20146 NCT02294175 0
1552
+ sigir-20146 NCT02329366 1
1553
+ sigir-20146 NCT02379507 1
1554
+ sigir-20146 NCT02405741 0
1555
+ sigir-20146 NCT02447172 0
1556
+ sigir-20146 NCT02458495 0
1557
+ sigir-20146 NCT02482948 1
1558
+ sigir-20146 NCT02512159 2
1559
+ sigir-20146 NCT02557698 0
1560
+ sigir-20146 NCT02563678 2
1561
+ sigir-20146 NCT02583958 0
1562
+ sigir-20146 NCT02586519 0
1563
+ sigir-20146 NCT02598180 0
1564
+ sigir-20146 NCT02619877 1
1565
+ sigir-20146 NCT02621476 0
1566
+ sigir-20147 NCT00000369 2
1567
+ sigir-20147 NCT00005015 1
1568
+ sigir-20147 NCT00006170 0
1569
+ sigir-20147 NCT00012558 2
1570
+ sigir-20147 NCT00043654 1
1571
+ sigir-20147 NCT00044187 0
1572
+ sigir-20147 NCT00063362 1
1573
+ sigir-20147 NCT00074789 0
1574
+ sigir-20147 NCT00088387 0
1575
+ sigir-20147 NCT00114439 0
1576
+ sigir-20147 NCT00116259 0
1577
+ sigir-20147 NCT00156325 0
1578
+ sigir-20147 NCT00156533 0
1579
+ sigir-20147 NCT00167479 0
1580
+ sigir-20147 NCT00174876 0
1581
+ sigir-20147 NCT00177216 0
1582
+ sigir-20147 NCT00194038 0
1583
+ sigir-20147 NCT00202293 0
1584
+ sigir-20147 NCT00203450 0
1585
+ sigir-20147 NCT00221442 0
1586
+ sigir-20147 NCT00223509 2
1587
+ sigir-20147 NCT00226135 2
1588
+ sigir-20147 NCT00275834 0
1589
+ sigir-20147 NCT00277641 0
1590
+ sigir-20147 NCT00277654 0
1591
+ sigir-20147 NCT00296179 0
1592
+ sigir-20147 NCT00296790 0
1593
+ sigir-20147 NCT00318448 0
1594
+ sigir-20147 NCT00332098 0
1595
+ sigir-20147 NCT00348036 0
1596
+ sigir-20147 NCT00374543 1
1597
+ sigir-20147 NCT00380081 1
1598
+ sigir-20147 NCT00383643 0
1599
+ sigir-20147 NCT00384332 0
1600
+ sigir-20147 NCT00393978 0
1601
+ sigir-20147 NCT00394095 0
1602
+ sigir-20147 NCT00422331 0
1603
+ sigir-20147 NCT00431171 0
1604
+ sigir-20147 NCT00432198 0
1605
+ sigir-20147 NCT00464191 2
1606
+ sigir-20147 NCT00466193 0
1607
+ sigir-20147 NCT00469937 0
1608
+ sigir-20147 NCT00485680 1
1609
+ sigir-20147 NCT00492232 0
1610
+ sigir-20147 NCT00494468 0
1611
+ sigir-20147 NCT00501540 0
1612
+ sigir-20147 NCT00545233 0
1613
+ sigir-20147 NCT00552760 1
1614
+ sigir-20147 NCT00563992 2
1615
+ sigir-20147 NCT00573196 2
1616
+ sigir-20147 NCT00579280 0
1617
+ sigir-20147 NCT00582712 0
1618
+ sigir-20147 NCT00584961 2
1619
+ sigir-20147 NCT00592696 0
1620
+ sigir-20147 NCT00601536 1
1621
+ sigir-20147 NCT00601575 0
1622
+ sigir-20147 NCT00602394 0
1623
+ sigir-20147 NCT00602537 0
1624
+ sigir-20147 NCT00606840 0
1625
+ sigir-20147 NCT00608296 1
1626
+ sigir-20147 NCT00630175 1
1627
+ sigir-20147 NCT00641108 0
1628
+ sigir-20147 NCT00658541 0
1629
+ sigir-20147 NCT00662155 0
1630
+ sigir-20147 NCT00665366 1
1631
+ sigir-20147 NCT00672490 2
1632
+ sigir-20147 NCT00684814 0
1633
+ sigir-20147 NCT00709202 0
1634
+ sigir-20147 NCT00716521 0
1635
+ sigir-20147 NCT00720395 0
1636
+ sigir-20147 NCT00721955 1
1637
+ sigir-20147 NCT00741299 2
1638
+ sigir-20147 NCT00750061 0
1639
+ sigir-20147 NCT00781482 0
1640
+ sigir-20147 NCT00806234 0
1641
+ sigir-20147 NCT00814502 0
1642
+ sigir-20147 NCT00820794 0
1643
+ sigir-20147 NCT00838032 0
1644
+ sigir-20147 NCT00845507 0
1645
+ sigir-20147 NCT00845988 2
1646
+ sigir-20147 NCT00883493 1
1647
+ sigir-20147 NCT00934908 0
1648
+ sigir-20147 NCT00936598 0
1649
+ sigir-20147 NCT00956319 1
1650
+ sigir-20147 NCT00957359 0
1651
+ sigir-20147 NCT00986128 2
1652
+ sigir-20147 NCT00993850 2
1653
+ sigir-20147 NCT00997672 0
1654
+ sigir-20147 NCT00998634 0
1655
+ sigir-20147 NCT00999219 0
1656
+ sigir-20147 NCT01006525 0
1657
+ sigir-20147 NCT01012180 1
1658
+ sigir-20147 NCT01072929 0
1659
+ sigir-20147 NCT01074073 0
1660
+ sigir-20147 NCT01075295 0
1661
+ sigir-20147 NCT01093937 0
1662
+ sigir-20147 NCT01117961 0
1663
+ sigir-20147 NCT01134731 0
1664
+ sigir-20147 NCT01159652 0
1665
+ sigir-20147 NCT01166425 0
1666
+ sigir-20147 NCT01172652 0
1667
+ sigir-20147 NCT01181232 1
1668
+ sigir-20147 NCT01181583 0
1669
+ sigir-20147 NCT01184443 0
1670
+ sigir-20147 NCT01259388 0
1671
+ sigir-20147 NCT01293825 1
1672
+ sigir-20147 NCT01363310 0
1673
+ sigir-20147 NCT01385709 2
1674
+ sigir-20147 NCT01395238 0
1675
+ sigir-20147 NCT01416220 0
1676
+ sigir-20147 NCT01428518 0
1677
+ sigir-20147 NCT01471613 0
1678
+ sigir-20147 NCT01491490 0
1679
+ sigir-20147 NCT01526148 2
1680
+ sigir-20147 NCT01551485 0
1681
+ sigir-20147 NCT01689909 1
1682
+ sigir-20147 NCT01704352 1
1683
+ sigir-20147 NCT01736709 0
1684
+ sigir-20147 NCT01764035 0
1685
+ sigir-20147 NCT01783652 0
1686
+ sigir-20147 NCT01784666 2
1687
+ sigir-20147 NCT01804036 0
1688
+ sigir-20147 NCT01855594 0
1689
+ sigir-20147 NCT01863628 1
1690
+ sigir-20147 NCT01892306 0
1691
+ sigir-20147 NCT01893229 2
1692
+ sigir-20147 NCT01896336 0
1693
+ sigir-20147 NCT01928446 0
1694
+ sigir-20147 NCT01944293 2
1695
+ sigir-20147 NCT01954680 0
1696
+ sigir-20147 NCT02003690 0
1697
+ sigir-20147 NCT02033915 0
1698
+ sigir-20147 NCT02039479 0
1699
+ sigir-20147 NCT02090595 0
1700
+ sigir-20147 NCT02096900 0
1701
+ sigir-20147 NCT02116400 0
1702
+ sigir-20147 NCT02129790 0
1703
+ sigir-20147 NCT02139098 0
1704
+ sigir-20147 NCT02163564 0
1705
+ sigir-20147 NCT02198859 0
1706
+ sigir-20147 NCT02281162 0
1707
+ sigir-20147 NCT02287259 0
1708
+ sigir-20147 NCT02323763 2
1709
+ sigir-20147 NCT02353299 1
1710
+ sigir-20147 NCT02399423 0
1711
+ sigir-20147 NCT02484963 0
1712
+ sigir-20147 NCT02490241 0
1713
+ sigir-20147 NCT02491307 2
1714
+ sigir-20147 NCT02525991 0
1715
+ sigir-20147 NCT02527564 0
1716
+ sigir-20147 NCT02593643 0
1717
+ sigir-20147 NCT02604277 2
1718
+ sigir-20147 NCT02607696 0
1719
+ sigir-20148 NCT00002414 1
1720
+ sigir-20148 NCT00004771 0
1721
+ sigir-20148 NCT00031369 1
1722
+ sigir-20148 NCT00040196 0
1723
+ sigir-20148 NCT00077896 1
1724
+ sigir-20148 NCT00104663 0
1725
+ sigir-20148 NCT00108849 0
1726
+ sigir-20148 NCT00169468 0
1727
+ sigir-20148 NCT00297271 0
1728
+ sigir-20148 NCT00306124 0
1729
+ sigir-20148 NCT00340301 1
1730
+ sigir-20148 NCT00393588 0
1731
+ sigir-20148 NCT00439127 0
1732
+ sigir-20148 NCT00474292 0
1733
+ sigir-20148 NCT00476372 0
1734
+ sigir-20148 NCT00526084 0
1735
+ sigir-20148 NCT00631332 0
1736
+ sigir-20148 NCT00718107 1
1737
+ sigir-20148 NCT00718458 0
1738
+ sigir-20148 NCT00781833 0
1739
+ sigir-20148 NCT00786032 0
1740
+ sigir-20148 NCT00812474 0
1741
+ sigir-20148 NCT00816556 0
1742
+ sigir-20148 NCT00832403 0
1743
+ sigir-20148 NCT00897299 0
1744
+ sigir-20148 NCT00921648 0
1745
+ sigir-20148 NCT01022307 0
1746
+ sigir-20148 NCT01050881 0
1747
+ sigir-20148 NCT01122342 0
1748
+ sigir-20148 NCT01231672 0
1749
+ sigir-20148 NCT01238926 1
1750
+ sigir-20148 NCT01315704 1
1751
+ sigir-20148 NCT01388400 0
1752
+ sigir-20148 NCT01390922 2
1753
+ sigir-20148 NCT01438060 0
1754
+ sigir-20148 NCT01463475 0
1755
+ sigir-20148 NCT01507454 0
1756
+ sigir-20148 NCT01519271 2
1757
+ sigir-20148 NCT01555827 0
1758
+ sigir-20148 NCT01586520 0
1759
+ sigir-20148 NCT01592825 0
1760
+ sigir-20148 NCT01628315 2
1761
+ sigir-20148 NCT01637051 0
1762
+ sigir-20148 NCT01641627 0
1763
+ sigir-20148 NCT01677793 0
1764
+ sigir-20148 NCT01725178 0
1765
+ sigir-20148 NCT01862172 0
1766
+ sigir-20148 NCT01910363 1
1767
+ sigir-20148 NCT01942759 0
1768
+ sigir-20148 NCT01944397 0
1769
+ sigir-20148 NCT01960985 1
1770
+ sigir-20148 NCT01962779 0
1771
+ sigir-20148 NCT02002884 0
1772
+ sigir-20148 NCT02020980 0
1773
+ sigir-20148 NCT02045004 0
1774
+ sigir-20148 NCT02056613 0
1775
+ sigir-20148 NCT02067247 0
1776
+ sigir-20148 NCT02152449 0
1777
+ sigir-20148 NCT02208219 0
1778
+ sigir-20148 NCT02212119 1
1779
+ sigir-20148 NCT02275312 0
1780
+ sigir-20148 NCT02440815 0
1781
+ sigir-20148 NCT02480803 0
1782
+ sigir-20148 NCT02544178 0
1783
+ sigir-20148 NCT02571504 0
1784
+ sigir-20148 NCT02579278 0
1785
+ sigir-20148 NCT02588053 0
1786
+ sigir-20148 NCT02589925 0
1787
+ sigir-20148 NCT02604186 0
1788
+ sigir-20149 NCT00124163 0
1789
+ sigir-20149 NCT00237276 0
1790
+ sigir-20149 NCT00291486 0
1791
+ sigir-20149 NCT00476905 2
1792
+ sigir-20149 NCT00610818 0
1793
+ sigir-20149 NCT00617825 0
1794
+ sigir-20149 NCT00667225 0
1795
+ sigir-20149 NCT00684294 0
1796
+ sigir-20149 NCT00911352 0
1797
+ sigir-20149 NCT00937690 1
1798
+ sigir-20149 NCT01010321 1
1799
+ sigir-20149 NCT01014819 2
1800
+ sigir-20149 NCT01023984 0
1801
+ sigir-20149 NCT01072045 0
1802
+ sigir-20149 NCT01125150 0
1803
+ sigir-20149 NCT01259037 2
1804
+ sigir-20149 NCT01384357 0
1805
+ sigir-20149 NCT01405755 1
1806
+ sigir-20149 NCT01406379 0
1807
+ sigir-20149 NCT01444989 2
1808
+ sigir-20149 NCT01492647 0
1809
+ sigir-20149 NCT01509599 0
1810
+ sigir-20149 NCT01541553 1
1811
+ sigir-20149 NCT01565993 0
1812
+ sigir-20149 NCT01574664 0
1813
+ sigir-20149 NCT01633515 0
1814
+ sigir-20149 NCT01636453 0
1815
+ sigir-20149 NCT01680562 2
1816
+ sigir-20149 NCT01700101 1
1817
+ sigir-20149 NCT01800656 0
1818
+ sigir-20149 NCT01950026 1
1819
+ sigir-20149 NCT01994616 0
1820
+ sigir-20149 NCT02005796 0
1821
+ sigir-20149 NCT02009566 2
1822
+ sigir-20149 NCT02063243 0
1823
+ sigir-20149 NCT02063971 0
1824
+ sigir-20149 NCT02147353 0
1825
+ sigir-20149 NCT02156193 0
1826
+ sigir-20149 NCT02160626 0
1827
+ sigir-20149 NCT02196246 1
1828
+ sigir-20149 NCT02220127 0
1829
+ sigir-20149 NCT02260180 0
1830
+ sigir-20149 NCT02366559 0
1831
+ sigir-20149 NCT02432118 0
1832
+ sigir-20149 NCT02476747 0
1833
+ sigir-20149 NCT02525822 0
1834
+ sigir-20149 NCT02537483 0
1835
+ sigir-20149 NCT02615912 1
1836
+ sigir-20151 NCT00038272 0
1837
+ sigir-20151 NCT00040495 2
1838
+ sigir-20151 NCT00147030 0
1839
+ sigir-20151 NCT00152399 2
1840
+ sigir-20151 NCT00153712 0
1841
+ sigir-20151 NCT00164905 1
1842
+ sigir-20151 NCT00164931 1
1843
+ sigir-20151 NCT00165009 2
1844
+ sigir-20151 NCT00282373 0
1845
+ sigir-20151 NCT00314704 2
1846
+ sigir-20151 NCT00316017 0
1847
+ sigir-20151 NCT00374101 1
1848
+ sigir-20151 NCT00392639 0
1849
+ sigir-20151 NCT00432991 0
1850
+ sigir-20151 NCT00441727 1
1851
+ sigir-20151 NCT00612196 0
1852
+ sigir-20151 NCT00624169 2
1853
+ sigir-20151 NCT00687336 1
1854
+ sigir-20151 NCT00727974 0
1855
+ sigir-20151 NCT00731601 2
1856
+ sigir-20151 NCT00751634 0
1857
+ sigir-20151 NCT00753064 0
1858
+ sigir-20151 NCT00771563 0
1859
+ sigir-20151 NCT00797641 1
1860
+ sigir-20151 NCT00810121 0
1861
+ sigir-20151 NCT00838682 2
1862
+ sigir-20151 NCT00843063 1
1863
+ sigir-20151 NCT00854776 0
1864
+ sigir-20151 NCT00881413 2
1865
+ sigir-20151 NCT00950417 0
1866
+ sigir-20151 NCT01040416 0
1867
+ sigir-20151 NCT01041196 0
1868
+ sigir-20151 NCT01080326 2
1869
+ sigir-20151 NCT01123837 0
1870
+ sigir-20151 NCT01138969 0
1871
+ sigir-20151 NCT01142180 1
1872
+ sigir-20151 NCT01142245 1
1873
+ sigir-20151 NCT01155401 2
1874
+ sigir-20151 NCT01165866 0
1875
+ sigir-20151 NCT01180179 1
1876
+ sigir-20151 NCT01182597 2
1877
+ sigir-20151 NCT01292915 2
1878
+ sigir-20151 NCT01353144 0
1879
+ sigir-20151 NCT01371591 2
1880
+ sigir-20151 NCT01408186 1
1881
+ sigir-20151 NCT01411852 0
1882
+ sigir-20151 NCT01474915 0
1883
+ sigir-20151 NCT01551641 1
1884
+ sigir-20151 NCT01560702 2
1885
+ sigir-20151 NCT01822600 2
1886
+ sigir-20151 NCT01838863 0
1887
+ sigir-20151 NCT01845168 0
1888
+ sigir-20151 NCT01888588 0
1889
+ sigir-20151 NCT01911702 0
1890
+ sigir-20151 NCT01923064 0
1891
+ sigir-20151 NCT01926600 2
1892
+ sigir-20151 NCT01956955 0
1893
+ sigir-20151 NCT01993381 0
1894
+ sigir-20151 NCT02017379 2
1895
+ sigir-20151 NCT02049619 0
1896
+ sigir-20151 NCT02088385 2
1897
+ sigir-20151 NCT02105532 1
1898
+ sigir-20151 NCT02150941 2
1899
+ sigir-20151 NCT02166008 0
1900
+ sigir-20151 NCT02197039 1
1901
+ sigir-20151 NCT02241044 2
1902
+ sigir-20151 NCT02245802 2
1903
+ sigir-20151 NCT02316990 0
1904
+ sigir-20151 NCT02342470 0
1905
+ sigir-20151 NCT02352155 2
1906
+ sigir-20151 NCT02358850 0
1907
+ sigir-20151 NCT02417519 0
1908
+ sigir-20151 NCT02446678 0
1909
+ sigir-20151 NCT02456012 1
1910
+ sigir-20151 NCT02461329 1
1911
+ sigir-20151 NCT02477501 0
1912
+ sigir-20151 NCT02535624 0
1913
+ sigir-20152 NCT00000665 0
1914
+ sigir-20152 NCT00000673 0
1915
+ sigir-20152 NCT00000726 0
1916
+ sigir-20152 NCT00000970 0
1917
+ sigir-20152 NCT00000981 0
1918
+ sigir-20152 NCT00001471 1
1919
+ sigir-20152 NCT00001890 0
1920
+ sigir-20152 NCT00002025 0
1921
+ sigir-20152 NCT00002275 0
1922
+ sigir-20152 NCT00005547 0
1923
+ sigir-20152 NCT00005572 2
1924
+ sigir-20152 NCT00034437 1
1925
+ sigir-20152 NCT00077909 2
1926
+ sigir-20152 NCT00159055 1
1927
+ sigir-20152 NCT00225394 1
1928
+ sigir-20152 NCT00241345 0
1929
+ sigir-20152 NCT00411645 0
1930
+ sigir-20152 NCT00442975 1
1931
+ sigir-20152 NCT00471250 2
1932
+ sigir-20152 NCT00495963 0
1933
+ sigir-20152 NCT00497796 0
1934
+ sigir-20152 NCT00547235 0
1935
+ sigir-20152 NCT00662012 0
1936
+ sigir-20152 NCT00674648 0
1937
+ sigir-20152 NCT00699868 1
1938
+ sigir-20152 NCT00766415 0
1939
+ sigir-20152 NCT00817908 2
1940
+ sigir-20152 NCT00838552 0
1941
+ sigir-20152 NCT00907686 0
1942
+ sigir-20152 NCT00954200 0
1943
+ sigir-20152 NCT01088243 0
1944
+ sigir-20152 NCT01128907 0
1945
+ sigir-20152 NCT01220895 0
1946
+ sigir-20152 NCT01251744 0
1947
+ sigir-20152 NCT01259141 0
1948
+ sigir-20152 NCT01292213 0
1949
+ sigir-20152 NCT01301131 0
1950
+ sigir-20152 NCT01376778 0
1951
+ sigir-20152 NCT01395498 2
1952
+ sigir-20152 NCT01587807 0
1953
+ sigir-20152 NCT01646645 1
1954
+ sigir-20152 NCT01810731 0
1955
+ sigir-20152 NCT01818726 0
1956
+ sigir-20152 NCT01833416 0
1957
+ sigir-20152 NCT01862159 0
1958
+ sigir-20152 NCT01903928 0
1959
+ sigir-20152 NCT01945619 0
1960
+ sigir-20152 NCT02025335 1
1961
+ sigir-20152 NCT02081716 1
1962
+ sigir-20152 NCT02083042 0
1963
+ sigir-20152 NCT02136797 1
1964
+ sigir-20152 NCT02152358 0
1965
+ sigir-20152 NCT02154880 0
1966
+ sigir-20152 NCT02156479 0
1967
+ sigir-20152 NCT02328963 0
1968
+ sigir-20152 NCT02370758 0
1969
+ sigir-20152 NCT02406729 0
1970
+ sigir-20152 NCT02474901 0
1971
+ sigir-20152 NCT02496494 0
1972
+ sigir-20152 NCT02509091 0
1973
+ sigir-20152 NCT02527291 0
1974
+ sigir-20152 NCT02532452 1
1975
+ sigir-20152 NCT02622009 0
1976
+ sigir-20152 NCT02630537 0
1977
+ sigir-20153 NCT00035971 0
1978
+ sigir-20153 NCT00043927 0
1979
+ sigir-20153 NCT00045760 0
1980
+ sigir-20153 NCT00154895 0
1981
+ sigir-20153 NCT00182143 1
1982
+ sigir-20153 NCT00182364 0
1983
+ sigir-20153 NCT00187408 0
1984
+ sigir-20153 NCT00188032 2
1985
+ sigir-20153 NCT00219921 0
1986
+ sigir-20153 NCT00225108 0
1987
+ sigir-20153 NCT00264901 0
1988
+ sigir-20153 NCT00302601 0
1989
+ sigir-20153 NCT00311753 0
1990
+ sigir-20153 NCT00314548 0
1991
+ sigir-20153 NCT00358735 0
1992
+ sigir-20153 NCT00361959 1
1993
+ sigir-20153 NCT00378027 1
1994
+ sigir-20153 NCT00413374 1
1995
+ sigir-20153 NCT00413504 0
1996
+ sigir-20153 NCT00421538 0
1997
+ sigir-20153 NCT00425542 1
1998
+ sigir-20153 NCT00451412 0
1999
+ sigir-20153 NCT00462241 0
2000
+ sigir-20153 NCT00539487 0
2001
+ sigir-20153 NCT00643370 0
2002
+ sigir-20153 NCT00700739 1
2003
+ sigir-20153 NCT00707811 1
2004
+ sigir-20153 NCT00720915 2
2005
+ sigir-20153 NCT00740883 0
2006
+ sigir-20153 NCT00823563 0
2007
+ sigir-20153 NCT00873587 0
2008
+ sigir-20153 NCT00878475 0
2009
+ sigir-20153 NCT00954395 0
2010
+ sigir-20153 NCT00957021 0
2011
+ sigir-20153 NCT00967304 2
2012
+ sigir-20153 NCT01014156 0
2013
+ sigir-20153 NCT01084239 0
2014
+ sigir-20153 NCT01096927 0
2015
+ sigir-20153 NCT01097928 2
2016
+ sigir-20153 NCT01112436 0
2017
+ sigir-20153 NCT01117610 0
2018
+ sigir-20153 NCT01133002 2
2019
+ sigir-20153 NCT01139632 1
2020
+ sigir-20153 NCT01164046 0
2021
+ sigir-20153 NCT01169389 0
2022
+ sigir-20153 NCT01214954 1
2023
+ sigir-20153 NCT01230931 0
2024
+ sigir-20153 NCT01240044 0
2025
+ sigir-20153 NCT01242150 0
2026
+ sigir-20153 NCT01245283 1
2027
+ sigir-20153 NCT01274637 0
2028
+ sigir-20153 NCT01274871 0
2029
+ sigir-20153 NCT01285648 0
2030
+ sigir-20153 NCT01291979 0
2031
+ sigir-20153 NCT01298531 0
2032
+ sigir-20153 NCT01304108 0
2033
+ sigir-20153 NCT01308385 0
2034
+ sigir-20153 NCT01312077 0
2035
+ sigir-20153 NCT01312376 1
2036
+ sigir-20153 NCT01313676 0
2037
+ sigir-20153 NCT01319682 0
2038
+ sigir-20153 NCT01326507 2
2039
+ sigir-20153 NCT01355965 0
2040
+ sigir-20153 NCT01499784 0
2041
+ sigir-20153 NCT01531829 1
2042
+ sigir-20153 NCT01535248 0
2043
+ sigir-20153 NCT01546857 0
2044
+ sigir-20153 NCT01599403 0
2045
+ sigir-20153 NCT01604538 1
2046
+ sigir-20153 NCT01608360 0
2047
+ sigir-20153 NCT01608373 0
2048
+ sigir-20153 NCT01633671 0
2049
+ sigir-20153 NCT01635257 2
2050
+ sigir-20153 NCT01660594 0
2051
+ sigir-20153 NCT01721837 0
2052
+ sigir-20153 NCT01724996 0
2053
+ sigir-20153 NCT01743313 1
2054
+ sigir-20153 NCT01787773 2
2055
+ sigir-20153 NCT01803022 0
2056
+ sigir-20153 NCT01817257 0
2057
+ sigir-20153 NCT01849614 0
2058
+ sigir-20153 NCT01871194 0
2059
+ sigir-20153 NCT01898637 1
2060
+ sigir-20153 NCT01935141 2
2061
+ sigir-20153 NCT01959529 0
2062
+ sigir-20153 NCT01992224 0
2063
+ sigir-20153 NCT02008370 0
2064
+ sigir-20153 NCT02015858 1
2065
+ sigir-20153 NCT02134652 0
2066
+ sigir-20153 NCT02204514 0
2067
+ sigir-20153 NCT02230865 0
2068
+ sigir-20153 NCT02235558 0
2069
+ sigir-20153 NCT02248610 2
2070
+ sigir-20153 NCT02258958 0
2071
+ sigir-20153 NCT02271399 0
2072
+ sigir-20153 NCT02289937 0
2073
+ sigir-20153 NCT02334007 0
2074
+ sigir-20153 NCT02355548 1
2075
+ sigir-20153 NCT02356120 2
2076
+ sigir-20153 NCT02375919 2
2077
+ sigir-20153 NCT02386696 0
2078
+ sigir-20153 NCT02402881 1
2079
+ sigir-20153 NCT02408263 0
2080
+ sigir-20153 NCT02427516 1
2081
+ sigir-20153 NCT02437942 0
2082
+ sigir-20153 NCT02440529 0
2083
+ sigir-20153 NCT02446587 0
2084
+ sigir-20153 NCT02458729 1
2085
+ sigir-20153 NCT02476721 0
2086
+ sigir-20153 NCT02507180 0
2087
+ sigir-20153 NCT02531542 1
2088
+ sigir-20153 NCT02532075 0
2089
+ sigir-20153 NCT02546817 2
2090
+ sigir-20153 NCT02553733 0
2091
+ sigir-20153 NCT02558465 2
2092
+ sigir-20153 NCT02596555 2
2093
+ sigir-20153 NCT02601846 1
2094
+ sigir-20153 NCT02604550 0
2095
+ pfizer-covidbooster-001 NCT05930730 2
2096
+ pfizer-covidbooster-001 NCT05197621 1
2097
+ pfizer-covidbooster-001 NCT05170399 1
2098
+ pfizer-covidbooster-002 NCT05930730 2
2099
+ pfizer-covidbooster-002 NCT05197621 1
2100
+ pfizer-covidbooster-003 NCT05930730 2
2101
+ elranatamab-pta-001 NCT06057402 2
2102
+ elranatamab-pta-002 NCT06057402 2
2103
+ covid-maternal-001 NCT05197621 2
2104
+ covid-maternal-002 NCT05197621 2
2105
+ covid-maternal-003 NCT05197621 2
2106
+ hemophilia-gene-001 NCT05568719 2
2107
+ hemophilia-gene-002 NCT05568719 2
2108
+ hemophilia-gene-003 NCT05568719 2
2109
+ mevpro1-mcrpc-001 NCT06551324 2
2110
+ mevpro1-mcrpc-002 NCT06551324 2
2111
+ mevpro1-mcrpc-003 NCT06551324 2
2112
+ bcell-vax-001 NCT05170399 2
2113
+ bcell-vax-002 NCT05170399 2
2114
+ bcell-vax-003 NCT05170399 2
2115
+ txa-orbit-001 NCT00736086 1
2116
+ txa-orbit-002 NCT00736086 1
2117
+ ama-001 NCT00001951 1
2118
+ ama-002 NCT00001951 1
2119
+ ama-003 NCT00001951 1
2120
+ mythic-3001 NCT01577771 1
2121
+ mythic-3002 NCT01577771 1
2122
+ mpa-lngius-0001 NCT00001951 1
2123
+ mpa-lngius-0002 NCT00001951 1
2124
+ mpa-lngius-0003 NCT00001951 1
2125
+ mpa-lngius-0004 NCT00001951 1
2126
+ axspa-001 NCT02592434 1
2127
+ axspa-002 NCT02592434 1
2128
+ axspa-003 NCT02592434 1
2129
+ ama-001 NCT04669717 2
2130
+ ama-002 NCT04669717 2
2131
+ ama-003 NCT04669717 2
2132
+ mythic-3001 NCT06325293 2
2133
+ mythic-3002 NCT06325293 2
2134
+ mythic-3001 NCT01280461 1
2135
+ mythic-3002 NCT01280461 1
2136
+ mpa-lngius-0001 NCT05565573 2
2137
+ mpa-lngius-0002 NCT05565573 2
2138
+ mpa-lngius-0003 NCT05565573 2
2139
+ mpa-lngius-0004 NCT05565573 2
2140
+ txa-orbit-001 NCT00313365 1
2141
+ txa-orbit-002 NCT00313365 1
2142
+ axspa-001 NCT00672490 1
2143
+ axspa-002 NCT00672490 1
2144
+ axspa-003 NCT00672490 1
dataset/sigir/queries.jsonl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:9feeb8a450d544b5e121ac9c591c9ee48da3ef90542ec0be97a72304d07efe82
3
+ size 46261
dataset/sigir/retrieved_trials.json ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:529823a52827e0623fb2eb6b450ec2cdfc56cf890b6b095ce75a0291f2d78595
3
+ size 284678
dataset/sigir/s.json ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a422252f465ddc173d111231b6427051503f478d98c327a6b6d53c5a5320c251
3
+ size 281830
dataset/sigir/wrap_gpt35turbo.py ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+
3
+ # Load the original file
4
+ with open('/l/users/salma.hassan/TrialGPT_scratch/dataset/sigir/id2queries.json', 'r') as f:
5
+ data = json.load(f)
6
+
7
+ # Wrap each entry with 'gpt-35-turbo'
8
+ wrapped = {}
9
+ for k, v in data.items():
10
+ wrapped[k] = {"gpt-35-turbo": v}
11
+
12
+ # Write to a new file (to avoid overwriting the original)
13
+ with open('/l/users/salma.hassan/TrialGPT_scratch/dataset/sigir/id2queries_gpt35turbo.json', 'w') as f:
14
+ json.dump(wrapped, f, indent=2)
15
+
16
+ print('Done. Output written to id2queries_gpt35turbo.json')
dataset/trial_info.json ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:1ce098c5b511353533bc409a5b66ea2cf0263e6564d0c6431b3034e441f7e2e1
3
+ size 68526681
requirements.txt ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ beir==2.0.0
2
+ faiss==1.8.0
3
+ faiss_cpu==1.8.0
4
+ nltk==3.8.1
5
+ numpy==1.26.4
6
+ openai==1.30.5
7
+ pandas==2.2.2
8
+ rank_bm25==0.2.2
9
+ scikit_learn==1.2.2
10
+ sentence_transformers==2.6.1
11
+ torch==2.2.2
12
+ tqdm==4.65.0
13
+ transformers==4.39.3
trialgpt_matching/TrialGPT.py ADDED
@@ -0,0 +1,118 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ __author__ = "qiao"
2
+
3
+ """
4
+ TrialGPT-Matching main functions.
5
+ """
6
+
7
+ import json
8
+ from nltk.tokenize import sent_tokenize
9
+ import time
10
+ import os
11
+
12
+ from openai import AzureOpenAI
13
+
14
+ client = AzureOpenAI(
15
+ api_version="2023-09-01-preview",
16
+ azure_endpoint=os.getenv("OPENAI_ENDPOINT"),
17
+ api_key=os.getenv("OPENAI_API_KEY"),
18
+ )
19
+
20
+ def parse_criteria(criteria):
21
+ output = ""
22
+ criteria = criteria.split("\n\n")
23
+
24
+ idx = 0
25
+ for criterion in criteria:
26
+ criterion = criterion.strip()
27
+
28
+ if "inclusion criteria" in criterion.lower() or "exclusion criteria" in criterion.lower():
29
+ continue
30
+
31
+ if len(criterion) < 5:
32
+ continue
33
+
34
+ output += f"{idx}. {criterion}\n"
35
+ idx += 1
36
+
37
+ return output
38
+
39
+
40
+ def print_trial(
41
+ trial_info: dict,
42
+ inc_exc: str,
43
+ ) -> str:
44
+ """Given a dict of trial information, returns a string of trial."""
45
+
46
+ trial = f"Title: {trial_info['brief_title']}\n"
47
+ trial += f"Target diseases: {', '.join(trial_info['diseases_list'])}\n"
48
+ trial += f"Interventions: {', '.join(trial_info['drugs_list'])}\n"
49
+ trial += f"Summary: {trial_info['brief_summary']}\n"
50
+
51
+ if inc_exc == "inclusion":
52
+ trial += "Inclusion criteria:\n %s\n" % parse_criteria(trial_info['inclusion_criteria'])
53
+ elif inc_exc == "exclusion":
54
+ trial += "Exclusion criteria:\n %s\n" % parse_criteria(trial_info['exclusion_criteria'])
55
+
56
+ return trial
57
+
58
+
59
+ def get_matching_prompt(
60
+ trial_info: dict,
61
+ inc_exc: str,
62
+ patient: str,
63
+ ) -> str:
64
+ """Output the prompt."""
65
+ prompt = f"You are a helpful assistant for clinical trial recruitment. Your task is to compare a given patient note and the {inc_exc} criteria of a clinical trial to determine the patient's eligibility at the criterion level.\n"
66
+
67
+ if inc_exc == "inclusion":
68
+ prompt += "The factors that allow someone to participate in a clinical study are called inclusion criteria. They are based on characteristics such as age, gender, the type and stage of a disease, previous treatment history, and other medical conditions.\n"
69
+
70
+ elif inc_exc == "exclusion":
71
+ prompt += "The factors that disqualify someone from participating are called exclusion criteria. They are based on characteristics such as age, gender, the type and stage of a disease, previous treatment history, and other medical conditions.\n"
72
+
73
+ prompt += f"You should check the {inc_exc} criteria one-by-one, and output the following three elements for each criterion:\n"
74
+ prompt += f"\tElement 1. For each {inc_exc} criterion, briefly generate your reasoning process: First, judge whether the criterion is not applicable (not very common), where the patient does not meet the premise of the criterion. Then, check if the patient note contains direct evidence. If so, judge whether the patient meets or does not meet the criterion. If there is no direct evidence, try to infer from existing evidence, and answer one question: If the criterion is true, is it possible that a good patient note will miss such information? If impossible, then you can assume that the criterion is not true. Otherwise, there is not enough information.\n"
75
+ prompt += f"\tElement 2. If there is relevant information, you must generate a list of relevant sentence IDs in the patient note. If there is no relevant information, you must annotate an empty list.\n"
76
+ prompt += f"\tElement 3. Classify the patient eligibility for this specific {inc_exc} criterion: "
77
+
78
+ if inc_exc == "inclusion":
79
+ prompt += 'the label must be chosen from {"not applicable", "not enough information", "included", "not included"}. "not applicable" should only be used for criteria that are not applicable to the patient. "not enough information" should be used where the patient note does not contain sufficient information for making the classification. Try to use as less "not enough information" as possible because if the note does not mention a medically important fact, you can assume that the fact is not true for the patient. "included" denotes that the patient meets the inclusion criterion, while "not included" means the reverse.\n'
80
+ elif inc_exc == "exclusion":
81
+ prompt += 'the label must be chosen from {"not applicable", "not enough information", "excluded", "not excluded"}. "not applicable" should only be used for criteria that are not applicable to the patient. "not enough information" should be used where the patient note does not contain sufficient information for making the classification. Try to use as less "not enough information" as possible because if the note does not mention a medically important fact, you can assume that the fact is not true for the patient. "excluded" denotes that the patient meets the exclusion criterion and should be excluded in the trial, while "not excluded" means the reverse.\n'
82
+
83
+ prompt += "You should output only a JSON dict exactly formatted as: dict{str(criterion_number): list[str(element_1_brief_reasoning), list[int(element_2_sentence_id)], str(element_3_eligibility_label)]}."
84
+
85
+ user_prompt = f"Here is the patient note, each sentence is led by a sentence_id:\n{patient}\n\n"
86
+ user_prompt += f"Here is the clinical trial:\n{print_trial(trial_info, inc_exc)}\n\n"
87
+ user_prompt += f"Plain JSON output:"
88
+
89
+ return prompt, user_prompt
90
+
91
+
92
+ def trialgpt_matching(trial: dict, patient: str, model: str):
93
+ results = {}
94
+
95
+ # doing inclusions and exclusions in separate prompts
96
+ for inc_exc in ["inclusion", "exclusion"]:
97
+ system_prompt, user_prompt = get_matching_prompt(trial, inc_exc, patient)
98
+
99
+ messages = [
100
+ {"role": "system", "content": system_prompt},
101
+ {"role": "user", "content": user_prompt},
102
+ ]
103
+
104
+ response = client.chat.completions.create(
105
+ model=model,
106
+ messages=messages,
107
+ temperature=0,
108
+ )
109
+
110
+ message = response.choices[0].message.content.strip()
111
+ message = message.strip("`").strip("json")
112
+
113
+ try:
114
+ results[inc_exc] = json.loads(message)
115
+ except:
116
+ results[inc_exc] = message
117
+
118
+ return results
trialgpt_matching/__pycache__/TrialGPT.cpython-39.pyc ADDED
Binary file (5.76 kB). View file
 
trialgpt_matching/run_matching.py ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ __author__ = "qiao"
2
+
3
+ """
4
+ Running the TrialGPT matching for three cohorts (sigir, TREC 2021, TREC 2022).
5
+ """
6
+
7
+ import json
8
+ from nltk.tokenize import sent_tokenize
9
+ import os
10
+ import sys
11
+ from tqdm import tqdm
12
+ from TrialGPT import trialgpt_matching
13
+
14
+ if __name__ == "__main__":
15
+ corpus = sys.argv[1]
16
+ model = sys.argv[2]
17
+
18
+ dataset = json.load(open(f"dataset/{corpus}/retrieved_trials.json"))
19
+
20
+ output_path = f"results/matching_results_{corpus}_{model}.json"
21
+
22
+ # Dict{Str(patient_id): Dict{Str(label): Dict{Str(trial_id): Str(output)}}}
23
+ if os.path.exists(output_path):
24
+ output = json.load(open(output_path))
25
+ else:
26
+ output = {}
27
+
28
+ for instance in tqdm(dataset):
29
+ # Dict{'patient': Str(patient), '0': Str(NCTID), ...}
30
+ patient_id = instance["patient_id"]
31
+ patient = instance["patient"]
32
+ sents = sent_tokenize(patient)
33
+ sents.append("The patient will provide informed consent, and will comply with the trial protocol without any practical issues.")
34
+ sents = [f"{idx}. {sent}" for idx, sent in enumerate(sents)]
35
+ patient = "\n".join(sents)
36
+
37
+ # initialize the patient id in the output
38
+ if patient_id not in output:
39
+ output[patient_id] = {"0": {}, "1": {}, "2": {}}
40
+
41
+ for label in ["2", "1", "0"]:
42
+ if label not in instance: continue
43
+
44
+ for trial in instance[label]:
45
+ trial_id = trial["NCTID"]
46
+
47
+ # already calculated and cached
48
+ if trial_id in output[patient_id][label]:
49
+ continue
50
+
51
+ # in case anything goes wrong (e.g., API calling errors)
52
+ try:
53
+ results = trialgpt_matching(trial, patient, model)
54
+ output[patient_id][label][trial_id] = results
55
+
56
+ with open(output_path, "w") as f:
57
+ json.dump(output, f, indent=4)
58
+
59
+ except Exception as e:
60
+ print(e)
61
+ continue
trialgpt_ranking/TrialGPT.py ADDED
@@ -0,0 +1,120 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ __author__ = "qiao"
2
+
3
+ """
4
+ TrialGPT-Ranking main functions.
5
+ """
6
+
7
+ import json
8
+ from nltk.tokenize import sent_tokenize
9
+ import time
10
+ import os
11
+
12
+ from openai import AzureOpenAI
13
+
14
+ client = AzureOpenAI(
15
+ api_version="2023-09-01-preview",
16
+ azure_endpoint=os.getenv("OPENAI_ENDPOINT"),
17
+ api_key=os.getenv("OPENAI_API_KEY"),
18
+ )
19
+
20
+ def convert_criteria_pred_to_string(
21
+ prediction: dict,
22
+ trial_info: dict,
23
+ ) -> str:
24
+ """Given the TrialGPT prediction, output the linear string of the criteria."""
25
+ output = ""
26
+
27
+ for inc_exc in ["inclusion", "exclusion"]:
28
+
29
+ # first get the idx2criterion dict
30
+ idx2criterion = {}
31
+ criteria = trial_info[inc_exc + "_criteria"].split("\n\n")
32
+
33
+ idx = 0
34
+ for criterion in criteria:
35
+ criterion = criterion.strip()
36
+
37
+ if "inclusion criteria" in criterion.lower() or "exclusion criteria" in criterion.lower():
38
+ continue
39
+
40
+ if len(criterion) < 5:
41
+ continue
42
+
43
+ idx2criterion[str(idx)] = criterion
44
+ idx += 1
45
+
46
+ for idx, info in enumerate(prediction[inc_exc].items()):
47
+ criterion_idx, preds = info
48
+
49
+ if criterion_idx not in idx2criterion:
50
+ continue
51
+
52
+ criterion = idx2criterion[criterion_idx]
53
+
54
+ if len(preds) != 3:
55
+ continue
56
+
57
+ output += f"{inc_exc} criterion {idx}: {criterion}\n"
58
+ output += f"\tPatient relevance: {preds[0]}\n"
59
+ if len(preds[1]) > 0:
60
+ output += f"\tEvident sentences: {preds[1]}\n"
61
+ output += f"\tPatient eligibility: {preds[2]}\n"
62
+
63
+ return output
64
+
65
+
66
+ def convert_pred_to_prompt(
67
+ patient: str,
68
+ pred: dict,
69
+ trial_info: dict,
70
+ ) -> str:
71
+ """Convert the prediction to a prompt string."""
72
+ # get the trial string
73
+ trial = f"Title: {trial_info['brief_title']}\n"
74
+ trial += f"Target conditions: {', '.join(trial_info['diseases_list'])}\n"
75
+ trial += f"Summary: {trial_info['brief_summary']}"
76
+
77
+ # then get the prediction strings
78
+ pred = convert_criteria_pred_to_string(pred, trial_info)
79
+
80
+ # construct the prompt
81
+ prompt = "You are a helpful assistant for clinical trial recruitment. You will be given a patient note, a clinical trial, and the patient eligibility predictions for each criterion.\n"
82
+ prompt += "Your task is to output two scores, a relevance score (R) and an eligibility score (E), between the patient and the clinical trial.\n"
83
+ prompt += "First explain the consideration for determining patient-trial relevance. Predict the relevance score R (0~100), which represents the overall relevance between the patient and the clinical trial. R=0 denotes the patient is totally irrelevant to the clinical trial, and R=100 denotes the patient is exactly relevant to the clinical trial.\n"
84
+ prompt += "Then explain the consideration for determining patient-trial eligibility. Predict the eligibility score E (-R~R), which represents the patient's eligibility to the clinical trial. Note that -R <= E <= R (the absolute value of eligibility cannot be higher than the relevance), where E=-R denotes that the patient is ineligible (not included by any inclusion criteria, or excluded by all exclusion criteria), E=R denotes that the patient is eligible (included by all inclusion criteria, and not excluded by any exclusion criteria), E=0 denotes the patient is neutral (i.e., no relevant information for all inclusion and exclusion criteria).\n"
85
+ prompt += 'Please output a JSON dict formatted as Dict{"relevance_explanation": Str, "relevance_score_R": Float, "eligibility_explanation": Str, "eligibility_score_E": Float}.'
86
+
87
+
88
+ user_prompt = "Here is the patient note:\n"
89
+ user_prompt += patient + "\n\n"
90
+ user_prompt += "Here is the clinical trial description:\n"
91
+ user_prompt += trial + "\n\n"
92
+ user_prompt += "Here are the criterion-level eligibility prediction:\n"
93
+ user_prompt += pred + "\n\n"
94
+ user_prompt += "Plain JSON output:"
95
+
96
+ return prompt, user_prompt
97
+
98
+
99
+ def trialgpt_aggregation(patient: str, trial_results: dict, trial_info: dict, model: str):
100
+ system_prompt, user_prompt = convert_pred_to_prompt(
101
+ patient,
102
+ trial_results,
103
+ trial_info
104
+ )
105
+
106
+ messages = [
107
+ {"role": "system", "content": system_prompt},
108
+ {"role": "user", "content": user_prompt}
109
+ ]
110
+
111
+ response = client.chat.completions.create(
112
+ model=model,
113
+ messages=messages,
114
+ temperature=0,
115
+ )
116
+ result = response.choices[0].message.content.strip()
117
+ result = result.strip("`").strip("json")
118
+ result = json.loads(result)
119
+
120
+ return result
trialgpt_ranking/__pycache__/TrialGPT.cpython-39.pyc ADDED
Binary file (4.06 kB). View file
 
trialgpt_ranking/rank_results.py ADDED
@@ -0,0 +1,120 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ __author__ = "qiao"
2
+
3
+ """
4
+ Rank the trials given the matching and aggregation results
5
+ """
6
+
7
+ import json
8
+ import sys
9
+
10
+ eps = 1e-9
11
+
12
+ def get_matching_score(matching):
13
+ # count only the valid ones
14
+ included = 0
15
+ not_inc = 0
16
+ na_inc = 0
17
+ no_info_inc = 0
18
+
19
+ excluded = 0
20
+ not_exc = 0
21
+ na_exc = 0
22
+ no_info_exc = 0
23
+
24
+ # first count inclusions
25
+ for criteria, info in matching["inclusion"].items():
26
+
27
+ if len(info) != 3:
28
+ continue
29
+
30
+ if info[2] == "included":
31
+ included += 1
32
+ elif info[2] == "not included":
33
+ not_inc += 1
34
+ elif info[2] == "not applicable":
35
+ na_inc += 1
36
+ elif info[2] == "not enough information":
37
+ no_info_inc += 1
38
+
39
+ # then count exclusions
40
+ for criteria, info in matching["exclusion"].items():
41
+
42
+ if len(info) != 3:
43
+ continue
44
+
45
+ if info[2] == "excluded":
46
+ excluded += 1
47
+ elif info[2] == "not excluded":
48
+ not_exc += 1
49
+ elif info[2] == "not applicable":
50
+ na_exc += 1
51
+ elif info[2] == "not enough information":
52
+ no_info_exc += 1
53
+
54
+ # get the matching score
55
+ score = 0
56
+
57
+ score += included / (included + not_inc + no_info_inc + eps)
58
+
59
+ if not_inc > 0:
60
+ score -= 1
61
+
62
+ if excluded > 0:
63
+ score -= 1
64
+
65
+ return score
66
+
67
+
68
+ def get_agg_score(assessment):
69
+ try:
70
+ rel_score = float(assessment["relevance_score_R"])
71
+ eli_score = float(assessment["eligibility_score_E"])
72
+ except:
73
+ rel_score = 0
74
+ eli_score = 0
75
+
76
+ score = (rel_score + eli_score) / 100
77
+
78
+ return score
79
+
80
+
81
+ if __name__ == "__main__":
82
+ # args are the results paths
83
+ matching_results_path = sys.argv[1]
84
+ agg_results_path = sys.argv[2]
85
+
86
+ # loading the results
87
+ matching_results = json.load(open(matching_results_path))
88
+ agg_results = json.load(open(agg_results_path))
89
+
90
+ # loop over the patients
91
+ for patient_id, label2trial2results in matching_results.items():
92
+
93
+ trial2score = {}
94
+
95
+ for _, trial2results in label2trial2results.items():
96
+ for trial_id, results in trial2results.items():
97
+
98
+ matching_score = get_matching_score(results)
99
+
100
+ if patient_id not in agg_results or trial_id not in agg_results[patient_id]:
101
+ print(f"Patient {patient_id} Trial {trial_id} not in the aggregation results.")
102
+ agg_score = 0
103
+ else:
104
+ agg_score = get_agg_score(agg_results[patient_id][trial_id])
105
+
106
+ trial_score = matching_score + agg_score
107
+
108
+ trial2score[trial_id] = trial_score
109
+
110
+ sorted_trial2score = sorted(trial2score.items(), key=lambda x: -x[1])
111
+
112
+ print()
113
+ print(f"Patient ID: {patient_id}")
114
+ print("Clinical trial ranking:")
115
+
116
+ for trial, score in sorted_trial2score:
117
+ print(trial, score)
118
+
119
+ print("===")
120
+ print()
trialgpt_ranking/run_aggregation.py ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ __author__ = "qiao"
2
+
3
+ """
4
+ Using GPT to aggregate the scores by itself.
5
+ """
6
+
7
+ from beir.datasets.data_loader import GenericDataLoader
8
+ import json
9
+ from nltk.tokenize import sent_tokenize
10
+ import os
11
+ import sys
12
+ import time
13
+
14
+ from TrialGPT import trialgpt_aggregation
15
+
16
+ if __name__ == "__main__":
17
+ corpus = sys.argv[1]
18
+ model = sys.argv[2]
19
+
20
+ # the path of the matching results
21
+ matching_results_path = sys.argv[3]
22
+ results = json.load(open(matching_results_path))
23
+
24
+ # loading the trial2info dict
25
+ trial2info = json.load(open("dataset/trial_info.json"))
26
+
27
+ # loading the patient info
28
+ _, queries, _ = GenericDataLoader(data_folder=f"dataset/{corpus}/").load(split="test")
29
+
30
+ # output file path
31
+ output_path = f"results/aggregation_results_{corpus}_{model}.json"
32
+
33
+ if os.path.exists(output_path):
34
+ output = json.load(open(output_path))
35
+ else:
36
+ output = {}
37
+
38
+ # patient-level
39
+ for patient_id, info in results.items():
40
+ # get the patient note
41
+ patient = queries[patient_id]
42
+ sents = sent_tokenize(patient)
43
+ sents.append("The patient will provide informed consent, and will comply with the trial protocol without any practical issues.")
44
+ sents = [f"{idx}. {sent}" for idx, sent in enumerate(sents)]
45
+ patient = "\n".join(sents)
46
+
47
+ if patient_id not in output:
48
+ output[patient_id] = {}
49
+
50
+ # label-level, 3 label / patient
51
+ for label, trials in info.items():
52
+
53
+ # trial-level
54
+ for trial_id, trial_results in trials.items():
55
+ # already cached results
56
+ if trial_id in output[patient_id]:
57
+ continue
58
+
59
+ if type(trial_results) is not dict:
60
+ output[patient_id][trial_id] = "matching result error"
61
+
62
+ with open(output_path, "w") as f:
63
+ json.dump(output, f, indent=4)
64
+
65
+ continue
66
+
67
+ # specific trial information
68
+ trial_info = trial2info[trial_id]
69
+
70
+ try:
71
+ result = trialgpt_aggregation(patient, trial_results, trial_info, model)
72
+ output[patient_id][trial_id] = result
73
+
74
+ with open(output_path, "w") as f:
75
+ json.dump(output, f, indent=4)
76
+
77
+ except:
78
+ continue
trialgpt_retrieval/__pycache__/retriever.cpython-39.pyc ADDED
Binary file (6.25 kB). View file
 
trialgpt_retrieval/bm25_corpus_sigir.json ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e801cf14babb39ac15836939d6826a4ad077847dcb8a4cf2218e549f8061d253
3
+ size 28346027
trialgpt_retrieval/hybrid_fusion_retrieval.py ADDED
@@ -0,0 +1,230 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ __author__ = "qiao"
2
+
3
+ """
4
+ Conduct the first stage retrieval by the hybrid retriever
5
+ """
6
+
7
+ from beir.datasets.data_loader import GenericDataLoader
8
+ import faiss
9
+ import json
10
+ from nltk import word_tokenize
11
+ import numpy as np
12
+ import os
13
+ from rank_bm25 import BM25Okapi
14
+ import sys
15
+ import tqdm
16
+ import torch
17
+ from transformers import AutoTokenizer, AutoModel
18
+ from beir import util, LoggingHandler
19
+
20
+ # Device detection - use CUDA if available, otherwise CPU
21
+ device = "cuda" if torch.cuda.is_available() else "cpu"
22
+ print(f"Using device: {device}")
23
+
24
+ def get_bm25_corpus_index(corpus):
25
+ corpus_path = os.path.join(f"trialgpt_retrieval/bm25_corpus_{corpus}.json")
26
+
27
+ # if already cached then load, otherwise build
28
+ if os.path.exists(corpus_path):
29
+ corpus_data = json.load(open(corpus_path))
30
+ tokenized_corpus = corpus_data["tokenized_corpus"]
31
+ corpus_nctids = corpus_data["corpus_nctids"]
32
+
33
+ else:
34
+ tokenized_corpus = []
35
+ corpus_nctids = []
36
+
37
+ with open(f"dataset/{corpus}/corpus.jsonl", "r") as f:
38
+ for line in f.readlines():
39
+ entry = json.loads(line)
40
+ corpus_nctids.append(entry["_id"])
41
+
42
+ # weighting: 3 * title, 2 * condition, 1 * text
43
+ tokens = word_tokenize(entry["title"].lower()) * 3
44
+ for disease in entry["metadata"]["diseases_list"]:
45
+ tokens += word_tokenize(disease.lower()) * 2
46
+ tokens += word_tokenize(entry["text"].lower())
47
+
48
+ tokenized_corpus.append(tokens)
49
+
50
+ corpus_data = {
51
+ "tokenized_corpus": tokenized_corpus,
52
+ "corpus_nctids": corpus_nctids,
53
+ }
54
+
55
+ with open(corpus_path, "w") as f:
56
+ json.dump(corpus_data, f, indent=4)
57
+
58
+ bm25 = BM25Okapi(tokenized_corpus)
59
+
60
+ return bm25, corpus_nctids
61
+
62
+
63
+ def get_medcpt_corpus_index(corpus):
64
+ corpus_path = f"trialgpt_retrieval/{corpus}_embeds.npy"
65
+ nctids_path = f"trialgpt_retrieval/{corpus}_nctids.json"
66
+
67
+ # if already cached then load, otherwise build
68
+ if os.path.exists(corpus_path):
69
+ embeds = np.load(corpus_path)
70
+ corpus_nctids = json.load(open(nctids_path))
71
+
72
+ else:
73
+ embeds = []
74
+ corpus_nctids = []
75
+
76
+ model = AutoModel.from_pretrained("ncbi/MedCPT-Article-Encoder").to(device)
77
+ tokenizer = AutoTokenizer.from_pretrained("ncbi/MedCPT-Article-Encoder")
78
+
79
+ with open(f"dataset/{corpus}/corpus.jsonl", "r") as f:
80
+ print("Encoding the corpus")
81
+ for line in tqdm.tqdm(f.readlines()):
82
+ entry = json.loads(line)
83
+ corpus_nctids.append(entry["_id"])
84
+
85
+ title = entry["title"]
86
+ text = entry["text"]
87
+
88
+ with torch.no_grad():
89
+ # tokenize the articles
90
+ encoded = tokenizer(
91
+ [[title, text]],
92
+ truncation=True,
93
+ padding=True,
94
+ return_tensors='pt',
95
+ max_length=512,
96
+ ).to(device)
97
+
98
+ embed = model(**encoded).last_hidden_state[:, 0, :]
99
+
100
+ embeds.append(embed[0].cpu().numpy())
101
+
102
+ embeds = np.array(embeds)
103
+
104
+ np.save(corpus_path, embeds)
105
+ with open(nctids_path, "w") as f:
106
+ json.dump(corpus_nctids, f, indent=4)
107
+
108
+ index = faiss.IndexFlatIP(768)
109
+ index.add(embeds)
110
+
111
+ return index, corpus_nctids
112
+
113
+
114
+ if __name__ == "__main__":
115
+ # different corpora, "trec_2021", "trec_2022", "sigir"
116
+ corpus = sys.argv[1]
117
+
118
+ # query type
119
+ q_type = sys.argv[2]
120
+
121
+ # different k for fusion
122
+ k = int(sys.argv[3])
123
+
124
+ # bm25 weight
125
+ bm25_wt = int(sys.argv[4])
126
+
127
+ # medcpt weight
128
+ medcpt_wt = int(sys.argv[5])
129
+
130
+ # how many to rank
131
+ N = 2000
132
+
133
+ # loading the qrels
134
+ _, _, qrels = GenericDataLoader(data_folder=f"dataset/{corpus}/").load(split="test")
135
+
136
+ # loading all types of queries
137
+ id2queries = json.load(open(f"dataset/{corpus}/id2queries.json"))
138
+
139
+ # loading the indices
140
+ bm25, bm25_nctids = get_bm25_corpus_index(corpus)
141
+ medcpt, medcpt_nctids = get_medcpt_corpus_index(corpus)
142
+
143
+ # loading the query encoder for MedCPT
144
+ model = AutoModel.from_pretrained("ncbi/MedCPT-Query-Encoder").to(device)
145
+ tokenizer = AutoTokenizer.from_pretrained("ncbi/MedCPT-Query-Encoder")
146
+
147
+ # then conduct the searches, saving top 1k
148
+ output_path = f"results/qid2nctids_results_{q_type}_{corpus}_k{k}_bm25wt{bm25_wt}_medcptwt{medcpt_wt}_N{N}.json"
149
+
150
+ qid2nctids = {}
151
+ recalls = []
152
+
153
+ with open(f"dataset/{corpus}/queries.jsonl", "r") as f:
154
+ for line in tqdm.tqdm(f.readlines()):
155
+ entry = json.loads(line)
156
+ query = entry["text"]
157
+ qid = entry["_id"]
158
+
159
+ if qid not in qrels:
160
+ continue
161
+
162
+ truth_sum = sum(qrels[qid].values())
163
+
164
+ # get the keyword list
165
+ if q_type in ["raw", "human_summary"]:
166
+ conditions = [id2queries[qid][q_type]]
167
+ elif "turbo" in q_type:
168
+ conditions = id2queries[qid][q_type]["conditions"]
169
+ elif "Clinician" in q_type:
170
+ conditions = id2queries[qid].get(q_type, [])
171
+
172
+ if len(conditions) == 0:
173
+ nctid2score = {}
174
+ else:
175
+ # a list of nctid lists for the bm25 retriever
176
+ bm25_condition_top_nctids = []
177
+
178
+ for condition in conditions:
179
+ tokens = word_tokenize(condition.lower())
180
+ top_nctids = bm25.get_top_n(tokens, bm25_nctids, n=N)
181
+ bm25_condition_top_nctids.append(top_nctids)
182
+
183
+ # doing MedCPT retrieval
184
+ with torch.no_grad():
185
+ encoded = tokenizer(
186
+ conditions,
187
+ truncation=True,
188
+ padding=True,
189
+ return_tensors='pt',
190
+ max_length=256,
191
+ ).to(device)
192
+
193
+ # encode the queries (use the [CLS] last hidden states as the representations)
194
+ embeds = model(**encoded).last_hidden_state[:, 0, :].cpu().numpy()
195
+
196
+ # search the Faiss index
197
+ scores, inds = medcpt.search(embeds, k=N)
198
+
199
+ medcpt_condition_top_nctids = []
200
+ for ind_list in inds:
201
+ top_nctids = [medcpt_nctids[ind] for ind in ind_list]
202
+ medcpt_condition_top_nctids.append(top_nctids)
203
+
204
+ nctid2score = {}
205
+
206
+ for condition_idx, (bm25_top_nctids, medcpt_top_nctids) in enumerate(zip(bm25_condition_top_nctids, medcpt_condition_top_nctids)):
207
+
208
+ if bm25_wt > 0:
209
+ for rank, nctid in enumerate(bm25_top_nctids):
210
+ if nctid not in nctid2score:
211
+ nctid2score[nctid] = 0
212
+
213
+ nctid2score[nctid] += (1 / (rank + k)) * (1 / (condition_idx + 1))
214
+
215
+ if medcpt_wt > 0:
216
+ for rank, nctid in enumerate(medcpt_top_nctids):
217
+ if nctid not in nctid2score:
218
+ nctid2score[nctid] = 0
219
+
220
+ nctid2score[nctid] += (1 / (rank + k)) * (1 / (condition_idx + 1))
221
+
222
+ nctid2score = sorted(nctid2score.items(), key=lambda x: -x[1])
223
+ top_nctids = [nctid for nctid, _ in nctid2score[:N]]
224
+ qid2nctids[qid] = top_nctids
225
+
226
+ actual_sum = sum([qrels[qid].get(nctid, 0) for nctid in top_nctids])
227
+ recalls.append(actual_sum / truth_sum)
228
+
229
+ with open(output_path, "w") as f:
230
+ json.dump(qid2nctids, f, indent=4)
trialgpt_retrieval/keyword_generation.py ADDED
@@ -0,0 +1,166 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ __author__ = "qiao"
2
+
3
+ """
4
+ generate the search keywords for each patient
5
+ """
6
+
7
+ import json
8
+ import os
9
+ import time
10
+ from openai import AzureOpenAI
11
+
12
+ import sys
13
+
14
+ client = AzureOpenAI(
15
+ api_version="2023-09-01-preview",
16
+ azure_endpoint=os.getenv("OPENAI_ENDPOINT"),
17
+ api_key=os.getenv("OPENAI_API_KEY"),
18
+ )
19
+
20
+
21
+ def get_keyword_generation_messages(note):
22
+ system = 'You are a helpful assistant and your task is to help search relevant clinical trials for a given patient description. Please first summarize the main medical problems of the patient. Then generate up to 32 key conditions for searching relevant clinical trials for this patient. The key condition list should be ranked by priority. Please output only a JSON dict formatted as Dict{{"summary": Str(summary), "conditions": List[Str(condition)]}}.'
23
+
24
+ prompt = f"Here is the patient description: \n{note}\n\nJSON output:"
25
+
26
+ messages = [
27
+ {"role": "system", "content": system},
28
+ {"role": "user", "content": prompt}
29
+ ]
30
+
31
+ return messages
32
+
33
+
34
+ def is_valid_json(json_str):
35
+ """Check if a string is valid JSON"""
36
+ try:
37
+ json.loads(json_str)
38
+ return True
39
+ except (json.JSONDecodeError, TypeError):
40
+ return False
41
+
42
+
43
+ def fix_truncated_json(json_str):
44
+ """Attempt to fix common JSON truncation issues"""
45
+ if not json_str or not isinstance(json_str, str):
46
+ return None
47
+
48
+ # Remove any trailing commas before closing brackets/braces
49
+ json_str = json_str.rstrip()
50
+
51
+ # If it ends with a comma, remove it
52
+ if json_str.endswith(','):
53
+ json_str = json_str[:-1]
54
+
55
+ # If it ends with an incomplete string, try to close it
56
+ if json_str.count('"') % 2 != 0:
57
+ # Find the last quote and see if we can close the string
58
+ last_quote_pos = json_str.rfind('"')
59
+ if last_quote_pos != -1:
60
+ # Check if this is an opening quote (no closing quote after it)
61
+ remaining = json_str[last_quote_pos+1:]
62
+ if '"' not in remaining:
63
+ # Try to close the string and the JSON
64
+ json_str += '"]}'
65
+
66
+ # If it ends with an incomplete array, try to close it
67
+ if json_str.endswith('['):
68
+ json_str += ']}'
69
+ elif json_str.endswith('["'):
70
+ json_str += ']}'
71
+
72
+ # If it ends with an incomplete object, try to close it
73
+ if json_str.endswith('{'):
74
+ json_str += '}'
75
+
76
+ return json_str
77
+
78
+
79
+ if __name__ == "__main__":
80
+ # the corpus: trec_2021, trec_2022, or sigir
81
+ corpus = sys.argv[1]
82
+
83
+ # the model index to use
84
+ model = sys.argv[2]
85
+
86
+ outputs = {}
87
+
88
+ with open(f"dataset/{corpus}/queries.jsonl", "r") as f:
89
+ for line in f.readlines():
90
+ entry = json.loads(line)
91
+ messages = get_keyword_generation_messages(entry["text"])
92
+
93
+ max_retries = 3
94
+ retry_count = 0
95
+
96
+ while retry_count < max_retries:
97
+ try:
98
+ response = client.chat.completions.create(
99
+ model=model,
100
+ messages=messages,
101
+ temperature=0,
102
+ max_tokens=2000, # Increase max tokens to avoid truncation
103
+ )
104
+
105
+ output = response.choices[0].message.content
106
+
107
+ # Check if output is None or empty
108
+ if output is None or output.strip() == "":
109
+ print(f"Warning: Empty response for entry {entry['_id']}, retry {retry_count + 1}/{max_retries}")
110
+ retry_count += 1
111
+ if retry_count < max_retries:
112
+ time.sleep(2) # Wait before retrying
113
+ continue
114
+ else:
115
+ print(f"Error: Failed to get response for entry {entry['_id']} after {max_retries} retries, skipping...")
116
+ break
117
+
118
+ output = output.strip("`").strip("json")
119
+
120
+ # Try to fix truncated JSON
121
+ if not is_valid_json(output):
122
+ fixed_output = fix_truncated_json(output)
123
+ if fixed_output and is_valid_json(fixed_output):
124
+ output = fixed_output
125
+ print(f"Info: Fixed truncated JSON for entry {entry['_id']}")
126
+ else:
127
+ print(f"Warning: Invalid JSON for entry {entry['_id']}, retry {retry_count + 1}/{max_retries}")
128
+ print(f"Raw output: {output[:200]}...") # Show first 200 chars
129
+ retry_count += 1
130
+ if retry_count < max_retries:
131
+ time.sleep(2) # Wait before retrying
132
+ continue
133
+ else:
134
+ print(f"Error: Failed to parse JSON for entry {entry['_id']} after {max_retries} retries, skipping...")
135
+ break
136
+
137
+ try:
138
+ parsed_output = json.loads(output)
139
+ outputs[entry["_id"]] = parsed_output
140
+ print(f"Success: Processed entry {entry['_id']}")
141
+ break # Success, exit retry loop
142
+
143
+ except json.JSONDecodeError as e:
144
+ print(f"Warning: Failed to parse JSON for entry {entry['_id']}: {e}")
145
+ print(f"Raw output: {output[:200]}...") # Show first 200 chars
146
+ retry_count += 1
147
+ if retry_count < max_retries:
148
+ time.sleep(2) # Wait before retrying
149
+ continue
150
+ else:
151
+ print(f"Error: Failed to parse JSON for entry {entry['_id']} after {max_retries} retries, skipping...")
152
+ break
153
+
154
+ except Exception as e:
155
+ print(f"Error processing entry {entry['_id']}: {e}")
156
+ retry_count += 1
157
+ if retry_count < max_retries:
158
+ time.sleep(2) # Wait before retrying
159
+ continue
160
+ else:
161
+ print(f"Error: Failed to process entry {entry['_id']} after {max_retries} retries, skipping...")
162
+ break
163
+
164
+ # Save progress after each entry
165
+ with open(f"results/retrieval_keywords_{model}_{corpus}.json", "w") as f:
166
+ json.dump(outputs, f, indent=4)
trialgpt_retrieval/retriever.py ADDED
@@ -0,0 +1,348 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # """
2
+ # Retriever module for TrialGPT
3
+ # """
4
+
5
+ # import json
6
+ # import os
7
+ # import numpy as np
8
+ # import torch
9
+ # from nltk import word_tokenize
10
+ # from rank_bm25 import BM25Okapi
11
+ # import faiss
12
+ # from transformers import AutoTokenizer, AutoModel
13
+
14
+ # def get_bm25_corpus_index(corpus="sigir"):
15
+ # """Get BM25 corpus index for the specified corpus."""
16
+ # corpus_path = os.path.join(f"trialgpt_retrieval/bm25_corpus_{corpus}.json")
17
+
18
+ # if os.path.exists(corpus_path):
19
+ # corpus_data = json.load(open(corpus_path))
20
+ # tokenized_corpus = corpus_data["tokenized_corpus"]
21
+ # corpus_nctids = corpus_data["corpus_nctids"]
22
+ # else:
23
+ # # If the pre-built index doesn't exist, we'll need to build it
24
+ # # For now, return None to indicate the index needs to be built
25
+ # return None, None
26
+
27
+ # bm25 = BM25Okapi(tokenized_corpus)
28
+ # return bm25, corpus_nctids
29
+
30
+ # def get_medcpt_corpus_index(corpus="sigir"):
31
+ # """Get MedCPT corpus index for the specified corpus."""
32
+ # corpus_path = f"trialgpt_retrieval/{corpus}_embeds.npy"
33
+ # nctids_path = f"trialgpt_retrieval/{corpus}_nctids.json"
34
+
35
+ # if os.path.exists(corpus_path):
36
+ # embeds = np.load(corpus_path)
37
+ # corpus_nctids = json.load(open(nctids_path))
38
+ # else:
39
+ # # If the pre-built index doesn't exist, return None
40
+ # return None, None
41
+
42
+ # index = faiss.IndexFlatIP(768)
43
+ # index.add(embeds)
44
+
45
+ # return index, corpus_nctids
46
+
47
+ # def retrieve_trials(conditions, corpus="sigir", top_k=5, bm25_weight=1, medcpt_weight=1):
48
+ # """
49
+ # Retrieve clinical trials based on conditions using hybrid BM25 + MedCPT retrieval.
50
+
51
+ # Args:
52
+ # conditions (list): List of condition strings to search for
53
+ # corpus (str): Corpus to search in ("trec_2021", "trec_2022", "sigir")
54
+ # top_k (int): Number of top trials to return
55
+ # bm25_weight (int): Weight for BM25 scores
56
+ # medcpt_weight (int): Weight for MedCPT scores
57
+
58
+ # Returns:
59
+ # list: List of NCT IDs for the top matching trials
60
+ # """
61
+ # # Get the retrieval indices
62
+ # bm25, bm25_nctids = get_bm25_corpus_index(corpus)
63
+ # medcpt, medcpt_nctids = get_medcpt_corpus_index(corpus)
64
+
65
+ # if bm25 is None or medcpt is None:
66
+ # print(f"Warning: Pre-built indices for corpus '{corpus}' not found.")
67
+ # print("Please run the hybrid_fusion_retrieval.py script first to build the indices.")
68
+ # return []
69
+
70
+ # if len(conditions) == 0:
71
+ # return []
72
+
73
+ # # BM25 retrieval
74
+ # bm25_condition_top_nctids = []
75
+ # if bm25_weight > 0:
76
+ # for condition in conditions:
77
+ # tokens = word_tokenize(condition.lower())
78
+ # top_nctids = bm25.get_top_n(tokens, bm25_nctids, n=top_k*2) # Get more for fusion
79
+ # bm25_condition_top_nctids.append(top_nctids)
80
+
81
+ # # MedCPT retrieval
82
+ # medcpt_condition_top_nctids = []
83
+ # if medcpt_weight > 0:
84
+ # try:
85
+ # model = AutoModel.from_pretrained("ncbi/MedCPT-Query-Encoder")
86
+ # tokenizer = AutoTokenizer.from_pretrained("ncbi/MedCPT-Query-Encoder")
87
+
88
+ # with torch.no_grad():
89
+ # encoded = tokenizer(
90
+ # conditions,
91
+ # truncation=True,
92
+ # padding=True,
93
+ # return_tensors='pt',
94
+ # max_length=256,
95
+ # )
96
+
97
+ # # encode the queries
98
+ # embeds = model(**encoded).last_hidden_state[:, 0, :].numpy()
99
+
100
+ # # search the Faiss index
101
+ # scores, inds = medcpt.search(embeds, k=top_k*2) # Get more for fusion
102
+
103
+ # for ind_list in inds:
104
+ # top_nctids = [medcpt_nctids[ind] for ind in ind_list]
105
+ # medcpt_condition_top_nctids.append(top_nctids)
106
+
107
+ # except Exception as e:
108
+ # print(f"Warning: MedCPT retrieval failed: {e}")
109
+ # medcpt_weight = 0
110
+
111
+ # # Fusion of results
112
+ # nctid2score = {}
113
+
114
+ # for condition_idx, condition in enumerate(conditions):
115
+ # # BM25 scoring
116
+ # if bm25_weight > 0 and condition_idx < len(bm25_condition_top_nctids):
117
+ # for rank, nctid in enumerate(bm25_condition_top_nctids[condition_idx]):
118
+ # if nctid not in nctid2score:
119
+ # nctid2score[nctid] = 0
120
+ # nctid2score[nctid] += bm25_weight * (1 / (rank + 1)) * (1 / (condition_idx + 1))
121
+
122
+ # # MedCPT scoring
123
+ # if medcpt_weight > 0 and condition_idx < len(medcpt_condition_top_nctids):
124
+ # for rank, nctid in enumerate(medcpt_condition_top_nctids[condition_idx]):
125
+ # if nctid not in nctid2score:
126
+ # nctid2score[nctid] = 0
127
+ # nctid2score[nctid] += medcpt_weight * (1 / (rank + 1)) * (1 / (condition_idx + 1))
128
+
129
+ # # Sort by score and return top_k
130
+ # nctid2score = sorted(nctid2score.items(), key=lambda x: -x[1])
131
+ # top_nctids = [nctid for nctid, _ in nctid2score[:top_k]]
132
+
133
+ # return top_nctids
134
+
135
+ """
136
+ GPU-accelerated Retriever module for TrialGPT
137
+ """
138
+
139
+ import json
140
+ import os
141
+ import numpy as np
142
+ import torch
143
+ from nltk import word_tokenize
144
+ from rank_bm25 import BM25Okapi
145
+ import faiss
146
+ from transformers import AutoTokenizer, AutoModel
147
+
148
+ class GPUTrialRetriever:
149
+ """GPU-accelerated trial retriever with model caching."""
150
+
151
+ def __init__(self, device=None):
152
+ self.device = device or ('cuda' if torch.cuda.is_available() else 'cpu')
153
+ self.model = None
154
+ self.tokenizer = None
155
+ self._model_loaded = False
156
+
157
+ def _load_medcpt_model(self):
158
+ """Load MedCPT model once and cache it."""
159
+ if not self._model_loaded:
160
+ self.tokenizer = AutoTokenizer.from_pretrained("ncbi/MedCPT-Query-Encoder")
161
+ self.model = AutoModel.from_pretrained("ncbi/MedCPT-Query-Encoder")
162
+
163
+ # Move model to GPU if available
164
+ if self.device != 'cpu':
165
+ self.model = self.model.to(self.device)
166
+
167
+ # Set to evaluation mode for inference
168
+ self.model.eval()
169
+ self._model_loaded = True
170
+ print(f"MedCPT model loaded on {self.device}")
171
+
172
+ def get_bm25_corpus_index(corpus="sigir"):
173
+ """Get BM25 corpus index for the specified corpus."""
174
+ corpus_path = os.path.join(f"trialgpt_retrieval/bm25_corpus_{corpus}.json")
175
+
176
+ if os.path.exists(corpus_path):
177
+ corpus_data = json.load(open(corpus_path))
178
+ tokenized_corpus = corpus_data["tokenized_corpus"]
179
+ corpus_nctids = corpus_data["corpus_nctids"]
180
+ else:
181
+ return None, None
182
+
183
+ bm25 = BM25Okapi(tokenized_corpus)
184
+ return bm25, corpus_nctids
185
+
186
+ def get_medcpt_corpus_index_gpu(corpus="sigir", use_gpu=True):
187
+ """Get GPU-accelerated MedCPT corpus index."""
188
+ corpus_path = f"trialgpt_retrieval/{corpus}_embeds.npy"
189
+ nctids_path = f"trialgpt_retrieval/{corpus}_nctids.json"
190
+
191
+ if os.path.exists(corpus_path):
192
+ embeds = np.load(corpus_path).astype(np.float32) # Ensure float32 for GPU
193
+ corpus_nctids = json.load(open(nctids_path))
194
+ else:
195
+ return None, None
196
+
197
+ # Use GPU FAISS index if available and requested
198
+ if use_gpu and torch.cuda.is_available():
199
+ try:
200
+ # Create GPU resources
201
+ res = faiss.StandardGpuResources()
202
+
203
+ # Create CPU index first
204
+ cpu_index = faiss.IndexFlatIP(768)
205
+ cpu_index.add(embeds)
206
+
207
+ # Move to GPU
208
+ gpu_index = faiss.index_cpu_to_gpu(res, 0, cpu_index)
209
+ print(f"FAISS index moved to GPU with {len(corpus_nctids)} embeddings")
210
+ return gpu_index, corpus_nctids
211
+
212
+ except Exception as e:
213
+ print(f"GPU FAISS failed, falling back to CPU: {e}")
214
+ # Fall back to CPU index
215
+ index = faiss.IndexFlatIP(768)
216
+ index.add(embeds)
217
+ return index, corpus_nctids
218
+ else:
219
+ # CPU index
220
+ index = faiss.IndexFlatIP(768)
221
+ index.add(embeds)
222
+ return index, corpus_nctids
223
+
224
+ def retrieve_trials_gpu(conditions, corpus="sigir", top_k=5, bm25_weight=1, medcpt_weight=1,
225
+ use_gpu=True, batch_size=32, retriever=None):
226
+ """
227
+ GPU-accelerated clinical trial retrieval with optimized batching.
228
+
229
+ Args:
230
+ conditions (list): List of condition strings to search for
231
+ corpus (str): Corpus to search in ("trec_2021", "trec_2022", "sigir")
232
+ top_k (int): Number of top trials to return
233
+ bm25_weight (int): Weight for BM25 scores
234
+ medcpt_weight (int): Weight for MedCPT scores
235
+ use_gpu (bool): Whether to use GPU acceleration
236
+ batch_size (int): Batch size for MedCPT encoding
237
+ retriever (GPUTrialRetriever): Cached retriever instance
238
+
239
+ Returns:
240
+ list: List of NCT IDs for the top matching trials
241
+ """
242
+ if len(conditions) == 0:
243
+ return []
244
+
245
+ # Get the retrieval indices
246
+ bm25, bm25_nctids = get_bm25_corpus_index(corpus)
247
+ medcpt, medcpt_nctids = get_medcpt_corpus_index_gpu(corpus, use_gpu)
248
+
249
+ if bm25 is None or medcpt is None:
250
+ print(f"Warning: Pre-built indices for corpus '{corpus}' not found.")
251
+ print("Please run the hybrid_fusion_retrieval.py script first to build the indices.")
252
+ return []
253
+
254
+ # Initialize retriever if not provided
255
+ if retriever is None:
256
+ device = 'cuda' if use_gpu and torch.cuda.is_available() else 'cpu'
257
+ retriever = GPUTrialRetriever(device)
258
+
259
+ # BM25 retrieval (CPU-bound, hard to optimize further)
260
+ bm25_condition_top_nctids = []
261
+ if bm25_weight > 0:
262
+ for condition in conditions:
263
+ tokens = word_tokenize(condition.lower())
264
+ top_nctids = bm25.get_top_n(tokens, bm25_nctids, n=top_k*2)
265
+ bm25_condition_top_nctids.append(top_nctids)
266
+
267
+ # MedCPT retrieval with GPU acceleration
268
+ medcpt_condition_top_nctids = []
269
+ if medcpt_weight > 0:
270
+ try:
271
+ retriever._load_medcpt_model()
272
+
273
+ # Process conditions in batches for better GPU utilization
274
+ all_embeds = []
275
+
276
+ for i in range(0, len(conditions), batch_size):
277
+ batch_conditions = conditions[i:i + batch_size]
278
+
279
+ with torch.no_grad():
280
+ # Tokenize batch
281
+ encoded = retriever.tokenizer(
282
+ batch_conditions,
283
+ truncation=True,
284
+ padding=True,
285
+ return_tensors='pt',
286
+ max_length=256,
287
+ )
288
+
289
+ # Move tensors to GPU
290
+ if retriever.device != 'cpu':
291
+ encoded = {k: v.to(retriever.device) for k, v in encoded.items()}
292
+
293
+ # Get embeddings
294
+ batch_embeds = retriever.model(**encoded).last_hidden_state[:, 0, :]
295
+
296
+ # Always move to CPU before appending (fixes the CUDA tensor issue)
297
+ batch_embeds = batch_embeds.cpu()
298
+ all_embeds.append(batch_embeds)
299
+
300
+ # Concatenate all embeddings and convert to numpy
301
+ embeds = torch.cat(all_embeds, dim=0).numpy()
302
+
303
+ # Search the FAISS index
304
+ scores, inds = medcpt.search(embeds, k=top_k*2)
305
+
306
+ # Convert indices to NCT IDs
307
+ for ind_list in inds:
308
+ top_nctids = [medcpt_nctids[ind] for ind in ind_list]
309
+ medcpt_condition_top_nctids.append(top_nctids)
310
+
311
+ except Exception as e:
312
+ print(f"Warning: MedCPT retrieval failed: {e}")
313
+ medcpt_weight = 0
314
+
315
+ # Fusion of results (same as original)
316
+ nctid2score = {}
317
+
318
+ for condition_idx, condition in enumerate(conditions):
319
+ # BM25 scoring
320
+ if bm25_weight > 0 and condition_idx < len(bm25_condition_top_nctids):
321
+ for rank, nctid in enumerate(bm25_condition_top_nctids[condition_idx]):
322
+ if nctid not in nctid2score:
323
+ nctid2score[nctid] = 0
324
+ nctid2score[nctid] += bm25_weight * (1 / (rank + 1)) * (1 / (condition_idx + 1))
325
+
326
+ # MedCPT scoring
327
+ if medcpt_weight > 0 and condition_idx < len(medcpt_condition_top_nctids):
328
+ for rank, nctid in enumerate(medcpt_condition_top_nctids[condition_idx]):
329
+ if nctid not in nctid2score:
330
+ nctid2score[nctid] = 0
331
+ nctid2score[nctid] += medcpt_weight * (1 / (rank + 1)) * (1 / (condition_idx + 1))
332
+
333
+ # Sort by score and return top_k
334
+ nctid2score = sorted(nctid2score.items(), key=lambda x: -x[1])
335
+ top_nctids = [nctid for nctid, _ in nctid2score[:top_k]]
336
+
337
+ return top_nctids
338
+
339
+ # Convenience function for backward compatibility
340
+ def retrieve_trials(conditions, corpus="sigir", top_k=5, bm25_weight=1, medcpt_weight=1):
341
+ """Original interface with GPU acceleration."""
342
+ return retrieve_trials_gpu(conditions, corpus, top_k, bm25_weight, medcpt_weight)
343
+
344
+ # Example usage with persistent retriever for multiple calls
345
+ def create_retriever_session(use_gpu=True):
346
+ """Create a retriever session for multiple queries to avoid model reloading."""
347
+ device = 'cuda' if use_gpu and torch.cuda.is_available() else 'cpu'
348
+ return GPUTrialRetriever(device)
trialgpt_retrieval/sigir_embeds.npy ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:6d0d11b601ae441f3f5545445844890d194c27a3ce1482c6da766c4dde8ca555
3
+ size 11157632
trialgpt_retrieval/sigir_nctids.json ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c3d425afa157e3bc7265d288902836b0516484fd0f3297b2a3216f7728c30605
3
+ size 69010