23#include "GaudiKernel/SystemOfUnits.h"
43 header.m_version = version;
62 header.m_qualy_mask = 0x8000;
63 header.m_egain_mask = 0x6000;
64 header.m_esign_mask = 0x1000;
70 header.m_crtae_mask = 0x0fff;
71 header.m_egain_tile_mask = 0x4000;
72 header.m_esign_tile_mask = 0x2000;
76 header.m_crtae_tile_mask = 0x1fff;
77 header.m_tsign_mask = 0x8000;
78 header.m_logat_mask = 0x7fff;
88 header.m_e1_norm_res = 3.2*Gaudi::Units::TeV;
89 header.m_e1_high_res = 50*Gaudi::Units::GeV;
90 header.m_high_tile = 50*Gaudi::Units::GeV;
91 header.m_low_tile = 3.2*Gaudi::Units::TeV;
92 header.m_t0 = 0.001*Gaudi::Units::ns;
93 header.m_t1 = 1250.0*Gaudi::Units::ns;
105 header.m_ncells_larem = 0;
106 header.m_ncells_larhec = 0;
107 header.m_ncells_larfcal = 0;
113 header.m_lengthProvenance = 0;
131 pars.m_nseq_max = 0x3fff;
135 pars.m_prov_max = 0x1fff;
136 pars.m_prov_max_tile = 0x1f1f;
139 pars.m_cbrt_e1_norm_res = cbrt(
static_cast<double>(pars.m_e1_norm_res));
140 pars.m_cbrt_e1_high_res = cbrt(
static_cast<double>(pars.m_e1_high_res));
141 pars.m_cbrt_low_tile = cbrt(
static_cast<double>(pars.m_low_tile));
142 pars.m_cbrt_high_tile = cbrt(
static_cast<double>(pars.m_high_tile));
145 pars.m_log_t0 = log(
static_cast<double>(pars.m_t0));
146 pars.m_log_t1 = log(
static_cast<double>(pars.m_t1));
151 pars.m_crtae_norm_field =
153 pars.m_cbrt_e1_norm_res);
154 pars.m_crtae_high_field =
156 pars.m_cbrt_e1_high_res);
159 pars.m_log_t0, pars.m_log_t1);
160 pars.m_egain_tile_field =
162 pars.m_crtae_tile_high_field =
164 pars.m_cbrt_high_tile);
165 pars.m_crtae_tile_low_field =
167 pars.m_cbrt_low_tile);
174 pars.m_egain_field.in (pars.m_enhig) |
175 pars.m_qualy_field.in (pars.m_qabad) |
176 pars.m_crtae_norm_field.in (cbrt (pars.m_e1_norm_res)) |
180 pars.m_egain_tile_field.in (pars.m_glow) |
181 pars.m_qualy_field.in (pars.m_qabad) |
182 pars.m_crtae_tile_high_field.in (pars.m_cbrt_high_tile) |
183 pars.m_esign_tile_mask;
188 pars.m_lar_dummy_subst = (pars.m_lar_dummy & ~pars.m_crtae_mask) |
189 elar.
in (elar.
out (pars.m_lar_dummy)-1);
192 pars.m_tile_dummy_subst = (pars.m_tile_dummy & ~pars.m_crtae_tile_mask) |
193 etile.
in (etile.
out (pars.m_tile_dummy)-1);
217 float ltime = pars.m_log_t0;
219 ltime = log(fabs(time));
228 if ( time < 0 &&
data != 0 )
229 data |= pars.m_tsign_mask;
251 double energy = cell->energy();
252 double time = cell->time();
254 if( (cell->provenance() & 0x2000) == 0x2000 )
255 qualflag=pars.m_qgood;
257 qualflag=pars.m_qabad;
259 int gain = cell->gain();
268 gainflag = pars.m_enlow;
272 fabs(energy) < pars.m_e1_high_res )
274 gainflag = pars.m_ehhig;
278 gainflag = pars.m_enmed;
281 if ( fabs(energy) < pars.m_e1_high_res &&
284 gainflag = pars.m_ehhig;
288 gainflag = pars.m_enhig;
296 if (gainflag == -999) {
297 it.set (pars.m_lar_dummy);
301 double crtae = cbrt(fabs(energy));
303 (cbrt_flag ? pars.m_crtae_high_field.in (crtae)
304 : pars.m_crtae_norm_field.in (crtae));
310 if (energy < 0 &&
data != 0)
311 data |= pars.m_esign_mask;
313 data |= pars.m_egain_field.in (gainflag) |
314 pars.m_qualy_field.in (qualflag);
316 if (
data == pars.m_lar_dummy)
317 data = pars.m_lar_dummy_subst;
323 if ( qualflag != pars.m_qabad){
325 if (pars.m_version >= 500)
326 it.set(cell->quality());
346 double ene[2] = {cell->ene1(), cell->ene2()};
347 double time[2] = {cell->time1(), cell->time2()};
348 int qbit[2] = {cell->qbit1(), cell->qbit2()};
349 int gain[2] = {cell->gain1(), cell->gain2()};
354 bool write_qual =
false;
355 for (
int ipmt=0; ipmt<2; ++ipmt) {
357 bool write_time =
false;
365 data = pars.m_tile_dummy;
370 int qualflag = pars.m_qabad;
372 qualflag = pars.m_qgood;
378 double crtae = cbrt(fabs(ene[ipmt]));
379 if (gain[ipmt] != pars.m_glow)
380 data = pars.m_crtae_tile_high_field.in (crtae);
382 data = pars.m_crtae_tile_low_field.in (crtae);
388 if (ene[ipmt] < 0 &&
data != 0)
389 data |= pars.m_esign_tile_mask;
393 pars.m_egain_tile_field.in (gain[ipmt]) |
394 pars.m_qualy_field.in (qualflag);
396 if (
data == pars.m_tile_dummy)
397 data = pars.m_tile_dummy_subst;
408 if (pars.m_version >= 502 && write_qual) {
409 it.set (cell->quality());
432 pars.m_hash_field.in(hash) | pars.m_nseq_field.in(nseq);
435 it.set ((
data>>16) & 0xffff);
436 it.set (
data & 0xffff);
441 pars.m_ncells_larem += nseq;
445 pars.m_ncells_larhec += nseq;
449 pars.m_ncells_larfcal += nseq;
450 ++pars.m_seq_larfcal;
453 pars.m_ncells_tile += nseq;
479 std::vector<short unsigned int> vProvenance;
487 unsigned int maxsize =
489 packed.resize (maxsize);
495 (packed.compact_begin_output (pars.m_length));
500 (packed.compact_begin_output (pars.m_length));
503 unsigned int seqhash =
static_cast<unsigned int> (-1);
507 unsigned int nseq = 0;
513 short unsigned int prevCellProvenance=0;
529 for (
size_t icell = 0;
const CaloCell* cell : cells)
532 if (dec && dec->
thinned (icell++)) {
545 nseq >= pars.m_nseq_max ||
547 seqhash + nseq != hash ||
558 finish_seq (seqhash, nseq, seqit, prevcalo, pars);
575 if (version >= 502 &&
576 (cell->provenance() & pars.m_prov_max_tile) != prevCellProvenance)
578 prevCellProvenance = cell->provenance() & pars.m_prov_max_tile;
580 pars.m_hash_field.in(hash) |
581 pars.m_prov_field.in(prevCellProvenance);
582 vProvenance.push_back ((
data>>16) & 0xffff);
583 vProvenance.push_back (
data & 0xffff);
587 pack_lar (cell, subcalo, outit, pars);
590 if (version >= 500 &&
591 (cell->provenance() & pars.m_prov_max) != prevCellProvenance)
593 prevCellProvenance = cell->provenance() & pars.m_prov_max;
595 pars.m_hash_field.in(hash) |
596 pars.m_prov_field.in(prevCellProvenance);
597 vProvenance.push_back ((
data>>16) & 0xffff);
598 vProvenance.push_back (
data & 0xffff);
606 finish_seq (seqhash, nseq, seqit, prevcalo, pars);
608 pars.m_lengthProvenance = vProvenance.size();
610 assert (outit.
used() + pars.m_length + vProvenance.size()/2 + 1 <= maxsize);
612 if (pars.m_lengthProvenance > 0) {
620 if (
x!=
y) outit.
set(0);
624 for (
unsigned short & iter : vProvenance)
631 packed.resize (outit.
used() + pars.m_length);
647 const int * phead = &(
header.m_length);
648 std::vector<CaloCompactCellContainer::value_type>
649 vhead (phead, phead +
header.m_length);
650 packed.setHeader(vhead);
677 double time = pars.m_logat_field.out (
data, underflow);
684 double ee = std::exp (time);
685 if (
data & pars.m_tsign_mask)
710 uint16_t provenance)
const
716 if (
data == pars.m_lar_dummy)
723 int gainflag = pars.m_egain_field.out (
data);
724 int qualflag = pars.m_qualy_field.out (
data);
731 if ( gainflag == pars.m_ehhig ) {
736 energy = pars.m_crtae_high_field.out (
data);
739 if ( gainflag == pars.m_enhig ) {
742 else if ( gainflag == pars.m_enmed ) {
745 else if ( gainflag == pars.m_enlow) {
748 energy = pars.m_crtae_norm_field.out (
data);
752 energy = energy*energy*energy;
753 if (
data & pars.m_esign_mask)
759 if ( qualflag != pars.m_qabad ) {
761 if (pars.m_version >= 500)
763 provenance = provenance | 0x2000;
767 cell->set (energy, time, quality, provenance, gain);
786 uint16_t provenance)
const
794 bool read_qual =
false;
796 for (
int ipmt = 0; ipmt < 2; ++ipmt) {
801 if (
data == pars.m_tile_dummy)
808 time[ipmt] = time[0];
815 int qualflag = pars.m_qualy_field.out (
data);
816 int gainflag = pars.m_egain_tile_field.out (
data);
818 gain[ipmt] = gainflag;
822 if (gainflag != pars.m_glow)
823 e = pars.m_crtae_tile_high_field.out (
data);
825 e = pars.m_crtae_tile_low_field.out (
data);
827 if (
data & pars.m_esign_tile_mask)
828 ene[ipmt] = -ene[ipmt];
831 if (qualflag != pars.m_qabad) {
843 if (pars.m_version >= 502) {
844 qbit[0] |= pars.m_tile_qual1_field.out (provenance);
845 qbit[1] |= pars.m_tile_qual2_field.out (provenance);
847 uint16_t qualp = it.next();
848 qual[0] = pars.m_tile_qual1_field.out (qualp);
849 qual[1] = pars.m_tile_qual2_field.out (qualp);
856 qual[0] = qual[1] = 0;
860 return TileCell (dde, ene[0], ene[1], time[0], time[1],
861 qual[0], qual[1], qbit[0], qbit[1], gain[0], gain[1]);
879 const std::vector<int>& vheader,
888 pars.m_seq_larem = 0;
889 pars.m_seq_larhec = 0;
890 pars.m_seq_larfcal = 0;
891 pars.m_lengthProvenance = 0;
892 pars.m_ncells_tile = 0;
893 pars.m_ncells_larhec = 0;
894 pars.m_ncells_larfcal = 0;
895 pars.m_ncells_larem = 0;
898 const int* headerbeg = &*vheader.begin();
899 const int* headerend = headerbeg + vheader.size();
900 size_t nheader = headerend - headerbeg;
901 size_t parsize =
sizeof(
header) /
sizeof(
int);
902 size_t ncopy = std::min (nheader, parsize);
903 int* parsbeg =
reinterpret_cast<int*
>(&pars);
904 std::copy (headerbeg, headerbeg+ncopy, parsbeg);
905 if (nheader > parsize) {
909 "CaloCellPacker_400_500 ")
910 <<
"Corrupted data: Compact cell header is "
911 << nheader <<
" words long, longer than the largest expected value of "
914 else if (ncopy < parsize) {
919 std::fill (parsbeg + ncopy, parsbeg + parsize, 0);
927 unsigned nprov = pars.m_lengthProvenance/2;
928 if (nprov + vheader.size() > packed.getData().size()) {
930 "CaloCellPacker_400_500 ")
931 <<
"Corrupted data: Provenance count too large "
932 << pars.m_lengthProvenance <<
".";
933 pars.m_lengthProvenance = 0;
939 packed.compact_begin_input_from(pars.m_lengthProvenance/2);
943 short unsigned int currProvValue=0;
945 short unsigned int nextProvValue=0;
946 if (pars.m_lengthProvenance) {
947 unsigned int provhash = provIt.
next();
948 provhash = (provhash<<16) | provIt.
next();
949 nextProvValue = pars.m_prov_field.out (provhash);
950 nextProvHash = pars.m_hash_field.out (provhash);
962 throw std::runtime_error(
"Failed to initialize ReadCondHandleKey for CaloSuperCellDetDescrManager");
965 ddmgr = *caloSuperCellMgrHandle;
971 throw std::runtime_error(
"Failed to initialize ReadCondHandleKey for CaloDetDescrManager");
974 ddmgr = *caloMgrHandle;
981 pars.m_ncells_larem + pars.m_ncells_larhec +
982 pars.m_ncells_larfcal + pars.m_ncells_tile;
985 "CaloCellPacker_400_500 ")
986 <<
"Corrupted data: Too many cells " << totcells <<
".";
989 cells.reserve (totcells);
993 packed.compact_begin_input();
996 std::vector<CaloCompactCellContainer::value_type>::const_iterator pend =
997 packed.getData().end() - (pars.m_lengthProvenance+1)/2;
1000 unsigned int ncells =
1001 pars.m_ncells_larem +
1002 pars.m_ncells_larhec +
1003 pars.m_ncells_larfcal +
1005 unsigned int nseqs =
1008 pars.m_seq_larfcal +
1018 if (ncells > hashmax || nseqs > hashmax || nseqs > ncells) {
1020 "CaloCellPacker_400_500 ")
1021 <<
"Corrupted data: Bad counts"
1022 <<
": ncells " << ncells <<
" nseqs " << nseqs <<
" hashmax " << hashmax;
1028 for (; nseqs > 0; --nseqs) {
1031 if (it.base() >= pend) {
1033 "CaloCellPacker_400_500 ")
1034 <<
"Corrupted data: cell vector overrun.";
1040 unsigned int hashlength =
data << 16;
1041 hashlength |= it.next();
1043 unsigned int hash = pars.m_hash_field.out (hashlength);
1044 unsigned int nseq = pars.m_nseq_field.out (hashlength);
1046 if (nseq > ncells || hash+nseq > hashmax)
1049 "CaloCellPacker_400_500 ")
1050 <<
"Corrupted data: bad sequence. "
1051 <<
"nseq " << nseq <<
" hash " << hash <<
" ncells " << ncells
1052 <<
" hashmax " << hashmax;
1061 if (subcalo != prevcalo) {
1064 cells.updateCaloEndIterators (prevcalo, cells.size());
1065 if (subcalo < prevcalo) {
1067 "CaloCellPacker_400_500 ")
1068 <<
"Cells not in subcalo order; iterators will be wrong.";
1071 cells.updateCaloBeginIterators (subcalo, cells.size());
1073 cells.setHasCalo (subcalo);
1082 if (dde ==
nullptr) {
1084 "CaloCellPacker_400_500 ")
1085 <<
"Corrupted data: can't find DDE for cell with hash " << hash;
1129 if (hash==
static_cast<unsigned int>(nextProvHash)){
1130 currProvValue = nextProvValue;
1132 unsigned int provhash = provIt.
next();
1133 provhash = (provhash<<16) | provIt.
next();
1134 nextProvValue = pars.m_prov_field.out (provhash);
1135 nextProvHash = pars.m_hash_field.out (provhash);
1147 pars, currProvValue));
1154 cell->set (dde, calo_id->
cell_id(hash));
1159 cells.push_back (cell);
1168 cells.updateCaloEndIterators (prevcalo, cells.size());
1172 if (it.base() < pend-2) {
1174 "CaloCellPacker_400_500 ")
1175 <<
"Corrupted data: didn't consume all packed data.";
std::vector< Identifier > ID
Calo cell packer/unpacker v400/500.
Definition of CaloDetDescrManager.
Helpers for checking error return status codes and reporting errors.
#define REPORT_MESSAGE_WITH_CONTEXT(LVL, CONTEXT_NAME)
Report a message, with an explicitly specified context name.
char data[hepevt_bytes_allocation_ATLAS]
Hold thinning decisions for one container.
Container class for CaloCell.
Helper for packing into/out of a bit field.
unsigned int out(unsigned int x) const
Extract a value from the bitfield.
unsigned int in(unsigned int x) const
Shift and mask a value into the bitfield.
Helper for packing a float into/out of a bit field, with a minimum of 0.
Helper for packing a float into/out of a bit field.
CaloCell * unpack_lar(CaloCompactCellContainer::compact_input_iterator &it, CaloCell_ID::SUBCALO subcalo, LArCell *cell, const pars500 &pars, uint16_t provenance) const
Unpack a LAr cell.
void finish_seq(unsigned int hash, unsigned int nseq, CaloCompactCellContainer::compact_output_iterator &it, CaloCell_ID::SUBCALO subcalo, pars500 &pars) const
Finish up one cell sequence.
void write_header(const header &header, CaloCompactCellContainer &packed) const
Write the header to the output container.
void pack_tile(const TileCell *cell, CaloCompactCellContainer::compact_output_iterator &it, const pars500 &pars) const
Pack one tile cell.
header501 header
The most recent header version.
void unpack(const CaloCompactCellContainer &packed, const std::vector< CaloCompactCellContainer::value_type > &vheader, CaloCellContainer &cells, DataPool< LArCell > &larpool, DataPool< TileCell > &tilepool) const
Unpack cells.
double unpack_time(CaloCompactCellContainer::compact_input_iterator &it, const pars500 &pars) const
Unpack the time word.
void pack_time(float time, CaloCompactCellContainer::compact_output_iterator &it, const pars500 &pars) const
Pack a time value.
void pack_lar(const CaloCell *cell, CaloCell_ID::SUBCALO subcalo, CaloCompactCellContainer::compact_output_iterator &it, const pars500 &pars) const
Pack one LAr cell.
void init_derived(pars500 &pars) const
Initialize the derived packing parameters from the constants in the header.
TileCell unpack_tile(CaloCompactCellContainer::compact_input_iterator &it, const CaloDetDescrElement *dde, const pars500 &pars, uint16_t provenance) const
Unpack a tile cell.
void init_header(header &header, int version) const
Initialize header with the current version of the packing parameters.
void pack(const CaloCellContainer &cells, CaloCompactCellContainer &packed, const SG::ThinningDecisionBase *dec, int version) const
Pack cells.
void clear_header(header &header) const
Clear the counters in the event header.
Helper base class for offline cell identifiers.
int sub_calo(const Identifier id) const
returns an int taken from SUBCALO enum and describing the subCalo to which the Id belongs.
size_type calo_cell_hash_max() const
cell 'global' hash table max size
bool is_supercell(const Identifier id) const
Test if the identifier represents a supercell.
Identifier cell_id(const int subCalo, const int barec_or_posneg, const int sampling_or_fcalmodule, const int region_or_dummy, const int eta, const int phi) const
Make a cell (== channel) ID from constituting fields and subCalo index; for (Mini)FCAL,...
CaloCell_Base_ID::size_type size_type
CaloCell_Base_ID::SUBCALO SUBCALO
Data object for each calorimeter readout cell.
Simple iterator-like object for writing to the container.
int used() const
Return the number of underlying value_type words used.
void set(CaloCompactCell::value_type x)
Set the next value, and advance the iterator.
container class for CaloCompactCell objects
int value_type
value type for the internal data
unsigned short value_type
value type for the compact CaloCell data
This class groups all DetDescr information related to a CaloCell.
IdentifierHash calo_hash() const
cell calo hash
CaloCell_ID::SUBCALO getSubCalo() const
cell subcalo
const CaloDetDescriptor * descriptor() const
cell descriptor
const CaloDetDescrElement * get_element(const Identifier &cellId) const
get element by its identifier
const CaloCell_Base_ID * getCaloCell_ID() const
get calo cell ID helper
const CaloCell_Base_ID * get_calo_helper() const
get Calo Cell ID helper
a typed memory pool that saves time spent allocation small object.
pointer nextElementPtr()
obtain the next available element in pool by pointer pool is resized if its limit has been reached On...
This is a "hash" representation of an Identifier.
Data object for LAr calorimeter readout cell.
StatusCode initialize(bool used=true)
Hold thinning decisions for one container.
bool thinned(size_t ndx) const
Return true if element ndx should be thinned.
@ VIEW_ELEMENTS
this data object is a view, it does not own its elmts
Derived packing parmeters.