Exemple #1
0
int main (int argc, char *argv[]) {

	struct params par = PAR_DEFAULT;

	int j, js, fd;
	int n_read;
	int spurious_count=0;
	struct timespec very_first, very_last;
	struct event *time_buf, *time_list, *event;
        struct event *big_time_buf=NULL, origin;
	int side, size;
	int *i_differ, *e_delay=NULL, *i_delay;
	int delta_e;
	int status;
	int count=0, first;
	float sigma, quantum;
	FILE * logfile=NULL, * listfile=NULL;
	FILE * plot=NULL;
	char buff[BUFLEN];
	double *tevi=NULL, delta;
	double cf[2];
	double average;
	int total_time;
	int block_size, full_size;
	int bin_size;

	parse_options (argc, argv, &par);

	if (par.p & MRC_PM) {
		bin_size = (par.n + BINS - 1) / BINS;
		if (par.v) printf ("Bin size is: %d\n", bin_size);
	}
	if (!par.e && par.p & LAT_PM) {
		printf ("The latency distribution will not be computed if"
			" the external clock is not specified [-e]\n");
		par.p &= ~LAT_PM;
	}

	quantum = par.g * par.c;     /* usec/channel in time distributions */

	/* start auxiliary services: gnuplot */

	if (par.p) {
		plot = popen("/usr/bin/gnuplot -noraise -persist -geometry "
			     "1024x512", "w");
		if (plot == NULL) {
			printf ("Start of graphical display failed!\n");
			exit (-1);
		} else {
			if (par.v) printf (
				"Time distributions will be plotted\n");
			fprintf (plot, "set grid; set term X11\n");
		}
	}

	/* open time device and log files */

	if (par.i == NULL) par.i = "/dev/latim";
	if (strcmp(par.i, "-") == 0) {         /* data from standard input */
		fd = 0;
	} else {
		fd = open (par.i, O_RDONLY);
		if (fd == -1) {
			printf ("Failed while opening time device '%s'\n",
				par.i);
			perror ("");
			exit (-1);
		}
	}

	if (!par.f) par.f = new_code();
	logfile = fopen(par.f, "w");
	if (!logfile) {
		perror ("Failed while opening log file");
		exit (-1);
	}
	printf ("Log to file %s\n", par.f);

	if (par.L) {
		strcpy (par.f+strlen(par.f)-3, "lst");
		listfile = fopen (par.f, "w");
		if (!listfile) {
			perror ("Failed while opening list file");
			exit (-1);
		}
		printf ("Time list to file %s\n", par.f);
	}

	/* save the full command line to log file */

	fprintf (logfile, "# ");
	for ( j=0 ; j<argc ; j++) {
		fprintf (logfile, "%s ", *(argv+j));
		if (par.v) printf ("%s ", *(argv+j));
	}
	fprintf (logfile, "\n\n");
	if (par.v) printf ("\n");
	    
	/* get memory for buffers */

	block_size = par.n * SLOT;
	full_size = (par.U ? par.N : 1) * block_size;

	big_time_buf = malloc (full_size+SLOT);
	time_buf = big_time_buf;
	if (!time_buf) {
		perror ("malloc failed with time_buf");
		exit (-1);
	}

	if (par.v) printf ("Allocated time buffer %d bytes wide at %p\n",
			   (int) (full_size+SLOT), big_time_buf);

	time_list = time_buf + 1;

	tevi = malloc (par.n * sizeof(double));
	if (!tevi) {
		perror ("malloc failed with tevi");
		goto bad_exit;
	}
	if (par.v) printf ("Allocated count buffer %d bytes wide at %p\n",
			   (int) (par.n * sizeof(*tevi)), tevi);

	side = par.m/par.c + 1.0;
	size = 2*side + 1;

	e_delay = calloc (3*size, sizeof(int));
	if (!e_delay) {
		perror ("malloc failed with e_delay");
		goto bad_exit;
	}
	if (par.v) printf ("Allocated distribution buffer %d bytes wide "
			   "at %p\n", (int) (3*size*sizeof(int)), e_delay);
	i_differ = e_delay + size;
	i_delay = i_differ + size;

	/*
	 *   enter the main loop
	 */

	n_read = read (fd, (void *) time_buf, SLOT);
	if (n_read != SLOT) {
		printf ("reading of time origin failed with %d\n", n_read);
		goto bad_exit;
	}

	origin = *time_buf;
	count = 0;
	while (!par.N || count < par.N) {

		n_read = 0;
		while (n_read < block_size) {
			status = read (fd, (void *) time_list +
				       n_read, block_size - n_read);
			if (status == 0) break;
			if (status < 0) {
				perror ("read operation failed");
				goto bad_exit;
			}
			n_read += status;
		}
		if (status == 0) {
			printf ("Undue EOF after %d bytes\n", n_read);
			goto bad_exit;
		}

		if (n_read != block_size) {
			printf("read operation failed with return %d\n",
			       n_read);
			perror ("reason");
			goto bad_exit;
		}
    
		first = count * par.n;

		/*
		 *    issue a complete list of all events:
                 *    -l  list to console
                 *    -L  list to file
		 */

                list_events (&par, listfile, time_list, first, &origin);

		/*     Analyze buffer for spurious events.
		 *     An event is spurious when the measured latency exceeds
		 *     the given threshold (-m).
		 */

                if (check_events (&par, time_list, logfile, count,
                                  &spurious_count, first, &origin) == -1)
                  goto bad_exit;
                
		printf ("events/err.: %9d / %d", first+par.n, spurious_count);

		/*
		 *    histograms:
		 *
		 *    i_differ: distribution of internal clock differences
		 *    e_delay:  distribution of external counter delays
		 *    i_delay:  distribution of internal clock delays
		 *
		 */

		/* build i_differ and e_delay time distributions */

		for ( j=0 ; j<par.n ; j++ ) {
			event = time_list+j;
			delta = (us_diff(&event->timic, &(event-1)->timic) -
                                 par.t) / quantum;
			if (delta < -side) delta = -side;
			else if (delta > side) delta = side;
			i_differ[(int) (delta + side)] += 1;
//			tevi[j] = us_diff(&event->timic, &origin.timic);
			tevi[j] = us_diff(&event->timic, &time_list->timic);
			if (par.e) {
				delta_e = diff_e(event) / par.g;
				if (delta_e > size) delta_e = size;
				e_delay[delta_e] += 1;
			}
		}

		/* compute clock rate and build 'i_delay' histogram */

		fit1 (tevi, par.n, cf);
		printf ("      clock rate: %9.3f  %8.3f\n", cf[0], cf[1]+200);

		for ( j=0 ; j<par.n ; j++ ) {
			tevi[j] -= (cf[0]*(j+1) + cf[1]);
			if (tevi[j] < -par.m) tevi[j] = -par.m;
			if (tevi[j] >= par.m) tevi[j] = par.m;
			delta = tevi[j] / (par.g * par.c);
			i_delay[(int) (delta+side)] += 1;
		}

		/* plots */

                plot_histograms
                  (&par, plot, i_differ, i_delay, e_delay, tevi, time_list);

                /*
                 * close the main loop
                 */

		if (!count) very_first = time_buf->timic;
		very_last = (time_buf + par.n)->timic;
		if (par.U) {
			time_buf += par.n;
			time_list = time_buf + 1;
		} else {
			*time_buf = *(time_buf + par.n);
		}
		count++;
	}

	/* print final logs */

	if ((par.L || par.l) && par.U) {
		for ( j=0 ; j<par.n*par.N ; j++ ) {
			event = big_time_buf+j+1;
			delta = us_diff (&event->timic, &(event-1)->timic);
			sprintf (buff, "%8d  %12ld.%09ld  %10d  %8.2f %6.2f",
                                 j, event->timic.tv_sec, event->timic.tv_nsec,
				 tm_diff(&event->timic, &origin.timic),
				 delta, delta - par.t);
			if (par.e) {
				delta_e = diff_e(event);
				sprintf (buff+strlen(buff), "    %4d  %4d",
					 event->timec, delta_e);
			}
			sprintf (buff+strlen(buff), "\n");
			if (par.l) printf (buff);
			if (par.L) fprintf (listfile, buff);
		}
	}

	/* print final time distributions */

	if (par.S) {                                        /* i_differ */
		printf ("\nTime distribution from internal clock\n");
		print_distrib (i_differ, size, logfile, side, quantum);

		if (par.e) {                                 /* e_delay */
			printf ("\nTime distribution from external clock\n");
			fprintf (logfile, "\n\n");
			print_distrib (e_delay, size, logfile, 0, quantum);
		}

		printf ("\nTime distribution of delays from internal clock\n");
		fprintf (logfile, "\n\n");                       /* delay */
		print_distrib (i_delay, size, logfile, side, quantum);
	}

	/* time distribution average and width */

	if (par.s || par.S) {

		sigma = 0.;
		average = 0.;

		for ( js=-side ; js<=side ; js++ )
                  average += i_differ[js+side] * js;

		average /= (par.n * par.N)/quantum;

		for ( js=-side ; js<=side ; js++ )
                  sigma += i_differ[js+side] * (js-average) * (js-average);

		sprintf (buff, "par.t: %d   <T>: %f   Sigma: %f\n", par.t,
			 average, quantum*sqrt(sigma/(par.n * par.N - 1)));

		printf ("\n%s", buff);
		fprintf (logfile, "\n# %s", buff); 
	}

	total_time = tm_diff(&very_last, &very_first);
	sprintf (buff, "Total time: %d   skew: %d\n",
		 total_time, total_time -
		 par.n * par.N * par.t);
	printf (buff);
	fprintf (logfile, "# %s", buff);

	if (listfile) fclose (listfile);
	if (logfile) fclose (logfile);

	if (par.v) printf ("Cleaning buffers at %p %p %p\n",
			   big_time_buf, tevi, e_delay);
	free (big_time_buf);
	free (tevi);
	free (e_delay);

	return 0;

 bad_exit:
	if (logfile) fclose (logfile);
	if (listfile) fclose (listfile);
	free (big_time_buf);
	free (tevi);
	free (e_delay);
	return -1;
}
//                     DOFF do fit fft   1=fit   2=fft+fit
//   fit cointains: baselineshift; fft; 
//
void ro_readwav(char* fname , int start=0, int stop=0, int DOFF=0,char *OPT="WWN0Q", char *clerun="run"){

  FILE *f;
  int i,j=0;
  Short_t ssample[10];
  UShort_t buffer[2200]; // usually 600

  //============ OPEN FILE========== READ 1st word
  f=fopen( fname , "r" );
  fread( ssample, sizeof(Short_t), 1 , f );
  printf("i ... sample size = %d ... one integer is %d  bytes\n",
	 ssample[0] , sizeof(Short_t)  );
  // read the rest =================== 1st sample 
  fread( buffer, sizeof(Short_t), ssample[0]-1, f );
  for (i=0;i<ssample[0];i++){buffer[i]=0;} // clean buffer
  printf("%s\n", "buffer clean");


  //----------------- DECLARATIONS #2
  TH1F *hch[8]; // channel histograms: 0-7 FW
  for (i=0;i<8;i++){hch[i]=NULL;}
  TH1F *hchf[8]; // chan fit 
  for (i=0;i<8;i++){hchf[i]=NULL;}
  TH1F *htime[8]; // I cannot Fill time histo !?
  for (i=0;i<8;i++){htime[i]=NULL;}
  TH2F* bidim[8];  // slope vs ene
  for (i=0;i<8;i++){bidim[i]=NULL;}
  //  TH2F* ede=new TH2F("ede","E x dE matrix",400,0,8000,400,0,8000);



  
  TH1F *h; // WAVE HISTOGRAM ============ MAIN HISTOGRAM
  
  char hname[20];   // histo channels
  int result;    
  int sizeOfStr=16; // SIZE OF struct with b,ch,t,E
  // ---- structure data:
  Short_t b,ch, evnt, ene ;  // board channel energy
  unsigned long long time=0;
  // tets differences
  unsigned long long timelast=0;
  Short_t extr;
  float avg=0.0;
  // fit parameters:
  double* pars;
  

    //==============================FILE  TTREE ================
    struct Tdata{
      ULong64_t t;   //l  time 
      Int_t n;       // i  event number
      Int_t ch;      // i   channel
      Int_t e;       //i    energy
      Float_t efit;  //F    energy from fit
      Float_t xi;    //F    Xi2 from  fit
      Float_t s;     //F    s - slope from fit
     //-------------------COINCIDENCES from NOW -----------
      Int_t e0;      // COINC CASE    E0
      Int_t e1;      // COINC CASE    E0
      Int_t dt;      //I   +-

      Int_t efit0;
      Int_t efit1;
      Int_t s0;
      Int_t s1;
      
    } event;
      
    char outname[300];   // OUT =   infile.root
    char wc[100];int wci=0;
    //    sprintf(outname,"%s_%06d_%06d.root", fname , start, stop );
    sprintf(outname,"%s_%06d_%06d.root" , clerun, start, stop );
    
    TFile *fo=new TFile(  outname ,"recreate");
    TTree *to=new TTree("pha","dpp_pha_data");
    to->Branch("time",&event.t,"t/l");
    to->Branch("data",&event.n,"n/i:ch/i:e/i:efit/F:xi/F:s/F");
    to->Branch("coin",&event.e0,"e0/i:e1/i:dt/I:efit0/I:efit1/I:s0/I:s1/I");


    MyCoinc *mc=new MyCoinc(0,1);  // guard channels  0 + 1 
//
    //
    //

    //#####################################  LOOP #####################
    int JMIN=start;
    int JMAX=stop;
    if (stop==0){JMAX=999999999;}
    //  JMAX=111;    // limit for test
    for (j=0;j<=JMAX;j++){
    
    event.n=j;
    event.e=0;
    event.efit=0;
    event.xi=0;
    event.s=0;

    event.efit0=0;
    event.efit1=0;
    event.s0=0;
    event.s1=0;

    // ch  t 
    
    result=fread( buffer,sizeof(Short_t) , sizeOfStr, f );
    if (result<sizeOfStr) break;
    //---------------- FW header decode
    b=buffer[0];
    ch=buffer[1];
    evnt=buffer[2];
    //[8]-[11] ... time
    //--------------- Time decode
    time=0;
    time=buffer[11];      time=time<<16;
    time=time+buffer[10]; time=time<<16;
    time=time+buffer[9]; time=time<<16;
    time=time+buffer[8];
    timelast=time;
    
    ene=buffer[12];
    extr=buffer[13];
    //    printf( "ch/evnt/ene   %3d   %3d  %3d  E=%3d  %3d\n", ch, evnt, ene, extr );
    //    printf("%lld  =======  %3d  \n", time, ene);

    event.t=time;
    event.e=ene;
    event.ch=ch;

    
    //================ FILL ENERGY HISTO
    if (hch[ ch ]==NULL){
      sprintf(hname,"hifw_%02d", ch);
      hch[ ch ]= new TH1F( hname,hname,16000,0,16000);
    }
    //  printf("%s\n", "J loop hifw ok");
    hch[ch]->Fill( ene );

    //================ FILL TIME HISTO
    if (htime[ch]==NULL){
      sprintf(hname,"hitime_%02d", ch); 
      //      htime[ch]= new TH1F( hname,"timeprofile;[seconds]",1000000,0,100);
      int seconds=1000;
      htime[ch]= new TH1F( hname,"hname",seconds*100,0,seconds);
      printf("defined  %d. htime\n",ch);
    }
    htime[ch]->Fill( float(time/100000000.) );

    if (j%1000==0){printf( "j=%d ...\n", j );}

    
    //    if ( j>= start){ //=======PARALLEL LOOP===============
    //===============================================LOAD WAVEFORM
    result = fread( buffer,sizeof(Short_t) , ssample[0], f );
    if (result< ssample[0]) break;

    
   


    
    // ============ FIT / ANALYZE ================
    int makefit=0;
    if ((j>=start)&&(j<stop) ){ makefit=1;}

    
    if (DOFF==0){ makefit=0;} //no reason, but ok
    if (makefit==1){
      //====CREATE HISTOGRAM wave ==>>> VARIANT:create/analyze/root it/delete
      //      if (j-start<100){
	sprintf(hname,"wave_%06d", j); // here I keep the channel
	h=new TH1F( hname,hname, ssample[0],0,ssample[0] );
     //      }// create only when #<100;  then REUSE "h"

      //====== prepare ZERO (one analyze parameter now)
      avg=0.0;
      for (i=0;i<50;i++){avg=avg+buffer[i];}
      avg=avg/(50.);


      // HISTOGRAM IS FILLED  HERE:
      // ### ======= Fill SHIFTED buffer TO ZERO histogram
      for (i=0;i<ssample[0];i++){    // i add ch 0/1 to the end!
	h->SetBinContent( i+1, buffer[i] - avg ); // 0-1 is #1
      }

      // ### FFT HERE //
      if (DOFF==2){  //====================++FFT BEGIN =============
      int n=ssample[0];
	TH1 *hmsm =0;
	TH1 *hpsm =0;
	hmsm=h->FFT(hmsm,"MAG");
	hpsm=h->FFT(hpsm,"PH");
	TVirtualFFT *fft = TVirtualFFT::GetCurrentTransform();
	Double_t *re_full = new Double_t[ssample[0]];
	Double_t *im_full = new Double_t[ssample[0]];
	fft->GetPointsComplex(re_full,im_full);
	for (int j=0;j<ssample[0]/2; j++){
	  hmsm->SetBinContent( j,  re_full[j]   );
	  hpsm->SetBinContent( j,  im_full[j]   );
	}
	//	for (int j=16;j>11;j--){
	hmsm->Smooth(2);
	hpsm->Smooth(2);
	for (int j=16;j>5;j--){
	  hmsm->SetBinContent( j,  0.8*re_full[j]   );
	  hpsm->SetBinContent( j,  0.8*im_full[j]   );
	}
	hmsm->Smooth(2);
	hpsm->Smooth(2);

	for (int j=0;j<ssample[0]/2;j++){
	  re_full[j]=hmsm->GetBinContent(j);
	  im_full[j]=hpsm->GetBinContent(j);
	}
 	TVirtualFFT *fft_back = TVirtualFFT::FFT(1, &n, "C2R M K");
	fft_back->SetPointsComplex(re_full,im_full);
	fft_back->Transform();
	TH1 *hb = 0;
	hb = TH1::TransformHisto(fft_back,hb,"Re");
	double mx= mx=hb->GetMaximum();
	double omax= h->GetMaximum();
	hb->Scale( omax/mx );
	delete fft_back;
	delete [] re_full;
	delete [] im_full;
	if (gPad!=NULL){
	  h->Draw();
	  hb->Draw("same");hb->SetLineColor(3);
	  gPad->Modified(); gPad->Update();
	}
	for (int j=0;j<ssample[0];j++){
	  h->SetBinContent( j, hb->GetBinContent(j) );
	}
	delete hb;
	delete hmsm;
	delete hpsm;
	//	sleep(1);
	//	h->Draw(); gPad->Modified(); gPad->Update();

      }// ========================================= FFT HERE  END



      
      // ### ===========     fit 1 ==========
      pars=fit1( ssample[0],  h , OPT ); // FIT 400 points in a sample
      printf("%06d/ %6.1f %5.2f    %5.2f  \n", j, pars[0], pars[1] ,pars[2]  );
      if ( bidim[ch]==NULL ){
	sprintf(hname,"bishape_%02d", ch);
	bidim[ch]=new TH2F( hname,"shapes;Energy;slope in channels", 2500,0,2500,450,2,45);
      }
      bidim[ch]->Fill( pars[0], pars[1] );
      //      sleep(1);
      
      //##### DEBUG HERE".....................
      // # pars[1]===S
      // # pars[0]==E
      //      if ( (ch==0)&&(pars[0]>960.) ){
      /*
      if ( (ch==0)&&(pars[1]>100.) ){
	printf("S problem @ %d chan %d S=%f\n",j,ch, pars[1]);
	sleep(5);
      }
      */
      //================ FILL ENERGY FIT HISTO
      if (hchf[ ch ]==NULL){
	sprintf(hname,"hifit_%02d", ch);
	hchf[ ch ]= new TH1F( hname,hname,16000,0,16000);
      }
      hchf[ch]->Fill( pars[0] );

      event.efit=pars[0];
      event.s=10*pars[1];
      event.xi=10*pars[2];
      if ( strstr(OPT,"WWN0Q")!=NULL)  {
	delete h;
	//       	printf("%s %s\n","...DELEING histogram ", OPT);
      }else{
	h->Write();
	printf("%s","...writing histogram to file\n");
      } //write to tree if not N0Q
    } // fit ---------------------------------------------END--
   // =========== FIT / ANALYZE  ============= END  ===========
    if ( event.efit>16000){
      event.efit=0;
      event.s=0;
      event.xi=0;
    }

    event.e0=0;
    event.e1=0;
    event.dt=0;


    //=================COINCIDENCES ========== BEGIN ======
    //  and if result == 1 : coincidence was found....
    if (1==mc->add( ch, event.t, event.e, event.efit, event.xi,event.s) ){
                                    // event.efit
      event.e0=mc->getlastC0();
      event.e1=mc->getlastC1();
      event.efit0=mc->getlastC0fit();
      event.efit1=mc->getlastC1fit();
      event.s0=mc->getlastC0s();
      event.s1=mc->getlastC1s();
      event.dt=-mc->getlastDT();
      if ( (event.dt>400)||(event.dt<-400)){
	printf("%4d mc ============================\n", event.dt);
      }
    } //============================ COINCIDENCES END =====
    


    
    if (makefit==1){ delete pars; } // no pars if no fit
    //    if (h!=NULL){delete h;}   // delete  WAVE HISTOGRAM

    //==========SAVE TTREE======
    //    if (makefit==1){
      to->Fill();
      //    }
    //    } // ===========PARALLEL LOOP ===========
    
  } //------- j < JMAX ------=====================================END




    fclose(f);
    
    if (j>=JMAX){  // i dont create thousands of th1f anymore
      printf("!... limit in number of histograms reached....%d.  STOP \n", j);
    }else{
      printf("!... total number of histograms  == %d \n", j);
      }     
    if ( (gPad!=NULL)&&(bidim[0]!=NULL)){    bidim[0]->Draw("col"); }
    double dlt=(timelast/100/1000);
    printf("%7.3f s =last time\n", dlt/1000.);

    //====SAVE==============================
    for (ch=0;ch<8;ch++){
      //      printf("ch == %d\n", ch);
      if (hch[ch]!=NULL){ hch[ch]->Write();}
      if (htime[ch]!=NULL){ htime[ch]->Write();}
      if (bidim[ch]!=NULL){ bidim[ch]->Write();}
    }

    //  ede->Write();
    // ttree:=====================
    //    mc->print();
    TH2F* mcbi=(TH2F*) mc->getbidim();  // this is coincidences stored in [mc]
    TH2F* mcbifi=(TH2F*) mc->getfitbidim();  // this is fit coincidences stored in [mc]
    TH1F* mchidt=(TH1F*) mc->gethidt();
    mcbi->Write();
    mcbifi->Write();
    mchidt->Write();
 
    to->Print();
    to->Write();
    fo->Close();

} //######################################################## END ##############