-
Notifications
You must be signed in to change notification settings - Fork 62
/
StTpcHitMaker.cxx
1466 lines (1453 loc) · 52.7 KB
/
StTpcHitMaker.cxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/***************************************************************************
*
* $Id: StTpcHitMaker.cxx,v 1.82 2021/05/10 21:13:19 fisyak Exp $
*
* Author: Valeri Fine, BNL Feb 2007
***************************************************************************
*
* Description: Fill the StEvent from the DAQ clusters
*
* Input: DAQReader
* Output: StTpcHit collection added to StEvent
*
***************************************************************************
*
* $Log: StTpcHitMaker.cxx,v $
* Revision 1.82 2021/05/10 21:13:19 fisyak
* Clean up
*
* Revision 1.81 2020/03/20 02:25:35 genevb
* Only look for StEvent when needed, e.g. not for raw modes such as in embedding
*
* Revision 1.80 2020/02/24 23:15:06 genevb
* Faster Afterburner(), Remove compiler ambiguity on double vs. float in TMath::Min,Max()
*
* Revision 1.79 2020/02/20 18:36:54 genevb
* Reduce time-expenseive calls to GetInputDS(), some coverity cleanup
*
* Revision 1.78 2019/05/11 02:20:34 genevb
* Add TPC-dead status handling
*
* Revision 1.77 2019/03/22 18:08:46 fisyak
* recover skip of legacy if exists Tpx or iTpc. Checked by Irakli
*
* Revision 1.76 2019/03/01 15:50:20 fisyak
* Fix bug. 3385
*
* Revision 1.75 2019/02/14 17:40:39 fisyak
* Fix selection for row number (Thanks Iraklii for checking)
*
* Revision 1.74 2018/10/17 20:45:27 fisyak
* Restore update for Run XVIII dE/dx calibration removed by Gene on 08/07/2018
*
* Revision 1.72 2018/06/22 18:35:19 perev
* Merging with TPC group code
*
* Revision 1.55 2018/02/18 23:35:33 perev
* Remove iTPC update
*
* Revision 1.53 2015/04/09 19:54:03 genevb
* Introduce sector masking (only MTD-based so far)
*
* Revision 1.52 2015/03/02 21:10:15 genevb
* pad and timebucket sanity units were off by x64, mistakenly using units of StTpcHit data members (RT 3507)
*
* Revision 1.51 2014/06/26 21:31:41 fisyak
* New Tpc Alignment, v632
*
* Revision 1.49 2013/04/07 21:58:36 fisyak
* Move selection of sector range from InitRun to Init, add cluster averaging based on TH3
*
* Revision 1.48 2013/01/29 23:28:16 fisyak
* comment out occupancy print outs
*
* Revision 1.47 2013/01/28 20:26:50 fisyak
* Simplify loop over clusters
*
* Revision 1.46 2012/12/06 14:33:47 fisyak
* Keep only clusters with flag == 0 or FCF_ONEPAD | FCF_MERGED | FCF_BIG_CHARGE. Tonko's instruction
*
* Revision 1.45 2012/11/20 22:55:56 fisyak
* Set the same cuts for online cluster maker as for offline one
*
* Revision 1.44 2012/10/24 13:36:06 fisyak
* Increase no. of pad rows
*
* Revision 1.43 2012/09/13 21:00:04 fisyak
* Corrections for iTpx, clean up
*
* Revision 1.42 2012/05/07 15:51:01 fisyak
* Remove hard coded TPC numbers
*
* Revision 1.41 2011/06/09 20:52:08 genevb
* Set sanity flag
*
* Revision 1.40 2011/04/07 23:33:12 genevb
* Restore to version before previous commit
*
* Revision 1.38 2011/03/31 19:31:12 fisyak
* Add adc to Tpc hit
*
* Revision 1.37 2011/03/08 18:20:44 genevb
* Limit on number of hits starting at time bin 0
*
* Revision 1.36 2011/01/21 18:35:25 fisyak
* change flag type from UChar_t to UShort_t
*
* Revision 1.35 2011/01/20 18:26:30 genevb
* Add FCF_flags include, and exclude any flagged hit from AfterBurner()
*
* Revision 1.34 2010/11/05 16:25:19 genevb
* No longer include hits found on dead padrows
*
* Revision 1.33 2010/11/04 19:39:12 genevb
* Maintain backward reproducibility
*
* Revision 1.32 2010/11/04 18:30:47 genevb
* Typo correction
*
* Revision 1.31 2010/11/04 18:29:58 genevb
* Max hits scaling does not need to use PadGainT0 table
*
* Revision 1.30 2010/10/04 19:06:56 fisyak
* Use FCF flag definition
*
* Revision 1.29 2010/09/08 15:44:41 genevb
* Slightly better arrangement for limiting excessive TPC events
*
* Revision 1.28 2010/09/01 21:14:33 fisyak
* Add codes for S-shape correction (disactivated)
*
* Revision 1.27 2010/08/31 15:19:36 genevb
* Lower bound on reduced hit maxima
*
* Revision 1.26 2010/08/31 14:16:30 genevb
* Correct mistake from prev commit of location of TPC cluster check
*
* Revision 1.25 2010/08/30 18:02:01 genevb
* Introduce hit maxima for tracking
*
* Revision 1.24 2010/08/02 23:06:15 fisyak
* Fix format
*
* Revision 1.23 2010/03/25 15:05:54 fisyak
* Add AfterBurner
*
* Revision 1.22 2010/02/19 23:36:08 fisyak
* Add hit Id
*
* Revision 1.21 2010/01/12 22:54:36 fisyak
* Propagate flags from online clustering into StEvent
*
* Revision 1.20 2009/11/18 14:29:02 fisyak
* Restore slewing correction
*
* Revision 1.19 2009/11/10 21:05:08 fisyak
* Add attributes for sector and pad row selections
*
* Revision 1.18 2009/09/11 22:11:58 genevb
* Introduce TPC slewing corrections
*
* Revision 1.17 2009/03/18 14:21:06 fisyak
* Move sector check under condition that there is some TPC data
*
* Revision 1.16 2009/03/17 19:19:21 fisyak
* Account new Valery's interface for adc values
*
* Revision 1.15 2009/03/16 13:41:45 fisyak
* Switch to new scheme (avoid legacy) for TPX cluster reading
*
* Revision 1.14 2009/03/11 18:38:20 fisyak
* Add 22 time bins to account subtracted by Tonko, clean up
*
* Revision 1.13 2009/02/20 22:06:15 fisyak
* Restore access to TPX
*
* Revision 1.12 2008/12/29 23:58:06 fine
* Optimize the DAQ data access
*
* Revision 1.11 2008/12/29 21:14:41 fine
* Sort out the tps/tpc data handling
*
* Revision 1.10 2008/12/29 18:23:48 fine
* avoid using the dummy data
*
* Revision 1.9 2008/12/18 20:20:25 fine
* access two different detectors tpx/tpc
*
* Revision 1.8 2008/12/17 23:27:04 fine
* Clean up
*
* Revision 1.7 2008/12/17 23:26:00 fine
* Adjust the sector number
*
* Revision 1.6 2008/12/17 02:04:28 fine
* fix the sector number to make the new interface happy
*
* Revision 1.5 2008/12/16 20:43:25 fine
* add the DAQ_READER compliant access to the tpx sector
*
* Revision 1.4 2008/12/15 21:04:01 fine
* For for the NEW_DAQ_READER
*
* Revision 1.3 2008/07/31 20:45:26 fisyak
* Add TpcMixer
*
* Revision 1.2 2008/06/23 20:13:53 fisyak
* Add real data pixel annotation
*
* Revision 1.1.1.1 2008/05/27 14:22:41 fisyak
* Maker to access TPC DAQ information via EVP_READER
*
* Revision 1.3 2008/05/27 14:18:18 fisyak
* Freeze before moving to STAR repository
*
* Revision 1.2 2008/04/28 14:37:15 fisyak
* Rearrage TpcHitMaker to make it run for parallel taks, add the first version of online clustering
*
* Revision 1.1.1.1 2008/04/03 20:16:41 fisyak
* Initial version
*
* Revision 1.9 2008/01/29 02:44:38 fine
* INFO
*
* Revision 1.8 2008/01/29 02:42:31 fine
* remove 16th sector constarin. EVP_READER can read all of them alone now.
*
* Revision 1.7 2008/01/28 23:48:39 fine
* use the new base class
*
* Revision 1.6 2008/01/10 01:12:49 fine
* makr to use the full TPC + TPX
*
* Revision 1.5 2008/01/09 15:16:48 fine
* Correct the sector number
*
* Revision 1.4 2008/01/09 00:43:29 fine
* Working version. It can be used as the protopty for anither maker that calles RTS_READER to fill the 16-th TPX sector
*
* Revision 1.3 2008/01/07 19:04:07 fine
* Add the interface to access the DAQ clusters
*
* Revision 1.2 2008/01/07 17:37:39 fine
* check for tpcHitCollection and new StTpcHit object
*
* Revision 1.1 2008/01/04 17:52:32 fine
* New maker to populate the StEvent from the tpc structure filled by the new EVP_READER package
*
*
* StTpcHitMaker - class to fille the StEvewnt from DAQ reader
*
**************************************************************************/
//#define __MAKE_NTUPLE__
//#define __CORRECT_S_SHAPE__
//#define __TOKENIZED__
//#define __USE__THnSparse__
#include <assert.h>
#include "StEvent/StTpcHit.h"
#include <algorithm>
#include "StTpcHitMaker.h"
#include "TDataSetIter.h"
#include "StDAQMaker/StDAQReader.h"
#include "TError.h"
#include "string.h"
#include "StEvent.h"
#include "StEvent/StTpcHitCollection.h"
#include "StEvent/StTpcHit.h"
#include "RTS/src/DAQ_TPX/tpxFCF_flags.h" // for FCF flag definition
#include "StTpcRawData.h"
#include "StThreeVectorF.hh"
#include "StDaqLib/TPC/trans_table.hh"
#include "StRtsTable.h"
#include "StDbUtilities/StTpcCoordinateTransform.hh"
#include "StTpcDb/StTpcDb.h"
#include "StDbUtilities/StCoordinates.hh"
#include "StDetectorDbMaker/St_tss_tssparC.h"
#include "StDetectorDbMaker/St_tpcSlewingC.h"
#ifdef __CORRECT_S_SHAPE__
#include "StDetectorDbMaker/St_TpcPadCorrectionC.h"
#endif /* __CORRECT_S_SHAPE__ */
#include "StDetectorDbMaker/St_tpcPadGainT0BC.h"
#include "StDetectorDbMaker/St_tpcAnodeHVavgC.h"
#include "StDetectorDbMaker/St_tpcMaxHitsC.h"
#include "StDetectorDbMaker/StDetectorDbTpcRDOMasks.h"
#include "StDetectorDbMaker/St_tpcPadConfigC.h"
#include "StDetectorDbMaker/St_tpcStatusC.h"
#include "TFile.h"
#include "TNtuple.h"
#include "TH2.h"
#include "St_tpc_cl.h"
TableClassImpl(St_tpc_cl,tcl_cl);
#include "St_daq_cld.h"
TableClassImpl(St_daq_cld,tcl_cl);
#include "St_daq_sim_cld.h"
TableClassImpl(St_daq_sim_cld,tcl_cl);
#include "St_daq_adc_tb.h"
TableClassImpl(St_daq_adc_tb,daq_adc_tb);
#include "St_daq_sim_adc_tb.h"
TableClassImpl(St_daq_sim_adc_tb,daq_sim_adc_tb);
ClassImp(StTpcHitMaker);
static TNtuple *pulserP = 0;
Float_t StTpcHitMaker::fgDp = .1; // hardcoded errors
Float_t StTpcHitMaker::fgDt = .2;
Float_t StTpcHitMaker::fgDperp = .1;
Bool_t StTpcHitMaker::fgCosmics = kFALSE;
static Int_t _debug = 0;
#ifdef __TOKENIZED__
#define __NOT_ZERO_SUPPRESSED_DATA__
#endif
//#define __NOT_ZERO_SUPPRESSED_DATA__
#ifdef __NOT_ZERO_SUPPRESSED_DATA__
#include "StDetectorDbMaker/St_tpcPedestalC.h"
#endif
static const Char_t *Names[StTpcHitMaker::kAll] = {"undef",
"tpc_hits","tpx_hits","itpc_hits",
"TpcPulser","TpxPulser","iTPCPulser",
"TpcRaw","TpxRaw","iTPCRaw",
"TpcAvLaser","TpxAvLaser","tpc_hitsO"};
//_____________________________________________________________
StTpcHitMaker::StTpcHitMaker(const char *name) : StRTSBaseMaker("tpc",name), kMode(kUndefined),
kReaderType(kUnknown), mQuery(""), fTpc(0), fAvLaser(0), fSectCounts(0), fThr(0), fSeq(0) {
SetAttr("minSector",1);
SetAttr("maxSector",24);
SetAttr("minRow",1);
SetAttr("UseTonkoClusterAnnotation",1);
}
//_____________________________________________________________
Int_t StTpcHitMaker::Init() {
LOG_INFO << "StTpcHitMaker::Init as\t" << GetName() << endm;
TString MkName(GetName());
for (Int_t k = 1; k < kAll; k++) {
if (MkName.CompareTo(Names[k],TString::kIgnoreCase) == 0) {kMode = (EMode) k; break;}
}
assert(kMode);
memset(maxHits,0,sizeof(maxHits));
maxBin0Hits = 0;
bin0Hits = 0;
return kStOK ;
}
//________________________________________________________________________________
void StTpcHitMaker::InitializeHistograms(Int_t token) {
static Int_t oldToken = -1;
Int_t newToken = token/10;
if (newToken == oldToken) return;
TFile *f = GetTFile();
if (! f) {gMessMgr->Error() << "with Tpx/Tpc AvLaser you must provide TFile as the 5-th parameter in bfc.C macro" << endm; assert(0);}
f->cd();
if (oldToken >= 0) {
if (fSectCounts) {fSectCounts->Write(); delete fSectCounts;}
if (fAvLaser) {
for (Int_t s = 1; s <= 24; s++) {
if (fAvLaser[s-1]) {fAvLaser[s-1]->Write(); delete fAvLaser[s-1];}
}
delete [] fAvLaser; fAvLaser = 0;
}
}
enum {NoDim = 3};
const Char_t *NameV[NoDim] = { "row", "pad","time"};
const Double_t xMin[NoDim] = {0.5 , 0.5, -0.5};
const Double_t xMax[NoDim] = {0.5+St_tpcPadConfigC::instance()->numberOfRows(20), 182.5, 399.5};
Int_t nBins[NoDim] = { St_tpcPadConfigC::instance()->numberOfRows(20), 182, 400};
fSectCounts = new TH1F(Form("SectorCounts_%03i",newToken),"Count no. of sectors",25,-0.5,24.5);
#ifdef __USE__THnSparse__
fAvLaser = new THnSparseF *[24];
for (Int_t s = 1; s <= 24; s++) {
fAvLaser[s-1] = new THnSparseF(Form("AvLaser_%02i_%03i",s,newToken), Form("Averaged laser event for sector %02i for token %03i",s,newToken),
NoDim, nBins, xMin, xMax);
// fAvLaser[s-1]->CalculateErrors(kTRUE);
for (Int_t i = 0; i < NoDim; i++) {
fAvLaser[s-1]->GetAxis(i)->SetName(NameV[i]);
}
f->Add(fAvLaser[s-1]);
}
#else /* ! __USE__THnSparse__ */
fAvLaser = new TH3F *[24];
TH1::SetDefaultSumw2(kTRUE);
for (Int_t s = 1; s <= 24; s++) {
TString name(Form("AvLaser_%02i",s));
if (newToken) name += Form("_%03i",newToken);
fAvLaser[s-1] = new TH3F(name, Form("Averaged laser event for sector %02i for token %03i",s,newToken),
nBins[0],xMin[0],xMax[0],
nBins[1],xMin[1],xMax[1],
nBins[2],xMin[2],xMax[2]);
fAvLaser[s-1]->GetXaxis()->SetTitle(NameV[0]);
fAvLaser[s-1]->GetYaxis()->SetTitle(NameV[1]);
fAvLaser[s-1]->GetZaxis()->SetTitle(NameV[2]);
}
#endif /* __USE__THnSparse__ */
oldToken = newToken;
}
//________________________________________________________________________________
Int_t StTpcHitMaker::InitRun(Int_t runnumber) {
SetAttr("maxRow",St_tpcPadConfigC::instance()->numberOfRows(20));
if (IAttr("Cosmics")) SetCosmics();
// Prepare scaled hit maxima
// No hit maxima if these DB params are 0
Int_t maxHitsPerSector = St_tpcMaxHitsC::instance()->maxSectorHits();
Int_t maxBinZeroHits = St_tpcMaxHitsC::instance()->maxBinZeroHits();
Int_t livePads = 0;
Int_t totalPads = 0;
Float_t liveFrac = 1;
for(Int_t sector=1;sector<=24;sector++) {
Int_t liveSecPads = 0;
Int_t totalSecPads = 0;
if (maxHitsPerSector > 0 || maxBinZeroHits > 0) {
for(Int_t row=1;row<=St_tpcPadConfigC::instance()->numberOfRows(sector);row++) {
Int_t numPadsAtRow = St_tpcPadConfigC::instance()->padsPerRow(sector,row);
totalSecPads += numPadsAtRow;
if (StDetectorDbTpcRDOMasks::instance()->isRowOn(sector,row,1) &&
St_tpcAnodeHVavgC::instance()->livePadrow(sector,row))
liveSecPads += numPadsAtRow;
}
livePads += liveSecPads;
totalPads += totalSecPads;
}
if (maxHitsPerSector > 0) {
liveFrac = TMath::Max(0.1f,
((Float_t) liveSecPads) / (1e-15f + (Float_t) totalSecPads));
maxHits[sector-1] = (Int_t) (liveFrac * maxHitsPerSector);
if (Debug()) {LOG_INFO << "maxHits in sector " << sector
<< " = " << maxHits[sector-1] << endm;}
} else {
maxHits[sector-1] = 0;
if (Debug()) {LOG_INFO << "No maxHits in sector " << sector << endm;}
}
}
if (maxBinZeroHits > 0) {
liveFrac = TMath::Max(0.1f,
((Float_t) livePads) / ((Float_t) totalPads));
maxBin0Hits = (Int_t) (liveFrac * maxBinZeroHits);
if (Debug()) {LOG_INFO << "maxBinZeroHits " << maxBin0Hits << endm;}
} else {
maxBin0Hits = 0;
if (Debug()) {LOG_INFO << "No maxBinZeroHits" << endm;}
}
// write event header for AvLaser
if (kMode == kTpxAvLaser || kMode == kTpcAvLaser) {
StEvtHddr *header = GetEvtHddr();
if (header) {
TFile *f = GetTFile();
if (! f) {gMessMgr->Error() << "with Tpx/Tpc AvLaser you must provide TFile as the 5-th parameter in bfc.C macro" << endm; assert(0);}
f->cd();
header->Write();
}
}
return kStOK;
}
//_____________________________________________________________
Int_t StTpcHitMaker::Make() {
if (St_tpcStatusC::instance()->isDead()) {
LOG_WARN << "TPC status indicates it is unusable for this event. Ignoring hits." << endm;
return kStOK;
}
static Int_t minSector = IAttr("minSector");
static Int_t maxSector = IAttr("maxSector");
static Int_t minRow = IAttr("minRow");
static Int_t maxRow = IAttr("maxRow");
if (kMode == kTpxAvLaser || kMode == kTpcAvLaser) {
#ifdef __TOKENIZED__
InitializeHistograms(Token());
#else
InitializeHistograms(0);
#endif
}
StMaker* maskMk = GetMakerInheritsFrom("StMtdTrackingMaskMaker");
unsigned int mask = (maskMk ? maskMk->UAttr("TpcSectorsByMtd") : ~0U); // 24 bit masking for sectors 1..24
bin0Hits = 0;
if (fSectCounts) fSectCounts->Fill(0);
static const Char_t *tpcDataNames[5] = {0,"tpc/legacy","tpx/legacy","tpx","itpc"};
TString cldadc("cld");
if ( kMode == kTpxRaw || kMode == kTpcRaw || kMode == kiTPCRaw ||
kMode == kTpcAvLaser || kMode == kTpxAvLaser) cldadc = "adc";
for (Int_t sector = minSector; sector <= maxSector; sector++) {
if (!((1U<<(sector-1)) & mask)) continue; // sector masking
fId = 0;
// invoke tpcReader to fill the TPC DAQ sector structure
Int_t hitsAdded = 0;
Int_t kMin = kUnknown;
for (Int_t k = kStandardiTPC; k > kMin; k--) {
if (k > kLegacyTpx)
mQuery = Form("%s/%s[%i]",tpcDataNames[k],cldadc.Data(),sector);
else
mQuery = Form("%s[%i]",tpcDataNames[k],sector);
StRtsTable *daqTpcTable = GetNextDaqElement(mQuery);
if (! daqTpcTable) continue;
// Int_t Nrows = daqTpcTable->GetNRows();
// if (! Nrows) continue;
kReaderType = (EReaderType) k;
if (kReaderType > kLegacyTpx) kMin = kLegacyTpx;
while (daqTpcTable) {
if (Sector() == sector) {
if (Debug()/100 > 0) {
daqTpcTable->Print(0,10);
}
if (daqTpcTable->GetNRows()) {
fTpc = 0;
if (kReaderType == kLegacyTpx || kReaderType == kLegacyTpc) fTpc = (tpc_t*)*DaqDta()->begin();
Int_t row = RowNumber();
if (row >= minRow && row <= maxRow) {
if (Debug()) {
LOG_INFO << "StTpcHitMaker::Make(" << Names[kMode] << ") => " << tpcDataNames[k] << " for sector = " << sector << " row = " << row << endm;
}
switch (kMode) {
case kTpc:
case kiTPC:
case kTpxO:
case kTpx: hitsAdded += UpdateHitCollection(sector); break;
case kTpcPulser:
case kTpxPulser: if (fTpc) DoPulser(sector); break;
case kTpcAvLaser:
case kTpxAvLaser:
if ( fTpc) TpcAvLaser(sector);
else TpxAvLaser(sector);
fSectCounts->Fill(sector);
break;
case kTpcRaw:
case kTpxRaw:
case kiTPCRaw:
if ( fTpc) RawTpcData(sector);
else RawTpxData(sector);
break;
default:
break;
}
}
}
}
daqTpcTable = GetNextDaqElement(mQuery);
}
} // Loop over ReaderType
if (maxHits[sector-1] && hitsAdded > maxHits[sector-1]) {
LOG_ERROR << "Too many hits (" << hitsAdded << ") in one sector ("
<< sector << "). Skipping event." << endm;
return kStSkip;
}
}
if (maxBin0Hits && bin0Hits > maxBin0Hits) {
LOG_ERROR << "Too many hits (" << bin0Hits
<< ") starting at time bin 0. Skipping event." << endm;
return kStSkip;
}
if (kMode == kTpc || kMode == kTpx || kMode == kTpxO) { // || kMode == kiTPC) { --> no after burner for iTpc
StEvent *pEvent = dynamic_cast<StEvent *> (GetInputDS("StEvent"));
if (Debug()) {LOG_INFO << "StTpcHitMaker::Make : StEvent has been retrieved " <<pEvent<< endm;}
if (! pEvent) {LOG_INFO << "StTpcHitMaker::Make : StEvent has not been found " << endm; return kStWarn;}
StTpcHitCollection *hitCollection = pEvent->tpcHitCollection();
if (hitCollection && ! IAttr("NoTpxAfterBurner")) AfterBurner(hitCollection);
}
if (IAttr("CheckThrSeq") && (kMode == kTpcRaw || kMode == kTpxRaw || kMode == kiTPCRaw)) {
CheckThrSeq();
}
return kStOK;
}
//_____________________________________________________________
void StTpcHitMaker::CheckThrSeq() {
if (! fThr || !fSeq) {
fThr = new TH2C("Thr","ADC Thresold value versus sector and row",24,0.5,24.5,72,0.5,72.5); fThr->SetDirectory(0);
fSeq = new TH2C("Seq","ADC sequnce value versus sector and row",24,0.5,24.5,72,0.5,72.5); fSeq->SetDirectory(0);
for (Int_t s = 1; s <= 24; s++)
for (Int_t r = 1; r <= 72; r++) {
fThr->SetBinContent(s,r,127);
fSeq->SetBinContent(s,r,127);
}
}
for (Int_t s = 1; s <= 24; s++){
StTpcDigitalSector *digitalSector = GetDigitalSector(s);
if (! digitalSector) continue;
Int_t Nrows = digitalSector->numberOfRows();
for (Int_t r = 1; r <= Nrows; r++) {
Int_t Npads = digitalSector->numberOfPadsInRow(r);
for (Int_t p = 1; p <= Npads; p++) {
Int_t ntb = digitalSector->numberOfTimeBins(r,p);
if (! ntb) continue;
digitalSector->getTimeAdc(r,p,ADCs,IDTs);
Int_t adcMin = 127;
Int_t seq = 127;
Int_t tbF = -1, tbL = -1;
for (Int_t tb = 0; tb < __MaxNumberOfTimeBins__; tb++) {
if (! ADCs[tb]) {
if (tbF > -1 && tbL >= tbF) {
if (seq > tbL - tbF + 1) seq = tbL - tbF + 1;
}
tbF = tbL = -1;
continue;
}
if (ADCs[tb] < adcMin) {
adcMin = TMath::Max(ADCs[tb-2],TMath::Max(ADCs[tb-1],TMath::Max(ADCs[tb],TMath::Max(ADCs[tb+1],ADCs[tb+1]))));
}
if (tbF < 0) tbF = tb;
tbL = tb;
}
if (adcMin < 127 && seq < 127) {
if (seq == 1 && adcMin == 1) {
static Int_t ibreak = 0;
ibreak++;
}
Char_t th = fThr->GetBinContent(s,r);
if (th > adcMin) fThr->SetBinContent(s,r, adcMin);
Char_t sq = fSeq->GetBinContent(s,r);
if (sq > seq) fSeq->SetBinContent(s,r, seq);
}
}
}
}
}
//_____________________________________________________________
Int_t StTpcHitMaker::Finish() {
#ifdef __USE__THnSparse__
if (GetTFile() && fAvLaser) {
for (Int_t sector = 1; sector <= 24; sector++) {
if (fAvLaser[sector-1]) {
THnSparseF *hnew = CompressTHn(fAvLaser[sector-1]);
GetTFile()->Remove(fAvLaser[sector-1]);
delete fAvLaser[sector-1];
fAvLaser[sector-1] = hnew;
GetTFile()->Add(fAvLaser[sector-1]);
}
}
}
#endif /* __USE__THnSparse__ */
if (fThr && fSeq) {
Int_t adcMinFL = 127;
Int_t seqFL = 127;
Int_t s1 = -1, s2 = -1, r1 = -1, r2 = -1;
for (Int_t s = 1; s <= 24; s++){
for (Int_t r = 1; r <= 72; r++) {
Int_t adcMin = fThr->GetBinContent(s,r);
Int_t seq = fSeq->GetBinContent(s,r);
if (adcMin == 127 || seq == 127) continue;
if (adcMinFL == 127 && seqFL == 127) {
adcMinFL = adcMin;
seqFL = seq;
s1 = s2 = s;
r1 = r2 = r;
} else {
if (adcMinFL == adcMin && seqFL == seq) {
r2 = r;
s2 = s;
} else {
LOG_INFO << "StTpcHitMaker::Finish CheckThrSeq in sectors [" << s1 << "," << s2 << "] and rows[" << r1 << "," << r2 << "] Threshold = " << adcMinFL << " and sequence = " << seqFL << endm;
adcMinFL = adcMin;
seqFL = seq;
s1 = s2 = s;
r1 = r2 = r;
}
}
}
}
LOG_INFO << "StTpcHitMaker::Finish CheckThrSeq in sectors [" << s1 << "," << s2 << "] and rows[" << r1 << "," << r2 << "] Threshold = " << adcMinFL << " and sequence = " << seqFL << endm;
}
SafeDelete(fThr);
SafeDelete(fSeq);
return StMaker::Finish();
}
//_____________________________________________________________
Int_t StTpcHitMaker::UpdateHitCollection(Int_t sector) {
// Populate StEvent with StTpcHit collection
StEvent *pEvent = dynamic_cast<StEvent *> (GetInputDS("StEvent"));
if (Debug()) {LOG_INFO << "StTpcHitMaker::Make : StEvent has been retrieved " <<pEvent<< endm;}
if (! pEvent) {LOG_INFO << "StTpcHitMaker::Make : StEvent has not been found " << endm; return 0;}
StTpcHitCollection *hitCollection = pEvent->tpcHitCollection();
if ( !hitCollection ) {
// Save the hit collection to StEvent...if needed
hitCollection = new StTpcHitCollection();
pEvent->setTpcHitCollection(hitCollection);
}
Int_t NRows = DaqDta()->GetNRows();
if (NRows <= 0) return 0;
Int_t nhitsBefore = hitCollection->numberOfHits();
Int_t sec = DaqDta()->Sector();
Int_t row = RowNumber();
if (kReaderType == kLegacyTpc || kReaderType == kLegacyTpx) {
tpc_t *tpc = (tpc_t *) DaqDta()->GetTable();
for (Int_t l = 0; l < NRows; tpc++) {
if ( !tpc->has_clusters ) return 0;
for(Int_t padrow=0;padrow<St_tpcPadConfigC::instance()->numberOfRows(sector);padrow++) {
tpc_cl *c = &tpc->cl[padrow][0];
Int_t ncounts = tpc->cl_counts[padrow];
for(Int_t j=0;j<ncounts;j++,c++) {
if (! c || ! c->charge) continue;
if (c->flags &&
(c->flags & ~(FCF_ONEPAD | FCF_MERGED | FCF_BIG_CHARGE))) continue;
if (kMode == kTpxO) c->flags |= 256; // mark cluster if it is coming from extra online maker
Int_t row = padrow + 1;
Float_t pad = c->p;
Int_t iRdo = StDetectorDbTpcRDOMasks::instance()->rdoForPadrow(sector,row,pad);
if ( ! StDetectorDbTpcRDOMasks::instance()->isOn(sector,iRdo)) continue;
StTpcHit *tpcHit = CreateTpcHit(*c,sector,row);
Int_t iok = hitCollection->addHit(tpcHit);
assert(iok);
}
}
}
} else {
// kReaderType == kStandardTpx
daq_cld *cld = (daq_cld *) DaqDta()->GetTable();
if (Debug() > 1) {
LOG_INFO << Form("CLD sec %2d: row %2d: clusters: %3d",sec, row, NRows) << endm;
}
for (Int_t l = 0; l < NRows; l++, cld++) {
if (Debug() > 1) {
LOG_INFO << Form(" pad %f[%d:%d], tb %f[%d:%d], cha %d, fla 0x%X",//, Id %d, Q %d ",
cld->pad,
cld->p1,
cld->p2,
cld->tb,
cld->t1,
cld->t2,
cld->charge,
cld->flags
) << endm;
}
if (! cld->pad || ! cld->charge) continue;
if (! cld->tb) continue;
if (cld->tb < 0 || cld->tb >= __MaxNumberOfTimeBins__) continue;
if (cld->t1 < 0 || cld->t1 >= __MaxNumberOfTimeBins__) continue;
if (cld->t2 < 0 || cld->t2 >= __MaxNumberOfTimeBins__) continue;
if (cld->flags &&
(cld->flags & ~(FCF_ONEPAD | FCF_MERGED | FCF_BIG_CHARGE))) continue;
if (kMode == kTpxO) cld->flags |= 256; // mark cluster if it is coming from extra online maker
Float_t pad = cld->pad;
Int_t iRdo = StDetectorDbTpcRDOMasks::instance()->rdoForPadrow(sector,row,pad);
if ( ! StDetectorDbTpcRDOMasks::instance()->isOn(sector,iRdo)) continue;
StTpcHit *tpcHit = CreateTpcHit(*cld,sector,row);
Int_t iok = hitCollection->addHit(tpcHit);
assert(iok);
}
}
Int_t nhits = hitCollection->numberOfHits() - nhitsBefore;
if (Debug()) {
LOG_INFO << " Total hits in Sector : row " << sector << " : " << row << " = " << nhits << endm;
}
return nhits;
}
//_____________________________________________________________
StTpcHit *StTpcHitMaker::CreateTpcHit(const tpc_cl &cluster, Int_t sector, Int_t row) {
// Create an instance of the StTpcHit from the tpcReader data
Float_t pad = cluster.p;
Float_t time = cluster.t;
if (kReaderType == kLegacyTpx) time += 22; // remove Tonko's offset
static StTpcCoordinateTransform transform(gStTpcDb);
static StTpcLocalSectorCoordinate local;
static StTpcLocalCoordinate global;
StTpcPadCoordinate padcoord(sector, row, pad, time);
transform(padcoord,local,kFALSE);
transform(local,global);
UInt_t hw = 1; // detid_tpc
hw += sector << 4; // (row/100 << 4); // sector
hw += row << 9; // (row%100 << 9); // row
static StThreeVector<double> hard_coded_errors(fgDp,fgDt,fgDperp);
#if 0
Double_t gain = (row<=St_tpcPadConfigC::instance()->innerPadRows(sector)) ? St_tss_tssparC::instance()->gain_in() : St_tss_tssparC::instance()->gain_out();
Double_t wire_coupling = (row<=St_tpcPadConfigC::instance()->innerPadRows(sector)) ? St_tss_tssparC::instance()->wire_coupling_in() : St_tss_tssparC::instance()->wire_coupling_out();
#endif
Double_t q = 0; //cluster.charge * ((Double_t)St_tss_tssparC::instance()->ave_ion_pot() * (Double_t)St_tss_tssparC::instance()->scale())/(gain*wire_coupling) ;
StTpcHit *hit = StTpcHitFlag(global.position(),hard_coded_errors,hw,q
, (UChar_t ) 0 // c
, (Int_t) 0 // idTruth=0
, (UShort_t) 0 // quality=0,
, ++fId // id
, cluster.p1 // mnpad
, cluster.p2 // mxpad
, cluster.t1 // mntmbk
, cluster.t2 // mxtmbk
, pad
, time
, cluster.charge
,cluster.flags);
if (hit->minTmbk() == 0) bin0Hits++;
if (Debug()) {
LOG_INFO << "StTpcHitMaker::CreateTpcHit fromt tpc_cl\t" <<*hit << endm;
}
return hit;
}
//_____________________________________________________________
StTpcHit *StTpcHitMaker::CreateTpcHit(const daq_cld &cluster, Int_t sector, Int_t row) {
// Create an instance of the StTpcHit from the tpcReader data
Float_t pad = cluster.pad;
Float_t time = cluster.tb;
#if 1
Double_t gain = (row<=St_tpcPadConfigC::instance()->innerPadRows(sector)) ? St_tss_tssparC::instance()->gain_in() : St_tss_tssparC::instance()->gain_out();
Double_t wire_coupling = (row<=St_tpcPadConfigC::instance()->innerPadRows(sector)) ? St_tss_tssparC::instance()->wire_coupling_in() : St_tss_tssparC::instance()->wire_coupling_out();
Double_t q = cluster.charge * ((Double_t)St_tss_tssparC::instance()->ave_ion_pot() * (Double_t)St_tss_tssparC::instance()->scale())/(gain*wire_coupling) ;
#else /* used in TFG till 07/31/20 */
Double_t q = 0;
#endif
// Check that slewing is active
static St_tpcSlewingC *tpcSlewing = St_tpcSlewingC::instance();
if (tpcSlewing && tpcSlewing->type() != 1001) tpcSlewing = 0;
if (tpcSlewing) {
// Correct for slewing (needs corrected q, and time in microsec)
Double_t freq = gStTpcDb->Electronics()->samplingFrequency();
time = freq * tpcSlewing->correctedT(sector,row,q,time/freq);
}
static StTpcCoordinateTransform transform(gStTpcDb);
static StTpcLocalSectorCoordinate local;
static StTpcLocalCoordinate global;
StTpcPadCoordinate padcoord(sector, row, pad, time);
transform(padcoord,local,kFALSE);
transform(local,global);
UInt_t hw = 1; // detid_tpc
hw += sector << 4; // (row/100 << 4); // sector
hw += row << 9; // (row%100 << 9); // row
static StThreeVector<double> hard_coded_errors(fgDp,fgDt,fgDperp);
UShort_t flag = cluster.flags;
if (kMode == kTpxO) flag |= 256; // mark cluster if it is coming from extra online maker
StTpcHit *hit = StTpcHitFlag(global.position(),hard_coded_errors,hw,q
, (UChar_t ) 0 // c
, (Int_t) 0 // idTruth=0
, (UShort_t) 0 // quality=0,
, ++fId // id =0
, cluster.p1 // mnpad
, cluster.p2 // mxpad
, cluster.t1 // mntmbk
, cluster.t2 // mxtmbk
, pad
, time
, cluster.charge
, flag);
if (hit->minTmbk() == 0) bin0Hits++;
if (Debug()) {
LOG_INFO << "StTpcHitMaker::CreateTpcHit fromt daq_cld\t" <<*hit << endm;
}
return hit;
}
//________________________________________________________________________________
void StTpcHitMaker::DoPulser(Int_t sector) {
struct Pulser_t {Float_t sector, row, pad, gain, t0, nnoise, noise, npeak;};
static const Char_t *names = "sector:row:pad:gain:t0:nnoise:noise:npeak";
static Pulser_t Pulser;
if (! pulserP) {
TFile *f = GetTFile();
assert(f);
f->cd();
pulserP = new TNtuple("pulserP","Pulser analysis",names);
}
Int_t r, p, tb, tbmax;
Int_t npeak, nnoise;
if (! fTpc) return;
if (! fTpc->channels_sector) return;
for(Int_t row = 1; row <= St_tpcPadConfigC::instance()->numberOfRows(sector); row++) {
r = row - 1;
if (! fTpc->cl_counts[r]) continue;
for (Int_t pad = 1; pad <= 182; pad++) {
p = pad - 1;
Int_t ncounts = fTpc->counts[r][p];
if (! ncounts) continue;
static UShort_t adc[512];
memset (adc, 0, sizeof(adc));
tbmax = 513;
UShort_t adcmax = 0;
for (Int_t i = 0; i < ncounts; i++) {
tb = fTpc->timebin[r][p][i];
adc[tb] = log8to10_table[fTpc->adc[r][p][i]];
if (adc[tb] > adcmax) {
tbmax = tb;
adcmax = adc[tb];
}
}
if (tbmax < 2 || tbmax > 504) continue;
npeak = nnoise = 0;
Int_t i1s = TMath::Max( 0, tbmax - 2);
Int_t i2s = TMath::Min(511, tbmax + 7);
Int_t i1 = TMath::Max(0 ,i1s - 20);
Int_t i2 = TMath::Min(511,i2s + 20);
Double_t peak = 0;
Double_t noise = 0;
Double_t t0 = 0;
for (Int_t i = i1; i <= i2; i++) {
if (i >= i1s && i <= i2s) continue;
nnoise++;
noise += adc[i];
}
if (nnoise) noise /= nnoise;
for (Int_t i = i1s; i <= i2s; i++) {
npeak++;
peak += adc[i] - noise;
t0 += i*(adc[i] - noise);
}
if (peak <= 0) continue;
t0 /= peak;
Pulser.sector = sector;
Pulser.row = row;
Pulser.pad = pad;
Pulser.gain = peak;
Pulser.t0 = t0;
Pulser.nnoise = nnoise;
Pulser.noise = noise;
Pulser.npeak = npeak;
pulserP->Fill(&Pulser.sector);
}
}
}
//________________________________________________________________________________
void StTpcHitMaker::TpcAvLaser(Int_t sector) {
if (! fTpc || !fAvLaser) return;
Int_t npixels = 0;
struct pixl_t {
Double_t sector, row, pad, time;
};
#ifdef __USE__THnSparse__
if (fAvLaser[sector-1]->GetNbins() > 500000) {
THnSparseF *hnew = CompressTHn(fAvLaser[sector-1]);
GetTFile()->Remove(fAvLaser[sector-1]);
delete fAvLaser[sector-1];
fAvLaser[sector-1] = hnew;
GetTFile()->Add(fAvLaser[sector-1]);
}
#endif /* __USE__THnSparse__ */
pixl_t pixel;
pixel.sector = sector;
for(Int_t r = 0; r < St_tpcPadConfigC::instance()->numberOfRows(sector); r++) {
pixel.row = r+1;
for (Int_t pad = 1; pad <= 182; pad++) {
pixel.pad = pad;
Int_t p = pad - 1;
Double_t gain = St_tpcPadGainT0BC::instance()->Gain(pixel.sector,pixel.row,pixel.pad);
if (gain <= 0) continue;
Int_t ncounts = fTpc->counts[r][p];
if (! ncounts) continue;
for (Int_t i = 0; i < ncounts; i++) {
pixel.time = fTpc->timebin[r][p][i];
Double_t adc = log8to10_table[fTpc->adc[r][p][i]];
#ifdef __USE__THnSparse__
fAvLaser[sector-1]->Fill(&pixel.row,adc);
#else /* ! __USE__THnSparse__ */
fAvLaser[sector-1]->Fill(pixel.row,pixel.pad,pixel.time,adc);
#endif /* __USE__THnSparse__ */
npixels++;
}
}
}
LOG_INFO << " Total pixels in Sector : " << sector << " = " << npixels << endm;
}
//________________________________________________________________________________
void StTpcHitMaker::TpxAvLaser(Int_t sector) {
assert(fAvLaser[sector-1]);
#ifdef __USE__THnSparse__
if (fAvLaser[sector-1]->GetNbins() > 1000000) {
THnSparseF *hnew = CompressTHn(fAvLaser[sector-1]);
GetTFile()->Remove(fAvLaser[sector-1]);
delete fAvLaser[sector-1];
fAvLaser[sector-1] = hnew;
GetTFile()->Add(fAvLaser[sector-1]);
}
#endif /* __USE__THnSparse__ */
Int_t r=RowNumber() ; // I count from 1
if(r==0) return; // TPC does not support unphy. rows so we skip em
r-- ; // TPC wants from 0
Int_t p = Pad() - 1 ; // ibid.
if (p < 0 || p >= St_tpcPadConfigC::instance()->padsPerRow(sector,r+1)) return;
struct pixl_t {
Double_t sector, row, pad, time;
};
pixl_t pixel;
pixel.sector = sector;
pixel.row = r+1;
pixel.pad = p+1;
TGenericTable::iterator iword = DaqDta()->begin();
for (;iword != DaqDta()->end();++iword) {
daq_adc_tb &daqadc = (*(daq_adc_tb *)*iword);
Int_t tb = daqadc.tb;
pixel.time = tb;
Double_t adc = daqadc.adc;
#ifdef __NOT_ZERO_SUPPRESSED_DATA__
#ifdef __TOKENIZED__
if (tb >= 368 && tb <= 383)
// adc -= St_tpcPedestalC::instance()->Pedestal(sector,r+1,p+1,tb);
adc -= St_tpcPedestalC::instance()->Pedestal(sector,r+1,p+1);
#else /* ! __TOKENIZED__ */
// adc -= St_tpcPedestalC::instance()->Pedestal(sector,r+1,p+1,tb);
adc -= St_tpcPedestalC::instance()->Pedestal(sector,r+1,p+1);
#endif /* __TOKENIZED__ */
#else
// if (adc < 6) continue;
#endif /* __NOT_ZERO_SUPPRESSED_DATA__ */
#ifdef __USE__THnSparse__
fAvLaser[sector-1]->Fill(&pixel.row,adc);
#else /* ! __USE__THnSparse__ */
fAvLaser[sector-1]->Fill(pixel.row,pixel.pad,pixel.time,adc);
#endif /* __USE__THnSparse__ */
}
}
//________________________________________________________________________________
void StTpcHitMaker::DumpPixels2Ntuple(Int_t sector, Int_t row, Int_t pad) {
struct BPoint_t {
Float_t event, sector, row, pad, tb, adc, idt;
};
static const Char_t *BName = "event:sector:row:pad:tb:adc:idt";
static TNtuple *adcP = 0;
if (! adcP && GetTFile() ) {
GetTFile()->cd();
adcP = new TNtuple("adcP","Pulser ADC",BName);
}
if (! adcP) return;
static BPoint_t P;
P.event = GetEventNumber();
P.sector = sector;
P.row = row;
P.pad = pad;
for (Int_t i = 0; i < __MaxNumberOfTimeBins__; i++) {
if (! ADCs[i]) continue;