ROOT logo
///////////////////////////////////////////////
// Simple event display for channel spectra
// Input file should be raw DATE root tree file
///////////////////////////////////////////////

// for the readout
const int NFEC    =  36;                        // Max 36 FrontEndCard per SM
const int NCHIP   =  4;                         // 4 ALTROs per FEC
const int NCHAN   = 16;                         // Channels per ALTRO
const int TOTCHAN = NFEC * NCHIP * NCHAN;	// Max uses ALTRO channels

const int NCOLS = 48; // per SM
const int NROWS = 24;
const int NMINI = 3; // number of ministrips, or T-cards, per strip

// gamma2 fit function
double fitfun(double *x, double *par) {
  double Amp	= par[0];
  double Tmax	= par[1];
  double Tau	= par[2];
  double Ped	= par[3];
  double gammaN   = par[4];
  double t = 0;
  if(Tau) t = (x[0] - Tmax + Tau)/Tau;
  if(t<0) t = 0;
  
  // Since we have now set gammaN to 2, we replace the pow(t, 2) call in
  // double f = Amp * pow(t,gammaN) * exp(gammaN*(1-t)) + Ped;
  // with just t*t
  double f = Amp * t*t * exp(gammaN*(1-t)) + Ped;
  return f;
}

// main method
void RAW_evtdis(const int year=12, const int runno = 191741, const int streamno=8, const int segno=10,
		const int gainv = 1,  /*0=low, 1=high*/
		const int evtnum= 1,
		const int module = 0,
		const int strip = 0,
		int ymax=200, // set the scale of plots
		const int delay = 1)  // -1=no delay, wait for input, X>=0 => sleep aprox. X sec. after making plot
{
  // set ranges to plot
  const int col_f = strip*2;
  const int col_l = col_f + 1;
  const int row_f = 0;
  const int row_l = NROWS - 1;

  const int nsamples = 15; // number of ADC time samples per channel and event

  const int saveplot = 0;
  const int numbering      = 1; // 0: no numbering, 1: numbering on each plot
  const int dofit = 0; // 0: no fit, 1: try to fit the spectra (not debugged) 
  const int debug    = 0;
  const float gammaN = 2;
  // end of setup    

  // Assume we are just interested in the 1st segment, _0.root below for fname*
  Char_t fname[256];
  sprintf(fname, "%02d%09d0%02d.%d.root", year, runno, streamno, segno);

  // set up a raw reader of the data
  AliRawReader *rawReader = NULL;
  rawReader = new AliRawReaderRoot(fname);
  AliCaloRawStreamV3 *in = NULL; 
  in = new AliCaloRawStreamV3(rawReader,"EMCAL");
  rawReader->Select("EMCAL", 0, AliEMCALGeoParams::fgkLastAltroDDL) ; //select EMCAL DDL range

  // set up histograms
  TH1F *hfit[TOTCHAN];
  TF1 *f1[TOTCHAN];
  char ch_label[TOTCHAN][100];
  char buff1[100];
  char name[80];
  for(int i=0; i<TOTCHAN; i++) {
    sprintf(buff1,"hfit_%d",i);
    hfit[i] = new TH1F(buff1,"hfit", nsamples , -0.5, nsamples - 0.5);
    hfit[i]->SetDirectory(0);
    sprintf(name,"f1_%d",i);
    f1[i] = new TF1(name,fitfun,0,70,5);
    f1[i]->SetLineWidth(2);
    f1[i]->SetLineColor(2);

    //	int idx = arow * NCOLS + acol + NCOLS*NROWS * gain; // encoding used later
    int gain = i / (NCOLS*NROWS);
    int row = (i % (NCOLS*NROWS))/NCOLS;
    int col = i % NCOLS;
    sprintf(ch_label[i], "Col%02d Row%02d", col, row);
  }

  int numcol = col_l-col_f+1;
  int numrow = row_l-row_f+1;

  TCanvas *cc[NMINI];
  for (int ic=0; ic<NMINI; ic++) {
    sprintf(buff1, "cc%d", ic);
    // use the usual StripX CY, X=0..23, Y=0..2 notation for T-cards (mini-strips)
    sprintf(name,"Strip %d MiniStrip(T-card) C%d", strip, ic);
    cc[ic] = new TCanvas(buff1,name, 400*ic, 10, 400,800);
    cc[ic]->Divide(numcol, numrow/NMINI);
    cc[ic]->SetTitle(name);
  }

  TText *t = new TText;
  t->SetTextSize(0.17);
  int clr[2] = {4,2}; // colors

  // figure out which events we should look at
  int firstevent = evtnum;
  int lastevent = evtnum;
  if (evtnum < 0) { // get a bunch of events
    firstevent = 0;
    lastevent = - evtnum;
  }
  if (evtnum == 0) { // get all events
    firstevent = 0;
    lastevent = 1000000;
  }

  Int_t iev =0;
  AliRawEventHeaderBase *aliHeader=NULL;    
  while ( rawReader->NextEvent() && iev < firstevent) {
    aliHeader = (AliRawEventHeaderBase*) rawReader->GetEventHeader();
    iev++;
  }
  
  // loop over selected events
  while ( rawReader->NextEvent() && iev <= lastevent) {
    aliHeader = (AliRawEventHeaderBase*) rawReader->GetEventHeader();
    int runNumber = aliHeader->Get("RunNb"); 
    
    cout << "Found run number " << runNumber << endl;

    // reset histograms
    for(int i=0; i<TOTCHAN; i++) {
      hfit[i]->Reset();
    }

    // get events (the "1" ensures that we actually select all events for now)
    if ( 1 || aliHeader->Get("Type") == AliRawEventHeaderBase::kPhysicsEvent ) {
      const UInt_t * evtId = aliHeader->GetP("Id");
      int evno_raw = (int) evtId[0];
      int timestamp = aliHeader->Get("Timestamp");

      cout << " evno " << evno_raw
	   << " size " << aliHeader->GetEventSize()
	   << " type " << aliHeader->Get("Type")
	   << " type name " << aliHeader->GetTypeName()
	   << " timestamp " << timestamp
	   << endl;

      int sample = 0;
      int time = 0;
      /// process_event stream
      while (in->NextDDL()) {
	//	if (module == in->GetModule()) {
	if (1) {
	  while (in->NextChannel()) {
       
	    int acol = in->GetColumn();
	    int arow = in->GetRow();
	    int gain = in->GetCaloFlag();

	    int idx = arow * NCOLS + acol + NCOLS*NROWS * gain;
	    //cout << "module " << in->GetModule() << endl;

	    if (gain>1 || module!=in->GetModule()) { // TRU or LEDMon
	    }
	    else if (idx < 0 || idx > TOTCHAN) { 
	      cout << "Hist idx out of range: " << idx << endl;
	    }
	    else { // reasonable range of idx (removes TRU and LEDMon data also)
	      //cout << "hist idx " << idx << endl;
	      
	      while (in->NextBunch()) {
		const UShort_t *sig = in->GetSignals();
		int startBin = in->GetStartTimeBin(); 
		for (Int_t i = 0; i < in->GetBunchLength(); i++) {
		  sample = sig[i];
		  time = startBin--;
		  if (debug>2) {
		    cout << " hw address " << in->GetHWAddress()
			 << " time " << time << " sample " << sample
			 << endl;
		  } // debug

		  if (idx >= 0 && idx < TOTCHAN) {  
		    hfit[idx]->SetBinContent(time, sample);
		  }
		}
	      }
	    }
	  }
	}
      } // Raw data read

      // Next: let's actually plot the data..
      int nrow_mini = NROWS/NMINI; // number of rows per T-card or mini-strip
      for (Int_t arow = row_f; arow <= row_l; arow++) {
	for (Int_t acol = col_f; acol <=  col_l; acol++) {
	  int idx = arow * NCOLS + acol + NCOLS*NROWS * gainv;

	  // which T-card does the tower belong to?
	  int mini = arow / (nrow_mini); 	  
	  // on which pad should we plot it?
	  int pad_id = ((row_l-arow)%nrow_mini) *(col_l-col_f+1) + acol - col_f + 1;
	  
	  cout << "row="<< arow << ", col=" << acol
	       << ", C" << mini << ", pad=" << pad_id << endl;
	  cc[mini]->cd(pad_id);
	  hfit[idx]->SetTitle("");
	  hfit[idx]->SetFillColor(5);
	  hfit[idx]->SetMaximum(ymax);
	  hfit[idx]->SetMinimum(0);
	  // we may or may not decide to fit the data
	  if (dofit) {
	    hfit[idx]->Fit(f1[i]);
	  }
	  hfit[idx]->Draw();
	  if( numbering ) {
	    t->SetTextColor(clr[gainv]);
	    t->DrawTextNDC(0.45,0.45,ch_label[idx]);
	  }
	}
      }

      // add some extra text on the canvases
      for (int ic=0; ic<NMINI; ic++) {
	// print a box showing run #, evt #, and timestamp
	cc[ic]->cd();
	// first draw transparent pad
	TPad *trans = new TPad("trans","",0,0,1,1);
	trans->SetFillStyle(4000);
	trans->Draw();
	trans->cd();
	// then draw text
	TPaveText *label = new TPaveText(.2,.11,.8,.14,"NDC"); 
	//  label->Clear();
	label->SetBorderSize(1);
	label->SetFillColor(0);
	label->SetLineColor(clr[gainv]);
	label->SetTextColor(clr[gainv]);
	//label->SetFillStyle(0);
	TDatime d;
	d.Set(timestamp);
	sprintf(name,"Run %d, Event %d, Hist Max %d, %s",runno,iev,ymax,d.AsString());
	label->AddText(name);
	label->Draw();
	cc[ic]->Update();
	cout << "Done" << endl;
      }

      // some shenanigans to hold the plotting, if requested
      if (firstevent != lastevent) {
	if (delay == -1) {
	  // wait for character input before proceeding
	  cout << " enter y to proceed " << endl;
	  char dummy[2];
	  cin >> dummy;
	  cout << " read " << dummy << endl;
	  if (strcmp(dummy, "y")==0) {
	    cout << " ok, continuing with event " << iev+1 << endl;
	  }
	  else {
	    cout << " ok, exiting " << endl;
	    //exit(1);
	  }
	}
	else {
	  cout << "Sleeping for " << delay * 500 << endl;
	  gSystem->Sleep(delay * 500);
	}
      }

    } // event selection
    iev ++;
  } // event loop

  // save plot, if setup/requested to do so
  char plotname[100];
  if (saveplot==1) {
    for (int ic=0; ic<NMINI; ic++) {
      sprintf(plotname,"Run_%d_Ev%d_Strip%d_C%d_Gain%d_MaxHist%d.gif",
	      runno,iev,strip,ic,gainv,ymax);  
  
      cout <<"SAVING plot:"<< plotname << endl;
      cc[ic]->SaveAs(plotname);
    }
  }

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