ROOT logo

// macro to calculate the pt RecAnCuts/MCAcc
// efficiency, from a CF container 
// Author: C. Zampolli 

// channel could be:
// D0: D0 -> Kpi, from old task
// D0_New: D0 -> Kpi, from new CF common implementation
// Dplus_New: D+ -> Kpipi, from new CF common implementation
//
// eff = sum of the efficiency indexes to compute
// MCAcc_over_MCLimAcc = 0x001
// RecPPR_over_MCAcc = 0x002
// RecPID_over_MCAcc = 0x004
// all = 0x007
//
// selection = D origin
// 0 --> from c only
// 1 --> from b only
// 2 --> from both c and b

#include <Riostream.h>

extern TRandom *gRandom;
extern TBenchmark *gBenchmark;
extern TSystem *gSystem;

void DrawEfficiency(const char* channel, Int_t selection = 0, Int_t ieff = 7){

	gROOT->SetStyle("Plain");
	gStyle->SetPalette(1);
	gStyle->SetOptStat(0);
	gStyle->SetPalette(1);
	gStyle->SetCanvasColor(0);
	gStyle->SetFrameFillColor(0);
	gStyle->SetOptTitle(0);
	
	gSystem->SetIncludePath("-I. -I$ALICE_ROOT/include  -I$ROOTSYS/include");
	gSystem->Load("libANALYSIS.so");
	gSystem->Load("libANALYSISalice.so");
	gSystem->Load("$ALICE_ROOT/CORRFW/libCORRFW.so") ;
	gSystem->Load("libPWGHFbase.so");
	gSystem->Load("libPWGHFvertexingHF.so");
		
	Int_t mcAcc_over_mcLimAcc = 0x001;
	Int_t recPPR_over_mcAcc = 0x002;
	Int_t recPID_over_mcAcc = 0x004;

	// pt index
	Int_t ipt =0;

	Int_t stepNum = -1;
	Int_t stepDen = -1;
	
	// Read the  container from file
	TFile* f = new TFile("AnalysisResults.root");	
	TString directoryName;
	TString containerName;
	TString cutName;
	TString outfileName;

	if (channel == "D0") {
		if (selection == 0){
			directoryName = "PWG3_D2H_CFtaskD0toKpi";
			containerName = "CFHFccontainer0";
			cutName = "Cuts";
			outfileName = "fileEff_D0_from_c.root";
		}
		else if (selection == 1){
			directoryName = "PWG3_D2H_CFtaskD0toKpiKeepD0fromBOnly";
			containerName = "CFHFccontainer0D0fromB";
			cutName = "Cuts";
			outfileName = "fileEff_D0_from_b.root";
		}
		else if (selection == 2){
			directoryName = "PWG3_D2H_CFtaskD0toKpiKeepD0fromB";
			containerName = "CFHFccontainer0allD0";
			cutName = "Cuts";
			outfileName = "fileEff_D0_from_c_and_b.root";
		}
		else {
			Printf("not a valid selection, return");
			return;
		}
	}
	else if (channel == "D0_New"){
		if (selection == 0){
			directoryName = "PWG3_D2H_CFtaskD0toKpi_NEW";
			containerName = "CFHFccontainer0_New";
			cutName = "Cuts_New";
			//directoryName = "PWG3_D2H_CFtaskD0toKpi_CommonFramework";
			//containerName = "CFHFccontainer0_CommonFramework";
			//cutName = "Cuts_CommonFramework";
			outfileName = "fileEff_D0_CommonFramework_from_c.root";
		}
		else if (selection == 1){
			directoryName = "PWG3_D2H_CFtaskD0toKpiKeepDfromBOnly";
			containerName = "CFHFccontainer0DfromB_New";
			cutName = "Cuts_New";
			//directoryName = "PWG3_D2H_CFtaskD0toKpiKeepDfromBOnly_CommonFramework";
			//containerName = "CFHFccontainer0DfromB_CommonFramework";	
			//cutName = "Cuts_CommonFramework";
			outfileName = "fileEff_D0_CommonFramework_from_b.root";
		}
		else if (selection == 2){
			directoryName = "PWG3_D2H_CFtaskD0toKpiKeepDfromB_NEW";
			containerName = "CFHFccontainer0allD_New";
			cutName = "Cuts_New";
			//directoryName = "PWG3_D2H_CFtaskD0toKpiKeepDfromB_CommonFramework";
			//containerName = "CFHFccontainer0allD_CommonFramework";
			//cutName = "Cuts_CommonFramework";
			outfileName = "fileEff_D0_CommonFramework_from_c_and_b.root";
		}
		else {
			Printf("not a valid selection, return");
			return;
		}
	}
	else if (channel == "Dplus_New"){
		if (selection == 0){
			directoryName = "PWG3_D2H_CFtaskDplustoKpipi_NEW";
			containerName = "CFHFccontainer0_New_3Prong";
			cutName = "Cuts_3Prong";
			//directoryName = "PWG3_D2H_CFtaskDplustoKpipi_CommonFramework";
			//containerName = "CFHFccontainer0_3Prong_CommonFramework";
			//cutName =  "Cuts_3Prong_CommonFramework";
			outfileName = "fileEff_Dplus_CommonFramework_from_c.root";
		}
		else if (selection == 1){
			directoryName = "PWG3_D2H_CFtaskDplustoKpipiKeepDfromBOnly";
			containerName = "CFHFccontainer0DfromB_New_3Prong";
			cutName = "Cuts_3Prong";
			//directoryName = "PWG3_D2H_CFtaskDplustoKpipiKeepDfromBOnly_CommonFramework";
			//containerName = "CFHFccontainer0DfromB_3Prong_CommonFramework";
			//cutName =  "Cuts_3Prong_CommonFramework";
			outfileName = "fileEff_Dplus_CommonFramework_from_b.root";
		}
		else if (selection == 2){
			directoryName = "PWG3_D2H_CFtaskDplustoKpipiKeepDfromB_NEW";
			containerName = "CFHFccontainer0allD_New_3Prong";
			cutName = "Cuts_3Prong";
			//directoryName = "PWG3_D2H_CFtaskDplustoKpipiKeepDfromB_CommonFramework";
			//containerName = "CFHFccontainer0allD_3Prong_CommonFramework";
			//cutName =  "Cuts_3Prong_CommonFramework";
			outfileName = "fileEff_Dplus_CommonFramework_from_c_and_b.root";
		}
		else {
			Printf("not a valid selection, return");
			return;
		}
	}
	else {
		Printf("not a valid channel, return");
		return;
	}

	Printf("Opening file Analysisresults.root");
	Printf("Reading Directory \"%s\"",directoryName.Data());
	Printf("Getting CF Container \"%s\"",containerName.Data());
	Printf("Getting Cut Object \"%s\"",cutName.Data());


	TDirectoryFile* d = (TDirectoryFile*)f->Get(directoryName.Data());
	if (!d){
		Printf("Directory does not exist! Check directory name (%s) in file AnalysisResults.root - returning...", directoryName.Data());
		return;
	}
	AliCFContainer *data = (AliCFContainer*) (d->Get(containerName.Data()));
	AliRDHFCuts *cutsRDHF = (AliRDHFCuts*)(d->Get(cutName.Data()));

	if (!data){
		Printf("Container does not exist! Check container name (%s) in directory %s - returning...", containerName.Data(), directoryName.Data());
		return;
	}
	
	TFile* fileEff = new TFile(outfileName.Data(), "RECREATE");
	TString plotDir(Form("EffPlots/%s",channel));
	gSystem->Exec(Form("mkdir EffPlots"));
	gSystem->Exec(Form("mkdir %s",plotDir.Data()));
	
	//construct the efficiency grid from the data container 
	AliCFEffGrid *eff = new AliCFEffGrid("eff"," The efficiency",*data);

	TCanvas *ceffpt = new TCanvas("ceffpt","Efficiency vs pt",50,50,550,550);
	ceffpt->cd();
	ceffpt->SetLeftMargin(0.15);
	ceffpt->SetRightMargin(0.05);
	TH1D *hpteffCF = 0x0; //the efficiency vs pt

	if (ieff & mcAcc_over_mcLimAcc){
		AliCFEffGrid *eff = new AliCFEffGrid("eff"," The efficiency",*data);
		stepDen = (Int_t)(AliCFTaskVertexingHF::kStepGeneratedLimAcc);	
		stepNum = (Int_t)(AliCFTaskVertexingHF::kStepAcceptance);	
		printf("Calculating efficiency for mcAcc_over_mcLimAcc: stepDen = %d, stepNum = %d\n",stepDen,stepNum);	
		eff->CalculateEfficiency(stepNum,stepDen); //eff= step1/step0
		
		//canvas
		ceffpt->cd();

		//The efficiency along the variables
		hpteffCF = eff->Project(ipt); 
		SetHistoEff(hpteffCF,8,20,"mcAcc_over_mcLimAcc");
		hpteffCF->Draw("hist");
		hpteffCF->Draw("err same");
		fileEff->cd();
		hpteffCF->Write("hpteffCF_mcAcc_over_mcLimAcc");
		
		// printing png files
		ceffpt->Print(Form("%s/effpt_mcAcc_over_mcLimAcc.png", plotDir.Data()));
		ceffpt->Print(Form("%s/effpt_mcAcc_over_mcLimAcc.eps", plotDir.Data()));
		ceffpt->Print(Form("%s/effpt_mcAcc_over_mcLimAcc.gif", plotDir.Data()));
		delete eff;
		eff = 0x0;
	}

	if (ieff & recPPR_over_mcAcc){
		AliCFEffGrid *eff = new AliCFEffGrid("eff"," The efficiency",*data);
		stepDen = (Int_t)(AliCFTaskVertexingHF::kStepAcceptance);	
		stepNum = (Int_t)(AliCFTaskVertexingHF::kStepRecoPPR);	
		printf("Calculating efficiency for RecPPR_over_mcAcc: stepDen = %d, stepNum = %d\n",stepDen,stepNum);	
		eff->CalculateEfficiency(stepNum,stepDen); //eff= step1/step0
		
		//canvas
		ceffpt->cd();
		
		//The efficiency along the variables
		hpteffCF = eff->Project(ipt); 
		SetHistoEff(hpteffCF,8,20, "recAnCuts_over_mcAcc");
		hpteffCF->Draw("hist");
		hpteffCF->Draw("err same");
		fileEff->cd();
		hpteffCF->Write("hpteffCF_RecAnCut_over_mcAcc");
		
		// printing png files
		ceffpt->Print(Form("%s/effpt_RecAnCut_over_mcAcc.png", plotDir.Data()));
		ceffpt->Print(Form("%s/effpt_RecAnCut_over_mcAcc.eps", plotDir.Data()));
		ceffpt->Print(Form("%s/effpt_RecAnCut_over_mcAcc.gif", plotDir.Data()));
		delete eff;
		eff = 0x0;
	}

	if (ieff & recPID_over_mcAcc){
		AliCFEffGrid *eff = new AliCFEffGrid("eff"," The efficiency",*data);
		stepDen = (Int_t)(AliCFTaskVertexingHF::kStepAcceptance);	
		stepNum = (Int_t)(AliCFTaskVertexingHF::kStepRecoPID);	
		printf("Calculating efficiency for RecPID_over_mcAcc: stepDen = %d, stepNum = %d\n",stepDen,stepNum);	
		eff->CalculateEfficiency(stepNum,stepDen); //eff= step1/step0
		
		//canvas
		ceffpt->cd();
		
		//The efficiency along the variables
		hpteffCF = eff->Project(ipt); 
		SetHistoEff(hpteffCF,8,20,"recPID_over_mcAcc");
		hpteffCF->Draw("hist");
		hpteffCF->Draw("err same");
		fileEff->cd();
		hpteffCF->Write("hpteffCF_RecPID_over_mcAcc");
		
		// printing png files
		ceffpt->Print(Form("%s/effpt_RecPID_over_mcAcc.png", plotDir.Data()));
		ceffpt->Print(Form("%s/effpt_RecPID_over_mcAcc.eps", plotDir.Data()));
		ceffpt->Print(Form("%s/effpt_RecPID_over_mcAcc.gif", plotDir.Data()));
		delete eff;
		eff = 0x0;
	}
	
	cutsRDHF->Write("Cuts");

	// writing single distributions
	TH1D *hMCAccpt = data->ShowProjection(ipt, AliCFTaskVertexingHF::kStepAcceptance);
	SetHistoDistribution(hMCAccpt, 1, 20);
	hMCAccpt->Draw();
	TH1D *hMCLimAccpt = data->ShowProjection(ipt, AliCFHeavyFlavourTaskMultiVarMultiStep::kStepGeneratedLimAcc);
	SetHistoDistribution(hMCLimAccpt, 4, 20);
	TH1D *hRecoAnCutspt = data->ShowProjection(ipt, AliCFTaskVertexingHF::kStepRecoPPR);
	SetHistoDistribution(hRecoAnCutspt, 8, 20);
	TH1D *hRecoPIDpt = data->ShowProjection(ipt, AliCFTaskVertexingHF::kStepRecoPID);
	SetHistoDistribution(hRecoPIDpt, 6, 20);
	hMCAccpt->Write("hMCAccpt");
	hMCLimAccpt->Write("hMCLimAccpt");
	hRecoAnCutspt->Write("hRecoAnCutspt");
	hRecoPIDpt->Write("hRecoPIDpt");

	//	fileEff->Close(); // commented out to see the canvas on the screen....

}

void SetHistoEff(TH1D* h, Int_t color, Int_t style, const char* effType){

	h->SetLineColor(color);
	h->SetLineWidth(3);
	h->SetMarkerStyle(style);
	h->SetMarkerColor(color);
	h->SetMarkerSize(1.2);
	h->GetYaxis()->SetTitleOffset(1.5);
	h->GetXaxis()->SetTitleOffset(1.2);
	h->GetXaxis()->SetTitle("p_{t} [GeV/c]");
	h->GetYaxis()->SetTitle(Form("%s, Efficiency",effType));
	return;
}
void SetHistoDistribution(TH1D* h, Int_t color, Int_t style){

	h->SetLineColor(color);
	h->SetLineWidth(3);
	h->SetMarkerStyle(style);
	h->SetMarkerColor(color);
	h->SetMarkerSize(1.2);
	h->GetXaxis()->SetTitleOffset(1.2);
	h->GetXaxis()->SetTitle("p_{t} [GeV/c]");
	return;
}
 DrawEfficiency.C:1
 DrawEfficiency.C:2
 DrawEfficiency.C:3
 DrawEfficiency.C:4
 DrawEfficiency.C:5
 DrawEfficiency.C:6
 DrawEfficiency.C:7
 DrawEfficiency.C:8
 DrawEfficiency.C:9
 DrawEfficiency.C:10
 DrawEfficiency.C:11
 DrawEfficiency.C:12
 DrawEfficiency.C:13
 DrawEfficiency.C:14
 DrawEfficiency.C:15
 DrawEfficiency.C:16
 DrawEfficiency.C:17
 DrawEfficiency.C:18
 DrawEfficiency.C:19
 DrawEfficiency.C:20
 DrawEfficiency.C:21
 DrawEfficiency.C:22
 DrawEfficiency.C:23
 DrawEfficiency.C:24
 DrawEfficiency.C:25
 DrawEfficiency.C:26
 DrawEfficiency.C:27
 DrawEfficiency.C:28
 DrawEfficiency.C:29
 DrawEfficiency.C:30
 DrawEfficiency.C:31
 DrawEfficiency.C:32
 DrawEfficiency.C:33
 DrawEfficiency.C:34
 DrawEfficiency.C:35
 DrawEfficiency.C:36
 DrawEfficiency.C:37
 DrawEfficiency.C:38
 DrawEfficiency.C:39
 DrawEfficiency.C:40
 DrawEfficiency.C:41
 DrawEfficiency.C:42
 DrawEfficiency.C:43
 DrawEfficiency.C:44
 DrawEfficiency.C:45
 DrawEfficiency.C:46
 DrawEfficiency.C:47
 DrawEfficiency.C:48
 DrawEfficiency.C:49
 DrawEfficiency.C:50
 DrawEfficiency.C:51
 DrawEfficiency.C:52
 DrawEfficiency.C:53
 DrawEfficiency.C:54
 DrawEfficiency.C:55
 DrawEfficiency.C:56
 DrawEfficiency.C:57
 DrawEfficiency.C:58
 DrawEfficiency.C:59
 DrawEfficiency.C:60
 DrawEfficiency.C:61
 DrawEfficiency.C:62
 DrawEfficiency.C:63
 DrawEfficiency.C:64
 DrawEfficiency.C:65
 DrawEfficiency.C:66
 DrawEfficiency.C:67
 DrawEfficiency.C:68
 DrawEfficiency.C:69
 DrawEfficiency.C:70
 DrawEfficiency.C:71
 DrawEfficiency.C:72
 DrawEfficiency.C:73
 DrawEfficiency.C:74
 DrawEfficiency.C:75
 DrawEfficiency.C:76
 DrawEfficiency.C:77
 DrawEfficiency.C:78
 DrawEfficiency.C:79
 DrawEfficiency.C:80
 DrawEfficiency.C:81
 DrawEfficiency.C:82
 DrawEfficiency.C:83
 DrawEfficiency.C:84
 DrawEfficiency.C:85
 DrawEfficiency.C:86
 DrawEfficiency.C:87
 DrawEfficiency.C:88
 DrawEfficiency.C:89
 DrawEfficiency.C:90
 DrawEfficiency.C:91
 DrawEfficiency.C:92
 DrawEfficiency.C:93
 DrawEfficiency.C:94
 DrawEfficiency.C:95
 DrawEfficiency.C:96
 DrawEfficiency.C:97
 DrawEfficiency.C:98
 DrawEfficiency.C:99
 DrawEfficiency.C:100
 DrawEfficiency.C:101
 DrawEfficiency.C:102
 DrawEfficiency.C:103
 DrawEfficiency.C:104
 DrawEfficiency.C:105
 DrawEfficiency.C:106
 DrawEfficiency.C:107
 DrawEfficiency.C:108
 DrawEfficiency.C:109
 DrawEfficiency.C:110
 DrawEfficiency.C:111
 DrawEfficiency.C:112
 DrawEfficiency.C:113
 DrawEfficiency.C:114
 DrawEfficiency.C:115
 DrawEfficiency.C:116
 DrawEfficiency.C:117
 DrawEfficiency.C:118
 DrawEfficiency.C:119
 DrawEfficiency.C:120
 DrawEfficiency.C:121
 DrawEfficiency.C:122
 DrawEfficiency.C:123
 DrawEfficiency.C:124
 DrawEfficiency.C:125
 DrawEfficiency.C:126
 DrawEfficiency.C:127
 DrawEfficiency.C:128
 DrawEfficiency.C:129
 DrawEfficiency.C:130
 DrawEfficiency.C:131
 DrawEfficiency.C:132
 DrawEfficiency.C:133
 DrawEfficiency.C:134
 DrawEfficiency.C:135
 DrawEfficiency.C:136
 DrawEfficiency.C:137
 DrawEfficiency.C:138
 DrawEfficiency.C:139
 DrawEfficiency.C:140
 DrawEfficiency.C:141
 DrawEfficiency.C:142
 DrawEfficiency.C:143
 DrawEfficiency.C:144
 DrawEfficiency.C:145
 DrawEfficiency.C:146
 DrawEfficiency.C:147
 DrawEfficiency.C:148
 DrawEfficiency.C:149
 DrawEfficiency.C:150
 DrawEfficiency.C:151
 DrawEfficiency.C:152
 DrawEfficiency.C:153
 DrawEfficiency.C:154
 DrawEfficiency.C:155
 DrawEfficiency.C:156
 DrawEfficiency.C:157
 DrawEfficiency.C:158
 DrawEfficiency.C:159
 DrawEfficiency.C:160
 DrawEfficiency.C:161
 DrawEfficiency.C:162
 DrawEfficiency.C:163
 DrawEfficiency.C:164
 DrawEfficiency.C:165
 DrawEfficiency.C:166
 DrawEfficiency.C:167
 DrawEfficiency.C:168
 DrawEfficiency.C:169
 DrawEfficiency.C:170
 DrawEfficiency.C:171
 DrawEfficiency.C:172
 DrawEfficiency.C:173
 DrawEfficiency.C:174
 DrawEfficiency.C:175
 DrawEfficiency.C:176
 DrawEfficiency.C:177
 DrawEfficiency.C:178
 DrawEfficiency.C:179
 DrawEfficiency.C:180
 DrawEfficiency.C:181
 DrawEfficiency.C:182
 DrawEfficiency.C:183
 DrawEfficiency.C:184
 DrawEfficiency.C:185
 DrawEfficiency.C:186
 DrawEfficiency.C:187
 DrawEfficiency.C:188
 DrawEfficiency.C:189
 DrawEfficiency.C:190
 DrawEfficiency.C:191
 DrawEfficiency.C:192
 DrawEfficiency.C:193
 DrawEfficiency.C:194
 DrawEfficiency.C:195
 DrawEfficiency.C:196
 DrawEfficiency.C:197
 DrawEfficiency.C:198
 DrawEfficiency.C:199
 DrawEfficiency.C:200
 DrawEfficiency.C:201
 DrawEfficiency.C:202
 DrawEfficiency.C:203
 DrawEfficiency.C:204
 DrawEfficiency.C:205
 DrawEfficiency.C:206
 DrawEfficiency.C:207
 DrawEfficiency.C:208
 DrawEfficiency.C:209
 DrawEfficiency.C:210
 DrawEfficiency.C:211
 DrawEfficiency.C:212
 DrawEfficiency.C:213
 DrawEfficiency.C:214
 DrawEfficiency.C:215
 DrawEfficiency.C:216
 DrawEfficiency.C:217
 DrawEfficiency.C:218
 DrawEfficiency.C:219
 DrawEfficiency.C:220
 DrawEfficiency.C:221
 DrawEfficiency.C:222
 DrawEfficiency.C:223
 DrawEfficiency.C:224
 DrawEfficiency.C:225
 DrawEfficiency.C:226
 DrawEfficiency.C:227
 DrawEfficiency.C:228
 DrawEfficiency.C:229
 DrawEfficiency.C:230
 DrawEfficiency.C:231
 DrawEfficiency.C:232
 DrawEfficiency.C:233
 DrawEfficiency.C:234
 DrawEfficiency.C:235
 DrawEfficiency.C:236
 DrawEfficiency.C:237
 DrawEfficiency.C:238
 DrawEfficiency.C:239
 DrawEfficiency.C:240
 DrawEfficiency.C:241
 DrawEfficiency.C:242
 DrawEfficiency.C:243
 DrawEfficiency.C:244
 DrawEfficiency.C:245
 DrawEfficiency.C:246
 DrawEfficiency.C:247
 DrawEfficiency.C:248
 DrawEfficiency.C:249
 DrawEfficiency.C:250
 DrawEfficiency.C:251
 DrawEfficiency.C:252
 DrawEfficiency.C:253
 DrawEfficiency.C:254
 DrawEfficiency.C:255
 DrawEfficiency.C:256
 DrawEfficiency.C:257
 DrawEfficiency.C:258
 DrawEfficiency.C:259
 DrawEfficiency.C:260
 DrawEfficiency.C:261
 DrawEfficiency.C:262
 DrawEfficiency.C:263
 DrawEfficiency.C:264
 DrawEfficiency.C:265
 DrawEfficiency.C:266
 DrawEfficiency.C:267
 DrawEfficiency.C:268
 DrawEfficiency.C:269
 DrawEfficiency.C:270
 DrawEfficiency.C:271
 DrawEfficiency.C:272
 DrawEfficiency.C:273
 DrawEfficiency.C:274
 DrawEfficiency.C:275
 DrawEfficiency.C:276
 DrawEfficiency.C:277
 DrawEfficiency.C:278
 DrawEfficiency.C:279
 DrawEfficiency.C:280
 DrawEfficiency.C:281
 DrawEfficiency.C:282
 DrawEfficiency.C:283
 DrawEfficiency.C:284
 DrawEfficiency.C:285
 DrawEfficiency.C:286
 DrawEfficiency.C:287
 DrawEfficiency.C:288
 DrawEfficiency.C:289
 DrawEfficiency.C:290
 DrawEfficiency.C:291
 DrawEfficiency.C:292
 DrawEfficiency.C:293
 DrawEfficiency.C:294
 DrawEfficiency.C:295
 DrawEfficiency.C:296
 DrawEfficiency.C:297
 DrawEfficiency.C:298
 DrawEfficiency.C:299
 DrawEfficiency.C:300
 DrawEfficiency.C:301
 DrawEfficiency.C:302
 DrawEfficiency.C:303
 DrawEfficiency.C:304
 DrawEfficiency.C:305
 DrawEfficiency.C:306
 DrawEfficiency.C:307
 DrawEfficiency.C:308
 DrawEfficiency.C:309
 DrawEfficiency.C:310
 DrawEfficiency.C:311
 DrawEfficiency.C:312
 DrawEfficiency.C:313