StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
St_pp2pp_Maker.cxx
1 
22 #include "St_pp2pp_Maker.h"
23 #include "StRtsTable.h"
24 #include "TDataSetIter.h"
25 #include "RTS/src/DAQ_PP2PP/pp2pp.h"
26 
27 #include "St_db_Maker/St_db_Maker.h"
28 
29 #include "tables/St_pp2ppPedestal_Table.h"
30 #include "tables/St_pp2ppPedestal160_Table.h" // K. Yip : Feb. 20, 2015 : New pedestal table (one per SVX)
31 #include "tables/St_pp2ppOffset_Table.h"
32 #include "tables/St_pp2ppZ_Table.h"
33 #include "tables/St_pp2ppRPpositions_Table.h" // K. Yip : Aug. 10, 2015 : LVDT readings for RP positions
34 #include "tables/St_pp2ppAcceleratorParameters_Table.h" // K. Yip : Aug. 10, 2015 : LVDT readings for RP positions
35 #include "tables/St_pp2ppPMTSkewConstants_Table.h" // K. Yip : Aug. 10, 2015 : LVDT readings for RP positions
36 
37 #include "StEvent/StEvent.h"
38 #include "StEvent/StRunInfo.h"
39 #include "StEvent/StRpsCollection.h"
40 #include "StEvent/StRpsCluster.h"
41 #include "StEvent/StRpsTrackPoint.h" // added by Rafal
42 #include "StEvent/StRpsTrack.h" // added by Rafal
43 
44 #include "StEvent/StTriggerData2009.h"
45 #include "StEvent/StTriggerData2012.h"
46 #include "StEvent/StTriggerData2013.h"
47 #include "StEvent/StTriggerData2016.h"
48 #include "StEvent/StTriggerData2017.h"
49 
50 using namespace std;
51 
52 ClassImp(St_pp2pp_Maker)
53 
54  St_pp2pp_Maker::St_pp2pp_Maker(const char *name) : StRTSBaseMaker("pp2pp",name),
55  mPedestalPerchannelFilename("pedestal.in.perchannel"), mLDoCluster(kTRUE),
56  kMaxPitchesToMatch(3.0), // added by Rafal
57  kPitch{ kpitch_6svx, kpitch_4svx }{ // added by Rafal
58  // ctor
59  // nevt_count = 0 ;
60 
61  // --- default values for pp run15 (in case it's not read from database) ---
62  mXYZ_IP[kX] = 0.0;
63  mXYZ_IP[kY] = 0.0;
64  mXYZ_IP[kZ] = 0.0;
65  mThetaXY_tilt[kX] = 0.0;
66  mThetaXY_tilt[kY] = 0.0;
67  mDistanceFromIPtoDX[StBeamDirection::east] = 9.8;
68  mDistanceFromIPtoDX[StBeamDirection::west] = 9.8;
69  mLDX[StBeamDirection::east] = 3.7;
70  mLDX[StBeamDirection::west] = 3.7;
71  mBendingAngle[StBeamDirection::east] = 0.018832292;
72  mBendingAngle[StBeamDirection::west] = 0.018826657;
73  mConversion_TAC_time = 18e-12;
74  // --- --- --- --- --- --- --- --- ---
75 }
76 
77 
78 St_pp2pp_Maker::~St_pp2pp_Maker() {
79 }
80 
81 //_____________________________________________________________________________
84  mLastSvx = ErrorCode;
85  mLastChain = ErrorCode;
86  mLastSeq = ErrorCode ;
87  return StMaker::Init();
88 }
89 
90 Int_t St_pp2pp_Maker::InitRun(int runumber) {
91 
92  if ( runumber < 16000000 )
93  mVersion = 1 ; // from 2009 to < 2015
94  else if ( runumber < 18000000 )
95  mVersion = 2 ; // >= 2015 < 2017
96  else
97  mVersion = 3 ; // >= 2017
98 
99  cout << "St_pp2pp_Maker: Timestamp - Day: " << GetDateTime().GetDate() << " , DB-Time: " << GetDBTime().GetDate() << endl ;
100  cout << "St_pp2pp_Maker: Timestamp - Time: " << GetDateTime().GetTime() << " , DB-Date: " << GetDBTime().GetTime() << endl ;
101 
102  if ( mLDoCluster ) {
103  readPedestalPerchannel() ;
104  readOffsetPerplane() ;
105  readZPerplane() ;
106 
107  // K. Yip (2015-10-22): for Rafal's Tracking really
108  if ( mVersion >= 2 ) {
109  readSkewParameter() ;
110  readAccelerateParameter() ;
111  }
112  }
113 
114  return kStOk ;
115 }
116 
117 Int_t St_pp2pp_Maker::readPedestalPerchannel() {
118 
119  // cout << "Size of each struct in DB : " << sizeof(pp2ppPedestal_st) << endl ;
120 
121  // cout << "Size of mPedave : " << sizeof(mPedave) << " , Size of mPedrms : " << sizeof(mPedrms) << endl ;
122 
123  memset(mPedave,0,sizeof(mPedave));
124  memset(mPedrms,0,sizeof(mPedrms));
125 
126  Int_t s, c, sv, ch, idb = 0 ;
127 
128  /*
129  // cout << GetTime() << " " << GetDate() << endl ;
130 
131  St_db_Maker *dbMk = (St_db_Maker*) GetMaker("db");
132  if ( ! dbMk ) {
133  LOG_WARN << "No St_db_Maker existed ?! " << endm ;
134  }
135  else {
136  // cout << "I got St_db_Maker ?? " << endl ;
137  dbMk->SetDateTime(this->GetDate(), this->GetTime());
138  }
139  */
140 
141  // Database
142  TDataSet *DB = 0;
143  if ( mVersion == 1 ) { // before 2015
144 
145  DB = GetInputDB("Calibrations/pp2pp/pp2ppPedestal");
146  if (!DB) {
147  LOG_ERROR << "ERROR: cannot find database Calibrations_pp2pp/pp2ppPedestal ?" << endm ;
148  }
149  else {
150  // fetch ROOT descriptor of db table
151  St_pp2ppPedestal *descr = 0;
152  descr = (St_pp2ppPedestal*) DB->Find("pp2ppPedestal");
153  // fetch data and place it to appropriate structure
154  if (descr) {
155  pp2ppPedestal_st *table = descr->GetTable();
156  // cout << "Reading pp2ppPedestal table with nrows = " << descr->GetNRows() << endl ;
157  for ( idb = 0; idb < descr->GetNRows(); idb++ ) {
158  s = (Int_t) table[idb].sequencer ;
159  c = (Int_t) table[idb].chain ;
160  sv = (Int_t) table[idb].SVX ;
161  ch = (Int_t) table[idb].channel ;
162 
163  if ( s > 0 ) {
164  mPedave[s-1][c][sv][ch] = table[idb].mean ;
165  mPedrms[s-1][c][sv][ch] = table[idb].rms ;
166  }
167  // cout << s << " " << c << " " << sv << " " << ch << " " << mPedave[s-1][c][sv][ch] << " " << mPedrms[s-1][c][sv][ch] << endl ;
168 
169  }
170  } else {
171  LOG_ERROR << "St_pp2pp_Maker: No data in pp2ppPedestal table (wrong timestamp?). Nothing to return, then." << endm ;
172  }
173  }
174  }
175  else { // 2015 and afterwards
176  // K. Yip : Feb. 20, 2015 : Use a new table of pedestal/rms per SVX (160 of them only)
177  DB = GetDataBase("Calibrations/pp2pp/pp2ppPedestal160");
178  if (!DB) {
179  LOG_ERROR << "ERROR: cannot find database Calibrations/pp2pp/pp2ppPedestal160 ?" << endm ;
180  }
181  else {
182 
183  St_pp2ppPedestal160 *dataset = 0;
184  dataset = (St_pp2ppPedestal160*) DB->Find("pp2ppPedestal160");
185 
186  if (dataset) {
187  if ( dataset->GetNRows() > 1 ) {
188  LOG_ERROR << "St_pp2pp_Maker : Found INDEXED table with " << dataset->GetNRows() << " rows \?!" << endm ;
189  }
190 
191  pp2ppPedestal160_st *table = dataset->GetTable();
192  for (Int_t j = 0; j < 160; j++) {
193 
194  s = j/20 ; // == Sequence - 1
195  if ( (j%20) < 4 ) {
196  c = 0 ;
197  sv = j%20 ;
198  }
199  else if ( (j%20) < 10 ) {
200  c = 1 ;
201  sv = j%20 - 4 ;
202  }
203  else if ( (j%20) < 14 ) {
204  c = 2 ;
205  sv = j%20 - 10 ;
206  }
207  else {
208  c = 3 ;
209  sv = j%20 - 14 ;
210  }
211 
212  LOG_DEBUG << j << "th element: seq = " << s+1 << " chain = " << c << " svx = " << sv
213  << " => mean: " << table[0].mean[j] << ", rms: " << table[0].rms[j] << endm ;
214 
215  mPedrms[s][c][sv][0] = table[0].rms[j] ;
216 
217  }
218  }
219  else {
220  LOG_ERROR << "St_pp2pp_Maker: dataset does not contain requested table" << endm ;
221  }
222 
223  }
224  }
225 
226  // LOG_DEBUG << idb << " pedestal entries read from DB table Calibration/pp2pp read. " << endm ;
227 
228 
229  return kStOk ;
230 
231 }
232 
233 Int_t St_pp2pp_Maker::readOffsetPerplane() {
234 
235  mOffsetTable = 0;
236  mRPpositionsTable = 0 ; // >= 2015
237 
238  TDataSet *DB = 0;
239  DB = GetInputDB("Geometry/pp2pp/pp2ppOffset");
240  if (!DB) {
241  LOG_ERROR << "ERROR: cannot find database Geometry_pp2pp/pp2ppOffset ?" << endm ;
242  }
243  else {
244 
245  // fetch ROOT descriptor of db table
246  St_pp2ppOffset *descr = 0;
247  descr = (St_pp2ppOffset*) DB->Find("pp2ppOffset");
248  // fetch data and place it to appropriate structure
249  if (descr) {
250  mOffsetTable = descr->GetTable();
251  LOG_DEBUG << "St_pp2pp_Maker : Reading pp2ppOffset table with nrows = " << descr->GetNRows() << endm ;
252  /*
253  for (Int_t i = 0; i < descr->GetNRows(); i++) {
254  for ( Int_t j = 0; j< 32 ; j++ )
255  std::cout << mOffsetTable[i].rp_offset_plane[j] << " " ;
256  cout << endl ;
257  }
258  */
259  } else {
260  LOG_ERROR << "St_pp2pp_Maker : No data in pp2ppOffset table (wrong timestamp?). Nothing to return, then" << endm ;
261  }
262 
263  }
264 
265  if ( mVersion >= 2 ) { // only for >=2015
266 
267  DB = GetInputDB("Calibrations/pp2pp/pp2ppRPpositions");
268  if (!DB) {
269  LOG_ERROR << "ERROR: cannot find database Calibrations_pp2pp/pp2ppRPpositions ?" << endm ;
270  }
271  else {
272  // fetch ROOT descriptor of db table
273  St_pp2ppRPpositions *descr = 0;
274  descr = (St_pp2ppRPpositions*) DB->Find("pp2ppRPpositions");
275  if (descr) {
276  LOG_DEBUG << "St_pp2pp_Maker : Reading pp2ppRPpositions table with nrows = " << descr->GetNRows() << endm ;
277  mRPpositionsTable = descr->GetTable();
278  mLVDT_pos[0] = mRPpositionsTable[0].y_right_E1U ;
279  mLVDT_pos[1] = mRPpositionsTable[0].y_left_E1D ;
280  mLVDT_pos[2] = mRPpositionsTable[0].y_top_E2U ;
281  mLVDT_pos[3] = mRPpositionsTable[0].y_bot_E2D ;
282  mLVDT_pos[4] = mRPpositionsTable[0].b_right_W1U ;
283  mLVDT_pos[5] = mRPpositionsTable[0].b_left_W1D ;
284  mLVDT_pos[6] = mRPpositionsTable[0].b_top_W2U ;
285  mLVDT_pos[7] = mRPpositionsTable[0].b_bot_W2D ;
286  /*
287  for (Int_t i = 0; i < descr->GetNRows(); i++) {
288  std::cout << i << "th row : " << mRPpositionsTable[i].b_left_W1D << " " << mRPpositionsTable[i].b_right_W1U
289  << " " << mRPpositionsTable[i].b_bot_W2D << " " << mRPpositionsTable[i].b_top_W2U
290  << " " << mRPpositionsTable[i].y_left_E1D << " " << mRPpositionsTable[i].y_right_E1U
291  << " " << mRPpositionsTable[i].y_bot_E2D << " " << mRPpositionsTable[i].y_top_E2U << std::endl;
292  }
293  */
294  } else {
295  LOG_ERROR << "St_pp2pp_Maker : No data in pp2ppRPpositions table (wrong timestamp?). Nothing to return, then" << endm ;
296  }
297 
298 
299  }
300 
301  }
302 
303  return kStOk ;
304 
305 }
306 
307 
308 Int_t St_pp2pp_Maker::readZPerplane() {
309 
310  mZTable = 0;
311 
312  TDataSet *DB = 0;
313  DB = GetInputDB("Geometry/pp2pp/pp2ppZ");
314  if (!DB) {
315  LOG_ERROR << "ERROR: cannot find database Geometry_pp2pp/pp2ppZ ?" << endm ;
316  }
317  else {
318 
319  // fetch ROOT descriptor of db table
320  St_pp2ppZ *descr = 0;
321  descr = (St_pp2ppZ*) DB->Find("pp2ppZ");
322  // fetch data and place it to appropriate structure
323  if (descr) {
324  mZTable = descr->GetTable();
325  LOG_DEBUG << "Reading pp2ppZ table with nrows = " << descr->GetNRows() << endm ;
326  /*
327  for (Int_t i = 0; i < descr->GetNRows(); i++) {
328  for ( Int_t j = 0; j< 32 ; j++ )
329  std::cout << mZTable[i].rp_z_plane[j] << " " ;
330  cout << endl ;
331  }
332  */
333  } else {
334  LOG_ERROR << "St_pp2pp_Maker : No data in pp2ppZ table (wrong timestamp?). Nothing to return, then" << endm ;
335  }
336 
337  }
338 
339  return kStOk ;
340 
341 }
342 
343 
344 Int_t St_pp2pp_Maker::readSkewParameter() {
345 
346  memset(mSkew_param,0,sizeof(mSkew_param));
347 
348  int s, ipmt, ipar ;
349 
350  // Database
351  TDataSet *DB = 0;
352  DB = GetDataBase("Calibrations/pp2pp/pp2ppPMTSkewConstants");
353  if (!DB) {
354  LOG_ERROR << "ERROR: cannot find database Calibrations/pp2pp/pp2ppPMTSkewConstants ?" << endm ;
355  }
356  else {
357 
358  St_pp2ppPMTSkewConstants *dataset = 0;
359  dataset = (St_pp2ppPMTSkewConstants*) DB->Find("pp2ppPMTSkewConstants");
360 
361  if (dataset) {
362 
363  if ( dataset->GetNRows() > 1 ) {
364  LOG_ERROR << "St_pp2pp_Maker : Found INDEXED table with " << dataset->GetNRows() << " rows \?!" << endm ;
365  }
366 
367  pp2ppPMTSkewConstants_st *table = dataset->GetTable();
368  for (int j = 0; j < 64; j++) {
369 
370  s = j/kMAXSEQ ; // RP 0 .. 7
371  ipmt = (j/4) % 2 ; // 0 or 1
372  ipar = j - 4*ipmt - s*kMAXSEQ ; // 0 .. 3
373 
374  LOG_DEBUG << j << "th element: RP = " << s << " PMT = " << ipmt << " parameter = " << ipar
375  << " with parameter : " << table[0].skew_param[j] << endm ;
376 
377  mSkew_param[s][ipmt][ipar] = table[0].skew_param[j] ;
378 
379  }
380  }
381  else {
382  LOG_ERROR << "St_pp2pp_Maker: dataset does not contain requested table pp2ppPMTSkewConstants ." << endm ;
383  }
384 
385  }
386 
387  return kStOk ;
388 
389 }
390 
391 
392 Int_t St_pp2pp_Maker::readAccelerateParameter() {
393 
394  TDataSet *DB = 0;
395  DB = GetInputDB("Geometry/pp2pp/pp2ppAcceleratorParameters");
396  if (!DB) {
397  LOG_ERROR << "ERROR: cannot find database Geometry_pp2pp/pp2ppAcceleratorParameters ?" << endm ;
398  }
399  else {
400 
401  // fetch ROOT descriptor of db table
402  St_pp2ppAcceleratorParameters *descr = 0;
403  descr = (St_pp2ppAcceleratorParameters*) DB->Find("pp2ppAcceleratorParameters");
404  // fetch data and place it to appropriate structure
405  if (descr) {
406  pp2ppAcceleratorParameters_st *table = descr->GetTable();
407  LOG_DEBUG << "St_pp2pp_Maker : Reading pp2ppAcceleratorParameters table with nrows = " << descr->GetNRows() << endm ;
408 
409  mXYZ_IP[0] = table[0].x_IP ;
410  mXYZ_IP[1] = table[0].y_IP ;
411  mXYZ_IP[2] = table[0].z_IP ;
412 
413  mThetaXY_tilt[0] = table[0].theta_x_tilt ;
414  mThetaXY_tilt[1] = table[0].theta_y_tilt ;
415 
416  mDistanceFromIPtoDX[0] = table[0].distancefromDX_east ;
417  mDistanceFromIPtoDX[1] = table[0].distancefromDX_west ;
418 
419  mLDX[0] = table[0].LDX_east ;
420  mLDX[1] = table[0].LDX_west ;
421 
422  mBendingAngle[0] = table[0].bendingAngle_east ;
423  mBendingAngle[1] = table[0].bendingAngle_west ;
424 
425  mConversion_TAC_time = table[0].conversion_TAC_time ;
426 
427  LOG_DEBUG << mXYZ_IP[0] << " " << mXYZ_IP[1] << " " << mXYZ_IP[2] << " "
428  << mThetaXY_tilt[0] << " " << mThetaXY_tilt[1] << " "
429  << mDistanceFromIPtoDX[0] << " " << mDistanceFromIPtoDX[1] << " "
430  << mLDX[0] << " " << mLDX[1] << " "
431  << mBendingAngle[0] << " " << mBendingAngle[1] << " "
432  << mConversion_TAC_time << endm ;
433 
434  } else {
435  LOG_ERROR << "St_pp2pp_Maker : No data in pp2ppAcceleratorParameters table (wrong timestamp?). Nothing to return, then" << endm ;
436  }
437 
438  }
439 
440  return kStOk ;
441 
442 }
443 
444 
445 
446 //_____________________________________________________________________________
448 void St_pp2pp_Maker::Clear(Option_t *) {
449 
450  // Deleting previous cluster info.
451  for ( Int_t i=0; i<kMAXSEQ; i++)
452  for ( Int_t j=0; j<kMAXCHAIN; j++)
453  (mValidHits[i][j]).clear();
454 
455  StMaker::Clear(); // perform the basic clear (mandatory)
456 
457 }
458 
459 
460 //_____________________________________________________________________________
463 
464  // if ( nevt_count%10000 == 0 ) cout << "St_pp2pp_Maker:: Event count : " << nevt_count << endl ;
465 
466  // nevt_count++ ;
467 
468  if ( Token() == 0 )
469  return kStOK ;
470 
471  //
472  // PrintInfo();
473  //
474  // ls (0);
475 
476  int counter = -1;
477 
478  TGenericTable *pp2ppRawHits = new TGenericTable("pp2ppRawHit_st","pp2ppRawHits");
479 
480 
481  // Each GetNextAdc would get a SVX ...
482  if ( mVersion == 1 ) { // before 2015
483  while ( GetNextAdc() ) {
484  counter++;
485  TGenericTable::iterator iword = DaqDta()->begin();
486  for (;iword != DaqDta()->end();++iword) {
487  pp2pp_t &d = *(pp2pp_t *)*iword;
488  // do something
489  if ( DoerPp2pp(d,*pp2ppRawHits) != kStOK )
490  return kStERR ;
491  if ( counter == 0 ) mSiliconBunch = d.bunch_xing ;
492  }
493  }
494  } else { // >= 2015
495  while ( GetNext("adc_ped_sub") ) { // K. Yip : Feb. 20, 2015 : to get the pedestal-subtracted ADC's
496  counter++;
497  TGenericTable::iterator iword = DaqDta()->begin();
498  for (;iword != DaqDta()->end();++iword) {
499  pp2pp_t &d = *(pp2pp_t *)*iword;
500  // do something
501  if ( DoerPp2pp(d,*pp2ppRawHits) != kStOK )
502  return kStERR ;
503  if ( counter == 0 ) mSiliconBunch = d.bunch_xing ;
504  }
505  }
506  }
507 
508  if (counter < 0) {
509  LOG_DEBUG << "There was no pp2pp data for this event. " << endm;
510  } else {
511  LOG_DEBUG << "End of pp2pp data for this event : " << GetEventNumber() << ", Total = " << counter+1
512  << " records were found" << endm;
513  }
514 
515  AddData(pp2ppRawHits); // publish RawHits to make it available for other makers in the chain
516  // one may not call AddData if the result should not be published.
517  // to discard the result one should call "delete pp2ppRawHits"
518 
519 
520  if ( mLDoCluster ) {
521 
522  for ( Int_t i=0; i<kMAXSEQ; i++)
523  for ( Int_t j=0; j<kMAXCHAIN; j++) {
524  sort( (mValidHits[i][j]).begin(), (mValidHits[i][j]).end(), hitcompare);
525  // cout << "Size of vector of sequencer " << i+1 << " chain " << j << " " << dec << (mValidHits[i][j]).size() << endl ;
526  }
527 
528  MakeClusters();
529 
530  }
531 
532  return kStOK;
533 
534 }
535 
536 //_____________________________________________________________________________
538 Int_t St_pp2pp_Maker::DoerPp2pp(const pp2pp_t &d, TGenericTable &hitsTable) {
539 
540  pp2ppRawHit_st oneSihit = {0}; // This essentially gives adc the value of "0"
541  oneSihit.sec = Sector() ;
542  oneSihit.sequencer = d.seq_id ;
543  oneSihit.chain = d.chain_id ;
544  oneSihit.svx = d.svx_id ;
545 
546  // For clustering purpose
547  HitChannel onehit ;
548 
549  // Mar. 14, 2009 (K. Yip) : checking for wrong SVX_ID
550  // One known case is for SEQ 3, CHAIN 2 and SVX is 7 but it should be 3.
551  // Mostly, just some debugging codes that we've used in the past and shouldn't happen
552 
553  if ( mVersion == 1 ) { // before 2015
554  if ( (oneSihit.svx != mLastSvx) && (mLastSvx != ErrorCode) ) {
555 
556  if ( Int_t(oneSihit.svx-1) != mLastSvx )
557 
558  if ( ( (oneSihit.svx-mLastSvx) != -3 && ( (oneSihit.chain%2)==1 ) ) ||
559  ( (oneSihit.svx-mLastSvx) != -5 && ( (oneSihit.chain%2)==0 ) ) ) {
560 
561  if ( oneSihit.svx == 7 && oneSihit.sequencer == 3 && oneSihit.chain == 2 )
562  oneSihit.svx = 3 ;
563  // else if ( oneSihit.svx < mLastSvx ) {
564  else if ( oneSihit.svx < mLastSvx && ( GetRunNumber()<10185015 || (mLastSeq!=2 && mLastChain!=2)) ) { // bad seq 2 and chain D
565 
566  LOG_WARN << "Decreased ? " << GetEventNumber() << " : mLastSeq = " << mLastSeq << ", mLastChain = " << mLastChain << ", mLastSvx = " << mLastSvx << endm ;
567  LOG_WARN << "Decreased ? " << GetEventNumber() << " : Now, seq = " << (int) oneSihit.sequencer << ", chain = " << (int) oneSihit.chain << ", svx = " << (int) oneSihit.svx << endm ;
568 
569  oneSihit.svx = mLastSvx + 1 ;
570 
571  LOG_WARN << "Decreased ? : So -> " << " svx is now = " << (int) oneSihit.svx << endm ;
572 
573  }
574  // else if ( mLastSeq!=2 && mLastChain!=2 ) { // bad seq 2 and chain D
575  else if ( GetRunNumber()<10185015 || ( mLastSeq!=2 && mLastChain!=2 ) ) { // bad seq 2 and chain D
576 
577  LOG_WARN << GetEventNumber() << " : mLastSeq = " << mLastSeq << ", mLastChain = " << mLastChain << ", mLastSvx = " << mLastSvx << endm ;
578  LOG_WARN << GetEventNumber() << " : Now, seq = " << (int) oneSihit.sequencer << ", chain = " << (int) oneSihit.chain << ", svx = " << (int) oneSihit.svx << endm ;
579 
580  }
581 
582  }
583 
584 
585  }
586  else if ( (oneSihit.chain==mLastChain) && (mLastChain != ErrorCode) ) {
587  LOG_WARN << "Repeated ? :" << GetEventNumber() << " : mLastSeq = " << mLastSeq << ", mLastChain = " << mLastChain << ", mLastSvx = " << mLastSvx << endm ;
588  LOG_WARN << "Repeated ? : " << GetEventNumber() << " : Now, seq = " << (int) oneSihit.sequencer << ", chain = " << (int) oneSihit.chain << ", svx = " << (int) oneSihit.svx << endm ;
589 
590  oneSihit.svx = mLastSvx + 1 ;
591 
592  LOG_WARN << "Repeated : So -> " << " svx is now = " << (int) oneSihit.svx << endm ;
593  }
594 
595  } else { // >= 2015
596 
597  // K. Yip : Feb. 20, 2015 : Since we're reading "adc_ped_sub" bank, the continuity is no longer there.
598 
599  // K. Yip : Feb. 20, 2015 : Now, it's for SEQ 7, CHAIN 2 => SVX is 7 but it should be 3.
600  if ( oneSihit.svx == 7 && oneSihit.sequencer == 7 && oneSihit.chain == 2 )
601  oneSihit.svx = 3 ;
602  }
603 
604  mRpStatus[oneSihit.sequencer - 1] = d.bunch_xing ; // hack to store the silicon_bunch
605 
606  mLastSeq = oneSihit.sequencer;
607  mLastChain = oneSihit.chain;
608  mLastSvx = oneSihit.svx;
609 
610  // cout << "Seq: " << mLastSeq << " , chain " << mLastChain << ", SVX = " << mLastSvx << endl ;
611 
612  for(unsigned int c=0;c<sizeof(d.adc);c++) {
613  // if( d.adc[c] ) printf(" %3d: %3d [0x%02X]\n",c,d.adc[c],d.adc[c]) ;
614  // adc[nsvx][c] = d.adc[c];
615  if ( d.trace[c] == 1 ) {
616  oneSihit.channel = c ;
617  oneSihit.adc = d.adc[c];
618  hitsTable.AddAt(&oneSihit);
619 
620  // cout << "channel " << c << " , adc " << (int) d.adc[c] << endl ;
621 
622  if ( mLDoCluster && (c != (kMAXSTRIP-1)) && (c != 0) ) { // Avoid the channels at 2 ends of SVX
623 
624  // Getting rid of the 1st channel (0) and the last channel (127)
625  // K. Yip : Feb. 20, 2015 :
626  // The plane E2D.A installed on Jan. 30, 2015 had an old BNL made silicon in it. In this version _all_ SVX channels were connected to the silicon.
627  if ( ( mLastSeq == 4 ) && ( mLastChain == 0 ) && ( mVersion>=2 ) ) // for >= 2015
628  onehit.first = mLastSvx*(kMAXSTRIP) + oneSihit.channel ;
629  else
630  onehit.first = mLastSvx*(kMAXSTRIP-2) + oneSihit.channel - 1 ;
631 
632 
633  if ( mVersion<=1 ) {
634 
635  onehit.second = oneSihit.adc - mPedave[mLastSeq-1][mLastChain][mLastSvx][oneSihit.channel] ;
636 
637  if ( onehit.second > 5*mPedrms[mLastSeq-1][mLastChain][mLastSvx][oneSihit.channel] ) {
638  (mValidHits[mLastSeq-1][mLastChain]).push_back(onehit);
639  // cout << "mValidHits : position " << onehit.first << " , energy " << onehit.second << endl ;
640  }
641 
642  } else {
643 
644  onehit.second = oneSihit.adc ; // as it's pedestal-subtracted already
645 
646  if ( onehit.second > 5*mPedrms[mLastSeq-1][mLastChain][mLastSvx][0] ) {
647  (mValidHits[mLastSeq-1][mLastChain]).push_back(onehit);
648  }
649 
650  }
651 
652  }
653 
654  }
655  else if ( d.trace[c] == 2 ) { // 2015-1-25 (K. Yip) : Tonko's advice if there is trace =2 anywhere, just drop this event
656  LOG_ERROR << "St_pp2pp_Maker : d->trace[c] == 2 ! " << endm ;
657  return kStERR ;
658  }
659  else if ( d.trace[c] != 0 )
660  std::cout << GetEventNumber() << " : trace = " << (Int_t) d.trace[c] << ", Seq " << (Int_t) oneSihit.sequencer
661  << ", chain " << (Int_t) oneSihit.chain << ", SVX " << (Int_t) oneSihit.svx << ", channel " << c
662  << " is duplicated ? ==> " << (Int_t) d.adc[c] << std::endl ;
663  }
664 
665  return kStOk;
666 
667 }
668 
670 
671  // const Int_t MAX_Cls_L = 5 ;
672  // const Int_t MIN_Charge = 20 ;
674  // 2009
675  // EHI EHO EVU EVD WHI WHO WVD WVU
676  const short orientations[kMAXCHAIN*kMAXSEQ] = {-1,1,-1,1, 1,-1,1,-1, 1,1,1,1, -1,-1,-1,-1, -1,-1,-1,-1, 1,1,1,1, -1,1,-1,1, 1,-1,1,-1 };
677  // >=2015
678  // E1U E1D E2U E2D W1U W1D W2U W2D
679  const short orientations2[kMAXCHAIN*kMAXSEQ] = {1,1,1,1, -1,-1,-1,-1, 1,1,1,1, -1,-1,-1,-1, 1,-1,1,-1, -1,1,-1,1, 1,-1,1,-1, -1,1,-1,1 };
681  const double zcoordinates[kMAXSEQ] = { -55.496, -55.496, -58.496, -58.496, 55.496, 55.496, 58.496, 58.496 };
682 
684  const short EW[kMAXSEQ] = { 0, 0, 0, 0, 1, 1, 1, 1 } ;
685  const short VH[kMAXSEQ] = { 1, 1, 0, 0, 1, 1, 0, 0 } ;
686  const short UDOI[kMAXSEQ] = { 1, 0, 0, 1, 1, 0, 1, 0 } ;
687  // >=2015 --- W2U (~WVU) is sequencer 7 and W2D (~WVD) is sequencer 8
688  const short UD[kMAXSEQ] = { 1, 0, 0, 1, 1, 0, 0, 1 } ;
689 
690  // 2015:
691  // Bogdan's alignment-corrected offsets (in mm) // version 1.1. -> included by Rafal
692  const double LVDT_OFFSET[32] = {
693  4.991, -36.620, 4.945, -36.610, -4.147, 41.738, -4.103, 41.722,
694  5.114, -14.433, 5.197, -14.490, -4.439, 64.106, -4.679, 63.878,
695  4.708, 42.106, 4.764, 41.758, -5.443, -37.980, -5.365, -38.274,
696  4.065, 63.583, 4.072, 63.513, -3.665, -16.674, -3.714, -16.881,
697  };
698 
699  const double LVDT_SCALE[32] = {
700  0.999, -0.010, 0.999, -0.011, 0.999, 0.000, 0.999, 0.000,
701  0.997, 0.000, 0.997, 0.000, 0.997, 0.000, 0.997, 0.000,
702  0.993, 0.000, 0.993, 0.000, 0.966, 0.000, 0.965, 0.000,
703  1.004, 0.000, 1.004, 0.000, 1.050, 0.000, 1.049, 0.000,
704  };
705 
706  // 2017: added by K. Yip (2018-1-18)
707  /* corrected */
708  // const char *LVDT_REVISION = "LVDTConst Version: 2017.0.1";
709  const double LVDT_OFFSET_2017[32] = {
710  3.752, -37.124, 3.699, -37.169, -5.160, 42.434, -5.115, 42.355,
711  4.236, -19.230, 4.321, -19.339, -5.311, 59.894, -5.533, 59.612,
712  4.864, 41.480, 4.908, 41.213, -4.293, -37.968, -4.315, -38.297,
713  5.169, 63.474, 5.106, 63.479, 3.377, -15.926, 3.412, -16.133,
714  };
715 
716  const double LVDT_SCALE_2017[32] = {
717  0.998, 0.000, 0.998, 0.000, 0.998, 0.000, 0.998, 0.000,
718  0.996, 0.000, 0.996, 0.000, 0.996, 0.000, 0.998, 0.000,
719  0.997, 0.000, 0.997, 0.000, 1.002, 0.000, 1.002, 0.000,
720  1.003, 0.000, 1.003, 0.000, 1.007, 0.000, 1.007, 0.000,
721  };
722 
723 
724  Bool_t is_candidate_to_store ;
725 
726  Int_t NCluster_Length, Diff_Bunch ;
727  Double_t ECluster, POStimesE, POStimesESq, position, positionRMS, offset, pitch ;
728 
729  StTriggerData* trg_p = 0 ;
731  TObjectSet *os = (TObjectSet*)GetDataSet("StTriggerData");
732  if (os) {
733  trg_p = (StTriggerData*)os->GetObject();
734  }
735 
736 
738  StRpsCollection * pp2ppColl = new StRpsCollection();
739 
741  pp2ppColl->setSiliconBunch(mSiliconBunch) ;
742 
743  vector< HitChannel >::iterator it, it_next ;
744 
745  for ( Int_t i=0; i<kMAXSEQ; i++)
746  for ( Int_t j=0; j<kMAXCHAIN; j++) {
747 
748 
749  // Put in trigger stuff
750 
751  if(trg_p){
752 
753  if ( mVersion == 1 ) { // 2009
754  pp2ppColl->romanPot(i)->setAdc((uint32_t) trg_p->pp2ppADC( (StBeamDirection) EW[i],VH[i],UDOI[i],0),
755  (uint32_t) trg_p->pp2ppADC( (StBeamDirection) EW[i],VH[i],UDOI[i],1) );
756  pp2ppColl->romanPot(i)->setTac((uint32_t) trg_p->pp2ppTAC( (StBeamDirection) EW[i],VH[i],UDOI[i],0),
757  (uint32_t) trg_p->pp2ppTAC( (StBeamDirection) EW[i],VH[i],UDOI[i],1) );
758  }
759  else { // >= 2015
760  pp2ppColl->romanPot(i)->setAdc((uint32_t) trg_p->pp2ppADC( (StBeamDirection) EW[i],VH[i],UD[i],0),
761  (uint32_t) trg_p->pp2ppADC( (StBeamDirection) EW[i],VH[i],UD[i],1) );
762  pp2ppColl->romanPot(i)->setTac((uint32_t) trg_p->pp2ppTAC( (StBeamDirection) EW[i],VH[i],UD[i],0),
763  (uint32_t) trg_p->pp2ppTAC( (StBeamDirection) EW[i],VH[i],UD[i],1) );
764  }
765 
766  // for now (Jan. 2010) : use the status byte as "silicon_bunch - bunchId7Bit()"
767  Diff_Bunch = mRpStatus[i] - trg_p->bunchId7Bit() ;
768  if ( Diff_Bunch < 0 ) Diff_Bunch += 120 ;
769  pp2ppColl->romanPot(i)->setStatus( (unsigned char) Diff_Bunch ) ;
770 
771  }
772  else
773  LOG_WARN << "No StTriggerData ?! " << endm ;
774 
775 
776  NCluster_Length = 0 ;
777  ECluster = 0 ;
778  POStimesE = 0 ;
779  POStimesESq = 0 ;
780 
781  if ( mZTable )
782  pp2ppColl->romanPot(i)->plane(j)->setZ( mZTable[0].rp_z_plane[4*i+j] ) ;
783  else
784  pp2ppColl->romanPot(i)->plane(j)->setZ(zcoordinates[i]) ;
785 
786  if ( mVersion < 2 ) {
787  if ( mOffsetTable )
788  offset = mOffsetTable[0].rp_offset_plane[4*i+j]/1000. ;
789  else
790  offset = double(ErrorCode) ;
791  // cout << "Offsets : " << i << " " << j << " " << mOffsetTable[0].rp_offset_plane[4*i+j] << endl ;
792  }
793  else {
794  if ( mRPpositionsTable ) {
795  // K. Yip (Oct. 19, 2015) : set offsets back to m (as LVDT arrays are in mm)
796  if ( mVersion == 2 )
797  offset = ( LVDT_OFFSET[4*i+j] + LVDT_SCALE[4*i+j]*mLVDT_pos[i] )/1000. ;
798  else // for 2017: added by K. Yip (2018-1-18)
799  offset = ( LVDT_OFFSET_2017[4*i+j] + LVDT_SCALE_2017[4*i+j]*mLVDT_pos[i] )/1000. ;
800  }
801  else
802  offset = double(ErrorCode) ;
803  // cout << "Offsets : " << i << " " << j << " " << offset << endl ;
804  }
805 
806  pp2ppColl->romanPot(i)->plane(j)->setOffset( offset ) ;
807 
808  if ( mVersion < 2 )
809  pp2ppColl->romanPot(i)->plane(j)->setOrientation( orientations[4*i+j] ) ;
810  else
811  pp2ppColl->romanPot(i)->plane(j)->setOrientation( orientations2[4*i+j] ) ;
812 
813  it = (mValidHits[i][j]).begin() ;
814 
815  while ( it != (mValidHits[i][j]).end() ) {
816 
817  // cout << "Seq: " << i+1 << " , chain " << j << ", channel : " << it->first << " , energy : " << it->second << endl ;
818  NCluster_Length++ ;
819  ECluster += it->second ;
820  POStimesE += it->first*it->second ;
821  POStimesESq += it->first * it->first * it->second ;
822 
823  it_next = it + 1 ;
824 
825  is_candidate_to_store = kFALSE ;
826 
827  // Deciding whether it's time to finish this particular clustering process
828  if ( it_next != (mValidHits[i][j]).end() ) {
829 
830  // if the next one is not a neighbor --> a candidate cluster
831  if ( (it_next->first - it->first)!=1 )
832  is_candidate_to_store = kTRUE ;
833 
834  }
835  else { // if already at the end --> a candidate cluster
836  is_candidate_to_store = kTRUE ;
837  }
838 
839  if ( is_candidate_to_store == kTRUE ) {
840 
841  // if ( NCluster_Length <= MAX_Cls_L && ECluster >= MIN_Charge ) {
842 
843  // StEvent Clusters
844  StRpsCluster * oneStCluster = new StRpsCluster() ;
845 
846  oneStCluster->setEnergy(ECluster);
847  oneStCluster->setLength(NCluster_Length);
848  position = POStimesE/ECluster ;
849  // K. Yip : Oct. 3, 2015 : Added positionRMS
850  positionRMS = POStimesESq/ECluster - position*position ;
851  if ( positionRMS > 0 ) // protecting against possibly numbers very close to 0 which may be -ve
852  positionRMS = sqrt( positionRMS ) ;
853  else
854  positionRMS = 0.0 ;
855 
856  if ( (j % 2) == 0 ) { // A or C : pitch_4svx = 0.00974 cm
857  // K. Yip : Aug. 14, 2015 :
858  // The plane E2D.A installed on Jan. 30, 2015 had an old BNL made silicon in it, where _all_ SVX channels were connected to the silicon and the pitch is smaller.
859  if ( ( mVersion >= 2 ) && ( i == 3 ) && ( j == 0 ) ) { // Here the sequence nos. are from 0 to 7 (as they're from mValidHits arrays)
860  pitch = kpitch_4svx2 ; // in m
861  }
862  else {
863  pitch = kpitch_4svx ; // in m
864  }
865  }
866  else { // B or D : pitch_6svx = 0.01050 cm
867  pitch = kpitch_6svx ; // in m
868  }
869 
870  position = position*pitch ;
871  positionRMS = positionRMS*pitch ;
872 
873  oneStCluster->setPosition(position); // in m
874  oneStCluster->setPositionRMS(positionRMS); // in m
875 
876  if ( mVersion < 2 )
877  oneStCluster->setXY( offset + orientations[4*i+j]*position ) ; // all in m
878  else
879  oneStCluster->setXY( offset + orientations2[4*i+j]*position ) ; // all in m
880 
881  pp2ppColl->romanPot(i)->plane(j)->addCluster(oneStCluster);
882 
883  // }
884  /*
885  else
886  cout << "NOT Stored ! seq/chain : " << i+1 << "/" << j
887  << " , length = " << NCluster_Length << " , energy = " << ECluster
888  << " , position = " << POStimesE/ECluster << endl ;
889  */
890 
891  ECluster = 0 ;
892  POStimesE = 0 ;
893  POStimesESq = 0 ;
894  NCluster_Length = 0 ;
895 
896  }
897 
898  it++ ;
899 
900  } // while
901 
902  } // for ( Int_t j=0; j<kMAXCHAIN; j++) {
903 
904  mEvent = (StEvent *) GetInputDS("StEvent");
905  if ( mEvent ) {
906 
907  if ( mVersion>1 )
908  MakeTracks(*pp2ppColl, mEvent->runInfo()->beamEnergy(StBeamDirection::blue), mEvent->runInfo()->beamEnergy(StBeamDirection::yellow) );
909 
910  // Store into StEvent
911  mEvent->setRpsCollection(pp2ppColl);
912  }
913  else
914  LOG_ERROR << "St_pp2pp_Maker : StEvent not found !" << endm ;
915 
916  return kStOk ;
917 
918 }
919 
920 
921 //BEGIN ------------------------ Rafal's code ------------------------
922 
923 
924 Int_t St_pp2pp_Maker::MakeTracks(StRpsCollection &RpsColl, float blue_beamenergy, float yellow_beamenergy) {
925 
926  vector< StRpsTrackPoint* > trackPointsVec[kMAXSEQ];
927  vector< StRpsTrack* > trackVec;
928 
929  // reconstructing track-points
930  formTrackPoints( RpsColl, trackPointsVec );
931 
932  // reconstructing tracks
933  formTracks( &trackVec, trackPointsVec, blue_beamenergy, yellow_beamenergy );
934 
935  //filling StRpsCollection with track-points and tracks
936  for(int i=0; i<kMAXSEQ; ++i){
937  for(unsigned int j=0; j<trackPointsVec[i].size(); ++j){
938  RpsColl.addTrackPoint( trackPointsVec[i][j] );
939  }
940  }
941  for(unsigned int j=0; j<trackVec.size(); ++j){
942  RpsColl.addTrack( trackVec[j] );
943  }
944 
945  return kStOk ;
946 
947 }
948 
949 
950 void St_pp2pp_Maker::formTracks( vector< StRpsTrack* > *trackVec, const vector< StRpsTrackPoint* > *trackPointVec, const float beamMomentumWest, const float beamMomentumEast ) const{
951 
952  double beamMomentum[2];
953  beamMomentum[StBeamDirection::east] = beamMomentumEast;
954  beamMomentum[StBeamDirection::west] = beamMomentumWest;
955 
956  for(int branch=0; branch<kBranches; ++branch){ // loop over all branches in the Roman Pot system
957 
958  unsigned int side = ( branch < kBranches/2 ? StBeamDirection::east : StBeamDirection::west );
959  int sign = (side == StBeamDirection::east ? -1 : 1 );
960  int nPts[kStationsPerBranch]; // reading number of track-points found in the branch
961  nPts[kRP1] = trackPointVec[ kRpInBranch[branch][kRP1] ].size();
962  nPts[kRP2] = trackPointVec[ kRpInBranch[branch][kRP2] ].size();
963 
964  if( nPts[kRP1] && nPts[kRP2] ){ // if track-points reconstructed in both stations in branch
965 
966  for(int i=0; i<nPts[kRP1]; ++i){ // loops over all combinations of track-points
967  for(int j=0; j<nPts[kRP2]; ++j){
968  StRpsTrack* track = new StRpsTrack();
969 
970  track->setBranch( branch ); // setting ID of branch
971  track->setType( StRpsTrack::rpsGlobal ); // setting the type of the track
972  track->setTrackPoint( trackPointVec[ kRpInBranch[branch][kRP1] ][i], kRP1 ); // setting constituent track-points
973  track->setTrackPoint( trackPointVec[ kRpInBranch[branch][kRP2] ][j], kRP2 ); // setting constituent track-points
974 
975  // below calculating momentum vector
976  double localThetaX = track->thetaRp( StRpsTrack::rpsAngleThetaX ) - sign*mThetaXY_tilt[kX]; // REMINDER: sensitive to changes in StRpsTrack::thetaRp() !
977  double localThetaY = track->thetaRp( StRpsTrack::rpsAngleThetaY ) - sign*mThetaXY_tilt[kY]; // REMINDER: sensitive to changes in StRpsTrack::thetaRp() !
978  double x_BCS = trackPointVec[ kRpInBranch[branch][kRP1] ][i]->x() - mXYZ_IP[kX] - sin(mThetaXY_tilt[kX])*( trackPointVec[ kRpInBranch[branch][kRP1] ][i]->z() - mXYZ_IP[kZ] ); // x_RP1 in beam coordinate system
979  double d2 = abs( trackPointVec[ kRpInBranch[branch][kRP1] ][i]->z() ) - mLDX[side] - mDistanceFromIPtoDX[side]; // distance from DX magnet exit to first RP station
980  double thetaX_IP = ( x_BCS - (d2 + 0.5*mLDX[side])*localThetaX ) / ( mDistanceFromIPtoDX[side] + 0.5*mLDX[side] );
981  double xi = 1. / ( 1 + (mBendingAngle[side]*(mDistanceFromIPtoDX[side] + 0.5*mLDX[side])) / ( localThetaX*abs( trackPointVec[ kRpInBranch[branch][kRP1] ][i]->z() ) - x_BCS ) );
982  double momentumValue = beamMomentum[side] * (1.-xi);
983 
984  StThreeVectorF momentumVector( 0, 0, sign*momentumValue );
985  momentumVector.rotateX( -sign*localThetaY );
986  momentumVector.rotateY( sign*thetaX_IP );
987  track->setP( momentumVector ); // setting the momentum vector
988 
989  trackVec->push_back( track ); // storing the track
990  }
991  }
992  }
993  else if( nPts[kRP1] || nPts[kRP2] ){ // if track-point reconstructed only in one station in branch
994 
995  int station = nPts[kRP1] ? kRP1 : kRP2; // checking ID of station where track-point was found
996  for(int i=0; i<nPts[station]; ++i){ // loop over all track-points
997  StRpsTrack* track = new StRpsTrack();
998 
999  track->setBranch( branch ); // setting ID of branch
1000  track->setType( StRpsTrack::rpsLocal ); // setting the type of the track
1001  track->setTrackPoint( trackPointVec[ kRpInBranch[branch][station] ][i], station ); // setting constituent track-point
1002 
1003  // below calculating momentum vector (assuming no momentum loss == elastic track)
1004  double x_BCS = trackPointVec[ kRpInBranch[branch][station] ][i]->x() - mXYZ_IP[kX] - sin(mThetaXY_tilt[kX])*( trackPointVec[ kRpInBranch[branch][station] ][i]->z() - mXYZ_IP[kZ] ); // x_RP in beam coordinate system
1005  double y_BCS = trackPointVec[ kRpInBranch[branch][station] ][i]->y() - mXYZ_IP[kY] - sin(mThetaXY_tilt[kY])*( trackPointVec[ kRpInBranch[branch][station] ][i]->z() - mXYZ_IP[kZ] ); // y_RP in beam coordinate system
1006  double localThetaX = x_BCS / abs( trackPointVec[ kRpInBranch[branch][station] ][i]->z() );
1007  double localThetaY = y_BCS / abs( trackPointVec[ kRpInBranch[branch][station] ][i]->z() );
1008  double momentumValue = beamMomentum[side];
1009 
1010  StThreeVectorF momentumVector( 0, 0, sign*momentumValue );
1011  momentumVector.rotateX( -sign*localThetaY );
1012  momentumVector.rotateY( sign*localThetaX );
1013  track->setP( momentumVector ); // setting the momentum vector
1014 
1015  trackVec->push_back( track ); // storing the track
1016  }
1017  }
1018 
1019  }
1020 }
1021 
1022 
1023 void St_pp2pp_Maker::formTrackPoints(const StRpsCollection& RpsColl, vector< StRpsTrackPoint* > *trackPointVec ) const{
1024 
1025  for(int i=0; i<kMAXSEQ; ++i){ // loop over all Roman Pots
1026 
1027  // looking for hits in X and Y direction (necessary to determine (x,y) coordinates of track-point)
1028  vector<St_pp2pp_Maker::StRpsHit> hits[kCoordinates];
1029  hits[kY] = formHits(RpsColl.romanPot(i), kY);
1030  if( hits[kY].size()==0 ) continue; // if no hits in planes A&C => cannot reconstruct a track-point
1031  hits[kX] = formHits(RpsColl.romanPot(i), kX);
1032  if( hits[kX].size()==0 ) continue; // if no hits in planes B&D => cannot reconstruct a track-point
1033 
1034  // calculating time of detection in PMTs (invoked here to avoid multiple calclation in case of many hits)
1035  double time[2] = {-1, -1};
1036  for(unsigned int pmt=0; pmt<2; ++pmt){
1037  if( RpsColl.romanPot(i)->tac(pmt) < kMaxPedestalTAC ) continue; // don't calculate time if TAC is at pedestal
1038  time[pmt] = timeFromTAC( i, pmt, RpsColl.romanPot(i)->tac(pmt), RpsColl.romanPot(i)->adc(pmt) );
1039  }
1040 
1041  // loops over all combinations of hits in X and Y directions
1042  for(unsigned int j=0; j<hits[kX].size(); ++j){
1043  for(unsigned int k=0; k<hits[kY].size(); ++k){
1044  StRpsTrackPoint* trackPoint = new StRpsTrackPoint();
1045 
1046  // setting position of the track-point
1047  double x = hits[kX][j].mPositionXY;
1048  double y = hits[kY][k].mPositionXY;
1049  double z = (hits[kX][j].mPositionZ*hits[kX][j].mPlanesUsed + hits[kY][k].mPositionZ*hits[kY][k].mPlanesUsed) / (hits[kX][j].mPlanesUsed + hits[kY][k].mPlanesUsed);
1050  StThreeVectorF pos( x, y, z );
1051  trackPoint->setPosition( pos );
1052 
1053  // setting ID of Roman Pot
1054  trackPoint->setRpId( i );
1055 
1056  // setting IDs of clusters used to form a track-point
1057  for(int l=0; l<kPlanesPerCoordinate; ++l){
1058  trackPoint->setClusterId( hits[kY][k].mClusterId[l], kPlanes[kY][l] );
1059  trackPoint->setClusterId( hits[kX][j].mClusterId[l], kPlanes[kX][l] );
1060  }
1061 
1062  // setting time of the hit (in time units)
1063  for(unsigned int pmt=0; pmt<trackPoint->mNumberOfPmtsInRp; ++pmt){
1064  trackPoint->setTime( time[pmt], pmt );
1065  }
1066 
1067  // setting flag of track-point quality
1068  if( hits[kX][j].mGolden && hits[kY][k].mGolden ) trackPoint->setQuality( StRpsTrackPoint::rpsGolden );
1069  else trackPoint->setQuality( StRpsTrackPoint::rpsNormal );
1070 
1071  // storing a track-point in a vector
1072  trackPointVec[i].push_back( trackPoint );
1073  }
1074  }
1075 
1076  }
1077 }
1078 
1079 
1080 vector<St_pp2pp_Maker::StRpsHit> St_pp2pp_Maker::formHits(const StRpsRomanPot* Rp, const int coordinate) const{
1081 
1082  vector<St_pp2pp_Maker::StRpsHit> hitVec;
1083 
1084  vector<double> pos[kPlanesPerCoordinate];
1085  vector<int> en[kPlanesPerCoordinate];
1086  vector<int> len[kPlanesPerCoordinate];
1087  vector<int> id[kPlanesPerCoordinate];
1088 
1089  preselectClusters(Rp, coordinate, pos, en, len, id);
1090  int clCase = classifyClustersCase(pos);
1091 
1092  if(clCase>0){
1093 
1094  std::vector<int> validClusters[kPlanesPerCoordinate];
1095  bool matched = matchClusters(coordinate, clCase, pos, validClusters);
1096 
1097  if( matched ){ // if there are pair of clusters which match - use only those
1098  for(unsigned int k=0; k<validClusters[kFirst].size(); ++k){
1099  St_pp2pp_Maker::StRpsHit hit;
1100  hit.mPositionXY = ( pos[kFirst][validClusters[kFirst][k]] + pos[kSecond][validClusters[kSecond][k]] )/2;
1101  hit.mPositionZ = ( Rp->plane(kPlanes[coordinate][kFirst])->z() + Rp->plane(kPlanes[coordinate][kSecond])->z() )/2;
1102  for(int j=0; j<kPlanesPerCoordinate; ++j) hit.mClusterId[j] = id[j][validClusters[j][k]];
1103  hit.mPlanesUsed = kPlanesPerCoordinate;
1104  if(clCase==5) hit.mGolden = true; // golden hit <-- 1/1
1105  else hit.mGolden = false;
1106 
1107  hitVec.push_back( hit );
1108  }
1109  }
1110  else{ // if clusters don't match, use each one separately
1111  for(int j=0; j<kPlanesPerCoordinate; ++j){ // loop over 2 planes in given _coordinate_
1112  for(unsigned int k=0; k<pos[j].size(); ++k){
1113  St_pp2pp_Maker::StRpsHit hit;
1114  hit.mPositionXY = pos[j][k];
1115  hit.mPositionZ = Rp->plane(kPlanes[coordinate][j])->z();
1116  for(int l=0; l<kPlanesPerCoordinate; ++l){
1117  if(l==j) hit.mClusterId[l] = id[l][k];
1118  else hit.mClusterId[l] = -1;
1119  }
1120  hit.mPlanesUsed = 1;
1121  hit.mGolden = false;
1122  hitVec.push_back( hit );
1123  }
1124  }
1125  }
1126 
1127  }
1128 
1129  return hitVec;
1130 }
1131 
1132 
1133 void St_pp2pp_Maker::preselectClusters(const StRpsRomanPot* Rp, const int coordinate, vector<double>* pos, vector<int>* en, vector<int>* len, vector<int>* id) const{
1134  for(int j=0; j<kPlanesPerCoordinate; ++j){ // loop over planes measuring given _coordinate_
1135  const StRpsPlane* SiPlane = Rp->plane( kPlanes[coordinate][j] );
1136  int nClusters = SiPlane->numberOfClusters();
1137  if(nClusters < kMaxNumberOfClusterPerPlane) // continue only if nClusters is small, otherwise plane is not used in reconstruction
1138  for(int k=0; k < nClusters; ++k){ // loop over clusters in this plane
1139  const StRpsCluster* Cluster = SiPlane->cluster( k );
1140  int lenCluster = Cluster->length();
1141  if(lenCluster <= kMaxClusterLength && lenCluster>0){
1142  int enCluster = Cluster->energy();
1143  if(enCluster >= kEmin[ Rp->romanPotId() ][lenCluster-1]){ // allow using this cluster only if it passes the energy cut
1144  pos[j].push_back( Cluster->xy() );
1145  en[j].push_back( enCluster );
1146  len[j].push_back( lenCluster );
1147  id[j].push_back( k );
1148  }
1149  }
1150  }
1151  }
1152 }
1153 
1154 
1155 Int_t St_pp2pp_Maker::classifyClustersCase(vector<double>* pos) const{
1156  int lA = pos[kFirst].size();
1157  int lB = pos[kSecond].size();
1158 
1159  if( lA==0 && lB==0 ) return -1; else
1160  if( lA==1 && lB==1 ) return 5; else
1161  if( lA==1 && lB >1 ) return 6; else
1162  if( lA >1 && lB==1 ) return 7; else
1163  if( lA==0 && lB==1 ) return 2; else
1164  if( lA==1 && lB==0 ) return 1; else
1165  if( lA>=2 && lB>=2 ) return 8; else
1166  if( lA==0 && lB >1 ) return 4; else
1167  if( lA >1 && lB==0 ) return 3; else
1168  return -100;
1169 }
1170 
1171 
1172 Bool_t St_pp2pp_Maker::matchClusters(const int coordinate, const int clCase, const vector<double>* pos, std::vector<int>* validClusters) const{
1173  switch(clCase){
1174  case 5: if( areMatched(coordinate, pos[kFirst][0], pos[kSecond][0]) ){
1175  validClusters[kFirst].push_back( 0 );
1176  validClusters[kSecond].push_back( 0 );
1177  return true;
1178  } return false;
1179  case 6:
1180  case 7: {double DeltaPosition = 1e9;
1181  double minDeltaPosition = 1e9;
1182  int index[kPlanesPerCoordinate] = { -1, -1 };
1183  for(unsigned int c1=0; c1<pos[kFirst].size(); ++c1){
1184  for(unsigned int c2=0; c2<pos[kSecond].size(); ++c2){
1185  if(areMatched(coordinate, pos[kFirst][c1], pos[kSecond][c2], &DeltaPosition)){
1186  if(abs(DeltaPosition) < minDeltaPosition){
1187  minDeltaPosition = abs(DeltaPosition);
1188  index[kFirst] = c1;
1189  index[kSecond] = c2;
1190  }
1191  }
1192  }
1193  }
1194  if(index[kFirst]>-1){
1195  validClusters[kFirst].push_back( index[kFirst] );
1196  validClusters[kSecond].push_back( index[kSecond] );
1197  return true;
1198  } else return false;}
1199  case 8: {for(unsigned int c1=0; c1<pos[kFirst].size(); ++c1){
1200  for(unsigned int c2=0; c2<pos[kSecond].size(); ++c2){
1201  if(areMatched(coordinate, pos[kFirst][c1], pos[kSecond][c2])){
1202  validClusters[kFirst].push_back( c1 );
1203  validClusters[kSecond].push_back( c2 );
1204  }
1205  }
1206  }
1207  if(validClusters[kFirst].size()>0) return true;
1208  else return false;}
1209  default: return false;
1210  }
1211  return false;
1212 }
1213 
1214 
1215 Bool_t St_pp2pp_Maker::areMatched(const int coordinate, const double p1, const double p2, double *deltaPitches) const{
1216  if(deltaPitches) *deltaPitches = (p1 - p2) / kPitch[coordinate];
1217  return abs( p1 - p2 ) < kMaxPitchesToMatch*kPitch[coordinate] ? true : false;
1218 }
1219 
1220 
1221 
1222 const double St_pp2pp_Maker::kEmin[kMAXSEQ][kMaxClusterLength] =
1223  {{20, 20, 20, 20, 20},
1224  {20, 20, 20, 20, 20},
1225  {20, 20, 20, 20, 20},
1226  {20, 20, 20, 20, 20},
1227  {20, 20, 20, 20, 20},
1228  {20, 20, 20, 20, 20},
1229  {20, 20, 20, 20, 20},
1230  {20, 20, 20, 20, 20}};
1231 
1232 const int St_pp2pp_Maker::kPlanes[kCoordinates][kPlanesPerCoordinate] =
1233  {{1, 3}, // kX (vertical strips)
1234  {0, 2}}; // kY (horizontal strips)
1235 
1236 const int St_pp2pp_Maker::kRpInBranch[kBranches][kStationsPerBranch] =
1237  {{0, 2}, {1, 3},
1238  {4, 6}, {5, 7}};
1239 
1240 //END ------------------------ Rafal's code ------------------------
1241 
1242 
1243 
1244 
1245 
1247  return StMaker::Finish();
1248 }
1249 
1250 
For pp2pp analysis : mainly to create clusters from raw data silicon hits.
Class StRTSBaseMaker - is an abstract StMaker to define the interface to access the DAQ data from the...
virtual Int_t Make()
Make - this method is called in loop for each event.
virtual void Clear(Option_t *option="")
User defined functions.
Definition: StMaker.cxx:634
Int_t MakeTracks(StRpsCollection &RpsColl, float blue_beamenergy, float yellow_beamenergy)
Int_t DoerPp2pp(const pp2pp_t &d, TGenericTable &hitsTable)
DoerPp2pp - this method is called as soon as next pp2pp record is read in.
virtual Int_t AddAt(const void *c)
Definition: TTable.cxx:1122
virtual Int_t Finish()
virtual void Clear(Option_t *option="")
Clear - this method is called in loop for prepare the maker for the next event.
virtual Int_t Init()
Init - is a first method the top level StChain calls to initialize all its makers.
Definition: Stypes.h:40
virtual Int_t Finish()
Definition: StMaker.cxx:776
virtual TObject * GetObject() const
The depricated method (left here for the sake of the backward compatibility)
Definition: TObjectSet.h:56
Definition: Stypes.h:41
virtual TDataSet * Find(const char *path) const
Definition: TDataSet.cxx:362
Definition: Stypes.h:45