// Macro to do common mode analysis on an event by event basis // 17/10/2000 SJMP // // Arguments: // filename : base (ie no extension) of filename to write to. // I do add my data directory, so please change it for your own. // A run and scan number of the first event will be added to the // filename. The macro will create a .root file for the data // and a .ps file as summary. // n_events : number of events to be taken // charge : charge (mV) to be injected in the chip // threshold : threshold setting in mV // moi : module identifaction nr to be used // update : update plot every 256 events // burst_type: select burst type to be used // default is 11, implemented to use burst_type 100 // (read-out of data directly and not the histogram due to // Mustard problems) // // ChangeLog: // 18/10/2000 : Added raw data save // 30/11/2000 : New data format used // 08/12/2000 : Better online display for quality check of data // 19/12/2000 : Fixed problems using burst_type 100 (avoiding histogram r/o) // HOWEVER: NOT TESTED FOR ANY OTHER BURST TYPES... // // Calibration pulse and threshold have to be set before by the user // void fwdsct_common_mode(Char_t * filename, Int_t n_events, Float_t charge, Float_t threshold, Int_t moi, Int_t update = 1, Int_t burst_type = 11) { // check if module is there if ( !e->m[moi]->present) return; // global constant variables const Int_t NSTRO = 4; // number of strobe channels const Int_t NCHIP = 12; // number of chips const Int_t NCHAN = 128; // number of channels per chip // global variables Int_t i,cal,event_nr,channel_nr,chip_nr,strobe_nr; Float_t oc[NCHIP][NSTRO]; Int_t n_trigs_org, burst_type_org, do_fits_org, trigger_org; Char_t s[250]; ULong_t wait, dummy_wait; Int_t start_burst; TH2F * hitmap = new TH2F("hitmap","hitmap", NCHIP*NCHAN,0,NCHIP*NCHAN-1,256,0,255); hitmap->SetXTitle("channel nr."); hitmap->SetYTitle("event nr."); TH1F * occupancy[NCHIP][NSTRO]; for ( chip_nr = 0 ; chip_nr < NCHIP ; ++chip_nr ) { for ( strobe_nr = 0 ; strobe_nr < NSTRO ; ++strobe_nr ) { sprintf(s,"occupancy chip: %d strobe: %d",chip_nr,strobe_nr); occupancy[chip_nr][strobe_nr] = new TH1F(s,s,NCHAN/NSTRO+1,0,NCHAN/NSTRO); occupancy[chip_nr][strobe_nr]->SetXTitle("occupancy"); } } // create tree to store the raw data sprintf(s,"D:\\sctvar\\data\\%s_%d_%d.root", filename,e->runnum,e->scannum); TFile * data_file = new TFile(s,"RECREATE"); FwdSctSingleEvent * event = new FwdSctSingleEvent(); TTree * tree = new TTree("data","event by event data"); TBranch * branch = tree->Branch("event", "FwdSctSingleEvent", &event); // set-up n_trigs_org = e->burst_ntrigs; burst_type_org = e->burst_type; do_fits_org = e->do_fits; trigger_org = e->burst_trtype; if ( charge == 0 ) { e->burst_trtype = 0; // L1A } else { e->burst_trtype = 3; // CAL+L1A e->ConfigureVariable(2,charge); // set Vcal (mV) e->ExecuteConfigs(1); } e->ConfigureVariable(1,threshold); // set Threshold (mV) e->burst_ntrigs = 1; e->burst_type = burst_type; e->do_fits = 0; // do not fit st_start_stopper(); // create display gStyle->SetOptStat(0); gStyle->SetTitleColor(10); gStyle->SetTitleW(1); gStyle->SetTitleBorderSize(0); gStyle->SetPadBottomMargin(0.15); gStyle->SetPadLeftMargin(0.15); gStyle->SetTitleOffset(2,"X"); TCanvas * occupancy_canvas = new TCanvas ("occupancy_canvas", "fwdsct_common_mode", 1100,750); occupancy_canvas->SetFillColor(0); TPad * pad_t_1 = new TPad ("pad_t_1","text1",0.01,0.91,0.99,0.99,10); TPad * pad_p_1 = new TPad ("pad_o_1","plot1",0.01,0.46,0.99,0.90,10); TPad * pad_p_2 = new TPad ("pad_o_2","plot2",0.01,0.01,0.99,0.45,10); pad_t_1->SetBorderMode(0); pad_p_1->SetBorderMode(0); pad_p_2->SetBorderMode(0); pad_t_1->Draw(); pad_p_1->Draw(); pad_p_2->Divide(NCHIP,NSTRO); pad_p_2->Draw(); // fill pads TPaveText *t1 = new TPaveText(0.0,0.0,1.0,1.0); t1->SetFillColor(10); t1->SetBorderSize(0); t1->SetTextAlign(22); t1->SetTextSize(0.5); t1->SetTextColor(1); t1->AddText("ATLAS FWD SCT Common Mode Analysis : occupancy"); pad_t_1->cd(); t1->Draw(); pad_p_1->cd(); hitmap->Draw("col"); for ( strobe_nr = 0 ; strobe_nr < NSTRO ; ++strobe_nr ) { for ( chip_nr = 0 ; chip_nr < NCHIP ; ++chip_nr ) { pad_p_2->cd(strobe_nr*NCHIP+chip_nr+1); occupancy[chip_nr][strobe_nr]->Draw(); } } occupancy_canvas->Update(); // run for ( event_nr = 0 ; event_nr < n_events ; ++event_nr ) { printf("event number : %d <---\n",event_nr); if ( st_do_stop() ) event_nr = n_events; // if burst_type == 100 the data needs to be reset if ( e->burst_type == 100 ) { printf("Clearing histograms burst_count %d\n",e->burst_count); for ( channel_nr = 0 ; channel_nr < 768; ++channel_nr ) { e->m[moi]->scan[e->burst_count][0][channel_nr] = 0; e->m[moi]->scan[e->burst_count][1][channel_nr] = 0; } } e->burst_count = 0; if ( charge == 0 ) { e->ExecuteBurst(0); } else { for ( cal = 0 ; cal < NSTRO ; ++cal ) { e->ConfigureVariable(-1,10,cal); // configure cal_mode e->ExecuteConfigs(1); for ( wait = 0 ; wait < 20000 ; ++wait ) dummy_wait = wait; e->ExecuteBurst(cal); e->burst_count = 0; // need it here as well (??) for ( channel_nr = 0 ; channel_nr < 32; ++channel_nr ) { printf("%d ", e->m[moi]->scan[e->burst_count][0][channel_nr]); } printf("\n"); for ( channel_nr = 0 ; channel_nr < 32; ++channel_nr ) { printf("%d ", e->m[moi]->scan[e->burst_count][1][channel_nr]); } printf("\n"); } } // fill hitmap for ( chip_nr = 0, channel_nr = 0 ; channel_nr < NCHIP*NCHAN ; ++channel_nr ) { if ( channel_nr % NCHAN == 0 && channel_nr != 0 ) { ++chip_nr; for ( strobe_nr = 0 ; strobe_nr < NSTRO ; ++strobe_nr ) { oc[chip_nr][strobe_nr] = 0; } } Float_t content = 0; if ( channel_nr < (NCHIP/2.)*NCHAN ) { content = e->m[moi]->scan[e->burst_count][0] [channel_nr]; } else { content = e->m[moi]->scan[e->burst_count][1] [channel_nr-(NCHIP/2.)*NCHAN]; } if ( content < 0 || content > 1 ) { printf("\nBincontent is not binary: %d\n",content); printf("Exiting...\n"); st_stop_stopper(); return; } hitmap->SetBinContent(hitmap->GetBin(channel_nr,event_nr%256), content); event->SetBit(channel_nr,content); strobe_nr = channel_nr%NSTRO; oc[chip_nr][strobe_nr] += content; } // for channel_nr // fill histograms for ( chip_nr = 0 ; chip_nr < NCHIP ; ++chip_nr ) { for ( strobe_nr = 0 ; strobe_nr < NSTRO ; ++strobe_nr ) { occupancy[chip_nr][strobe_nr]->Fill(oc[chip_nr][strobe_nr]); } // for strobe_nr } // for chip_nr // event added to tree tree->Fill(); // update plots if required if ( (event_nr%256) == 0 && event_nr != 0 && update ) { pad_p_1->cd(); pad_p_1->Modified(); pad_p_1->Update(); pad_p_2->Modified(); pad_p_2->Update(); } // if update } // for event_nr // clean up and plot e->burst_ntrigs = n_trigs_org; e->burst_type = burst_type_org; e->do_fits = do_fits_org; e->burst_trtype = trigger_org; pad_p_1->Modified(); pad_p_1->Update(); pad_p_2->Modified(); pad_p_2->Update(); // save file and plot data_file->Write(); tree->Print(); data_file->Close(); sprintf(s,"D:\\sctvar\\data\\%s_%d_%d.ps", filename,e->runnum,e->scannum++); occupancy_canvas->SaveAs(s); st_stop_stopper(); return; }