File size: 13,378 Bytes
ce70f59
 
 
 
0a96a85
1e86849
 
ce70f59
 
0a96a85
ce70f59
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1e86849
ce70f59
 
 
 
 
 
 
 
 
 
 
75af700
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ce70f59
 
8c94b6d
 
 
ce70f59
8c94b6d
 
 
ce70f59
8c94b6d
 
 
ce70f59
8c94b6d
 
 
ce70f59
8c94b6d
 
ce70f59
8c94b6d
 
ce70f59
8c94b6d
 
ce70f59
8c94b6d
 
 
 
ce70f59
8c94b6d
 
ce70f59
 
8c94b6d
 
ce70f59
 
 
 
 
 
 
 
 
 
 
8c94b6d
 
ce70f59
 
8c94b6d
ce70f59
8c94b6d
 
ce70f59
 
 
 
0a96a85
ce70f59
 
 
 
 
 
 
 
 
 
0a96a85
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ce70f59
 
 
 
0a96a85
ce70f59
 
 
 
 
 
0a96a85
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ce70f59
0a96a85
ce70f59
0a96a85
 
 
ce70f59
 
 
 
 
 
 
 
0a96a85
 
 
ce70f59
 
 
0a96a85
 
ce70f59
 
 
0a96a85
 
ce70f59
1e86849
 
 
 
 
 
 
 
 
 
 
 
 
 
ce70f59
 
1e86849
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ce70f59
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
from pathlib import Path
import numpy as np
import gradio as gr
import requests
import json
from transformers import ViTImageProcessor, ViTModel
from PIL import Image

# Store the server's URL
SERVER_URL = "https://ppaihack-match.azurewebsites.net/"
CURRENT_DIR = Path(__file__).parent
DEPLOYMENT_DIR = CURRENT_DIR / "deployment_files"
KEYS_DIR = DEPLOYMENT_DIR / ".fhe_keys"
CLIENT_DIR = DEPLOYMENT_DIR / "client_dir"
SERVER_DIR = DEPLOYMENT_DIR / "server_dir"


USER_ID = "user_id"
EXAMPLE_CLINICAL_TRIAL_LINK = "https://www.trials4us.co.uk/ongoing-clinical-trials/recruiting-healthy-adults-c23026?_gl=1*1ysp815*_up*MQ..&gclid=Cj0KCQjwr9m3BhDHARIsANut04bHqi5zE3sjS3f8JK2WRN3YEgY4bTfWbvTdZTxkUTSISxXX5ZWL7qEaAowwEALw_wcB&gbraid=0AAAAAD3Qci2k_3IERmM6U1FGDuYVayZWH"




# Define possible categories for fields without predefined categories
additional_categories = {
    "Gender": ["Male", "Female", "Other"],
    "Ethnicity": ["White", "Black or African American", "Asian", "American Indian or Alaska Native", "Native Hawaiian or Other Pacific Islander", "Other"],
    "Geographic_Location": ["North America", "South America", "Europe", "Asia", "Africa", "Australia", "Antarctica"],
    "Smoking_Status": ["Never", "Former", "Current"],
    "Diagnoses_ICD10": ["Actinic keratosis", "Melanoma", "Dermatofibroma", "Vascular lesion","None"],
    "Medications": ["Metformin", "Lisinopril", "Atorvastatin", "Amlodipine", "Omeprazole", "Simvastatin", "Levothyroxine", "None"],
    "Allergies": ["Penicillin", "Peanuts", "Shellfish", "Latex", "Bee stings", "None"],
    "Previous_Treatments": ["Chemotherapy", "Radiation Therapy", "Surgery", "Physical Therapy", "Immunotherapy", "None"],
    "Alcohol_Consumption": ["None", "Occasionally", "Regularly", "Heavy"],
    "Exercise_Habits": ["Sedentary", "Light", "Moderate", "Active", "Very Active"],
    "Diet": ["Omnivore", "Vegetarian", "Vegan", "Pescatarian", "Keto", "Mediterranean"],
    "Functional_Status": ["Independent", "Assisted", "Dependent"],
    "Previous_Trial_Participation": ["Yes", "No"]
}

# Define the input components for the form
age_input = gr.Slider(minimum=18, maximum=100, label="Age ", step=1, value=30)
gender_input = gr.Radio(choices=additional_categories["Gender"], label="Gender", value="Male")
ethnicity_input = gr.Radio(choices=additional_categories["Ethnicity"], label="Ethnicity", value="White")
geographic_location_input = gr.Radio(choices=additional_categories["Geographic_Location"], label="Geographic Location", value="North America")
medications_input = gr.CheckboxGroup(choices=additional_categories["Medications"], label="Medications", value=["Metformin"])
allergies_input = gr.CheckboxGroup(choices=additional_categories["Allergies"], label="Allergies", value=["Peanuts"])
previous_treatments_input = gr.CheckboxGroup(choices=additional_categories["Previous_Treatments"], label="Previous Treatments", value=["None"])
blood_glucose_level_input = gr.Slider(minimum=0, maximum=300, label="Blood Glucose Level", step=1, value=100)
blood_pressure_systolic_input = gr.Slider(minimum=80, maximum=200, label="Blood Pressure (Systolic)", step=1, value=120)
blood_pressure_diastolic_input = gr.Slider(minimum=40, maximum=120, label="Blood Pressure (Diastolic)", step=1, value=80)
bmi_input = gr.Slider(minimum=10, maximum=50, label="BMI ", step=1, value=20)
smoking_status_input = gr.Radio(choices=additional_categories["Smoking_Status"], label="Smoking Status", value="Never")
alcohol_consumption_input = gr.Radio(choices=additional_categories["Alcohol_Consumption"], label="Alcohol Consumption", value="None")
exercise_habits_input = gr.Radio(choices=additional_categories["Exercise_Habits"], label="Exercise Habits", value="Sedentary")
diet_input = gr.Radio(choices=additional_categories["Diet"], label="Diet", value="Omnivore")
condition_severity_input = gr.Slider(minimum=1, maximum=10, label="Condition Severity", step=1, value=5)
functional_status_input = gr.Radio(choices=additional_categories["Functional_Status"], label="Functional Status", value="Independent")
previous_trial_participation_input = gr.Radio(choices=additional_categories["Previous_Trial_Participation"], label="Previous Trial Participation", value="No")


# def encrypt_array(user_symptoms: np.ndarray, user_id: str) -> bytes:
#     """
#     Encrypt the user symptoms vector.

#     Args:
#         user_symptoms (np.ndarray): The vector of symptoms provided by the user.
#         user_id (str): The current user's ID.
    
#     Returns:
#         bytes: Encrypted and serialized symptoms.
#     """

#     # Retrieve the client API
#     client = FHEModelClient(path_dir=DEPLOYMENT_DIR, key_dir=KEYS_DIR / f"{user_id}")
#     client.load()

#     # Ensure the symptoms are properly formatted as an array
#     user_symptoms = np.array(user_symptoms).reshape(1, -1)

#     # Encrypt and serialize the symptoms
#     encrypted_quantized_user_symptoms = client.quantize_encrypt_serialize(user_symptoms)
    
#     # Ensure the encryption process returned bytes
#     assert isinstance(encrypted_quantized_user_symptoms, bytes)

#     # Save the encrypted data to a file (optional)
#     encrypted_input_path = KEYS_DIR / f"{user_id}/encrypted_input"
#     with encrypted_input_path.open("wb") as f:
#         f.write(encrypted_quantized_user_symptoms)

#     # Return the encrypted data
#     return encrypted_quantized_user_symptoms


# def decrypt_result(encrypted_answer: bytes, user_id: str) -> bool:
"""
    Decrypt the encrypted result.

    Args:
        encrypted_answer (bytes): The encrypted result.
        user_id (str): The current user's ID.
    
    Returns:
        bool: The decrypted result.
    """

    # Retrieve the client API
    # client = FHEModelClient(path_dir=DEPLOYMENT_DIR, key_dir=KEYS_DIR / f"{user_id}")
    # client.load()

    # Decrypt the result
    # decrypted_result = client.decrypt_deserialize(encrypted_answer)

    # # Return the decrypted result
    # return decrypted_result



def encode_categorical_data(data):
    categories = ["Gender", "Ethnicity", "Geographic_Location", "Diagnoses_ICD10", "Medications", "Allergies", "Previous_Treatments", "Smoking_Status", "Alcohol_Consumption", "Exercise_Habits", "Diet", "Functional_Status", "Previous_Trial_Participation"]
    encoded_data = []
    for i in range(len(categories)):
        sub_cats = additional_categories[categories[i]]
        if data[i] in sub_cats:
            encoded_data.append(sub_cats.index(data[i]) + 1)
        else:
            encoded_data.append(0)
        
    return encoded_data

def clear_data_to_json(data):
    print(data)
    patient_data = {
        "model_names": ["my_model"],
        "patient": {
            "Age": data.get("age", 30),
            "Blood_Glucose_Level": data.get("blood_glucose_level", 0),
            "Blood_Pressure_Systolic": data.get("blood_pressure_systolic", 0),
            "Blood_Pressure_Diastolic": data.get("blood_pressure_diastolic", 0),
            "BMI": data.get("bmi", 0),
            "Condition_Severity": data.get("condition_severity", 0),
            "Gender": data.get("Gender", 0),
            "Ethnicity": data.get("Ethnicity", 0),
            "Geographic_Location": data.get("Geographic_Location", 0),
            "Smoking_Status": data.get("Smoking_Status", 0),
            "Diagnoses_ICD10": data.get("Diagnoses_ICD10", 0),
            "Medications": data.get("Medications", 0),
            "Allergies": data.get("Allergies", 0),
            "Previous_Treatments": data.get("Previous_Treatments", 0),
            "Alcohol_Consumption": data.get("Alcohol_Consumption", 0),
            "Exercise_Habits": data.get("Exercise_Habits", 0),
            "Diet": data.get("Diet", 0),
            "Functional_Status": data.get("Functional_Status", 0),
            "Previous_Trial_Participation": data.get("Previous_Trial_Participation", 0)
        }
    }
    return json.dumps(patient_data, indent=4)


def process_patient_data(age, gender, ethnicity, geographic_location, diagnoses_icd10, medications, allergies, previous_treatments, blood_glucose_level, blood_pressure_systolic, blood_pressure_diastolic, bmi, smoking_status, alcohol_consumption, exercise_habits, diet, condition_severity, functional_status, previous_trial_participation):    
    
    # Encode the data
    categorical_data = [gender, ethnicity, geographic_location, diagnoses_icd10, medications, allergies, previous_treatments, smoking_status, alcohol_consumption, exercise_habits, diet, functional_status, previous_trial_participation]
    print(f"Categorical data: {categorical_data}")
    encoded_categorical_data = encode_categorical_data(categorical_data)
    numerical_data = np.array([age, blood_glucose_level, blood_pressure_systolic, blood_pressure_diastolic, bmi, condition_severity])
    print(f"Numerical data: {numerical_data}")
    print(f"One-hot encoded data: {encoded_categorical_data}")
    combined_data = np.hstack((numerical_data, encoded_categorical_data))

    ordered_categories = ["Gender", "Ethnicity", "Geographic_Location", "Diagnoses_ICD10", "Medications", "Allergies", "Previous_Treatments", "Smoking_Status", "Alcohol_Consumption", "Exercise_Habits", "Diet", "Functional_Status", "Previous_Trial_Participation"]
    zipped_data = zip(ordered_categories, encoded_categorical_data)
    # Convert the zipped data to a dictionary
    encoded_categorical_dict = {category: value for category, value in zipped_data}

    # Convert the data to JSON
    json_data = clear_data_to_json({
        "age": age,
        "blood_glucose_level": blood_glucose_level,
        "blood_pressure_systolic": blood_pressure_systolic,
        "blood_pressure_diastolic": blood_pressure_diastolic,
        "bmi": bmi,
        "condition_severity": condition_severity,
        **encoded_categorical_dict
    })

    print(f"JSON data: {json_data}")
    print(f"Combined data: {combined_data}")
    # encrypted_array = encrypt_array(combined_data, "user_id")

    # Send the data to the server 
    url = SERVER_URL + "clear-match"
    response = requests.post(url, data=json_data)

    # Check if the data was sent successfully
    if response.status_code == 200:
        print("Data sent successfully.")
    else:
        print("Error sending data.")
    
    # Decrypt the result
    # decrypted_result = decrypt_result(response.content, USER_ID)
    print()
    decrypted_result = response.json()
    # If the answer is True, return the link
    if decrypted_result:
        return (
            # f"Encrypted data: {encrypted_array}",
            f"Decrypted result: {response.json()}"
        )
    else:
        return (
            # f"Encrypted data: {encrypted_array}",
            f"Decrypted result: {response.json()}"
        )
# Define the function to handle image upload
def handle_image_upload(image):
    url = 'http://images.cocodataset.org/val2017/000000039769.jpg'
    image = Image.open(requests.get(url, stream=True).raw)

    processor = ViTImageProcessor.from_pretrained('google/vit-base-patch16-224-in21k')
    model = ViTModel.from_pretrained('google/vit-base-patch16-224-in21k')
    inputs = processor(images=image, return_tensors="pt")

    outputs = model(**inputs)
    pooler_output = outputs.pooler_output[0]
    sclaed_output = 127 + 127 * pooler_output / pooler_output.abs().max()
    sclaed_output = sclaed_output.to(int)
    return ["Melanoma", "Vascular lesion"]

# Create the Gradio interface
with gr.Blocks() as demo:
    gr.Markdown("# Patient Data Criteria Form\nPlease fill in the criteria for the type of patients you are looking for.")
    with gr.Column():
        with gr.Group():
            age_input.render()
            gender_input.render()
            ethnicity_input.render()
            geographic_location_input.render()
            medications_input.render()
            allergies_input.render()
            previous_treatments_input.render()
            blood_glucose_level_input.render()
            blood_pressure_systolic_input.render()
            blood_pressure_diastolic_input.render()
            bmi_input.render()
            smoking_status_input.render()
            alcohol_consumption_input.render()
            exercise_habits_input.render()
            diet_input.render()
            condition_severity_input.render()
            functional_status_input.render()
            previous_trial_participation_input.render()
        with gr.Group():
            diagnoses_icd10_input = gr.CheckboxGroup(choices=additional_categories["Diagnoses_ICD10"], label="Skin Diagnosis", interactive=False)
            image_input = gr.Image(label="Upload an Image")
            gr.Button("Upload").click(handle_image_upload, inputs=image_input, outputs=diagnoses_icd10_input)
        with gr.Group():
            output = gr.JSON(label="Patient Data JSON")
            gr.Button("Submit").click(process_patient_data, inputs=[
                age_input, gender_input, ethnicity_input, geographic_location_input, diagnoses_icd10_input, medications_input, allergies_input, previous_treatments_input, blood_glucose_level_input, blood_pressure_systolic_input, blood_pressure_diastolic_input, bmi_input, smoking_status_input, alcohol_consumption_input, exercise_habits_input, diet_input, condition_severity_input, functional_status_input, previous_trial_participation_input
            ], outputs=output)


# Launch the app
demo.launch()