pypho_signalsrc.py 6.86 KB
Newer Older
hm-striegle's avatar
hm-striegle committed
1 2 3 4 5 6 7 8 9 10
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
#  pypho.py
#  
#  Copyright 2014 Arne Striegler (arne.striegler@hm.edu)
#  
#   
#  
# Creates an electrical signal from bitpattern
hm-striegle's avatar
hm-striegle committed
11
#
hm-striegle's avatar
hm-striegle committed
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
#
########################################################################

import numpy as np
import sys

########################################################################

class pypho_signalsrc(object):
    def __init__(self, glova = None, pulseshape = [], fwhm = None):
            
        if glova == None:            
            print ("ERROR: You must define the global variables")
            sys.exit("PyPho stopped!")

        self.glova           = glova
        self.bitsequence     = []
        self.pulseshape      = None
        self.fwhm            = None
        
        self.set(pulseshape, fwhm)

########################################################################        
    def __call__(self, bitsequence = [], pulseshape = None, fwhm = None):        
    
        if len(bitsequence) == 0 :
            print ("Error: pypho_signalsrc: No bit pattern defined!")        
            sys.exit("PyPho stopped!")
        elif len(bitsequence) > 0:
            self.bitsequence = bitsequence
        
        self.set(pulseshape, fwhm)
    
hm-striegle's avatar
hm-striegle committed
45
     
hm-striegle's avatar
hm-striegle committed
46 47
        if self.pulseshape == "gauss_rz":
            self.tau = self.fwhm * 1/self.glova.symbolrate / 2.3582
hm-striegle's avatar
hm-striegle committed
48
            E = self.gauss_rz()        
hm-striegle's avatar
hm-striegle committed
49 50 51
                        
        elif self.pulseshape == "gauss_nrz":
            self.tau = self.fwhm * 1/self.glova.symbolrate / 2.3582
hm-striegle's avatar
hm-striegle committed
52
            E = self.gauss_nrz()    
hm-striegle's avatar
hm-striegle committed
53 54 55
                
        elif self.pulseshape == "sech_rz":
            self.tau = self.fwhm * 1/self.glova.symbolrate / 1.76
hm-striegle's avatar
hm-striegle committed
56
            E = self.sech_rz()    
hm-striegle's avatar
hm-striegle committed
57 58 59
   
        elif self.pulseshape == "rect":
            self.tau = 0
hm-striegle's avatar
hm-striegle committed
60
            E = self.rect()                
hm-striegle's avatar
hm-striegle committed
61 62 63
        else:
            print ("ERROR: No valid pulse shape")
            sys.exit("PyPho stopped!")        
hm-striegle's avatar
hm-striegle committed
64 65 66
        
        del self.bitsequence
        
hm-striegle's avatar
hm-striegle committed
67
        return E            
hm-striegle's avatar
hm-striegle committed
68 69 70 71 72
            

### Create Gauss RZ Pulse shape ########################################

    def gauss_rz(self):
hm-striegle's avatar
hm-striegle committed
73 74 75 76 77 78 79 80 81 82 83 84
        NoAb = 4
        refsig   = np.exp(-( ( self.glova.timeax[self.glova.nos*self.glova.sps/2 - NoAb*self.glova.sps : self.glova.nos*self.glova.sps/2 + NoAb*self.glova.sps] - 1/self.glova.symbolrate*self.glova.nos/2 )/ self.tau)**2 / 2.0 )                
        gesig    = np.zeros(self.glova.sps*self.glova.nos + 3*2*NoAb*self.glova.sps)        
        
        bits     = np.append(self.bitsequence[-NoAb:], self.bitsequence)
        bits     = np.append(bits, self.bitsequence[0:NoAb])
        for ndx in range(0, len(bits)):
            if 1 == bits[ndx]:               
                gesig[self.glova.sps * (ndx) :  self.glova.sps * (ndx + 2*NoAb )] +=  refsig
        del bits
        del  refsig
        return gesig[2*NoAb*self.glova.sps - self.glova.sps/2: 2*NoAb*self.glova.sps + self.glova.sps*self.glova.nos - self.glova.sps/2]
hm-striegle's avatar
hm-striegle committed
85 86 87 88 89
    
    
### Create sech RZ Pulse shape ########################################

    def sech_rz(self):
hm-striegle's avatar
hm-striegle committed
90 91 92 93 94 95 96
        
        NoAb = 4
        refsig   = 1/np.cosh( (self.glova.timeax[self.glova.nos*self.glova.sps/2 - NoAb*self.glova.sps : self.glova.nos*self.glova.sps/2 + NoAb*self.glova.sps] - 1/self.glova.symbolrate*self.glova.nos/2 )/ self.tau)       
        gesig    = np.zeros(self.glova.sps*self.glova.nos + 3*2*NoAb*self.glova.sps)
        
        bits     = np.append(self.bitsequence[-NoAb:], self.bitsequence)
        bits     = np.append(bits, self.bitsequence[0:NoAb])
hm-striegle's avatar
hm-striegle committed
97

hm-striegle's avatar
hm-striegle committed
98 99 100 101 102 103
        for ndx in range(0, len(bits)):
            if 1 == bits[ndx]:               
                gesig[self.glova.sps * (ndx) :  self.glova.sps * (ndx + 2*NoAb )] +=  refsig
        del bits
        del  refsig
        return gesig[2*NoAb*self.glova.sps - self.glova.sps/2: 2*NoAb*self.glova.sps + self.glova.sps*self.glova.nos - self.glova.sps/2]     
hm-striegle's avatar
hm-striegle committed
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173

### Create rectabgle pulse shape ########################################

    def rect(self):
        refrect  = np.concatenate((np.ones(self.glova.sps), np.zeros( self.glova.sps*(self.glova.nos -1 ) )), axis=0)
        bit_ones = self.bitsequence == 1
           
        gesig = 0*refrect
        
        for ndx, member in enumerate(bit_ones):
            if member:
                gesig += np.roll(refrect, self.glova.sps * ndx)
        return gesig    
        
### Create Gauss NRZ Pulse shape ########################################

    def gauss_nrz(self):
        refgaussinc        = np.exp(-( ( self.glova.timeax - 1/self.glova.symbolrate*self.glova.nos )/ self.tau)**2 / 2.0 )
        refgaussinc        = np.roll(refgaussinc, self.glova.sps/2)
        refgaussinc[self.glova.sps/2 : self.glova.sps ]  = 1
        
        refgaussdec        = np.exp(-(   self.glova.timeax / self.tau)**2 / 2.0)
        refgaussdec        = np.roll(refgaussdec, self.glova.sps/2)
        refgaussdec[0 : self.glova.sps/2 ]  = 1
        
        refgauss         = np.exp(-( ( self.glova.timeax - 1/self.glova.symbolrate*self.glova.nos/2 )/ self.tau)**2 / 2.0 )
        refgauss         = np.roll(refgauss, self.glova.sps * self.glova.nos/2 + self.glova.sps/2)
        
        refgausscomp    = np.roll(refgauss, - self.glova.sps/2)
        refgausscomp[self.glova.sps/2+1:self.glova.sps]    = refgauss[1:self.glova.sps/2]
        refgausscomp[self.glova.sps+1:]    = 0
        
        refzero            = np.zeros(self.glova.sps * self.glova.nos)
        refone            = np.concatenate([ np.ones(self.glova.sps) , np.zeros(self.glova.sps * (self.glova.nos-1)) ])

        
        gesig = 0*np.array(refgaussinc)
        bits_tmp = np.concatenate([ [0] , self.bitsequence])

        for x in range(1, self.glova.nos+1):

            if   bits_tmp[x-1]==0 and bits_tmp[x]==1:
                gesig += np.roll(refgaussinc, self.glova.sps * (x-1))
            elif bits_tmp[x-1]==1 and bits_tmp[x]==1:
                gesig += np.roll(refone, self.glova.sps * (x-1))
            elif bits_tmp[x-1]==1 and bits_tmp[x]==0:
                gesig += np.roll(refgaussdec, self.glova.sps * (x-1))
            elif bits_tmp[x-1]==0 and bits_tmp[x]==0:
                gesig += np.roll(refzero, self.glova.sps * (x-1))                

                
        return gesig    

########################################################################
    def set(self, pulseshape = None, fwhm = None):
        """Set  properties"""          
            
        if pulseshape == None and self.pulseshape == None:
            print ("WARNING: No pulseshape specified, so I am using 'gauss_rz'")
            self.pulseshape = "gauss_rz"
        elif pulseshape != None:
            self.pulseshape = pulseshape
            
            
        if fwhm == None and self.fwhm == None:
            print ("WARNING: No FWHM puls width specified, so I am using 0.3 of 1/symbolrate")
            fwhm = 0.333
        elif fwhm != None:
            self.fwhm = fwhm