StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
maker.cc
1 //
3 //
4 #define HISTOGRAM 1
5 #define UNPACK_ALL
6 #define ALL_OF_IT
7 //
8 //
10 #include <Stiostream.h>
11 #include <unistd.h>
12 
13 #include <string>
14 #include <vector>
15 #include <list>
16 #include <utility> // pair
17 #include <algorithm> // min() max()
18 
19 // SCL
20 #include "StGlobals.hh"
21 #include "StMatrix.hh"
22 #include "Randomize.h"
23 #ifdef HISTOGRAM
24 #include "StHbook.hh"
25 #endif
26 // General TRS
27 #include "StCoordinates.hh"
28 #include "StTpcCoordinateTransform.hh"
29 
30 // TRS
31 // db
32 #include "StTpcSimpleGeometry.hh"
33 #include "StTpcSimpleSlowControl.hh"
34 #include "StTpcSimpleElectronics.hh"
35 #include "StSimpleMagneticField.hh"
36 #include "StTrsDeDx.hh"
37 
38 // processes
39 #include "StTrsFastChargeTransporter.hh"
40 #include "StTrsSlowAnalogSignalGenerator.hh"
41 #include "StTrsFastDigitalSignalGenerator.hh"
42 
43 // containers
44 #include "StTrsChargeSegment.hh"
45 #include "StTrsMiniChargeSegment.hh"
46 #include "StTrsAnalogSignal.hh"
47 #include "StTrsWireBinEntry.hh"
48 #include "StTrsWireHistogram.hh"
49 
50 #include "StTrsSector.hh"
51 #include "StTrsDigitalSector.hh"
52 
53 // outPut Data--decoder
54 #include "StTrsRawDataEvent.hh"
55 #include "StTrsUnpacker.hh"
56 #include "StSequence.hh"
57 
58 // g2t tables
59 #include "g2t_tpc_hit.hh"
60 //#include "St_g2t_tpc_hit_Table.h"
61 //#include "St_g2t_track_Table.h"
62 
63 void whichSector(int volId, int* isDet, int* sector, int* padrow){
64 
65  //cout << "StTrsMaker::whichSector()" << endl;
66  //cout << volId << endl;
67  *isDet = (volId/100000);
68 
69  volId -= (*isDet)*100000;
70  *sector = volId/100;
71 
72  volId -= (*sector)*100;
73  *padrow = volId;
74 
75 }
76 
77 int main()
78 {
79 #ifdef HISTOGRAM
80  cout << "Histogram" << endl;
81 
82  //
83  // Open histogram file and book tuple
84  //
85  string fname = "hbook";
86  StHbookFile *hbookFile =
87  new StHbookFile(fname.c_str());
88 
89  //
90  // Unpacker Data
91  const int tupleSize1 = 5;
92  float tuple[tupleSize1];
93  StHbookTuple *theTuple =
94  new StHbookTuple("data", tupleSize1);
95  *theTuple << "sec" << "row" << "pad" << "amp" << "t" << book;
96 
97  //
98  const int tupleSize2 = 5;
99  float tuple2[tupleSize2];
100  StHbookTuple *secTuple =
101  new StHbookTuple("dedx", tupleSize2);
102 
103  *secTuple << "sec" << "row" << "x" << "y" << "z" << book;
104 #endif
105  //
106  // Make the DataBase
107  //
108  // Check File access
109  //
110  cout << "*********************************************" << endl;
111  cout << "Try Initialize" << endl;
112  string geoFile("../run/TPCgeo.conf");
113  if (access(geoFile.c_str(),R_OK)) {
114  cerr << "ERROR:\n" << geoFile.c_str() << " cannot be opened" << endl;
115  //shell(pwd);
116  cerr << "Exitting..." << endl;
117  exit(1);
118  }
119 
120  string scFile = "../run/sc.conf";
121  if (access(scFile.c_str(),R_OK)) {
122  cerr << "ERROR:\n" << scFile.c_str() << " cannot be opened" << endl;
123  cerr << "Exitting..." << endl;
124  exit(1);
125  }
126 
127  string electronicsFile = "../run/electronics.conf";
128  if (access(electronicsFile.c_str(),R_OK)) {
129  cerr << "ERROR:\n" << electronicsFile.c_str() << " cannot be opened" << endl;
130  cerr << "Exitting..." << endl;
131  exit(1);
132  }
133 
134  string magFile = "../run/example.conf"; // contains B field
135  if (access(magFile.c_str(),R_OK)) {
136  cerr << "ERROR:\n" << magFile.c_str() << " cannot be opened" << endl;
137  cerr << "Exitting..." << endl;
138  exit(1);
139  }
140 
141  //
142  // The DataBases
143  //
144  StTpcGeometry *mGeometryDb =
145  StTpcSimpleGeometry::instance(geoFile.c_str());
146  //mGeometryDb->print();
147 
148  StTpcSlowControl *mSlowControlDb =
149  StTpcSimpleSlowControl::instance(scFile.c_str());
150 
151  StMagneticField *mMagneticFieldDb =
152  StSimpleMagneticField::instance(magFile.c_str());
153 
154  StTpcElectronics *mElectronicsDb =
155  StTpcSimpleElectronics::instance(electronicsFile.c_str());
156  //mElectronicsDb->print();
157 
158  string gas =("Ar");
159  StTrsDeDx *mGasDb = new StTrsDeDx(gas);
160  //mGasDb->print();
161 
162  //
163  // Containers
164  //
165 
166  // A Wire Plane
167  StTrsWireHistogram *mWireHistogram =
168  StTrsWireHistogram::instance(mGeometryDb, mSlowControlDb);
169 // mWireHistogram->setDoGasGain(true); // True by default
170 // mWireHistogram->setDoGasGainFluctuations(true);
171  mWireHistogram->setGasGainInnerSector(2000); // True by default
172  mWireHistogram->setGasGainOuterSector(1000);
173  mWireHistogram->setDoTimeDelay(false);
174 
175  // create a Sector:
176  // Analog (for calculation)
177  StTrsSector *mSector =
178  new StTrsSector(mGeometryDb);
179 
180  // Output is into an StTpcRawDataEvent* vector<StTrsDigitalSector*>
181  // which is accessible via the StTrsUnpacker
182  StTrsUnpacker *mUnPacker = new StTrsUnpacker;
183 
184  StTrsRawDataEvent *mAllTheData =
185  new StTrsRawDataEvent();
186  //
187  // Processes
188  //
189  StTrsChargeTransporter *mChargeTransporter =
190  StTrsFastChargeTransporter::instance(mGeometryDb, mSlowControlDb, mGasDb, mMagneticFieldDb);
191  // set status:
192  mChargeTransporter->setChargeAttachment(true);
193  mChargeTransporter->setGatingGridTransparency(false);
194 // mChargeTransporter->setTransverseDiffusion(true);
195 // mChargeTransporter->setLongitudinalDiffusion(true);
196  mChargeTransporter->setExB(false);
197 
198 
199  StTrsAnalogSignalGenerator *mAnalogSignalGenerator =
200  StTrsSlowAnalogSignalGenerator::instance(mGeometryDb, mSlowControlDb, mElectronicsDb, mSector);
201  //
202  // Set the function for the induced charge on Pad
203  //
204  static_cast<StTrsSlowAnalogSignalGenerator*>(mAnalogSignalGenerator)->
205  setChargeDistribution(StTrsSlowAnalogSignalGenerator::endo);
206  //setChargeDistribution(StTrsSlowAnalogSignalGenerator::gatti);
207  //setChargeDistribution(StTrsSlowAnalogSignalGenerator::dipole);
208  //
209  // Set the function for the Analog Electronics signal shape
210  //
211  static_cast<StTrsSlowAnalogSignalGenerator*>(mAnalogSignalGenerator)->
212  setElectronicSampler(StTrsSlowAnalogSignalGenerator::symmetricGaussianApproximation);
213  //setElectronicSampler(StTrsSlowAnalogSignalGenerator::delta);
214  //setElectronicSampler(StTrsSlowAnalogSignalGenerator::symmetricGaussianExact);
215  //setElectronicSampler(StTrsSlowAnalogSignalGenerator::asymmetricGaussianApproximation);
216  //setElectronicSampler(StTrsSlowAnalogSignalGenerator::realShaper);
217  mAnalogSignalGenerator->setDeltaRow(0);
218  mAnalogSignalGenerator->setDeltaPad(2);
219  mAnalogSignalGenerator->setSignalThreshold(1.*(.001*volt));
220  mAnalogSignalGenerator->setSuppressEmptyTimeBins(true);
221  mAnalogSignalGenerator->addNoise(false);
222  mAnalogSignalGenerator->generateNoiseUnderSignalOnly(false);
223  mAnalogSignalGenerator->setNoiseRMS(900.); // set in #e
224 
225  StTrsDigitalSignalGenerator *mDigitalSignalGenerator =
226  StTrsFastDigitalSignalGenerator::instance(mElectronicsDb, mSector);
227 
229 
230 // // Read the Ionization
231 // //
232 
233  cout << "Processing" << endl;
234 
235  int bisdet, bsectorOfHit, bpadrow;
236 
237  // Where is the first hit in the TPC
238  //whichSector(tpc_hit->volume_id, &bisdet, &bsectorOfHit, &bpadrow);
239 // PR(bisdet);
240 // PR(bsectorOfHit);
241 // PR(bpadrow);
242 // PR(currentSectorProcessed);
243 
244  //ifstream ifs("/data/stix/event_global.txt",ios::in);
245  ifstream ifs("/data/stix/event_14.txt",ios::in);
246  //ifstream ifs("/data/stix/trial.txt",ios::in); // 2000 hits in 13 sectors
247  g2t_tpc_hit tpc_hit;
248 
249  //
250  // the Limits
251  int firstSectorToProcess = 1;
252  int lastSectorToProcess = 1;
253  PR(firstSectorToProcess);
254  PR(lastSectorToProcess);
255  bool low = false;
256  bool high = false;
257 
258  //
259  // Bookeeping
260  int currentSectorProcessed = firstSectorToProcess;
261  int lastSectorProcessed = currentSectorProcessed;
262 
263  //
264  //
265  int numberOfPointsInWirePlane = 0;
266 
267  int no_tpc_hits = 400000;
268  //int no_tpc_hits = 15000;
269  //int no_tpc_hits = 18412; // hits in sector 1
270  //int no_tpc_hits = 331;
271  int i=0;
272  do {
273  i++;
274  cout << "--> tpc_hit: " << i << endl;
275  ifs >> tpc_hit.volume_id
276  >> tpc_hit.de
277  >> tpc_hit.ds
278  >> tpc_hit.x
279  >> tpc_hit.p;
280  if(ifs.eof() || ifs.bad()) break;
281 // cout << tpc_hit << endl;
282  whichSector(tpc_hit.volume_id, &bisdet, &bsectorOfHit, &bpadrow);
283 // PR(bisdet);
284 // PR(bsectorOfHit);
285 // PR(bpadrow);
286 
287  if(bsectorOfHit >= firstSectorToProcess)
288  low = true;
289  else
290  low = false;
291 
292  if(bsectorOfHit <= lastSectorToProcess)
293  high = true;
294  else
295  high = false;
296 
297  // Save time initially - by not processing pseudo padrows
298  if(bisdet) {
299 // cout << "Segment in a pseudo-padRow. Skipping..." << endl;
300  if(i != no_tpc_hits) continue;
301  }
302 
303 
304  if( low &&
305  high &&
306  i != no_tpc_hits &&
307  (bsectorOfHit == currentSectorProcessed)) {
308 
309  int pID = 1; // I need to know the PID for ionization calculations
310 
311  // I can't believe this. After such careful design of the coordinate
312  // transformation, I am reduced to this because I am fixed to GEANT
313  // coordinates. This is the problem you get if you
314  // don't use a common data base
315  // GEANT uses: (which is not correct!)
316 
317  double GEANTDriftLength = 208.55119*centimeter;
318  double GEANTOffSet = mGeometryDb->frischGrid() - GEANTDriftLength;
319 // PR(GEANTOffSet);
320 // PR(GEANTDriftLength);
321 
322  // Now relative to this, we get the zPosition in coordinates where :
323  // 0 is the membrane, 208+/-dz is the wire grid
324  //double zPosition = tpc_hit.x[2]*centimeter + GEANTOffSet; // ?
325  double zPosition = tpc_hit.x[2]*centimeter;
326 // PR(tpc_hit->x[2]*centimeter);
327 // PR(zPosition);
328 
329  StThreeVector<double> hitPosition(tpc_hit.x[0]*centimeter,
330  tpc_hit.x[1]*centimeter,
331  tpc_hit.x[2]*centimeter);
332 // PR(hitPosition);
333 
334 // // Drift Length is calculated with respect to the FG!
335 // double fgOffSet = (bpadrow <= mGeometryDb->numberOfInnerRows()) ?
336 // mGeometryDb->innerSectorFrischGridPadPlaneSeparation() :
337 // mGeometryDb->innerSectorFrischGridPadPlaneSeparation();
338 
339 // PR(mGeometryDb->radialDistanceAtRow(bpadrow));
340 // PR(mGeometryDb->radialDistanceAtRow(bpadrow)/centimeter);
341 // PR(mGeometryDb->frischGrid());
342 
343  // And we have our choice of coordinate system.
344  // Let us use globals for now:
345  // could use Matrix, but let's not for now.
346  // This is code copy from coordinate transform...
347 // PR(bsectorOfHit);
348  double beta = (bsectorOfHit>12) ?
349  -bsectorOfHit*M_PI/6 :
350  bsectorOfHit*M_PI/6 ; //(30 degrees)
351 // PR(beta*30/(M_PI/6));
352  double xp = hitPosition.x()*cos(beta) - hitPosition.y()*sin(beta);
353  double yp = hitPosition.x()*sin(beta) + hitPosition.y()*cos(beta);
354 
356  sector12Coordinate(xp*centimeter,
357  yp*centimeter,
358  zPosition);
359 // PR(sector12Coordinate);
360  //tpc_hit->x[2]*centimeter + mGeometryDb->frischGrid() + fgOffSet);
361  StThreeVector<double> hitMomentum(tpc_hit.p[0]*GeV,
362  tpc_hit.p[1]*GeV,
363  tpc_hit.p[2]*GeV);
364 
365  // I need PID info here, otherwise it is a pion. This is needed for the ionization splitting!
366  StTrsChargeSegment aSegment(sector12Coordinate,
367  hitMomentum,
368  (fabs(tpc_hit.de*GeV)), // cannot use abs (not overloaded for LINUX!
369  tpc_hit.ds*centimeter,
370  pID);
371 
372 #ifdef HISTOGRAM
373  tuple2[0] = static_cast<float>(bsectorOfHit);
374  tuple2[1] = static_cast<float>(bpadrow);
375  tuple2[2] = static_cast<float>(sector12Coordinate.x());
376  tuple2[3] = static_cast<float>(sector12Coordinate.y());
377  tuple2[4] = static_cast<float>(sector12Coordinate.z());
378  secTuple->fill(tuple2);
379 #endif
380 
381 // PR(hitMomentum.mag());
382 // PR(aSegment);
383 
384 #ifndef ST_NO_TEMPLATE_DEF_ARGS
385  vector<int> all[3];
386 #else
387  vector<int,allocator<int> > all[3];
388 #endif
389 
390 #ifndef ST_NO_TEMPLATE_DEF_ARGS
391  list<StTrsMiniChargeSegment> comp;
392  list<StTrsMiniChargeSegment>::iterator iter;
393 #else
394  list<StTrsMiniChargeSegment,allocator<StTrsMiniChargeSegment> > comp;
395  list<StTrsMiniChargeSegment,allocator<StTrsMiniChargeSegment> >::iterator iter;
396 #endif
397  int breakNumber = 1;
398 // PR(aSegment.ds()/millimeter);
399  //breakNumber = aSegment.ds()/(4.*millimeter);
400 // PR(breakNumber);
401  aSegment.split(mGasDb, mMagneticFieldDb, breakNumber, &comp);
402 
403 
404 #ifndef ST_NO_TEMPLATE_DEF_ARGS
405 // copy(comp.begin(), comp.end(), ostream_iterator<StTrsMiniChargeSegment>(cout,"\n"));
406 // cout << endl;
407 #endif
408 
409 // cout << "-->Number of \"miniSegments\": " << (comp.size()) << endl;
410 
411  // Loop over the miniSegments
412  for(iter = comp.begin();
413  iter != comp.end();
414  iter++) {
415 
416  //
417  // TRANSPORT HERE
418  //
419  mChargeTransporter->transportToWire(*iter);
420 // PR(*iter);
421 
422  //
423  // CHARGE COLLECTION AND AMPLIFICATION
424  //
425 
426 #ifndef __sun // Bug in the sun iterators. Must Explicitly dereference!
427  StTrsWireBinEntry anEntry(iter->position(), iter->charge());
428 // PR(anEntry);
429 #else
430  StTrsWireBinEntry anEntry((*iter).position(), (*iter).charge());
431 #endif
432  mWireHistogram->addEntry(anEntry);
433 
434  } // Loop over the list of iterators
435 
436  //
437  // Evaluate the situation:
438  // are you at the end of a data file?
439  // should you continue processing this sector?
440  // if eof, break;
441  // PR(i);
442  // PR(no_tpc_hits);
443 
444  //tpc_hit++; // increase the pointer to the next hit
445  numberOfPointsInWirePlane++;
446  continue; // don't digitize, you still have data in the same sector to process
447  } // if (currentSector == bsectorOfHit)
448 
449  // Do the digitization, if there are points in the wire plane...
450  if(numberOfPointsInWirePlane) {
451  cout << "Processing Sector: " << currentSectorProcessed << endl;
452  //sleep(3);
453  //
454  // Generate the ANALOG Signals on pads
455  //
456  cout << "--->inducedChargeOnPad()..." << endl;
457  mAnalogSignalGenerator->inducedChargeOnPad(mWireHistogram);
458 
459  cout << "--->sampleAnalogSignal()..." << endl;
460  mAnalogSignalGenerator->sampleAnalogSignal();
461  //
462  // Digitize the Signals
463  //
464  // First make a sector where the data can go...
465  StTrsDigitalSector* aDigitalSector =
466  new StTrsDigitalSector(mGeometryDb);
467  //
468  // Point to the object you wnat to fill
469  //
470  mDigitalSignalGenerator->fillSector(aDigitalSector);
471 
472  //
473  // ...and digitize it
474  cout << "--->digitizeSignal()..." << endl;
475  mDigitalSignalGenerator->digitizeSignal();
476 
477  //
478  // Fill it into the event structure...
479  // and you better check the sector number!
480  // PR(currentSectorProcessed);
481  // PR(mAllTheData->mSectors.size());
482 
483  // cout << "Try add it" << endl;
484  mAllTheData->mSectors[(currentSectorProcessed-1)] = aDigitalSector;
485 // PR(mAllTheData->mSectors[(currentSectorProcessed-1)]->numberOfRows());
486 // cout << "okay" << endl;
487 
488  // Clear and reset for next sector:
489  mWireHistogram->clear();
490  mSector->clear();
491  numberOfPointsInWirePlane = 0;
492  //
493  // Go to the next sector
494  PR(currentSectorProcessed);
495  currentSectorProcessed = bsectorOfHit;
496 // if(currentSectorProcessed>13) break;
497  PR(currentSectorProcessed);
498  PR(bsectorOfHit);
499 
500  // This is the place if you want to process one sector only.
501  //
502  //break; // Finish here
503  //
504  } // digitization
505 
506  // tpc_hit++;
507 
508  } while(true);// loop over all segments: for(int i...
509  //} // mDataSet
510 
511  // The access stuff:
512 #ifdef UNPACK_ALL
513  //
514  // Access it!
515  // with:
516  // *mUnPacker
517  cout << "Try Access the data!" << endl;
518  //
519  // Loop around the sectors: (should be from db, or size of the structure!)
520  PR(mAllTheData->mSectors.size());
521  for(int isector=1; isector<=24; isector++) {
522  int getSectorStatus =
523  mUnPacker->getSector(isector,
524  static_cast<StTpcRawDataEvent*>(mAllTheData));
525  //PR(getSectorStatus);
526 
527  // if getSectorStatus is bad move on to the next sector
528  if(getSectorStatus) continue;
529 
530  // otherwise, let's decode it
531  unsigned char* padList;
532  for(int irow=1; irow<=45; irow++) {
533 #ifdef ALL_OF_IT
534  PR(irow);
535 #endif
536  int numberOfPads = mUnPacker->getPadList(irow, &padList);
537  PR(numberOfPads);
538 
539  if(!numberOfPads)
540  continue; // That is, go to the next row...
541 
542  for(int ipad = 0; ipad<numberOfPads; ipad++) {
543 #ifdef ALL_OF_IT
544 // PR(ipad);
545  PR(static_cast<int>(padList[ipad]));
546 #endif
547  int nseq;
548 
549  //mUnPacker->clearSequences();
550  StSequence* listOfSequences;
551  int getSequencesStatus =
552  mUnPacker->getSequences(irow, padList[ipad], &nseq, &listOfSequences);
553 
554  PR(getSequencesStatus);
555 #ifdef ALL_OF_IT
556  PR(nseq);
557 #endif
558  for(int kk=0; kk<nseq; kk++) {
559 #ifdef ALL_OF_IT
560  PR(listOfSequences[kk].length);
561  PR(listOfSequences[kk].startTimeBin);
562 
563  for(int zz=0; zz<listOfSequences[kk].length; zz++) {
564  cout << " " << kk << " " << zz << '\t'
565  << '\t' << static_cast<int>(*(listOfSequences[kk].firstAdc)) << endl;
566  tuple[0] = static_cast<float>(isector);
567  tuple[1] = static_cast<float>(irow);
568  tuple[2] = static_cast<float>(padList[ipad]);
569  tuple[3] = static_cast<float>(static_cast<int>(*(listOfSequences[kk].firstAdc)));
570  tuple[4] = static_cast<float>(listOfSequences[kk].startTimeBin+zz);
571  theTuple->fill(tuple);
572 
573  listOfSequences[kk].firstAdc++;
574  } // zz
575 #endif
576 // cout << endl;
577  } // Loop kk
578  //mUnPacker->clearSequences();
579  } // loop over pads
580 
581  // Do the data manipulation here!
582  mUnPacker->clear();
583 
584  } // Loop over rows!
585 
586  } // Loop over sectors
587 #endif
588 
589  cout << "Got to the end of the maker" << endl;
590 
591 #ifdef HISTOGRAM
592  cout << "Save and close " << endl;
593  hbookFile->saveAndClose();
594 #endif
595  return 0;
596 }
597 
598 // *****************************************************************
599 // Make sure the memory is deallocated!
600 // Either Finish() or clean()
601 // Make sure the return type is proper!
602 //
603 // void StTrsMaker::Finish()
604 //{
605 // Clean up all the pointers that were initialized in StTrsMaker::Init()
606 // delete mGeometryDb;
607 // delete mSlowControlDb;
608 // delete mMagneticFieldDb;
609 // delete mElectronicsDb;
610 // delete mGasDb;
611 
612 // delete mWireHistogram;
613 // delete mSector;
614 // delete mUnPacker;
615 // delete mAllTheData;
616 
617 // delete mChargeTransporter;
618 // delete mAnalogSignalGenerator;
619 // delete mDigitalSignalGenerator;
620 //}