File size: 41,470 Bytes
516007b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
768fc43
 
 
 
5f96ee8
516007b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
da25b63
516007b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81dc13f
 
 
 
 
da25b63
516007b
 
 
 
 
 
 
 
 
 
 
 
 
 
5f96ee8
516007b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
eec7adf
4a76d29
eec7adf
c4e7d21
486542b
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
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
from dotenv import load_dotenv
from langchain_core.tools import tool
import math
from datetime import datetime, timedelta
from langchain_core.tools import tool
import matplotlib.pyplot as plt
from langchain.agents import initialize_agent, AgentType
from langchain_core.tools import tool
from datetime import datetime
from typing import Dict, Union
from langchain_google_genai import ChatGoogleGenerativeAI
import math   
import random
import os
import gradio as gr
#load 
load_dotenv()

api_key = os.getenv("GEMINI_API_KEY")
# Line 23 should have ZERO spaces at the start if it's not in a function
llm = ChatGoogleGenerativeAI(model="gemini-2.5-flash", api_key=api_key)
CORRECT_PASSWORD =os.getenv("passCS")
# Dictionary of dose limits (units in mSv)
OCCUPATIONAL_LIMITS = {
        "Annual dose limit to Workers": 50,  # mSv per year
        "Annual Exposure Limit to Workers (5-year avg)": 20,  # mSv per year
        "Monthly dose Limit to Worker": 4.16,  # mSv per month (approx.)
        "Lens of Eye Dose Limit to Worker": 50,  # mSv per year
        "Extremity Dose Limit to Worker": 500,  # mSv per year
        "Annual Dose Limit to Public": 1,  # mSv per year
        "Lens of Eye Dose Limit to Public": 15,  # mSv per year
        "Extremity Dose Limit to Public": 50,  # mSv per year
        "Annual Dose Limit to Caregivers": 5,  # mSv per year
        "Annual Dose Limit to Comforter": 5,  # mSv per year
        "PNRA release limit(dose)": 50,  # USv 
        "PNRA release limit(activity)": 30,  # mci 

        "Discharge TEDE Threshold":0.5, #rem
        "Occupancy factor (6/24)":0.25, #if patient expose 6hr public a day
        "Occupancy factor (3/24)":0.125, #if public expose 3hr a day from patient

    }
# ✅ Dictionary of Radioactive Nuclide & Their Half-Lives (in Days)
from datetime import datetime
import math
RADIOACTIVE_NUCLIDES = {
    "Uranium-238": 4.47e9 * 365,  # Billion years converted to days
    "Uranium-235": 704e6 * 365,   # Million years converted to days
    "Thorium-232": 14.05e9 * 365,
    "Plutonium-239": 24100,
    "Plutonium-238": 87.7,
    "Radon-222": 3.8,
    "Radium-226": 1600,
    "Polonium-210": 138,
    "Americium-241": 432,
    "Carbon-14": 5730,
    "Strontium-90": 28.8 * 365,
    "Iodine-131 (I-131)": 8.02,
    "I-131": 8.02,
    "Iodine-125(I-125)": 59.4,
    "I-125": 59.4,
    "Cesium-137": 30.2 * 365,
     "Cs-137": 30.2 * 365,
    "Technetium-99m": 0.25,  # 6 hours converted to days
    "Tc-99m": 0.25,  # 6 hours converted to days
    "Cobalt-60": 5.27 * 365,
    "Co-60": 5.27 * 365,
    "Cobalt-57": 271.8,
    "Co-57": 271.8,
    "Tritium (H-3)": 12.32 * 365,
    "Krypton-85": 10.76 * 365,
    "Ruthenium-106": 373.6,
    "Molybdenum (MO-99)": 66/24,
    "Cesium Cs-137": 10950,  # ~30 years
    "Cobalt Co-60": 1925,    # ~5.3 years
    "Cobalt Co-57": 271.8,   # ~9 months
    "Barium Ba-133": 3843,   # ~10.5 years
}
# Half-life values (in days)
HALF_LIFE = {
    "Cs-137": 10950,  # ~30 years
    "Co-60": 1925,    # ~5.3 years
    "Co-57": 271.8,   # ~9 months
    "Ba-133": 3843,   # ~10.5 years
}

# Source purchase dates (YYYY-MM-DD)
SOURCE_PURCHASE = {
    "Cs-137": "2019-09-20",
    "Co-60": "2019-09-20",
    "Co-57": "2022-04-21",
    "Ba-133": "2019-09-20",
}

# Initial activities (in MBq) at the time of purchase (Example Values)
INITIAL_ACTIVITY = {
    "Cs-137": 370,   # Example values, replace with actual
    "Co-60": 1000,
    "Co-57": 740,
    "Ba-133": 500,
}


#   Tool 1: Unit Conversion
@tool
def unit_conversion_tool(value, from_unit, to_unit):
    """
    Converts radiation measurement units.
    """
    conversion_factors = {
        "Gy_to_rad": 100, "rad_to_Gy": 0.01,
        "Sv_to_rem": 100, "rem_to_Sv": 0.01,
        "Bq_to_Ci": 2.7e-11, "Ci_to_Bq": 3.7e10,
        "C/kg_to_R": 2.58e-4, "R_to_C/kg": 0.387e4,
    }
    key = f"{from_unit}_to_{to_unit}"
    if key in conversion_factors:
        result = value * conversion_factors[key]
        return f"**Conversion:** {value} {from_unit}{to_unit}\n**Result:** {result:.4f} {to_unit}"
    else:
        return "⚠️ Invalid conversion request."

#  Tool 2: Radioactive Decay Calculation
@tool
# Function to Calculate Radioactive Decay
def radioactive_decay_tool(nuclide, initial_activity, elapsed_days):
    """
    Computes remaining radioactive activity based on the nuclide, initial activity, and elapsed time.
    Generates a Medical Physics (MP) report in Google Doc style.
    Args:
        nuclide (str): Name of the radioactive nuclide.
        initial_activity (float): Initial activity in Bq or Ci or mCi.
        elapsed_days (float): Time elapsed in days .
    Returns:
        str: A formatted Google Doc-style report with computed decay results.
    """
    initial_activity = float(initial_activity)  
    elapsed_days = int(elapsed_days)  

    # Now comparisons will work correctly
    if initial_activity <= 0 or elapsed_days < 0:
        return "Error: Initial activity must be positive, and elapsed days cannot be negative."
    # Retrieve half-life from the dictionary
    half_life = RADIOACTIVE_NUCLIDES.get(nuclide, None)
    H_L=HALF_LIFE.get(nuclide,None)

    #if half_life is None:
    if H_L is None:
        return f"⚠️ Error: Nuclide '{nuclide}' not found in database. Please check spelling or add it."

    # Compute decay constant
    #decay_constant = math.log(2) / half_life
    decay_constant = math.log(2) / H_L


    # Compute remaining activity
    remaining_activity = initial_activity * math.exp(-decay_constant * elapsed_days)

    # Generate Google Doc-style Report
    current_date = datetime.now().strftime("%Y-%m-%d")

    report = f"""
# 📊 **Medical Physics Report**
### 📅 Date: {current_date}
---
## **🔹 Radioactive Decay Calculation**
🔬 **Radionuclide:** {nuclide}  
📈 **Initial Activity:** {initial_activity} Bq  or Ci or mCi

   **HalfLife:**{H_L}
🕰️ **Elapsed Time:** {elapsed_days} days  
⚛️ **Remaining Activity:** {remaining_activity:.4f} Bq or Ci or mCi
---
🔚 **End of Report**
"""
    #**Half-life:** {half_life:.2f} days
#return report
 #  Tool 3: print list of exposure limits
@tool
def print_exposure_limits(query: str = "all") -> str:
    """
    Returns a SNIF Google Doc–style report of exposure/dose limits for workers, public, or caregivers.
    Args:
        query (str): A string indicating which limits to display. Acceptable values:"workers", "public", "caregivers","comforter" or "all" (default prints all limits).
    Returns:
        str: A formatted report with the requested dose limits.
    """
    query_lower = query.lower().strip()
    
    # Filter keys based on the query
    if query_lower == "workers":
        # Include keys related to workers (e.g., any key with "worker")
        keys = [k for k in OCCUPATIONAL_LIMITS if "worker" in k.lower()]
    elif query_lower == "public":
        keys = [k for k in OCCUPATIONAL_LIMITS if "public" in k.lower()]
    elif query_lower == "caregivers":
        keys = [k for k in OCCUPATIONAL_LIMITS if "caregiver" in k.lower()]
    elif query_lower == "comforter":
        keys = [k for k in OCCUPATIONAL_LIMITS if "comforter" in k.lower()]
    else:
        # If query is "all" or unrecognized, print all limits.
        keys = list(OCCUPATIONAL_LIMITS.keys())
    
    # Generate a SNIF Google Doc-style report
    current_date = datetime.now().strftime("%Y-%m-%d")
    report = f"""
#  **Exposure/Dose Limits Report**
### 📅 Date: {current_date}
---
"""
    for key in keys:
        report += f"\n- **{key}**: {OCCUPATIONAL_LIMITS[key]} mSv\n"
    
    report += "\n---\n🔚 **End of Report**"
    return report
# Tool 4:patient release criteria
@tool

def patient_release_decision(neck_dose_microSv_hr: float, exposure_duration_hr: float, initial_activity_mCi: float, sef: str) -> str:
    """
    Evaluates whether a patient treated with I-131 can be released based on their neck dose,
    remaining activity, and Socio-Economic Factor (SEF). Generates a structured SNIF Google Doc-style report.
    
    Args:
        neck_dose_microSv_hr (float): Measured neck dose in μSv/hr.
        exposure_duration_hr (float): Elapsed time in hours since administration.
        initial_activity_mCi (float): Administered activity in mCi.
        sef (str): Socio-Economic Factor, which should be either "good" or "bad".
        
    Returns:
        str: A formatted SNIF Google Doc-style report with the calculated TEDE and release recommendation.
    """
    # Validate input
    if neck_dose_microSv_hr < 0 or exposure_duration_hr < 0 or initial_activity_mCi <= 0:
        return "⚠️ Invalid input! Neck dose, exposure duration, and initial activity must be positive numbers."
    
    sef = sef.lower().strip()
    if sef not in ["good", "bad"]:
        return "⚠️ Invalid SEF! Please provide 'GOOD' or 'BAD' for the socio-economic factor."
    
    # Retrieve Constants
    occupancy_factor = OCCUPATIONAL_LIMITS.get("Occupancy factor (6/24)", 0.25)
    discharge_threshold = OCCUPATIONAL_LIMITS.get("Discharge TEDE Threshold", 0.5)
    pnra_limit = OCCUPATIONAL_LIMITS.get("PNRA release limit(dose)", 50)  # Default 50 µSv
    pnra_limit1= OCCUPATIONAL_LIMITS.get("PNRA release limit(activity)", 30)#default 30 mci
    half_life_days = RADIOACTIVE_NUCLIDES.get("I-131", 8.02)  # Half-life in days

    # Convert exposure duration to days
    exposure_duration_days = exposure_duration_hr / 24

    # Calculate Decay Constant (λ) in per day
    decay_constant = math.log(2) / half_life_days  # λ = ln(2) / T_half

    # Compute Remaining Activity After Decay
    remaining_activity_mCi = initial_activity_mCi * math.exp(-decay_constant * exposure_duration_days)

    # Compute TEDE (Dose-Based) from Measured Neck Dose
    tede_dose_rem = (neck_dose_microSv_hr * 1.44 * 24 * half_life_days * occupancy_factor) / 1000 * 0.1  # Convert to rem

    # Compute TEDE (Activity-Based) from Remaining I-131 Activity
    tede_activity_rem = (remaining_activity_mCi * 1.44 * 24 * 2.2 * half_life_days * occupancy_factor) / 1000 * 0.1  # Convert to rem

    # Debugging Print Statements
    print(f"Remaining Activity (mCi): {remaining_activity_mCi:.3f}")
    print(f"TEDE from Dose Measurement (rem): {tede_dose_rem:.3f}")
    print(f"TEDE from Activity Calculation (rem): {tede_activity_rem:.3f}")
    print(f"PNRA release Limit: on Measured Dose{pnra_limit} µSv")
    print(f"PNRA release Limit: on Residual Activity{pnra_limit1} mCi") 

    # **Decision-Making Based on NRC Guidelines**
    if tede_dose_rem < discharge_threshold and tede_activity_rem < discharge_threshold:
        recommendation = "✅ Immediate release recommended."
    elif tede_dose_rem < discharge_threshold and tede_activity_rem > discharge_threshold:
        if sef == "good":
            recommendation = "⚠️ Discharge allowed with strict home isolation guidelines."
        else:
            recommendation = "❌ Hospital stay recommended until TEDE (activity) < 0.5 rem."
    else:
        recommendation = "❌ Patient should remain hospitalized until both TEDE values are below 0.5 rem."

    # Generate SNIF Google Doc-style Report
    current_date = datetime.now().strftime("%Y-%m-%d")
    report = f"""
# 📊 **Medical Physics Patient Release Report**
### 📅 Date: {current_date}
---
## **🔹 Patient Exposure Assessment**
- **Neck Dose Rate:** {neck_dose_microSv_hr:.2f} μSv/hr  
- **Total Effective Dose Equivalent (TEDE from Measured Dose):** {tede_dose_rem:.3f} rem
- **Total Effective Dose Equivalent (TEDE from Activity Calculation):** {tede_activity_rem:.3f} rem
- **PNRA Release Limit:** on Measured dose {pnra_limit} µSv and on Residual Activity {pnra_limit1}mCi
- **Remaining Activity After {exposure_duration_days:.2f} Days:** {remaining_activity_mCi:.3f} mCi
## **🔸 Definitions**
- **TEDE (Activity-Based):** Estimated radiation exposure based on the remaining I-131 activity in the body which contribute to exposure to public.
- **TEDE (Dose-Based):** Radiation exposure measured from the patient's emitted dose using a survey meter.
## **🔹 Discharge Recommendation**
- **Threshold for Release:** {discharge_threshold} rem
- **Occupancy Factor:** {occupancy_factor}
- **Half-Life (I-131):** {half_life_days} days
- **Decision:** {recommendation}
---
🔚 **End of Report**
"""
    return report

# ✅ Example Function Call
#print(patient_release_decision(12.5, 48, 30, "good"))  # Example with 30 mCi initial dose, 48 hours exposure

# Tool-5:AI Agent to Call Tools
@tool
def medical_physics_agent(query):
    """
    An AI agent that takes user queries and calls the appropriate MP tool.
    """
    current_date = datetime.now().strftime("%Y-%m-%d")
    
    # Identify Query Type
    if "convert" in query:
        value = float(query.split()[1])  # Extract first number
        from_unit, to_unit = query.split()[2], query.split()[4]  # Extract units
        result = unit_conversion_tool(value, from_unit, to_unit)
        title = "Unit Conversion"
    
    elif "decay" in query:
        values = [float(i) for i in query.split() if i.replace('.', '', 1).isdigit()]
        if len(values) == 3:
            result = radioactive_decay_tool(values[0], values[1], values[2])
            title = "Radioactive Decay Calculation"
        else:
            return "⚠️ Invalid input format for decay calculation."
    
    elif "dose" in query:
        dose = float(query.split()[1])
        result = radiation_protection_advice(dose)
        title = "Occupational Dose Assessment"
    elif "predicted yield" in query:
        activity = float(query.split()[1])
        result = predict_tc99m_yield(datetime,activity)
        title = "Predicted Yield of Tc-99m"    
        
    elif "nm_test_protocol" in query:
        nm_test = float(query.split()[1])
        result = nm_test_protocol(nmTest,weight,height)
        title = "nm_test_protocol"   
    elif "QC Tests DOSE CALIBRATOR" in query:
        # Example Usage

        QC_test = float(query.split()[1])
        result = get_qc_test_details (QC_test)
        title = "QC_test_protocol"     
    elif "QC Tests GAMMA CAMERA" in query:
        # Example Usage

        QC_test = float(query.split()[1])
        result = get_gammaqc_test_details (QC_test)
        title = "QC_test_protocol"     
    else:
        return "⚠️ Sorry, I didn't understand your request."
    # Format Response in Google Doc SNIF Style
    report = f"""
# **📊 Medical Physics (MP) Report**
### **📅 Date:** {current_date}
---
## **{title}**
{result}
---
**End of Report**
"""
    return report

    
#Tool-6 RP-Advice
@tool
def radiation_protection_advice(daily_exposure_microSv):
    """
    Function to calculate monthly radiation exposure and provide safety advice
    based on regulatory limits.
    Parameters:
    daily_exposure_microSv (float): Radiation exposure in microSievert (µSv) for an 8-hour workday.
    Returns:
    str: Radiation safety advice.
    """
    # Constants
    WORK_DAYS_PER_MONTH = 22  # Assuming 22 working days in a month
    MONTHLY_LIMIT_mSv = OCCUPATIONAL_LIMITS["Monthly dose Limit to Worker"] # Monthly regulatory limit (20 mSv/year → 1.67 mSv/month)

    # Convert daily exposure from microSv to mSv
    daily_exposure_mSv = daily_exposure_microSv / 1000  # 1 mSv = 1000 µSv
    # Calculate Monthly Exposure
    monthly_exposure_mSv = daily_exposure_mSv * WORK_DAYS_PER_MONTH
    # Provide safety advice based on exposure levels
    advice = f"Estimated Monthly Dose: {monthly_exposure_mSv:.3f} mSv\n"
    if monthly_exposure_mSv < MONTHLY_LIMIT_mSv:
        advice += "✅ Exposure is within the safe limits. Continue monitoring and follow ALARA principles."
    elif monthly_exposure_mSv < 2 * MONTHLY_LIMIT_mSv:
        advice += "⚠️ Exposure is approaching the limit. Reduce unnecessary exposure, optimize shielding, and monitor closely."
    else:
        advice += "🚨 Exposure exceeds safe limits! Immediate review required. Restrict exposure and implement strict radiation safety measures."

    return advice
# Tool7-Predicted Yield Tc-99m
@tool
def predict_tc99m_yield(arrival_date, initial_activity):
    """
    Predicts the daily yield of a Tc-99m generator for the next 7 days.
    Parameters:
    arrival_date (str): Date when the generator arrives (format: "DD-MM-YYYY").
    initial_activity (float): Initial activity of Mo-99 in mCi.
    Returns:
    dict: Dictionary with dates as keys and predicted yields as values.
    """
    # Constants
    #half_life_Mo99 = 66  # Mo-99 half-life in hours
    half_life_Mo99=RADIOACTIVE_NUCLIDES["Molybdenum (MO-99)"]*24
    #print(f"half life ofMo-99{half_life_Mo99}")
    decay_constant = math.log(2) / half_life_Mo99  # Decay constant
    extraction_efficiency = 0.87  # Typical Tc-99m extraction efficiency
    
    # Convert string date to datetime object
    arrival_datetime = datetime.strptime(arrival_date, "%d-%m-%Y")
    
    # Predict yield for the next 7 days
    predicted_yields = {}
    
    for day in range(1, 8):  # Next 7 days
        current_date = arrival_datetime + timedelta(days=day)
        time_elapsed = day * 24  # Convert days to hours
        remaining_activity = initial_activity * math.exp(-decay_constant * time_elapsed)
        tc99m_yield = remaining_activity * extraction_efficiency  # Apply efficiency
        predicted_yields[current_date.strftime("%d-%m-%Y")] = round(tc99m_yield, 2)
    
    return predicted_yields
###TOOL8NM-SCAN PROTOCOL as per SNMMI
@tool
def nm_test_protocol(test_name, weight=None, height=None, age=None):
    """
    Function to return the nuclear medicine test protocol based on user query.
    
    Parameters:
    - test_name (str): Name of the NM test
    - weight (float): Patient weight in kg (for pediatric cases)
    - height (float): Patient height in cm (optional, not used for dosing)
    - age (int): Patient age in years (to determine adult vs pediatric dose)
    
    Returns:
    - A formatted string with test details.
    """

    # Database of NM test protocols
    nm_tests = {
        "bone scan": {
            "radiopharmaceutical": "99mTc-MDP/HDP",
            "dose_adult": "10–25 mCi (370–925 MBq)",
            "dose_pediatric": lambda w: f"{round(min(0.3 * w, 25), 2)} mCi ({round(min(11.1 * w, 925), 2)} MBq)",
            "imaging_time": "2–4 hrs",
            "preparation": "Hydrate well",
            "max_ped_dose": "25 mCi"
        },
        "mag3 renal scan": {
            "radiopharmaceutical": "99mTc-MAG3",
            "dose_adult": "3–10 mCi (111–370 MBq)",
            "dose_pediatric": lambda w: f"{round(min(0.1 * w, 10), 2)} mCi ({round(min(3.7 * w, 370), 2)} MBq)",
            "imaging_time": "Immediate",
            "preparation": "Hydrate well",
            "max_ped_dose": "10 mCi"
        },
        "dtpa renal scan": {
            "radiopharmaceutical": "99mTc-DTPA",
            "dose_adult": "3–10 mCi (111–370 MBq)",
            "dose_pediatric": lambda w: f"{round(min(0.2 * w, 10), 2)} mCi ({round(min(7.4 * w, 370), 2)} MBq)",
            "imaging_time": "Immediate",
            "preparation": "Hydrate well",
            "max_ped_dose": "10 mCi"
        },
        "dmsa renal scan": {
            "radiopharmaceutical": "99mTc-DMSA",
            "dose_adult": "1–5 mCi (37–185 MBq)",
            "dose_pediatric": lambda w: f"{round(min(0.3 * w, 5), 2)} mCi ({round(min(11.1 * w, 185), 2)} MBq)",
            "imaging_time": "2–4 hrs",
            "preparation": "None",
            "max_ped_dose": "5 mCi"
        },
        "hida scan": {
            "radiopharmaceutical": "99mTc-DISIDA/MeBrofenin",
            "dose_adult": "3–8 mCi (111–296 MBq)",
            "dose_pediatric": lambda w: f"{round(min(0.1 * w, 8), 2)} mCi ({round(min(3.7 * w, 296), 2)} MBq)",
            "imaging_time": "Immediate",
            "preparation": "NPO 4–6 hrs",
            "max_ped_dose": "8 mCi"
        },
        "cardiac MIBI scan": {
            "radiopharmaceutical": "99mTc-MIBI/Tetrofosmin",
            "dose_adult": "8–36 mCi (296–1332 MBq)",
            "dose_pediatric": lambda w: f"{round(min(0.3 * w, 36), 2)} mCi ({round(min(11.1 * w, 1332), 2)} MBq)",
            "imaging_time": "15–60 min",
            "preparation": "NPO 4–6 hrs, Avoid caffeine",
            "max_ped_dose": "36 mCi"
        }
    }

    # Normalize the test name to lowercase for matching
    test_name = test_name.lower()

    # Check if the test exists
    if test_name not in nm_tests:
        return "❌ Test not found. Please enter a valid NM test name."

    # Get test details
    test_details = nm_tests[test_name]

    # Determine dose based on age
    if age is None or age >= 18:
        dose_info = f"**Dose (Adult):** {test_details['dose_adult']}"
    elif weight is not None:
        dose_info = f"**Dose (Pediatric - Weight {weight} kg):** {test_details['dose_pediatric'](weight)} (Max: {test_details['max_ped_dose']})"
    else:
        dose_info = "**Pediatric dose requires weight input.**"

    # Format output
    result = f"""
    🔬**Nuclear Medicine Test Protocol at AEMCK: {test_name.title()}**  
    ______As per SNMMI
    - **Radiopharmaceutical:** {test_details['radiopharmaceutical']}
    {dose_info}
    - **Imaging Time:** {test_details['imaging_time']}
    - **Patient Preparation:** {test_details['preparation']}
    """

    return result.strip()

# Example Usage
#print(nm_test_protocol("Bone Scan", weight=15, age=5))
#print(nm_test_protocol("Cardiac MIBI Scan", age=25))
#print(nm_test_protocol("HIDA Scan", weight=30, age=10))


#Curent activity Tool9
@tool
def calculate_current_activity(source_name):
    """
    Calculates the current activity of a radioactive source based on the decay formula.
    Args:
        source_name (str): Name of the isotope (e.g., "Cs-137", "Co-60").
    Returns:
        float: Current activity in MBq.
    """
    if source_name not in HALF_LIFE or source_name not in SOURCE_PURCHASE:
        return "Unknown Source"

    # Get today's date and calculate decay
    today = datetime.today()
    purchase_date = datetime.strptime(SOURCE_PURCHASE[source_name], "%Y-%m-%d")
    days_elapsed = (today - purchase_date).days
    
    # Decay formula: A = A0 * (1/2)^(t/T)
    A0 = INITIAL_ACTIVITY[source_name]
    T = HALF_LIFE[source_name]
    A = A0 * math.pow(0.5, days_elapsed / T)

    return round(A, 2)  # Return current activity in MBq


#For QC-TESTTOOL#10


@tool
def get_qc_test_details(test_name):
    """
    Retrieves QC test details of DoseCalibrator CRC-25R, including frequency, acceptance values, instructions, and good practices."
     
    Args:
        test_name (str): The name of the QC test (e.g., "Accuracy", "Constancy Test", "Peak Positioning", "Energy Resolution,").
    Returns:
        dict: A dictionary containing test details or an error message if the test is invalid.
    Example Usage:
        >>> get_qc_test_details("Peak positioning")
    """
    
    qc_tests = {
        "Introduction":["AEMCK (Atomic Energy Medical Centre Karachi) has one Dose Calibrator",
        "CRC-25R and three Gamma Cameras for Diagnosis and Therapies.",
        "Daily QC includes Peak Position for Gamma cam, Energy Resolution, Background Test, and Image Quality Test.",
        "Monthly QC includes Centre of Rotation (COR) and Intrinsic Uniformity Test."],
        
        "Chamber Voltage": {
            "Frequency": "Daily",
            "Acceptance Value": "±1%",
            "Instructions": [
                "Turn on the dose calibrator and let it warm up.",
                "Check the voltage reading on the display.",
                "If deviation exceeds ±1%, recalibrate the system."
            ],
            "Good Practices": [
                "Ensure a stable power supply.",
                "Perform at the same time daily for consistency."
            ]
        },
        "Accuracy": {
            "Frequency": "Quarterly",
            "Acceptance Value": "±5%",
            "Instructions": [
                "Select the isotope setting (Cs-137, Co-57, Co-60, Ba-133).",
                "Place the radioactive source in the dose calibrator.",
                "Compare the displayed activity with the expected activity.",
                "If deviation is greater than ±5%, recalibrate."
            ],
            "Good Practices": [
                "Use standard sources: Co-57, Co-60, Ba-133, Cs-137.",
                "Perform test before patient doses to avoid delays."
            ],
            "Sources Used": {
                "Cs-137": calculate_current_activity("Cs-137"),
                "Co-60": calculate_current_activity("Co-60"),
                "Co-57": calculate_current_activity("Co-57"),
                "Ba-133": calculate_current_activity("Ba-133"),
            }
        },
        "Constancy Test": {
            "Frequency": "Daily",
            "Acceptance Value": "±5% of reference value",
            "Instructions": [
                "Use Cs-137 source for constancy checks.",
                "Measure the activity and compare with previous readings.",
                "Ensure the variation is within ±5%."
            ],
            "Good Practices": [
                "Perform under consistent environmental conditions.",
                "If deviation is high, check for contamination or drift."
            ]
        },
        "Zero Adjustment": {
            "Frequency": "Daily",
            "Acceptance Value": "±0.3 mV",
            "Good Practices": [
                "Ensure no external radiation sources nearby.",
                "Check before starting daily calibration."
            ]
        },
        "Background": {
            "Frequency": "Daily",
            "Acceptance Value": "±20% of current mean (<530 μCi)",
            "Good Practices": [
                "Check for contamination in the measurement chamber.",
                "Ensure no residual radiation is affecting readings."
            ]
        },
        "Data Check": {
            "Frequency": "Daily",
            "Acceptance Value": "Ensure correct readings",
            "Good Practices": [
                "Verify readings against known reference sources.",
                "Report and recalibrate if discrepancies are found."
            ]
        },
        
        "Contamination": {
            "Frequency": "Weekly",
            "Acceptance Value": "<3 μCi (0.12 MBq)",
            "Good Practices": [
                "Use wipe tests to check for contamination.",
                "Regularly clean the dose calibrator to prevent false readings."
            ]
        },
        
        "Linearity": {
            "Frequency": "Quarterly",
            "Acceptance Value": "5% of the expected value",
            "Good Practices": [
                "Use multiple activity levels to check for linearity.",
                "Ensure readings remain consistent over different dose levels."
            ]
        },
        "Geometry": {
            "Geometry QC Test": {
            "Frequency": "Acceptance Test (Once during installation or after major repairs or Annually)",
            "Acceptance Value": "Should remain within ±5% of expected value",
            "Instructions": [
                "Ensure the dose calibrator is properly set up and warmed up.",
                "Select the appropriate isotope setting for the test (e.g., Tc-99m).",
                "Prepare a series of different volume samples like 3ml syringe and 20ml vial using the same activity concentration.",
                "Measure the activity of each sample in the dose calibrator.",
                "Compare the readings across different volumes to assess consistency.",
                "If variation exceeds ±5%, apply correction factors or recalibrate the system."
            ],
            "Good Practices": [
                "Use a well-mixed radiopharmaceutical solution to maintain uniform activity concentration.",
                "Ensure consistent sample positioning inside the dose calibrator.",
                "Avoid air bubbles in syringes or vials as they can affect readings.",
                "Perform test with and without a syringe or vial to check geometry effects.",
                "Document results for future reference and consistency checks."
            ]
        },    
    }
    }
    #return qc_tests.get(test_name, {"Error": "Invalid QC Test Name"})
    return qc_tests.get(test_name, {"Error": "Invalid test name. Please choose a valid QC test."})
#Tool 11 for gamma qc
@tool
def get_gammaqc_test_details(test_name):
    """
    Retrieves QC test details of Gamma Camera, including Peak positioning, Energy Resolution etc.
    
    Args:
        test_name (str): The name of the QC test (e.g, "Peak Positioning", "Energy Resolution,").
    Returns:
        dict: A dictionary containing test details or an error message if the test is invalid.
    Example Usage:
        >>> get_qc_test_details("Peak positioning")
    """
    
    qc_tests = {
        "Introduction":["AEMCK (Atomic Energy Medical Centre Karachi) has three Gamma Cameras for Diagnosis and Therapies.",
        "Daily QC includes Peak Position , Energy Resolution, Background Test, and Image Quality Test.",
        "Monthly QC includes Centre of Rotation (COR) and Intrinsic Uniformity Test."],
        
        "Peak Position": {
            "Frequency": "Daily",
            "Acceptance Value": "Tc-99m: 140 ± 3 keV, Co-57: 122 ± 3 keV",
            "Instructions": [
                "Ensure proper calibration of the Gamma camera.",
                "Place the Tc-99m or Co-57 source appropriately.",
                "Verify that the peak position falls within the acceptable range."
            ],
            "Good Practices": [
                "Always use a well-calibrated source for Gamma cam.",
                "Check for any sudden peak shifts indicating detector issues."
            ]
        },
        "Energy Resolution": {
            "Frequency": "Daily",
            "Acceptance Value": "Tc-99m: < 11.0%, Co-57: < 12.0%",
            "Instructions": [
                "Acquire a spectrum using the Gamma camera.",
                "Calculate the full-width at half maximum (FWHM).",
                "Ensure that the energy resolution falls within the acceptance criteria."
            ],
            "Good Practices": [
                "Use a high-quality energy calibration source.",
                "Avoid fluctuations in environmental conditions."
            ]
        },
        "Intrinsic Uniformity": {
            "Frequency": "Monthly",
            "Acceptance Value": "CFOV Integral Uniformity < 5%",
            "Instructions": [
                "Perform an intrinsic uniformity scan using Tc-99m for Gamma Cam",
                "Analyze the image uniformity using processing software.",
                "Ensure that uniformity deviations remain within the threshold."
            ],
            "Good Practices": [
                "Use a uniform flood source.",
                "Regularly check for detector malfunctions."
            ]
        },
        "Centre of Rotation (COR)": {
            "Frequency": "Monthly",
            "Instructions": [
                "Use a point source of Tc-99m at the center of rotation for Gamma cam.",
                "Acquire multiple views and analyze COR deviation.",
                "Ensure that misalignment does not exceed acceptable limits."
            ],
            "Good Practices": [
                "Perform COR analysis after maintenance or detector adjustments.",
                "Verify consistency over multiple acquisitions."
            ]
        }               
               
    }
    
    #return qc_tests.get(test_name, {"Error": "Invalid QC Test Name"})
    return qc_tests.get(test_name, {"Error": "Invalid test name. Please choose a valid QC test."})

# Example Usage
#if __name__ == "__main__":
#    test_name = input("Enter the QC test name: ")
#    result = get_qc_test_details(test_name)
# #   print(result)



def random_prompt():
    return random.choice([
        "Convert 1Gy into rem.",
        "Tell me the half life of Iodine I-131.",
        "A patient with 50mci administered on 27-2-2025 after 1 day he has neckdose 25USv with good SEF, can I release patient?.",
        "List me all radiation dose limits for workers.",
        "Tell me the radiation dose limits for General Public as per PNRA.",
        "What is the  predicted yield for next seven days of 600mci of Tc-99m generator which received on 10-2-2025.",
        "A cobalt-57 (Co-57) source of 10mCi,what will be the remaining activity after 100days?",
        "If a worker got 2mSv daily in working hours, what will be the advice of RPO in ALARA context.",
        "What is the dose protocol of HIDA scan for Pedriatic patient of 7kg weight and 3 years age.",
        "Tell me the good practices of Accuracy Qc test of Dose Callibrator.",
        "Geometry Qc test for Dose Callibrator instructions",


        
    ])
tools=[get_gammaqc_test_details,get_qc_test_details,calculate_current_activity,nm_test_protocol,radiation_protection_advice,predict_tc99m_yield,print_exposure_limits,patient_release_decision,unit_conversion_tool,radioactive_decay_tool]

#agent=initialize_agent(tools,llm,agent=AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION)
agent = initialize_agent(
    tools=tools,
    llm=llm,
    agent=AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION,
    verbose=True,
    max_iterations=3,                # Limit steps to prevent slowness(addnew)
    handle_parsing_errors=True,
    early_stopping_method="generate"
)
#response=agent.invoke({"input":" Neck dose of iodine treated patient is 20 microSv he is staying 24 hrs and his sef is BAD.  "})
#print(f"\n{response}\n")
# Define the function that handles user input
def process_input(user_input):
    # Assuming agent.invoke(user_input) is your processing logic.You should replace this with the actual call to your agentFor example: response = agent.invoke(user_input)
    
    # For now, we are just simulating the response with a simple message
    response = agent.invoke(user_input) 
    return response


# Define the correct password
#CORRECT_PASSWORD =os.getenv("app_password")
#print(f"SECRET_KEY: {CORRECT_PASSWORD}")

# Function to check password and return output
def authenticate(password):
    if password == CORRECT_PASSWORD:
        success_message =" ✅ **Access Granted!"
        return success_message, gr.Textbox(visible=True), gr.Button(visible=True)
        
    else:
        failure_message =  " ❌ **Access Denied!Incorrect Password"
        return failure_message, gr.Textbox(visible=False), gr.Button(visible=False)

custom_css = """
<style>
    .custom-input {
        background-color: black; 
        color: white; 
        font-size: 16px; 
        border-radius: 10px;
        padding: 10px;
    }
    
    .custom-output {
        background-color: #222; 
        color: cyan; 
        font-size: 16px; 
        border-radius: 10px;
        padding: 10px;
        alignment(center);
    }
    
    .custom-button {
        background-color: blue; 
        color: white; 
        font-size: 18px; 
        border-radius: 8px;
        padding: 10px 20px;
        font-weight: bold;
    }
    .custom-button:hover {
        background-color: darkblue;
    }
    .custom-json {
        font-size: 18px !important;  /* Increase JSON output text size */
    }
</style>
"""


# Gradio UI
with gr.Blocks() as ui:
    gr.Markdown(custom_css)

    gr.HTML("""
    <style>
        button.svelte-1ipelgc { 
        display: none !important;
        }
    </style>
    """)
    gr.HTML("""
        <style>
        .custom-title {
        text-align: center;
        color: blue;
        font-size: 32px;
        font-weight: bold;
        }
        .custom-sub {
        text-align: center;
        color: gray;
        font-size: 16px;
        font-weight: bold;
        }
        .custom-page {
        text-align: center;
        color: green;
        font-size: 12px;
        
        }
        .custom-footer {
        text-align: right;
        color: orange;
        font-size: 12px;
        
        }
        </style>
    <h1 class="custom-title"></h1>
    <h2 class="custom-sub"></h2>
    """)

    #<p  class="custom-page">An intelligent system for Radiation unit conversions, Activity and decay calculations, the management of Iodine-treated patient releases, Predicted yield of Tc-99m,ALARA advice to exposed worker, also the St.INJECTION PROTOCOLS for NM Scans, Ensures compliance with radiation protection regulations and QC standards for Modalities, integrating all relevant safety limits and guidelines with Security 🔒</p>

    # Inject inline CSS using Markdown (works properly in Gradio)
    
    gr.HTML("""
    <div style="text-align: center;">
        <span style="font-size: 24px; font-weight: bold; color: darkblue;">MEDICAL PHYSICS-NEXUS</span> 
        <span style="font-size: 16px; color: gray;">(PART-I)</span><br>
        <span style="font-size: 16px; color: black;">Powered with Generative AI</span><br>
        <span style="font-size: 10px; color: green;">
            An intelligent system for Radiation unit conversions, Activity and decay calculations, 
            the management of Iodine-treated patient releases, Predicted yield of Tc-99m, 
            ALARA advises exposed workers and the St. INJECTION PROTOCOLS for NM Scans. 
            Ensures compliance with radiation protection regulations and QC standards for Modalities, 
            integrating all relevant safety limits and guidelines with Security 🔒.
        </span>
    </div>
    """)




    # Display title and description
    #gr.Markdown("<h1 style='text-align:center ;margin-bottom:0.0px;margin-top:0.5px; color: blue;'>MedicalPhysics-Nexus</h1>",elem_classes="custom-output")

    #gr.Markdown("<h4 style='margin-top:0.0;margin-bottom:5px;text-align: center; color: Black;'>Powered with Generative AI</h4>")

    #gr.Markdown("<p style='text-align: center; color: green;'>An intelligent system for Radiation units conversions, Activity and decay calculations, the management of Iodine-treated patient releases, Predicted yield of Tc-99m,ALARA advice to exposed worker, also the St.INJECTION PROTOCOLS for NM Scans, Ensures compliance with radiation protection regulations and QC standards for Modalities, integrating all relevant safety limits and guidelines with Security 🔒.</p>")
    
    # Password Input
    # User input and output text
    password_input = gr.Textbox(label="Password Required", type="password", placeholder="Enter your password")
    submit_button1=gr.Button("authentication")
    auth_message = gr.Textbox(label="Status", interactive=False)
    
    # Initially hidden prompt input and submit button
    #prompt_input = gr.Textbox(label="Enter your prompt", visible=False)
    user_input = gr.Textbox(value=random_prompt,label="Enter your Prompt",lines=3,max_lines=5,elem_classes="custom-input")
    submit_button = gr.Button("Submit", visible=False)
    #response_output = gr.Textbox(label="AI Response", interactive=False)
    response_output=gr.JSON(label="formatted response",elem_classes="custom-json")
    #output_text = gr.JSON(label="Formatted Response\n")

    # Authenticate and reveal prompt field
   # password_input.submit(authenticate, inputs=password_input, outputs=[auth_message, user_input, submit_button])
    submit_button1.click(
        authenticate,
        inputs=password_input,
        outputs=[auth_message,user_input,submit_button]
    )
    # Process the prompt after authentication
    submit_button.click(process_input, inputs=user_input, outputs=response_output)
    # User input and output text
    #user_input = gr.Textbox(value=random_prompt,label="Enter your Prompt",lines=3,max_lines=5)
    #password_input = gr.Textbox(label="Password Required", type="password", placeholder="Enter your password")
    #output_text = gr.JSON(label="Formatted Response\n")
    
    #output_text = gr.Textbox(label="Response", interactive=False)
    # Submit button
    #submit_button = gr.Button("Submit")
    
    # Define button interaction
    #submit_button.click(fn=process_input, inputs=user_input, outputs=output_text)
    #submit_button.click(authenticate, inputs=password_input, outputs=output_text)




    # Footer text
    #gr.Markdown("<h3 style='text-align: right;font-size: 14.0px ; color: blue;'>Medical Physics Division,Atomic Energy Medical Centre Karachi.</h3>")
   # Footer using gr.HTML
   
    # gr.HTML("""
    #<div style="text-align: right;">
    #<span style="font-size:14px color: blue;"> 2025 Medical Physics Division, Atomic Energy Medical Centre.</span>
    #""")
   # </div>
   # """)
    
    
    gr.HTML("""
        <footer style="
        position: relative;
        bottom: 0;
        width: 100%;
        text-align: right;
        padding: 10px;
        background-color: #f8f9fa;
        color: #333;
        font-size: 12px;
    ">
    © 2025 Medical Physics Division, Atomic Energy Medical Centre.
    </footer>
        """)


# Launch the Gradio app with public URL
#ui.launch()
#ui.launch(share=True, show_api=False)  # Ensures no external sharing & API buttons
ui.launch(show_api=False)
#ui.launch(server_name="0.0.0.0", server_port=7860, show_api=False)
#ui.launch(server_name="0.0.0.0", server_port=7860, show_api=False)