1414 TimeElapsedColumn ,
1515)
1616
17+ from CodeEntropy .config .logging_config import LoggingConfig
18+
1719logger = logging .getLogger (__name__ )
20+ console = LoggingConfig .get_console ()
1821
1922
2023class EntropyManager :
@@ -58,6 +61,10 @@ def execute(self):
5861 start , end , step = self ._get_trajectory_bounds ()
5962 number_frames = self ._get_number_frames (start , end , step )
6063
64+ console .print (
65+ f"Analyzing a total of { number_frames } frames in this calculation."
66+ )
67+
6168 ve = VibrationalEntropy (
6269 self ._run_manager ,
6370 self ._args ,
@@ -572,7 +579,7 @@ def _finalize_molecule_results(self):
572579 entropy_type ,
573580 result ,
574581 ) in self ._data_logger .molecule_data :
575- if level != "Molecule Total" :
582+ if level != "Group Total" :
576583 try :
577584 entropy_by_molecule [mol_id ] += float (result )
578585 except ValueError :
@@ -584,8 +591,8 @@ def _finalize_molecule_results(self):
584591 self ._data_logger .molecule_data .append (
585592 (
586593 mol_id ,
587- "Molecule Total" ,
588- "Molecule Total Entropy" ,
594+ "Group Total" ,
595+ "Group Total Entropy" ,
589596 total_entropy ,
590597 )
591598 )
@@ -616,103 +623,126 @@ def _finalize_molecule_results(self):
616623
617624 def _calculate_water_entropy (self , universe , start , end , step , group_id = None ):
618625 """
619- Calculate water entropy and map all waters to a single group ID.
620- Aggregates entropy components per water group.
626+ Calculate and aggregate the entropy of water molecules in a simulation.
627+
628+ This function computes orientational, translational, and rotational
629+ entropy components for all water molecules, aggregates them per residue,
630+ and maps all waters to a single group ID. It also logs the total results
631+ and labels the water group in the data logger.
632+
633+ Parameters
634+ ----------
635+ universe : MDAnalysis.Universe
636+ The simulation universe containing water molecules.
637+ start : int
638+ The starting frame for analysis.
639+ end : int
640+ The ending frame for analysis.
641+ step : int
642+ Frame interval for analysis.
643+ group_id : int or str, optional
644+ The group ID to which all water molecules will be assigned.
621645 """
622- Sorient_dict , _ , vibrations , _ , water_count = (
646+ Sorient_dict , covariances , vibrations , _ , water_count = (
623647 GetSolvent .get_interfacial_water_orient_entropy (
624648 universe , start , end , step , self ._args .temperature , parallel = True
625649 )
626650 )
627651
628- self ._calculate_water_orientational_entropy (Sorient_dict , group_id , water_count )
652+ self ._calculate_water_orientational_entropy (Sorient_dict , group_id )
629653 self ._calculate_water_vibrational_translational_entropy (
630- vibrations , group_id , water_count
654+ vibrations , group_id , covariances
631655 )
632656 self ._calculate_water_vibrational_rotational_entropy (
633- vibrations , group_id , water_count
657+ vibrations , group_id , covariances
634658 )
635659
636- results = {}
637- for row in self ._data_logger .residue_data :
638- mol_id = row [1 ]
639- entropy_type = row [3 ].split ()[0 ]
640- value = float (row [5 ])
641-
642- if mol_id not in results :
643- results [mol_id ] = {
644- "Orientational" : 0.0 ,
645- "Transvibrational" : 0.0 ,
646- "Rovibrational" : 0.0 ,
647- }
648- results [mol_id ][entropy_type ] += value
649-
650- for mol_id , components in results .items ():
651- for entropy_type in ["Orientational" , "Transvibrational" , "Rovibrational" ]:
652- S_component = components [entropy_type ]
653- self ._data_logger .add_results_data (
654- group_id , "water" , entropy_type , S_component
655- )
656-
657660 water_selection = universe .select_atoms ("resname WAT" )
658661 actual_water_residues = len (water_selection .residues )
659-
660- residue_names = set ()
661- for res_dict in Sorient_dict .values ():
662- for resname in res_dict .keys ():
663- if resname .upper () in water_selection .residues .resnames :
664- residue_names . add ( resname )
662+ residue_names = {
663+ resname
664+ for res_dict in Sorient_dict .values ()
665+ for resname in res_dict .keys ()
666+ if resname .upper () in water_selection .residues .resnames
667+ }
665668
666669 residue_group = "_" .join (sorted (residue_names )) if residue_names else "WAT"
667- residue_count = actual_water_residues
668- atom_count = len (water_selection .atoms )
669-
670670 self ._data_logger .add_group_label (
671- group_id , residue_group , residue_count , atom_count
671+ group_id , residue_group , actual_water_residues , len ( water_selection . atoms )
672672 )
673673
674- def _calculate_water_orientational_entropy (
675- self , Sorient_dict , group_id , water_count
676- ):
674+ def _calculate_water_orientational_entropy (self , Sorient_dict , group_id ):
677675 """
678- Aggregate all orientational entropy for waters into a single group.
676+ Aggregate orientational entropy for all water molecules into a single group.
677+
678+ Parameters
679+ ----------
680+ Sorient_dict : dict
681+ Dictionary containing orientational entropy values per residue.
682+ group_id : int or str
683+ The group ID to which the water residues belong.
684+ covariances : object
685+ Covariance object.
679686 """
680- total_S = 0.0
681687 for resid , resname_dict in Sorient_dict .items ():
682688 for resname , values in resname_dict .items ():
683689 if isinstance (values , list ) and len (values ) == 2 :
684690 Sor , count = values
685- total_S += Sor
686-
687- self ._data_logger .add_residue_data (
688- group_id , "WAT" , "Water" , "Orientational" , water_count , total_S
689- )
691+ self ._data_logger .add_residue_data (
692+ group_id , resname , "Water" , "Orientational" , count , Sor
693+ )
690694
691695 def _calculate_water_vibrational_translational_entropy (
692- self , vibrations , group_id , water_count
696+ self , vibrations , group_id , covariances
693697 ):
694- total_S = 0.0
698+ """
699+ Aggregate translational vibrational entropy for all water molecules.
700+
701+ Parameters
702+ ----------
703+ vibrations : object
704+ Object containing translational entropy data (vibrations.translational_S).
705+ group_id : int or str
706+ The group ID for the water residues.
707+ covariances : object
708+ Covariance object.
709+ """
710+
695711 for (solute_id , _ ), entropy in vibrations .translational_S .items ():
696712 if isinstance (entropy , (list , np .ndarray )):
697713 entropy = float (np .sum (entropy ))
698- total_S += entropy
699714
700- self ._data_logger .add_residue_data (
701- group_id , "WAT" , "Water" , "Transvibrational" , water_count , total_S
702- )
715+ count = covariances .counts .get ((solute_id , "WAT" ), 1 )
716+ resname = solute_id .rsplit ("_" , 1 )[0 ] if "_" in solute_id else solute_id
717+ self ._data_logger .add_residue_data (
718+ group_id , resname , "Water" , "Transvibrational" , count , entropy
719+ )
703720
704721 def _calculate_water_vibrational_rotational_entropy (
705- self , vibrations , group_id , water_count
722+ self , vibrations , group_id , covariances
706723 ):
707- total_S = 0.0
724+ """
725+ Aggregate rotational vibrational entropy for all water molecules.
726+
727+ Parameters
728+ ----------
729+ vibrations : object
730+ Object containing rotational entropy data (vibrations.rotational_S).
731+ group_id : int or str
732+ The group ID for the water residues.
733+ covariances : object
734+ Covariance object.
735+ """
708736 for (solute_id , _ ), entropy in vibrations .rotational_S .items ():
709737 if isinstance (entropy , (list , np .ndarray )):
710738 entropy = float (np .sum (entropy ))
711- total_S += entropy
712739
713- self ._data_logger .add_residue_data (
714- group_id , "WAT" , "Water" , "Rovibrational" , water_count , total_S
715- )
740+ count = covariances .counts .get ((solute_id , "WAT" ), 1 )
741+
742+ resname = solute_id .rsplit ("_" , 1 )[0 ] if "_" in solute_id else solute_id
743+ self ._data_logger .add_residue_data (
744+ group_id , resname , "Water" , "Rovibrational" , count , entropy
745+ )
716746
717747
718748class VibrationalEntropy (EntropyManager ):
0 commit comments