| 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 | }}} |