def test_get_step_index(self): structured_datapath_loc = os.path.join( TEST_FILE_DIR, "PreDiag_000240_000227_truncated_structure.json") parameters_path = os.path.join(TEST_FILE_DIR, "data-share", "raw", "parameters") structured_datapath = auto_load_processed(structured_datapath_loc) data = structured_datapath.diagnostic_data hppc_cycles = data.loc[data.cycle_type == "hppc"] # print(hppc_cycles.step_index.unique()) _, protocol_name = os.path.split(structured_datapath.metadata.protocol) parameter_row, _ = parameters_lookup.get_protocol_parameters( protocol_name, parameters_path=parameters_path) for cycle in hppc_cycles.cycle_index.unique(): hppc_cycle = hppc_cycles[hppc_cycles.cycle_index == cycle] for step in hppc_cycle.step_index.unique(): hppc_cycle_step = hppc_cycle[(hppc_cycle.step_index == step)] for step_iter in hppc_cycle_step.step_index_counter.unique(): hppc_cycle_step_iter = hppc_cycle_step[( hppc_cycle_step.step_index_counter == step_iter)] duration = hppc_cycle_step_iter.test_time.max( ) - hppc_cycle_step_iter.test_time.min() median_crate = np.round( hppc_cycle_step.current.median() / parameter_row["capacity_nominal"].iloc[0], 2) # print(step, median_crate, duration) step_ind = featurizer_helpers.get_step_index(structured_datapath, cycle_type="hppc", diag_pos=0) self.assertEqual(len(step_ind.values()), 6) print([ step_ind["hppc_long_rest"], step_ind["hppc_discharge_pulse"], step_ind["hppc_short_rest"], step_ind["hppc_charge_pulse"], step_ind["hppc_discharge_to_next_soc"] ]) self.assertEqual( step_ind, { 'hppc_charge_to_soc': 9, 'hppc_long_rest': 11, 'hppc_discharge_pulse': 12, 'hppc_short_rest': 13, 'hppc_charge_pulse': 14, 'hppc_discharge_to_next_soc': 15 }) step_ind = featurizer_helpers.get_step_index(structured_datapath, cycle_type="hppc", diag_pos=1) self.assertEqual(len(step_ind.values()), 6) self.assertEqual( step_ind, { 'hppc_charge_to_soc': 41, 'hppc_long_rest': 43, 'hppc_discharge_pulse': 44, 'hppc_short_rest': 45, 'hppc_charge_pulse': 46, 'hppc_discharge_to_next_soc': 47 })
def test_RawInterpolatedData(self): structured_datapath_loc = os.path.join( TEST_FILE_DIR, "PredictionDiagnostics_000132_00004C_structure.json") structured_datapath = auto_load_processed(structured_datapath_loc) f = RawInterpolatedData(structured_datapath) self.assertTrue(f.validate()[0]) self.assertListEqual(f.hyperparameters["metrics"], ['capacity', 'dQdV', 'test_time']) f.create_features() self.assertEqual(f.features.shape, (1, 36)) for column, content in f.features.items(): self.assertEqual(len(content.tolist()[0]), 500) self.assertAlmostEqual( f.features.iloc[0]["diag_cycle_1_rpt_0.2C_test_time_step_0"][-1], 1.685e+04, delta=1e2) # Test if rerunning feature works since dictionaries are being updated in place f = RawInterpolatedData(structured_datapath) f.create_features() self.assertEqual(f.features.shape, (1, 36))
def test_ChargingProtocol(self): structured_datapath_loc = os.path.join( TEST_FILE_DIR, "PredictionDiagnostics_000132_00004C_structure.json") structured_datapath = auto_load_processed(structured_datapath_loc) f = ChargingProtocol(structured_datapath) self.assertTrue(f.validate()[0]) self.assertListEqual(f.hyperparameters["quantities"], [ "charge_constant_current_1", "charge_constant_current_2", "charge_cutoff_voltage", "charge_constant_voltage_time", "discharge_constant_current", "discharge_cutoff_voltage" ]) f.create_features() self.assertEqual(f.features.shape, (1, 6)) # print(list(f.features.iloc[2, :])) self.assertAlmostEqual(f.features.iloc[0]["charge_constant_current_1"], 1.0, 2) # Test if rerunning feature works since dictionaries are being updated in place f = ChargingProtocol(structured_datapath) f.create_features() self.assertEqual(f.features.shape, (1, 6))
def test_HPPCRelaxationFeatures_class(self): with ScratchDir("."): os.environ["BEEP_PROCESSING_DIR"] = TEST_FILE_DIR pcycler_run_loc = os.path.join( TEST_FILE_DIR, "PreDiag_000240_000227_truncated_structure.json") pcycler_run = auto_load_processed(pcycler_run_loc) featurizer = HPPCRelaxationFeatures.from_run( pcycler_run_loc, os.getcwd(), pcycler_run) path, local_filename = os.path.split(featurizer.name) folder = os.path.split(path)[-1] dumpfn(featurizer, featurizer.name) params_dict = { "test_time_filter_sec": 1000000, "cycle_index_filter": 6, "n_soc_windows": 8, "soc_list": [90, 80, 70, 60, 50, 40, 30, 20, 10], "percentage_list": [50, 80, 99], "hppc_list": [0, 1], } self.assertEqual(folder, "HPPCRelaxationFeatures") self.assertEqual(featurizer.X.shape[1], 30) self.assertListEqual( [featurizer.X.columns[0], featurizer.X.columns[-1]], ["var_50%", "SOC10%_degrad99%"], ) self.assertEqual(featurizer.metadata["parameters"], params_dict)
def test_reloading_new(self): test_file = os.path.join( TEST_FILE_DIR, "PredictionDiagnostics_000107_0001B9_structure_short.json") struct = auto_load_processed(test_file) self.assertEqual( struct.schema, os.path.join(VALIDATION_SCHEMA_DIR, "schema-maccor-2170.yaml"))
def setUp(self): run = os.path.join(TEST_FILE_DIR, 'PreDiag_000220_00005E_structure_omit.json') self.cell_struct = auto_load_processed(run) self.cathode_file = os.path.join( TEST_FILE_DIR, 'data-share/raw/cell_info/cathode_test.csv') self.anode_file = os.path.join( TEST_FILE_DIR, 'data-share/raw/cell_info/anode_test.csv')
def test_feature_class(self): with ScratchDir("."): os.environ["BEEP_PROCESSING_DIR"] = os.getcwd() pcycler_run_loc = os.path.join( TEST_FILE_DIR, "2017-06-30_2C-10per_6C_CH10_structure.json") pcycler_run = auto_load_processed(pcycler_run_loc) featurizer = DeltaQFastCharge.from_run(pcycler_run_loc, os.getcwd(), pcycler_run) path, local_filename = os.path.split(featurizer.name) folder = os.path.split(path)[-1] self.assertEqual( local_filename, "2017-06-30_2C-10per_6C_CH10_features_DeltaQFastCharge.json", ) self.assertEqual(folder, "DeltaQFastCharge") dumpfn(featurizer, featurizer.name) processed_run_list = [] processed_result_list = [] processed_message_list = [] processed_paths_list = [] run_id = 1 featurizer_classes = [DeltaQFastCharge, TrajectoryFastCharge] for featurizer_class in featurizer_classes: featurizer = featurizer_class.from_run(pcycler_run_loc, os.getcwd(), pcycler_run) if featurizer: self.assertEqual(featurizer.metadata["channel_id"], 9) self.assertEqual( featurizer.metadata["protocol"], '2017-06-30_tests\\20170629-2C_10per_6C.sdu') self.assertEqual(featurizer.metadata["barcode"], 'el150800460605') dumpfn(featurizer, featurizer.name) processed_paths_list.append(featurizer.name) processed_run_list.append(run_id) processed_result_list.append("success") processed_message_list.append({"comment": "", "error": ""}) else: processed_paths_list.append(pcycler_run_loc) processed_run_list.append(run_id) processed_result_list.append("incomplete") processed_message_list.append({ "comment": "Insufficient or incorrect data for featurization", "error": "", }) self.assertEqual(processed_result_list, ["success", "success"]) trajectory = loadfn( os.path.join( "TrajectoryFastCharge", "2017-06-30_2C-10per_6C_CH10_features_TrajectoryFastCharge.json", )) self.assertEqual(trajectory.X.loc[0, "capacity_0.8"], 161)
def test_get_step_index_3(self): structured_datapath_loc = os.path.join( TEST_FILE_DIR, "PredictionDiagnostics_000136_00002D_truncated_structure.json") structured_datapath = auto_load_processed(structured_datapath_loc) step_ind = featurizer_helpers.get_step_index(structured_datapath, cycle_type="hppc", diag_pos=0) self.assertEqual(len(step_ind.values()), 6)
def test_get_step_index_3(self): pcycler_run_loc = os.path.join( TEST_FILE_DIR, "PredictionDiagnostics_000136_00002D_truncated_structure.json") os.environ["BEEP_PROCESSING_DIR"] = TEST_FILE_DIR pcycler_run = auto_load_processed(pcycler_run_loc) step_ind = featurizer_helpers.get_step_index(pcycler_run, cycle_type="hppc", diag_pos=0) self.assertEqual(len(step_ind.values()), 6)
def test_feature_label_full_model(self): processed_cycler_run_path = os.path.join(TEST_FILE_DIR, self.processed_cycler_file) with ScratchDir("."): os.environ["BEEP_PROCESSING_DIR"] = os.getcwd() pcycler_run = auto_load_processed(processed_cycler_run_path) featurizer = DeltaQFastCharge.from_run(processed_cycler_run_path, os.getcwd(), pcycler_run) self.assertEqual(featurizer.X.columns.tolist()[4], "charge_time_cycles_1:5")
def test_feature_serialization_for_training(self): processed_cycler_run_path = os.path.join(TEST_FILE_DIR, self.processed_cycler_file) with ScratchDir("."): os.environ["BEEP_PROCESSING_DIR"] = os.getcwd() pcycler_run = auto_load_processed(processed_cycler_run_path) featurizer = DeltaQFastCharge.from_run(processed_cycler_run_path, os.getcwd(), pcycler_run) dumpfn(featurizer, featurizer.name) features_reloaded = loadfn(featurizer.name) self.assertIsInstance(features_reloaded, DeltaQFastCharge)
def test_get_diffusion_coeff(self): with ScratchDir("."): structured_datapath_loc = os.path.join( TEST_FILE_DIR, "PreDiag_000240_000227_truncated_structure.json") structured_datapath = auto_load_processed(structured_datapath_loc) diffusion_df = featurizer_helpers.get_diffusion_coeff( structured_datapath, 1) print(np.round(diffusion_df.iloc[0].to_list(), 3)) self.assertEqual( np.round(diffusion_df.iloc[0].to_list(), 3)[0], -0.016) self.assertEqual( np.round(diffusion_df.iloc[0].to_list(), 3)[5], -0.011)
def test_generate_dQdV_peak_fits(self): processed_cycler_run_path = os.path.join( TEST_FILE_DIR, "PreDiag_000304_000153_truncated_structure.json") with ScratchDir("."): os.environ["BEEP_PROCESSING_DIR"] = TEST_FILE_DIR pcycler_run = auto_load_processed(processed_cycler_run_path) peaks_df = featurizer_helpers.generate_dQdV_peak_fits( pcycler_run, 'rpt_0.2C', 0, 1, plotting_y_n=1) print(len(peaks_df.columns)) self.assertEqual(peaks_df.columns.tolist(), [ 'm0_Amp_rpt_0.2C_1', 'm0_Mu_rpt_0.2C_1', 'm1_Amp_rpt_0.2C_1', 'm1_Mu_rpt_0.2C_1', 'm2_Amp_rpt_0.2C_1', 'm2_Mu_rpt_0.2C_1', 'trough_height_0_rpt_0.2C_1', 'trough_height_1_rpt_0.2C_1' ])
def test_get_diffusion_coeff(self): with ScratchDir("."): os.environ["BEEP_PROCESSING_DIR"] = TEST_FILE_DIR pcycler_run_loc = os.path.join( TEST_FILE_DIR, "PreDiag_000240_000227_truncated_structure.json") pcycler_run = auto_load_processed(pcycler_run_loc) diffusion_df = featurizer_helpers.get_diffusion_coeff( pcycler_run, 1) print(np.round(diffusion_df.iloc[0].to_list(), 3)) self.assertEqual( np.round(diffusion_df.iloc[0].to_list(), 3)[0], -0.016) self.assertEqual( np.round(diffusion_df.iloc[0].to_list(), 3)[5], -0.011)
def setUp(self): run_path = os.path.join(TEST_FILE_DIR, 'PreDiag_000220_00005E_structure_omit.json') self.datapath = auto_load_processed(run_path) cathode_file = os.path.join( TEST_FILE_DIR, 'data-share/raw/cell_info/cathode_test.csv') anode_file = os.path.join(TEST_FILE_DIR, 'data-share/raw/cell_info/anode_test.csv') self.params = { 'diagnostic_cycle_type': 'rpt_0.2C', 'step_type': 0, "anode_file": anode_file, "cathode_file": cathode_file }
def test_HPPCResistanceVoltageFeatures(self): structured_datapath = auto_load_processed( self.structured_cycler_file_path_trunc) f = HPPCResistanceVoltageFeatures(structured_datapath) self.assertTrue(f.validate()[0]) f.create_features() self.assertEqual(f.features.shape[1], 76) self.assertEqual(f.features.columns[0], "r_c_0s_00") self.assertEqual(f.features.columns[-1], "D_8") self.assertAlmostEqual(f.features.iloc[0, 0], -0.08845776922490017, 6) self.assertAlmostEqual(f.features.iloc[0, 5], -0.1280224700339366, 6) self.assertAlmostEqual(f.features.iloc[0, 27], -0.10378359476555565, 6)
def test_feature_serialization(self): structured_datapath = auto_load_processed( self.structured_cycler_file_path) f = DeltaQFastCharge(structured_datapath) f.create_features() filename = f.__class__.__name__ dumpfn(f, filename) f_reloaded = loadfn(filename) self.assertIsInstance(f_reloaded, DeltaQFastCharge) # test nominal capacity is being generated self.assertEqual( f_reloaded.features.loc[0, "nominal_capacity_by_median"], 1.0628421000000001)
def test_must_fail_featurization(self): # insufficient structured file must fail structured_insuf = auto_load_processed( self.structured_cycler_file_path_insuf) f = DiagnosticSummaryStats(structured_insuf) val, msg = f.validate() self.assertFalse(val) self.assertEqual(msg, "Datapath does not have diagnostic summary") unstructured = auto_load( os.path.join(TEST_FILE_DIR, "2017-12-04_4_65C-69per_6C_CH29.csv")) with self.assertRaises(BEEPFeaturizationError): DiagnosticSummaryStats(unstructured)
def test_feature_serialization(self): processed_cycler_run_path = os.path.join(TEST_FILE_DIR, self.processed_cycler_file) with ScratchDir("."): os.environ["BEEP_PROCESSING_DIR"] = os.getcwd() pcycler_run = auto_load_processed(processed_cycler_run_path) featurizer = DeltaQFastCharge.from_run(processed_cycler_run_path, os.getcwd(), pcycler_run) dumpfn(featurizer, featurizer.name) features_reloaded = loadfn(featurizer.name) self.assertIsInstance(features_reloaded, DeltaQFastCharge) # test nominal capacity is being generated self.assertEqual( features_reloaded.X.loc[0, "nominal_capacity_by_median"], 1.0628421000000001)
def setUp(self): run_path = os.path.join(TEST_FILE_DIR, 'PreDiag_000220_00005E_structure_omit.json') self.datapath = auto_load_processed(run_path) cathode_file = os.path.join( TEST_FILE_DIR, 'cathode_clean_cc_charge_exptl_aligned.csv') anode_file = os.path.join( TEST_FILE_DIR, 'anode_secondMeasure_clean_cc_charge_exptl_aligned.csv') self.params = { 'diagnostic_cycle_type': 'rpt_0.2C', 'step_type': 0, "anode_file": anode_file, "cathode_file": cathode_file }
def test_DiagnosticProperties(self): structured_datapath_loc = os.path.join( TEST_FILE_DIR, "PredictionDiagnostics_000132_00004C_structure.json") structured_datapath = auto_load_processed(structured_datapath_loc) f = DiagnosticProperties(structured_datapath) self.assertTrue(f.validate()[0]) self.assertListEqual(f.hyperparameters["interpolation_axes"], ['normalized_regular_throughput', 'cycle_index']) f.create_features() self.assertEqual(f.features.shape, (1, 4)) # print(list(f.features.iloc[2, :])) self.assertAlmostEqual( f.features.iloc[0]["initial_regular_throughput"], 497.587658, 5)
def test_HPPCResistanceVoltageFeatures_class(self): with ScratchDir("."): os.environ["BEEP_PROCESSING_DIR"] = TEST_FILE_DIR pcycler_run_loc = os.path.join( TEST_FILE_DIR, "PreDiag_000240_000227_truncated_structure.json") pcycler_run = auto_load_processed(pcycler_run_loc) featurizer = HPPCResistanceVoltageFeatures.from_run( pcycler_run_loc, os.getcwd(), pcycler_run) path, local_filename = os.path.split(featurizer.name) folder = os.path.split(path)[-1] dumpfn(featurizer, featurizer.name) self.assertEqual(folder, "HPPCResistanceVoltageFeatures") self.assertEqual(featurizer.X.shape[1], 76) self.assertListEqual( [featurizer.X.columns[0], featurizer.X.columns[-1]], ["ohmic_r_d0", "D_8"], )
def test_sequential_multiple_features(self): structured_datapath = auto_load_processed( self.structured_cycler_file_path) for fclass in [DeltaQFastCharge, TrajectoryFastCharge]: f = fclass(structured_datapath) self.assertTrue(f.validate()[0]) f.create_features() self.assertEqual(f.metadata["channel_id"], 9) self.assertEqual(f.metadata["protocol"], '2017-06-30_tests\\20170629-2C_10per_6C.sdu') self.assertEqual(f.metadata["barcode"], 'el150800460605') filename = f.__class__.__name__ + ".json" dumpfn(f, filename) traj = loadfn("TrajectoryFastCharge.json") self.assertEqual(traj.features.loc[0, "capacity_0.8"], 161)
def pivot_data( file_list_json, qty_to_pca="discharge_capacity", pivot_column="voltage", cycles_to_pca=np.linspace(10, 100, 10, dtype=int), ): """ Method to take a list of structure jsons, construct a dataframe to PCA using a pivoting column. Args: file_list_json (str): json string or json filename corresponding to a dictionary with a file_list and validity attribute, if this string ends with ".json", a json file is assumed. qty_to_pca (str): string denoting quantity to pca. pivot_column (str): string denoting column to pivot on. For PCA of Q(V), pivot_column would be voltage. cycles_to_pca (np.array): how many cycles per file to use for pca decomposition. Returns: pandas.DataFrame: pandas dataframe to PCA. """ if file_list_json.endswith(".json"): file_list_data = loadfn(file_list_json) else: file_list_data = json.loads(file_list_json) file_list = file_list_data["file_list"] df_to_pca = pd.DataFrame() for file in file_list: processed_run = auto_load_processed(file) df = processed_run.structured_data[ processed_run.structured_data.step_type == "discharge"] df = df[df.cycle_index.isin(cycles_to_pca)] df_to_pca = df_to_pca.append( df.pivot(index="cycle_index", columns=pivot_column, values=qty_to_pca), ignore_index=True, ) return df_to_pca
def test_featurization_basic_DeltaQFastCharge(self): structured_datapath = auto_load_processed( self.structured_cycler_file_path) f = DeltaQFastCharge(structured_datapath) self.assertTrue(f.validate()[0]) f.create_features() self.assertEqual(len(f.features), 1) # just test if works for now # Ensure no NaN values # print(featurizer.X.to_dict()) self.assertFalse(np.any(f.features.isnull())) self.assertEqual( np.round( f.features.loc[ 0, 'intercept_discharge_capacity_cycle_number_91:100'], 6), np.round(1.1050065801818196, 6)) self.assertEqual(f.features.columns.tolist()[4], "charge_time_cycles_1:5")
def test_feature_generation_full_model(self): processed_cycler_run_path = os.path.join(TEST_FILE_DIR, self.processed_cycler_file) with ScratchDir("."): os.environ["BEEP_PROCESSING_DIR"] = os.getcwd() pcycler_run = auto_load_processed(processed_cycler_run_path) featurizer = DeltaQFastCharge.from_run(processed_cycler_run_path, os.getcwd(), pcycler_run) self.assertEqual(len(featurizer.X), 1) # just test if works for now # Ensure no NaN values # print(featurizer.X.to_dict()) self.assertFalse(np.any(featurizer.X.isnull())) self.assertEqual( np.round( featurizer.X.loc[ 0, 'intercept_discharge_capacity_cycle_number_91:100'], 6), np.round(1.1050065801818196, 6))
def test_get_hppc_ocv(self): structured_datapath_loc = os.path.join( TEST_FILE_DIR, "PreDiag_000240_000227_truncated_structure.json") structured_datapath = auto_load_processed(structured_datapath_loc) hppc_ocv_features = featurizer_helpers.get_hppc_ocv( structured_datapath, 1) self.assertAlmostEqual(hppc_ocv_features['var_ocv'].iloc[0], 0.000016, 6) self.assertAlmostEqual(hppc_ocv_features['min_ocv'].iloc[0], -0.001291, 6) self.assertAlmostEqual(hppc_ocv_features['mean_ocv'].iloc[0], 0.002221, 6) self.assertAlmostEqual(hppc_ocv_features['skew_ocv'].iloc[0], 1.589392, 6) self.assertAlmostEqual(hppc_ocv_features['kurtosis_ocv'].iloc[0], 7.041016, 6) self.assertAlmostEqual(hppc_ocv_features['sum_ocv'].iloc[0], 0.025126, 6) self.assertAlmostEqual(hppc_ocv_features['sum_square_ocv'].iloc[0], 0.000188, 6)
def test_get_hppc_ocv(self): pcycler_run_loc = os.path.join( TEST_FILE_DIR, "PreDiag_000240_000227_truncated_structure.json") os.environ["BEEP_PROCESSING_DIR"] = TEST_FILE_DIR pcycler_run = auto_load_processed(pcycler_run_loc) hppc_ocv_features = featurizer_helpers.get_hppc_ocv(pcycler_run, 1) self.assertEqual(np.round(hppc_ocv_features['var_ocv'].iloc[0], 6), 0.000016) self.assertEqual(np.round(hppc_ocv_features['min_ocv'].iloc[0], 6), -0.001291) self.assertEqual(np.round(hppc_ocv_features['mean_ocv'].iloc[0], 6), 0.002221) self.assertEqual(np.round(hppc_ocv_features['skew_ocv'].iloc[0], 6), 1.589392) self.assertEqual( np.round(hppc_ocv_features['kurtosis_ocv'].iloc[0], 6), 7.041016) self.assertEqual(np.round(hppc_ocv_features['sum_ocv'].iloc[0], 6), 0.025126) self.assertEqual( np.round(hppc_ocv_features['sum_square_ocv'].iloc[0], 6), 0.000188)
def test_DiagnosticProperties_class(self): with ScratchDir("."): os.environ["BEEP_PROCESSING_DIR"] = TEST_FILE_DIR pcycler_run_loc = os.path.join( TEST_FILE_DIR, "PreDiag_000240_000227_truncated_structure.json") pcycler_run = auto_load_processed(pcycler_run_loc) featurizer = DiagnosticProperties.from_run(pcycler_run_loc, os.getcwd(), pcycler_run) path, local_filename = os.path.split(featurizer.name) folder = os.path.split(path)[-1] dumpfn(featurizer, featurizer.name) self.assertEqual(folder, "DiagnosticProperties") self.assertEqual(featurizer.X.shape, (30, 9)) print(list(featurizer.X.iloc[2, :])) self.assertListEqual(list(featurizer.X.iloc[2, :]), [ 141, 0.9859837086597274, 7.885284043, 4.323121513988055, 21.12108276469096, 30, 100, 'reset', 'discharge_energy' ])
def test_CycleSummaryStats_class(self): with ScratchDir("."): os.environ["BEEP_PROCESSING_DIR"] = TEST_FILE_DIR pcycler_run_loc = os.path.join( TEST_FILE_DIR, "PreDiag_000296_00270E_truncated_structure.json") # Test diagnostic with regular cycles pcycler_run = auto_load_processed(pcycler_run_loc) featurizer = CycleSummaryStats.from_run(pcycler_run_loc, os.getcwd(), pcycler_run) self.assertAlmostEqual( featurizer.X['square_discharging_capacity'].iloc[0], 0.764316, 6) # Test diagnostic with regular cycles with different index params_dict = {"cycle_comp_num": [11, 100]} features = CycleSummaryStats.from_run(pcycler_run_loc, os.getcwd(), pcycler_run, params_dict) self.assertAlmostEqual( features.X['square_discharging_capacity'].iloc[0], 0.7519596, 6)