Package: pcwa
PCWAA highly parallel and fast event detector based on CWT transform.PCWAis a multiscale approache to find events with any shape with a mother wavelet that matches with events shape (details provided in theNature Communicationsmanuscript currently under review). Unlike previous CWT based peak finders,PCWAis able to fit with any user defined mother wavelet function,, by grouping and clustering initial candidate points (local maxima). The clustering step involvesMacro-andu-clustering steps to break big data into smallerM-clusters. The clustering steps utilizedx-axis,scale-axisandcoefficient valuesall together to improve accuracy of located events.RequirementsPython >= 3.8.5numpy >= 1.19.2scipy >= 1.6.2matplotlib >= 3.3.4h5py >= 2.10.0pandas >= 1.2.1Most likely will work with older versions (Python > 3), not tested by the time of writing this document.How to use PCWAPCWAis designed as a Python class and requires initializing. Importpcwaand initiate a new instant:importpcwaaspcwapcwa_analyzer=pcwa.PCWA(parallel=False)# pcwa_analyzer.show_wavelets = Truepcwa_analyzer.w,pcwa_analyzer.h=1.5,1.5pcwa_analyzer.selectivity=0.7pcwa_analyzer.use_scratchfile=Falseproperties can be set during or after initializing. A list of properties are as below:Propertiesdt=1e5# sampling period of the signal in sparallel=True# enable/disable multiprocessingmcluster=True# enable/disable macro-clusteringlogscale=True# enable/disable logarithmic scale for scale-axiswavelet=['ricker']# list of wavelet function namesscales=[0.01e-3,0.1e-3,30]# scale range and count in in sselectivity=0.5# minimum number of candidates in a valid micro-clusterw=2# spreading factor in x-axish=6# spreading factor in y-axis (scale-axis)extent=1# global extent along x and y axis, used in macro-clusteringtrace=None# trace (data) variable. 1D numpy vectorevents=[]# list of detected events (valid after calling detect_events() function)cwt={}# dictionary of cwt coefficientswavelets={}# dictionary of generated scaled&normalized 1D wavelet arraysshow_wavelets=False# plot wavelet functionsupdate_cwt=True# if False, will use the current cwt coefficients to detect events to save time tuning threshold parameterskeep_cwt=False# if False, will use less memory by running conv() and local_maxima() at the same time. Otherwise will generate entire CWT coefficient before looking for local maxima (conventional method)use_scratchfile=False# stores cwt coefficients in the scarach file (hdf5 formatted) fileEvent DetectionAfter initializing, events can be detected by callingdetect_events()method.events=pcwa_analyzer.detect_events(trace=data,wavelet=['ricker'],scales=[0.1e-3,1.0e-3,50],threshold=3)tpr,fdr=pcwa.tprfdr(truth,events['loc'],e=7e-3/1e-5,MS=True)# e is the tolerance of error for event location, here 7ms/0.01ms (in data points), 0.01ms is the bin sizesome of pcwa parameters can overridden when callingdetect_events()by passing the following parameters:trace:        overrides the tracewavelet:      overrides wavelet functionsscales:       overrides scalesthresholdis the only parameter required at each call.Example CodeThe example below shows how to usePCWAto detect peaks in a simulated mass spectroscopy data.importnumpyasnpimportpandasaspdimportpcwaaspcwaimportmatplotlib.pyplotasplt# read the raw mass scpectroscopy data and truth valuesdf_raw=pd.read_csv('n100sig66_dataset_1_25/Dataset_14/RawSpectra/noisy22.txt',sep=' ')df_true=pd.read_csv('n100sig66_dataset_1_25/Dataset_14/truePeaks/truth22.txt',sep=' ')# create pcwa_analyzer object and set the desired parameterspcwa_analyzer=pcwa.PCWA()pcwa_analyzer.trace=df_raw['Intensity']pcwa_analyzer.dt=1pcwa_analyzer.scales=[10,100,100]pcwa_analyzer.wavelet=['ricker']pcwa_analyzer.keep_cwt=Falsepcwa_analyzer.w,pcwa_analyzer.h=0.2,1pcwa_analyzer.show_wavelets=Falsepcwa_analyzer.use_scratchfile=False# detect events (peaks)events=pcwa_analyzer.detect_events(threshold=200)# fine tune the location of detected peaksloc=[int(e-events['scale'][n]+np.argmax(df_raw['Intensity'][int(e-events['scale'][n]):int(e+events['scale'][n])]))forn,einenumerate(events['loc'])]fig,ax=plt.subplots(3,1,figsize=(16,4),dpi=96,sharex=True,gridspec_kw={'height_ratios':[12,1,1]})plt.subplots_adjust(hspace=0,wspace=0)l0,=ax[1].plot(df_true['Mass'],df_true['Particles']*0,'|',markersize=10,color='gray',label='Truth')ax[0].plot(df_raw['Mass'],df_raw['Intensity'],color='blue')l1,=ax[2].plot(df_raw['Mass'].iloc[loc],[0]*len(loc),'|',markersize=10,color='red',label='PCWA')ax[1].set_yticks([])ax[1].set_ylim(0,0)ax[2].set_yticks([])ax[2].set_ylim(0,0)ax[0].set_ylabel('Intensity')ax[-1].set_xlabel('m/z')plt.legend(handles=[l0,l1],bbox_to_anchor=(1.0,4),loc='upper left')plt.show()Once the analysis is finished, the plot window should show the results as below:If you want to calculateTPRandFDRvalue, useful forROCplots,PCWAclass provides a function to do that.true_peaks=np.sort(df_true['Mass'].to_numpy())detected_peaks=np.sort(df_raw['Mass'].iloc[loc].to_numpy())tpr,fdr=pcwa.tprfdr(true_peaks,detected_peaks,e=0.01,MS=True)print(f"TPR={tpr:.3f}, FDR={fdr:.3f}")TPR=0.864, FDR=0.014the command window should show theTPRandFDRvalues based on the ground truth values and acceptable error range (1% here).MSparameter determines the way of applying acceptable error, for mass spectroscopy data error is considered relative to mass value (). IfMS=False, the absolute error value is considered.
The full example file is provided in this repository (ms_example.py).ReferenceThe provided dataset is a subset taken from the simulated Mass Spectroscopy dataset (DOI:10.1093/bioinformatics/bti254).