Upload stress_gf_xgb.joblib

#9
by OmarOmar91 - opened
This view is limited to 50 files because it contains too many changes. See the raw diff here.
Files changed (50) hide show
  1. .gitattributes +0 -128
  2. app.py +166 -813
  3. {papers → literature_pdfs}/Carbon fiber reinforced cement improved by using silane-treated carbon fibers.pdf +0 -0
  4. {papers → literature_pdfs}/Silane-treated carbon fiber for reinforcing cement.pdf +0 -0
  5. papers/1-s2.0-S095006181732278X-main.pdf +0 -3
  6. papers/1-s2.0-S0950061820330786-main.pdf +0 -3
  7. papers/1-s2.0-S1359836816316882-main.pdf +0 -3
  8. papers/1-s2.0-S2090447920301593-main.pdf +0 -3
  9. papers/2011-EffectofSpecimenSizeonStaticStrengthandDIFofHSCfromSHPBTest.pdf +0 -3
  10. papers/Capacitance-based stress self-sensing in cement paste without requiring any admixture.pdf +0 -3
  11. papers/Capacitive compressive stress self-sensing behavior of cement mortar and its dependence on the thickness.pdf +0 -3
  12. papers/Development of self-sensing ultra-high-performance concrete using hybrid carbon black and carbon nanofibers.pdf +0 -3
  13. papers/Development of sensing concrete Principles, properties and its applications.pdf +0 -3
  14. papers/EVALUA~1.PDF +0 -3
  15. papers/Effect of silane treatment on microstructure of sisal fibers.pdf +0 -3
  16. papers/Graphene family (GFMs), carbon nanotubes (CNTs) and carbon black (CB) on smart materials for civil construction.pdf +0 -3
  17. papers/Influence of the structures of polycarboxylate superplasticizer on its performance in cement-based materials-A review.pdf +0 -3
  18. papers/Investigating the synergistic effects of carbon fiber and silica fume on concrete strength and eco-efficiency.pdf +0 -3
  19. papers/Investigation of 3D Printed Self-Sensing UHPC Composites Using Graphite and Hybrid Carbon Microfibers.pdf +0 -3
  20. papers/Ozone treatment of carbon fiber for reinforcing cement.pdf +0 -3
  21. papers/PIEZOE~1.PDF +0 -3
  22. papers/Performance of silica fume slurry treated recycled aggregate concrete reinforced with carbon fibers.pdf +0 -3
  23. papers/Piezopermittivity for capacitance-based strain stress sensing.pdf +0 -3
  24. papers/Review Improving cement-based materials by using silica fume.pdf +0 -3
  25. papers/Revolutionizing infrastructure The evolving landscape of electricity-based multifunctional concrete from concept to practice.pdf +0 -3
  26. papers/S1-An-experimental-study-of-self-sensing-concrete-enhanced_2020_Construction-an.pdf +0 -3
  27. papers/S10-Enhancing-self-stress-sensing-ability-of-smart-ultra-high_2021_Journal-of-Bu.pdf +0 -3
  28. papers/S100-C~1.PDF +0 -3
  29. papers/S11-Environment-Friendly, Self-Sensing Concrete Blended with Byproduct Wastes.pdf +0 -3
  30. papers/S12-Hybrid-effects-of-steel-fiber-and-carbon-nanotube-on-s_2018_Construction-and.pdf +0 -3
  31. papers/S13-Increasing-self-sensing-capability-of-carbon-nanotubes-c_2020_Construction-a.pdf +0 -3
  32. papers/S14-Influence-of-carbon-nanofiber-content-and-sodium-chloride-_2019_Case-Studies.pdf +0 -3
  33. papers/S15-Influence-of-water-ingress-on-the-electrical-properties-_2021_Journal-of-Bui.pdf +0 -3
  34. papers/S16-Investigations-on-scalable-fabrication-procedures-for-sel_2016_Cement-and-Co.pdf +0 -3
  35. papers/S17-Cross tension and compression loading and large-scale testing of strain and damage sensing smart concrete.pdf +0 -3
  36. papers/S18-Nano graphite platelets-enabled piezoresistive cementitious composites for structural health monitoring.pdf +0 -3
  37. papers/S19-Self-sensing-piezoresistive-cement-composite-loaded_2017_Cement-and-Concrete.pdf +0 -3
  38. papers/S2-Characterization-of-smart-brass-fiber-reinforced-co_2020_Construction-and-Bu.pdf +0 -3
  39. papers/S20-IN~1.PDF +0 -3
  40. papers/S21-Mechanical, electrical and self-sensing properties of cementitious mortars containing short carbon fibers.pdf +0 -3
  41. papers/S22-Improved strain sensing properties of cement-based sensors through enhanced carbon nanotube dispersion.pdf +0 -3
  42. papers/S23-Increasing self-sensing capability of carbon nanotubes cement-based materials by simultaneous addition of Ni nanofibers.pdf +0 -3
  43. papers/S24-Multifunctional-self-sensing-and-ductile-cementit_2019_Cement-and-Concrete-R.pdf +0 -3
  44. papers/S25-Self-sensing-capability-of-ultra-high-performance-concr_2018_Sensors-and-Act.pdf +0 -3
  45. papers/S26-TE~1.PDF +0 -3
  46. papers/S27-Effect of aspect ratio on strain sensing capacity of carbon fiber reinforced cement composites.pdf +0 -3
  47. papers/S28-Smart Graphite–Cement Composites with Low Percolation Threshold.pdf +0 -3
  48. papers/S29-Hybrid Carbon Microfibers-Graphite Fillers for Piezoresistive Cementitious Composites.pdf +0 -3
  49. papers/S3-Effect of characteristics of assembly unit of CNTNCB composite fillers on properties of smart cement-based materials.pdf +0 -3
  50. papers/S30-Smart Graphite–Cement Composite for Roadway-Integrated Weigh-In-Motion Sensing.pdf +0 -3
.gitattributes CHANGED
@@ -290,131 +290,3 @@ literature_pdfs/Self-sensing[[:space:]]performance[[:space:]]of[[:space:]]cement
290
  literature_pdfs/Self‐Sensing[[:space:]]Cementitious[[:space:]]Composites[[:space:]]with[[:space:]]Hierarchical[[:space:]]Carbon[[:space:]]Fiber‐Carbon[[:space:]]Nanotube[[:space:]]Composite[[:space:]]Fillers.pdf filter=lfs diff=lfs merge=lfs -text
291
  literature_pdfs/Silane[[:space:]]treatment[[:space:]]of[[:space:]]bagasse[[:space:]]fiber[[:space:]]for[[:space:]]reinforcement[[:space:]]of[[:space:]]cementitious[[:space:]]composites.pdf filter=lfs diff=lfs merge=lfs -text
292
  literature_pdfs/The[[:space:]]effect[[:space:]]of[[:space:]]silane[[:space:]]surface[[:space:]]treatment[[:space:]]on[[:space:]]the[[:space:]]mechanical[[:space:]]properties[[:space:]]of[[:space:]]UHPFRC.pdf filter=lfs diff=lfs merge=lfs -text
293
- papers/1-s2.0-S095006181732278X-main.pdf filter=lfs diff=lfs merge=lfs -text
294
- papers/1-s2.0-S0950061820330786-main.pdf filter=lfs diff=lfs merge=lfs -text
295
- papers/1-s2.0-S1359836816316882-main.pdf filter=lfs diff=lfs merge=lfs -text
296
- papers/1-s2.0-S2090447920301593-main.pdf filter=lfs diff=lfs merge=lfs -text
297
- papers/2011-EffectofSpecimenSizeonStaticStrengthandDIFofHSCfromSHPBTest.pdf filter=lfs diff=lfs merge=lfs -text
298
- papers/document.pdf filter=lfs diff=lfs merge=lfs -text
299
- papers/Capacitance-based[[:space:]]stress[[:space:]]self-sensing[[:space:]]in[[:space:]]cement[[:space:]]paste[[:space:]]without[[:space:]]requiring[[:space:]]any[[:space:]]admixture.pdf filter=lfs diff=lfs merge=lfs -text
300
- papers/Capacitive[[:space:]]compressive[[:space:]]stress[[:space:]]self-sensing[[:space:]]behavior[[:space:]]of[[:space:]]cement[[:space:]]mortar[[:space:]]and[[:space:]]its[[:space:]]dependence[[:space:]]on[[:space:]]the[[:space:]]thickness.pdf filter=lfs diff=lfs merge=lfs -text
301
- papers/Development[[:space:]]of[[:space:]]self-sensing[[:space:]]ultra-high-performance[[:space:]]concrete[[:space:]]using[[:space:]]hybrid[[:space:]]carbon[[:space:]]black[[:space:]]and[[:space:]]carbon[[:space:]]nanofibers.pdf filter=lfs diff=lfs merge=lfs -text
302
- papers/Development[[:space:]]of[[:space:]]sensing[[:space:]]concrete[[:space:]]Principles,[[:space:]]properties[[:space:]]and[[:space:]]its[[:space:]]applications.pdf filter=lfs diff=lfs merge=lfs -text
303
- papers/Effect[[:space:]]of[[:space:]]silane[[:space:]]treatment[[:space:]]on[[:space:]]microstructure[[:space:]]of[[:space:]]sisal[[:space:]]fibers.pdf filter=lfs diff=lfs merge=lfs -text
304
- papers/EVALUA~1.PDF filter=lfs diff=lfs merge=lfs -text
305
- papers/Graphene[[:space:]]family[[:space:]](GFMs),[[:space:]]carbon[[:space:]]nanotubes[[:space:]](CNTs)[[:space:]]and[[:space:]]carbon[[:space:]]black[[:space:]](CB)[[:space:]]on[[:space:]]smart[[:space:]]materials[[:space:]]for[[:space:]]civil[[:space:]]construction.pdf filter=lfs diff=lfs merge=lfs -text
306
- papers/Influence[[:space:]]of[[:space:]]the[[:space:]]structures[[:space:]]of[[:space:]]polycarboxylate[[:space:]]superplasticizer[[:space:]]on[[:space:]]its[[:space:]]performance[[:space:]]in[[:space:]]cement-based[[:space:]]materials-A[[:space:]]review.pdf filter=lfs diff=lfs merge=lfs -text
307
- papers/Investigating[[:space:]]the[[:space:]]synergistic[[:space:]]effects[[:space:]]of[[:space:]]carbon[[:space:]]fiber[[:space:]]and[[:space:]]silica[[:space:]]fume[[:space:]]on[[:space:]]concrete[[:space:]]strength[[:space:]]and[[:space:]]eco-efficiency.pdf filter=lfs diff=lfs merge=lfs -text
308
- papers/Investigation[[:space:]]of[[:space:]]3D[[:space:]]Printed[[:space:]]Self-Sensing[[:space:]]UHPC[[:space:]]Composites[[:space:]]Using[[:space:]]Graphite[[:space:]]and[[:space:]]Hybrid[[:space:]]Carbon[[:space:]]Microfibers.pdf filter=lfs diff=lfs merge=lfs -text
309
- papers/Ozone[[:space:]]treatment[[:space:]]of[[:space:]]carbon[[:space:]]fiber[[:space:]]for[[:space:]]reinforcing[[:space:]]cement.pdf filter=lfs diff=lfs merge=lfs -text
310
- papers/Performance[[:space:]]of[[:space:]]silica[[:space:]]fume[[:space:]]slurry[[:space:]]treated[[:space:]]recycled[[:space:]]aggregate[[:space:]]concrete[[:space:]]reinforced[[:space:]]with[[:space:]]carbon[[:space:]]fibers.pdf filter=lfs diff=lfs merge=lfs -text
311
- papers/PIEZOE~1.PDF filter=lfs diff=lfs merge=lfs -text
312
- papers/Piezopermittivity[[:space:]]for[[:space:]]capacitance-based[[:space:]]strain[[:space:]]stress[[:space:]]sensing.pdf filter=lfs diff=lfs merge=lfs -text
313
- papers/Review[[:space:]]Improving[[:space:]]cement-based[[:space:]]materials[[:space:]]by[[:space:]]using[[:space:]]silica[[:space:]]fume.pdf filter=lfs diff=lfs merge=lfs -text
314
- papers/Revolutionizing[[:space:]]infrastructure[[:space:]]The[[:space:]]evolving[[:space:]]landscape[[:space:]]of[[:space:]]electricity-based[[:space:]]multifunctional[[:space:]]concrete[[:space:]]from[[:space:]]concept[[:space:]]to[[:space:]]practice.pdf filter=lfs diff=lfs merge=lfs -text
315
- papers/S1-An-experimental-study-of-self-sensing-concrete-enhanced_2020_Construction-an.pdf filter=lfs diff=lfs merge=lfs -text
316
- papers/S10-Enhancing-self-stress-sensing-ability-of-smart-ultra-high_2021_Journal-of-Bu.pdf filter=lfs diff=lfs merge=lfs -text
317
- papers/S100-C~1.PDF filter=lfs diff=lfs merge=lfs -text
318
- papers/S11-Environment-Friendly,[[:space:]]Self-Sensing[[:space:]]Concrete[[:space:]]Blended[[:space:]]with[[:space:]]Byproduct[[:space:]]Wastes.pdf filter=lfs diff=lfs merge=lfs -text
319
- papers/S12-Hybrid-effects-of-steel-fiber-and-carbon-nanotube-on-s_2018_Construction-and.pdf filter=lfs diff=lfs merge=lfs -text
320
- papers/S13-Increasing-self-sensing-capability-of-carbon-nanotubes-c_2020_Construction-a.pdf filter=lfs diff=lfs merge=lfs -text
321
- papers/S14-Influence-of-carbon-nanofiber-content-and-sodium-chloride-_2019_Case-Studies.pdf filter=lfs diff=lfs merge=lfs -text
322
- papers/S15-Influence-of-water-ingress-on-the-electrical-properties-_2021_Journal-of-Bui.pdf filter=lfs diff=lfs merge=lfs -text
323
- papers/S16-Investigations-on-scalable-fabrication-procedures-for-sel_2016_Cement-and-Co.pdf filter=lfs diff=lfs merge=lfs -text
324
- papers/S17-Cross[[:space:]]tension[[:space:]]and[[:space:]]compression[[:space:]]loading[[:space:]]and[[:space:]]large-scale[[:space:]]testing[[:space:]]of[[:space:]]strain[[:space:]]and[[:space:]]damage[[:space:]]sensing[[:space:]]smart[[:space:]]concrete.pdf filter=lfs diff=lfs merge=lfs -text
325
- papers/S18-Nano[[:space:]]graphite[[:space:]]platelets-enabled[[:space:]]piezoresistive[[:space:]]cementitious[[:space:]]composites[[:space:]]for[[:space:]]structural[[:space:]]health[[:space:]]monitoring.pdf filter=lfs diff=lfs merge=lfs -text
326
- papers/S19-Self-sensing-piezoresistive-cement-composite-loaded_2017_Cement-and-Concrete.pdf filter=lfs diff=lfs merge=lfs -text
327
- papers/S2-Characterization-of-smart-brass-fiber-reinforced-co_2020_Construction-and-Bu.pdf filter=lfs diff=lfs merge=lfs -text
328
- papers/S20-IN~1.PDF filter=lfs diff=lfs merge=lfs -text
329
- papers/S21-Mechanical,[[:space:]]electrical[[:space:]]and[[:space:]]self-sensing[[:space:]]properties[[:space:]]of[[:space:]]cementitious[[:space:]]mortars[[:space:]]containing[[:space:]]short[[:space:]]carbon[[:space:]]fibers.pdf filter=lfs diff=lfs merge=lfs -text
330
- papers/S22-Improved[[:space:]]strain[[:space:]]sensing[[:space:]]properties[[:space:]]of[[:space:]]cement-based[[:space:]]sensors[[:space:]]through[[:space:]]enhanced[[:space:]]carbon[[:space:]]nanotube[[:space:]]dispersion.pdf filter=lfs diff=lfs merge=lfs -text
331
- papers/S23-Increasing[[:space:]]self-sensing[[:space:]]capability[[:space:]]of[[:space:]]carbon[[:space:]]nanotubes[[:space:]]cement-based[[:space:]]materials[[:space:]]by[[:space:]]simultaneous[[:space:]]addition[[:space:]]of[[:space:]]Ni[[:space:]]nanofibers.pdf filter=lfs diff=lfs merge=lfs -text
332
- papers/S24-Multifunctional-self-sensing-and-ductile-cementit_2019_Cement-and-Concrete-R.pdf filter=lfs diff=lfs merge=lfs -text
333
- papers/S25-Self-sensing-capability-of-ultra-high-performance-concr_2018_Sensors-and-Act.pdf filter=lfs diff=lfs merge=lfs -text
334
- papers/S26-TE~1.PDF filter=lfs diff=lfs merge=lfs -text
335
- papers/S27-Effect[[:space:]]of[[:space:]]aspect[[:space:]]ratio[[:space:]]on[[:space:]]strain[[:space:]]sensing[[:space:]]capacity[[:space:]]of[[:space:]]carbon[[:space:]]fiber[[:space:]]reinforced[[:space:]]cement[[:space:]]composites.pdf filter=lfs diff=lfs merge=lfs -text
336
- papers/S28-Smart[[:space:]]Graphite–Cement[[:space:]]Composites[[:space:]]with[[:space:]]Low[[:space:]]Percolation[[:space:]]Threshold.pdf filter=lfs diff=lfs merge=lfs -text
337
- papers/S29-Hybrid[[:space:]]Carbon[[:space:]]Microfibers-Graphite[[:space:]]Fillers[[:space:]]for[[:space:]]Piezoresistive[[:space:]]Cementitious[[:space:]]Composites.pdf filter=lfs diff=lfs merge=lfs -text
338
- papers/S3-Effect[[:space:]]of[[:space:]]characteristics[[:space:]]of[[:space:]]assembly[[:space:]]unit[[:space:]]of[[:space:]]CNTNCB[[:space:]]composite[[:space:]]fillers[[:space:]]on[[:space:]]properties[[:space:]]of[[:space:]]smart[[:space:]]cement-based[[:space:]]materials.pdf filter=lfs diff=lfs merge=lfs -text
339
- papers/S30-Smart[[:space:]]Graphite–Cement[[:space:]]Composite[[:space:]]for[[:space:]]Roadway-Integrated[[:space:]]Weigh-In-Motion[[:space:]]Sensing.pdf filter=lfs diff=lfs merge=lfs -text
340
- papers/S31-Electrical[[:space:]]and[[:space:]]piezoresistive[[:space:]]properties[[:space:]]of[[:space:]]carbon[[:space:]]nanofiber[[:space:]]cement[[:space:]]mortar[[:space:]]under[[:space:]]different[[:space:]]temperatures[[:space:]]and[[:space:]]water[[:space:]]contents.pdf filter=lfs diff=lfs merge=lfs -text
341
- papers/S32-Self-stress-sensing-smart-concrete-containing-fine-stee_2019_Construction-an.pdf filter=lfs diff=lfs merge=lfs -text
342
- papers/S33-IN~1.PDF filter=lfs diff=lfs merge=lfs -text
343
- papers/S34-Self-sensing-ultra-high-performance-concrete-fo_2021_Sensors-and-Actuators-A.pdf filter=lfs diff=lfs merge=lfs -text
344
- papers/S35-EL~1.PDF filter=lfs diff=lfs merge=lfs -text
345
- papers/S36-Piezoresistivity[[:space:]]enhancement[[:space:]]of[[:space:]]functional[[:space:]]carbon[[:space:]]black[[:space:]]filled[[:space:]]cement-based[[:space:]]sensor[[:space:]]using[[:space:]]polypropylene[[:space:]]fibre.pdf filter=lfs diff=lfs merge=lfs -text
346
- papers/S37-Test[[:space:]]and[[:space:]]Study[[:space:]]on[[:space:]]Electrical[[:space:]]Property[[:space:]]of[[:space:]]Conductive[[:space:]]Concrete.pdf filter=lfs diff=lfs merge=lfs -text
347
- papers/S38[[:space:]]-[[:space:]]Electrical-resistance-based[[:space:]]Sensing[[:space:]]of[[:space:]]Impact[[:space:]][[:space:]]Damage[[:space:]]in[[:space:]]Carbon[[:space:]]Fiber[[:space:]]Reinforced[[:space:]]Cement-based[[:space:]]Materials.pdf filter=lfs diff=lfs merge=lfs -text
348
- papers/S39[[:space:]]-[[:space:]]Electrical[[:space:]]conductivity[[:space:]]of[[:space:]]self-monitoring[[:space:]]CFRC.pdf filter=lfs diff=lfs merge=lfs -text
349
- papers/S4-Effect-of-steel-fiber-and-carbon-black-on-the-self-s_2019_Construction-and-B.pdf filter=lfs diff=lfs merge=lfs -text
350
- papers/S40[[:space:]]-[[:space:]]Resistance[[:space:]]Changes[[:space:]]during[[:space:]]Compression[[:space:]]of[[:space:]]Carbon[[:space:]]Fiber[[:space:]]Cement[[:space:]]COmposites.pdf filter=lfs diff=lfs merge=lfs -text
351
- papers/S41[[:space:]]-[[:space:]]Electrical-resistance-based[[:space:]]damage[[:space:]]self-sensing[[:space:]]in[[:space:]]carbon[[:space:]]fiber[[:space:]]reinforced[[:space:]]cement.pdf filter=lfs diff=lfs merge=lfs -text
352
- papers/S42-SE~1.PDF filter=lfs diff=lfs merge=lfs -text
353
- papers/S43[[:space:]]-[[:space:]]the[[:space:]]100th[[:space:]]anniversary[[:space:]]of[[:space:]]the[[:space:]]four-point[[:space:]]probe[[:space:]]technique[[:space:]]the[[:space:]]role[[:space:]]of[[:space:]]probe[[:space:]]geometries[[:space:]]in[[:space:]]isotropic[[:space:]]andanisotropic[[:space:]]systems.pdf filter=lfs diff=lfs merge=lfs -text
354
- papers/S44-Sensing[[:space:]]performance[[:space:]]of[[:space:]]engineered[[:space:]]cementitious[[:space:]]composites[[:space:]]in[[:space:]]different[[:space:]]application[[:space:]]forms.pdf filter=lfs diff=lfs merge=lfs -text
355
- papers/S45-Insitu[[:space:]]synthesizing[[:space:]]carbon[[:space:]]nanotubes[[:space:]]on[[:space:]]cement[[:space:]]to[[:space:]]develop[[:space:]]self-sensing[[:space:]]cementitious[[:space:]]composites.pdf filter=lfs diff=lfs merge=lfs -text
356
- papers/S46-SE~1.PDF filter=lfs diff=lfs merge=lfs -text
357
- papers/S47-The[[:space:]]applicability[[:space:]]of[[:space:]]shungite[[:space:]]as[[:space:]]an[[:space:]]electrically[[:space:]]conductive[[:space:]]additive[[:space:]]in[[:space:]]cement[[:space:]]composites.pdf filter=lfs diff=lfs merge=lfs -text
358
- papers/S48-Self-sensing[[:space:]]properties[[:space:]]and[[:space:]]piezoresistive[[:space:]]effect[[:space:]]of[[:space:]]high[[:space:]]ductility[[:space:]]cementitious[[:space:]]composite.pdf filter=lfs diff=lfs merge=lfs -text
359
- papers/S49-ME~1.PDF filter=lfs diff=lfs merge=lfs -text
360
- papers/S5-Effects-of-carbon-nanomaterial-type-and-amount-on-self-sensing-_2019_Measure.pdf filter=lfs diff=lfs merge=lfs -text
361
- papers/S50-IM~1.PDF filter=lfs diff=lfs merge=lfs -text
362
- papers/S51-Electrical[[:space:]]and[[:space:]]piezoresistive[[:space:]]properties[[:space:]]of[[:space:]]cement[[:space:]]composites[[:space:]]with[[:space:]]carbon[[:space:]]nanomaterials.pdf filter=lfs diff=lfs merge=lfs -text
363
- papers/S52-Influences[[:space:]]of[[:space:]](MCNT)[[:space:]]fraction,[[:space:]]moisture,[[:space:]]stressstrain[[:space:]]level[[:space:]]on[[:space:]]the[[:space:]]electrical[[:space:]]properties[[:space:]]of[[:space:]]MCNT[[:space:]]of[[:space:]]cement-based[[:space:]]composites.pdf filter=lfs diff=lfs merge=lfs -text
364
- papers/S53-CA~1.PDF filter=lfs diff=lfs merge=lfs -text
365
- papers/S54-Carbon[[:space:]]Nanofibers[[:space:]]Grown[[:space:]]in[[:space:]]CaO[[:space:]]for[[:space:]]Self-Sensing[[:space:]]in[[:space:]]Mortar.pdf filter=lfs diff=lfs merge=lfs -text
366
- papers/S55-Electro-mechanical[[:space:]]self-sensing[[:space:]]response[[:space:]]of[[:space:]]ultra-high-performance[[:space:]]fiber-reinforced[[:space:]]concrete[[:space:]]in[[:space:]]tension.pdf filter=lfs diff=lfs merge=lfs -text
367
- papers/S55-Nanocarbon[[:space:]]black-based[[:space:]]ultra-high-performance[[:space:]]concrete[[:space:]](UHPC)[[:space:]]with[[:space:]]self-strain[[:space:]]sensing[[:space:]]capability.pdf filter=lfs diff=lfs merge=lfs -text
368
- papers/S56-Self-sensing[[:space:]]cementitious[[:space:]]composites[[:space:]]incorporated[[:space:]]with[[:space:]]botryoid[[:space:]]hybrid[[:space:]]nano-carbon[[:space:]]materials[[:space:]]for[[:space:]]smart[[:space:]]infrastructures.pdf filter=lfs diff=lfs merge=lfs -text
369
- papers/S57-IN~1.PDF filter=lfs diff=lfs merge=lfs -text
370
- papers/S58-DE~1.PDF filter=lfs diff=lfs merge=lfs -text
371
- papers/S59-Modifying[[:space:]]self-sensing[[:space:]]cement-based[[:space:]]composites[[:space:]]through[[:space:]]multiscale[[:space:]]composition.pdf filter=lfs diff=lfs merge=lfs -text
372
- papers/S6-Electrically[[:space:]]conductive[[:space:]]behaviors[[:space:]]and[[:space:]]mechanisms[[:space:]]of[[:space:]]short-cut[[:space:]]super-fine[[:space:]]stainless[[:space:]]wire[[:space:]]reinforced[[:space:]]reactive[[:space:]]powder[[:space:]]concrete.pdf filter=lfs diff=lfs merge=lfs -text
373
- papers/S60-Study[[:space:]]on[[:space:]]self-sensing[[:space:]]capabilities[[:space:]]of[[:space:]]smart[[:space:]]cements[[:space:]]filled[[:space:]]with[[:space:]]graphene[[:space:]]oxide[[:space:]]under[[:space:]]dynamic[[:space:]]cyclic[[:space:]]loading.pdf filter=lfs diff=lfs merge=lfs -text
374
- papers/S61-Piezoresistivity,[[:space:]]mechanisms[[:space:]]and[[:space:]]model[[:space:]]of[[:space:]]cement-based[[:space:]]materials[[:space:]]with[[:space:]]CNT_NCB[[:space:]]composite[[:space:]]fillers.pdf filter=lfs diff=lfs merge=lfs -text
375
- papers/S62-MU~1.PDF filter=lfs diff=lfs merge=lfs -text
376
- papers/S63-Piezoresistive[[:space:]]properties[[:space:]]of[[:space:]]cement[[:space:]]composites[[:space:]]with[[:space:]]expanded[[:space:]]graphite.pdf filter=lfs diff=lfs merge=lfs -text
377
- papers/S64-Electrical[[:space:]]Properties[[:space:]]of[[:space:]]Cement-Based[[:space:]]Composites[[:space:]]with[[:space:]]Carbon[[:space:]]Nanotubes,[[:space:]]Graphene,[[:space:]]and[[:space:]]Graphite[[:space:]]Nanofibers.pdf filter=lfs diff=lfs merge=lfs -text
378
- papers/S65-AN~1.PDF filter=lfs diff=lfs merge=lfs -text
379
- papers/S66-Experimental[[:space:]]Investigation[[:space:]]of[[:space:]]the[[:space:]]Piezoresistive[[:space:]]Properties[[:space:]]of[[:space:]]Cement[[:space:]]Composites[[:space:]]with[[:space:]]Hybrid[[:space:]]Carbon[[:space:]]Fibers[[:space:]]and[[:space:]]Nanotubes.pdf filter=lfs diff=lfs merge=lfs -text
380
- papers/S67-Strain[[:space:]]and[[:space:]]damage[[:space:]]sensing[[:space:]]properties[[:space:]]on[[:space:]]multifunctional[[:space:]]cement[[:space:]]composites[[:space:]]with[[:space:]]CNF[[:space:]]admixture.pdf filter=lfs diff=lfs merge=lfs -text
381
- papers/S68-EF~1.PDF filter=lfs diff=lfs merge=lfs -text
382
- papers/S69-Cement-based[[:space:]]sensors[[:space:]]with[[:space:]]carbon[[:space:]]fibers[[:space:]]and[[:space:]]carbon[[:space:]]nanotubes[[:space:]]for[[:space:]]piezoresistive[[:space:]]sensing.pdf filter=lfs diff=lfs merge=lfs -text
383
- papers/S7-Electrical[[:space:]]characteristics[[:space:]]and[[:space:]]pressure-sensitive[[:space:]]response[[:space:]]measurements[[:space:]]of[[:space:]]carboxyl[[:space:]]MWNT_cement[[:space:]]composites.pdf filter=lfs diff=lfs merge=lfs -text
384
- papers/S70-EV~1.PDF filter=lfs diff=lfs merge=lfs -text
385
- papers/S71-Enhanced[[:space:]]sensing[[:space:]]performance[[:space:]]of[[:space:]]cement-based[[:space:]]composites[[:space:]]achieved[[:space:]]via[[:space:]]magnetically[[:space:]]aligned[[:space:]]nickel[[:space:]]particle[[:space:]]network.pdf filter=lfs diff=lfs merge=lfs -text
386
- papers/S72-Anisotropic[[:space:]]electrical[[:space:]]and[[:space:]]piezoresistive[[:space:]]sensing[[:space:]]properties[[:space:]]of[[:space:]]cement-based[[:space:]]sensors[[:space:]]with[[:space:]]aligned[[:space:]]carbon[[:space:]]fibers.pdf filter=lfs diff=lfs merge=lfs -text
387
- papers/S73-Development[[:space:]]of[[:space:]]self-sensing[[:space:]]cement-based[[:space:]]sensor[[:space:]]using[[:space:]]recycled[[:space:]]fine[[:space:]]waste[[:space:]]glass[[:space:]]aggregates[[:space:]]coated[[:space:]]with[[:space:]]carbon[[:space:]]nanotube.pdf filter=lfs diff=lfs merge=lfs -text
388
- papers/S74-Strain[[:space:]]sensitivity[[:space:]]of[[:space:]]steel-fiber-reinforced[[:space:]]industrial[[:space:]]smart[[:space:]]concrete.pdf filter=lfs diff=lfs merge=lfs -text
389
- papers/S75-SE~1.PDF filter=lfs diff=lfs merge=lfs -text
390
- papers/S76-Strain-sensing[[:space:]]characteristics[[:space:]]of[[:space:]]self-consolidating[[:space:]]concrete[[:space:]]with[[:space:]]micro-carbon[[:space:]]fibre.pdf filter=lfs diff=lfs merge=lfs -text
391
- papers/S77-SE~1.PDF filter=lfs diff=lfs merge=lfs -text
392
- papers/S78-Mechanical[[:space:]]and[[:space:]]self-sensing[[:space:]]properties[[:space:]]of[[:space:]]concrete[[:space:]]reinforced[[:space:]]with[[:space:]]carbon[[:space:]]nanofibres.pdf filter=lfs diff=lfs merge=lfs -text
393
- papers/S79-Carbon[[:space:]]nanotube[[:space:]]cement-based[[:space:]]transducers[[:space:]]for[[:space:]]dynamic[[:space:]]sensing[[:space:]]of[[:space:]]strain.pdf filter=lfs diff=lfs merge=lfs -text
394
- papers/S8-Electrically-cured-ultra-high-performance-concrete--UHPC--embe_2020_Material.pdf filter=lfs diff=lfs merge=lfs -text
395
- papers/S80-MA~1.PDF filter=lfs diff=lfs merge=lfs -text
396
- papers/S81-Piezoresistive[[:space:]]properties[[:space:]]of[[:space:]]ultra-high-performance[[:space:]]fiber-reinforced[[:space:]]concrete[[:space:]]incorporating[[:space:]]few-layer[[:space:]]graphene.pdf filter=lfs diff=lfs merge=lfs -text
397
- papers/S82-SY~1.PDF filter=lfs diff=lfs merge=lfs -text
398
- papers/S83-Effect[[:space:]]of[[:space:]]compressive[[:space:]]strain[[:space:]]on[[:space:]]electrical[[:space:]]resistivity[[:space:]]of[[:space:]]carbon[[:space:]]black-filled[[:space:]]cement-based[[:space:]]composites.pdf filter=lfs diff=lfs merge=lfs -text
399
- papers/S84-TA~1.PDF filter=lfs diff=lfs merge=lfs -text
400
- papers/S85-Performance[[:space:]]of[[:space:]]cement-based[[:space:]]sensors[[:space:]]with[[:space:]]CNT[[:space:]]for[[:space:]]strain[[:space:]]sensing.pdf filter=lfs diff=lfs merge=lfs -text
401
- papers/S86-EL~1.PDF filter=lfs diff=lfs merge=lfs -text
402
- papers/S87-EL~1.PDF filter=lfs diff=lfs merge=lfs -text
403
- papers/S88-ST~1.PDF filter=lfs diff=lfs merge=lfs -text
404
- papers/S89-Piezoresistivity[[:space:]]of[[:space:]]carbon[[:space:]]fiber[[:space:]]graphite[[:space:]]cement-based[[:space:]]composites[[:space:]]with[[:space:]]CCCW.pdf filter=lfs diff=lfs merge=lfs -text
405
- papers/S9-Electro-mechanical-self-sensing-response-of-ultra-high-_2018_Composites-Part.pdf filter=lfs diff=lfs merge=lfs -text
406
- papers/S90-EX~1.PDF filter=lfs diff=lfs merge=lfs -text
407
- papers/S91-A[[:space:]]comparative[[:space:]]study[[:space:]]on[[:space:]]the[[:space:]]influences[[:space:]]of[[:space:]]CNT[[:space:]]and[[:space:]]GNP[[:space:]]on[[:space:]]the[[:space:]]piezoresistivity[[:space:]]of[[:space:]]cement[[:space:]]composites.pdf filter=lfs diff=lfs merge=lfs -text
408
- papers/S92-Research-on-the-self-sensing-and-mechanical-properties-of_2021_Cement-and-Co.pdf filter=lfs diff=lfs merge=lfs -text
409
- papers/S93-Enhanced[[:space:]]effects[[:space:]]of[[:space:]]carbon-based[[:space:]]conductive[[:space:]]materials[[:space:]]on[[:space:]]the[[:space:]]piezoresistive[[:space:]]characteristics[[:space:]]of[[:space:]]cementitious[[:space:]]composites.pdf filter=lfs diff=lfs merge=lfs -text
410
- papers/S94-The[[:space:]]Utilization[[:space:]]of[[:space:]]Pearson’s[[:space:]]Method[[:space:]]to[[:space:]]Analyze[[:space:]]Piezoresistive[[:space:]]Effect[[:space:]]in[[:space:]]Self-Sensing[[:space:]]Cement[[:space:]]Composite[[:space:]]with[[:space:]]Graphite.pdf filter=lfs diff=lfs merge=lfs -text
411
- papers/S95-SE~1.PDF filter=lfs diff=lfs merge=lfs -text
412
- papers/S96-EL~1.PDF filter=lfs diff=lfs merge=lfs -text
413
- papers/S97-Self-sensing[[:space:]]GFRP-reinforced[[:space:]]concrete[[:space:]]beams[[:space:]]containing[[:space:]]carbon[[:space:]]nanotube-nano[[:space:]]carbon[[:space:]]black[[:space:]]composite[[:space:]]fillers.pdf filter=lfs diff=lfs merge=lfs -text
414
- papers/S98-MI~1.PDF filter=lfs diff=lfs merge=lfs -text
415
- papers/S99-Commercial[[:space:]]and[[:space:]]recycled[[:space:]]carbon-based[[:space:]]fillers[[:space:]]and[[:space:]]fibers[[:space:]]for[[:space:]]self-sensing[[:space:]]cement-based[[:space:]]composites.pdf filter=lfs diff=lfs merge=lfs -text
416
- papers/Self-sensing[[:space:]]enhancement[[:space:]]in[[:space:]]smart[[:space:]]ultra-high[[:space:]]performance[[:space:]]concrete[[:space:]]composites[[:space:]]via[[:space:]]multi-scale[[:space:]]carbon[[:space:]]black.pdf filter=lfs diff=lfs merge=lfs -text
417
- papers/Self-sensing[[:space:]]performance[[:space:]]of[[:space:]]cementitious[[:space:]]composites[[:space:]]with[[:space:]]functional[[:space:]]fillers[[:space:]]at[[:space:]]macro,[[:space:]]micro[[:space:]]and[[:space:]]nano[[:space:]]scales.pdf filter=lfs diff=lfs merge=lfs -text
418
- papers/Self‐Sensing[[:space:]]Cementitious[[:space:]]Composites[[:space:]]with[[:space:]]Hierarchical[[:space:]]Carbon[[:space:]]Fiber‐Carbon[[:space:]]Nanotube[[:space:]]Composite[[:space:]]Fillers.pdf filter=lfs diff=lfs merge=lfs -text
419
- papers/Silane[[:space:]]treatment[[:space:]]of[[:space:]]bagasse[[:space:]]fiber[[:space:]]for[[:space:]]reinforcement[[:space:]]of[[:space:]]cementitious[[:space:]]composites.pdf filter=lfs diff=lfs merge=lfs -text
420
- papers/The[[:space:]]effect[[:space:]]of[[:space:]]silane[[:space:]]surface[[:space:]]treatment[[:space:]]on[[:space:]]the[[:space:]]mechanical[[:space:]]properties[[:space:]]of[[:space:]]UHPFRC.pdf filter=lfs diff=lfs merge=lfs -text
 
290
  literature_pdfs/Self‐Sensing[[:space:]]Cementitious[[:space:]]Composites[[:space:]]with[[:space:]]Hierarchical[[:space:]]Carbon[[:space:]]Fiber‐Carbon[[:space:]]Nanotube[[:space:]]Composite[[:space:]]Fillers.pdf filter=lfs diff=lfs merge=lfs -text
291
  literature_pdfs/Silane[[:space:]]treatment[[:space:]]of[[:space:]]bagasse[[:space:]]fiber[[:space:]]for[[:space:]]reinforcement[[:space:]]of[[:space:]]cementitious[[:space:]]composites.pdf filter=lfs diff=lfs merge=lfs -text
292
  literature_pdfs/The[[:space:]]effect[[:space:]]of[[:space:]]silane[[:space:]]surface[[:space:]]treatment[[:space:]]on[[:space:]]the[[:space:]]mechanical[[:space:]]properties[[:space:]]of[[:space:]]UHPFRC.pdf filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app.py CHANGED
@@ -1,12 +1,8 @@
1
- # ================================================================
2
  # Self-Sensing Concrete Assistant — Predictor (XGB) + Hybrid RAG
3
- # - Uses local 'papers/' folder for literature
4
- # - Robust MMR sentence selection (no list index errors)
5
- # - Predictor: safe model caching + safe feature alignment
6
- # - Stable categoricals ("NA"); no over-strict completeness gate
7
- # - Lightweight instrumentation (JSONL logs per RAG turn)
8
- # - Dark-blue theme + Evaluate tab + k-slider styling
9
- # - Citations use SHORT CODES (e.g., S71, S92) from filenames
10
  # ================================================================
11
 
12
  # ---------------------- Runtime flags (HF-safe) ----------------------
@@ -16,9 +12,9 @@ os.environ["TRANSFORMERS_NO_FLAX"] = "1"
16
  os.environ["TOKENIZERS_PARALLELISM"] = "false"
17
 
18
  # ------------------------------- Imports ------------------------------
19
- import re, joblib, warnings, json, traceback, time, uuid, subprocess, sys
20
  from pathlib import Path
21
- from typing import List, Dict, Any, Optional
22
 
23
  import numpy as np
24
  import pandas as pd
@@ -39,48 +35,20 @@ except Exception:
39
  BM25Okapi = None
40
  print("rank_bm25 not installed; BM25 disabled (TF-IDF still works).")
41
 
42
- # Optional OpenAI (for LLM synthesis)
43
  OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
44
- OPENAI_MODEL = os.getenv("OPENAI_MODEL", "gpt-5")
 
45
  try:
46
  from openai import OpenAI
47
  except Exception:
48
  OpenAI = None
49
 
50
- # LLM availability flag — used internally; UI remains hidden
51
- LLM_AVAILABLE = (OPENAI_API_KEY is not None and OPENAI_API_KEY.strip() != "" and OpenAI is not None)
52
 
53
- # ========================= Predictor (kept) =========================
54
  CF_COL = "Conductive Filler Conc. (wt%)"
55
  TARGET_COL = "Stress GF (MPa-1)"
56
- CANON_NA = "NA" # canonical placeholder for categoricals
57
-
58
- TYPE_CHOICES = [
59
- "CNT",
60
- "Brass fiber",
61
- "GNP",
62
- "Steel fiber",
63
- "Carbon fiber",
64
- "Graphene oxide",
65
- "Graphene",
66
- "Carbon black",
67
- "Graphite",
68
- "Shungite",
69
- "Nickel powder",
70
- "Glass cullet",
71
- "MWCNT",
72
- "Nano carbon black",
73
- "Carbon powder",
74
- "Gasification char",
75
- "Used foundry sand",
76
- "Nickel fiber",
77
- "Nickel aggregate",
78
- "Steel slag aggregate",
79
- "TiO2",
80
- "Carbonyl iron powder",
81
- "Magnetite aggregate",
82
- CANON_NA
83
- ]
84
 
85
  MAIN_VARIABLES = [
86
  "Filler 1 Type",
@@ -137,133 +105,54 @@ CATEGORICAL_COLS = {
137
  "Current Type"
138
  }
139
 
140
- DIM_CHOICES = ["0D", "1D", "2D", "3D", CANON_NA]
141
- CURRENT_CHOICES = ["DC", "AC", CANON_NA]
142
 
143
  MODEL_CANDIDATES = [
144
  "stress_gf_xgb.joblib",
145
  "models/stress_gf_xgb.joblib",
146
  "/home/user/app/stress_gf_xgb.joblib",
147
- os.getenv("MODEL_PATH", "")
148
  ]
149
 
150
- # ---------- Model caching + status ----------
151
- MODEL = None
152
- MODEL_STATUS = "🔴 Model not loaded"
153
-
154
- def _try_load_model():
155
- global MODEL, MODEL_STATUS
156
- for p in [x for x in MODEL_CANDIDATES if x]:
157
  if os.path.exists(p):
158
  try:
159
- MODEL = joblib.load(p)
160
- MODEL_STATUS = f"🟢 Loaded model: {Path(p).name}"
161
- print("[ModelLoad] Loaded:", p)
162
- return
163
  except Exception as e:
164
- print(f"[ModelLoad] Error from {p}: {e}")
165
- traceback.print_exc()
166
- MODEL = None
167
- if MODEL is None:
168
- MODEL_STATUS = "🔴 Model not found (place stress_gf_xgb.joblib at repo root or models/, or set MODEL_PATH)"
169
- print("[ModelLoad]", MODEL_STATUS)
170
-
171
- _try_load_model() # load at import time
172
-
173
- def _canon_cat(v: Any) -> str:
174
- """Stable, canonical category placeholder normalization."""
175
- if v is None:
176
- return CANON_NA
177
- s = str(v).strip()
178
- if s == "" or s.upper() in {"N/A", "NONE", "NULL"}:
179
- return CANON_NA
180
- return s
181
-
182
- def _to_float_or_nan(v):
183
- if v in ("", None):
184
- return np.nan
185
- try:
186
- return float(str(v).replace(",", ""))
187
- except Exception:
188
- return np.nan
189
 
190
  def _coerce_to_row(form_dict: dict) -> pd.DataFrame:
191
  row = {}
192
  for col in MAIN_VARIABLES:
193
  v = form_dict.get(col, None)
194
  if col in NUMERIC_COLS:
195
- row[col] = _to_float_or_nan(v)
196
- elif col in CATEGORICAL_COLS:
197
- row[col] = _canon_cat(v)
 
 
 
 
198
  else:
199
- s = str(v).strip() if v is not None else ""
200
- row[col] = s if s else CANON_NA
201
  return pd.DataFrame([row], columns=MAIN_VARIABLES)
202
 
203
- def _align_columns_to_model(df: pd.DataFrame, mdl) -> pd.DataFrame:
204
- """
205
- SAFE alignment:
206
- - If mdl.feature_names_in_ exists AND is a subset of df.columns (raw names), reorder to it.
207
- - Else, try a Pipeline step (e.g., 'preprocessor') with feature_names_in_ subset of df.columns.
208
- - Else, DO NOT align (let the pipeline handle columns by name).
209
- """
210
- try:
211
- feat = getattr(mdl, "feature_names_in_", None)
212
- if isinstance(feat, (list, np.ndarray, pd.Index)):
213
- feat = list(feat)
214
- if all(c in df.columns for c in feat):
215
- return df[feat]
216
-
217
- if hasattr(mdl, "named_steps"):
218
- for key in ["preprocessor", "columntransformer"]:
219
- if key in mdl.named_steps:
220
- step = mdl.named_steps[key]
221
- feat2 = getattr(step, "feature_names_in_", None)
222
- if isinstance(feat2, (list, np.ndarray, pd.Index)):
223
- feat2 = list(feat2)
224
- if all(c in df.columns for c in feat2):
225
- return df[feat2]
226
- # fallback to first step if it exposes input names
227
- try:
228
- first_key = list(mdl.named_steps.keys())[0]
229
- step = mdl.named_steps[first_key]
230
- feat3 = getattr(step, "feature_names_in_", None)
231
- if isinstance(feat3, (list, np.ndarray, pd.Index)):
232
- feat3 = list(feat3)
233
- if all(c in df.columns for c in feat3):
234
- return df[feat3]
235
- except Exception:
236
- pass
237
-
238
- return df
239
- except Exception as e:
240
- print(f"[Align] Skip aligning due to: {e}")
241
- traceback.print_exc()
242
- return df
243
-
244
  def predict_fn(**kwargs):
245
- """
246
- Always attempt prediction.
247
- - Missing numerics -> NaN (imputer handles)
248
- - Categoricals -> 'NA'
249
- - If model missing or inference error -> 0.0 (keeps UI stable)
250
- """
251
- if MODEL is None:
252
- return 0.0
253
  X_new = _coerce_to_row(kwargs)
254
- X_new = _align_columns_to_model(X_new, MODEL)
255
  try:
256
- y_raw = MODEL.predict(X_new) # log1p or original scale depending on training
257
- if getattr(MODEL, "target_is_log1p_", False):
258
- y = np.expm1(y_raw)
259
- else:
260
- y = y_raw
261
- y = float(np.asarray(y).ravel()[0])
262
- return max(y, 0.0)
263
  except Exception as e:
264
- print(f"[Predict] {e}")
265
- traceback.print_exc()
266
- return 0.0
267
 
268
  EXAMPLE = {
269
  "Filler 1 Type": "CNT",
@@ -272,7 +161,7 @@ EXAMPLE = {
272
  "Filler 1 Length (mm)": 1.2,
273
  CF_COL: 0.5,
274
  "Filler 2 Type": "",
275
- "Filler 2 Dimensionality": CANON_NA,
276
  "Filler 2 Diameter (µm)": None,
277
  "Filler 2 Length (mm)": None,
278
  "Specimen Volume (mm3)": 1000,
@@ -300,14 +189,15 @@ def _clear_all():
300
  if col in NUMERIC_COLS:
301
  cleared.append(None)
302
  elif col in {"Filler 1 Dimensionality", "Filler 2 Dimensionality"}:
303
- cleared.append(CANON_NA)
304
  elif col == "Current Type":
305
- cleared.append(CANON_NA)
306
  else:
307
  cleared.append("")
308
  return cleared
309
 
310
- # ========================= Hybrid RAG =========================
 
311
  ARTIFACT_DIR = Path("rag_artifacts"); ARTIFACT_DIR.mkdir(exist_ok=True)
312
  TFIDF_VECT_PATH = ARTIFACT_DIR / "tfidf_vectorizer.joblib"
313
  TFIDF_MAT_PATH = ARTIFACT_DIR / "tfidf_matrix.joblib"
@@ -315,13 +205,16 @@ BM25_TOK_PATH = ARTIFACT_DIR / "bm25_tokens.joblib"
315
  EMB_NPY_PATH = ARTIFACT_DIR / "chunk_embeddings.npy"
316
  RAG_META_PATH = ARTIFACT_DIR / "chunks.parquet"
317
 
318
- LOCAL_PDF_DIR = Path("papers"); LOCAL_PDF_DIR.mkdir(exist_ok=True)
 
319
  USE_ONLINE_SOURCES = os.getenv("USE_ONLINE_SOURCES", "false").lower() == "true"
320
 
 
321
  W_TFIDF_DEFAULT = 0.50 if not USE_DENSE else 0.30
322
  W_BM25_DEFAULT = 0.50 if not USE_DENSE else 0.30
323
- W_EMB_DEFAULT = 0.00 if USE_DENSE is False else 0.40
324
 
 
325
  _SENT_SPLIT_RE = re.compile(r"(?<=[.!?])\s+|\n+")
326
  TOKEN_RE = re.compile(r"[A-Za-z0-9_#+\-/\.%]+")
327
  def sent_split(text: str) -> List[str]:
@@ -330,6 +223,7 @@ def sent_split(text: str) -> List[str]:
330
  def tokenize(text: str) -> List[str]:
331
  return [t.lower() for t in TOKEN_RE.findall(text)]
332
 
 
333
  def _extract_pdf_text(pdf_path: Path) -> str:
334
  try:
335
  import fitz
@@ -371,8 +265,8 @@ def _safe_init_st_model(name: str):
371
  USE_DENSE = False
372
  return None
373
 
 
374
  def build_or_load_hybrid(pdf_dir: Path):
375
- # Build or load the hybrid retriever cache
376
  have_cache = (TFIDF_VECT_PATH.exists() and TFIDF_MAT_PATH.exists()
377
  and RAG_META_PATH.exists()
378
  and (BM25_TOK_PATH.exists() or BM25Okapi is None)
@@ -396,11 +290,13 @@ def build_or_load_hybrid(pdf_dir: Path):
396
  rows.append({"doc_path": str(pdf), "chunk_id": i, "text": ch})
397
  all_tokens.append(tokenize(ch))
398
  if not rows:
 
399
  meta = pd.DataFrame(columns=["doc_path", "chunk_id", "text"])
400
  vectorizer = None; X_tfidf = None; emb = None; all_tokens = None
401
  return vectorizer, X_tfidf, meta, all_tokens, emb
402
 
403
  meta = pd.DataFrame(rows)
 
404
  from sklearn.feature_extraction.text import TfidfVectorizer
405
  vectorizer = TfidfVectorizer(
406
  ngram_range=(1,2),
@@ -424,11 +320,13 @@ def build_or_load_hybrid(pdf_dir: Path):
424
  print("Dense embedding failed:", e)
425
  emb = None
426
 
 
427
  joblib.dump(vectorizer, TFIDF_VECT_PATH)
428
  joblib.dump(X_tfidf, TFIDF_MAT_PATH)
429
  if BM25Okapi is not None:
430
  joblib.dump(all_tokens, BM25_TOK_PATH)
431
  meta.to_parquet(RAG_META_PATH, index=False)
 
432
  return vectorizer, X_tfidf, meta, all_tokens, emb
433
 
434
  tfidf_vectorizer, tfidf_matrix, rag_meta, bm25_tokens, emb_matrix = build_or_load_hybrid(LOCAL_PDF_DIR)
@@ -436,29 +334,9 @@ bm25 = BM25Okapi(bm25_tokens) if (BM25Okapi is not None and bm25_tokens is not N
436
  st_query_model = _safe_init_st_model(os.getenv("EMB_MODEL_NAME", "sentence-transformers/all-MiniLM-L6-v2"))
437
 
438
  def _extract_page(text_chunk: str) -> str:
439
- # Correct: [[PAGE=123]]
440
  m = list(re.finditer(r"\[\[PAGE=(\d+)\]\]", text_chunk or ""))
441
  return (m[-1].group(1) if m else "?")
442
 
443
- def _short_doc_code(doc_path: str) -> str:
444
- """
445
- Turn a full filename like:
446
- 'S92-Research-on-the-self-sensing-and-mechanical-properties-of_2021_Cement-and-Co.pdf'
447
- into a short code:
448
- 'S92'
449
- For generic names, falls back to the first token of the stem.
450
- """
451
- if not doc_path:
452
- return "Source"
453
- name = Path(doc_path).name
454
- stem = name.rsplit(".", 1)[0]
455
- # Split on whitespace, hyphen, underscore
456
- parts = re.split(r"[ \t\n\r\-_]+", stem)
457
- for p in parts:
458
- if p:
459
- return p
460
- return stem or "Source"
461
-
462
  def hybrid_search(query: str, k=8, w_tfidf=W_TFIDF_DEFAULT, w_bm25=W_BM25_DEFAULT, w_emb=W_EMB_DEFAULT):
463
  if rag_meta is None or rag_meta.empty:
464
  return pd.DataFrame()
@@ -485,7 +363,7 @@ def hybrid_search(query: str, k=8, w_tfidf=W_TFIDF_DEFAULT, w_bm25=W_BM25_DEFAUL
485
 
486
  # BM25 scores
487
  if bm25 is not None:
488
- q_tokens = [t.lower() for t in re.findall(r"[A-Za-z0-9_#+\-\/\.%]+", query)]
489
  bm25_scores = np.array(bm25.get_scores(q_tokens), dtype=float)
490
  else:
491
  bm25_scores = np.zeros(len(rag_meta), dtype=float); w_bm25 = 0.0
@@ -517,114 +395,71 @@ def split_sentences(text: str) -> List[str]:
517
  return [s for s in sents if 6 <= len(s.split()) <= 60]
518
 
519
  def mmr_select_sentences(question: str, hits: pd.DataFrame, top_n=4, pool_per_chunk=6, lambda_div=0.7):
520
- """
521
- Robust MMR sentence picker:
522
- - Handles empty pools
523
- - Clamps top_n to pool size
524
- - Avoids 'list index out of range'
525
- """
526
- # Build pool
527
  pool = []
528
  for _, row in hits.iterrows():
529
- doc_code = _short_doc_code(row["doc_path"])
530
  page = _extract_page(row["text"])
531
- sents = split_sentences(row["text"])
532
- if not sents:
533
- continue
534
- for s in sents[:max(1, int(pool_per_chunk))]:
535
- pool.append({"sent": s, "doc": doc_code, "page": page})
536
-
537
  if not pool:
538
  return []
539
 
540
- # Relevance vectors
541
  sent_texts = [p["sent"] for p in pool]
 
 
542
  use_dense = USE_DENSE and st_query_model is not None
543
- try:
544
- if use_dense:
545
  from sklearn.preprocessing import normalize as sk_normalize
546
- enc = st_query_model.encode([question] + sent_texts, convert_to_numpy=True)
 
547
  q_vec = sk_normalize(enc[:1])[0]
548
  S = sk_normalize(enc[1:])
549
  rel = (S @ q_vec)
550
  def sim_fn(i, j): return float(S[i] @ S[j])
551
- else:
552
- from sklearn.feature_extraction.text import TfidfVectorizer
553
- vect = TfidfVectorizer().fit(sent_texts + [question])
554
- Q = vect.transform([question]); S = vect.transform(sent_texts)
555
- rel = (S @ Q.T).toarray().ravel()
556
- def sim_fn(i, j):
557
- num = (S[i] @ S[j].T)
558
- return float(num.toarray()[0, 0]) if hasattr(num, "toarray") else float(num)
559
- except Exception:
560
- # Fallback: uniform relevance if vectorization fails
561
- rel = np.ones(len(sent_texts), dtype=float)
562
- def sim_fn(i, j): return 0.0
563
 
564
- # Normalize lambda_div
565
- lambda_div = float(np.clip(lambda_div, 0.0, 1.0))
 
 
 
 
566
 
567
- # Select first by highest relevance
568
  remain = list(range(len(pool)))
569
- if not remain:
570
- return []
571
  first = int(np.argmax(rel))
572
- selected_idx = [first]
573
- selected = [pool[first]]
574
- remain.remove(first)
575
 
576
- # Clamp top_n
577
- max_pick = min(int(top_n), len(pool))
578
- while len(selected) < max_pick and remain:
579
  cand_scores = []
580
  for i in remain:
581
- div_i = max(sim_fn(i, j) for j in selected_idx) if selected_idx else 0.0
582
- score = lambda_div * float(rel[i]) - (1.0 - lambda_div) * div_i
583
  cand_scores.append((score, i))
584
- if not cand_scores:
585
- break
586
  cand_scores.sort(reverse=True)
587
- _, best_i = cand_scores[0]
588
- selected_idx.append(best_i)
589
- selected.append(pool[best_i])
590
- remain.remove(best_i)
591
-
592
  return selected
593
 
594
  def compose_extractive(selected: List[Dict[str, Any]]) -> str:
595
  if not selected:
596
  return ""
597
- # Citations inside answer are short codes only, e.g. (S92), (S71)
598
- return " ".join(f"{s['sent']} ({s['doc']})" for s in selected)
599
-
600
- # ========================= NEW: Instrumentation helpers =========================
601
- LOG_PATH = ARTIFACT_DIR / "rag_logs.jsonl"
602
- OPENAI_IN_COST_PER_1K = float(os.getenv("OPENAI_COST_IN_PER_1K", "0"))
603
- OPENAI_OUT_COST_PER_1K = float(os.getenv("OPENAI_COST_OUT_PER_1K", "0"))
604
-
605
- def _safe_write_jsonl(path: Path, record: dict):
606
- try:
607
- with open(path, "a", encoding="utf-8") as f:
608
- f.write(json.dumps(record, ensure_ascii=False) + "\n")
609
- except Exception as e:
610
- print("[Log] write failed:", e)
611
 
612
- def _calc_cost_usd(prompt_toks, completion_toks):
613
- if prompt_toks is None or completion_toks is None:
614
  return None
615
- return (prompt_toks / 1000.0) * OPENAI_IN_COST_PER_1K + (completion_toks / 1000.0) * OPENAI_OUT_COST_PER_1K
616
-
617
- # ----------------- Modified to return (text, usage_dict) -----------------
618
- def synthesize_with_llm(question: str, sentence_lines: List[str], model: str = None, temperature: float = 0.2):
619
- if not LLM_AVAILABLE:
620
- return None, None
621
  client = OpenAI(api_key=OPENAI_API_KEY)
622
  model = model or OPENAI_MODEL
 
623
  SYSTEM_PROMPT = (
624
  "You are a scientific assistant for self-sensing cementitious materials.\n"
625
  "Answer STRICTLY using the provided sentences.\n"
626
  "Do not invent facts. Keep it concise (3–6 sentences).\n"
627
- "Retain inline citations exactly as given (e.g., (S92), (S92; S71))."
628
  )
629
  user_prompt = (
630
  f"Question: {question}\n\n"
@@ -640,205 +475,61 @@ def synthesize_with_llm(question: str, sentence_lines: List[str], model: str = N
640
  ],
641
  temperature=temperature,
642
  )
643
- out_text = getattr(resp, "output_text", None) or str(resp)
644
- usage = None
645
- try:
646
- u = getattr(resp, "usage", None)
647
- if u:
648
- pt = getattr(u, "prompt_tokens", None) if hasattr(u, "prompt_tokens") else u.get("prompt_tokens", None)
649
- ct = getattr(u, "completion_tokens", None) if hasattr(u, "completion_tokens") else u.get("completion_tokens", None)
650
- usage = {"prompt_tokens": pt, "completion_tokens": ct}
651
- except Exception:
652
- usage = None
653
- return out_text, usage
654
- except Exception:
655
- return None, None
656
 
657
  def rag_reply(
658
  question: str,
659
  k: int = 8,
660
  n_sentences: int = 4,
661
  include_passages: bool = False,
662
- use_llm: bool = False,
663
- model: str = None,
664
  temperature: float = 0.2,
665
  strict_quotes_only: bool = False,
666
  w_tfidf: float = W_TFIDF_DEFAULT,
667
  w_bm25: float = W_BM25_DEFAULT,
668
  w_emb: float = W_EMB_DEFAULT
669
  ) -> str:
670
- run_id = str(uuid.uuid4())
671
- t0_total = time.time()
672
- t0_retr = time.time()
673
-
674
- # --- Retrieval ---
675
  hits = hybrid_search(question, k=k, w_tfidf=w_tfidf, w_bm25=w_bm25, w_emb=w_emb)
676
- t1_retr = time.time()
677
- latency_ms_retriever = int((t1_retr - t0_retr) * 1000)
678
-
679
  if hits is None or hits.empty:
680
- final = "No indexed PDFs found. Upload PDFs to the 'papers/' folder and reload the Space."
681
- record = {
682
- "run_id": run_id,
683
- "ts": int(time.time()*1000),
684
- "inputs": {
685
- "question": question, "top_k": int(k), "n_sentences": int(n_sentences),
686
- "w_tfidf": float(w_tfidf), "w_bm25": float(w_bm25), "w_emb": float(w_emb),
687
- "use_llm": bool(use_llm), "model": model, "temperature": float(temperature)
688
- },
689
- "retrieval": {"hits": [], "latency_ms_retriever": latency_ms_retriever},
690
- "output": {"final_answer": final, "used_sentences": []},
691
- "latency_ms_total": int((time.time()-t0_total)*1000),
692
- "openai": None
693
- }
694
- _safe_write_jsonl(LOG_PATH, record)
695
- return final
696
-
697
- # Select sentences
698
- selected = mmr_select_sentences(question, hits, top_n=int(n_sentences), pool_per_chunk=6, lambda_div=0.7)
699
 
700
- # Header citations: short codes only, joined by '; ' (e.g., "S55; S71; S92")
701
- from urllib.parse import quote
702
-
703
-
704
-
705
- header_links = []
706
- unique_codes = set()
707
-
708
- for _, r in hits.head(6).iterrows():
709
- doc_path = r["doc_path"]
710
- filename = Path(doc_path).name
711
- short_code = _short_doc_code(doc_path)
712
-
713
- # ✅ Correct Gradio route is /file= (NOT /file/)
714
- abs_pdf = (LOCAL_PDF_DIR / filename).resolve()
715
- href = f"/file={quote('papers/' + filename)}"
716
- link = f'<a href="/file={quote("papers/" + filename)}" target="_blank" rel="noopener noreferrer">{short_code}</a>'
717
-
718
- if short_code not in unique_codes:
719
- header_links.append(link)
720
- unique_codes.add(short_code)
721
-
722
- header_cites = "; ".join(header_links)
723
-
724
- coverage_note = "" if len(unique_codes) >= 3 else (
725
- f"\n\n> Note: Only {len(unique_codes)} unique source(s) contributed. "
726
- "Add more PDFs or increase Top-K."
727
- )
728
 
729
- # Prepare retrieval list for logging (full filenames kept here)
730
- retr_list = []
731
- for _, r in hits.iterrows():
732
- retr_list.append({
733
- "doc": Path(r["doc_path"]).name,
734
- "page": _extract_page(r["text"]),
735
- "score_tfidf": float(r.get("score_tfidf", 0.0)),
736
- "score_bm25": float(r.get("score_bm25", 0.0)),
737
- "score_dense": float(r.get("score_dense", 0.0)),
738
- "combo_score": float(r.get("score", 0.0)),
739
- })
740
-
741
- # Strict quotes only (no LLM)
742
  if strict_quotes_only:
743
  if not selected:
744
- final = (
745
- "**Quoted Passages:**\n\n---\n" +
746
- "\n\n".join(hits['text'].tolist()[:2]) +
747
- f"\n\n**Citations:** {header_cites}{coverage_note}"
748
- )
749
- else:
750
- bullets = "\n- ".join(f"{s['sent']} ({s['doc']})" for s in selected)
751
- final = f"**Quoted Passages:**\n- {bullets}\n\n**Citations:** {header_cites}{coverage_note}"
752
- if include_passages:
753
- final += "\n\n---\n" + "\n\n".join(hits['text'].tolist()[:2])
754
-
755
- record = {
756
- "run_id": run_id,
757
- "ts": int(time.time()*1000),
758
- "inputs": {
759
- "question": question, "top_k": int(k), "n_sentences": int(n_sentences),
760
- "w_tfidf": float(w_tfidf), "w_bm25": float(w_bm25), "w_emb": float(w_emb),
761
- "use_llm": False, "model": None, "temperature": float(temperature)
762
- },
763
- "retrieval": {"hits": retr_list, "latency_ms_retriever": latency_ms_retriever},
764
- "output": {
765
- "final_answer": final,
766
- "used_sentences": [{"sent": s["sent"], "doc": s["doc"], "page": s["page"]} for s in selected]
767
- },
768
- "latency_ms_total": int((time.time()-t0_total)*1000),
769
- "openai": None
770
- }
771
- _safe_write_jsonl(LOG_PATH, record)
772
- return final
773
-
774
- # Extractive or LLM synthesis
775
  extractive = compose_extractive(selected)
776
- llm_usage = None
777
- llm_latency_ms = None
778
  if use_llm and selected:
779
- # Lines already carry short-code citations, e.g. "... (S92)"
780
- lines = [f"{s['sent']} ({s['doc']})" for s in selected]
781
- t0_llm = time.time()
782
- llm_text, llm_usage = synthesize_with_llm(question, lines, model=model, temperature=temperature)
783
- t1_llm = time.time()
784
- llm_latency_ms = int((t1_llm - t0_llm) * 1000)
785
-
786
  if llm_text:
787
- final = f"**Answer (LLM synthesis):** {llm_text}\n\n**Citations:** {header_cites}{coverage_note}"
788
  if include_passages:
789
- final += "\n\n---\n" + "\n\n".join(hits['text'].tolist()[:2])
790
- else:
791
- if not extractive:
792
- final = (
793
- f"**Answer:** Here are relevant passages.\n\n"
794
- f"**Citations:** {header_cites}{coverage_note}\n\n---\n" +
795
- "\n\n".join(hits['text'].tolist()[:2])
796
- )
797
- else:
798
- final = f"**Answer:** {extractive}\n\n**Citations:** {header_cites}{coverage_note}"
799
- if include_passages:
800
- final += "\n\n---\n" + "\n\n".join(hits['text'].tolist()[:2])
801
- else:
802
- if not extractive:
803
- final = (
804
- f"**Answer:** Here are relevant passages.\n\n"
805
- f"**Citations:** {header_cites}{coverage_note}\n\n---\n" +
806
- "\n\n".join(hits['text'].tolist()[:2])
807
- )
808
- else:
809
- final = f"**Answer:** {extractive}\n\n**Citations:** {header_cites}{coverage_note}"
810
- if include_passages:
811
- final += "\n\n---\n" + "\n\n".join(hits['text'].tolist()[:2])
812
-
813
- # --------- Log full run ---------
814
- prompt_toks = llm_usage.get("prompt_tokens") if llm_usage else None
815
- completion_toks = llm_usage.get("completion_tokens") if llm_usage else None
816
- cost_usd = _calc_cost_usd(prompt_toks, completion_toks)
817
-
818
- total_ms = int((time.time() - t0_total) * 1000)
819
- record = {
820
- "run_id": run_id,
821
- "ts": int(time.time()*1000),
822
- "inputs": {
823
- "question": question, "top_k": int(k), "n_sentences": int(n_sentences),
824
- "w_tfidf": float(w_tfidf), "w_bm25": float(w_bm25), "w_emb": float(w_emb),
825
- "use_llm": bool(use_llm), "model": model, "temperature": float(temperature)
826
- },
827
- "retrieval": {"hits": retr_list, "latency_ms_retriever": latency_ms_retriever},
828
- "output": {
829
- "final_answer": final,
830
- "used_sentences": [{"sent": s['sent'], "doc": s['doc'], "page": s['page']} for s in selected]
831
- },
832
- "latency_ms_total": total_ms,
833
- "latency_ms_llm": llm_latency_ms,
834
- "openai": {
835
- "prompt_tokens": prompt_toks,
836
- "completion_tokens": completion_toks,
837
- "cost_usd": cost_usd
838
- } if use_llm else None
839
- }
840
- _safe_write_jsonl(LOG_PATH, record)
841
- return final
842
 
843
  def rag_chat_fn(message, history, top_k, n_sentences, include_passages,
844
  use_llm, model_name, temperature, strict_quotes_only,
@@ -862,260 +553,24 @@ def rag_chat_fn(message, history, top_k, n_sentences, include_passages,
862
  except Exception as e:
863
  return f"RAG error: {e}"
864
 
865
- # ========================= UI (science-oriented styling) =========================
866
  CSS = """
867
- /* Science-oriented: crisp contrast + readable numerics */
868
- * {font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial;}
869
  .gradio-container {
870
- background: linear-gradient(135deg, #0b1020 0%, #0c2b1a 60%, #0a2b4d 100%) !important;
871
  }
872
- .card {background: rgba(255,255,255,0.06) !important; border: 1px solid rgba(255,255,255,0.14); border-radius: 12px;}
873
- label {color: #e8f7ff !important; text-shadow: 0 1px 0 rgba(0,0,0,0.35); cursor: pointer;}
874
- input[type="number"] {font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace;}
875
-
876
- /* Checkbox clickability fixes */
877
- input[type="checkbox"], .gr-checkbox, .gr-checkbox > * { pointer-events: auto !important; }
878
- .gr-checkbox label, .gr-check-radio label { pointer-events: auto !important; cursor: pointer; }
879
- #rag-tab input[type="checkbox"] { accent-color: #60a5fa !important; }
880
-
881
- /* RAG tab styling */
882
- #rag-tab .block, #rag-tab .group, #rag-tab .accordion {
883
- background: linear-gradient(160deg, #1f2937 0%, #14532d 55%, #0b3b68 100%) !important;
884
- border-radius: 12px;
885
- border: 1px solid rgba(255,255,255,0.14);
886
- }
887
- #rag-tab input, #rag-tab textarea, #rag-tab select, #rag-tab .scroll-hide, #rag-tab .chatbot textarea {
888
- background: rgba(17, 24, 39, 0.85) !important;
889
- border: 1px solid #60a5fa !important;
890
- color: #e5f2ff !important;
891
- }
892
- #rag-tab input[type="range"] { accent-color: #22c55e !important; }
893
- #rag-tab button { border-radius: 10px !important; font-weight: 600 !important; }
894
- #rag-tab .chatbot {
895
- background: rgba(15, 23, 42, 0.6) !important;
896
- border: 1px solid rgba(148, 163, 184, 0.35) !important;
897
- }
898
- #rag-tab .message.user {
899
- background: rgba(34, 197, 94, 0.15) !important;
900
- border-left: 3px solid #22c55e !important;
901
- }
902
- #rag-tab .message.bot {
903
- background: rgba(59, 130, 246, 0.15) !important;
904
- border-left: 3px solid #60a5fa !important;
905
- color: #eef6ff !important;
906
- }
907
-
908
- /* Evaluate tab dark/high-contrast styling */
909
- #eval-tab .block, #eval-tab .group, #eval-tab .accordion {
910
- background: linear-gradient(165deg, #0a0f1f 0%, #0d1a31 60%, #0a1c2e 100%) !important;
911
- border-radius: 12px;
912
- border: 1px solid rgba(139, 197, 255, 0.28);
913
- }
914
- #eval-tab label, #eval-tab .markdown, #eval-tab .prose, #eval-tab p, #eval-tab span {
915
- color: #e6f2ff !important;
916
- }
917
- #eval-tab input, #eval-tab .gr-file, #eval-tab .scroll-hide, #eval-tab textarea, #eval-tab select {
918
- background: rgba(8, 13, 26, 0.9) !important;
919
- border: 1px solid #3b82f6 !important;
920
- color: #dbeafe !important;
921
- }
922
- #eval-tab input[type="range"] { accent-color: #22c55e !important; }
923
- #eval-tab button {
924
- border-radius: 10px !important;
925
- font-weight: 700 !important;
926
- background: #0ea5e9 !important;
927
- color: #001321 !important;
928
- border: 1px solid #7dd3fc !important;
929
- }
930
- #eval-tab .gr-json, #eval-tab .markdown pre, #eval-tab .markdown code {
931
- background: rgba(2, 6, 23, 0.85) !important;
932
- color: #e2e8f0 !important;
933
- border: 1px solid rgba(148, 163, 184, 0.3) !important;
934
- border-radius: 10px !important;
935
- }
936
-
937
- /* Predictor output emphasis */
938
- #pred-out .wrap { font-size: 20px; font-weight: 700; color: #ecfdf5; }
939
-
940
- /* Tab header: darker blue theme for all tabs */
941
- .gradio-container .tab-nav button[role="tab"] {
942
- background: #0b1b34 !important;
943
- color: #cfe6ff !important;
944
- border: 1px solid #1e3a8a !important;
945
- }
946
- .gradio-container .tab-nav button[role="tab"][aria-selected="true"] {
947
- background: #0e2a57 !important;
948
- color: #e0f2fe !important;
949
- border-color: #3b82f6 !important;
950
- }
951
-
952
- /* Evaluate tab: enforce dark-blue text for labels/marks */
953
- #eval-tab .label,
954
- #eval-tab label,
955
- #eval-tab .gr-slider .label,
956
- #eval-tab .wrap .label,
957
- #eval-tab .prose,
958
- #eval-tab .markdown,
959
- #eval-tab p,
960
- #eval-tab span {
961
- color: #cfe6ff !important;
962
- }
963
-
964
- /* Target the specific k-slider label strongly */
965
- #k-slider .label,
966
- #k-slider label,
967
- #k-slider .wrap .label {
968
- color: #cfe6ff !important;
969
- text-shadow: 0 1px 0 rgba(0,0,0,0.35);
970
- }
971
-
972
- /* Slider track/thumb (dark blue gradient + blue thumb) */
973
- #eval-tab input[type="range"] {
974
- accent-color: #3b82f6 !important;
975
- }
976
-
977
- /* WebKit */
978
- #eval-tab input[type="range"]::-webkit-slider-runnable-track {
979
- height: 6px;
980
- background: linear-gradient(90deg, #0b3b68, #1e3a8a);
981
- border-radius: 4px;
982
- }
983
- #eval-tab input[type="range"]::-webkit-slider-thumb {
984
- -webkit-appearance: none;
985
- appearance: none;
986
- margin-top: -6px;
987
- width: 18px; height: 18px;
988
- background: #1d4ed8;
989
- border: 1px solid #60a5fa;
990
- border-radius: 50%;
991
- }
992
-
993
- /* Firefox */
994
- #eval-tab input[type="range"]::-moz-range-track {
995
- height: 6px;
996
- background: linear-gradient(90deg, #0b3b68, #1e3a8a);
997
- border-radius: 4px;
998
- }
999
- #eval-tab input[type="range"]::-moz-range-thumb {
1000
- width: 18px; height: 18px;
1001
- background: #1d4ed8;
1002
- border: 1px solid #60a5fa;
1003
- border-radius: 50%;
1004
- }
1005
-
1006
- /* ======== PATCH: Style the File + JSON outputs by ID ======== */
1007
- #perq-file, #agg-file {
1008
- background: rgba(8, 13, 26, 0.9) !important;
1009
- border: 1px solid #3b82f6 !important;
1010
- border-radius: 12px !important;
1011
- padding: 8px !important;
1012
- }
1013
- #perq-file * , #agg-file * { color: #dbeafe !important; }
1014
- #perq-file a, #agg-file a {
1015
- background: #0e2a57 !important;
1016
- color: #e0f2fe !important;
1017
- border: 1px solid #60a5fa !important;
1018
- border-radius: 8px !important;
1019
- padding: 6px 10px !important;
1020
- text-decoration: none !important;
1021
- }
1022
- #perq-file a:hover, #agg-file a:hover {
1023
- background: #10356f !important;
1024
- border-color: #93c5fd !important;
1025
- }
1026
- /* File preview wrappers (covers multiple Gradio render modes) */
1027
- #perq-file .file-preview, #agg-file .file-preview,
1028
- #perq-file .wrap, #agg-file .wrap {
1029
- background: rgba(2, 6, 23, 0.85) !important;
1030
- border-radius: 10px !important;
1031
- border: 1px solid rgba(148,163,184,.3) !important;
1032
- }
1033
-
1034
- /* JSON output: dark panel + readable text */
1035
- #agg-json {
1036
- background: rgba(2, 6, 23, 0.85) !important;
1037
- border: 1px solid rgba(148,163,184,.35) !important;
1038
- border-radius: 12px !important;
1039
- padding: 8px !important;
1040
- }
1041
- #agg-json *, #agg-json .json, #agg-json .wrap { color: #e6f2ff !important; }
1042
- #agg-json pre, #agg-json code {
1043
- background: rgba(4, 10, 24, 0.9) !important;
1044
- color: #e2e8f0 !important;
1045
- border: 1px solid rgba(148,163,184,.35) !important;
1046
- border-radius: 10px !important;
1047
- }
1048
- /* Tree/overflow modes */
1049
- #agg-json [data-testid="json-tree"],
1050
- #agg-json [role="tree"],
1051
- #agg-json .overflow-auto {
1052
- background: rgba(4, 10, 24, 0.9) !important;
1053
- color: #e6f2ff !important;
1054
- border-radius: 10px !important;
1055
- border: 1px solid rgba(148,163,184,.35) !important;
1056
- }
1057
-
1058
- /* Eval log markdown */
1059
- #eval-log, #eval-log * { color: #cfe6ff !important; }
1060
- #eval-log pre, #eval-log code {
1061
- background: rgba(2, 6, 23, 0.85) !important;
1062
- color: #e2e8f0 !important;
1063
- border: 1px solid rgba(148,163,184,.3) !important;
1064
- border-radius: 10px !important;
1065
- }
1066
-
1067
- /* When Evaluate tab is active and JS has added .eval-active, bump contrast subtly */
1068
- #eval-tab.eval-active .block,
1069
- #eval-tab.eval-active .group {
1070
- border-color: #60a5fa !important;
1071
- }
1072
- #eval-tab.eval-active .label {
1073
- color: #e6f2ff !important;
1074
- }
1075
-
1076
- /* --- THE UNIVERSAL DROPDOWN OVERRIDE --- */
1077
-
1078
- /* 1. All boxes show white text on the dark background */
1079
- #filler-dropdown .single-select, #filler-dropdown input,
1080
- #dim-dropdown .single-select, #dim-dropdown input,
1081
- #dim2-dropdown .single-select, #dim2-dropdown input,
1082
- #current-dropdown .single-select, #current-dropdown input {
1083
- color: #ffffff !important;
1084
- -webkit-text-fill-color: #ffffff !important;
1085
- }
1086
-
1087
- /* 2. All dropdown menus (the pop-outs) have a white background */
1088
- #filler-dropdown .options,
1089
- #dim-dropdown .options,
1090
- #dim2-dropdown .options,
1091
- #current-dropdown .options {
1092
- background-color: #ffffff !important;
1093
- }
1094
-
1095
- /* 3. All items in the lists are forced to PURE BLACK */
1096
- #filler-dropdown .item, #filler-dropdown .item span,
1097
- #dim-dropdown .item, #dim-dropdown .item span,
1098
- #dim2-dropdown .item, #dim2-dropdown .item span,
1099
- #current-dropdown .item, #current-dropdown .item span,
1100
- .gr-dropdown .options .item, .gr-dropdown .options .item * {
1101
- color: #000000 !important;
1102
- -webkit-text-fill-color: #000000 !important;
1103
- }
1104
-
1105
- /* 4. Hover effect for all dropdowns */
1106
- .gr-dropdown .item:hover {
1107
- background-color: #dbeafe !important;
1108
- }
1109
-
1110
  """
1111
 
1112
  theme = gr.themes.Soft(
1113
  primary_hue="blue",
1114
  neutral_hue="green"
1115
  ).set(
1116
- body_background_fill="#0b1020",
1117
  body_text_color="#e0f2fe",
1118
- input_background_fill="#0f172a",
1119
  input_border_color="#1e40af",
1120
  button_primary_background_fill="#2563eb",
1121
  button_primary_text_color="#ffffff",
@@ -1124,37 +579,12 @@ theme = gr.themes.Soft(
1124
  )
1125
 
1126
  with gr.Blocks(css=CSS, theme=theme, fill_height=True) as demo:
1127
- # Optional: JS to toggle .eval-active when Evaluate tab selected
1128
- gr.HTML("""
1129
- <script>
1130
- (function(){
1131
- const applyEvalActive = () => {
1132
- const selected = document.querySelector('.tab-nav button[role="tab"][aria-selected="true"]');
1133
- const evalPanel = document.querySelector('#eval-tab');
1134
- if (!evalPanel) return;
1135
- if (selected && /Evaluate/.test(selected.textContent)) {
1136
- evalPanel.classList.add('eval-active');
1137
- } else {
1138
- evalPanel.classList.remove('eval-active');
1139
- }
1140
- };
1141
- document.addEventListener('click', function(e) {
1142
- if (e.target && e.target.getAttribute('role') === 'tab') {
1143
- setTimeout(applyEvalActive, 50);
1144
- }
1145
- }, true);
1146
- document.addEventListener('DOMContentLoaded', applyEvalActive);
1147
- setTimeout(applyEvalActive, 300);
1148
- })();
1149
- </script>
1150
- """)
1151
-
1152
  gr.Markdown(
1153
  "<h1 style='margin:0'>Self-Sensing Concrete Assistant</h1>"
1154
  "<p style='opacity:.9'>"
1155
- "Left: ML prediction for Stress Gauge Factor (original scale, MPa<sup>-1</sup>). "
1156
- "Right: Literature Q&A via Hybrid RAG (BM25 + TF-IDF + optional dense) with MMR sentence selection. "
1157
- "Answers cite short document codes (e.g., <code>S71</code>, <code>S92</code>)."
1158
  "</p>"
1159
  )
1160
 
@@ -1164,26 +594,27 @@ with gr.Blocks(css=CSS, theme=theme, fill_height=True) as demo:
1164
  with gr.Row():
1165
  with gr.Column(scale=7):
1166
  with gr.Accordion("Primary conductive filler", open=True, elem_classes=["card"]):
1167
- f1_type = gr.Dropdown(TYPE_CHOICES,label="Filler 1 Type *", value="CNT", allow_custom_value=True, elem_id="filler-dropdown")
1168
- f1_diam = gr.Number(label="Filler 1 Diameter (µm) *")
1169
- f1_len = gr.Number(label="Filler 1 Length (mm) *")
1170
- cf_conc = gr.Number(label=f"{CF_COL} *", info="Weight percent of total binder")
1171
- f1_dim = gr.Dropdown(DIM_CHOICES, value=CANON_NA, label="Filler 1 Dimensionality *",elem_id="dim-dropdown")
1172
 
1173
  with gr.Accordion("Secondary filler (optional)", open=False, elem_classes=["card"]):
1174
  f2_type = gr.Textbox(label="Filler 2 Type", placeholder="Optional")
1175
  f2_diam = gr.Number(label="Filler 2 Diameter (µm)")
1176
  f2_len = gr.Number(label="Filler 2 Length (mm)")
1177
- f2_dim = gr.Dropdown(DIM_CHOICES, value=CANON_NA, label="Filler 2 Dimensionality", elem_id="dim2-dropdown")
 
1178
  with gr.Accordion("Mix design & specimen", open=False, elem_classes=["card"]):
1179
- spec_vol = gr.Number(label="Specimen Volume (mm3) *")
1180
- probe_cnt = gr.Number(label="Probe Count *")
1181
- probe_mat = gr.Textbox(label="Probe Material *", placeholder="e.g., Copper, Silver paste")
1182
- wb = gr.Number(label="W/B *")
1183
- sb = gr.Number(label="S/B *")
1184
- gauge_len = gr.Number(label="Gauge Length (mm) *")
1185
- curing = gr.Textbox(label="Curing Condition *", placeholder="e.g., 28d water, 20°C")
1186
- n_fillers = gr.Number(label="Number of Fillers *")
1187
 
1188
  with gr.Accordion("Processing", open=False, elem_classes=["card"]):
1189
  dry_temp = gr.Number(label="Drying Temperature (°C)")
@@ -1191,14 +622,13 @@ with gr.Blocks(css=CSS, theme=theme, fill_height=True) as demo:
1191
 
1192
  with gr.Accordion("Mechanical & electrical loading", open=False, elem_classes=["card"]):
1193
  load_rate = gr.Number(label="Loading Rate (MPa/s)")
1194
- E_mod = gr.Number(label="Modulus of Elasticity (GPa) *")
1195
- current = gr.Dropdown(CURRENT_CHOICES, value=CANON_NA, label="Current Type", elem_id="current-dropdown")
1196
  voltage = gr.Number(label="Applied Voltage (V)")
1197
 
1198
  with gr.Column(scale=5):
1199
  with gr.Group(elem_classes=["card"]):
1200
- out_pred = gr.Number(label="Predicted Stress GF (MPa-1)", value=0.0, precision=6, elem_id="pred-out")
1201
- gr.Markdown(f"<small>{MODEL_STATUS}</small>")
1202
  with gr.Row():
1203
  btn_pred = gr.Button("Predict", variant="primary")
1204
  btn_clear = gr.Button("Clear")
@@ -1206,14 +636,14 @@ with gr.Blocks(css=CSS, theme=theme, fill_height=True) as demo:
1206
 
1207
  with gr.Accordion("About this model", open=False, elem_classes=["card"]):
1208
  gr.Markdown(
1209
- "- Pipeline: ColumnTransformer (RobustScaler + OneHot) XGBoost\n"
1210
- "- Target: Stress GF (MPa<sup>-1</sup>) on original scale (model may train on log1p; saved flag used at inference).\n"
1211
  "- Missing values are safely imputed per-feature.\n"
1212
  "- Trained columns:\n"
1213
- f" `{', '.join(MAIN_VARIABLES)}`",
1214
- elem_classes=["prose"]
1215
  )
1216
 
 
1217
  inputs_in_order = [
1218
  f1_type, f1_diam, f1_len, cf_conc,
1219
  f1_dim, f2_type, f2_diam, f2_len,
@@ -1228,115 +658,38 @@ with gr.Blocks(css=CSS, theme=theme, fill_height=True) as demo:
1228
  return predict_fn(**data)
1229
 
1230
  btn_pred.click(_predict_wrapper, inputs=inputs_in_order, outputs=out_pred)
1231
- btn_clear.click(lambda: _clear_all(), inputs=None, outputs=inputs_in_order).then(lambda: 0.0, outputs=out_pred)
1232
  btn_demo.click(lambda: _fill_example(), inputs=None, outputs=inputs_in_order)
1233
 
1234
  # ------------------------- Literature Tab -------------------------
1235
- with gr.Tab("📚 Ask the Literature (Hybrid RAG + MMR)", elem_id="rag-tab"):
1236
- pdf_count = len(list(LOCAL_PDF_DIR.glob("**/*.pdf")))
1237
  gr.Markdown(
1238
- f"Using local folder <code>papers/</code> **{pdf_count} PDF(s)** indexed. "
1239
- "Upload more PDFs and reload the Space to expand coverage. "
1240
- "Answers cite short document codes such as <code>S71</code>, <code>S92</code>."
1241
  )
1242
  with gr.Row():
1243
  top_k = gr.Slider(5, 12, value=8, step=1, label="Top-K chunks")
1244
  n_sentences = gr.Slider(2, 6, value=4, step=1, label="Answer length (sentences)")
1245
- include_passages = gr.Checkbox(value=False, label="Include supporting passages", interactive=True)
1246
-
1247
  with gr.Accordion("Retriever weights (advanced)", open=False):
1248
  w_tfidf = gr.Slider(0.0, 1.0, value=W_TFIDF_DEFAULT, step=0.05, label="TF-IDF weight")
1249
  w_bm25 = gr.Slider(0.0, 1.0, value=W_BM25_DEFAULT, step=0.05, label="BM25 weight")
1250
- w_emb = gr.Slider(0.0, 1.0, value=(0.0 if not USE_DENSE else 0.40), step=0.05, label="Dense weight (set 0 if disabled)")
1251
-
1252
- # Hidden states (unchanged)
1253
- state_use_llm = gr.State(LLM_AVAILABLE)
1254
- state_model_name = gr.State(os.getenv("OPENAI_MODEL", OPENAI_MODEL))
1255
- state_temperature = gr.State(0.2)
1256
- state_strict = gr.State(False)
1257
-
1258
  gr.ChatInterface(
1259
  fn=rag_chat_fn,
1260
- additional_inputs=[
1261
- top_k, n_sentences, include_passages,
1262
- state_use_llm, state_model_name, state_temperature, state_strict,
1263
- w_tfidf, w_bm25, w_emb
1264
- ],
1265
  title="Literature Q&A",
1266
- description="Hybrid retrieval with diversity. Answers carry inline short-code citations (e.g., (S92), (S71))."
1267
  )
1268
 
1269
- # ====== Evaluate (Gold vs Logs) ======
1270
- with gr.Tab("📏 Evaluate (Gold vs Logs)", elem_id="eval-tab"):
1271
- gr.Markdown("Upload your **gold.csv** and compute metrics against the app logs.")
1272
- with gr.Row():
1273
- gold_file = gr.File(label="gold.csv", file_types=[".csv"], interactive=True)
1274
- k_slider = gr.Slider(3, 12, value=8, step=1, label="k for Hit/Recall/nDCG", elem_id="k-slider")
1275
- with gr.Row():
1276
- btn_eval = gr.Button("Compute Metrics", variant="primary")
1277
- with gr.Row():
1278
- out_perq = gr.File(label="Per-question metrics (CSV)", elem_id="perq-file")
1279
- out_agg = gr.File(label="Aggregate metrics (JSON)", elem_id="agg-file")
1280
- out_json = gr.JSON(label="Aggregate summary", elem_id="agg-json")
1281
- out_log = gr.Markdown(label="Run log", elem_id="eval-log")
1282
-
1283
- def _run_eval_inproc(gold_path: str, k: int = 8):
1284
- import json as _json
1285
- out_dir = str(ARTIFACT_DIR)
1286
- logs = str(LOG_PATH)
1287
- cmd = [
1288
- sys.executable, "rag_eval_metrics.py",
1289
- "--gold_csv", gold_path,
1290
- "--logs_jsonl", logs,
1291
- "--k", str(k),
1292
- "--out_dir", out_dir
1293
- ]
1294
- try:
1295
- p = subprocess.run(cmd, capture_output=True, text=True, check=False)
1296
- stdout = p.stdout or ""
1297
- stderr = p.stderr or ""
1298
- perq = ARTIFACT_DIR / "metrics_per_question.csv"
1299
- agg = ARTIFACT_DIR / "metrics_aggregate.json"
1300
- agg_json = {}
1301
- if agg.exists():
1302
- agg_json = _json.loads(agg.read_text(encoding="utf-8"))
1303
- report = "```\n" + (stdout.strip() or "(no stdout)") + ("\n" + stderr.strip() if stderr else "") + "\n```"
1304
- return (str(perq) if perq.exists() else None,
1305
- str(agg) if agg.exists() else None,
1306
- agg_json,
1307
- report)
1308
- except Exception as e:
1309
- return (None, None, {}, f"**Eval error:** {e}")
1310
-
1311
- def _eval_wrapper(gf, k):
1312
- from pathlib import Path as _Path
1313
- if gf is None:
1314
- default_gold = _Path("gold.csv")
1315
- if not default_gold.exists():
1316
- return None, None, {}, "**No gold.csv provided or found in repo root.**"
1317
- gold_path = str(default_gold)
1318
- else:
1319
- gold_path = gf.name
1320
- return _run_eval_inproc(gold_path, int(k))
1321
-
1322
- btn_eval.click(_eval_wrapper, inputs=[gold_file, k_slider],
1323
- outputs=[out_perq, out_agg, out_json, out_log])
1324
-
1325
  # ------------- Launch -------------
1326
  if __name__ == "__main__":
1327
- # 1. Start the Chatbot (This is what gives you the link)
1328
- # If using Gradio:
1329
- demo.launch()
1330
-
1331
- # Or if using Flask:
1332
- # app.run(debug=True)
1333
-
1334
- # 2. Everything below here only runs AFTER the server stops
1335
- # (or might not run at all depending on how the server handles the exit)
1336
- import os as _os
1337
- import pandas as _pd
1338
- folder = "papers"
1339
- files = sorted(_os.listdir(folder)) if _os.path.exists(folder) else []
1340
- _pd.DataFrame({"doc": files}).to_csv("paper_list.csv", index=False)
1341
- print("✅ Saved paper_list.csv with", len(files), "papers")
1342
-
 
1
+ # vmm
2
  # Self-Sensing Concrete Assistant — Predictor (XGB) + Hybrid RAG
3
+ # - Predictor tab: identical behavior to your "second code"
4
+ # - Literature tab: from your "first code" (Hybrid RAG + MMR)
5
+ # - Hugging Face friendly: online PDF fetching OFF by default
 
 
 
 
6
  # ================================================================
7
 
8
  # ---------------------- Runtime flags (HF-safe) ----------------------
 
12
  os.environ["TOKENIZERS_PARALLELISM"] = "false"
13
 
14
  # ------------------------------- Imports ------------------------------
15
+ import re, time, joblib, warnings, json
16
  from pathlib import Path
17
+ from typing import List, Dict, Any
18
 
19
  import numpy as np
20
  import pandas as pd
 
35
  BM25Okapi = None
36
  print("rank_bm25 not installed; BM25 disabled (TF-IDF still works).")
37
 
38
+ # Optional OpenAI (for LLM paraphrase)
39
  OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
40
+ OPENAI_MODEL = os.getenv("OPENAI_MODEL", "gpt-4o-mini").strip().strip('"').strip("'")
41
+
42
  try:
43
  from openai import OpenAI
44
  except Exception:
45
  OpenAI = None
46
 
47
+ print("openAI: ", OpenAI)
 
48
 
49
+ # ========================= Predictor (kept same as 2nd) =========================
50
  CF_COL = "Conductive Filler Conc. (wt%)"
51
  TARGET_COL = "Stress GF (MPa-1)"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
 
53
  MAIN_VARIABLES = [
54
  "Filler 1 Type",
 
105
  "Current Type"
106
  }
107
 
108
+ DIM_CHOICES = ["0D", "1D", "2D", "3D", "NA"]
109
+ CURRENT_CHOICES = ["DC", "AC", "NA"]
110
 
111
  MODEL_CANDIDATES = [
112
  "stress_gf_xgb.joblib",
113
  "models/stress_gf_xgb.joblib",
114
  "/home/user/app/stress_gf_xgb.joblib",
 
115
  ]
116
 
117
+ def _load_model_or_error():
118
+ for p in MODEL_CANDIDATES:
 
 
 
 
 
119
  if os.path.exists(p):
120
  try:
121
+ return joblib.load(p)
 
 
 
122
  except Exception as e:
123
+ return f"Could not load model from {p}: {e}"
124
+ return ("Model file not found. Upload your trained pipeline as "
125
+ "stress_gf_xgb.joblib (or put it in models/).")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
 
127
  def _coerce_to_row(form_dict: dict) -> pd.DataFrame:
128
  row = {}
129
  for col in MAIN_VARIABLES:
130
  v = form_dict.get(col, None)
131
  if col in NUMERIC_COLS:
132
+ if v in ("", None):
133
+ row[col] = np.nan
134
+ else:
135
+ try:
136
+ row[col] = float(v)
137
+ except Exception:
138
+ row[col] = np.nan
139
  else:
140
+ row[col] = "" if v in (None, "NA") else str(v).strip()
 
141
  return pd.DataFrame([row], columns=MAIN_VARIABLES)
142
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
143
  def predict_fn(**kwargs):
144
+ mdl = _load_model_or_error()
145
+ if isinstance(mdl, str):
146
+ return mdl
 
 
 
 
 
147
  X_new = _coerce_to_row(kwargs)
 
148
  try:
149
+ y_log = mdl.predict(X_new) # model predicts log1p(target)
150
+ y = float(np.expm1(y_log)[0]) # back to original scale MPa^-1
151
+ if -1e-10 < y < 0:
152
+ y = 0.0
153
+ return y
 
 
154
  except Exception as e:
155
+ return f"Prediction error: {e}"
 
 
156
 
157
  EXAMPLE = {
158
  "Filler 1 Type": "CNT",
 
161
  "Filler 1 Length (mm)": 1.2,
162
  CF_COL: 0.5,
163
  "Filler 2 Type": "",
164
+ "Filler 2 Dimensionality": "NA",
165
  "Filler 2 Diameter (µm)": None,
166
  "Filler 2 Length (mm)": None,
167
  "Specimen Volume (mm3)": 1000,
 
189
  if col in NUMERIC_COLS:
190
  cleared.append(None)
191
  elif col in {"Filler 1 Dimensionality", "Filler 2 Dimensionality"}:
192
+ cleared.append("NA")
193
  elif col == "Current Type":
194
+ cleared.append("NA")
195
  else:
196
  cleared.append("")
197
  return cleared
198
 
199
+ # ========================= Hybrid RAG (from 1st code) =========================
200
+ # Configuration
201
  ARTIFACT_DIR = Path("rag_artifacts"); ARTIFACT_DIR.mkdir(exist_ok=True)
202
  TFIDF_VECT_PATH = ARTIFACT_DIR / "tfidf_vectorizer.joblib"
203
  TFIDF_MAT_PATH = ARTIFACT_DIR / "tfidf_matrix.joblib"
 
205
  EMB_NPY_PATH = ARTIFACT_DIR / "chunk_embeddings.npy"
206
  RAG_META_PATH = ARTIFACT_DIR / "chunks.parquet"
207
 
208
+ # PDF source (HF-safe: rely on local /papers by default)
209
+ LOCAL_PDF_DIR = Path("./literature_pdfs"); LOCAL_PDF_DIR.mkdir(exist_ok=True)
210
  USE_ONLINE_SOURCES = os.getenv("USE_ONLINE_SOURCES", "false").lower() == "true"
211
 
212
+ # Retrieval weights
213
  W_TFIDF_DEFAULT = 0.50 if not USE_DENSE else 0.30
214
  W_BM25_DEFAULT = 0.50 if not USE_DENSE else 0.30
215
+ W_EMB_DEFAULT = 0.00 if not USE_DENSE else 0.40
216
 
217
+ # Simple text processing
218
  _SENT_SPLIT_RE = re.compile(r"(?<=[.!?])\s+|\n+")
219
  TOKEN_RE = re.compile(r"[A-Za-z0-9_#+\-/\.%]+")
220
  def sent_split(text: str) -> List[str]:
 
223
  def tokenize(text: str) -> List[str]:
224
  return [t.lower() for t in TOKEN_RE.findall(text)]
225
 
226
+ # PDF text extraction (PyMuPDF preferred; pypdf fallback)
227
  def _extract_pdf_text(pdf_path: Path) -> str:
228
  try:
229
  import fitz
 
265
  USE_DENSE = False
266
  return None
267
 
268
+ # Build or load index
269
  def build_or_load_hybrid(pdf_dir: Path):
 
270
  have_cache = (TFIDF_VECT_PATH.exists() and TFIDF_MAT_PATH.exists()
271
  and RAG_META_PATH.exists()
272
  and (BM25_TOK_PATH.exists() or BM25Okapi is None)
 
290
  rows.append({"doc_path": str(pdf), "chunk_id": i, "text": ch})
291
  all_tokens.append(tokenize(ch))
292
  if not rows:
293
+ # create empty stub to avoid crashes; UI will message user to upload PDFs
294
  meta = pd.DataFrame(columns=["doc_path", "chunk_id", "text"])
295
  vectorizer = None; X_tfidf = None; emb = None; all_tokens = None
296
  return vectorizer, X_tfidf, meta, all_tokens, emb
297
 
298
  meta = pd.DataFrame(rows)
299
+
300
  from sklearn.feature_extraction.text import TfidfVectorizer
301
  vectorizer = TfidfVectorizer(
302
  ngram_range=(1,2),
 
320
  print("Dense embedding failed:", e)
321
  emb = None
322
 
323
+ # Save artifacts
324
  joblib.dump(vectorizer, TFIDF_VECT_PATH)
325
  joblib.dump(X_tfidf, TFIDF_MAT_PATH)
326
  if BM25Okapi is not None:
327
  joblib.dump(all_tokens, BM25_TOK_PATH)
328
  meta.to_parquet(RAG_META_PATH, index=False)
329
+
330
  return vectorizer, X_tfidf, meta, all_tokens, emb
331
 
332
  tfidf_vectorizer, tfidf_matrix, rag_meta, bm25_tokens, emb_matrix = build_or_load_hybrid(LOCAL_PDF_DIR)
 
334
  st_query_model = _safe_init_st_model(os.getenv("EMB_MODEL_NAME", "sentence-transformers/all-MiniLM-L6-v2"))
335
 
336
  def _extract_page(text_chunk: str) -> str:
 
337
  m = list(re.finditer(r"\[\[PAGE=(\d+)\]\]", text_chunk or ""))
338
  return (m[-1].group(1) if m else "?")
339
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
340
  def hybrid_search(query: str, k=8, w_tfidf=W_TFIDF_DEFAULT, w_bm25=W_BM25_DEFAULT, w_emb=W_EMB_DEFAULT):
341
  if rag_meta is None or rag_meta.empty:
342
  return pd.DataFrame()
 
363
 
364
  # BM25 scores
365
  if bm25 is not None:
366
+ q_tokens = [t.lower() for t in re.findall(r"[A-Za-z0-9_#+\-/\.%]+", query)]
367
  bm25_scores = np.array(bm25.get_scores(q_tokens), dtype=float)
368
  else:
369
  bm25_scores = np.zeros(len(rag_meta), dtype=float); w_bm25 = 0.0
 
395
  return [s for s in sents if 6 <= len(s.split()) <= 60]
396
 
397
  def mmr_select_sentences(question: str, hits: pd.DataFrame, top_n=4, pool_per_chunk=6, lambda_div=0.7):
 
 
 
 
 
 
 
398
  pool = []
399
  for _, row in hits.iterrows():
400
+ doc = Path(row["doc_path"]).name
401
  page = _extract_page(row["text"])
402
+ for s in split_sentences(row["text"])[:pool_per_chunk]:
403
+ pool.append({"sent": s, "doc": doc, "page": page})
 
 
 
 
404
  if not pool:
405
  return []
406
 
 
407
  sent_texts = [p["sent"] for p in pool]
408
+
409
+ # Embedding-based relevance if available, else TF-IDF
410
  use_dense = USE_DENSE and st_query_model is not None
411
+ if use_dense:
412
+ try:
413
  from sklearn.preprocessing import normalize as sk_normalize
414
+ texts = [question] + sent_texts
415
+ enc = st_query_model.encode(texts, convert_to_numpy=True)
416
  q_vec = sk_normalize(enc[:1])[0]
417
  S = sk_normalize(enc[1:])
418
  rel = (S @ q_vec)
419
  def sim_fn(i, j): return float(S[i] @ S[j])
420
+ except Exception:
421
+ use_dense = False
 
 
 
 
 
 
 
 
 
 
422
 
423
+ if not use_dense:
424
+ from sklearn.feature_extraction.text import TfidfVectorizer
425
+ vect = TfidfVectorizer().fit(sent_texts + [question])
426
+ Q = vect.transform([question]); S = vect.transform(sent_texts)
427
+ rel = (S @ Q.T).toarray().ravel()
428
+ def sim_fn(i, j): return float((S[i] @ S[j].T).toarray()[0, 0])
429
 
430
+ selected, selected_idx = [], []
431
  remain = list(range(len(pool)))
 
 
432
  first = int(np.argmax(rel))
433
+ selected.append(pool[first]); selected_idx.append(first); remain.remove(first)
 
 
434
 
435
+ while len(selected) < top_n and remain:
 
 
436
  cand_scores = []
437
  for i in remain:
438
+ sim_to_sel = max(sim_fn(i, j) for j in selected_idx) if selected_idx else 0.0
439
+ score = lambda_div * rel[i] - (1 - lambda_div) * sim_to_sel
440
  cand_scores.append((score, i))
 
 
441
  cand_scores.sort(reverse=True)
442
+ best_i = cand_scores[0][1]
443
+ selected.append(pool[best_i]); selected_idx.append(best_i); remain.remove(best_i)
 
 
 
444
  return selected
445
 
446
  def compose_extractive(selected: List[Dict[str, Any]]) -> str:
447
  if not selected:
448
  return ""
449
+ return " ".join(f"{s['sent']} ({s['doc']}, p.{s['page']})" for s in selected)
 
 
 
 
 
 
 
 
 
 
 
 
 
450
 
451
+ def synthesize_with_llm(question: str, sentence_lines: List[str], model: str = None, temperature: float = 0.2) -> str:
452
+ if OPENAI_API_KEY is None or OpenAI is None:
453
  return None
454
+ print("calling LLM api")
 
 
 
 
 
455
  client = OpenAI(api_key=OPENAI_API_KEY)
456
  model = model or OPENAI_MODEL
457
+ print("using: ", model)
458
  SYSTEM_PROMPT = (
459
  "You are a scientific assistant for self-sensing cementitious materials.\n"
460
  "Answer STRICTLY using the provided sentences.\n"
461
  "Do not invent facts. Keep it concise (3–6 sentences).\n"
462
+ "Retain inline citations like (Doc.pdf, p.X) exactly as given."
463
  )
464
  user_prompt = (
465
  f"Question: {question}\n\n"
 
475
  ],
476
  temperature=temperature,
477
  )
478
+ print(resp.output_text)
479
+ return getattr(resp, "output_text", None) or str(resp)
480
+ except Exception as e:
481
+ print("error in LLM synthesis:", e)
482
+ return None
483
+
 
 
 
 
 
 
 
484
 
485
  def rag_reply(
486
  question: str,
487
  k: int = 8,
488
  n_sentences: int = 4,
489
  include_passages: bool = False,
490
+ use_llm: bool = True,
491
+ model: str = "gpt-4o-mini",
492
  temperature: float = 0.2,
493
  strict_quotes_only: bool = False,
494
  w_tfidf: float = W_TFIDF_DEFAULT,
495
  w_bm25: float = W_BM25_DEFAULT,
496
  w_emb: float = W_EMB_DEFAULT
497
  ) -> str:
 
 
 
 
 
498
  hits = hybrid_search(question, k=k, w_tfidf=w_tfidf, w_bm25=w_bm25, w_emb=w_emb)
 
 
 
499
  if hits is None or hits.empty:
500
+ return "No indexed PDFs found. Upload PDFs to the 'papers/' folder and reload the Space."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
501
 
502
+ selected = mmr_select_sentences(question, hits, top_n=int(n_sentences), pool_per_chunk=6, lambda_div=0.7)
503
+ header_cites = "; ".join(f"{Path(r['doc_path']).name} (p.{_extract_page(r['text'])})" for _, r in hits.head(6).iterrows())
504
+ srcs = {Path(r['doc_path']).name for _, r in hits.iterrows()}
505
+ coverage_note = "" if len(srcs) >= 3 else f"\n\n> Note: Only {len(srcs)} unique source(s) contributed. Add more PDFs or increase Top-K."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
506
 
 
 
 
 
 
 
 
 
 
 
 
 
 
507
  if strict_quotes_only:
508
  if not selected:
509
+ return f"**Quoted Passages:**\n\n---\n" + "\n\n".join(hits['text'].tolist()[:2]) + f"\n\n**Citations:** {header_cites}{coverage_note}"
510
+ msg = "**Quoted Passages:**\n- " + "\n- ".join(f"{s['sent']} ({s['doc']}, p.{s['page']})" for s in selected)
511
+ msg += f"\n\n**Citations:** {header_cites}{coverage_note}"
512
+ if include_passages:
513
+ msg += "\n\n---\n" + "\n\n".join(hits['text'].tolist()[:2])
514
+ return msg
515
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
516
  extractive = compose_extractive(selected)
 
 
517
  if use_llm and selected:
518
+ lines = [f"{s['sent']} ({s['doc']}, p.{s['page']})" for s in selected]
519
+ llm_text = synthesize_with_llm(question, lines, model=model, temperature=temperature)
 
 
 
 
 
520
  if llm_text:
521
+ msg = f"**Answer (LLM synthesis):** {llm_text}\n\n**Citations:** {header_cites}{coverage_note}"
522
  if include_passages:
523
+ msg += "\n\n---\n" + "\n\n".join(hits['text'].tolist()[:2])
524
+ return msg
525
+
526
+ if not extractive:
527
+ return f"**Answer:** Here are relevant passages.\n\n**Citations:** {header_cites}{coverage_note}\n\n---\n" + "\n\n".join(hits['text'].tolist()[:2])
528
+
529
+ msg = f"**Answer:** {extractive}\n\n**Citations:** {header_cites}{coverage_note}"
530
+ if include_passages:
531
+ msg += "\n\n---\n" + "\n\n".join(hits['text'].tolist()[:2])
532
+ return msg
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
533
 
534
  def rag_chat_fn(message, history, top_k, n_sentences, include_passages,
535
  use_llm, model_name, temperature, strict_quotes_only,
 
553
  except Exception as e:
554
  return f"RAG error: {e}"
555
 
556
+ # ========================= UI (predictor styling kept) =========================
557
  CSS = """
558
+ /* Blue to green gradient background */
 
559
  .gradio-container {
560
+ background: linear-gradient(135deg, #1e3a8a 0%, #166534 60%, #15803d 100%) !important;
561
  }
562
+ * {font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial;}
563
+ .card {background: rgba(255,255,255,0.07) !important; border: 1px solid rgba(255,255,255,0.12);}
564
+ label.svelte-1ipelgc {color: #e0f2fe !important;}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
565
  """
566
 
567
  theme = gr.themes.Soft(
568
  primary_hue="blue",
569
  neutral_hue="green"
570
  ).set(
571
+ body_background_fill="#1e3a8a",
572
  body_text_color="#e0f2fe",
573
+ input_background_fill="#172554",
574
  input_border_color="#1e40af",
575
  button_primary_background_fill="#2563eb",
576
  button_primary_text_color="#ffffff",
 
579
  )
580
 
581
  with gr.Blocks(css=CSS, theme=theme, fill_height=True) as demo:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
582
  gr.Markdown(
583
  "<h1 style='margin:0'>Self-Sensing Concrete Assistant</h1>"
584
  "<p style='opacity:.9'>"
585
+ "Left tab: ML prediction for Stress Gauge Factor (kept identical to your deployed predictor). "
586
+ "Right tab: Literature Q&A via Hybrid RAG (BM25 + TF-IDF + optional dense) with MMR sentence selection. "
587
+ "Upload PDFs into <code>papers/</code> in your Space repo."
588
  "</p>"
589
  )
590
 
 
594
  with gr.Row():
595
  with gr.Column(scale=7):
596
  with gr.Accordion("Primary conductive filler", open=True, elem_classes=["card"]):
597
+ f1_type = gr.Textbox(label="Filler 1 Type", placeholder="e.g., CNT, Graphite, Steel fiber")
598
+ f1_diam = gr.Number(label="Filler 1 Diameter (µm)")
599
+ f1_len = gr.Number(label="Filler 1 Length (mm)")
600
+ cf_conc = gr.Number(label=f"{CF_COL}", info="Weight percent of total binder")
601
+ f1_dim = gr.Dropdown(DIM_CHOICES, value="NA", label="Filler 1 Dimensionality")
602
 
603
  with gr.Accordion("Secondary filler (optional)", open=False, elem_classes=["card"]):
604
  f2_type = gr.Textbox(label="Filler 2 Type", placeholder="Optional")
605
  f2_diam = gr.Number(label="Filler 2 Diameter (µm)")
606
  f2_len = gr.Number(label="Filler 2 Length (mm)")
607
+ f2_dim = gr.Dropdown(DIM_CHOICES, value="NA", label="Filler 2 Dimensionality")
608
+
609
  with gr.Accordion("Mix design & specimen", open=False, elem_classes=["card"]):
610
+ spec_vol = gr.Number(label="Specimen Volume (mm3)")
611
+ probe_cnt = gr.Number(label="Probe Count")
612
+ probe_mat = gr.Textbox(label="Probe Material", placeholder="e.g., Copper, Silver paste")
613
+ wb = gr.Number(label="W/B")
614
+ sb = gr.Number(label="S/B")
615
+ gauge_len = gr.Number(label="Gauge Length (mm)")
616
+ curing = gr.Textbox(label="Curing Condition", placeholder="e.g., 28d water, 20°C")
617
+ n_fillers = gr.Number(label="Number of Fillers")
618
 
619
  with gr.Accordion("Processing", open=False, elem_classes=["card"]):
620
  dry_temp = gr.Number(label="Drying Temperature (°C)")
 
622
 
623
  with gr.Accordion("Mechanical & electrical loading", open=False, elem_classes=["card"]):
624
  load_rate = gr.Number(label="Loading Rate (MPa/s)")
625
+ E_mod = gr.Number(label="Modulus of Elasticity (GPa)")
626
+ current = gr.Dropdown(CURRENT_CHOICES, value="NA", label="Current Type")
627
  voltage = gr.Number(label="Applied Voltage (V)")
628
 
629
  with gr.Column(scale=5):
630
  with gr.Group(elem_classes=["card"]):
631
+ out_pred = gr.Number(label="Predicted Stress GF (MPa-1)", precision=6)
 
632
  with gr.Row():
633
  btn_pred = gr.Button("Predict", variant="primary")
634
  btn_clear = gr.Button("Clear")
 
636
 
637
  with gr.Accordion("About this model", open=False, elem_classes=["card"]):
638
  gr.Markdown(
639
+ "- Pipeline: ColumnTransformer -> (RobustScaler + OneHot) -> XGBoost\n"
640
+ "- Target: Stress GF (MPa^-1) on original scale (model trains on log1p).\n"
641
  "- Missing values are safely imputed per-feature.\n"
642
  "- Trained columns:\n"
643
+ f" `{', '.join(MAIN_VARIABLES)}`"
 
644
  )
645
 
646
+ # Wire predictor buttons
647
  inputs_in_order = [
648
  f1_type, f1_diam, f1_len, cf_conc,
649
  f1_dim, f2_type, f2_diam, f2_len,
 
658
  return predict_fn(**data)
659
 
660
  btn_pred.click(_predict_wrapper, inputs=inputs_in_order, outputs=out_pred)
661
+ btn_clear.click(lambda: _clear_all(), inputs=None, outputs=inputs_in_order)
662
  btn_demo.click(lambda: _fill_example(), inputs=None, outputs=inputs_in_order)
663
 
664
  # ------------------------- Literature Tab -------------------------
665
+ with gr.Tab("📚 Ask the Literature (Hybrid RAG + MMR)"):
 
666
  gr.Markdown(
667
+ "Upload PDFs into the repository folder <code>papers/</code> then reload the Space. "
668
+ "Answers cite (Doc.pdf, p.X). Toggle strict quotes or optional LLM paraphrasing."
 
669
  )
670
  with gr.Row():
671
  top_k = gr.Slider(5, 12, value=8, step=1, label="Top-K chunks")
672
  n_sentences = gr.Slider(2, 6, value=4, step=1, label="Answer length (sentences)")
673
+ include_passages = gr.Checkbox(value=False, label="Include supporting passages")
 
674
  with gr.Accordion("Retriever weights (advanced)", open=False):
675
  w_tfidf = gr.Slider(0.0, 1.0, value=W_TFIDF_DEFAULT, step=0.05, label="TF-IDF weight")
676
  w_bm25 = gr.Slider(0.0, 1.0, value=W_BM25_DEFAULT, step=0.05, label="BM25 weight")
677
+ w_emb = gr.Slider(0.0, 1.0, value=W_EMB_DEFAULT, step=0.05, label="Dense weight (set 0 if disabled)")
678
+ with gr.Accordion("LLM & Controls", open=False):
679
+ strict_quotes_only = gr.Checkbox(value=False, label="Strict quotes only (no paraphrasing)")
680
+ use_llm = gr.Checkbox(value=True, label="Use LLM to paraphrase selected sentences")
681
+ model_name = gr.Textbox(value=os.getenv("OPENAI_MODEL", OPENAI_MODEL),
682
+ label="LLM model", placeholder="e.g., gpt-5 or gpt-5-mini")
683
+ temperature = gr.Slider(0.0, 1.0, value=0.2, step=0.05, label="Temperature")
 
684
  gr.ChatInterface(
685
  fn=rag_chat_fn,
686
+ additional_inputs=[top_k, n_sentences, include_passages, use_llm, model_name,
687
+ temperature, strict_quotes_only, w_tfidf, w_bm25, w_emb],
 
 
 
688
  title="Literature Q&A",
689
+ description="Hybrid retrieval with diversity. Answers carry inline (Doc, p.X) citations. Toggle strict/LLM modes."
690
  )
691
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
692
  # ------------- Launch -------------
693
  if __name__ == "__main__":
694
+ # queue() helps HF Spaces with concurrency; show_error suggests upload PDFs if none
695
+ demo.queue().launch()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
{papers → literature_pdfs}/Carbon fiber reinforced cement improved by using silane-treated carbon fibers.pdf RENAMED
File without changes
{papers → literature_pdfs}/Silane-treated carbon fiber for reinforcing cement.pdf RENAMED
File without changes
papers/1-s2.0-S095006181732278X-main.pdf DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:e6ac4d8d3c2572eab3e5b721e0520656699b5b2e49e12f51cc52ef41d7ac5e6f
3
- size 2770836
 
 
 
 
papers/1-s2.0-S0950061820330786-main.pdf DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:3e0545545fe157b4b451f27645fc3b948179d592a82d69a0162cc68316799c3f
3
- size 7895635
 
 
 
 
papers/1-s2.0-S1359836816316882-main.pdf DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:fac05273a94954a02f1b7f78a8a2dc48965e6dff8d2417804284df5d5ebf2cc7
3
- size 993983
 
 
 
 
papers/1-s2.0-S2090447920301593-main.pdf DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:0811c3ff0f36a2e53819abdd70aab63a47735cf157e081be31a1a0b7fd9a2290
3
- size 2639742
 
 
 
 
papers/2011-EffectofSpecimenSizeonStaticStrengthandDIFofHSCfromSHPBTest.pdf DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:bfe41da8fd83964ccc2d63a44cde66663191f0ceec5da19d8ab714571f31e1d0
3
- size 902749
 
 
 
 
papers/Capacitance-based stress self-sensing in cement paste without requiring any admixture.pdf DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:91c43a579673112bc4fd4c779e032998854eda1a83cbb52995da1b08cb8a3fbb
3
- size 2607121
 
 
 
 
papers/Capacitive compressive stress self-sensing behavior of cement mortar and its dependence on the thickness.pdf DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:10cb37f750e10da02dc2683fac6e0cc21792146f41f043ca421ac485bb78b90e
3
- size 1053149
 
 
 
 
papers/Development of self-sensing ultra-high-performance concrete using hybrid carbon black and carbon nanofibers.pdf DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:7038811667d71f1d2dbb5d22c17310ea10b45c1112a4609913bc2003fa69b560
3
- size 18592856
 
 
 
 
papers/Development of sensing concrete Principles, properties and its applications.pdf DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:99231674c2f181ba902eddb435422e60fd2aad7b6f0dee8586caf65ffa9e8434
3
- size 4935899
 
 
 
 
papers/EVALUA~1.PDF DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:a17dc91f53a82741e12c8711c992d8193fc891c2aac5a005635d6bb21832323e
3
- size 3449663
 
 
 
 
papers/Effect of silane treatment on microstructure of sisal fibers.pdf DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:14e24a7b5089fa8b0fcba20f929ffb0ad8a51d76c7b62dd9a8e793a2dd746bef
3
- size 1767808
 
 
 
 
papers/Graphene family (GFMs), carbon nanotubes (CNTs) and carbon black (CB) on smart materials for civil construction.pdf DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:06cf6a6f7ae59ff9f4e8cc253af7022d43096e1d86a9334c87f13198f3300989
3
- size 3325137
 
 
 
 
papers/Influence of the structures of polycarboxylate superplasticizer on its performance in cement-based materials-A review.pdf DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:5594e415ae5beb8962fd0f915f2d9326017c8c927ce01ab947525ce2d27d194e
3
- size 2319864
 
 
 
 
papers/Investigating the synergistic effects of carbon fiber and silica fume on concrete strength and eco-efficiency.pdf DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:6300a5c9d8e56577739677a3d6fb76bc83794c2e26433e3bee134c6aa96419f5
3
- size 8796244
 
 
 
 
papers/Investigation of 3D Printed Self-Sensing UHPC Composites Using Graphite and Hybrid Carbon Microfibers.pdf DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:76a51ea3c14556d9e0816f7bf1a1081c96fecafeaec6318e478256046004c403
3
- size 19966500
 
 
 
 
papers/Ozone treatment of carbon fiber for reinforcing cement.pdf DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:1a780e58eeb5fac9eb52da3d8e1b22836eb0efeede7e0c24a34f03f78f3e543a
3
- size 158724
 
 
 
 
papers/PIEZOE~1.PDF DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:b29bdceed88bf961874d5df014ab286e20408a7db568dbf81031d7062cfc0aa3
3
- size 2799712
 
 
 
 
papers/Performance of silica fume slurry treated recycled aggregate concrete reinforced with carbon fibers.pdf DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:9b7113d7790e508928c28f5c19646c5ec746d158fd069806f6519b2fa2fb17f9
3
- size 6511841
 
 
 
 
papers/Piezopermittivity for capacitance-based strain stress sensing.pdf DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:686a01889e91d7914752144928985ba9c6eb4ea64f4e31272ced5703533f0b3b
3
- size 8547318
 
 
 
 
papers/Review Improving cement-based materials by using silica fume.pdf DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:d3b067125bf3d799e0d5cfd92293d7a619bd9c160b99f764866e6780c1168f7d
3
- size 130361
 
 
 
 
papers/Revolutionizing infrastructure The evolving landscape of electricity-based multifunctional concrete from concept to practice.pdf DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:b6df06b979a5e5655dc6ce6a7b1d2df44fefa7343e85060871b58835eb380a28
3
- size 51623146
 
 
 
 
papers/S1-An-experimental-study-of-self-sensing-concrete-enhanced_2020_Construction-an.pdf DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:b68187d8c4614c3e241bbb4c89e8c14d744533b18f63834a3d26f599a569fcb5
3
- size 10170858
 
 
 
 
papers/S10-Enhancing-self-stress-sensing-ability-of-smart-ultra-high_2021_Journal-of-Bu.pdf DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:bab3678971e41461f6f0d19678d0c93b31b9d6c8523d45b2cdfaea9dc84b5751
3
- size 12180099
 
 
 
 
papers/S100-C~1.PDF DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:c4c288018725ff22661b823c066bad8fb7d0f871cfc74c39cabee284b22a684e
3
- size 16436378
 
 
 
 
papers/S11-Environment-Friendly, Self-Sensing Concrete Blended with Byproduct Wastes.pdf DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:0de399fce2dfc1ea5b910ccaf28c466847908bf0f19fde5818dba1d383dba17e
3
- size 4414928
 
 
 
 
papers/S12-Hybrid-effects-of-steel-fiber-and-carbon-nanotube-on-s_2018_Construction-and.pdf DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:0219166e4a61d8e1bb036e7a3d0eb64d09f0f2eebbed1c051c123b2ae0d1c9be
3
- size 6352700
 
 
 
 
papers/S13-Increasing-self-sensing-capability-of-carbon-nanotubes-c_2020_Construction-a.pdf DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:2b6961eb33c2dc1945e80cb424ca0e60be831739795c3d3ed861debd4bc47c00
3
- size 2491685
 
 
 
 
papers/S14-Influence-of-carbon-nanofiber-content-and-sodium-chloride-_2019_Case-Studies.pdf DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:e8a467d09713940de2b53cf79a2558aedcb8f88e99396304bd18324ea75e9fbf
3
- size 1429796
 
 
 
 
papers/S15-Influence-of-water-ingress-on-the-electrical-properties-_2021_Journal-of-Bui.pdf DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:dc378192f5970beb777212a40e11edc194c88d0d014b6a4c23388dd350a7c05e
3
- size 8114891
 
 
 
 
papers/S16-Investigations-on-scalable-fabrication-procedures-for-sel_2016_Cement-and-Co.pdf DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:c019a8649804527c6f6946f0630958baafa168c30c3a7fad8ac1714f5d83af00
3
- size 3699381
 
 
 
 
papers/S17-Cross tension and compression loading and large-scale testing of strain and damage sensing smart concrete.pdf DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:8a3f2ace2a355e9ad3fe8f7a8509752295d16f5254b5ddb26e1e063b0fadfce3
3
- size 12549353
 
 
 
 
papers/S18-Nano graphite platelets-enabled piezoresistive cementitious composites for structural health monitoring.pdf DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:1b6351f0d89ef05de0842a767ca3d185144071d09703518c511a55a32730f6b7
3
- size 6955295
 
 
 
 
papers/S19-Self-sensing-piezoresistive-cement-composite-loaded_2017_Cement-and-Concrete.pdf DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:0b89c68444198a3125bc36d7d7ad895c85679378ddd950574e941f4482cc56b0
3
- size 1291076
 
 
 
 
papers/S2-Characterization-of-smart-brass-fiber-reinforced-co_2020_Construction-and-Bu.pdf DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:c573ef904178659e66b169c74a6cbd7805e09145deceeb5cd447863817f42895
3
- size 3456970
 
 
 
 
papers/S20-IN~1.PDF DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:ef0dbea7d457fa02864341d1690484c47dbd39ab0a1b7a85062ce1640e907371
3
- size 1178272
 
 
 
 
papers/S21-Mechanical, electrical and self-sensing properties of cementitious mortars containing short carbon fibers.pdf DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:684a75200bebe7438346021f784154f769d6b61275f0268fd970f42c5ad467e2
3
- size 916061
 
 
 
 
papers/S22-Improved strain sensing properties of cement-based sensors through enhanced carbon nanotube dispersion.pdf DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:e596ce613b5af3083c9738328c5aeb85d6c950751ace1fdfedd695044b25db26
3
- size 7881761
 
 
 
 
papers/S23-Increasing self-sensing capability of carbon nanotubes cement-based materials by simultaneous addition of Ni nanofibers.pdf DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:b11d51d6ed34e67eb268940b8389bf678e2387474c4e38b23c66214789132d37
3
- size 2491685
 
 
 
 
papers/S24-Multifunctional-self-sensing-and-ductile-cementit_2019_Cement-and-Concrete-R.pdf DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:e3f581bb63eff732f22b0019ea8cdb495dae35b6c6b7aae88a9b127efb34abcb
3
- size 16496962
 
 
 
 
papers/S25-Self-sensing-capability-of-ultra-high-performance-concr_2018_Sensors-and-Act.pdf DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:681f62bb383c1466a88694f215a0b0575c1094ffe8be40fe865105b987e38d0f
3
- size 5220733
 
 
 
 
papers/S26-TE~1.PDF DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:456f19cca981522e080236b4552cc96970f0cdd2342938d99e06cc1b00ab8e61
3
- size 2185689
 
 
 
 
papers/S27-Effect of aspect ratio on strain sensing capacity of carbon fiber reinforced cement composites.pdf DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:fe60fd559cc6f743e238a520b680d0d02bb555933328a5a6c0cf01ea9fd0aaa4
3
- size 2781671
 
 
 
 
papers/S28-Smart Graphite–Cement Composites with Low Percolation Threshold.pdf DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:5f8238daf3fc5e20e13de68491a4c58d64253d40ced2d96b7cbe491c05cddfe2
3
- size 5383561
 
 
 
 
papers/S29-Hybrid Carbon Microfibers-Graphite Fillers for Piezoresistive Cementitious Composites.pdf DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:9b35eaed680f105a0d35fd4b5f704552d9b9dddfbf491871bbbb70fd237da632
3
- size 15621213
 
 
 
 
papers/S3-Effect of characteristics of assembly unit of CNTNCB composite fillers on properties of smart cement-based materials.pdf DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:7bc5d4db3e5f2048a09afcab1e919041bef9ba87abbfac7dd287e14bae6648ac
3
- size 2216621
 
 
 
 
papers/S30-Smart Graphite–Cement Composite for Roadway-Integrated Weigh-In-Motion Sensing.pdf DELETED
@@ -1,3 +0,0 @@
1
- version https://git-lfs.github.com/spec/v1
2
- oid sha256:0ed37d39cd118e46bf7cd584630809651e0e0141959c007bed1421714d78fb25
3
- size 4501952