pyphyschemtools 0.1.0__py3-none-any.whl → 0.1.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. pyphyschemtools/.__init__.py.swp +0 -0
  2. pyphyschemtools/.ipynb_checkpoints/Chem3D-checkpoint.py +835 -0
  3. pyphyschemtools/.ipynb_checkpoints/PeriodicTable-checkpoint.py +294 -0
  4. pyphyschemtools/.ipynb_checkpoints/aithermo-checkpoint.py +349 -0
  5. pyphyschemtools/.ipynb_checkpoints/core-checkpoint.py +120 -0
  6. pyphyschemtools/.ipynb_checkpoints/spectra-checkpoint.py +471 -0
  7. pyphyschemtools/.ipynb_checkpoints/survey-checkpoint.py +1048 -0
  8. pyphyschemtools/.ipynb_checkpoints/sympyUtilities-checkpoint.py +51 -0
  9. pyphyschemtools/.ipynb_checkpoints/tools4AS-checkpoint.py +964 -0
  10. pyphyschemtools/.readthedocs.yaml +23 -0
  11. pyphyschemtools/Chem3D.py +12 -8
  12. pyphyschemtools/ML.py +6 -4
  13. pyphyschemtools/PeriodicTable.py +9 -4
  14. pyphyschemtools/__init__.py +3 -3
  15. pyphyschemtools/aithermo.py +5 -6
  16. pyphyschemtools/core.py +7 -6
  17. pyphyschemtools/spectra.py +78 -58
  18. pyphyschemtools/survey.py +0 -449
  19. pyphyschemtools/sympyUtilities.py +9 -9
  20. pyphyschemtools/tools4AS.py +12 -8
  21. {pyphyschemtools-0.1.0.dist-info → pyphyschemtools-0.1.2.dist-info}/METADATA +2 -2
  22. {pyphyschemtools-0.1.0.dist-info → pyphyschemtools-0.1.2.dist-info}/RECORD +30 -20
  23. /pyphyschemtools/{icons-logos-banner → icons_logos_banner}/Logo_pyPhysChem_border.svg +0 -0
  24. /pyphyschemtools/{icons-logos-banner → icons_logos_banner}/__init__.py +0 -0
  25. /pyphyschemtools/{icons-logos-banner → icons_logos_banner}/logo.png +0 -0
  26. /pyphyschemtools/{icons-logos-banner → icons_logos_banner}/tools4pyPC_banner.png +0 -0
  27. /pyphyschemtools/{icons-logos-banner → icons_logos_banner}/tools4pyPC_banner.svg +0 -0
  28. {pyphyschemtools-0.1.0.dist-info → pyphyschemtools-0.1.2.dist-info}/WHEEL +0 -0
  29. {pyphyschemtools-0.1.0.dist-info → pyphyschemtools-0.1.2.dist-info}/licenses/LICENSE +0 -0
  30. {pyphyschemtools-0.1.0.dist-info → pyphyschemtools-0.1.2.dist-info}/top_level.txt +0 -0
pyphyschemtools/survey.py CHANGED
@@ -597,452 +597,3 @@ class SurveyApp:
597
597
  f"<code>{os.path.abspath(self.summary_dir)}</code>"
598
598
  ))
599
599
 
600
- ############################################################
601
- # Absorption spectra
602
- ############################################################
603
-
604
- import numpy as np
605
- import matplotlib.pyplot as plt
606
- import scipy.constants as sc
607
-
608
- class SpectrumSimulator:
609
-
610
- def __init__(self, sigma_ev=0.3, plotWH=(12,8), \
611
- fontSize_axisText=14, fontSize_axisLabels=14, fontSize_legends=12,
612
- fontsize_peaks=12,
613
- colorS='#3e89be',colorVT='#469cd6'
614
- ):
615
- """
616
- Initializes the spectrum simulator
617
-
618
- Args:
619
- - sigma_ev (float): Gaussian half-width at half-maximum in electron-volts (eV).
620
- Default is 0.3 eV (GaussView default is 0.4 eV).
621
- - plotWH (tuple(int,int)): Width and Height of the matplotlib figures in inches. Default is (12,8).
622
- - colorS: color of the simulated spectrum (default ='#3e89be')
623
- - colorVT: color of the vertical transition line (default = '#469cd6')
624
-
625
- Returns:
626
- None: This method initializes the instance attributes.
627
- Calculates:
628
- - sigmanm = half-width of the Gaussian band, in nm
629
- """
630
- self.sigma_ev = sigma_ev
631
- # Conversion constante eV -> nm sigma
632
- self.ev2nm_const = (sc.h * sc.c) * 1e9 / sc.e
633
- self.sigmanm = self.ev2nm_const / self.sigma_ev
634
- self.plotW = plotWH[0]
635
- self.plotH = plotWH[1]
636
- self.colorS = colorS
637
- self.colorVT = colorVT
638
- self.fig = None
639
- self.graph = None
640
- self.fontSize_axisText = fontSize_axisText
641
- self.fontSize_axisLabels = fontSize_axisLabels
642
- self.fontSize_legends = fontSize_legends
643
- self.fontsize_peaks = fontsize_peaks
644
-
645
- print(f"sigma = {sigma_ev} eV -> sigmanm = {self.sigmanm:.1f} nm")
646
-
647
- def _initializePlot(self):
648
- fig, graph = plt.subplots(figsize=(self.plotW,self.plotH))
649
- plt.subplots_adjust(wspace=0)
650
- plt.xticks(fontsize=self.fontSize_axisText,fontweight='bold')
651
- plt.yticks(fontsize=self.fontSize_axisText,fontweight='bold')
652
- return fig, graph
653
-
654
- def _calc_epsiG(self,lambdaX,lambdai,fi):
655
- '''
656
- calculates a Gaussian band shape around a vertical transition
657
- input:
658
- - lambdaX = wavelength variable, in nm
659
- - lambdai = vertical excitation wavelength for i_th state, in nm
660
- - fi = oscillator strength for state i (dimensionless)
661
- output :
662
- molar absorption coefficient, in L mol-1 cm-1
663
- '''
664
- import scipy.constants as sc
665
- import numpy as np
666
- c = sc.c*1e2 #cm-1
667
- NA = sc.N_A #mol-1
668
- me = sc.m_e*1000 #g
669
- e = sc.e*sc.c*10 #elementary charge in esu
670
- pf = np.sqrt(np.pi)*e**2*NA/(1000*np.log(10)*c**2*me)
671
- nubarX = 1e7 / lambdaX # nm to cm-1
672
- nubari = 1e7 / lambdai
673
- sigmabar = 1e7 / self.sigmanm
674
- epsi = pf * (fi / sigmabar) * np.exp(-((nubarX - nubari)/sigmabar)**2)
675
- return epsi
676
-
677
- def _Absorbance(self,eps,opl,cc):
678
- '''
679
- Calculates the Absorbance with the Beer-Lambert law
680
- input:
681
- - eps = molar absorption coefficient, in L mol-1 cm-1
682
- - opl = optical path length, in cm
683
- - cc = concentration of the attenuating species, in mol.L-1
684
- output :
685
- Absorbance, A (dimensionless)
686
- '''
687
- return eps*opl*cc
688
-
689
- def _sumStatesWithGf(self,wavel,wavelTAB,feTAB):
690
- '''
691
- '''
692
- import numpy as np
693
- sumInt = np.zeros(len(wavel))
694
- for l in wavel:
695
- for i in range(len(wavelTAB)):
696
- sumInt[np.argwhere(l==wavel)[0][0]] += self._calc_epsiG(l,wavelTAB[i],feTAB[i])
697
- return sumInt
698
-
699
- def _FindPeaks(self,sumInt,height,prom=1):
700
- '''
701
- Finds local maxima within the spectrum based on height and prominence.
702
-
703
- Prominence is crucial when switching between linear and logarithmic scales:
704
- - In Linear mode: A large prominence (e.g., 1 to 1000) filters out noise.
705
- - In Log mode: Data is compressed into a range of ~0 to 5. A large
706
- prominence will 'hide' real peaks. A smaller value (0.01 to 0.1)
707
- is required to detect shoulders and overlapping bands.
708
-
709
- Input:
710
- - sumInt: Array of intensities (Epsilon or Absorbance).
711
- - height: Minimum height a peak must reach to be considered.
712
- - prom: Required vertical distance between the peak and its lowest contour line.
713
-
714
- Returns:
715
- - PeakIndex: Indices of the detected peaks in the wavelength array.
716
- - PeakHeight: The intensity values at these peak positions.
717
- '''
718
- from scipy.signal import find_peaks
719
- peaks = find_peaks(sumInt, height = height, threshold = None, distance = 1, prominence=prom)
720
- PeakIndex = peaks[0]
721
- # Check if 'peak_heights' exists in the properties dictionary
722
- if 'peak_heights' in peaks[1]:
723
- PeakHeight = peaks[1]['peak_heights']
724
- else:
725
- # If height=None, we extract values manually from the input data
726
- PeakHeight = sumInt[PeakIndex]
727
- return PeakIndex,PeakHeight
728
-
729
- def _FindShoulders(self, data, tP):
730
- '''
731
- ###not working
732
- Detects shoulders using the second derivative.
733
- A shoulder appears as a peak in the negative second derivative.
734
-
735
- Note on scales:
736
- - If ylog is True: data should be log10(sumInt) and tP should be log10(tP).
737
- The second derivative on log data is much more sensitive to subtle
738
- inflection points in weak transitions (like n -> pi*).
739
- - If ylog is False: data is linear sumInt and tP is linear.
740
-
741
- Returns:
742
- - shoulder_idx (ndarray): Array of indices where shoulders were found.
743
- - shoulder_heights (ndarray): The intensity values at these positions
744
- extracted from the input data.
745
- '''
746
- import numpy as np
747
- # Calculate the second derivative (rate of change of the slope)
748
- d2 = np.gradient(np.gradient(data))
749
-
750
- # We search for peaks in the opposite of the second derivative (-d2).
751
- # A local maximum in -d2 corresponds to a point of maximum curvature
752
- # (inflection), which identifies a shoulder.
753
- # We use a very low prominence threshold to capture subtle inflections.
754
- shoulder_idx, _ = self._FindPeaks(-d2, height=None, prom=0.0001)
755
- shoulder_heights = data[shoulder_idx]
756
- print(shoulder_idx, shoulder_heights )
757
-
758
- return shoulder_idx, shoulder_heights
759
-
760
- def _pickPeak(self,wavel,peaksIndex,peaksH,color,\
761
- shift=500,height=500,posAnnotation=200, ylog=False):
762
- '''
763
- Annotates peaks with a small vertical tick and the wavelength value.
764
- Adjusts offsets based on whether the plot is in log10 scale or linear.
765
- In log mode, peaksH must already be log10 values.
766
- '''
767
- s=shift
768
- h=height
769
- a=posAnnotation
770
-
771
-
772
- for i in range(len(peaksIndex)):
773
- x = wavel[peaksIndex[i]]
774
- y = peaksH[i]
775
- if ylog:
776
- # In log scale, we use multipliers to keep the same visual distance
777
- # 1.1 means "10% above the peak"
778
- # Adjust these factors based on your preference
779
- y_s = y * 1.1
780
- y_h = y * 1.3
781
- y_a = y * 1.5
782
- self.graph.vlines(x, y_s, y_h, colors=color, linestyles='solid')
783
- self.graph.annotate(f"{x:.1f}",xy=(x,y),xytext=(x,y_a),rotation=90,size=self.fontsize_peaks,ha='center',va='bottom', color=color)
784
- else:
785
- # Classic linear offsets
786
- self.graph.vlines(x, y+s, y+s+h, colors=color, linestyles='solid')
787
- self.graph.annotate(f"{x:.1f}",xy=(x,y),xytext=(x,y+s+h+a),rotation=90,size=self.fontsize_peaks,ha='center',va='bottom',color=color)
788
- return
789
-
790
- def _setup_axes(self, lambdamin, lambdamax, ymax, ylabel="Absorbance"):
791
- self.graph.set_xlabel('wavelength / nm', size=self.fontSize_axisLabels, fontweight='bold', color='#2f6b91')
792
- self.graph.set_ylabel(ylabel, size=self.fontSize_axisLabels, fontweight='bold', color='#2f6b91')
793
- self.graph.set_xlim(lambdamin, lambdamax)
794
- self.graph.set_ylim(0, ymax)
795
- self.graph.tick_params(axis='both', labelsize=self.fontSize_axisText,labelcolor='black')
796
- for tick in self.graph.xaxis.get_majorticklabels(): tick.set_fontweight('bold') #it is both powerful
797
- # (you can specify the type of a specific tick) and annoying
798
- for tick in self.graph.yaxis.get_majorticklabels(): tick.set_fontweight('bold')
799
-
800
- def plotTDDFTSpectrum(self,wavel,sumInt,wavelTAB,feTAB,tP,ylog,labelSpectrum,colorS='#0000ff',colorT='#0000cf'):
801
-
802
- '''
803
- Called by plotEps_lambda_TDDFT. Plots a single simulated UV-Vis spectrum, i.e. after
804
- gaussian broadening, together with the TDDFT vertical transitions (i.e. plotted as lines)
805
-
806
- input:
807
- - wavel = array of gaussian-broadened wavelengths, in nm
808
- - sumInt = corresponding molar absorptiopn coefficients, in L. mol-1 cm-1
809
- - wavelTAB = wavelength of TDDFT, e.g. discretized, transitions
810
- - ylog = log plot of epsilon
811
- - tP: threshold for finding the peaks
812
- - feTAB = TDDFT oscillator strength for each transition of wavelTAB
813
- - labelSpectrum = title for the spectrum
814
- '''
815
-
816
- # # --- DEBUG START ---
817
- # if ylog:
818
- # print(f"\n--- DEBUG LOG MODE ---")
819
- # print(f"Max sumInt (linear): {np.max(sumInt):.2f}")
820
- # print(f"Max sumInt (log10): {np.log10(max(np.max(sumInt), 1e-5)):.2f}")
821
- # # --- DEBUG END ---
822
- if ylog:
823
- # Apply safety floor to the entire array
824
- self.graph.set_yscale('log')
825
- ymin_val = 1.0 # Epsilon = 1
826
- else:
827
- self.graph.set_yscale('linear')
828
- ymin_val = 0
829
-
830
- # vertical lines
831
- for i in range(len(wavelTAB)):
832
- val_eps = self._calc_epsiG(wavelTAB[i],wavelTAB[i],feTAB[i])
833
- self.graph.vlines(x=wavelTAB[i], ymin=ymin_val, ymax=max(val_eps, ymin_val), colors=colorT)
834
-
835
- self.graph.plot(wavel,sumInt,linewidth=3,linestyle='-',color=colorS,label=labelSpectrum)
836
-
837
- self.graph.legend(fontsize=self.fontSize_legends)
838
- if ylog:
839
- # Use log-transformed data and log-transformed threshold
840
- # Clipping tP to 1e-5 ensures we don't take log of 0 or negative
841
- tPlog = np.log10(max(tP, 1e-5))
842
- # prom=0.05 allows detection of peaks that are close in log-magnitude
843
- peaks, peaksH_log = self._FindPeaks(np.log10(np.clip(sumInt, 1e-5, None)), tPlog, prom=0.05)
844
- peaksH = 10**peaksH_log
845
- # shoulders, shouldersH_log = self._FindShoulders(np.log10(np.clip(sumInt, 1e-5, None)), tPlog)
846
- # all_idx = np.concatenate((peaks, shoulders))
847
- # allH_log = np.concatenate((peaksH_log, shouldersH_log))
848
- # allH = 10**allH_log
849
- else:
850
- peaks, peaksH = self._FindPeaks(sumInt,tP)
851
- # shoulders, shouldersH = self._FindShoulders(wavel, sumInt, tP)
852
- # all_idx = np.concatenate((peaks, shoulders))
853
- # allH = np.concatenate((peaksH, shouldersH))
854
- self._pickPeak(wavel,peaks,peaksH,colorS,500,500,200,ylog)
855
-
856
-
857
- def plotEps_lambda_TDDFT(self,datFile,lambdamin=200,lambdamax=800,\
858
- epsMax=None, titles=None, tP = 10, \
859
- ylog=False,\
860
- filename=None):
861
- '''
862
- Plots a TDDFT VUV simulated spectrum (vertical transitions and transitions summed with gaussian functions)
863
- between lambdamin and lambdamax (sum of states done in the range [lambdamin-50, lambdamlax+50] nm)
864
- input:
865
- - datFile: list of pathway/names to "XXX_ExcStab.dat" files generated by 'GParser Gaussian.log -S'
866
- - lambdamin, lambdamax: plot range
867
- - epsMax: y axis graph limit
868
- - titles: list of titles (1 per spectrum plot)
869
- - tP: threshold for finding the peaks (default = 10 L. mol-1 cm-1)
870
- - ylog: y logarithmic axis (default: False).
871
- - save: saves in a png file (300 dpi) if True (default = False)
872
- - filename: saves figure in a 300 dpi png file if not None (default), with filename=full pathway
873
- '''
874
- if self.fig is not None:
875
- graph = self.graph
876
- fig = self.fig
877
- lambdamin = self.lambdamin
878
- lambdamax = self.lambdamax
879
- epsMax = self.epsMax
880
- else:
881
- fig, graph = self._initializePlot()
882
-
883
- graph.set_prop_cycle(None)
884
-
885
- if self.fig is None:
886
- self.fig = fig
887
- self.graph = graph
888
- self.lambdamin = lambdamin
889
- self.lambdamax = lambdamax
890
- self.epsMax = epsMax
891
-
892
- graph.set_xlabel('wavelength / nm',size=self.fontSize_axisLabels,fontweight='bold',color='#2f6b91')
893
-
894
- graph.set_xlim(lambdamin,lambdamax)
895
-
896
- import matplotlib.ticker as ticker
897
- graph.xaxis.set_major_locator(ticker.MultipleLocator(50)) # sets a tick for every integer multiple of the base (here 250) within the view interval
898
-
899
- istate,state,wavel,fe,SSq = np.genfromtxt(datFile,skip_header=1,dtype="<U20,<U20,float,float,<U20",unpack=True)
900
- wavel = np.array(wavel)
901
- fe = np.array(fe)
902
- if wavel.size == 1:
903
- wavel = np.array([wavel])
904
- fe = np.array([fe])
905
- wvl = np.arange(lambdamin-50,lambdamax+50,1)
906
- sumInt = self._sumStatesWithGf(wvl,wavel,fe)
907
- self.plotTDDFTSpectrum(wvl,sumInt,wavel,fe,tP,ylog,titles,self.colorS,self.colorVT)
908
- if ylog:
909
- graph.set_ylabel('log(molar absorption coefficient / L mol$^{-1}$ cm$^{-1})$',size=self.fontSize_axisLabels,fontweight='bold',color='#2f6b91')
910
- graph.set_ylim(1, epsMax * 5 if epsMax else None)
911
- else:
912
- graph.set_yscale('linear')
913
- graph.set_ylabel('molar absorption coefficient / L mol$^{-1}$ cm$^{-1}$',size=self.fontSize_axisLabels,fontweight='bold',color='#2f6b91')
914
- graph.set_ylim(0, epsMax if epsMax else np.max(sumInt)*1.18)
915
- if filename is not None: self.fig.savefig(filename, dpi=300, bbox_inches='tight')
916
- plt.show()
917
-
918
- peaksI, peaksH = self._FindPeaks(sumInt,tP)
919
- print(f"{bg.LIGHTREDB}{titles}{bg.OFF}")
920
- for i in range(len(peaksI)):
921
- print(f"peak {i:3}. {wvl[peaksI[i]]:4} nm. epsilon_max = {peaksH[i]:.1f} L mol-1 cm-1")
922
- if ylog:
923
- print()
924
- # prom=0.05 allows detection of peaks that are close in log-magnitude
925
- peaksI, peaksH = self._FindPeaks(np.log10(np.clip(sumInt, 1e-5, None)), np.log10(max(tP, 1e-5)), prom=0.05)
926
- for i in range(len(peaksI)):
927
- print(f"peak {i:3}. {wvl[peaksI[i]]:4} nm. log10(epsilon_max) = {peaksH[i]:.1f}")
928
-
929
- def plotAbs_lambda_TDDFT(self, datFiles=None, C0=1e-5, lambdamin=200, lambdamax=800, Amax=2.0,\
930
- titles=None, linestyles=[], annotateP=[], tP = 0.1,\
931
- resetColors=False,\
932
- filename=None):
933
- '''
934
- Plots a simulated TDDFT VUV absorbance spectrum (transitions summed with gaussian functions)
935
- between lambdamin and lambdamax (sum of states done in the range [lambdamin-50, lambdamlax+50] nm)
936
- input:
937
- - datFiles: list of pathway/name to files generated by 'GParser Gaussian.log -S'
938
- - C0: list of concentrations needed to calculate A = epsilon x l x c (in mol.L-1)
939
- - lambdamin, lambdamax: plot range (x axis)
940
- - Amax: y axis graph limit
941
- - titles: list of titles (1 per spectrum plot)
942
- - linestyles: list of line styles(default = "-", i.e. a continuous line)
943
- - annotateP: list of Boolean (annotate lambda max True or False. Default = True)
944
- - tP: threshold for finding the peaks (default = 0.1)
945
- - resetColors (bool): If True, resets the matplotlib color cycle
946
- to the first color. This allows different series
947
- (e.g., gas phase vs. solvent) to share the same
948
- color coding for each molecule across multiple calls. Default: False
949
- - save: saves in a png file (300 dpi) if True (default = False)
950
- - filename: saves figure in a 300 dpi png file if not None (default), with filename=full pathway
951
- '''
952
-
953
- if self.fig is None:
954
- fig, graph = self._initializePlot()
955
- self.fig = fig
956
- self.graph = graph
957
- self.lambdamin = lambdamin
958
- self.lambdamax = lambdamax
959
- self.Amax = Amax
960
- else:
961
- graph = self.graph
962
- fig = self.fig
963
- lambdamin = self.lambdamin
964
- lambdamax = self.lambdamax
965
- Amax = self.Amax
966
- if resetColors: graph.set_prop_cycle(None)
967
-
968
- if linestyles == []: linestyles = len(datFiles)*['-']
969
- if annotateP == []: annotateP = len(datFiles)*[True]
970
-
971
- self._setup_axes(lambdamin, lambdamax, self.Amax, ylabel="Absorbance")
972
-
973
- wvl = np.arange(lambdamin-50,lambdamax+50,1)
974
- for f in range(len(datFiles)):
975
- istate,state,wavel,fe,SSq = np.genfromtxt(datFiles[f],skip_header=1,dtype="<U20,<U20,float,float,<U20",unpack=True)
976
- sumInt = self._sumStatesWithGf(wvl,wavel,fe)
977
- Abs = self._Absorbance(sumInt,1,C0[f])
978
- plot=self.graph.plot(wvl,Abs,linewidth=3,linestyle=linestyles[f],label=f"{titles[f]}. TDDFT ($C_0$={C0[f]} mol/L)")
979
- peaksI, peaksH = self._FindPeaks(Abs,tP,0.01)
980
- if (annotateP[f]): self._pickPeak(wvl,peaksI,peaksH,plot[0].get_color(),0.01,0.04,0.02)
981
- print(f"{bg.LIGHTREDB}TDDFT. {titles[f]}{bg.OFF}")
982
- for i in range(len(peaksI)):
983
- print(f"peak {i:3}. {wvl[peaksI[i]]:4} nm. A = {peaksH[i]:.2f}")
984
-
985
- self.graph.legend(fontsize=self.fontSize_legends)
986
-
987
- if filename is not None: self.fig.savefig(filename, dpi=300, bbox_inches='tight')
988
-
989
- return
990
-
991
- def plotAbs_lambda_exp(self, csvFiles, C0, lambdamin=200, lambdamax=800,\
992
- Amax=2.0, titles=None, linestyles=[], annotateP=[], tP = 0.1,\
993
- filename=None):
994
- '''
995
- Plots an experimental VUV absorbance spectrum read from a csv file between lambdamin and lambdamax
996
- input:
997
- - superpose: False = plots a new graph, otherwise the plot is superposed to a previously created one
998
- (probably with plotAbs_lambda_TDDFT())
999
- - csvfiles: list of pathway/name to experimental csvFiles (see examples for the format)
1000
- - C0: list of experimental concentrations, i.e. for each sample
1001
- - lambdamin, lambdamax: plot range (x axis)
1002
- - Amax: graph limit (y axis)
1003
- - titles: list of titles (1 per spectrum plot)
1004
- - linestyles: list of line styles(default = "--", i.e. a dashed line)
1005
- - annotateP: list of Boolean (annotate lambda max True or False. Default = True)
1006
- - tP: threshold for finding the peaks (default = 0.1)
1007
- - save: saves in a png file (300 dpi) if True (default = False)
1008
- - filename: saves figure in a 300 dpi png file if not None (default), with filename=full pathway
1009
- '''
1010
- if linestyles == []: linestyles = len(csvFiles)*['--']
1011
- if annotateP == []: annotateP = len(csvFiles)*[True]
1012
-
1013
- if self.fig is not None:
1014
- graph = self.graph
1015
- fig = self.fig
1016
- lambdamin = self.lambdamin
1017
- lambdamax = self.lambdamax
1018
- Amax = self.Amax
1019
- else:
1020
- fig, graph = self._initializePlot()
1021
-
1022
- graph.set_prop_cycle(None)
1023
-
1024
- if self.fig is None:
1025
- self.graph = graph
1026
- self.fig = fig
1027
- self.lambdamin = lambdamin
1028
- self.lambdamax = lambdamax
1029
- self.Amax = Amax
1030
-
1031
- self._setup_axes(lambdamin, lambdamax, self.Amax, ylabel="Absorbance")
1032
-
1033
- for f in range(len(csvFiles)):
1034
- wavel,Abs = np.genfromtxt(csvFiles[f],skip_header=1,unpack=True,delimiter=";")
1035
- wavel *= 1e9
1036
- plot=graph.plot(wavel,Abs,linewidth=3,linestyle=linestyles[f],label=f"{titles[f]}. exp ($C_0$={C0[f]} mol/L)")
1037
- peaksI, peaksH = self._FindPeaks(Abs,tP,0.01)
1038
- if (annotateP[f]): self._pickPeak(wavel,peaksI,peaksH,plot[0].get_color(),0.01,0.04,0.02)
1039
- print(f"{bg.LIGHTREDB}exp. {titles[f]}{bg.OFF}")
1040
- for i in range(len(peaksI)):
1041
- print(f"peak {i:3}. {wavel[peaksI[i]]:4} nm. A = {peaksH[i]:.2f}")
1042
-
1043
- graph.legend(fontsize=self.fontSize_legends)
1044
-
1045
- if filename is not None: self.fig.savefig(filename, dpi=300, bbox_inches='tight')
1046
-
1047
- return
1048
-
@@ -8,11 +8,9 @@ def PrintLatexStyleSymPyEquation(spe):
8
8
  """
9
9
  Function that displays a SymPy expression (spe) in a jupyter notebbok after its conversion into a LaTeX / Math output
10
10
 
11
- Input:
12
- spe: SymPy expression
11
+ Input: spe= SymPy expression
13
12
 
14
- Output:
15
- Pretty printing of spe
13
+ Output: Pretty printing of spe
16
14
 
17
15
  """
18
16
  from IPython.display import display,Math
@@ -23,12 +21,14 @@ def PrintLatexStyleSymPyEquation(spe):
23
21
  def e2Lists(eigenvectors, sort=False):
24
22
  '''
25
23
  returns two separate lists from the list of tuples returned by the eigenvects() function of SymPy
26
- input
27
- - the list of tuples returned by eigenvects
28
- - sort (default: False): returns sorted eigenvalues and corresponding eigenvectors if True
24
+
25
+ input:
26
+ - the list of tuples returned by eigenvects
27
+ - sort (default: False): returns sorted eigenvalues and corresponding eigenvectors if True
28
+
29
29
  output
30
- - list of eigenvalues, sorted or not
31
- - list of corresponding eigenvectors
30
+ - list of eigenvalues, sorted or not
31
+ - list of corresponding eigenvectors
32
32
  '''
33
33
  import numpy as np
34
34
  eps = list()
@@ -30,22 +30,24 @@ import seaborn as sns
30
30
 
31
31
  def verifNotes(dfCC,labelNoteCC,nomCC,NI,absents='aabs'):
32
32
  """
33
- entrée :
33
+ Args:
34
34
  - dfCC = dataframe dont 1 colonne contient les notes de CC
35
35
  - labelNoteCC = label de la colonne qui contient les notes
36
36
  - nomCC = label de l'épreuve de CC (ex CC1), utilisé pour l'affichage
37
37
  - NI = nombre d'inscrits dans le module
38
- - absents = 'aabs' : analyser s'il y a des étudiants qui n'ont pas été pointés au CC (défaut)
39
- = 'noabs' : ne pas analyser s'il y a des étudiants qui n'ont pas été pointés au CC
40
- (ça n'a plus de sens une fois les fichiers concaténés)
38
+ - absents:
39
+ * 'aabs' : analyser s'il y a des étudiants qui n'ont pas été pointés au CC (défaut)
40
+ * 'noabs' : ne pas analyser s'il y a des étudiants qui n'ont pas été pointés au CC
41
+ (ça n'a plus de sens une fois les fichiers concaténés)
41
42
 
42
- sortie :
43
+ Returns:
43
44
  - la moyenne et la déviation standard de liste de notes contenues dans le dataframe dfCC
44
45
  - le nombre d'étudiants qui n'ont pas composé au CC
45
46
 
46
- affichages :
47
- - nombre d'étudiants avec label 'ABS'|'Abs'|'abs'
48
- - nombre d'étudiants sans note ni label ABS. En général c'est problématique. Vérifier le PV
47
+ Note:
48
+ Affiche le nombre d'étudiants avec le label 'ABS' et signale les
49
+ étudiants sans note ni label, ce qui nécessite une vérification du PV.
50
+
49
51
  """
50
52
  print()
51
53
  #pd.set_option("display.max_rows", len(dfCC))
@@ -81,9 +83,11 @@ def RenameDfHeader(dfCC,dfCCname,labelNoteCC,nomCC):
81
83
  - dfCCname = nom (string) du dataframe. Il est recommandé d'utiliser f'{dfCC=}'.split('=')[0]
82
84
  - labelNoteCC = label de la colonne qui contient les notes
83
85
  - nomCC = label de l'épreuve de CC (ex CC1), utilisé pour l'affichage
86
+
84
87
  sortie : aucune
85
88
 
86
89
  la fonction change le nom 'labelNoteCC' en 'nomCC'
90
+
87
91
  """
88
92
  print(f"{hl.BOLD}{fg.BLUE}Normalisation du nom des colonnes de notes{fg.OFF}")
89
93
  print(f"{hl.BOLD}Dataframe = {dfCCname}.{fg.OFF} {labelNoteCC} --> {nomCC}")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyphyschemtools
3
- Version: 0.1.0
3
+ Version: 0.1.2
4
4
  Summary: A comprehensive Python toolbox for physical chemistry and cheminformatics
5
5
  Author-email: "Romuald POTEAU, LPCNO" <romuald.poteau@utoulouse.fr>
6
6
  Project-URL: Homepage, https://github.com/rpoteau/pyphyschemtools
@@ -29,7 +29,7 @@ Requires-Dist: numpydoc; extra == "docs"
29
29
  Dynamic: license-file
30
30
 
31
31
  <div style="text-align:center">
32
- <img src="https://raw.githubusercontent.com/rpoteau/pyphyschemtools/main/pyphyschemtools/icons-logos-banner/tools4pyPC_banner.png" alt="t4pyPCbanner" width="800"/>
32
+ <img src="https://raw.githubusercontent.com/rpoteau/pyphyschemtools/main/pyphyschemtools/icons_logos_banner/tools4pyPC_banner.png" alt="t4pyPCbanner" width="800"/>
33
33
  </div>
34
34
 
35
35
  # pyPhysChemTools
@@ -1,22 +1,32 @@
1
- pyphyschemtools/Chem3D.py,sha256=i6ieFGEiO1bwZ7GdtNnFCEbfVRXa4YSGkd7SLnjndUs,32709
2
- pyphyschemtools/ML.py,sha256=ofNGptNqv31BGG_QKepYmpF9M_uPLkDRXhrJiDWsqWo,1608
3
- pyphyschemtools/PeriodicTable.py,sha256=bk11SIN3xofpIp2SIZHLx7t-EyRBFUVRUUpfddaSvCc,13499
4
- pyphyschemtools/__init__.py,sha256=CUZWtKfjmw964Dx6wfVxBu5j049Om-f6ScwhGyvjMsE,1465
5
- pyphyschemtools/aithermo.py,sha256=8x204bHVZwR2bb6j3G6XrUD0XePxcZG6NCH6808x8K0,15017
1
+ pyphyschemtools/.__init__.py.swp,sha256=JxmB0a9RQHIw7mLGqOKJivHfhEca0dQRe3uVOBKNh9E,12288
2
+ pyphyschemtools/.readthedocs.yaml,sha256=ZTw2bOyF9p3JpeF8Ux0fwhYWO6KHCsroNEOvnXxbYGM,469
3
+ pyphyschemtools/Chem3D.py,sha256=LGMZYXF3iKaXERZGFCaqql3mQMN3di47TWv39FWSj3U,32719
4
+ pyphyschemtools/ML.py,sha256=kR_5vm5TOOjVef8uXCW57y7685ts6K6OkRMBYKP_cYw,1599
5
+ pyphyschemtools/PeriodicTable.py,sha256=LfLSFOzRkirREQlwfeSR3TyvgHyjGiltIZXNmvBkbhQ,13526
6
+ pyphyschemtools/__init__.py,sha256=obYnkAlRpwE3vUFgeQDML3wvhkzTTW1BD5nFxV2qsZ4,1442
7
+ pyphyschemtools/aithermo.py,sha256=kF8wtuYIJzkUKM2AGubmn9haAJKz-XaBskZ7HjivJeY,14984
6
8
  pyphyschemtools/cheminformatics.py,sha256=Qps_JSYWOzZQcXwKElI1iWGjWAPDgwmtDKuJwONsKmI,8977
7
- pyphyschemtools/core.py,sha256=m2WGuu3EmLTJvMoD_WDScGesbRfo9PIC6HIdAUQRGHg,4866
9
+ pyphyschemtools/core.py,sha256=5fRu83b125w2p_m2H521fLjktyswZHJXNKww1wfBwbU,4847
8
10
  pyphyschemtools/kinetics.py,sha256=3YyzzQ7FKZ7wNALRDsLNLhpZpDp38LHWOUfMojsh8hE,7696
9
- pyphyschemtools/spectra.py,sha256=XMkkzrWK6QtDm2mcvNSJfbE6fiGPU-8U-nvTcPYWWdI,21626
10
- pyphyschemtools/survey.py,sha256=Rcw0xb0_nwsxETleB1C2xjKmZfrUw4PXDm48CMSptHU,45816
11
- pyphyschemtools/sympyUtilities.py,sha256=eZHv0vDAxJ5hWb40U3ZmhfDU-cwEdN-_1ZgcV_B6dGo,1558
12
- pyphyschemtools/tools4AS.py,sha256=733OboqFLDscmtVLDLdDNjAGQgUcBVm6H6Zm3uG_q3I,44778
11
+ pyphyschemtools/spectra.py,sha256=eCN9X6pK5k4KMcfWUskedWYwtxbrmJH_BvFXU1GZfVo,21702
12
+ pyphyschemtools/survey.py,sha256=YjZhhb8GFVNXoXSCxgGdZFqmCtNCx7O_uiFVCcGBYYo,24268
13
+ pyphyschemtools/sympyUtilities.py,sha256=LgLloh9dD9Mkff2WNoSnrJa3hxK0axOnK-4GS9wPtT0,1545
14
+ pyphyschemtools/tools4AS.py,sha256=BVfxf6bHnCciBMdQBSJ76Ja_aA-I_iOqQHZuVb-DsdY,44783
13
15
  pyphyschemtools/visualID.py,sha256=JlAd5nnZIliHOiKvkToArYhkbty-OntuFGf2CdPbgo8,3061
14
16
  pyphyschemtools/visualID_Eng.py,sha256=o-EdCOduo_qruRrr5kkplixaT1t79f3I3M1Ya5TOc_Q,5244
15
- pyphyschemtools/icons-logos-banner/Logo_pyPhysChem_border.svg,sha256=w6AhEF3Ym5Xe6AyUJ0WZ8rTzYXCFCSQLCAftrmPaG7w,55288
16
- pyphyschemtools/icons-logos-banner/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
- pyphyschemtools/icons-logos-banner/logo.png,sha256=qnxdLQGvv1TNcz_n4EseQhzZgIX6O710tqm418_EIRY,388311
18
- pyphyschemtools/icons-logos-banner/tools4pyPC_banner.png,sha256=z7o_kBK0sIBsXHEJrT2GyLHu-0T0T3S8YkWcpxR2joA,89058
19
- pyphyschemtools/icons-logos-banner/tools4pyPC_banner.svg,sha256=JQhtJmTXkatvHwGtSc0gHBTZB_E0eh_nLB9kX7sxt7k,99752
17
+ pyphyschemtools/.ipynb_checkpoints/Chem3D-checkpoint.py,sha256=LGMZYXF3iKaXERZGFCaqql3mQMN3di47TWv39FWSj3U,32719
18
+ pyphyschemtools/.ipynb_checkpoints/PeriodicTable-checkpoint.py,sha256=LfLSFOzRkirREQlwfeSR3TyvgHyjGiltIZXNmvBkbhQ,13526
19
+ pyphyschemtools/.ipynb_checkpoints/aithermo-checkpoint.py,sha256=kF8wtuYIJzkUKM2AGubmn9haAJKz-XaBskZ7HjivJeY,14984
20
+ pyphyschemtools/.ipynb_checkpoints/core-checkpoint.py,sha256=5fRu83b125w2p_m2H521fLjktyswZHJXNKww1wfBwbU,4847
21
+ pyphyschemtools/.ipynb_checkpoints/spectra-checkpoint.py,sha256=eCN9X6pK5k4KMcfWUskedWYwtxbrmJH_BvFXU1GZfVo,21702
22
+ pyphyschemtools/.ipynb_checkpoints/survey-checkpoint.py,sha256=Rcw0xb0_nwsxETleB1C2xjKmZfrUw4PXDm48CMSptHU,45816
23
+ pyphyschemtools/.ipynb_checkpoints/sympyUtilities-checkpoint.py,sha256=LgLloh9dD9Mkff2WNoSnrJa3hxK0axOnK-4GS9wPtT0,1545
24
+ pyphyschemtools/.ipynb_checkpoints/tools4AS-checkpoint.py,sha256=BVfxf6bHnCciBMdQBSJ76Ja_aA-I_iOqQHZuVb-DsdY,44783
25
+ pyphyschemtools/icons_logos_banner/Logo_pyPhysChem_border.svg,sha256=w6AhEF3Ym5Xe6AyUJ0WZ8rTzYXCFCSQLCAftrmPaG7w,55288
26
+ pyphyschemtools/icons_logos_banner/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
+ pyphyschemtools/icons_logos_banner/logo.png,sha256=qnxdLQGvv1TNcz_n4EseQhzZgIX6O710tqm418_EIRY,388311
28
+ pyphyschemtools/icons_logos_banner/tools4pyPC_banner.png,sha256=z7o_kBK0sIBsXHEJrT2GyLHu-0T0T3S8YkWcpxR2joA,89058
29
+ pyphyschemtools/icons_logos_banner/tools4pyPC_banner.svg,sha256=JQhtJmTXkatvHwGtSc0gHBTZB_E0eh_nLB9kX7sxt7k,99752
20
30
  pyphyschemtools/resources/css/BrainHalfHalf-120x139.base64,sha256=rn-r0NKiX92EEEOlME-nUw_fC8B6mrEThX7v9L1y4Eg,25092
21
31
  pyphyschemtools/resources/css/BrainHalfHalf-120x139.png,sha256=tBhhTXidkqjvmavprPAl3BZlsqswu7DbP_rAz-tyS_Q,18818
22
32
  pyphyschemtools/resources/css/BrainHalfHalf.base64,sha256=0VLlFvSdEaVfHJR-RDNu27V0PzBN0HSfsXxGU0mRFXw,633735
@@ -73,8 +83,8 @@ pyphyschemtools/resources/svg/pyPhysChemBanner.png,sha256=sK5NwjbEYJvMAAzPBCqwvr
73
83
  pyphyschemtools/resources/svg/pyPhysChemBanner.svg,sha256=39LrLnFn7R681Hh3YXB3K17Sp0Xp3ynDOGUbXuORQ3s,4388883
74
84
  pyphyschemtools/resources/svg/qrcode-pyPhysChem.png,sha256=rP7X-9eHL7HYj4ffmwBMLfQTaRIOyzShVfavRXiomtw,71070
75
85
  pyphyschemtools/resources/svg/repository-open-graph-template.png,sha256=UlnW5BMkLGOv6IAnEi7teDYS_5qeSLmpxRMT9r9m-5Q,51470
76
- pyphyschemtools-0.1.0.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
77
- pyphyschemtools-0.1.0.dist-info/METADATA,sha256=czaz2iQUWNclIfmwqo9E1ZIKio-KGYN8_jB6jSsJcaw,1352
78
- pyphyschemtools-0.1.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
79
- pyphyschemtools-0.1.0.dist-info/top_level.txt,sha256=N92w2qk4LQ42OSdzK1R2h_x1CyUFaFBOrOML2RnmFgE,16
80
- pyphyschemtools-0.1.0.dist-info/RECORD,,
86
+ pyphyschemtools-0.1.2.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
87
+ pyphyschemtools-0.1.2.dist-info/METADATA,sha256=-dKdPNmGcUsjudhxuYnjOjU6idzHn99AuV7Hg_02FSw,1352
88
+ pyphyschemtools-0.1.2.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
89
+ pyphyschemtools-0.1.2.dist-info/top_level.txt,sha256=N92w2qk4LQ42OSdzK1R2h_x1CyUFaFBOrOML2RnmFgE,16
90
+ pyphyschemtools-0.1.2.dist-info/RECORD,,