| 1 | // | 
| 2 | //   Given a calibration and a data file this program create an ntuple with LEVEL1 calorimeter variables - Emiliano Mocchiutti | 
| 3 | // | 
| 4 | //   FCaloLEVEL1.cxx    version 1.01  (2006-03-03) | 
| 5 | // | 
| 6 | //   The only input needed is the path to the directory created by YODA for the data file you want to analyze. | 
| 7 | // | 
| 8 | //   Changelog: | 
| 9 | // | 
| 10 | //   1.00 - 1.01 (2006-03-03): read unique YODA file and compile correctly with ROOT classes etc. | 
| 11 | // | 
| 12 | //   0.00 - 1.00 (2006-03-03): clone of CaloLEVEL1.c v 1.21. | 
| 13 | // | 
| 14 | #include <fstream> | 
| 15 | #include <sstream> | 
| 16 | #include <TTree.h> | 
| 17 | #include <TBranch.h> | 
| 18 | #include <TClassEdit.h> | 
| 19 | #include <TObject.h> | 
| 20 | #include <TList.h> | 
| 21 | #include <TSystem.h> | 
| 22 | #include <TSystemDirectory.h> | 
| 23 | #include <TString.h> | 
| 24 | #include <TFile.h> | 
| 25 | #include <TClass.h> | 
| 26 | #include <TCanvas.h> | 
| 27 | #include <TH1.h> | 
| 28 | #include <TH1F.h> | 
| 29 | #include <TH2D.h> | 
| 30 | #include <TLatex.h> | 
| 31 | #include <TPad.h> | 
| 32 | #include <TPaveLabel.h> | 
| 33 | #include <TChain.h> | 
| 34 | extern const char *pathtocalibration(); | 
| 35 | #include <PamelaRun.h> | 
| 36 | #include <physics/calorimeter/CalorimeterEvent.h> | 
| 37 | #include <physics/trigger/TriggerEvent.h> | 
| 38 | #include <CalibCalPedEvent.h> | 
| 39 | #include <fcalostructs.h> | 
| 40 | // | 
| 41 | extern char *getLEVname(TString, TString, TString, TString); | 
| 42 | extern TString whatnamewith(TString, Int_t); | 
| 43 | extern void stringcopy(TString&, const TString&, Int_t, Int_t); | 
| 44 | extern int CaloPede(TString, Int_t, Int_t, Calib &); | 
| 45 | extern void CaloFindBaseRaw(Calib &, Evento &, Int_t, Int_t, Int_t); | 
| 46 | extern void CaloCompressData(Calib &, Evento &, Int_t, Int_t, Int_t); | 
| 47 | extern int CaloFindCalibs(TString &, TString &, Int_t &, Calib &); | 
| 48 | extern bool existfile(TString); | 
| 49 | // | 
| 50 | #include <caloclassesfun.h> | 
| 51 |  | 
| 52 | short int FCaloLEVEL1(TString filename, TString OutDir="", TString calcalibfile = "", Int_t FORCE = 0){ | 
| 53 | const char* startingdir = gSystem->WorkingDirectory(); | 
| 54 | if ( !strcmp(OutDir.Data(),"") ) OutDir = startingdir; | 
| 55 | stringstream calfile; | 
| 56 | const char *pam_calib = pathtocalibration(); | 
| 57 | calfile.str(""); | 
| 58 | calfile << pam_calib << "/FCaloADC2MIP.dat"; | 
| 59 | // | 
| 60 | if ( !existfile(filename) ){ | 
| 61 | printf(" %s :no such file or directory \n",filename.Data()); | 
| 62 | return(1); | 
| 63 | }; | 
| 64 | TFile *File = new TFile(filename.Data()); | 
| 65 | TTree *otr = (TTree*)File->Get("Physics"); | 
| 66 | otr->SetBranchStatus("*",0); //disable all branches | 
| 67 | otr->SetBranchStatus("iev*",1); | 
| 68 | otr->SetBranchStatus("dexy*",1); | 
| 69 | otr->SetBranchStatus("stwerr*",1); | 
| 70 | otr->SetBranchStatus("perror*",1); | 
| 71 | otr->SetBranchStatus("cal*",1); | 
| 72 | otr->SetBranchStatus("base*",1); | 
| 73 | otr->SetBranchStatus("Pscu*",1); | 
| 74 | otr->SetBranchStatus("Calorimeter*",1); | 
| 75 | otr->SetBranchStatus("Header*",1); | 
| 76 | // | 
| 77 | pamela::calorimeter::CalorimeterEvent *de = 0; | 
| 78 | pamela::PscuHeader *ph = 0; | 
| 79 | pamela::EventHeader *eh = 0; | 
| 80 | // | 
| 81 | otr->SetBranchAddress("Calorimeter", &de); | 
| 82 | otr->SetBranchAddress("Header", &eh); | 
| 83 | // | 
| 84 | // calibration file | 
| 85 | // | 
| 86 | if ( calcalibfile == "" ) calcalibfile = filename; | 
| 87 | // | 
| 88 | struct Evento evento; | 
| 89 | struct Evento evento2; | 
| 90 | struct Calib calib; | 
| 91 | evento.emin = 0.7; | 
| 92 | Int_t tot0 = 0; | 
| 93 | Int_t tot1 = 0; | 
| 94 | Int_t tot2 = 0; | 
| 95 | Int_t baseDIFFfull = 0; | 
| 96 | // | 
| 97 | // Define variables | 
| 98 | // | 
| 99 | Long64_t nevents    = otr->GetEntries(); | 
| 100 | if ( nevents < 1 ) { | 
| 101 | printf("The file is empty!\n"); | 
| 102 | return(1); | 
| 103 | }; | 
| 104 | Float_t mip[2][22][96]; | 
| 105 | Int_t b[4]; | 
| 106 | Int_t etime,evno,stwerr[4]; | 
| 107 | //    Int_t etime,pl,evno,stwerr[4]; | 
| 108 | //    Float_t ener, basel,sbase[2][22][6],sdexy[2][22][96],sdexyc[2][22][96]; | 
| 109 | Float_t ener, basel,sdexy[2][22][96],sdexyc[2][22][96]; | 
| 110 | Float_t esup[2][22][96], einf[2][22][96], edelta[2][22][96]; | 
| 111 | // | 
| 112 | // create the ntuple level1 name | 
| 113 | // | 
| 114 | //    file = "dw_000000_00000.Physics.Level1.Calorimeter.Event.root"; // just to make space... | 
| 115 | TString numb = "1";  // level | 
| 116 | TString detc = "Calorimeter";  // detector | 
| 117 | char *file = getLEVname(filename,detc,numb,"root"); | 
| 118 | //printf("file> %s\n",file); | 
| 119 | //return; | 
| 120 | // | 
| 121 | //    char *file2; // the full path and name of the level1 ntuple | 
| 122 | stringstream file2; | 
| 123 | const char *file3; | 
| 124 | file3 = OutDir; | 
| 125 | file2.str(""); | 
| 126 | file2 << file3 << "/"; | 
| 127 | file2 << file; | 
| 128 | //  file2 = Form("%s/Physics/Level1/%s",file3,file);  // add the path where to save | 
| 129 | printf("\n Filename will be: \n %s \n\n",file2.str().c_str()); | 
| 130 | // | 
| 131 | // check if Level1 directory exists, if not create it. | 
| 132 | // | 
| 133 | stringstream savedir; | 
| 134 | savedir.str(""); | 
| 135 | savedir << file3 << "/"; | 
| 136 | //    char *savedir; | 
| 137 | //savedir = Form("%s/Physics/Level1"); | 
| 138 | //    Int_t ERR = gSystem->OpenDirectory(savedir.str().c_str()); | 
| 139 | // | 
| 140 | // check if Level1 directory exists, if not create it. | 
| 141 | // | 
| 142 | Int_t ERR = gSystem->MakeDirectory(savedir.str().c_str()); | 
| 143 | // | 
| 144 | if ( !ERR ) { | 
| 145 | printf(" LEVEL1 directory doesn't exist! Creating LEVEL1 directory \n\n"); | 
| 146 | gSystem->MakeDirectory(savedir.str().c_str()); | 
| 147 | } else { | 
| 148 | // | 
| 149 | // directory exists, check if file exists (if we are not in the force mode) | 
| 150 | // | 
| 151 | if ( !FORCE ) { | 
| 152 | printf(" Not in FORCE mode, check the existance of LEVEL1 data: \n\n"); | 
| 153 | TFile tfile(file2.str().c_str()); | 
| 154 | if ( !tfile.IsZombie() ) { | 
| 155 | printf(" ERROR: file already exists! Use FORCE = 1 to override \n\n"); | 
| 156 | return(3); | 
| 157 | } else { | 
| 158 | printf("\n OK, I will create it!\n"); | 
| 159 | }; | 
| 160 | }; | 
| 161 | }; | 
| 162 | char *type; | 
| 163 | type = "NEW"; | 
| 164 | if ( FORCE ) type = "RECREATE"; | 
| 165 | TFile *hfile = 0; | 
| 166 | hfile = new TFile(file2.str().c_str(),type,"Calorimeter LEVEL1 data"); | 
| 167 | // | 
| 168 | // variables which will fill the ntuple | 
| 169 | // | 
| 170 | Float_t perror[4]; | 
| 171 | Float_t nstrip; | 
| 172 | Float_t qtot; | 
| 173 | Float_t calevnum[4]; | 
| 174 | Float_t estrip[2][22][96]; | 
| 175 | Float_t estripnull[2][22][96]; | 
| 176 | Float_t diffbas[2][22][6]; | 
| 177 | // | 
| 178 | // class CalorimeterLevel1 | 
| 179 | // | 
| 180 | CalorimeterLevel1 *calo = new CalorimeterLevel1(); | 
| 181 | // | 
| 182 | // Create a ROOT Tree | 
| 183 | TTree *tree = 0; | 
| 184 | //    calo = new CalorimeterLevel1(); | 
| 185 | tree = new TTree("CaloLevel1","PAMELA Level1 calorimeter data"); | 
| 186 | tree->Branch("Event","CalorimeterLevel1",&calo); | 
| 187 | //TBranch *branch = tree->Branch("Event",&calo,64000,0); | 
| 188 | // | 
| 189 | // this is the value of the mip for each strip. To be changed when we will have the real values | 
| 190 | // | 
| 191 | for (Int_t s=0; s<4;s++){ | 
| 192 | for (Int_t d = 0; d<51; d++){ | 
| 193 | calib.ttime[s][d] = 0 ; | 
| 194 | calib.time[s][d] = 0 ; | 
| 195 | }; | 
| 196 | }; | 
| 197 | // | 
| 198 | Int_t okcalo = 0; | 
| 199 | printf(" ADC to MIP conversion file: \n %s \n",calfile.str().c_str()); | 
| 200 | FILE *f; | 
| 201 | f = fopen(calfile.str().c_str(),"rb"); | 
| 202 | if ( !f ){ | 
| 203 | printf(" WARNING: no calorimeter ADC to MIP file! \n Using 26 as conversion factor for all strips. \n"); | 
| 204 | } else { | 
| 205 | okcalo = 1; | 
| 206 | }; | 
| 207 | // | 
| 208 | if ( okcalo ) { | 
| 209 | for (Int_t m = 0; m < 2 ; m++ ){ | 
| 210 | for (Int_t k = 0; k < 22; k++ ){ | 
| 211 | for (Int_t l = 0; l < 96; l++ ){ | 
| 212 | fread(&mip[m][k][l],sizeof(mip[m][k][l]),1,f); | 
| 213 | calib.calped[m][k][l] = 0. ; | 
| 214 | evento.dexy[m][k][l] = 0. ; | 
| 215 | evento.dexyc[m][k][l] = 0. ; | 
| 216 | estrip[m][k][l] = 0.; | 
| 217 | estripnull[m][k][l] = 0.; | 
| 218 | einf[m][k][l] = 32000.; | 
| 219 | esup[m][k][l] = 0.; | 
| 220 | edelta[m][k][l] = 0.; | 
| 221 | }; | 
| 222 | }; | 
| 223 | }; | 
| 224 | } else { | 
| 225 | for (Int_t m = 0; m < 2 ; m++ ){ | 
| 226 | for (Int_t k = 0; k < 22; k++ ){ | 
| 227 | for (Int_t l = 0; l < 96; l++ ){ | 
| 228 | mip[m][k][l] = 26. ; | 
| 229 | calib.calped[m][k][l] = 0. ; | 
| 230 | evento.dexy[m][k][l] = 0. ; | 
| 231 | evento.dexyc[m][k][l] = 0. ; | 
| 232 | estrip[m][k][l] = 0.; | 
| 233 | einf[m][k][l] = 32000.; | 
| 234 | esup[m][k][l] = 0.; | 
| 235 | edelta[m][k][l] = 0.; | 
| 236 | }; | 
| 237 | }; | 
| 238 | }; | 
| 239 | }; | 
| 240 | if ( okcalo ) fclose(f); | 
| 241 | //    chfile->Close(); | 
| 242 | // | 
| 243 | // first of all find the calibrations in the file | 
| 244 | // | 
| 245 | Int_t wused = 0; | 
| 246 | CaloFindCalibs(filename, calcalibfile, wused, calib); | 
| 247 | if ( wused == 1 ) calcalibfile = filename; | 
| 248 | // | 
| 249 | // print on the screen the results: | 
| 250 | // | 
| 251 | const char *ffile; | 
| 252 | Int_t done = 0; | 
| 253 | Int_t rdone = 0; | 
| 254 | Int_t fcheck = 0; | 
| 255 | Int_t fdone = 0; | 
| 256 | //    Int_t nn = 0; | 
| 257 | ffile = filename; | 
| 258 | printf(" ------ %s ------- \n \n",ffile); | 
| 259 | Int_t calibex = 0; | 
| 260 | TString pfile; | 
| 261 | for (Int_t s=0; s<4;s++){ | 
| 262 | printf(" ** SECTION %i **\n",s); | 
| 263 | for (Int_t d = 0; d<51; d++){ | 
| 264 | if ( calib.ttime[s][d] != 0 ) { | 
| 265 | calibex++; | 
| 266 | if ( calib.fcode[s][d] != 10 ){ | 
| 267 | TString file2f = ""; | 
| 268 | stringcopy(file2f,calcalibfile,0,0); | 
| 269 | pfile = (TString)whatnamewith(file2f,calib.fcode[s][d]); | 
| 270 | } else { | 
| 271 | pfile = (TString)calcalibfile; | 
| 272 | }; | 
| 273 | const char *ffile; | 
| 274 | ffile = pfile; | 
| 275 | printf(" - from time %i to time %i use calibration at\n time %i, file: %s \n",calib.time[s][d],calib.time[s][d+1],calib.ttime[s][d],ffile); | 
| 276 | if ( !strcmp(ffile,"wrong") ) calibex--; | 
| 277 | }; | 
| 278 | }; | 
| 279 | printf("\n"); | 
| 280 | }; | 
| 281 | printf(" ----------------------------------------------------------------------- \n \n"); | 
| 282 | // | 
| 283 | if ( calibex < 4 ) { | 
| 284 | printf("No full calibration data in this file, sorry!\n\n "); | 
| 285 | // | 
| 286 | // remove the empty file! | 
| 287 | // | 
| 288 | stringstream remfile; | 
| 289 | remfile.str(""); | 
| 290 | remfile << "rm -f " << file2.str().c_str(); | 
| 291 | //      char *remfile; | 
| 292 | //remfile = Form("rm -f %s",file2.str().c_str()); | 
| 293 | gSystem->Exec(remfile.str().c_str()); | 
| 294 | return(4); | 
| 295 | }; | 
| 296 | // | 
| 297 | // calibrate before starting | 
| 298 | // | 
| 299 | for (Int_t s = 0; s < 4; s++){ | 
| 300 | b[s]=0; | 
| 301 | if ( calib.fcode[s][b[s]] != 10 ){ | 
| 302 | TString file2f = ""; | 
| 303 | stringcopy(file2f,calcalibfile,0,0); | 
| 304 | TString pfile = whatnamewith(file2f,calib.fcode[s][b[s]]); | 
| 305 | } else { | 
| 306 | TString pfile(calcalibfile); | 
| 307 | }; | 
| 308 | CaloPede(pfile,s,calib.ttime[s][b[s]],calib); | 
| 309 | }; | 
| 310 | // | 
| 311 | // run over all the events | 
| 312 | // | 
| 313 | printf("\n Processed events: \n\n"); | 
| 314 | // | 
| 315 | Int_t se = 5; | 
| 316 | bool isCOMP = 0; | 
| 317 | bool isFULL = 0; | 
| 318 | bool isRAW = 0; | 
| 319 | Int_t upnn = 0; | 
| 320 | Double_t prima = 0.; | 
| 321 | Double_t prmndp = 0.; | 
| 322 | calo = new CalorimeterLevel1(); | 
| 323 | for (Int_t i = 0; i < nevents; i++){ | 
| 324 | //for (Int_t i = 0; i < 1000; i++){ | 
| 325 | //calo = new pamela::calorimeter::CalorimeterLevel1(); | 
| 326 | evno = i; | 
| 327 | if ( i%1000 == 0 && i > 0 ) printf(" %iK \n",i/1000); | 
| 328 | // | 
| 329 | // | 
| 330 | // | 
| 331 | qtot = 0.; | 
| 332 | nstrip = 0.; | 
| 333 | // | 
| 334 | // read from the header of the event the absolute time at which it was recorded | 
| 335 | // | 
| 336 | otr->GetEntry(i); | 
| 337 | ph = eh->GetPscuHeader(); | 
| 338 | etime = ph->GetOrbitalTime(); | 
| 339 | // | 
| 340 | // for each event check that the calibration we are using are still within calibration limits, if not call the next calibration | 
| 341 | // | 
| 342 | if ( !calib.obtjump ) { | 
| 343 | for (Int_t s = 0; s < 4; s++){ | 
| 344 | if ( calib.ttime[s][b[s]] ){ | 
| 345 | while ( etime > calib.time[s][b[s]+1] ){ | 
| 346 | printf(" CALORIMETER: \n" ); | 
| 347 | printf(" - Section %i, event at time %i while old calibration time limit at %i. Use new calibration at time %i -\n",s,etime,calib.time[s][b[s]+1],calib.ttime[s][b[s]+1]); | 
| 348 | printf(" END CALORIMETER. \n\n" ); | 
| 349 | b[s]++; | 
| 350 | if ( calib.fcode[s][b[s]] != 10 ){ | 
| 351 | TString file2f = ""; | 
| 352 | stringcopy(file2f,calcalibfile,0,0); | 
| 353 | TString pfile = whatnamewith(file2f,calib.fcode[s][b[s]]); | 
| 354 | } else { | 
| 355 | TString pfile(calcalibfile); | 
| 356 | }; | 
| 357 | CaloPede(pfile,s,calib.ttime[s][b[s]],calib); | 
| 358 | }; | 
| 359 | }; | 
| 360 | }; | 
| 361 | }; | 
| 362 | // | 
| 363 | // do whatever you want with data | 
| 364 | // | 
| 365 | evento.iev = de->iev; | 
| 366 | // | 
| 367 | // run over views and planes | 
| 368 | // | 
| 369 | for (Int_t l = 0; l < 2; l++){ | 
| 370 | for (Int_t m = 0; m < 22; m++){ | 
| 371 | // | 
| 372 | // determine the section number | 
| 373 | // | 
| 374 | se = 5; | 
| 375 | if (l == 0 && m%2 == 0) se = 3; | 
| 376 | if (l == 0 && m%2 != 0) se = 2; | 
| 377 | if (l == 1 && m%2 == 0) se = 1; | 
| 378 | if (l == 1 && m%2 != 0) se = 0; | 
| 379 | // | 
| 380 | // determine what kind of event we are going to analyze | 
| 381 | // | 
| 382 | isCOMP = 0; | 
| 383 | isFULL = 0; | 
| 384 | isRAW = 0; | 
| 385 | if ( de->stwerr[se] & (1 << 16) ) isCOMP = 1; | 
| 386 | if ( de->stwerr[se] & (1 << 17) ) isFULL = 1; | 
| 387 | if ( de->stwerr[se] & (1 << 3) ) isRAW = 1; | 
| 388 | // | 
| 389 | // save the prevoius energy deposit and calibration in sbase, sdexy, sdexyc | 
| 390 | // | 
| 391 | Int_t pre = -1; | 
| 392 | if ( isRAW ){ | 
| 393 | for (Int_t nn = 0; nn < 96; nn++){ | 
| 394 | if ( nn%16 == 0 ) pre++; | 
| 395 | evento.base[l][m][pre] = calib.calbase[l][m][pre]; | 
| 396 | sdexy[l][m][nn] = evento.dexy[l][m][nn]; | 
| 397 | evento.dexy[l][m][nn] = de->dexy[l][m][nn] ; | 
| 398 | sdexyc[l][m][nn] = evento.dexyc[l][m][nn]; | 
| 399 | evento.dexyc[l][m][nn] = de->dexyc[l][m][nn] ; | 
| 400 | }; | 
| 401 | }; | 
| 402 | // | 
| 403 | // run over strips | 
| 404 | // | 
| 405 | pre = -1; | 
| 406 | for (Int_t n =0 ; n < 96; n++){ | 
| 407 | if ( n%16 == 0 ) { | 
| 408 | pre++; | 
| 409 | done = 0; | 
| 410 | rdone = 0; | 
| 411 | fdone = 0; | 
| 412 | }; | 
| 413 | // | 
| 414 | // baseline check and calculation | 
| 415 | // | 
| 416 | if ( !isRAW ) { | 
| 417 | // | 
| 418 | // if it isn't raw and we haven't checked yet, check that the baseline is fine, if not calculate it with a relaxed algorithm. | 
| 419 | // | 
| 420 | if ( !done ){ | 
| 421 | evento.base[l][m][pre] = de->base[l][m][pre] ; | 
| 422 | evento.dexyc[l][m][n] = de->dexyc[l][m][n] ; | 
| 423 | }; | 
| 424 | } else { | 
| 425 | // | 
| 426 | // if it is a raw event and we haven't checked yet, calculate the baseline. Then check that the baseline is fine, | 
| 427 | // if not calculate it with relaxed algorithm. | 
| 428 | // | 
| 429 | if ( !rdone ){ | 
| 430 | CaloFindBaseRaw(calib,evento,l,m,pre); | 
| 431 | tot1++; | 
| 432 | rdone = 1; | 
| 433 | }; | 
| 434 | }; | 
| 435 | // | 
| 436 | // no suitable new baseline, use old ones and compress data! | 
| 437 | // | 
| 438 | if ( !done && (evento.base[l][m][pre] == 31000. || evento.base[l][m][pre] == 0.) ){ | 
| 439 | tot0++; | 
| 440 | evento.base[l][m][pre] = calib.sbase[l][m][pre]; | 
| 441 | upnn = n+16; | 
| 442 | if ( upnn > 96 ) n = 96; | 
| 443 | for ( Int_t nn = n; nn<upnn; nn++ ){ | 
| 444 | evento.dexyc[l][m][nn] = de->dexyc[l][m][nn] ; | 
| 445 | }; | 
| 446 | CaloCompressData(calib,evento,l,m,pre); | 
| 447 | done = 1; | 
| 448 | }; | 
| 449 | // | 
| 450 | // if here we don't have a valid baseline we will skip the event. | 
| 451 | // | 
| 452 | if ( evento.base[l][m][pre] == 31000. ) tot2++; | 
| 453 | // | 
| 454 | //  check the baseline calculation in FULL mode: baseline recorded from DSP must be identical to the one calculated using RAW data. | 
| 455 | // | 
| 456 | if ( isFULL ) { | 
| 457 | if ( !fdone) { | 
| 458 | fdone = 1; | 
| 459 | if ( de->base[l][m][pre] > 0. && de->base[l][m][pre] < 32000. ) { | 
| 460 | fcheck = 0; | 
| 461 | for (Int_t nn = pre*16; nn < (pre+1)*16 ; nn++){ | 
| 462 | if ( de->dexy[l][m][nn] > 0. &&  de->dexy[l][m][nn] < 32000. ) fcheck++; | 
| 463 | }; | 
| 464 | if ( fcheck ) { | 
| 465 | memcpy(&evento2, &evento, sizeof(evento)); | 
| 466 | prima = evento.base[l][m][pre]; | 
| 467 | CaloFindBaseRaw(calib,evento2,l,m,pre); | 
| 468 | diffbas[l][m][pre] = 0.; | 
| 469 | if ( evento2.base[l][m][pre] != 31000. ) { | 
| 470 | prmndp = prima - evento2.base[l][m][pre]; | 
| 471 | if ( prmndp > 100000000. || prmndp < 100000000. ) prmndp = 0.; | 
| 472 | diffbas[l][m][pre] = (float)prmndp; | 
| 473 | calo->diffbas[l][m][pre] = (float)prmndp; | 
| 474 | if ( prmndp != 0. ) { | 
| 475 | baseDIFFfull++; | 
| 476 | //printf("differenza! %f %i %i %i %i %i \n",prmndp,i,l,m,pre,nn); | 
| 477 | //return; | 
| 478 | }; | 
| 479 | }; | 
| 480 | }; | 
| 481 | }; | 
| 482 | }; | 
| 483 | }; | 
| 484 | // | 
| 485 | // CALIBRATION ALGORITHM | 
| 486 | // | 
| 487 | basel = evento.base[l][m][pre]; | 
| 488 | ener = evento.dexyc[l][m][n]; | 
| 489 | estrip[l][m][n] = 0.; | 
| 490 | if ( ener > esup[l][m][n] && ener < 32000 ) esup[l][m][n] = ener; | 
| 491 | if ( ener < einf[l][m][n] && ener > 0 ) einf[l][m][n] = ener; | 
| 492 | if ( basel>0 && basel < 30000. && ener > 0. ){ | 
| 493 | estrip[l][m][n] = (ener - calib.calped[l][m][n] - basel)/mip[l][m][n] ; | 
| 494 | // | 
| 495 | // OK, now in estrip we have the energy deposit in MIP of all the strips for this event (at the end of loops of course) | 
| 496 | // | 
| 497 | //if (estrip[l][m][n]<0.1 ) printf(" %i %i %i here %f \n",l,m,n,estrip[l][m][n]); | 
| 498 | calo->good[l][m][n] = (int)calib.calgood[l][m][n]; | 
| 499 | if ( estrip[l][m][n] > evento.emin && calib.calgood[l][m][n] == 0 ) { | 
| 500 | qtot += estrip[l][m][n]; | 
| 501 | nstrip += 1.; | 
| 502 | }; | 
| 503 | }; | 
| 504 | calib.sbase[l][m][pre] = evento.base[l][m][pre]; | 
| 505 | }; | 
| 506 | }; | 
| 507 | }; | 
| 508 | // | 
| 509 | // per ogni evento... | 
| 510 | // | 
| 511 | calo->qtot = qtot; | 
| 512 | calo->nstrip = nstrip; | 
| 513 | calo->evno = evno; | 
| 514 | calo->nobase = tot2; | 
| 515 | memcpy(calo->stwerr, de->stwerr, sizeof(stwerr)); | 
| 516 | memcpy(calo->perror, de->perror, sizeof(perror)); | 
| 517 | memcpy(calo->calevnum, de->calevnum, sizeof(calevnum)); | 
| 518 | memcpy(calo->estrip, estrip, sizeof(estrip)); | 
| 519 | tree->Fill(); | 
| 520 | memcpy(estrip, estripnull, sizeof(estrip)); | 
| 521 | }; | 
| 522 | hfile->Write(); | 
| 523 | hfile->Close(); | 
| 524 | printf("\n"); | 
| 525 | gSystem->ChangeDirectory(startingdir); | 
| 526 | return(0); | 
| 527 | } | 
| 528 |  | 
| 529 |  | 
| 530 |  |