| | 1 | Here is an example how to do a simple database based analysis in Python. This examples illustrates how to fill theta-square plots and are the Python counterparts to the example given on the main page. |
| | 2 | |
| | 3 | == Query == |
| | 4 | |
| | 5 | Both examples on this page read the following query from an ascii file `query.txt`: |
| | 6 | |
| | 7 | {{{#!sql |
| | 8 | SELECT |
| | 9 | Events.*, |
| | 10 | Position.X, |
| | 11 | Position.Y |
| | 12 | FROM |
| | 13 | Events |
| | 14 | LEFT JOIN Position USING (FileId, EvtNumber) |
| | 15 | LEFT JOIN RunInfo USING (FileId) |
| | 16 | WHERE |
| | 17 | fSourceKey=5 |
| | 18 | AND |
| | 19 | fRunTypeKey=1 |
| | 20 | AND |
| | 21 | FileId BETWEEN 180100000 AND 180200000 |
| | 22 | AND |
| | 23 | fZenithDistanceMax<35 |
| | 24 | AND |
| | 25 | fR750Cor>0.9*fR750Ref |
| | 26 | AND |
| | 27 | NumUsedPixels>5.5 |
| | 28 | AND |
| | 29 | NumIslands<3.5 |
| | 30 | AND |
| | 31 | Leakage1<0.1 |
| | 32 | AND |
| | 33 | Width*Length*PI() < LOG10(Size)*898-1535; |
| | 34 | }}} |
| | 35 | |
| | 36 | == One shot example == |
| | 37 | |
| | 38 | The first example runs the query and filling the on- and off-histograms in a single python program: |
| | 39 | |
| | 40 | {{{#!python |
| | 41 | import numpy as np |
| | 42 | import matplotlib.pyplot as plt |
| | 43 | import mysql.connector |
| | 44 | |
| | 45 | def FillHistogram(bins,n,value,weight=1): |
| | 46 | idx = np.searchsorted(bins,value) |
| | 47 | if not idx==0 and not idx>n.size: |
| | 48 | n[idx-1]+=weight |
| | 49 | |
| | 50 | mm2deg = 0.0117193246260285378 |
| | 51 | |
| | 52 | # Create bins for the histograms |
| | 53 | bins = np.linspace(0,1,56) |
| | 54 | non = np.zeros(55) |
| | 55 | noff = np.zeros(55) |
| | 56 | |
| | 57 | # Read the MySQL query from a text file |
| | 58 | queryFile = open('query.txt') |
| | 59 | query = queryFile.read() |
| | 60 | queryFile.close() |
| | 61 | |
| | 62 | # Open a connection to the MySQL database |
| | 63 | conn = mysql.connector.connect(user='fact',password='[...]',host='ihp-pc45.ethz.ch',database='factdata',port='3306') |
| | 64 | cursor = conn.cursor(dictionary=True) |
| | 65 | cursor.execute(query) |
| | 66 | |
| | 67 | # Loop over all events received from the database |
| | 68 | for Event in cursor: |
| | 69 | # Intialize all variables needed in the calculations |
| | 70 | Length = Event['Length'] |
| | 71 | Width = Event['Width'] |
| | 72 | NumIslands = Event['NumIslands'] |
| | 73 | NumUsedPixels = Event['NumUsedPixels'] |
| | 74 | Leakage1 = Event['Leakage1'] |
| | 75 | Size = Event['Size'] |
| | 76 | X = Event['X'] |
| | 77 | Y = Event['Y'] |
| | 78 | CosDelta = Event['CosDelta'] |
| | 79 | SinDelta = Event['SinDelta'] |
| | 80 | M3Long = Event['M3Long'] |
| | 81 | SlopeLong = Event['SlopeLong'] |
| | 82 | MeanX = Event['MeanX'] |
| | 83 | MeanY = Event['MeanY'] |
| | 84 | |
| | 85 | # First calculate all cuts to speedup the analysis |
| | 86 | area = np.pi*Width*Length |
| | 87 | |
| | 88 | # The abberation correction does increase also Width and Length by 1.02 |
| | 89 | cutq = (NumIslands<3.5 and NumUsedPixels>5.5 and Leakage1<0.1) |
| | 90 | if not cutq: |
| | 91 | continue |
| | 92 | |
| | 93 | cut0 = area<(np.log10(Size)*898-1535) |
| | 94 | if not cut0: |
| | 95 | continue |
| | 96 | |
| | 97 | # Loop over all wobble positions in the camera |
| | 98 | for angle in range(0,360,60): |
| | 99 | # ----------- Source dependent parameter calculation ---------- |
| | 100 | cr = np.cos(np.deg2rad(angle)) |
| | 101 | sr = np.sin(np.deg2rad(angle)) |
| | 102 | |
| | 103 | px = cr*X-sr*Y |
| | 104 | py = cr*Y+sr*X |
| | 105 | |
| | 106 | dx = MeanX-px |
| | 107 | dy = MeanY-py |
| | 108 | |
| | 109 | norm = np.sqrt(dx*dx+dy*dy) |
| | 110 | dist = norm*mm2deg |
| | 111 | |
| | 112 | lx = np.min([np.max([(CosDelta*dy-SinDelta*dx)/norm,-1.]),1.]) |
| | 113 | ly = np.min([np.max([(CosDelta*dx+SinDelta*dy)/norm,-1.]),1.]) |
| | 114 | |
| | 115 | alpha = np.arcsin(lx) |
| | 116 | sgn = np.sign(ly) |
| | 117 | |
| | 118 | # ------------------------ Application --------------------- |
| | 119 | m3l = M3Long*sgn*mm2deg |
| | 120 | slope = SlopeLong*sgn/mm2deg |
| | 121 | |
| | 122 | # -------------------------- Analysis ---------------------- |
| | 123 | xi = 1.39252+0.154247*slope+1.67972*(1-1/(1+4.86232*Leakage1)) |
| | 124 | |
| | 125 | sign1 = m3l+0.07 |
| | 126 | sign2 = (dist-0.5)*7.2-slope |
| | 127 | |
| | 128 | disp = (-xi if (sign1<0 or sign2<0) else xi)*(1-Width/Length) |
| | 129 | |
| | 130 | thetasq = disp*disp+dist*dist-2*disp*dist*np.sqrt(1-lx*lx) |
| | 131 | |
| | 132 | if angle==0: |
| | 133 | FillHistogram(bins,non,thetasq) |
| | 134 | else: |
| | 135 | FillHistogram(bins,noff,thetasq,weight=1./5.) |
| | 136 | |
| | 137 | conn.close() |
| | 138 | |
| | 139 | plt.hist(bins[:-1],bins=bins,histtype='step',weights=non) |
| | 140 | plt.hist(bins[:-1],bins=bins,histtype='step',weights=noff) |
| | 141 | plt.show() |
| | 142 | }}} |
| | 143 | |
| | 144 | == Two step example == |
| | 145 | |
| | 146 | This example works similar to `rootifysql` and a ROOT macro. It first requests the data from a database an stores it into a file and then processed the file with a second program. |
| | 147 | |
| | 148 | === Requesting and storing the data === |
| | 149 | |
| | 150 | {{{#!python |
| | 151 | import numpy as np |
| | 152 | import pickle |
| | 153 | import mysql.connector |
| | 154 | |
| | 155 | # Read the MySQL query from a text file |
| | 156 | queryFile = open('query.txt') |
| | 157 | query = queryFile.read() |
| | 158 | queryFile.close() |
| | 159 | |
| | 160 | # Open a connection to the MySQL database |
| | 161 | conn = mysql.connector.connect(user='fact',password='[...]',host='ihp-pc45.ethz.ch',database='factdata',port='3306') |
| | 162 | cursor = conn.cursor() |
| | 163 | cursor.execute(query) |
| | 164 | |
| | 165 | with open('crab-data-only.p','wb') as outFile: |
| | 166 | description = np.array(cursor.description).T[0] |
| | 167 | pickle.dump(description,outFile,pickle.HIGHEST_PROTOCOL) |
| | 168 | for Event in cursor: |
| | 169 | pickle.dump(Event,outFile,pickle.HIGHEST_PROTOCOL) |
| | 170 | |
| | 171 | conn.close() |
| | 172 | }}} |
| | 173 | |
| | 174 | === Reading and processing the data === |
| | 175 | |
| | 176 | {{{#!python |
| | 177 | import numpy as np |
| | 178 | import pickle |
| | 179 | import matplotlib.pyplot as plt |
| | 180 | |
| | 181 | def FillHistogram(bins,n,value,weight=1): |
| | 182 | idx = np.searchsorted(bins,value) |
| | 183 | if not idx==0 and not idx>n.size: |
| | 184 | n[idx-1]+=weight |
| | 185 | |
| | 186 | inFile = open('crab-data-only.p','rb') |
| | 187 | description = pickle.load(inFile) |
| | 188 | |
| | 189 | # Find indices corresponding to the different variables |
| | 190 | Length_idx = np.nonzero(description=='Length')[0][0] |
| | 191 | Width_idx = np.nonzero(description=='Width')[0][0] |
| | 192 | NumIslands_idx = np.nonzero(description=='NumIslands')[0][0] |
| | 193 | NumUsedPixels_idx = np.nonzero(description=='NumUsedPixels')[0][0] |
| | 194 | Leakage1_idx = np.nonzero(description=='Leakage1')[0][0] |
| | 195 | Size_idx = np.nonzero(description=='Size')[0][0] |
| | 196 | X_idx = np.nonzero(description=='X')[0][0] |
| | 197 | Y_idx = np.nonzero(description=='Y')[0][0] |
| | 198 | CosDelta_idx = np.nonzero(description=='CosDelta')[0][0] |
| | 199 | SinDelta_idx = np.nonzero(description=='SinDelta')[0][0] |
| | 200 | M3Long_idx = np.nonzero(description=='M3Long')[0][0] |
| | 201 | SlopeLong_idx = np.nonzero(description=='SlopeLong')[0][0] |
| | 202 | MeanX_idx = np.nonzero(description=='MeanX')[0][0] |
| | 203 | MeanY_idx = np.nonzero(description=='MeanY')[0][0] |
| | 204 | |
| | 205 | mm2deg = 0.0117193246260285378 |
| | 206 | |
| | 207 | # Create bins for the histogram |
| | 208 | bins = np.linspace(0,1,56) |
| | 209 | non = np.zeros(55) |
| | 210 | noff = np.zeros(55) |
| | 211 | |
| | 212 | while True: |
| | 213 | try: |
| | 214 | Event = pickle.load(inFile) |
| | 215 | except: |
| | 216 | break |
| | 217 | |
| | 218 | # Intialize all variables needed in the calculations |
| | 219 | Length = Event[Length_idx] |
| | 220 | Width = Event[Width_idx] |
| | 221 | NumIslands = Event[NumIslands_idx] |
| | 222 | NumUsedPixels = Event[NumUsedPixels_idx] |
| | 223 | Leakage1 = Event[Leakage1_idx] |
| | 224 | Size = Event[Size_idx] |
| | 225 | X = Event[X_idx] |
| | 226 | Y = Event[Y_idx] |
| | 227 | CosDelta = Event[CosDelta_idx] |
| | 228 | SinDelta = Event[SinDelta_idx] |
| | 229 | M3Long = Event[M3Long_idx] |
| | 230 | SlopeLong = Event[SlopeLong_idx] |
| | 231 | MeanX = Event[MeanX_idx] |
| | 232 | MeanY = Event[MeanY_idx] |
| | 233 | |
| | 234 | # First calculate all cuts to speedup the analysis |
| | 235 | area = np.pi*Width*Length |
| | 236 | |
| | 237 | # The abberation correction does increase also Width and Length by 1.02 |
| | 238 | cutq = (NumIslands<3.5 and NumUsedPixels>5.5 and Leakage1<0.1) |
| | 239 | if not cutq: |
| | 240 | continue |
| | 241 | |
| | 242 | cut0 = area<(np.log10(Size)*898-1535) |
| | 243 | if not cut0: |
| | 244 | continue |
| | 245 | |
| | 246 | #print(area,cutq,cut0) |
| | 247 | |
| | 248 | # Loop over all wobble positions in the camera |
| | 249 | for angle in range(0,360,60): |
| | 250 | # ----------- Source dependent parameter calculation ---------- |
| | 251 | cr = np.cos(np.deg2rad(angle)) |
| | 252 | sr = np.sin(np.deg2rad(angle)) |
| | 253 | |
| | 254 | px = cr*X-sr*Y |
| | 255 | py = cr*Y+sr*X |
| | 256 | |
| | 257 | dx = MeanX-px |
| | 258 | dy = MeanY-py |
| | 259 | |
| | 260 | norm = np.sqrt(dx*dx+dy*dy) |
| | 261 | dist = norm*mm2deg |
| | 262 | |
| | 263 | lx = np.min([np.max([(CosDelta*dy-SinDelta*dx)/norm,-1.]),1.]) |
| | 264 | ly = np.min([np.max([(CosDelta*dx+SinDelta*dy)/norm,-1.]),1.]) |
| | 265 | |
| | 266 | alpha = np.arcsin(lx) |
| | 267 | sgn = np.sign(ly) |
| | 268 | |
| | 269 | # ------------------------ Application --------------------- |
| | 270 | m3l = M3Long*sgn*mm2deg |
| | 271 | slope = SlopeLong*sgn/mm2deg |
| | 272 | |
| | 273 | # -------------------------- Analysis ---------------------- |
| | 274 | xi = 1.39252+0.154247*slope+1.67972*(1-1/(1+4.86232*Leakage1)) |
| | 275 | |
| | 276 | sign1 = m3l+0.07 |
| | 277 | sign2 = (dist-0.5)*7.2-slope |
| | 278 | |
| | 279 | disp = (-xi if (sign1<0 or sign2<0) else xi)*(1-Width/Length) |
| | 280 | |
| | 281 | thetasq = disp*disp+dist*dist-2*disp*dist*np.sqrt(1-lx*lx) |
| | 282 | |
| | 283 | if angle==0: |
| | 284 | FillHistogram(bins,non,thetasq) |
| | 285 | else: |
| | 286 | FillHistogram(bins,noff,thetasq,weight=1./5.) |
| | 287 | |
| | 288 | plt.hist(bins[:-1],bins=bins,histtype='step',weights=non) |
| | 289 | plt.hist(bins[:-1],bins=bins,histtype='step',weights=noff) |
| | 290 | plt.show() |
| | 291 | }}} |