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 ##############