task: metadata: install: pip install -e .[dev]
patch: diff --git a/CHANGELOG.md b/CHANGELOG.md
index db09d9c..3328c92 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -14,6 +14,9 @@ First stable release.
 #### Changed
 - Return type for `hm_utils.pc_counter` is now either a tone counter or the sum of the quarter length values associated with each pitch class; any normalization now must use `hm_utils.normalize_pc_counter`.
 
+#### Removed
+- Removed unnecessary `frag_type` parameter to `Extraction`. Now a class attribute of `GeneralFragment` (and subclasses).
+
 ## [v0.14.1](https://github.com/Luke-Poeppel/decitala/tree/v0.14.1) July 2, 2021
 #### Fixed
 - Fixed a number of typos and added missing examples in `decitala.hm`.
diff --git a/decitala/path_finding/pofp.py b/decitala/path_finding/pofp.py
index 9f11be7..b01c87e 100644
--- a/decitala/path_finding/pofp.py
+++ b/decitala/path_finding/pofp.py
@@ -76,11 +76,11 @@ def get_pareto_optimal_longest_paths(data):
 	>>> from decitala.search import Extraction
 	>>> from decitala.fragment import GreekFoot, GeneralFragment
 	>>> data = [
-	... 	Extraction(fragment=GreekFoot("Spondee"), frag_type="greek_foot", onset_range=(0.0, 0.5), retrograde=False, factor=0.125, difference=0.0, mod_hierarchy_val=1, pitch_content=[None], is_spanned_by_slur=False, slur_count=0, slur_start_end_count=0, id_=1), # noqa
-	... 	Extraction(fragment=GeneralFragment([0.25, 0.25], name="cs-test1"), frag_type="general_fragment", onset_range=(0.0, 0.5), retrograde=False, factor=2.0, difference=0.0, mod_hierarchy_val=1, pitch_content=[None], is_spanned_by_slur=False, slur_count=0, slur_start_end_count=0, id_=2), # noqa
-	... 	Extraction(fragment=GreekFoot("Trochee"), frag_type="greek_foot", onset_range=(0.25, 0.625), retrograde=False, factor=0.125, difference=0.0, mod_hierarchy_val=1, pitch_content=[None], is_spanned_by_slur=False, slur_count=0, slur_start_end_count=0, id_=3), # noqa
-	... 	Extraction(fragment=GeneralFragment([0.25, 0.125], name="cs-test2"), frag_type="general_fragment", onset_range=(0.25, 0.625), retrograde=False, factor=0.125, difference=0.0, mod_hierarchy_val=1, pitch_content=[None], is_spanned_by_slur=False, slur_count=0, slur_start_end_count=0, id_=4), # noqa
-	... 	Extraction(fragment=GreekFoot("Dactyl"), frag_type="greek_foot", onset_range=(0.5, 1.0), retrograde=False, factor=0.125, difference=0.0, mod_hierarchy_val=1, pitch_content=[None], is_spanned_by_slur=False, slur_count=0, slur_start_end_count=0, id_=5) # noqa
+	... 	Extraction(fragment=GreekFoot("Spondee"), onset_range=(0.0, 0.5), retrograde=False, factor=0.125, difference=0.0, mod_hierarchy_val=1, pitch_content=[None], is_spanned_by_slur=False, slur_count=0, slur_start_end_count=0, id_=1), # noqa
+	... 	Extraction(fragment=GeneralFragment([0.25, 0.25], name="cs-test1"), onset_range=(0.0, 0.5), retrograde=False, factor=2.0, difference=0.0, mod_hierarchy_val=1, pitch_content=[None], is_spanned_by_slur=False, slur_count=0, slur_start_end_count=0, id_=2), # noqa
+	... 	Extraction(fragment=GreekFoot("Trochee"), onset_range=(0.25, 0.625), retrograde=False, factor=0.125, difference=0.0, mod_hierarchy_val=1, pitch_content=[None], is_spanned_by_slur=False, slur_count=0, slur_start_end_count=0, id_=3), # noqa
+	... 	Extraction(fragment=GeneralFragment([0.25, 0.125], name="cs-test2"), onset_range=(0.25, 0.625), retrograde=False, factor=0.125, difference=0.0, mod_hierarchy_val=1, pitch_content=[None], is_spanned_by_slur=False, slur_count=0, slur_start_end_count=0, id_=4), # noqa
+	... 	Extraction(fragment=GreekFoot("Dactyl"), onset_range=(0.5, 1.0), retrograde=False, factor=0.125, difference=0.0, mod_hierarchy_val=1, pitch_content=[None], is_spanned_by_slur=False, slur_count=0, slur_start_end_count=0, id_=5) # noqa
 	... ]
 	>>> for path in get_pareto_optimal_longest_paths(data):
 	... 	for fragment in path:
diff --git a/decitala/search.py b/decitala/search.py
index 9981996..ad8ebf7 100644
--- a/decitala/search.py
+++ b/decitala/search.py
@@ -48,7 +48,6 @@ class SearchException(Exception):
 @dataclass
 class Extraction:
 	fragment: GeneralFragment
-	frag_type: str
 	onset_range: tuple
 
 	retrograde: bool
@@ -91,7 +90,6 @@ class Extraction:
 					if extraction.fragment == split_elem:
 						extraction_obj = Extraction(
 							fragment=extraction.fragment,
-							frag_type=extraction.frag_type,
 							onset_range=extraction.onset_range,
 							retrograde=extraction.retrograde,
 							factor=extraction.factor,
@@ -255,7 +253,6 @@ def frame_lookup(frame, ql_array, curr_fragment_id, table, windows):
 			offset_2 = frame[-1][0]
 			return Extraction(
 				fragment=searched["fragment"],
-				frag_type=searched["fragment"].frag_type,
 				onset_range=(offset_1.offset, offset_2.offset + offset_2.quarterLength),
 				retrograde=searched["retrograde"],
 				factor=searched["factor"],

problem_statement: Need for `fragment` and `frag_type` in `Extraction`?
Both shouldn't be needed. The `frag_type` is a class attribute of the `fragment`. 
https://github.com/Luke-Poeppel/decitala/blob/681b1158faeb19f4cd82573f3bcd9fb411560b35/decitala/search.py#L48-L52
repo: Luke-Poeppel/decitala
test_cmd: pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
test_patch: diff --git a/tests/test_pofp.py b/tests/test_pofp.py
index abb1884..807b440 100644
--- a/tests/test_pofp.py
+++ b/tests/test_pofp.py
@@ -19,7 +19,6 @@ from decitala.search import Extraction
 def fake_data():
 	extraction_1 = Extraction(
 		fragment=GeneralFragment(name="info1", data=[1, 2]),
-		frag_type="general_fragment",
 		onset_range=(0.0, 2.0),
 		retrograde=False,
 		factor=1.0,
@@ -33,7 +32,6 @@ def fake_data():
 	)
 	extraction_2 = Extraction(
 		fragment=GeneralFragment(name="info2", data=[1, 2]),
-		frag_type="general_fragment",
 		onset_range=(0.0, 4.0),
 		retrograde=False,
 		factor=2.0,
@@ -47,7 +45,6 @@ def fake_data():
 	)
 	extraction_3 = Extraction(
 		fragment=GeneralFragment(name="info3", data=[1, 2]),
-		frag_type="general_fragment",
 		onset_range=(2.0, 4.0),
 		retrograde=False,
 		factor=1.0,
@@ -61,7 +58,6 @@ def fake_data():
 	)
 	extraction_4 = Extraction(
 		fragment=GeneralFragment(name="info4", data=[1, 2]),
-		frag_type="general_fragment",
 		onset_range=(2.0, 5.75),
 		retrograde=True,
 		factor=1.0,
@@ -75,7 +71,6 @@ def fake_data():
 	)
 	extraction_5 = Extraction(
 		fragment=GeneralFragment(name="info5", data=[1, 2]),
-		frag_type="general_fragment",
 		onset_range=(2.5, 4.5),
 		retrograde=False,
 		factor=3.0,
@@ -89,7 +84,6 @@ def fake_data():
 	)
 	extraction_6 = Extraction(
 		fragment=GeneralFragment(name="info6", data=[1, 2]),
-		frag_type="general_fragment",
 		onset_range=(4.0, 5.5),
 		retrograde=False,
 		factor=1.0,
@@ -103,7 +97,6 @@ def fake_data():
 	)
 	extraction_7 = Extraction(
 		fragment=GeneralFragment(name="info7", data=[1, 2]),
-		frag_type="general_fragment",
 		onset_range=(6.0, 7.25),
 		retrograde=True,
 		factor=1.0,
diff --git a/tests/test_search.py b/tests/test_search.py
index 6c57c2b..2d800b0 100644
--- a/tests/test_search.py
+++ b/tests/test_search.py
@@ -82,7 +82,6 @@ def test_frame_is_spanned_by_slur_b(fp2):
 def extraction():
 	return search.Extraction(
 		fragment=Decitala("Gajajhampa"),
-		frag_type="decitala",
 		onset_range=(0.25, 0.75),
 		retrograde=False,
 		factor=1.0,