1 """
2 The stats module maps statistical category identifiers from NFL.com's
3 GameCenter JSON feed to a representation of what we believe that statistical
4 category means. This mapping has been reverse engineered with a lot of help
5 from reddit users rasherdk and curien.
6
7 If you think anything here is wrong (or can figure out some of the unknowns),
8 please let me know by filing an issue here:
9 https://github.com/BurntSushi/nflgame/issues
10
11 For each statistical category identifier, we create a dict of 6 fields
12 describing that statistical category. The fields are cat, field, yds, super,
13 value and desc.
14
15 cat specifies which statistical category the particular stat belong in. Only
16 statistical categories in nflgame.player.categories should be used.
17
18 field specifies the actual statistical field corresponding to the stat. This
19 will manifest itself as a property on statistical objects via the API.
20
21 yds specifies a field that contains the yardage totals relevant to the stat.
22 If a stat does not specify yards, this field should be blank (an empty string).
23
24 super specifies parent statistical fields that must be derived (either
25 partially or in full) from the stat. For example, the kicking_cnt field
26 has no corresponding statistical category id, but it can be derived through
27 multiple other fields (kicking_outendzone_fielded, kicking_inendzone_fielded,
28 and kicking_touchback). Thus, in each of the child fields, kicking_cnt should
29 be listed as a parent field. Parent fields always correspond to the sum of
30 all their child fields.
31
32 value specifies how much each statistic is worth. This is 1 in every case
33 except for split sacks.
34
35 desc specifies a human readable description for the statistic. It should be
36 concise and clear. If a statistical category is unknown, then desc should
37 contain a string like 'Unknown (reason for confusion)'. Valid reasons for
38 confusion include "data is inconsistent" or "this looks like a duplicate" all
39 the way to "I have no fucking clue."
40 """
41
42 categories = {
43 2: {
44 'cat': 'punting',
45 'field': 'punting_blk',
46 'yds': '',
47 'super': ['punting_cnt'],
48 'value': 1,
49 'desc': 'Punt blocked',
50 },
51 3: {
52 'cat': 'team',
53 'field': 'rushing_first_down',
54 'yds': '',
55 'super': ['first_down'],
56 'value': 1,
57 'desc': 'First down (rush)',
58 },
59 4: {
60 'cat': 'team',
61 'field': 'passing_first_down',
62 'yds': '',
63 'super': ['first_down'],
64 'value': 1,
65 'desc': 'First down (pass)',
66 },
67 5: {
68 'cat': 'team',
69 'field': 'penalty_first_down',
70 'yds': '',
71 'super': ['first_down'],
72 'value': 1,
73 'desc': 'First down (penalty)',
74 },
75 6: {
76 'cat': 'team',
77 'field': 'third_down_conv',
78 'yds': '',
79 'super': ['third_down_att'],
80 'value': 1,
81 'desc': 'Third down conversion',
82 },
83 7: {
84 'cat': 'team',
85 'field': 'third_down_failed',
86 'yds': '',
87 'super': ['third_down_att'],
88 'value': 1,
89 'desc': 'Third down failed',
90 },
91 8: {
92 'cat': 'team',
93 'field': 'fourth_down_conv',
94 'yds': '',
95 'super': ['fourth_down_att'],
96 'value': 1,
97 'desc': 'Fourth down conversion',
98 },
99 9: {
100 'cat': 'team',
101 'field': 'fourth_down_failed',
102 'yds': '',
103 'super': ['fourth_down_att'],
104 'value': 0,
105 'desc': 'Fourth down failed',
106 },
107 10: {
108 'cat': 'rushing',
109 'field': 'rushing_att',
110 'yds': 'rushing_yds',
111 'super': [],
112 'value': 1,
113 'desc': 'Rush',
114 },
115 11: {
116 'cat': 'rushing',
117 'field': 'rushing_tds',
118 'yds': 'rushing_yds',
119 'super': ['rushing_att'],
120 'value': 1,
121 'desc': 'Rush TD',
122 },
123 12: {
124 'cat': 'passing',
125 'field': None,
126 'yds': '',
127 'super': [],
128 'value': 0,
129 'desc': 'Unknown (no clue)',
130 },
131 14: {
132 'cat': 'passing',
133 'field': 'passing_incmp',
134 'yds': '',
135 'super': ['passing_att'],
136 'value': 1,
137 'desc': 'Incomplete pass',
138 },
139 15: {
140 'cat': 'passing',
141 'field': 'passing_cmp',
142 'yds': 'passing_yds',
143 'super': ['passing_att'],
144 'value': 1,
145 'desc': 'Completed pass (total yards)',
146 },
147 16: {
148 'cat': 'passing',
149 'field': 'passing_tds',
150 'yds': 'passing_yds',
151 'super': ['passing_att', 'passing_cmp'],
152 'value': 1,
153 'desc': 'Touchdown pass (total yards)',
154 },
155 19: {
156 'cat': 'passing',
157 'field': 'passing_int',
158 'yds': '',
159 'super': ['passing_att', 'passing_incmp'],
160 'value': 1,
161 'desc': 'QB throws interception',
162 },
163 20: {
164 'cat': 'passing',
165 'field': 'passing_sk',
166 'yds': 'passing_sk_yds',
167 'super': [],
168 'value': 1,
169 'desc': 'QB sacked',
170 },
171 21: {
172 'cat': 'receiving',
173 'field': 'receiving_rec',
174 'yds': 'receiving_yds',
175 'super': [],
176 'value': 1,
177 'desc': 'Completed reception (total yards)',
178 },
179 22: {
180 'cat': 'receiving',
181 'field': 'receiving_tds',
182 'yds': 'receiving_yds',
183 'super': ['receiving_rec'],
184 'value': 1,
185 'desc': 'Touchdown reception (total yards)',
186 },
187 23: {
188 'cat': 'lateral',
189 'field': 'lateral_rec',
190 'yds': 'lateral_rec_yds',
191 'super': [],
192 'value': 1,
193 'desc': 'Lateral catch on offense',
194 },
195 24: {
196
197 'cat': 'lateral',
198 'field': 'lateral_rec_tds',
199 'yds': 'lateral_rec_yds',
200 'super': ['lateral_rec'],
201 'value': 1,
202 'desc': 'Lateral catch on offense for touchdown',
203 },
204 25: {
205 'cat': 'defense',
206 'field': 'defense_int',
207 'yds': 'defense_int_yds',
208 'super': [],
209 'value': 1,
210 'desc': 'Interception',
211 },
212 26: {
213 'cat': 'defense',
214 'field': 'defense_int_tds',
215 'yds': 'defense_int_yds',
216 'super': ['defense_int'],
217 'value': 1,
218 'desc': 'Interception returned for touchdown',
219 },
220 27: {
221 'cat': 'lateral',
222 'field': 'lateral_int_rec',
223 'yds': 'lateral_int_rec_yds',
224 'super': [],
225 'value': 1,
226 'desc': 'Lateral catch after interception',
227 },
228 28: {
229 'cat': 'lateral',
230 'field': 'lateral_int_rec_tds',
231 'yds': 'lateral_int_rec_yds',
232 'super': ['lateral_int_rec'],
233 'value': 1,
234 'desc': 'Lateral catch after interception for touchdown',
235 },
236 29: {
237 'cat': 'punting',
238 'field': 'punting_cnt',
239 'yds': 'punting_yds',
240 'super': [],
241 'value': 1,
242 'desc': 'Punt',
243 },
244 30: {
245 'cat': 'punting',
246 'field': 'punting_i20',
247 'yds': '',
248 'super': ['punting_cnt'],
249 'value': 1,
250 'desc': 'Punt inside 20',
251 },
252 31: {
253 'cat': 'punting',
254 'field': None,
255 'yds': '',
256 'super': [],
257 'value': 0,
258 'desc': 'Unknown (inside 20 return? only happened 4 times in 2011)',
259 },
260 32: {
261 'cat': 'punting',
262 'field': 'punting_touchback',
263 'yds': 'punting_yds',
264 'super': ['punting_cnt'],
265 'value': 1,
266 'desc': 'Punt (touchback)',
267 },
268 33: {
269 'cat': 'puntret',
270 'field': 'puntret_tot',
271 'yds': 'puntret_yds',
272 'super': [],
273 'value': 1,
274 'desc': 'Punt return',
275 },
276 34: {
277 'cat': 'puntret',
278 'field': 'puntret_tds',
279 'yds': 'puntret_yds',
280 'super': [],
281 'value': 1,
282 'desc': 'Punt return touchdown',
283 },
284 35: {
285 'cat': 'lateral',
286 'field': 'lateral_punt_rec',
287 'yds': 'lateral_punt_rec_yds',
288 'super': [],
289 'value': 1,
290 'desc': 'Lateral catch after punt',
291 },
292 36: {
293
294 'cat': 'lateral',
295 'field': 'lateral_punt_rec_tds',
296 'yds': 'lateral_punt_rec_yds',
297 'super': ['lateral_punt_rec'],
298 'value': 1,
299 'desc': 'Lateral catch after punt for touchdown',
300 },
301 37: {
302 'cat': 'team',
303 'field': 'puntret_oob',
304 'yds': '',
305 'super': [],
306 'value': 1,
307 'desc': 'Punt out of bounds (receiving team)',
308 },
309 38: {
310 'cat': 'team',
311 'field': 'puntret_downed',
312 'yds': '',
313 'super': [],
314 'value': 1,
315 'desc': 'Punt downed by kicking team',
316 },
317 39: {
318 'cat': 'puntret',
319 'field': 'puntret_fair',
320 'yds': '',
321 'super': [],
322 'value': 1,
323 'desc': 'Punt fair catch',
324 },
325 40: {
326 'cat': 'team',
327 'field': 'puntret_touchback',
328 'yds': '',
329 'super': [],
330 'value': 1,
331 'desc': 'Punt return touchback',
332 },
333 41: {
334 'cat': 'kicking',
335 'field': 'kicking_outendzone_fielded',
336 'yds': 'kicking_yds',
337 'super': ['kicking_cnt', 'kicking_fielded'],
338 'value': 1,
339 'desc': 'Kickoff fielded from outside the endzone',
340 },
341 42: {
342 'cat': 'kicking',
343 'field': None,
344 'yds': '',
345 'super': [],
346 'value': 0,
347 'desc': 'Unknown (kick fielded? redundant?)',
348 },
349 43: {
350 'cat': 'kicking',
351 'field': 'kicking_inendzone_fielded',
352 'yds': 'kicking_yds',
353 'super': ['kicking_cnt', 'kicking_fielded'],
354 'value': 1,
355 'desc': 'Kickoff fielded from inside the endzone',
356 },
357 44: {
358 'cat': 'kicking',
359 'field': 'kicking_touchback',
360 'yds': 'kicking_yds',
361 'super': ['kicking_cnt', 'kicking_tbacks'],
362 'value': 1,
363 'desc': 'Kickoff touchback',
364 },
365 45: {
366 'cat': 'kickret',
367 'field': 'kickret_ret',
368 'yds': 'kickret_yds',
369 'super': [],
370 'value': 1,
371 'desc': 'Kickoff return',
372 },
373 46: {
374 'cat': 'kickret',
375 'field': 'kickret_td',
376 'yds': 'kickret_yds',
377 'super': ['kickret_ret'],
378 'value': 1,
379 'desc': 'Kickoff return TD',
380 },
381 47: {
382 'cat': 'lateral',
383 'field': None,
384 'yds': '',
385 'value': 0,
386 'desc': 'Unknown (lateral after kickoff; name is inconsistent?)',
387 },
388 48: {
389 'cat': 'lateral',
390 'field': None,
391 'yds': '',
392 'value': 0,
393 'desc': 'Unknown (lateral after kickoff for td?)',
394 },
395 49: {
396 'cat': 'team',
397 'field': 'kickret_oob',
398 'yds': '',
399 'super': [],
400 'value': 1,
401 'desc': 'Kickoff return out of bounds',
402 },
403 50: {
404 'cat': 'kickret',
405 'field': 'kickret_fair',
406 'yds': '',
407 'super': ['kickret_ret'],
408 'value': 1,
409 'desc': 'Kickoff return (fair catch)',
410 },
411 51: {
412 'cat': 'team',
413 'field': 'kickret_touchback_outendzone',
414 'yds': '',
415 'super': [],
416 'value': 0,
417 'desc': 'Kick return touchback out of endzone',
418 },
419 52: {
420 'cat': 'fumbles',
421 'field': 'fumbles_strp',
422 'yds': '',
423 'super': [],
424 'value': 1,
425 'desc': 'Fumbled (stripped)',
426 },
427 53: {
428 'cat': 'fumbles',
429 'field': 'fumbles_drop',
430 'yds': '',
431 'super': ['fumbles_tot'],
432 'value': 1,
433 'desc': 'Fumbled (drop)',
434 },
435 54: {
436 'cat': 'fumbles',
437 'field': 'fumbles_oob',
438 'yds': '',
439 'super': [],
440 'value': 1,
441 'desc': 'Fumbled (oob)',
442 },
443 55: {
444 'cat': 'fumbles',
445 'field': 'fumbles_rec',
446 'yds': 'fumbles_rec_yds',
447 'super': [],
448 'value': 1,
449 'desc': 'Fumble recovery',
450 },
451 56: {
452 'cat': 'fumbles',
453 'field': 'fumbles_rec_tds',
454 'yds': 'fumbles_rec_yds',
455 'super': ['fumbles_rec'],
456 'value': 1,
457 'desc': 'Fumble recovery touchdown',
458 },
459 57: {
460 'cat': 'fumbles',
461 'field': None,
462 'yds': '',
463 'super': [],
464 'value': 0,
465 'desc': 'Unknown (redundant with 53? incorrect negative yards?)',
466 },
467 59: {
468 'cat': 'defense',
469 'field': 'defense_frec',
470 'yds': 'defense_frec_yds',
471 'super': [],
472 'value': 1,
473 'desc': 'Defensive fumble recovery return',
474 },
475 60: {
476 'cat': 'defense',
477 'field': 'defense_frec_tds',
478 'yds': 'defense_frec_yds',
479 'super': ['defense_frec'],
480 'value': 1,
481 'desc': 'Defensive fumble recovery return touchdown',
482 },
483 61: {
484 'cat': 'lateral',
485 'field': 'lateral_fumble_rec',
486 'yds': 'lateral_fumble_rec_yds',
487 'super': [],
488 'value': 1,
489 'desc': 'Lateral catch after fumble recovery',
490 },
491 62: {
492
493 'cat': 'lateral',
494 'field': 'lateral_fumble_rec_tds',
495 'yds': 'lateral_fumble_rec_yds',
496 'super': ['lateral_fumble_rec'],
497 'value': 1,
498 'desc': 'Lateral catch after fumble recovery for touchdown',
499 },
500 63: {
501 'cat': 'defense',
502 'field': 'defense_blk_yds',
503 'yds': 'defense_blk_yds',
504 'super': [],
505 'value': 0,
506 'desc': 'FG/Punt block return',
507 },
508 64: {
509 'cat': 'defense',
510 'field': 'defense_blk_tds',
511 'yds': 'defense_blk_yds',
512 'super': [],
513 'value': 1,
514 'desc': 'FG/Punt block return',
515 },
516 68: {
517 'cat': 'team',
518 'field': 'timeout',
519 'yds': '',
520 'super': [],
521 'value': 1,
522 'desc': 'Timeout',
523 },
524 69: {
525 'cat': 'kicking',
526 'field': 'kicking_fgmissed',
527 'yds': 'kicking_fgmissed_yds',
528 'super': ['kicking_fga'],
529 'value': 1,
530 'desc': 'Field goal missed',
531 },
532 70: {
533 'cat': 'kicking',
534 'field': 'kicking_fgm',
535 'yds': 'kicking_fgm_yds',
536 'super': ['kicking_fga'],
537 'value': 1,
538 'desc': 'Field goal good',
539 },
540 71: {
541 'cat': 'kicking',
542 'field': 'kicking_fgb',
543 'yds': 'kicking_fgb_yds',
544 'super': ['kicking_fga'],
545 'value': 1,
546 'desc': 'Field goal blocked',
547 },
548 72: {
549 'cat': 'kicking',
550 'field': 'kicking_xpmade',
551 'yds': '',
552 'super': ['kicking_xpa'],
553 'value': 1,
554 'desc': 'PAT good',
555 },
556 73: {
557 'cat': 'kicking',
558 'field': 'kicking_xpmissed',
559 'yds': '',
560 'super': ['kicking_xpa'],
561 'value': 1,
562 'desc': 'PAT failed',
563 },
564 74: {
565 'cat': 'kicking',
566 'field': 'kicking_xpb',
567 'yds': '',
568 'super': ['kicking_xpa', 'kicking_xpmissed'],
569 'value': 1,
570 'desc': 'PAT blocked',
571 },
572 75: {
573 'cat': 'rushing',
574 'field': 'rushing_twoptm',
575 'yds': '',
576 'super': ['rushing_twopta'],
577 'value': 1,
578 'desc': '2pt conversion successful (rush)',
579 },
580 76: {
581 'cat': 'rushing',
582 'field': 'rushing_twoptmissed',
583 'yds': '',
584 'super': ['rushing_twopta'],
585 'value': 1,
586 'desc': '2pt conversion failed (rush)',
587 },
588 77: {
589 'cat': 'passing',
590 'field': 'passing_twoptm',
591 'yds': '',
592 'super': ['passing_twopta'],
593 'value': 1,
594 'desc': '2pt conversion successful (pass)',
595 },
596 78: {
597 'cat': 'passing',
598 'field': 'passing_twoptmissed',
599 'yds': '',
600 'super': ['passing_twopta'],
601 'value': 1,
602 'desc': '2pt conversion failed (pass)',
603 },
604 79: {
605 'cat': 'defense',
606 'field': 'defense_tkl',
607 'yds': '',
608 'super': [],
609 'value': 1,
610 'desc': 'Tackle',
611 },
612 80: {
613 'cat': 'defense',
614 'field': 'defense_tkl_primary',
615 'yds': '',
616 'super': ['defense_tkl'],
617 'value': 1,
618 'desc': 'Tackle (primary)',
619 },
620 82: {
621 'cat': 'defense',
622 'field': 'defense_ast',
623 'yds': '',
624 'super': [],
625 'value': 1,
626 'desc': 'Tackle (assist)',
627 },
628 83: {
629 'cat': 'defense',
630 'field': 'defense_sk',
631 'yds': 'defense_sk_yds',
632 'super': [],
633 'value': 1,
634 'desc': 'Sack',
635 },
636 84: {
637 'cat': 'defense',
638 'field': 'defense_sk_split',
639 'yds': 'defense_sk_yds',
640 'super': ['defense_sk'],
641 'value': 0.5,
642 'desc': 'Sack (split)',
643 },
644 85: {
645 'cat': 'defense',
646 'field': 'defense_pass_def',
647 'yds': '',
648 'super': [],
649 'value': 1,
650 'desc': 'Pass defended',
651 },
652 86: {
653 'cat': 'defense',
654 'field': 'defense_puntblk',
655 'yds': '',
656 'super': [],
657 'value': 1,
658 'desc': 'Punt blocked',
659 },
660 87: {
661 'cat': 'defense',
662 'field': 'defense_xpblk',
663 'yds': '',
664 'super': [],
665 'value': 1,
666 'desc': 'PAT blocked',
667 },
668 88: {
669 'cat': 'defense',
670 'field': 'defense_fgblk',
671 'yds': '',
672 'super': [],
673 'value': 1,
674 'desc': 'Blocked field goal',
675 },
676 89: {
677 'cat': 'defense',
678 'field': 'defense_safe',
679 'yds': '',
680 'super': [],
681 'value': 1,
682 'desc': 'Safety',
683 },
684 91: {
685 'cat': 'defense',
686 'field': 'defense_ffum',
687 'yds': '',
688 'super': [],
689 'value': 1,
690 'desc': 'Forced fumble',
691 },
692 93: {
693 'cat': 'penalty',
694 'field': 'penalty',
695 'yds': 'penalty_yds',
696 'super': [],
697 'value': 1,
698 'desc': 'Penalty',
699 },
700 95: {
701 'cat': 'team',
702 'field': 'rush_loss',
703 'yds': 'rush_loss_yds',
704 'super': [],
705 'value': 1,
706 'desc': 'Unknown (rush resulting in loss of yards)',
707 },
708 102: {
709 'cat': 'team',
710 'field': 'onside_failed',
711 'yds': '',
712 'super': ['onside_att'],
713 'value': 1,
714 'desc': 'Onside kick failed',
715 },
716 104: {
717 'cat': 'receiving',
718 'field': 'receiving_twoptm',
719 'yds': '',
720 'super': ['receiving_twopta'],
721 'value': 1,
722 'desc': '2pt conversion successful (reception)',
723 },
724 105: {
725 'cat': 'receiving',
726 'field': 'receiving_twoptmissed',
727 'yds': '',
728 'super': ['receiving_twopta'],
729 'value': 1,
730 'desc': '2pt conversion failed (reception)',
731 },
732 106: {
733 'cat': 'fumbles',
734 'field': 'fumbles_lost',
735 'yds': '',
736 'super': [],
737 'value': 1,
738 'desc': 'Fumble lost',
739 },
740 107: {
741 'cat': 'kicking',
742 'field': 'kicking_onside_rec',
743 'yds': '',
744 'super': [],
745 'value': 1,
746 'desc': 'Onside kick recovery',
747 },
748 110: {
749 'cat': 'defense',
750 'field': 'defense_qbtkl',
751 'yds': '',
752 'super': [],
753 'value': 1,
754 'desc': 'Tackled QB (including sacks)',
755 },
756 111: {
757 'cat': 'passing',
758 'field': 'passing_cmp_airyds',
759 'yds': 'passing_cmp_airyds',
760 'super': [],
761 'value': 0,
762 'desc': 'Completed yards (in the air)',
763 },
764 112: {
765 'cat': 'passing',
766 'field': 'passing_incmp_airyds',
767 'yds': 'passing_incmp_airyds',
768 'super': [],
769 'value': 0,
770 'desc': 'Passing yards (in the air; incomplete)',
771 },
772 113: {
773 'cat': 'receiving',
774 'field': 'receiving_yac',
775 'yds': 'receiving_yac',
776 'super': [],
777 'value': 0,
778 'desc': 'Yards after the catch',
779 },
780 115: {
781 'cat': 'receiving',
782 'field': 'receiving_tar',
783 'yds': '',
784 'super': [],
785 'value': 1,
786 'desc': 'Target',
787 },
788 120: {
789 'cat': 'defense',
790 'field': 'defense_tkl_loss',
791 'yds': '',
792 'super': [],
793 'value': 1,
794 'desc': 'Tackle (for loss of yards)',
795 },
796 301: {
797 'cat': 'team',
798 'field': 'xp_aborted',
799 'yds': '',
800 'super': [],
801 'value': 1,
802 'desc': 'PAT aborted',
803 },
804 402: {
805 'cat': 'defense',
806 'field': 'defense_tkl_loss_yds',
807 'yds': 'defense_tkl_loss_yds',
808 'super': [],
809 'value': 0,
810 'desc': 'Tackle yard loss',
811 },
812 }
813