typedef struct  {
 
   
 
    unsigned short offset;
 
    unsigned short fineadj_unipol;
 
    unsigned short kill;
 
   
 
} channel_register;
 
 
 
channel_register creg[144];
 
double gsigma=0;
 
double gmean=0;
 
 
 
 
 
double sa02calculateoffset(double x, int *offset, int * fineadj_unipol ){
 
 
 
    const double fscale= 2500/1023;      // 2500 mV / 1023 ch / dacch
 
    const double foffset = 59.0/fscale;  // 59.0 mV / dacch (coarse)
 
    const double ffine    = 5.4/fscale; // 5.4mV / dacch (fine)
 
     
 
    *offset        =  int(x/ foffset);
 
    x=x-(*offset)*foffset;
 
    *fineadj_unipol= int(x/ffine); 
 
        x=x-(*fineadj_unipol)*ffine;
 
        return x;
 
 
 
}
 
 
 
int sa02fithisto(double mean0=512 , double sigma0=3){
 
gmean=mean0;
 
gsigma=sigma0;
 
 
 
 TH2F *h=NULL;
 
 if (!h) h=((TH2F * ) gDirectory->Get("h2d")); 
 
double max= h->GetMaximum();
 
TF1 *f = new TF1("merfc","[2]*TMath::Erfc((x-[0])*[1])", 0 , 1000);
 
f->FixParameter(2,max*0.5);
 
 
 
 TNtuple *nt=new TNtuple("nt","nt","ch:mean:sigma");
 
 
 
 
 
 h->FitSlicesY(f);
 
 TAxis *ax= h->GetYaxis();
 
 double xmin=  ax->GetXmin();
 
 double xmax=  ax->GetXmax();
 
 char n0[100];
 
 char n1[100];
 
 char n2[100];
 
 sprintf(n0,"%s_0",h->GetName());
 
 sprintf(n1,"%s_1",h->GetName());
 
 sprintf(n2,"%s_2",h->GetName());
 
 TH1F *h0 = ((TH1F * ) gDirectory->Get(n0));
 
 TH1F *h1 = ((TH1F * ) gDirectory->Get(n1));
 
 TH1F *h2 = ((TH1F * ) gDirectory->Get(n2));
 
 //h0->Draw();
 
 TCanvas *c= new TCanvas("c","c",1000,1000);
 
 c->Divide(2,2);
 
 
 
 c->cd(1);
 
 h0->SetMaximum(xmax);
 
 h0->SetMinimum(xmin);
 
 h0->Draw();
 
 c->cd(3);
 
 h1->SetMaximum(200);
 
 h1->SetMinimum(0);
 
 sprintf(n0,"%sc",h1->GetName()); 
 
 TH1F *h1c = h1->Clone(n0);
 
 
 
 float fx[10];
 
 for (int i=1;i<h1->GetNbinsX()+1;i++){
 
    double first = h->GetBinContent(h->FindBin(i-1,xmin+1));
 
    double last  = h->GetBinContent(h->FindBin(i-1,xmax-1));
 
    
 
    double sigma= TMath::Abs( h1->GetBinContent(i) );
 
    double mean = TMath::Abs( h0->GetBinContent(i) ); 
 
    if (sigma>0) sigma=1/sigma; else sigma=0;
 
    fx[0]=i;
 
    fx[1]=mean;
 
    fx[2]=sigma;
 
        nt->Fill(fx); 
 
        double            x = ((mean+sigma0*sigma)-mean0) ;
 
    int offset        = 0;
 
    int fineadj_unipol= 0; 
 
 
 
        sa02calculateoffset(x, &offset, &fineadj_unipol );
 
    
 
    
 
        
 
        
 
        int valid = 1;
 
        if (last>0.5*h2d->GetMaximum())  valid = 0;
 
        if (first<0.5*h2d->GetMaximum()) valid = 0;
 
        if (valid) {
 
          creg[i-1].offset         = offset;
 
          creg[i-1].fineadj_unipol = fineadj_unipol;
 
          creg[i-1].kill           = 0;
 
        } else {
 
          creg[i-1].offset         = 0;
 
          creg[i-1].fineadj_unipol = 0;
 
          creg[i-1].kill           = 1;
 
        }
 
    
 
    printf("%d %f %f %f %f %d %d %f\n",i, first, last, mean,sigma,offset,fineadj_unipol ,x );
 
    
 
    h1c->SetBinContent(i,sigma);
 
     
 
    // of << ch << "\t" << (int)entries << "\t" << (((mean*2.4)-1245.2)) << "\t" << sigma*2.4 << endl;
 
    
 
 }
 
 h1c->Draw();
 
 c->cd(4);
 
 nt->Draw("sigma","sigma>0&&sigma<100");
 
 //h2->Draw();
 
 c->cd(2);
 
 
 
 //h->Draw("colz");
 
 /*
 
 h0->SetLineColor(kRed);
 
 h0->SetLineWidth(10);
 
 h0->Draw("same");
 
 */
 
 nt->Draw("mean","mean>0&&mean<1000");
 
  
 
 c->Modified();
 
 c->Update();
 
 
 
}
 
 
 
int sa02param( char *fname="../params/offset_orig.param", char *hname="offsettmp.param" ){
 
  
 
    
 
    int ndim=400;
 
    char line[400];
 
    char cmd[400];
 
    char sasic[400];
 
    char v0[400];
 
    char v1[400];
 
    int asic=0, ch=0;
 
    int  cval=0;
 
    int i;
 
 
 
    FILE *fout = fopen(hname,"w");
 
    if (!fout) {
 
        printf("Error! Cannot open file %s\n",hname);
 
        return -1;
 
    }
 
    
 
    
 
    FILE *fp = fopen(fname,"r");
 
    if (!fp) {
 
        printf("Error! Cannot open file %s\n",fname);
 
        return -1;
 
    }
 
    
 
        int write=1;
 
        fprintf(fout,"### Created from sa02fit mean=%f sigma=%f\n", gmean,gsigma);
 
        fprintf(fout,"### date tbi\n");
 
        char *null=NULL;
 
    while (fgets(line,ndim,fp)!=NULL) {
 
                write=1;
 
        int nb = sscanf(line,"%s%s%s%s",cmd,sasic,v0,v1);
 
        if (nb<1 || cmd[0]=='#') {
 
           fprintf(fout,line);
 
           continue;
 
        }   
 
 
 
        asic =   atoi (sasic);
 
        ch   =   atoi (v0);
 
        cval =   strtoul (v1,null,0);
 
        if (strcmp(cmd,"offset")==0)     {
 
                fprintf(fout,"offset %d %d %d\n", asic,ch, creg[asic*36+ch].offset);
 
                write=0;
 
        }
 
        if (strcmp(cmd,"fineadj_unipol")==0) {
 
                fprintf(fout,"fineadj_unipol %d %d %d\n", asic,ch, creg[asic*36+ch].fineadj_unipol);
 
                write=0;
 
        }
 
        if (strcmp(cmd,"kill")==0)       {
 
                fprintf(fout,"kill %d %d %d\n", asic,ch, creg[asic*36+ch].kill);
 
                write=0;
 
        }
 
        if (write){
 
           fprintf(fout,line);
 
        }
 
        
 
    }
 
    fclose(fp);
 
    fclose(fout);
 
return 0;
 
}
 
 
 
int sa02fit(char *hname,double mean0=400 , double sigma0=3, char *fnameparam="../../params/offset_orig.param"){
 
 gROOT->SetMacroPath("../macros");
 
 gROOT->ProcessLine(".L H2Dload.cxx");
 
 
 
 H2Dload(hname);
 
 //H2Dload(gSystem->UnixPathName(hname));
 
 sa02fithisto(mean0,sigma0);
 
 char foutparname[400];
 
 sprintf(foutparname,"%s.param",hname);
 
 sa02param(fnameparam,foutparname);
 
return 0;       
 
}