StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
L2Histo.cxx
1 #include <stdio.h>
2 #include <string.h>
3 #include <math.h>
4 /*********************************************************************
5  * $Id: L2Histo.cxx,v 1.6 2010/04/18 06:05:32 pibero Exp $
6  * \author Jan Balewski, IUCF, 2006
7  *********************************************************************
8  * Descripion:
9  * primitive 1-D or 2-D histograming I/O
10  * all indexes run [0,nb-1]
11  *********************************************************************
12  */
13 
14 #include "L2Histo.h"
15 
16 //=====================================
17 //=====================================
18 void
19 L2Histo::set( int idx, const char *tit, int nbx, int nby) {
20  if (!(idx>0 && nbx >0 && nby >0 && tit))
21  {
22  head.hid=1;
23  head.nBin=1;
24  head.nBinX=1;
25  head.nBinY=1;
26  head.dataSize=head.nBin*sizeof(int);
27  data=new int [head.nBin];
28  memset(data,0,head.dataSize);
29  head.title[0]=0;
30  strncpy(head.title,"set(): HISTOGRAM IS BROKEN IN. CONTACT EXPERT.",mxTx);
31  return;
32  }
33 
34  head.nOver=head.nUnder=0;
35  head.ver=version;
36  head.hid=idx;
37  head.nBin=nbx*nby;
38  head.nBinX=nbx;
39  head.nBinY=nby;
40  head.dataSize=head.nBin*sizeof(int);
41  data=new int [head.nBin];
42  memset(data,0,head.dataSize);
43  head.title[0]=0;
44  strncpy(head.title,tit,mxTx);
45 }
46 
47 //=====================================
48 //=====================================
49 void
50 L2Histo::setTitle(const char *tit){
51  head.title[0]=0;
52  if (!tit)
53  {
54  strncpy(head.title,"setTitle(): HISTOGRAM IS BROKEN. CONTACT EXPERT.",mxTx);
55  return;
56  }
57  strncpy(head.title,tit,mxTx);
58 }
59 
60 //=====================================
61 //=====================================
62 L2Histo::L2Histo(){
63  head.nOver=head.nUnder=-1;
64  head.ver=version;
65  head.hid=0;
66  head.nBin=0;
67  head.nBinX=head.nBin;
68  head.nBinY=1;
69  head.dataSize=0;
70  data=0;
71  head.title[0]=0;
72 }
73 
74 //=====================================
75 //=====================================
76 void
77 L2Histo::reset() {
78  head.nOver=head.nUnder=0;
79  if(head.dataSize>0) memset(data,0,head.dataSize);
80 }
81 
82 //=====================================
83 //=====================================
84 void
85 L2Histo::print( int flag, FILE *fd){
86  int dim=1;
87  if(head.nBinY>1) dim=2;
88  fprintf(fd," L2Histo::print h%d, %dD, tit='%s' head.nBin=%d nBinX=%d ver=%d\n", head.hid, dim, head.title, head.nBin, head.nBinX,head.ver);
89 
90  int i=0;
91  int sum=0;
92  for(i=0;i< head.nBin;i++) {
93  sum+= data[i];
94  if(flag) {
95  if(dim==1) {
96  fprintf(fd," bin=%2d value=%4d sum=%d\n",i, data[i],sum);
97  } else {
98  int ix=i%head.nBinX;
99  int iy=i/head.nBinX;
100  fprintf(fd," bin=%d ix=%d iy=%d value=%d \n",i,ix,iy, data[i]);
101  }
102  }
103  }
104  fprintf(fd," Counts: inRange=%d nUnder=%d, nOver=%d\n",sum, head.nUnder, head.nOver);
105 }
106 
107 
108 //=====================================
109 //=====================================
110 void
111 L2Histo::printCSV( FILE *fd){
112  if (!fd) {
113  printf("printCSV() passed bad output file!\n");
114  return;
115  }
116  fprintf(fd,"#L2H%d,%d,%s,", head.hid, head.nBin, head.title);
117  if(head.nBinY>1) {
118  fprintf(fd,"ny=%d,CVS format not supported for 2D histos,\n",head.nBinY);
119  return;
120  }
121  int i=0;
122 
123  for(i=0;i< head.nBin;i++) fprintf(fd,"%d,",data[i]);
124  fprintf(fd,"\n");
125  return;
126 }
127 
128 
129 //=====================================
130 //=====================================
131 void
132 L2Histo::fill( int bin){
133  /* should be: assert(head.nBinY==1)
134  but it is an online code - proceed, good luck
135  */
136  if(bin<0) { head.nUnder++; return;}
137  if(bin>=head.nBin) { head.nOver++; return;}
138  data[bin]++;
139 }
140 
141 
142 //=====================================
143 //=====================================
144 void
145 L2Histo::fillW( int bin, int w){
146  //Fill data[bin] with weight w.
147  /* should be: assert(head.nBinY==1)
148  but it is an online code - proceed, good luck
149  */
150  if(bin<0) { head.nUnder+=w; return;}
151  if(bin>=head.nBin) { head.nOver+=w; return;}
152  data[bin]+=w;
153 }
154 
155 //=====================================
156 //=====================================
157 void
158 L2Histo::fill( int binX, int binY){
159  /* will work fine for 1-D, unless binY is negative;
160  just computes too much
161  inverse is not true !
162  */
163  if(binX<0 || binY <0) { head.nUnder++; return;}
164  if(binX>=head.nBinX || binY>=head.nBinY) { head.nOver++; return;}
165  data[binY*head.nBinX+binX]++;
166 }
167 
168 //=====================================
169 //=====================================
170 void
171 L2Histo::fillW( int binX, int binY, int w){
172  /* will work fine for 1-D, unless binY is negative;
173  just computes too much
174  inverse is not true !
175  */
176  if(binX<0 || binY <0) { head.nUnder+=w; return;}
177  if(binX>=head.nBinX || binY>=head.nBinY) { head.nOver+=w; return;}
178  data[binY*head.nBinX+binX]+=w;
179 }
180 
181 //=====================================
182 //=====================================
183 void
184 L2Histo::write(FILE *fd, int dbg) {
185  if(fd==0) return;
186  if( head.nBin<=0) return;
187  if(dbg) print(dbg-1);
188  char *c;
189  unsigned int i;
190  //.... save histo header
191  c=(char *)&head;
192  for(i=0;i<sizeof(L2Histo::Head);i++) fputc(c[i],fd);
193 
194  //.... save histo data
195  c=(char *) data;
196  for(i=0;i< head.dataSize;i++) fputc(c[i],fd);
197 
198 }
199 
200 
201 //=====================================
202 //=====================================
203 int
204 L2Histo::read(FILE *fd, int dbg) {
205  if (!fd)
206  {
207  printf("L2Histo::read called with no file. Aborting\n");
208  return -1;
209  }
210  char *c;
211  unsigned int i;
212 
213  // printf("aa=%d\n",sizeof(*h));
214  //.... read histo header
215  c=(char *)&head;
216  for(i=0;i<sizeof(L2Histo::Head);i++) {
217  int val=fgetc(fd);
218  if(i==0 && val==EOF) return 1;
219  if(!(val!=EOF))
220  {
221  printf("L2Histo::read val==EOF. Aborting\n");
222  return -1;
223  }
224  c[i]=val;
225  }
226  // printf("rd ver %d %d \n", head.ver,version);
227  if (!( head.ver==version)) // change it in the future if header ever changes
228  {
229  printf("L2Histo::read head.ver!=version. Aborting\n");
230  return -1;
231  }
232  if (!( head.nBin>0))
233  {
234  printf("L2Histo::read head.nBin<=0. Aborting\n");
235  return -1;
236  }
237  if (!( head.dataSize== head.nBin*sizeof(int)))
238  {
239  printf("L2Histo::read head.dataSize!= head.nBin*sizeof(int). Aborting\n");
240  return -1;
241  }
242 
243  data=new int [head.dataSize];
244  memset( data,0, head.dataSize);
245 
246  //.... read histo data
247  c=(char *) data;
248  for(i=0;i< head.dataSize;i++) {
249  int val=fgetc(fd);
250  if(dbg)printf("i=%d val=%d\n",i,val);
251  if(i==0 && val==EOF) return 1;
252  if(!(val!=EOF))
253  {
254  printf("L2Histo::read val==EOF. Aborting\n");
255  return -1;
256  }
257  c[i]=val;
258  }
259 
260  if(dbg) printf("got histo hid=%d , head.nBin=%d, tit='%s'\n", head.hid, head.nBin, head.title);
261 
262  if(dbg) print(1);
263  return 0;
264 }
265 
266 
267 /*========================================
268  ======================================== */
269 bool
270 L2Histo::findMax( int *iMax, int *iFWHM) {
271  // returns true if both max & FWHM make sense
272  *iMax=*iFWHM=-1;
273 
274  /* finds pedestal & FWHM */
275  int maxVal=-1, maxJ=-1;
276  int j;
277  for(j=0; j<head.nBin;j++) {
278  // printf("j=%d maxVal=%d maxJ=%d yield=%d\n",j,maxVal, maxJ,data[j]);
279  if(data[j]<=maxVal) continue;
280  maxVal=data[j];
281  maxJ=j;
282  }
283 
284  if(maxJ<0) return false; /* no maximum found */
285 
286  *iMax=maxJ; // maximum was found
287 
288  if(head.nBinY>1) { // FWHM makes no sense for 2D plots
289  *iMax=maxJ;
290  *iFWHM=999;
291  return true;
292  }
293 
294 
295  // search for FWHM
296  int halfMax=maxVal/2;
297  int j1=-1, j2=-1;
298  for(j=maxJ+1; j<head.nBin;j++) {// forward
299  if(data[j]>halfMax) continue;
300  j2=j;
301  break;
302  }
303 
304  for(j=maxJ-1; j>=0;j--) { // backward
305  if(data[j]>halfMax) continue;
306  j1=j;
307  break;
308  }
309  if(j1<0 || j2<0) return false; /* FWHM is 0 ? */
310 
311 
312  *iFWHM=(j2-j1);
313 
314  return true;
315 }
316 
317 /*========================================
318  ======================================== */
319 bool
320 L2Histo::findMean( int *iMean, int *iRMS) {
321  // returns true if both mean & RMS make sense
322 
323  *iMean=*iRMS=-1;
324  if (head.nBinY>1)
325  return false; //this method doesn't work for 2d plots
326  /* finds mean & RMS without counting overflows */
327  int totalVal=0, weightedVal=0, meanJ=-1, rms=-1;
328  int j;
329  for(j=0; j<head.nBin;j++) {
330  // printf("j=%d maxVal=%d maxJ=%d yield=%d\n",j,maxVal, maxJ,data[j]);
331  weightedVal+=data[j]*j;
332  totalVal+=data[j];
333  }
334  if (totalVal>0) meanJ=weightedVal/totalVal;
335  if(meanJ<0) return false; /* no maximum found */
336 
337  *iMean=meanJ; // mean was found
338 
339  // search for RMS
340  weightedVal=0;
341  for(j=0; j<head.nBin;j++) {
342  // printf("j=%d maxVal=%d maxJ=%d yield=%d\n",j,maxVal, maxJ,data[j]);
343  weightedVal+=data[j]*(j-meanJ)*(j-meanJ);
344  }
345  rms=weightedVal/totalVal;
346 
347  *iRMS=rms;
348  return true;
349 }
350 
351 //=====================================
352 //=====================================
353 void
354 L2Histo::printPed( FILE *fd, int x0, int x1,char term){
355  if(head.nBinY>1) {
356  fprintf(fd," printped NOT implemented for 2D histos: hid=%d tit=%s\n",head.hid, head.title);
357  return;
358  }
359  int j;
360  for(j=0; j<head.nBin;j++) {
361  int adc=x0+j;
362  if(adc>=x1) break;
363  float val=data[j];
364  if(val<=0) { // print grid for empty bins
365  if(adc==0)
366  fprintf(fd,"*");
367  else if(adc==10 )
368  fprintf(fd,">");
369  else if(adc==-10 )
370  fprintf(fd,"<");
371  else if(adc%10==0)
372  fprintf(fd,",");
373  else
374  fprintf(fd,".");
375  continue;
376  }
377  // print yield for populated bins
378 
379  fprintf(fd,"%c",y2c(val));
380  }
381 
382  // sum higher bins t print overflow
383  int sum=head.nOver;
384  for(j=x1; j<head.nBin;j++) sum+=data[j];
385 
386  fprintf(fd,"ov=%d %c",sum,term);
387 }
388 
389 //=====================================
390 //=====================================
391 char
392 L2Histo::y2c(float val){
393  float valLog=log(val);
394  char k='?';
395  if(valLog<0.)
396  k='-';
397  else if(valLog<9)
398  k='1'+(int)valLog;
399  else
400  k='a'+(int)(valLog-9);
401  return k;
402 }
403 
404 
405 
406 /*
407 *********************************************************************
408  $Log: L2Histo.cxx,v $
409  Revision 1.6 2010/04/18 06:05:32 pibero
410  Address compiler warnings.
411 
412  Revision 1.5 2010/04/17 16:42:09 pibero
413  *** empty log message ***
414 
415  Revision 1.4 2008/01/16 23:32:33 balewski
416  toward token dependent compute()
417 
418  Revision 1.3 2008/01/10 22:45:39 balewski
419  reduce memory allocation for every histo
420 
421  Revision 1.2 2007/11/14 03:58:07 balewski
422  cleanup of common timing measurement
423 
424  Revision 1.1 2007/10/11 00:33:14 balewski
425  L2algo added
426 
427  Revision 1.3 2006/03/28 19:33:23 balewski
428  ver16b , in L2new
429 
430  Revision 1.2 2006/03/11 17:08:32 balewski
431  now CVS comments should work
432 
433 */
434