#include "lcio.h"
#include "IO/LCWriter.h"
#include "EVENT/LCIO.h"
#include "DATA/LCFloatVec.h"
#include "DATA/LCIntVec.h"
#include "IMPL/LCEventImpl.h"
#include "IMPL/LCRunHeaderImpl.h"
#include "IMPL/LCCollectionVec.h"
#include "IMPL/SimCalorimeterHitImpl.h"
#include "IMPL/SimTrackerHitImpl.h"
#include "IMPL/MCParticleImpl.h"
#include "IMPL/LCFlagImpl.h"
#include "IMPL/LCTOOLS.h"
#include "IMPL/TrackerRawDataImpl.h"
#include "IMPL/TrackerDataImpl.h"
#include "IMPL/TrackerPulseImpl.h"
#include "UTIL/LCRelationNavigator.h"
#include "UTIL/LCTime.h"
#include "UTIL/CellIDEncoder.h"
#include "UTIL/LCTypedVector.h"
#include "UTIL/LCSplitWriter.h"
#include <cstdlib>
#include <iostream>
#include <sstream>
Include dependency graph for simjob.cc:
Go to the source code of this file.
Defines | |
#define | WRITE_TRACKERRAWDATA 1 |
#define | WRITE_VTXRAWHITS 1 |
Functions | |
int | main (int argc, char **argv) |
Variables | |
static const int | NRUN = 10 |
static const int | NEVENT = 10 |
static const int | NMCPART = 10 |
static const int | NHITS = 50 |
static string | FILEN = "simjob.slcio" |
#define WRITE_TRACKERRAWDATA 1 |
#define WRITE_VTXRAWHITS 1 |
int main | ( | int | argc, | |
char ** | argv | |||
) |
Simple test program to demonstrate writing of data with lcio.
Definition at line 53 of file simjob.cc.
00053 { 00054 00055 try{ 00056 00057 00058 // loop over runs 00059 for(int rn=0;rn<NRUN;rn++){ 00060 00061 // create sio writer 00062 LCWriter* lcWrt = LCFactory::getInstance()->createLCWriter() ; 00063 00064 //LCWriter* lcWrt = new LCSplitWriter( LCFactory::getInstance()->createLCWriter(), 20000 ) ; 00065 00066 if( argc > 1 ) { FILEN = argv[1] ; } 00067 00068 // lcWrt->setCompressionLevel(0 ) ; 00069 00070 if( rn==0 ){ 00071 // turn off compression for first run ... 00072 lcWrt->setCompressionLevel( 0 ) ; 00073 lcWrt->open( FILEN , LCIO::WRITE_NEW ) ; 00074 00075 }else{ 00076 lcWrt->setCompressionLevel( 9 ) ; 00077 lcWrt->open( FILEN , LCIO::WRITE_APPEND ) ; 00078 } 00079 // NB: in order to test writing multiple files we create a new LCWriter 00080 // for every run even though we are in fact writing to one file only; 00081 // so for a simple job writing one file the 00082 // 'createLCWriter/open' and 'close/delete' will be outside the run loop... 00083 00084 00085 LCRunHeaderImpl* runHdr = new LCRunHeaderImpl ; 00086 runHdr->setRunNumber( rn ) ; 00087 00088 string detName("D09TileHcal") ; 00089 runHdr->setDetectorName( detName ) ; 00090 00091 stringstream description ; 00092 description << " run: " << rn <<" just for testing lcio - no physics !" ; 00093 runHdr->setDescription( description.str() ) ; 00094 00095 string ecalName("ECAL007") ; 00096 runHdr->addActiveSubdetector( ecalName ) ; 00097 00098 string tpcName("TPC4711") ; 00099 runHdr->addActiveSubdetector( tpcName ) ; 00100 00101 00102 // add some parameters to the run header 00103 // StringVec sv1 ; 00104 // sv1.push_back("simjob.cc") ; 00105 // runHdr->parameters().setValues( "SimulationProgram" , sv1 ) ; 00106 runHdr->parameters().setValue( "SimulationProgram" , "simjob.cc" ) ; 00107 IntVec iv(3) ; 00108 iv[0] = 1 ; 00109 iv[1] = 2 ; 00110 iv[2] = 3 ; 00111 runHdr->parameters().setValues( "SomeIndices" , iv ) ; 00112 00113 lcWrt->writeRunHeader( runHdr ) ; 00114 00115 // EventLoop - create some events and write them to the file 00116 for(int i=0;i<NEVENT;i++){ 00117 00118 // we need to use the implementation classes here 00119 LCEventImpl* evt = new LCEventImpl() ; 00120 00121 00122 evt->setRunNumber( rn ) ; 00123 evt->setEventNumber( i ) ; 00124 LCTime now ; 00125 evt->setTimeStamp( now.timeStamp() ) ; 00126 evt->setDetectorName( detName ) ; 00127 00128 evt->setWeight( 1.*rand()/RAND_MAX ) ; 00129 00130 evt->parameters().setValue("Description"," event can have it's own set of parameters" ) ; 00131 evt->parameters().setValue("Thrust", (float) 0.671 ) ; 00132 00133 FloatVec fv ; 00134 fv.push_back( 1.1 ) ; 00135 fv.push_back( 2.2 ) ; 00136 fv.push_back( 3.3 ) ; 00137 evt->parameters().setValues( "SomeNumbers" , fv ) ; 00138 00139 // create and add some mc particles 00140 LCCollectionVec* mcVec = new LCCollectionVec( LCIO::MCPARTICLE ) ; 00141 00142 // debug only - don't write MCParticles to output file: 00143 // mcVec->setTransient() ; 00144 00145 // debug only - add the same particle to more than one collection 00146 //LCCollectionVec* mcVec2 = new LCCollectionVec( LCIO::MCPARTICLE ) ; 00147 00148 MCParticleImpl* mom = new MCParticleImpl ; 00149 mom->setPDG( 1 ) ; 00150 float p0[3] = { 0. , 0. , 1000. } ; 00151 mom->setMomentum( p0 ) ; 00152 mom->setMass( 3.01 ) ; 00153 00154 00155 for(int j=0;j<NMCPART;j++){ 00156 00157 MCParticleImpl* mcp = new MCParticleImpl ; 00158 00159 mcp->setPDG( 1000 * (j+1) ) ; 00160 float p[3] = { j*1. , 4./1024. , 8./1024. } ; 00161 mcp->setMomentum( p ) ; 00162 mcp->setMass( .135 ) ; 00163 00164 // create and add some daughters 00165 for(int k=0;k<3;k++){ 00166 MCParticleImpl* d1 = new MCParticleImpl ; 00167 00168 d1->setPDG( 1000 * (j+1) + 100 * (k+1) ) ; 00169 float pd1[3] = { k*1. , 4.1 , 8.1 } ; 00170 d1->setMomentum( pd1 ) ; 00171 d1->setMass( .135 ) ; 00172 00173 for(int l=0;l<2;l++){ 00174 MCParticleImpl* d2 = new MCParticleImpl ; 00175 00176 d2->setPDG( 1000 * (j+1) + 100 * (k+1) + 10 * (l+1) ) ; 00177 float pd2[3] = { l*1. , 0.41 , 4.1 } ; 00178 d2->setMomentum( pd2 ) ; 00179 d2->setMass( .135 ) ; 00180 00181 double ep[3] = { 1.111111 , 2.2222222, 3.3333333 } ; 00182 d2->setEndpoint( ep ) ; 00183 // d2->setSimulatorStatus( 1234 ) ; 00184 d2->setCreatedInSimulation(true) ; 00185 d2->setBackscatter(true) ; 00186 d2->setDecayedInTracker(true) ; 00187 d2->setDecayedInCalorimeter(false); 00188 d2->setHasLeftDetector(false) ; 00189 d2->setStopped(true) ; 00190 00191 d2->addParent( d1 ); 00192 mcVec->push_back( d2 ) ; 00193 00194 // debug only - add the same particle to more than one collection 00195 //mcVec2->push_back( d2 ) ; 00196 } 00197 d1->addParent( mcp ); 00198 mcVec->push_back( d1 ) ; 00199 } 00200 00201 mcp->addParent( mom ); 00202 mcVec->push_back( mcp ) ; 00203 } 00204 mcVec->push_back( mom ) ; 00205 00206 // now add some calorimeter hits 00207 LCCollectionVec* calVec = new LCCollectionVec( LCIO::SIMCALORIMETERHIT ) ; 00208 00209 // set flag for long format (including position ) 00210 // and PDG and cellid1 00211 LCFlagImpl chFlag(0) ; 00212 chFlag.setBit( LCIO::CHBIT_LONG ) ; 00213 chFlag.setBit( LCIO::CHBIT_PDG ) ; 00214 calVec->setFlag( chFlag.getFlag() ) ; 00215 00216 std::string cellIDEncoding( "M:3,S-1:3,I:9,J:9,K-1:6") ;// old Mokka convention 00217 00218 // std::string cellIDEncoding( "M:3,S-1:3,I:9,J:9,K-1:6,Bla:34:6") ;// for testing cellid1 00219 00220 CellIDEncoder<SimCalorimeterHitImpl> b( cellIDEncoding , calVec ) ; 00221 00222 for(int j=0;j<NHITS;j++){ 00223 00224 SimCalorimeterHitImpl* hit = new SimCalorimeterHitImpl ; 00225 00226 hit->setEnergy( 3.1415 * rand()/RAND_MAX ) ; 00227 00228 float pos[3] = { 1.1* rand()/RAND_MAX , 2.2* rand()/RAND_MAX , 3.3* rand()/RAND_MAX } ; 00229 00230 // cell indices 00231 b["M"] = j % 8 ; 00232 b["S-1"] = (j+2) % 8 ; 00233 b["I"] = j % 512 ; 00234 b["J"] = (j+128) % 512 ; 00235 b["K-1"] = (j+32) % 64 ; 00236 00237 b.setCellID( hit ) ; 00238 00239 // hit->setCellID0( b.lowWord() ) ; 00240 // hit->setCellID1( b.highWord() ) ; 00241 00242 hit->setPosition( pos ) ; 00243 00244 calVec->push_back( hit ) ; 00245 00246 // assign the hits randomly to MC particles 00247 float rn = .99999*rand()/RAND_MAX ; 00248 int mcIndx = static_cast<int>( NMCPART * rn ) ; 00249 00250 // in order to access a MCParticle, we need a dynamic cast as the 00251 // LCCollection returns an LCIOObject - this is like vectors in Java 00252 hit->addMCParticleContribution( dynamic_cast<MCParticle*>(mcVec->getElementAt( mcIndx )) , 00253 0.314159, 0.1155 ) ; // no pdg 00254 00255 } 00256 00257 // -------- data can be modified as long as is not not made persistent -------- 00258 00259 for(int j=0;j<NHITS;j++){ 00260 SimCalorimeterHitImpl* existingHit 00261 = dynamic_cast<SimCalorimeterHitImpl*>( calVec->getElementAt(j) ) ; // << Ok now 00262 00263 // = dynamic_cast<SimCalorimeterHitImpl*>( (*calVec)[j] ) ; // << not needed 00264 00265 existingHit->addMCParticleContribution( dynamic_cast<MCParticle*> 00266 (mcVec->getElementAt(0)), 00267 0.1, 0. ) ; 00268 } 00269 00270 // // ----- find the MCParticle with the largest contribution to the SimCalorimeterHits: 00271 // for(int j=0;j<NHITS;j++){ 00272 00273 // SimCalorimeterHit* sh = 00274 // dynamic_cast<SimCalorimeterHit*>( calVec->getElementAt(j) ) ; 00275 00276 // typedef std::map<MCParticle*,double> MCPMap ; 00277 00278 // MCPMap mcpMap ; 00279 00280 // for( int ii=0 ;ii< sh->getNMCContributions() ; ++ii){ 00281 // mcpMap[ sh->getParticleCont(ii) ] += sh->getEnergyCont(ii) ; 00282 // } 00283 00284 // double eMax(0.) ; 00285 // MCParticle* mcp ; 00286 00287 // for( MCPMap::iterator it = mcpMap.begin() ; it != mcpMap.end() ; ++it ){ 00288 00289 // if( it->second > eMax ) { 00290 // mcp = it->first ; 00291 // eMax = it->second ; 00292 // } 00293 // } 00294 // // std::cout << " largest contribution " << eMax << " GeV from particle " 00295 // // << mcp << std::endl ; 00296 // } 00297 00298 // and finally some tracker hits 00299 // with some user extensions (4 floats and 2 ints) per track: 00300 // we just need to create parallel collections of float and int vectors 00301 LCCollectionVec* trkVec = new LCCollectionVec( LCIO::SIMTRACKERHIT ) ; 00302 LCCollectionVec* extFVec = new LCCollectionVec( LCIO::LCFLOATVEC ) ; 00303 LCCollectionVec* extIVec = new LCCollectionVec( LCIO::LCINTVEC ) ; 00304 00305 LCFlagImpl thFlag(0) ; 00306 thFlag.setBit( LCIO::THBIT_MOMENTUM ) ; 00307 trkVec->setFlag( thFlag.getFlag() ) ; 00308 00309 00310 LCTypedVector<MCParticle> mcpTV( mcVec ) ; 00311 00312 CellIDEncoder<SimTrackerHitImpl> cd( "i:8,j:8,k:8" ,trkVec ) ; 00313 00314 for(int j=0;j<NHITS;j++){ 00315 00316 SimTrackerHitImpl* hit = new SimTrackerHitImpl ; 00317 00318 cd["i"] = j ; 00319 cd["j"] = j + 100 ; 00320 cd["k"] = j + 200 ; 00321 00322 cd.setCellID( hit ) ; 00323 00324 LCFloatVec* extF = new LCFloatVec ; 00325 LCIntVec* extI = new LCIntVec ; 00326 00327 //hit->setdEdx( 30e-9 ) ; 00328 hit->setEDep( 30e-9 ) ; 00329 00330 double pos[3] = { 1.1* rand()/RAND_MAX , 2.2* rand()/RAND_MAX , 3.3* rand()/RAND_MAX } ; 00331 00332 hit->setPosition( pos ) ; 00333 00334 // assign the hits randomly to MC particles 00335 float rn = .99999*rand()/RAND_MAX ; 00336 int mcIndx = static_cast<int>( NMCPART * rn ) ; 00337 00338 00339 // hit->setMCParticle( dynamic_cast<MCParticle*>(mcVec->getElementAt( mcIndx ) ) ) ; 00340 hit->setMCParticle( mcpTV[ mcIndx ] ) ; 00341 00342 hit->setMomentum( 1. , 2. , 3. ) ; 00343 hit->setPathLength( .042 ) ; 00344 00345 // fill the extension vectors (4 floats, 2 ints) 00346 extF->push_back( 3.14159 ) ; 00347 for(int k=0;k<3;k++) extF->push_back( pos[k] * 0.1 ) ; 00348 00349 extI->push_back( 123456789 ) ; 00350 extI->push_back( mcIndx ) ; 00351 00352 // add the hit and the extensions to their corresponding collections 00353 trkVec->push_back( hit ) ; 00354 extFVec->push_back( extF ) ; 00355 extIVec->push_back( extI ) ; 00356 } 00357 00358 00359 // add all collections to the event 00360 evt->addCollection( mcVec , "MCParticle" ) ; 00361 00362 //deubg only 00363 //evt->addCollection( mcVec2, "MCParticle2" ) ; 00364 00365 evt->addCollection( calVec , ecalName ) ; 00366 evt->addCollection( trkVec , tpcName ) ; 00367 evt->addCollection( extFVec , tpcName+"UserFloatExtension" ) ; 00368 evt->addCollection( extIVec , tpcName+"UserIntExtension" ) ; 00369 00370 // test: add a collection for one event only: 00371 // if( rn == NRUN-1 && i == 0 ) { // first event o last run 00372 if( rn == 1 && i == 0 ) { // first event o last run 00373 LCCollectionVec* addExtVec = new LCCollectionVec( LCIO::LCFLOATVEC ) ; 00374 LCFloatVec* addExt = new LCFloatVec ; 00375 addExt->push_back( 1. ); 00376 addExt->push_back( 2. ); 00377 addExt->push_back( 3. ); 00378 addExt->push_back( 4. ); 00379 addExtVec->push_back( addExt ) ; 00380 evt->addCollection( addExtVec , "AdditionalExtension" ) ; 00381 } 00382 //---- write a subset of MCParticle to the event ------ 00383 LCCollectionVec* mcSubVec = new LCCollectionVec( LCIO::MCPARTICLE ) ; 00384 mcSubVec->setSubset(true) ; 00385 00386 for(int j=0;j< mcVec->getNumberOfElements() ; j++ ){ 00387 00388 MCParticle* p = dynamic_cast< MCParticle*>( mcVec->getElementAt(j) ) ; 00389 if( p->getDaughters().size() == 0 ) 00390 mcSubVec->addElement( p ) ; 00391 } 00392 evt->addCollection( mcSubVec , "FinalMCParticles" ) ; 00393 //----------------------------------------------------- 00394 00395 00396 00397 // even though this is a simjob we can store 'real data' objects :) 00398 00399 #define WRITE_TRACKERRAWDATA 1 00400 #ifdef WRITE_TRACKERRAWDATA 00401 //--- write some new TPC raw data collections to the file 00402 LCCollectionVec* tpcRawVec = new LCCollectionVec( LCIO::TRACKERRAWDATA ) ; 00403 00404 for(int j=0;j<NHITS;j++){ 00405 00406 TrackerRawDataImpl* tpcRaw = new TrackerRawDataImpl ; 00407 00408 tpcRaw->setCellID0( j ) ; 00409 tpcRaw->setTime( -j ) ; 00410 00411 if( j % 2 ) { // test two ways of setting the charge 00412 ShortVec adcValues ; 00413 adcValues.push_back( 42 ) ; 00414 adcValues.push_back( 43 ) ; 00415 adcValues.push_back( 44 ) ; 00416 adcValues.push_back( 45 ) ; 00417 tpcRaw->setADCValues( adcValues ) ; 00418 } else { 00419 tpcRaw->adcValues().push_back( 42 ) ; 00420 tpcRaw->adcValues().push_back( 43 ) ; 00421 tpcRaw->adcValues().push_back( 44 ) ; 00422 tpcRaw->adcValues().push_back( 45 ) ; 00423 } 00424 tpcRawVec->addElement( tpcRaw ) ; 00425 } 00426 evt->addCollection( tpcRawVec , "TrackerRawDataExample" ) ; 00427 00428 //---- test new relation navigator object 00429 LCRelationNavigator relNav( LCIO::TRACKERRAWDATA, LCIO::SIMTRACKERHIT ) ; 00430 00431 for(int j=0;j<NHITS;j++){ 00432 relNav.addRelation( tpcRawVec->getElementAt(j) , trkVec->getElementAt(j) , 0.42 ) ; 00433 00434 // tpcRawVec->getElementAt(j)->link<MyTrackLink>() = 00435 // (*tpcRawVec)[j]->link< MyTrackLink >() = 00436 // dynamic_cast<SimTrackerHit*>( (*trkVec)[j] ); 00437 00438 } 00439 evt->addCollection( relNav.createLCCollection() , "TPCRawFADCMCTruth" ) ; 00440 00441 00442 //------ corrected data 00443 00444 LCCollectionVec* tpcCorrectedVec = new LCCollectionVec( LCIO::TRACKERDATA ) ; 00445 00446 for(int j=0;j<NHITS;j++){ 00447 00448 TrackerDataImpl* tpcCorrected = new TrackerDataImpl ; 00449 00450 tpcCorrected->setCellID0( j ) ; 00451 tpcCorrected->setTime( -j ) ; 00452 00453 tpcCorrected->chargeValues().push_back( 42.12345 ) ; 00454 tpcCorrected->chargeValues().push_back( 43.09876 ) ; 00455 tpcCorrected->chargeValues().push_back( 44.12345 ) ; 00456 tpcCorrected->chargeValues().push_back( 45.09876 ) ; 00457 00458 tpcCorrectedVec->addElement( tpcCorrected ) ; 00459 } 00460 evt->addCollection( tpcCorrectedVec , "TrackerDataExample" ) ; 00461 00462 // ------ pulses 00463 00464 LCCollectionVec* tpcPulseVec = new LCCollectionVec( LCIO::TRACKERPULSE ) ; 00465 00466 IntVec qualityBits ; 00467 qualityBits.push_back(0) ; 00468 qualityBits.push_back(1) ; 00469 00470 StringVec bitNames ; 00471 bitNames.push_back("GOOD") ; 00472 bitNames.push_back("BAD") ; 00473 00474 tpcPulseVec->parameters().setValues("TrackerPulseQualityNames", bitNames ); 00475 tpcPulseVec->parameters().setValues("TrackerPulseQualityValues", qualityBits ); 00476 00477 for(int j=0;j<NHITS;j++){ 00478 00479 TrackerPulseImpl* tpcPulse = new TrackerPulseImpl ; 00480 00481 tpcPulse->setCellID0( j ) ; 00482 tpcPulse->setTime( 3.1415 + 0.1 * j ) ; 00483 tpcPulse->setCharge( 3.1415 - 0.1 * j ) ; 00484 00485 if( j % 2 ) { 00486 tpcPulse->setQualityBit( qualityBits[0] ) ; 00487 } else { 00488 00489 tpcPulse->setQualityBit( qualityBits[1] ) ; 00490 00491 TrackerData* corr = 00492 dynamic_cast<TrackerData*> ( tpcCorrectedVec->getElementAt(j) ) ; 00493 tpcPulse->setTrackerData( corr ) ; 00494 } 00495 00496 tpcPulseVec->addElement( tpcPulse ) ; 00497 } 00498 evt->addCollection( tpcPulseVec , "TrackerPulseExample" ) ; 00499 00500 //----------------------------------------------------- 00501 #endif // WRITE_TRACKERRAWDATA 00502 00503 #define WRITE_VTXRAWHITS 1 00504 #ifdef WRITE_VTXRAWHITS 00505 00506 //--- write some VTX raw hits to the file - using the TrackerPulse 00507 LCCollectionVec* vtxRawVec = new LCCollectionVec( LCIO::TRACKERPULSE ) ; 00508 00509 for(int j=0;j<NHITS;j++){ 00510 00511 TrackerPulseImpl* vtxRaw = new TrackerPulseImpl ; 00512 00513 vtxRaw->setCellID0( 0xBebaFeca ) ; 00514 vtxRaw->setCellID1( 0xCafeBabe ) ; 00515 vtxRaw->setTime( j ) ; 00516 vtxRaw->setCharge( 42 + j ) ; 00517 00518 vtxRawVec->addElement( vtxRaw ) ; 00519 } 00520 evt->addCollection( vtxRawVec , "SiliconRawHitExample" ) ; 00521 00522 //----------------------------------------------------- 00523 #endif // WRITE_VTXRAWHITS 00524 00525 00526 00527 // write the event to the file 00528 lcWrt->writeEvent( evt ) ; 00529 00530 // dump the event to the screen 00531 LCTOOLS::dumpEvent( evt ) ; 00532 00533 // ------------ IMPORTANT ------------- ! 00534 // we created the event so we need to delete it ... 00535 delete evt ; 00536 // ------------------------------------- 00537 00538 // dont use this (compatibility with Fortran simjob.F) 00539 // if( ! (i%100) ) cout << ". " << flush ; 00540 00541 } // evt loop 00542 00543 delete runHdr ; 00544 00545 lcWrt->close() ; 00546 delete lcWrt ; 00547 00548 } // run loop 00549 00550 cout << endl 00551 << " created " << NRUN << " runs with " << NRUN*NEVENT << " events" 00552 << endl << endl ; 00553 00554 00555 // ----- some testing code for the lctypename template ----- 00556 // std::cout << lctypename<MCParticle>() << std::endl ; 00557 // std::cout << lctypename<MCParticleImpl>() << std::endl ; 00558 00559 // std::cout << lctypename<ReconstructedParticle>() << std::endl ; 00560 00561 // std::cout << lctypename<SimTrackerHit>() << std::endl ; 00562 // std::cout << lctypename<SimTrackerHitImpl>() << std::endl ; 00563 00564 // SimTrackerHitImpl sth ; 00565 // std::cout << lctypename( &sth ) << std::endl ; 00566 00567 // LCObject* obj = &sth ; 00568 // std::cout << lctypename( obj ) << std::endl ; 00569 00570 00571 00572 00573 } catch( Exception& ex){ 00574 00575 cout << " an excpetion occured: " << endl ; 00576 cout << " " << ex.what() << endl ; 00577 return 1 ; 00578 } 00579 00580 return 0 ; 00581 }