@@ -417,7 +417,7 @@ def extract_scc_energy(lines, filename):
417
417
if "SCC energy" in line :
418
418
return float (line .split ()[3 ])
419
419
420
- self .args .log .write (f"x WARNING! Could not find SCC energy value in the file: { filename } " )
420
+ self .args .log .write (f"x WARNING! Could not find SCC energy value in the file: { os . path . basename ( filename ) } . Some CDFT-based descriptors will be missing. " )
421
421
return None
422
422
423
423
try :
@@ -443,16 +443,17 @@ def extract_scc_energy(lines, filename):
443
443
scc_energy_Nplus1 = extract_scc_energy (data3 , file_Nplus1 )
444
444
scc_energy_Nplus2 = extract_scc_energy (data4 , file_Nplus2 )
445
445
446
- if None in [scc_energy , scc_energy_Nminus1 , scc_energy_Nminus2 , scc_energy_Nplus1 , scc_energy_Nplus2 ]:
447
- self .args .log .write (f"x WARNING! Missing SCC energy in one or more files. Cannot calculate global CDFT descriptors." )
448
- return None
449
-
450
446
# Convert SCC energies to Hartree
451
- scc_energy *= Hartree
452
- scc_energy_Nminus1 *= Hartree
453
- scc_energy_Nminus2 *= Hartree
454
- scc_energy_Nplus1 *= Hartree
455
- scc_energy_Nplus2 *= Hartree
447
+ if scc_energy is not None :
448
+ scc_energy *= Hartree
449
+ if scc_energy_Nminus1 is not None :
450
+ scc_energy_Nminus1 *= Hartree
451
+ if scc_energy_Nminus2 is not None :
452
+ scc_energy_Nminus2 *= Hartree
453
+ if scc_energy_Nplus1 is not None :
454
+ scc_energy_Nplus1 *= Hartree
455
+ if scc_energy_Nplus2 is not None :
456
+ scc_energy_Nplus2 *= Hartree
456
457
457
458
# Initialize variables
458
459
delta_SCC_IP , delta_SCC_EA , electrophilicity_index = None , None , None
@@ -466,60 +467,66 @@ def extract_scc_energy(lines, filename):
466
467
Electrophilic_descriptor , w_cubic = None , None
467
468
468
469
# Calculate Global CDFT descriptors
469
- delta_SCC_IP = round (((scc_energy_Nminus1 - corr_xtb ) - scc_energy ),4 )
470
- delta_SCC_EA = round ((scc_energy - (scc_energy_Nplus1 + corr_xtb )),4 )
471
- chemical_hardness = round ((delta_SCC_IP - delta_SCC_EA ), 4 )
472
- chemical_potential = round (- (delta_SCC_IP + delta_SCC_EA ) / 2 , 4 )
473
- electrophilicity_index = (chemical_potential ** 2 )/ (2 * chemical_hardness )
474
- mulliken_electronegativity = round (- chemical_potential , 4 )
475
- electrofugality = round (- delta_SCC_EA + electrophilicity_index , 4 )
476
- nucleofugality = round (delta_SCC_IP + electrophilicity_index , 4 )
477
- electrodonating_maximum_electron_flow = round ((- (chemical_potential / chemical_hardness )),4 )
478
- electrodonating_chemical_potential = round (((1 / 4 )* ((- 3 * delta_SCC_IP ) - delta_SCC_EA )),4 )
479
- lectrodonating_maximum_electron_flow = round ((- (electrodonating_chemical_potential / chemical_hardness )),4 )
480
- Vertical_second_IP = round ((((scc_energy_Nminus2 - scc_energy_Nminus1 ) - corr_xtb )), 4 )
481
- Vertical_second_EA = round ((((scc_energy_Nplus1 - scc_energy_Nplus2 ) + corr_xtb )), 4 )
482
- hyper_hardness = round ((- ((0.5 ) * (delta_SCC_IP + delta_SCC_EA - Vertical_second_IP - Vertical_second_EA ))), 4 )
483
-
484
- if chemical_hardness != 0 :
470
+ if None not in [scc_energy_Nminus1 ,scc_energy ]:
471
+ delta_SCC_IP = round (((scc_energy_Nminus1 - corr_xtb ) - scc_energy ),4 )
472
+ if None not in [scc_energy_Nplus1 ,scc_energy ]:
473
+ delta_SCC_EA = round ((scc_energy - (scc_energy_Nplus1 + corr_xtb )),4 )
474
+ if None not in [delta_SCC_IP ,delta_SCC_EA ]:
475
+ chemical_hardness = round ((delta_SCC_IP - delta_SCC_EA ), 4 )
476
+ chemical_potential = round (- (delta_SCC_IP + delta_SCC_EA ) / 2 , 4 )
477
+ electrophilicity_index = (chemical_potential ** 2 )/ (2 * chemical_hardness )
478
+ mulliken_electronegativity = round (- chemical_potential , 4 )
479
+ electrofugality = round (- delta_SCC_EA + electrophilicity_index , 4 )
480
+ nucleofugality = round (delta_SCC_IP + electrophilicity_index , 4 )
481
+ electrodonating_maximum_electron_flow = round ((- (chemical_potential / chemical_hardness )),4 )
482
+ electrodonating_chemical_potential = round (((1 / 4 )* ((- 3 * delta_SCC_IP ) - delta_SCC_EA )),4 )
483
+ electrodonating_maximum_electron_flow = round ((- (electrodonating_chemical_potential / chemical_hardness )),4 )
484
+ if None not in [scc_energy_Nminus2 ,scc_energy_Nminus1 ]:
485
+ Vertical_second_IP = round ((((scc_energy_Nminus2 - scc_energy_Nminus1 ) - corr_xtb )), 4 )
486
+ if None not in [scc_energy_Nplus1 ,scc_energy_Nplus2 ]:
487
+ Vertical_second_EA = round ((((scc_energy_Nplus1 - scc_energy_Nplus2 ) + corr_xtb )), 4 )
488
+ if None not in [delta_SCC_IP ,delta_SCC_EA ,Vertical_second_IP ,Vertical_second_EA ]:
489
+ hyper_hardness = round ((- ((0.5 ) * (delta_SCC_IP + delta_SCC_EA - Vertical_second_IP - Vertical_second_EA ))), 4 )
490
+
491
+ if chemical_hardness is not None and chemical_hardness != 0 :
485
492
chemical_softness = round (1 / chemical_hardness , 4 )
486
493
electrodonating_power_index = round (((delta_SCC_IP + 3 * delta_SCC_EA )** 2 ) / (8 * chemical_hardness ), 4 )
487
494
electroaccepting_power_index = round (((3 * delta_SCC_IP + delta_SCC_EA )** 2 ) / (8 * chemical_hardness ), 4 )
488
495
intrinsic_reactivity_index = round ((delta_SCC_IP + delta_SCC_EA ) / chemical_hardness , 4 )
489
- Global_hypersoftness = round ((hyper_hardness / ((chemical_hardness ) ** 3 )), 4 )
496
+ if hyper_hardness is not None :
497
+ Global_hypersoftness = round ((hyper_hardness / ((chemical_hardness ) ** 3 )), 4 )
490
498
491
499
if electroaccepting_power_index != 0 :
492
500
nucleophilicity_index = round (10 / electroaccepting_power_index , 4 )
493
501
494
- net_electrophilicity = round (( electrodonating_power_index - electroaccepting_power_index ), 4 )
495
-
496
- # For lectrophilic descriptor calculations
497
- A = (( scc_energy_Nplus1 - scc_energy ) + corr_xtb )
498
- c = ( Vertical_second_IP - ( 2 * delta_SCC_IP ) + A ) / (( 2 * Vertical_second_IP ) - delta_SCC_IP - A )
499
- a = - (( delta_SCC_IP + A ) / 2 ) + ((( delta_SCC_IP - A ) / 2 ) * c )
500
- b = (( delta_SCC_IP - A ) / 2 ) - ((( delta_SCC_IP + A ) / 2 ) * c )
501
- Gamma = ( - 3 * c ) * ( b - ( a * c ) )
502
- Eta = 2 * ( b - ( a * c ) )
503
- chi = - a
504
- Mu = a
505
-
506
- discriminant = Eta ** 2 - ( 2 * Gamma * Mu ) # Checking the square root
507
- if discriminant < 0 :
508
- self . args . log . write ( f"x WARNING! Negative discriminant encountered, skipping Electrophilic descriptor calculation." )
509
- else :
510
- inter_phi = math .sqrt (discriminant )
511
- Phi = inter_phi - Eta
512
- Electrophilic_descriptor = round (((chi * (Phi / Gamma )) - (((Phi / Gamma ) ** 2 ) * ((Eta / 2 ) + (Phi / 6 )))), 4 )
502
+ if None not in [ electrodonating_power_index , electroaccepting_power_index ]:
503
+ net_electrophilicity = round (( electrodonating_power_index - electroaccepting_power_index ), 4 )
504
+
505
+ # For electrophilic descriptor calculations
506
+ if None not in [ scc_energy_Nplus1 , scc_energy , Vertical_second_IP , delta_SCC_IP ]:
507
+ A = (( scc_energy_Nplus1 - scc_energy ) + corr_xtb )
508
+ c = ( Vertical_second_IP - (2 * delta_SCC_IP ) + A ) / (( 2 * Vertical_second_IP ) - delta_SCC_IP - A )
509
+ a = - (( delta_SCC_IP + A ) / 2 ) + ((( delta_SCC_IP - A ) / 2 ) * c )
510
+ b = (( delta_SCC_IP - A ) / 2 ) - ((( delta_SCC_IP + A ) / 2 ) * c )
511
+ Gamma = ( - 3 * c ) * ( b - ( a * c ))
512
+ Eta = 2 * ( b - ( a * c ))
513
+ chi = - a
514
+ Mu = a
515
+
516
+ discriminant = Eta ** 2 - ( 2 * Gamma * Mu ) # Checking the square root
517
+ if discriminant >= 0 :
518
+ inter_phi = math .sqrt (discriminant )
519
+ Phi = inter_phi - Eta
520
+ Electrophilic_descriptor = round (((chi * (Phi / Gamma )) - (((Phi / Gamma ) ** 2 ) * ((Eta / 2 ) + (Phi / 6 )))), 4 )
513
521
514
522
# For cubic electrophilicity index
515
- Gamma_cubic = 2 * delta_SCC_IP - Vertical_second_IP - delta_SCC_EA
516
- Eta_cubic = delta_SCC_IP - delta_SCC_EA
523
+ if None not in [delta_SCC_IP ,Vertical_second_IP ,delta_SCC_EA ]:
524
+ Gamma_cubic = 2 * delta_SCC_IP - Vertical_second_IP - delta_SCC_EA
525
+ Eta_cubic = delta_SCC_IP - delta_SCC_EA
517
526
518
527
if Eta_cubic != 0 :
519
528
Mu_cubic = (1 / 6 ) * ((- 2 * delta_SCC_EA ) - (5 * delta_SCC_IP ) + Vertical_second_IP )
520
529
w_cubic = round (((Mu_cubic ** 2 ) / (2 * Eta_cubic )) * (1 + ((Mu_cubic / (3 * (Eta_cubic ) ** 2 )) * Gamma_cubic )), 4 )
521
- else :
522
- self .args .log .write (f"x WARNING! Eta_cubic is zero, skipping cub. electrophilicity idx calculation." )
523
530
524
531
# Return the calculated descriptors
525
532
cdft_descriptors = {
@@ -545,7 +552,7 @@ def extract_scc_energy(lines, filename):
545
552
"cub. electrophilicity idx" : w_cubic ,
546
553
"max. electron flow" : electrodonating_maximum_electron_flow ,
547
554
"Electrodon. Chem. potential" : electrodonating_chemical_potential ,
548
- "Electrodon. max. electron flow" : lectrodonating_maximum_electron_flow
555
+ "Electrodon. max. electron flow" : electrodonating_maximum_electron_flow
549
556
}
550
557
551
558
return cdft_descriptors
@@ -558,7 +565,13 @@ def calculate_local_CDFT_descriptors(file_fukui, cdft_descriptors,self):
558
565
with open (file_fukui , "r" ) as f :
559
566
data = f .readlines ()
560
567
568
+ # Initialize variables
561
569
f_pos , f_negs , f_rads = [], [], []
570
+ dual_descriptor ,s_pos ,s_negs ,s_rads = None ,None ,None ,None
571
+ Relative_nucleophilicity ,Relative_electrophilicity ,Grand_canonical_dual_descriptor = None ,None ,None
572
+ w_pos ,w_negs ,w_rads ,Multiphilic_descriptor = None ,None ,None ,None
573
+ Nu_pos ,Nu_negs ,Nu_rads = None ,None ,None
574
+
562
575
start , end = None , None
563
576
564
577
for i , line in enumerate (data ):
@@ -578,50 +591,46 @@ def calculate_local_CDFT_descriptors(file_fukui, cdft_descriptors,self):
578
591
f_rads .append (f_rad )
579
592
except ValueError :
580
593
continue
581
- else :
582
- self .args .log .write ("WARNING: Fukui data not found in the file. Please check the '.fukui' file." )
583
- return None
584
594
585
- if not f_pos or not f_negs or not f_rads :
586
- self .args .log .write ("WARNING: Fukui data lists are empty. Please check the '.fukui' file." )
587
- return None
588
-
589
- if None in [cdft_descriptors ]:
590
- self .args .log .write ("x WARNING! Missing required CDFT descriptors (Softness, Hypersoftness, Electrophil. idx or Nucleophilicity idx)." )
591
- return None
595
+ if f_pos == [] or f_negs == [] or f_rads == []:
596
+ self .args .log .write ("x WARNING! Fukui indices did not generate, please check the '.fukui' file." )
592
597
593
598
chemical_softness = cdft_descriptors .get ("Softness" )
594
599
Global_hypersoftness = cdft_descriptors .get ("Hypersoftness" )
595
600
electrophilicity_index = cdft_descriptors .get ("Electrophil. idx" )
596
601
nucleophilicity_index = cdft_descriptors .get ("Nucleophilicity idx" )
597
602
598
- if None in [chemical_softness , Global_hypersoftness , electrophilicity_index , nucleophilicity_index ]:
599
- self .args .log .write ("x WARNING! Missing required CDFT descriptors (Softness, Hypersoftness, Electrophil. idx or Nucleophilicity idx)." )
600
- return None
601
-
602
- # Calculating local descriptors:
603
- # 1) dual descrip.
604
- dual_descriptor = [round (f_po - f_neg , 4 ) for f_po , f_neg in zip (f_pos , f_negs )]
605
- # 2) softness+, softness- and softness0
606
- s_pos = [round (chemical_softness * f_po , 4 ) for f_po in f_pos ]
607
- s_negs = [round (chemical_softness * f_neg , 4 ) for f_neg in f_negs ]
608
- s_rads = [round (chemical_softness * f_rad , 4 ) for f_rad in f_rads ]
609
- # 3) Rel. nucleophilicity
610
- Relative_nucleophilicity = [round (s_neg / s_po , 4 ) if s_po != 0 else None for s_neg , s_po in zip (s_negs , s_pos )]
611
- # 4) Rel. electrophilicity
612
- Relative_electrophilicity = [round (s_po / s_neg , 4 ) if s_neg != 0 else None for s_neg , s_po in zip (s_negs , s_pos )]
613
- # 5) GC Dual Descrip.
614
- Grand_canonical_dual_descriptor = [round (Global_hypersoftness * dual , 4 ) for dual in dual_descriptor ]
615
- # 6) softness+, softness- and softness0
616
- w_pos = [round (electrophilicity_index * f_po , 4 ) for f_po in f_pos ]
617
- w_negs = [round (electrophilicity_index * f_neg , 4 ) for f_negs in f_negs ]
618
- w_rads = [round (electrophilicity_index * f_rad , 4 ) for f_rad in f_rads ]
619
- # 7) softness+, softness- and softness0
620
- Multiphilic_descriptor = [round (electrophilicity_index * dual , 4 ) for dual in dual_descriptor ]
621
- # 8) softness+, softness- and softness0
622
- Nu_pos = [round (nucleophilicity_index * f_po , 4 ) for f_po in f_pos ]
623
- Nu_negs = [round (nucleophilicity_index * f_neg , 4 ) for f_neg in f_negs ]
624
- Nu_rads = [round (nucleophilicity_index * f_rad , 4 ) for f_rad in f_rads ]
603
+ # Calculating local descriptors
604
+ if chemical_softness is not None and f_pos != [] and f_negs != [] and f_rads != []:
605
+ # 1) dual descrip.
606
+ dual_descriptor = [round (f_po - f_neg , 4 ) for f_po , f_neg in zip (f_pos , f_negs )]
607
+ # 2) softness+, softness- and softness0
608
+ s_pos = [round (chemical_softness * f_po , 4 ) for f_po in f_pos ]
609
+ s_negs = [round (chemical_softness * f_neg , 4 ) for f_neg in f_negs ]
610
+ s_rads = [round (chemical_softness * f_rad , 4 ) for f_rad in f_rads ]
611
+ # 3) Rel. nucleophilicity
612
+ Relative_nucleophilicity = [round (s_neg / s_po , 4 ) if s_po != 0 else None for s_neg , s_po in zip (s_negs , s_pos )]
613
+ # 4) Rel. electrophilicity
614
+ Relative_electrophilicity = [round (s_po / s_neg , 4 ) if s_neg != 0 else None for s_neg , s_po in zip (s_negs , s_pos )]
615
+
616
+ if Global_hypersoftness is not None and dual_descriptor is not None :
617
+ # 5) GC Dual Descrip.
618
+ Grand_canonical_dual_descriptor = [round (Global_hypersoftness * dual , 4 ) for dual in dual_descriptor ]
619
+
620
+ if electrophilicity_index is not None and f_pos != [] and f_negs != [] and f_rads != []:
621
+ # 6) softness+, softness- and softness0
622
+ w_pos = [round (electrophilicity_index * f_po , 4 ) for f_po in f_pos ]
623
+ w_negs = [round (electrophilicity_index * f_neg , 4 ) for f_neg in f_negs ]
624
+ w_rads = [round (electrophilicity_index * f_rad , 4 ) for f_rad in f_rads ]
625
+ if dual_descriptor is not None :
626
+ # 7) softness+, softness- and softness0
627
+ Multiphilic_descriptor = [round (electrophilicity_index * dual , 4 ) for dual in dual_descriptor ]
628
+
629
+ if nucleophilicity_index is not None and f_pos != [] and f_negs != [] and f_rads != []:
630
+ # 8) softness+, softness- and softness0
631
+ Nu_pos = [round (nucleophilicity_index * f_po , 4 ) for f_po in f_pos ]
632
+ Nu_negs = [round (nucleophilicity_index * f_neg , 4 ) for f_neg in f_negs ]
633
+ Nu_rads = [round (nucleophilicity_index * f_rad , 4 ) for f_rad in f_rads ]
625
634
626
635
localDescriptors = {
627
636
"fukui+" : f_pos ,
@@ -1598,7 +1607,10 @@ def update_atom_props_json(sorted_indices,match_names,atom_props,json_data,prefi
1598
1607
idx_xtb = atom_idx
1599
1608
for prop in atom_props :
1600
1609
try :
1601
- json_data [f'{ match_name } _{ prop } ' ] = json_data [prop ][idx_xtb ]
1610
+ if json_data [prop ] is not None :
1611
+ json_data [f'{ match_name } _{ prop } ' ] = json_data [prop ][idx_xtb ]
1612
+ else :
1613
+ json_data [f'{ match_name } _{ prop } ' ] = None
1602
1614
if f'{ match_name } _' not in prefixes_atom_prop :
1603
1615
prefixes_atom_prop .append (f'{ match_name } _' )
1604
1616
except (KeyError ,IndexError ): # prevents missing values
@@ -1610,8 +1622,12 @@ def update_atom_props_json(sorted_indices,match_names,atom_props,json_data,prefi
1610
1622
prop_values = []
1611
1623
for prop_name in match_names :
1612
1624
prop_values .append (json_data [f'{ prop_name } _{ prop } ' ])
1613
- json_data [f'{ pattern } _max_{ prop } ' ] = max (prop_values )
1614
- json_data [f'{ pattern } _min_{ prop } ' ] = min (prop_values )
1625
+ if None not in prop_values :
1626
+ json_data [f'{ pattern } _max_{ prop } ' ] = max (prop_values )
1627
+ json_data [f'{ pattern } _min_{ prop } ' ] = min (prop_values )
1628
+ else :
1629
+ json_data [f'{ pattern } _max_{ prop } ' ] = None
1630
+ json_data [f'{ pattern } _min_{ prop } ' ] = None
1615
1631
if f'{ pattern } _max_{ prop } ' not in prefixes_atom_prop :
1616
1632
prefixes_atom_prop .append (f'{ pattern } _max_' )
1617
1633
if f'{ pattern } _min_{ prop } ' not in prefixes_atom_prop :
0 commit comments